diff --git a/.cloudbuild/ci/doc-tests.yaml b/.cloudbuild/ci/doc-tests.yaml index b63204376c76a..5c73d9c13918c 100644 --- a/.cloudbuild/ci/doc-tests.yaml +++ b/.cloudbuild/ci/doc-tests.yaml @@ -1,5 +1,5 @@ steps: - - name: quay.io/gravitational/next:main + - name: quay.io/gravitational/docs:latest id: docs-test entrypoint: /bin/bash dir: /src diff --git a/.cloudbuild/ci/integration-tests.yaml b/.cloudbuild/ci/integration-tests.yaml index 4ef85011140eb..3001aacb261d5 100644 --- a/.cloudbuild/ci/integration-tests.yaml +++ b/.cloudbuild/ci/integration-tests.yaml @@ -1,7 +1,8 @@ timeout: 25m options: - machineType: E2_HIGHCPU_32 + pool: + name: projects/ci-account/locations/us-west1/workerPools/high-cpu-pool # This build needs to run in environments where the _GITHUB_DEPLOY_KEY_SRC # substitution is defined, but also environments where it isn't. The diff --git a/.cloudbuild/ci/lint.yaml b/.cloudbuild/ci/lint.yaml index 2d30cadc263d6..1e4bc02bd8161 100644 --- a/.cloudbuild/ci/lint.yaml +++ b/.cloudbuild/ci/lint.yaml @@ -3,4 +3,6 @@ steps: id: lint args: ['make', 'lint'] options: - machineType: 'E2_HIGHCPU_32' + pool: + name: projects/ci-account/locations/us-west1/workerPools/high-cpu-pool + diff --git a/.cloudbuild/ci/unit-tests.yaml b/.cloudbuild/ci/unit-tests.yaml index 86e840c64ccb9..e8da07117ce0f 100644 --- a/.cloudbuild/ci/unit-tests.yaml +++ b/.cloudbuild/ci/unit-tests.yaml @@ -1,7 +1,8 @@ timeout: 25m options: - machineType: E2_HIGHCPU_32 + pool: + name: projects/ci-account/locations/us-west1/workerPools/high-cpu-pool # This build needs to run in environments where the _GITHUB_DEPLOY_KEY_SRC # substitution is defined, but also environments where it isn't. The diff --git a/.drone.yml b/.drone.yml index a60f60b556d8a..58e70b9fbe2a5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -90,7 +90,7 @@ steps: - apk add --no-cache make - chown -R $UID:$GID /go - cd /go/src/github.com/gravitational/teleport - - make -C build.assets release-amd64 + - make -C build.assets release-amd64-centos7 environment: ARCH: amd64 GID: "1000" @@ -299,7 +299,7 @@ steps: - chown -R $UID:$GID /go - cd /go/src/github.com/gravitational/teleport - export VERSION=$(cat /go/.version.txt) - - make -C build.assets release-amd64-fips + - make -C build.assets release-amd64-centos7-fips environment: ARCH: amd64 FIPS: "yes" @@ -1464,7 +1464,7 @@ steps: - apk add --no-cache make - chown -R $UID:$GID /go - cd /go/src/github.com/gravitational/teleport - - make -C build.assets release-amd64 + - make -C build.assets release-amd64-centos7 environment: ARCH: amd64 GID: "1000" @@ -1619,7 +1619,7 @@ steps: - chown -R $UID:$GID /go - cd /go/src/github.com/gravitational/teleport - export VERSION=$(cat /go/.version.txt) - - make -C build.assets release-amd64-fips + - make -C build.assets release-amd64-centos7-fips environment: ARCH: amd64 FIPS: "yes" @@ -4585,7 +4585,7 @@ steps: - chown -R $UID:$GID /go - cd /go/src/github.com/gravitational/teleport - echo -n "$WINDOWS_SIGNING_CERT" | base64 -d > windows-signing-cert.pfx - - make -C build.assets release-amd64 + - make -C build.assets release-windows - rm -f windows-signing-cert.pfx environment: ARCH: amd64 @@ -5614,6 +5614,6 @@ volumes: name: drone-s3-debrepo-pvc --- kind: signature -hmac: 5acd82e991fc974378ec84b0265df412875f0c349000a6c92720b39287639ac8 +hmac: 34263b8b17bde404ec85a7f09a6edd6679664c70a6ce53c66e6e3104a94212f4 ... diff --git a/CHANGELOG.md b/CHANGELOG.md index abd9bb95d9e74..f83a2af72a647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,213 @@ ## 10.0.0 -Teleport 10.0 is a major release of Teleport that contains new features, improvements, and bug fixes. +Teleport 10 is a major release that brings the following new features. -### Breaking Changes +Platform: + +* Passwordless (Preview) +* Resource Access Requests (Preview) +* Proxy Peering (Preview) + +Server Access: + +* IP-Based Restrictions (Preview) +* Automatic User Provisioning (Preview) + +Database Access: + +* Audit Logging for Microsoft SQL Server Database Access +* Snowflake Database Access (Preview) +* ElastiCache/MemoryDB Database Access (Preview) + +Teleport Connect: + +* Teleport Connect for Server and Database Access (Preview) + +Machine ID: + +* Machine ID Database Access Support (Preview) + +### Passwordless (Preview) + +Teleport 10 introduces passwordless support to your clusters. To use passwordless +users may register a security key with resident credentials or use a built-in +authenticator, like Touch ID. + +See https://goteleport.com/docs/access-controls/guides/passwordless/. + +### Resource Access Requests (Preview) + +Teleport 10 expands just-in-time access requests to allow for requesting access +to specific resources. This lets you grant users the least privileged access +needed for their workflows. + +Just-in-time access requests are only available in Teleport Enterprise Edition. + +### Proxy Peering (Preview) + +Proxy peering enables Teleport deployments to scale without an increase in load +from the number of agent connections. This is accomplished by allowing Proxy +Services to tunnel client connections to the desired agent through a neighboring +proxy and decoupling the number of agent connections from the number of Proxies. + +Proxy peering can be enabled with the following configurations: + +```yaml +auth_service: + tunnel_strategy: + type: proxy_peering + agent_connection_count: 1 +``` + +```yaml +proxy_service: + peer_listen_addr: 0.0.0.0:3021 +``` + +Network connectivity between proxy servers to the `peer_listen_addr` is required +for this feature to work. + +Proxy peering is only available in Teleport Enterprise Edition. + +### IP-Based Restrictions (Preview) + +Teleport 10 introduces a new role option to pin the source IP in SSH +certificates. When enabled, the source IP that was used to request certificates +is embedded in the certificate, and SSH servers will reject connection attempts +from other IPs. This protects against attacks where valid credentials are +exfiltrated from disk and copied out into other environments. + +IP-based restrictions are only available in Teleport Enterprise Edition. + +### Automatic User Provisioning (Preview) + +Teleport 10 can be configured to automatically create Linux host users upon +login without having to use Teleport's PAM integration. Users can be added to specific +Linux groups and assigned appropriate “sudoer” privileges. + +To learn more about configuring automatic user provisioning read the guide: +https://goteleport.com/docs/server-access/guides/host-user-creation/. + +### Audit Logging for Microsoft SQL Server Database Access + +Teleport 9 introduced a preview of Database Access support for Microsoft SQL +Server which didn’t include audit logging of user queries. Teleport 10 captures +users' queries and prepared statements and sends them to the audit log, similarly +to other supported database protocols. + +Teleport Database Access for SQL Server remains in Preview mode with more UX +improvements coming in future releases. + +Refer to the guide to set up access to a SQL Server with Active Directory +authentication: https://goteleport.com/docs/database-access/guides/sql-server-ad/. + +### Snowflake Database Access (Preview) + +Teleport 10 brings support for Snowflake to Database Access. Administrators can +set up access to Snowflake databases through Teleport for their users with +standard Database Access features like role-based access control and audit +logging, including query activity. + +Connect your Snowflake database to Teleport following this guide: +https://goteleport.com/docs/database-access/guides/snowflake/. + +### Elasticache/MemoryDB Database Access (Preview) + +Teleport 9 added Redis protocol support to Database Access. Teleport 10 improves +this integration by adding native support for AWS-hosted Elasticache and +MemoryDB, including auto-discovery and automatic credential management in some +deployment configurations. + +Learn more about it in this guide: +https://goteleport.com/docs/database-access/guides/redis-aws/. + +### Teleport Connect for Server and Database Access (Preview) + +Teleport Connect is a graphical macOS application that simplifies access to your +Teleport resources. Teleport Connect 10 supports Server Access and Database Access. +Other protocols and Windows support are coming in a future release. + +Get Teleport Connect installer from the macOS tab on the downloads page: +https://goteleport.com/download/. + +### Machine ID Database Access Support (Preview) + +In Teleport 10 we’ve added Database Access support to Machine ID. Applications +can use Machine ID to access databases protected by Teleport. + +You can find Machine ID guide for database access in the documentation: +https://goteleport.com/docs/machine-id/guides/databases/. + +### Breaking changes + +Please familiarize yourself with the following potentially disruptive changes in +Teleport 10 before upgrading. + +#### Auth Service version check + +Teleport 10 agents will now refuse to start if they detect that the Auth Service +is more than one major version behind them. You can use the `--skip-version-check` flag to +bypass the version check. + +Take a look at component compatibility guarantees in the documentation: +https://goteleport.com/docs/setup/operations/upgrading/#component-compatibility. + +#### HTTP_PROXY for reverse tunnels + +Reverse tunnel connections will now respect `HTTP_PROXY` environment variables. +This may result in reverse tunnel agents not being able to re-establish +connections if the HTTP proxy is set in their environment and does not allow +connections to the Teleport Proxy Service. + +Refer to the following documentation section for more details: +https://goteleport.com/docs/setup/reference/networking/#http-connect-proxies. + +#### New APT repos + +With Teleport 10 we’ve migrated to new APT repositories that now support +multiple release channels, Teleport versions and OS distributions. The new +repositories have been backfilled with Teleport versions starting from 6.2.31 +and we recommend upgrading to them. The old repositories will be maintained for +the foreseeable future. + +See updated installation instructions: +https://goteleport.com/docs/server-access/getting-started/#step-14-install-teleport-on-your-linux-host. + +#### Removed “tctl access ls” + +The `tctl access ls` command that returned information about user server access +within the cluster was removed. Please use a previous `tctl` version if you’d like +to keep using it. #### Relaxed session join permissions -In previous versions of Teleport users need full access to the node/Kubernetes pod in order to join a session. With Teleport 10.0 we have relaxed this requirement. Joining sessions remains deny-by-default as of Teleport 9.0 but now only `join_policy` statements as described in the [Moderated Sessions Guide](https://goteleport.com/docs/access-controls/guides/moderated-sessions/) are checked for session join RBAC. +In previous versions of Teleport users needed full access to a Node/Kubernetes +pod in order to join a session. Teleport 10 relaxes this requirement. Joining +sessions remains deny-by-default but now only `join_policy` statements are +checked for session join RBAC. + +See the Moderated Sessions guide for more details: +https://goteleport.com/docs/access-controls/guides/moderated-sessions/. + +#### GitHub connectors + +The GitHub authentication connector’s `teams_to_logins` field is deprecated in favor of the new +`teams_to_roles` field. The old field will be removed in a future release. + +#### Teleport FIPS AWS endpoints + +Teleport 10 will now automatically use FIPS endpoints for AWS S3 and DynamoDB +when started with the `--fips` flag. You can use the `use_fips_endpoint=false` +connection endpoint option to use regular endpoints for Teleport in FIPS mode, +for example: + +``` +s3://bucket/path?region=us-east-1&use_fips_endpoint=false +``` + +See the S3/DynamoDB backends documentation for more information: +https://goteleport.com/docs/setup/reference/backends/#s3. ## 8.0.0 @@ -242,11 +442,11 @@ Kubernetes Access will no longer automatically register a cluster named after th Teleport 6.2 contains new features, improvements, and bug fixes. -**Note:** the DynamoDB migration described [below](#dynamodb-indexing-change) -may cause rate-limiting errors from AWS APIs and is slow on large deployments -(1000+ existing audit events). The next patch release, v6.2.1, will improve the -migration performance. If you run a large DynamoDB-based cluster, we advise you -to wait for v6.2.1 before upgrading. +**Note:** the DynamoDB indexing change described below may cause rate-limiting +errors from AWS APIs and is slow on large deployments (1000+ existing audit +events). The next patch release, v6.2.1, will improve the migration performance. +If you run a large DynamoDB-based cluster, we advise you to wait for v6.2.1 +before upgrading. ### New Features @@ -417,7 +617,7 @@ To learn more about configuring role-based access control for Database Access, c See [Reference](https://goteleport.com/teleport/docs/database-access/reference/) for an overview of Database Access related configuration and CLI commands. -Finally, check out [Frequently Asked Questions](./database-access/faq.mdx). +Finally, check out [Frequently Asked Questions](docs/pages/database-access/faq.mdx). #### OSS RBAC @@ -1192,9 +1392,9 @@ This is a minor Teleport release with a focus on new features and bug fixes. ### Improvements * Alpha: Enhanced Session Recording lets you know what's really happening during a Teleport Session. [#2948](https://github.com/gravitational/teleport/issues/2948) -* Alpha: Workflows API lets admins escalate RBAC roles in response to user requests. [Read the docs](./enterprise/workflow). [#3006](https://github.com/gravitational/teleport/issues/3006) -* Beta: Teleport provides HA Support using Firestore and Google Cloud Storage using Google Cloud Platform. [Read the docs](./setup/deployments/gcp.mdx). [#2821](https://github.com/gravitational/teleport/pull/2821) -* Remote tctl execution is now possible. [Read the docs](./setup/reference/cli.mdx#tctl). [#1525](https://github.com/gravitational/teleport/issues/1525) [#2991](https://github.com/gravitational/teleport/issues/2991) +* Alpha: Workflows API lets admins escalate RBAC roles in response to user requests. [Read the docs](./docs/pages/enterprise/workflow). [#3006](https://github.com/gravitational/teleport/issues/3006) +* Beta: Teleport provides HA Support using Firestore and Google Cloud Storage using Google Cloud Platform. [Read the docs](./docs/pages/setup/deployments/gcp.mdx). [#2821](https://github.com/gravitational/teleport/pull/2821) +* Remote tctl execution is now possible. [Read the docs](./docs/pages/setup/reference/cli.mdx#tctl). [#1525](https://github.com/gravitational/teleport/issues/1525) [#2991](https://github.com/gravitational/teleport/issues/2991) ### Fixes @@ -1202,8 +1402,8 @@ This is a minor Teleport release with a focus on new features and bug fixes. ### Documentation -* Adopting root/leaf terminology for trusted clusters. [Trusted cluster documentation](./setup/admin/trustedclusters.mdx). -* Documented Teleport FedRAMP & FIPS Support. [FedRAMP & FIPS documentation](./enterprise/fedramp.mdx). +* Adopting root/leaf terminology for trusted clusters. [Trusted cluster documentation](./docs/pages/setup/admin/trustedclusters.mdx). +* Documented Teleport FedRAMP & FIPS Support. [FedRAMP & FIPS documentation](./docs/pages/enterprise/fedramp.mdx). ## 4.1.11 @@ -1434,7 +1634,7 @@ With this release of Teleport, we have built out the foundation to help Teleport ### Improvements -* Teleport now support 10,000 remote connections to a single Teleport cluster. [Using our recommend hardware setup.](./setup/operations/scaling.mdx#hardware-recommendations) +* Teleport now support 10,000 remote connections to a single Teleport cluster. [Using our recommend hardware setup.](./docs/pages/setup/operations/scaling.mdx#hardware-recommendations) * Added ability to delete node using `tctl rm`. [#2685](https://github.com/gravitational/teleport/pull/2685) * Output of `tsh ls` is now sorted by node name. [#2534](https://github.com/gravitational/teleport/pull/2534) @@ -1918,7 +2118,7 @@ available Teleport clusters with ease. #### Configuration Changes * Role templates (depreciated in Teleport 2.3) were fully removed. We recommend - migrating to role variables which are documented [here](./access-controls/guides/role-templates.mdx) + migrating to role variables which are documented [here](./docs/pages/access-controls/guides/role-templates.mdx) * Resource names (like roles, connectors, trusted clusters) can no longer contain unicode or other special characters. Update the names of all user diff --git a/Cargo.lock b/Cargo.lock index 61d5f7d430603..e447ec54a185e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - [[package]] name = "arrayvec" version = "0.5.2" @@ -139,12 +133,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - [[package]] name = "cc" version = "1.0.73" @@ -157,15 +145,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cmake" -version = "0.1.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" -dependencies = [ - "cc", -] - [[package]] name = "const-oid" version = "0.7.1" @@ -184,19 +163,6 @@ dependencies = [ "volatile-register", ] -[[package]] -name = "crepe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0c81f0055a7c877a9a69ec9d667a0b14c2b38394c712f54b9a400d035f49a9" -dependencies = [ - "petgraph 0.5.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "critical-section" version = "0.2.7" @@ -299,12 +265,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - [[package]] name = "embedded-hal" version = "0.2.7" @@ -334,27 +294,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "fixedbitset" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" - -[[package]] -name = "fixedbitset" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" - [[package]] name = "generic-array" version = "0.12.4" @@ -424,12 +363,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -465,15 +398,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "iso7816" version = "0.1.0" @@ -493,15 +417,6 @@ dependencies = [ "untrusted 0.9.0", ] -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - [[package]] name = "js-sys" version = "0.3.57" @@ -593,12 +508,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - [[package]] name = "nb" version = "0.1.3" @@ -738,26 +647,6 @@ dependencies = [ "base64ct", ] -[[package]] -name = "petgraph" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" -dependencies = [ - "fixedbitset 0.2.0", - "indexmap", -] - -[[package]] -name = "petgraph" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" -dependencies = [ - "fixedbitset 0.4.1", - "indexmap", -] - [[package]] name = "pkcs1" version = "0.3.3" @@ -795,30 +684,6 @@ dependencies = [ "toml", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.39" @@ -828,61 +693,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae5a4388762d5815a9fc0dea33c56b021cdc8dde0c55e0c9ca57197254b0cab" -dependencies = [ - "bytes", - "cfg-if", - "cmake", - "heck", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph 0.6.2", - "prost", - "prost-types", - "regex", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-types" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" -dependencies = [ - "bytes", - "prost", -] - [[package]] name = "quote" version = "1.0.18" @@ -980,13 +790,14 @@ dependencies = [ "rand_chacha 0.3.1", "rdp-rs", "rsa", + "utf16string", "uuid", ] [[package]] name = "rdp-rs" version = "0.1.0" -source = "git+https://github.com/gravitational/rdp-rs?rev=17ec446ecb73c58b77ac47c6fc8598153f673076#17ec446ecb73c58b77ac47c6fc8598153f673076" +source = "git+https://github.com/gravitational/rdp-rs?rev=6075679e7c9bd8e3c2136a87f097d05c7db3235f#6075679e7c9bd8e3c2136a87f097d05c7db3235f" dependencies = [ "bufstream", "byteorder", @@ -1002,15 +813,6 @@ dependencies = [ "yasna", ] -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.5.6" @@ -1028,15 +830,6 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "ring" version = "0.16.20" @@ -1073,17 +866,6 @@ dependencies = [ "regex", ] -[[package]] -name = "role_tester" -version = "0.1.0" -dependencies = [ - "bytes", - "crepe", - "libc", - "prost", - "prost-build", -] - [[package]] name = "rsa" version = "0.6.1" @@ -1258,20 +1040,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "termcolor" version = "1.1.3" @@ -1324,6 +1092,15 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "utf16string" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b62a1e85e12d5d712bf47a85f426b73d303e2d00a90de5f3004df3596e9d216" +dependencies = [ + "byteorder", +] + [[package]] name = "uuid" version = "1.1.2" @@ -1446,17 +1223,6 @@ dependencies = [ "untrusted 0.7.1", ] -[[package]] -name = "which" -version = "4.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" -dependencies = [ - "either", - "lazy_static", - "libc", -] - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index dff20dd5db678..12ff7b0b8316e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,7 @@ [workspace] members = [ - "lib/srv/desktop/rdp/rdpclient", - "lib/datalog/roletester" + "lib/srv/desktop/rdp/rdpclient" ] [profile.dev] diff --git a/Makefile b/Makefile index 5f9ed43478212..2e4b1aecffc31 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ # Stable releases: "1.0.0" # Pre-releases: "1.0.0-alpha.1", "1.0.0-beta.2", "1.0.0-rc.3" # Master/dev branch: "1.0.0-dev" -VERSION=10.0.0-dev +VERSION=10.0.0 DOCKER_IMAGE ?= quay.io/gravitational/teleport DOCKER_IMAGE_CI ?= quay.io/gravitational/teleport-ci @@ -45,6 +45,9 @@ CGOFLAG_TSH = $(CGOFLAG) endif ifeq ("$(OS)","linux") +# Link static version of libgcc to reduce system dependencies. +CGOFLAG ?= CGO_ENABLED=1 CGO_LDFLAGS="-Wl,--as-needed" +CGOFLAG_TSH ?= CGO_ENABLED=1 CGO_LDFLAGS="-Wl,--as-needed" # ARM builds need to specify the correct C compiler ifeq ("$(ARCH)","arm") CGOFLAG = CGO_ENABLED=1 CC=arm-linux-gnueabihf-gcc @@ -115,8 +118,8 @@ RS_BPF_BUILDDIR := lib/restrictedsession/bytecode CLANG_BPF_SYS_INCLUDES = $(shell $(CLANG) -v -E - &1 \ | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') -CGOFLAG = CGO_ENABLED=1 CGO_LDFLAGS="-Wl,-Bstatic -lbpf -lelf -lz -Wl,-Bdynamic" -CGOFLAG_TSH = CGO_ENABLED=1 CGO_LDFLAGS="-Wl,-Bstatic -lelf -lz -Wl,-Bdynamic" +CGOFLAG = CGO_ENABLED=1 CGO_LDFLAGS="-Wl,-Bstatic -lbpf -lelf -lz -Wl,-Bdynamic -Wl,--as-needed" +CGOFLAG_TSH = CGO_ENABLED=1 endif endif endif @@ -125,9 +128,6 @@ endif CHECK_CARGO := $(shell cargo --version 2>/dev/null) CHECK_RUST := $(shell rustc --version 2>/dev/null) -with_roletester := no -ROLETESTER_MESSAGE := "without access tester" - with_rdpclient := no RDPCLIENT_MESSAGE := "without Windows RDP client" @@ -142,12 +142,9 @@ CARGO_TARGET := --target=${CARGO_TARGET_${OS}_${ARCH}} ifneq ($(CHECK_RUST),) ifneq ($(CHECK_CARGO),) -with_roletester := yes -ROLETESTER_MESSAGE := "with access tester" -ROLETESTER_TAG := roletester ifneq ("$(ARCH)","arm") -# Do not build RDP client on ARM. The client includes OpenSSL which requires libatomic on ARM 32bit. +# Do not build RDP client on ARM. with_rdpclient := yes RDPCLIENT_MESSAGE := "with Windows RDP client" RDPCLIENT_TAG := desktop_access_rdp @@ -188,7 +185,7 @@ endif # On Windows only build tsh. On all other platforms build teleport, tctl, # and tsh. BINARIES=$(BUILDDIR)/teleport $(BUILDDIR)/tctl $(BUILDDIR)/tsh $(BUILDDIR)/tbot -RELEASE_MESSAGE := "Building with GOOS=$(OS) GOARCH=$(ARCH) REPRODUCIBLE=$(REPRODUCIBLE) and $(PAM_MESSAGE) and $(FIPS_MESSAGE) and $(BPF_MESSAGE) and $(ROLETESTER_MESSAGE) and $(RDPCLIENT_MESSAGE) and $(LIBFIDO2_MESSAGE) and $(TOUCHID_MESSAGE)." +RELEASE_MESSAGE := "Building with GOOS=$(OS) GOARCH=$(ARCH) REPRODUCIBLE=$(REPRODUCIBLE) and $(PAM_MESSAGE) and $(FIPS_MESSAGE) and $(BPF_MESSAGE) and $(RDPCLIENT_MESSAGE) and $(LIBFIDO2_MESSAGE) and $(TOUCHID_MESSAGE)." ifeq ("$(OS)","windows") BINARIES=$(BUILDDIR)/tsh endif @@ -227,8 +224,8 @@ all: version # * Manual change detection was broken on a large dependency tree # If you are considering changing this behavior, please consult with dev team first .PHONY: $(BUILDDIR)/tctl -$(BUILDDIR)/tctl: roletester - GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG) $(ROLETESTER_TAG)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) ./tool/tctl +$(BUILDDIR)/tctl: + GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) ./tool/tctl .PHONY: $(BUILDDIR)/teleport $(BUILDDIR)/teleport: ensure-webassets bpf-bytecode rdpclient @@ -282,19 +279,6 @@ else bpf-bytecode: endif -# -# tctl role tester -# Requires a recent version of Rust and Cargo installed (tested rustc >= 1.52.1 and cargo >= 1.52.0) -# -ifeq ("$(with_roletester)", "yes") -.PHONY: roletester -roletester: - cargo build -p role_tester --release $(CARGO_TARGET) -else -.PHONY: roletester -roletester: -endif - ifeq ("$(with_rdpclient)", "yes") .PHONY: rdpclient rdpclient: @@ -520,12 +504,12 @@ test-helm-update-snapshots: # Chaos tests have high concurrency, run without race detector and have TestChaos prefix. # .PHONY: test-go -test-go: ensure-webassets bpf-bytecode roletester rdpclient $(TEST_LOG_DIR) $(RENDER_TESTS) +test-go: ensure-webassets bpf-bytecode rdpclient $(TEST_LOG_DIR) $(RENDER_TESTS) test-go: FLAGS ?= -race -shuffle on test-go: PACKAGES = $(shell go list ./... | grep -v integration | grep -v tool/tsh) test-go: CHAOS_FOLDERS = $(shell find . -type f -name '*chaos*.go' | xargs dirname | uniq) test-go: $(VERSRC) $(TEST_LOG_DIR) - $(CGOFLAG) go test -cover -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(ROLETESTER_TAG) $(RDPCLIENT_TAG) $(TOUCHID_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) \ + $(CGOFLAG) go test -cover -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(RDPCLIENT_TAG) $(TOUCHID_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) \ | tee $(TEST_LOG_DIR)/unit.json \ | ${RENDER_TESTS} # rdpclient and libfido2 don't play well together, so we run libfido2 tests @@ -546,7 +530,7 @@ endif $(CGOFLAG_TSH) go test -cover -json -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_TEST_TAG) $(TOUCHID_TAG)" github.com/gravitational/teleport/tool/tsh $(FLAGS) $(ADDFLAGS) \ | tee $(TEST_LOG_DIR)/unit.json \ | ${RENDER_TESTS} - $(CGOFLAG) go test -cover -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(ROLETESTER_TAG) $(RDPCLIENT_TAG)" -test.run=TestChaos $(CHAOS_FOLDERS) \ + $(CGOFLAG) go test -cover -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(RDPCLIENT_TAG)" -test.run=TestChaos $(CHAOS_FOLDERS) \ | tee $(TEST_LOG_DIR)/chaos.json \ | ${RENDER_TESTS} @@ -562,11 +546,11 @@ test-ci: $(TEST_LOG_DIR) $(RENDER_TESTS) # UNIT_ROOT_REGEX := ^TestRoot .PHONY: test-go-root -test-go-root: ensure-webassets bpf-bytecode roletester rdpclient $(TEST_LOG_DIR) $(RENDER_TESTS) +test-go-root: ensure-webassets bpf-bytecode rdpclient $(TEST_LOG_DIR) $(RENDER_TESTS) test-go-root: FLAGS ?= -race -shuffle on test-go-root: PACKAGES = $(shell go list $(ADDFLAGS) ./... | grep -v integration) test-go-root: $(VERSRC) - $(CGOFLAG) go test -json -run "$(UNIT_ROOT_REGEX)" -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(ROLETESTER_TAG) $(RDPCLIENT_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) + $(CGOFLAG) go test -json -run "$(UNIT_ROOT_REGEX)" -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(RDPCLIENT_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) | tee $(TEST_LOG_DIR)/unit-root.json \ | ${RENDER_TESTS} @@ -578,7 +562,7 @@ test-api: test-api: FLAGS ?= -race -shuffle on test-api: PACKAGES = $(shell cd api && go list ./...) test-api: $(VERSRC) $(TEST_LOG_DIR) $(RENDER_TESTS) - $(CGOFLAG) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(ROLETESTER_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) \ + $(CGOFLAG) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) \ | tee $(TEST_LOG_DIR)/api.json \ | ${RENDER_TESTS} @@ -620,7 +604,7 @@ integration: FLAGS ?= -v -race integration: PACKAGES = $(shell go list ./... | grep integration) integration: $(TEST_LOG_DIR) $(RENDER_TESTS) @echo KUBECONFIG is: $(KUBECONFIG), TEST_KUBE: $(TEST_KUBE) - $(CGOFLAG) go test -timeout 30m -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(ROLETESTER_TAG) $(RDPCLIENT_TAG)" $(PACKAGES) $(FLAGS) \ + $(CGOFLAG) go test -timeout 30m -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(RDPCLIENT_TAG)" $(PACKAGES) $(FLAGS) \ | tee $(TEST_LOG_DIR)/integration.json \ | $(RENDER_TESTS) -report-by test @@ -763,8 +747,7 @@ ADDLICENSE_ARGS := -c 'Gravitational, Inc' -l apache \ -ignore 'version.go' \ -ignore 'webassets/**' \ -ignore 'ignoreme' \ - -ignore 'lib/srv/desktop/rdp/rdpclient/target/**' \ - -ignore 'lib/datalog/roletester/target/**' + -ignore 'lib/srv/desktop/rdp/rdpclient/target/**' .PHONY: lint-license lint-license: $(ADDLICENSE) @@ -784,8 +767,7 @@ version: $(VERSRC) # This rule triggers re-generation of version files specified if Makefile changes. $(VERSRC): Makefile VERSION=$(VERSION) $(MAKE) -f version.mk setver - # Update api module path, but don't fail on error. - $(MAKE) update-api-import-path || true + # "TODO: Enable automatic updating of API import paths using update-api-import-path target once agreed upon the solution". # This rule updates the api module path to be in sync with the current api release version. # e.g. github.com/gravitational/teleport/api/vX -> github.com/gravitational/teleport/api/vY @@ -799,7 +781,7 @@ $(VERSRC): Makefile # Note: any build flags needed to compile go files (such as build tags) should be provided below. .PHONY: update-api-import-path update-api-import-path: - go run build.assets/gomod/update-api-import-path/main.go -tags "bpf fips pam roletester desktop_access_rdp linux" + go run build.assets/gomod/update-api-import-path/main.go -tags "bpf fips pam desktop_access_rdp linux" $(MAKE) grpc # make tag - prints a tag to use with git for the current version @@ -914,7 +896,6 @@ buildbox-grpc: api/types/types.proto \ api/types/webauthn/webauthn.proto \ api/types/wrappers/wrappers.proto \ - lib/datalog/types.proto \ lib/multiplexer/test/ping.proto \ lib/web/envelope.proto @@ -938,10 +919,6 @@ buildbox-grpc: --gogofast_out=plugins=grpc,$(GOGOPROTO_IMPORTMAP):. \ wrappers.proto - cd lib/datalog && protoc -I=.:$$PROTO_INCLUDE \ - --gogofast_out=plugins=grpc,$(GOGOPROTO_IMPORTMAP):. \ - types.proto - cd lib/multiplexer/test && protoc -I=.:$$PROTO_INCLUDE \ --gogofast_out=plugins=grpc,$(GOGOPROTO_IMPORTMAP):. \ ping.proto @@ -1039,7 +1016,7 @@ endif .PHONY: pkg pkg: mkdir -p $(BUILDDIR)/ - cp ./build.assets/build-package.sh $(BUILDDIR)/ + cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/ chmod +x $(BUILDDIR)/build-package.sh # arch and runtime are currently ignored on OS X # we pass them through for consistency - they will be dropped by the build script @@ -1057,7 +1034,7 @@ pkg-tsh: .PHONY: rpm rpm: mkdir -p $(BUILDDIR)/ - cp ./build.assets/build-package.sh $(BUILDDIR)/ + cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/ chmod +x $(BUILDDIR)/build-package.sh cp -a ./build.assets/rpm $(BUILDDIR)/ cp -a ./build.assets/rpm-sign $(BUILDDIR)/ @@ -1073,21 +1050,11 @@ rpm-unsigned: .PHONY: deb deb: mkdir -p $(BUILDDIR)/ - cp ./build.assets/build-package.sh $(BUILDDIR)/ + cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/ chmod +x $(BUILDDIR)/build-package.sh cd $(BUILDDIR) && ./build-package.sh -t oss -v $(VERSION) -p deb -a $(ARCH) $(RUNTIME_SECTION) $(TARBALL_PATH_SECTION) if [ -f e/Makefile ]; then $(MAKE) -C e deb; fi -# update Helm chart versions -# this isn't a 'proper' semver regex but should cover most cases -# the order of parameters in sed's extended regex mode matters; the -# dash (-) must be the last character for this to work as expected -.PHONY: update-helm-charts -update-helm-charts: - sed -i -E "s/^ tag: [a-z0-9.-]+$$/ tag: $(VERSION)/" examples/chart/teleport/values.yaml - sed -i -E "s/^ tag: [a-z0-9.-]+$$/ tag: $(VERSION)/" examples/chart/teleport-auto-trustedcluster/values.yaml - sed -i -E "s/^ tag: [a-z0-9.-]+$$/ tag: $(VERSION)/" examples/chart/teleport-daemonset/values.yaml - .PHONY: ensure-webassets ensure-webassets: @if [ ! -d $(shell pwd)/webassets/teleport/ ]; then \ diff --git a/README.md b/README.md index 21c3ea51b6b2a..026df45e9716b 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,11 @@ The `teleport` repository contains the Teleport daemon binary (written in Go) and a web UI written in Javascript (a git submodule located in the `webassets/` directory). -If your intention is to build and deploy for use in a production infrastructure -a released tag should be used. The default branch, `master`, is the current -development branch for an upcoming major version. Get the latest release tags -listed at https://goteleport.com/download/ and then use that tag in the `git clone`. -For example `git clone https://github.com/gravitational/teleport.git -b v9.1.2` gets release v9.1.2. +If your intention is to build and deploy for use in a production infrastructure +a released tag should be used. The default branch, `master`, is the current +development branch for an upcoming major version. Get the latest release tags +listed at https://goteleport.com/download/ and then use that tag in the `git clone`. +For example `git clone https://github.com/gravitational/teleport.git -b v9.1.2` gets release v9.1.2. ### Dockerized Build @@ -145,7 +145,7 @@ $ make -C build.assets build-binaries ### Local Build To perform a build on your host, ensure you have installed Go. In order to -include the Rust-powered features like Desktop Access and `roletester`, you'll +include the Rust-powered features like Desktop Access, you'll also need `cargo` and `rustc`. The current versions of these tools can be found in `build.assets/Makefile`. diff --git a/api/client/client.go b/api/client/client.go index cd6c48aa1f893..533e210b68e9f 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -651,6 +651,22 @@ func (c *Client) GetCurrentUser(ctx context.Context) (types.User, error) { return currentUser, nil } +// GetCurrentUserRoles returns current user's roles. +func (c *Client) GetCurrentUserRoles(ctx context.Context) ([]types.Role, error) { + stream, err := c.grpc.GetCurrentUserRoles(ctx, &empty.Empty{}) + if err != nil { + return nil, trail.FromGRPC(err) + } + var roles []types.Role + for role, err := stream.Recv(); err != io.EOF; role, err = stream.Recv() { + if err != nil { + return nil, trail.FromGRPC(err) + } + roles = append(roles, role) + } + return roles, nil +} + // GetUsers returns a list of users. // withSecrets controls whether authentication details are returned. func (c *Client) GetUsers(withSecrets bool) ([]types.User, error) { @@ -700,6 +716,16 @@ func (c *Client) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequ return certs, nil } +// UnstableAssertSystemRole is not a stable part of the public API. Used by older +// instances to prove that they hold a given system role. +// +// DELETE IN: 11.0 (server side method should continue to exist until 12.0 for back-compat reasons, +// but v11 clients should no longer need this method) +func (c *Client) UnstableAssertSystemRole(ctx context.Context, req proto.UnstableSystemRoleAssertion) error { + _, err := c.grpc.UnstableAssertSystemRole(ctx, &req, c.callOpts...) + return trail.FromGRPC(err) +} + // EmitAuditEvent sends an auditable event to the auth server. func (c *Client) EmitAuditEvent(ctx context.Context, event events.AuditEvent) error { grpcEvent, err := events.ToOneOf(event) @@ -1849,7 +1875,10 @@ func (c *Client) UpsertToken(ctx context.Context, token types.ProvisionToken) er // the Auth server and get a signed certificate and private key. func (c *Client) GenerateToken(ctx context.Context, req *proto.GenerateTokenRequest) (string, error) { resp, err := c.grpc.GenerateToken(ctx, req, c.callOpts...) - return resp.Token, trail.FromGRPC(err) + if err != nil { + return "", trail.FromGRPC(err) + } + return resp.Token, nil } // DeleteToken deletes a provision token by name. @@ -2674,7 +2703,10 @@ func (c *Client) CreateSessionTracker(ctx context.Context, st types.SessionTrack func (c *Client) GetSessionTracker(ctx context.Context, sessionID string) (types.SessionTracker, error) { req := &proto.GetSessionTrackerRequest{SessionID: sessionID} resp, err := c.grpc.GetSessionTracker(ctx, req, c.callOpts...) - return resp, trail.FromGRPC(err) + if err != nil { + return nil, trail.FromGRPC(err) + } + return resp, nil } // GetActiveSessionTrackers returns a list of active session trackers. diff --git a/api/client/contextdialer.go b/api/client/contextdialer.go index 0fae13ae726da..eaa86e770190e 100644 --- a/api/client/contextdialer.go +++ b/api/client/contextdialer.go @@ -59,8 +59,8 @@ func newDirectDialer(keepAlivePeriod, dialTimeout time.Duration) ContextDialer { func NewDialer(keepAlivePeriod, dialTimeout time.Duration) ContextDialer { return ContextDialerFunc(func(ctx context.Context, network, addr string) (net.Conn, error) { dialer := newDirectDialer(keepAlivePeriod, dialTimeout) - if proxyAddr := proxy.GetProxyAddress(addr); proxyAddr != nil { - return DialProxyWithDialer(ctx, proxyAddr.Host, addr, dialer) + if proxyURL := proxy.GetProxyURL(addr); proxyURL != nil { + return DialProxyWithDialer(ctx, proxyURL, addr, dialer) } return dialer.DialContext(ctx, network, addr) }) diff --git a/api/client/credentials_test.go b/api/client/credentials_test.go index 7985d9a4b4a5a..0511ebbce83f2 100644 --- a/api/client/credentials_test.go +++ b/api/client/credentials_test.go @@ -234,6 +234,7 @@ func writeProfile(t *testing.T, p *profile.Profile) { require.NoError(t, os.WriteFile(p.KnownHostsPath(), sshCACert, 0600)) require.NoError(t, os.MkdirAll(p.SSHDir(), 0700)) require.NoError(t, os.WriteFile(p.SSHCertPath(), sshCert, 0600)) + require.NoError(t, os.WriteFile(p.PPKFilePath(), ppkFile, 0600)) } func getExpectedTLSConfig(t *testing.T) *tls.Config { @@ -347,4 +348,31 @@ Na6B0YR7mdrrL+lyzymnOr6UOrT5nUWRAB1QeY7dhBNnsvoZwaS3VLSc1KCk sshCert = []byte("ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg8C10PShw+GxCadSlC4nFURIAyvDtgWRvHPabpL5wzDQAAAADAQABAAABAQDORRWgniufZcCLYcl4EgjGWx0w8bMuugm5v14cBWykC54MktKCpB24dOiDTVH0wABGhZTBtAs3QMhskUrvRSvARNdu5ERwbOoW9aU4Mtn+kxZBaP4eFk1luBkEojvAJewNrbkY3N5gJ5O9avpL6UGEu7Z5IZhQmBPIysTLZWBt/ceJEOm7ZZez/cyOl2b+UUa5c6gA7sGaRHC2FYtE4yE6j28d6w2U+JfhJrJYWqBvsROVbvhmFy5b8AfRP2pnzdWfSqbODm+iccbHvZI3jIq/ZsIjZAVlcoR/yxEwwPV2urE0Nnu+TGDO8lyS2DpgSleINe+kH9U9cnu2vxoJ+LdlAAAAAAAAAAAAAAABAAAADGFjY2Vzcy1hZG1pbgAAABAAAAAMYWNjZXNzLWFkbWluAAAAAGAtfCkAAAAAYC4lJQAAAAAAAACdAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnRlbGVwb3J0LXJvbGVzAAAALQAAACl7InZlcnNpb24iOiJ2MSIsInJvbGVzIjpbImFjY2Vzcy1hZG1pbiJdfQAAAA90ZWxlcG9ydC10cmFpdHMAAAATAAAAD3sibG9naW5zIjpudWxsfQAAAAAAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQD3VbuNmR0h3tjYIkTVG+HfNByigp6tuNl8XVylIWx7a7ojRA1nJVzAtNs9QQMut8XY+7jxf4Ue83eIaE0e0QKA0GZlRdbSG0zaYzK8CDAcPVN6Ywt8jnGKuuMhBAckGkN/9nyuJHgTAKeHYgdgQgijPuW/D59s3Sk3vCRHryZzJfZDQ52i40B1q2zLvCcQa6UBvPblHAF3usRa08DnsNkgLey1EkkyvBazqt1amH2Epl3uJRHHUtRVSp2a+0597leT58RZNFfFfB9pccPJfD7cn+iiDmN62T/8YslLYl/O6xCJ43Or7wIRHwJ1tY5hq/Bw7LYn29zeBrIkxIvsH8WtAAABFAAAAAxyc2Etc2hhMi01MTIAAAEAhIz0X+wgA0B8Bi67ALpTEA3kHVWaQY3aT+Ig8obof9upq51H0YlySPJph8h6pVzfSJzQYtuGbmzQ/XAGRMn541mnSUGoy0WCHzscyCowaj9VgjFyVpct7Nz98dB3PnRocNTajGGla+AteZEU3d6KXv/CaA4NGwO3k0rYB+UfX0AAaatAwwxnzYehpCvwSqPdrq/OIyb0aljZHADoNRrcnmYDbB1V76WWY6eTCxYGXx1QyU4A8kH9U8pIZ1fVif/i8dSTbBTftTtv5bmO4WUbVscRw/xIqgZ8v6StNLGHPTt/+Zn+iUoiIrwcnpy+yQp2SRTv7+Lg2SSvJO818x3NNg==") sshCACert = []byte("@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMIgxZpT5362npj0x6NQA76IB73bcK85K8cEyKURuHtFC83RjBzvzqtUz6X02+6ohVZiR2MdmsXkCLznzwEIZ0NtoxgnLTZLmduPLeAuYW2vIFpd0G17y6Yog9vxhQ0BLdlhU5Y3JYjRYjmQMfe1iD/RXWD6rEvgWlz+c3HMQR33JqkVIEFH34upfkC2RQG3TXjMe5t14l3yCTtyF5YGzN7+6z/4+/EDto/F3zVtSEp+k8XE/m0ddTGo7usa8ErAom31RwrgkNRmgJmPleDwEflybEsgGKApJXkfFxmG2wu20JoEt/CFjY3fIIa/5aqIGJPpMH4aEdLcj/iyNCog8D type=host") + + ppkFile = []byte(`PuTTY-User-Key-File-3: ssh-rsa +Encryption: none +Comment: test.com +Public-Lines: 6 +AAAAB3NzaC1yc2EAAAADAQABAAABAQDORRWgniufZcCLYcl4EgjGWx0w8bMuugm5 +v14cBWykC54MktKCpB24dOiDTVH0wABGhZTBtAs3QMhskUrvRSvARNdu5ERwbOoW +9aU4Mtn+kxZBaP4eFk1luBkEojvAJewNrbkY3N5gJ5O9avpL6UGEu7Z5IZhQmBPI +ysTLZWBt/ceJEOm7ZZez/cyOl2b+UUa5c6gA7sGaRHC2FYtE4yE6j28d6w2U+Jfh +JrJYWqBvsROVbvhmFy5b8AfRP2pnzdWfSqbODm+iccbHvZI3jIq/ZsIjZAVlcoR/ +yxEwwPV2urE0Nnu+TGDO8lyS2DpgSleINe+kH9U9cnu2vxoJ+Ld +Private-Lines: 14 +AAABAE1Vk207wAksAgt/5yQwRr/vizs9czuSnnDYsbT5x6idfm0iYvB+DXKJyl7o +D1Ee5zuJe6NAGHBnxn0F4D1jBqs4ZDj8NjicbQucn4w5bIfIp7BwZ83p+KypYB/f +n11EGoNqXZpXvLv6Oqbqw9rQIjNcmWZC1TNqQQioFS5Y3NV/gw5uYCRXZlSLMsRC +vcX2+LN2EP76ZbkpIVpTCidC2TxwFPPbyMsG774Olfz4U2IDgX1mO+milF7RIa/v +PADSeHAX6tJHmZ13GsyP0GAdPbFa0Ls/uykeGi1uGPFkdkNEqbWlDf1Z9IG0dr/c +k2eh8G2X8E+VFgzsKp4kWtH9nGEAAACBAOQgKFCPDVQPRqgCX7O4ZBh0MKV9V9fi +aRYReHWSrFeNDUXqmitL3f5lk2I5TDjzuqKJaz6Ag1JUGFOqaCA7RJ3yeipGLizI +MWSp0tjpQ7YSqGSXvWlEwj9UYU1R8sgAUV2xoLTTChWJGd/AvfiTPl+U9HimUx3i +vsI4mXeefrJtAAAAgQDneUWh0uIpCNBHsihSYan4/qqesPA51TVF9P2Ox7fnE5v2 +1i9mzdeRRdT4wQYAxbU++ajW/3E6Nlt0VgH0j+0hhNLKNhA1oWOAkw8wtLHaqMzO +EVcBjl/y3bT8IG3ZXWrjppry1HaWX/9C9jiaq8lRpoHSmS5qwVsoxclwYp292QAA +AIBV1ZA8WqvC+xZrPwmtmN87BHwGjqpE52kbUfcD94k8IqqhPR9oN9uOlcoBzZiS +3SkunUpmzKlcXe63RQYOEqEVlTNOafcYNc5gW8NXKrgF7vBE91VsfmOGJvLt3pIv +k53lH1qmEOm9+vrhNwNzpHk4AqDkP+0YDG++B4n0BtJJpw== +Private-MAC: 8951bbe929e0714a61df01bc8fbc5223e3688f174aee29339931984fb9224c7d`) ) diff --git a/api/client/inventory.go b/api/client/inventory.go new file mode 100644 index 0000000000000..0ad75469423fb --- /dev/null +++ b/api/client/inventory.go @@ -0,0 +1,543 @@ +/* +Copyright 2022 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "io" + "sync" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/trace" + "github.com/gravitational/trace/trail" +) + +// DownstreamInventoryControlStream is the client/agent side of a bidirectional stream established +// between teleport instances and auth servers. +type DownstreamInventoryControlStream interface { + // Send attempts to send an upstream message. An error returned from this + // method either indicates that the stream itself has failed, or that the + // supplied context was canceled. + Send(ctx context.Context, msg proto.UpstreamInventoryMessage) error + // Recv accesses the incoming/downstream message channel. + Recv() <-chan proto.DownstreamInventoryMessage + // Close closes the underlying stream without error. + Close() error + // CloseWithError closes the underlying stream with an error that can later + // be retrieved with Error(). Subsequent calls to CloseWithError have no effect. + CloseWithError(err error) error + // Done signals that the stream has been closed. + Done() <-chan struct{} + // Error checks for any error associated with stream closure (returns `nil` if + // the stream is open, or io.EOF if the stream was closed without error). + Error() error +} + +// UpstreamInventoryControlStream is the server/controller side of a bidirectional stream established +// between teleport instances and auth servers. +type UpstreamInventoryControlStream interface { + // Send attempts to send a downstream message. An error returned from this + // method either indicates that the stream itself has failed, or that the + // supplied context was canceled. + Send(ctx context.Context, msg proto.DownstreamInventoryMessage) error + // Recv access the incoming/upstream message channel. + Recv() <-chan proto.UpstreamInventoryMessage + // PeerAddr gets the underlying TCP peer address (may be empty in some cases). + PeerAddr() string + // Close closes the underlying stream without error. + Close() error + // CloseWithError closes the underlying stream with an error that can later + // be retrieved with Error(). Subsequent calls to CloseWithError have no effect. + CloseWithError(err error) error + // Done signals that the stream has been closed. + Done() <-chan struct{} + // Error checks for any error associated with stream closure (returns `nil` if + // the stream is open, or io.EOF if the stream closed without error). + Error() error +} + +type ICSPipeOption func(*pipeOptions) + +type pipeOptions struct { + peerAddr string +} + +func ICSPipePeerAddr(peerAddr string) ICSPipeOption { + return func(opts *pipeOptions) { + opts.peerAddr = peerAddr + } +} + +// InventoryControlStreamPipe creates the two halves of an inventory control stream over an in-memory +// pipe. +func InventoryControlStreamPipe(opts ...ICSPipeOption) (UpstreamInventoryControlStream, DownstreamInventoryControlStream) { + var options pipeOptions + for _, opt := range opts { + opt(&options) + } + pipe := &pipeControlStream{ + downC: make(chan proto.DownstreamInventoryMessage), + upC: make(chan proto.UpstreamInventoryMessage), + doneC: make(chan struct{}), + peerAddr: options.peerAddr, + } + return upstreamPipeControlStream{pipe}, downstreamPipeControlStream{pipe} +} + +type pipeControlStream struct { + downC chan proto.DownstreamInventoryMessage + upC chan proto.UpstreamInventoryMessage + peerAddr string + mu sync.Mutex + err error + doneC chan struct{} +} + +func (p *pipeControlStream) Close() error { + return p.CloseWithError(nil) +} + +func (p *pipeControlStream) CloseWithError(err error) error { + p.mu.Lock() + defer p.mu.Unlock() + if p.err != nil { + // stream already closed + return nil + } + + if err != nil { + p.err = err + } else { + // represent "closure without error" with EOF. + p.err = io.EOF + } + close(p.doneC) + return nil +} + +func (p *pipeControlStream) Done() <-chan struct{} { + return p.doneC +} + +func (p *pipeControlStream) Error() error { + p.mu.Lock() + defer p.mu.Unlock() + return p.err +} + +type upstreamPipeControlStream struct { + *pipeControlStream +} + +func (u upstreamPipeControlStream) Send(ctx context.Context, msg proto.DownstreamInventoryMessage) error { + select { + case u.downC <- msg: + return nil + case <-u.Done(): + return trace.Errorf("failed to send downstream inventory message (pipe closed)") + case <-ctx.Done(): + return trace.Errorf("failed to send downstream inventory message: %v", ctx.Err()) + } +} + +func (u upstreamPipeControlStream) Recv() <-chan proto.UpstreamInventoryMessage { + return u.upC +} + +func (u upstreamPipeControlStream) PeerAddr() string { + return u.peerAddr +} + +type downstreamPipeControlStream struct { + *pipeControlStream +} + +func (d downstreamPipeControlStream) Send(ctx context.Context, msg proto.UpstreamInventoryMessage) error { + select { + case d.upC <- msg: + return nil + case <-d.Done(): + return trace.Errorf("failed to send upstream inventory message (pipe closed)") + case <-ctx.Done(): + return trace.Errorf("failed to send upstream inventory message: %v", ctx.Err()) + } +} + +func (d downstreamPipeControlStream) Recv() <-chan proto.DownstreamInventoryMessage { + return d.downC +} + +// InventoryControlStream opens a new control stream. The first message sent must be an +// UpstreamInventoryHello, and the first message received must be a DownstreamInventoryHello. +func (c *Client) InventoryControlStream(ctx context.Context) (DownstreamInventoryControlStream, error) { + cancelCtx, cancel := context.WithCancel(ctx) + stream, err := c.grpc.InventoryControlStream(cancelCtx, c.callOpts...) + if err != nil { + cancel() + return nil, trail.FromGRPC(err) + } + return newDownstreamInventoryControlStream(stream, cancel), nil +} + +func (c *Client) GetInventoryStatus(ctx context.Context, req proto.InventoryStatusRequest) (proto.InventoryStatusSummary, error) { + rsp, err := c.grpc.GetInventoryStatus(ctx, &req, c.callOpts...) + if err != nil { + return proto.InventoryStatusSummary{}, trail.FromGRPC(err) + } + + return *rsp, nil +} + +func (c *Client) PingInventory(ctx context.Context, req proto.InventoryPingRequest) (proto.InventoryPingResponse, error) { + rsp, err := c.grpc.PingInventory(ctx, &req, c.callOpts...) + if err != nil { + return proto.InventoryPingResponse{}, trail.FromGRPC(err) + } + + return *rsp, nil +} + +func newDownstreamInventoryControlStream(stream proto.AuthService_InventoryControlStreamClient, cancel context.CancelFunc) DownstreamInventoryControlStream { + ics := &downstreamICS{ + sendC: make(chan upstreamSend), + recvC: make(chan proto.DownstreamInventoryMessage), + cancel: cancel, + doneC: make(chan struct{}), + } + + go ics.runRecvLoop(stream) + go ics.runSendLoop(stream) + + return ics +} + +// upstreamSend is a helper message used to help us inject per-send context cancellation +type upstreamSend struct { + msg proto.UpstreamInventoryMessage + errC chan error +} + +// downstreamICS is a helper which manages a proto.AuthService_InventoryControlStreamClient +// stream and wraps its API to use friendlier types and support select/cancellation. +type downstreamICS struct { + sendC chan upstreamSend + recvC chan proto.DownstreamInventoryMessage + mu sync.Mutex + cancel context.CancelFunc + doneC chan struct{} + err error +} + +// runRecvLoop waits for incoming messages, converts them to the friendlier DownstreamInventoryMessage +// type, and pushes them to the recvC channel. +func (i *downstreamICS) runRecvLoop(stream proto.AuthService_InventoryControlStreamClient) { + for { + oneOf, err := stream.Recv() + if err != nil { + // preserve EOF to help distinguish "ok" closure. + if !trace.IsEOF(err) { + err = trace.Errorf("inventory control stream closed: %v", trail.FromGRPC(err)) + } + i.CloseWithError(err) + return + } + + var msg proto.DownstreamInventoryMessage + + switch { + case oneOf.GetHello() != nil: + msg = *oneOf.GetHello() + case oneOf.GetPing() != nil: + msg = *oneOf.GetPing() + default: + // TODO: log unknown message variants once we have a better story around + // logging in api/* packages. + continue + } + + select { + case i.recvC <- msg: + case <-i.Done(): + // stream closed by other goroutine + return + } + } +} + +// runSendLoop pulls messages off of the sendC channel, applies the appropriate protobuf wrapper types, +// and sends them over the stream. +func (i *downstreamICS) runSendLoop(stream proto.AuthService_InventoryControlStreamClient) { + for { + select { + case sendMsg := <-i.sendC: + var oneOf proto.UpstreamInventoryOneOf + switch msg := sendMsg.msg.(type) { + case proto.UpstreamInventoryHello: + oneOf.Msg = &proto.UpstreamInventoryOneOf_Hello{ + Hello: &msg, + } + case proto.InventoryHeartbeat: + oneOf.Msg = &proto.UpstreamInventoryOneOf_Heartbeat{ + Heartbeat: &msg, + } + case proto.UpstreamInventoryPong: + oneOf.Msg = &proto.UpstreamInventoryOneOf_Pong{ + Pong: &msg, + } + default: + sendMsg.errC <- trace.BadParameter("cannot send unexpected upstream msg type: %T", msg) + continue + } + err := trail.FromGRPC(stream.Send(&oneOf)) + sendMsg.errC <- err + if err != nil { + // preserve EOF errors + if !trace.IsEOF(err) { + err = trace.Errorf("upstream send failed: %v", err) + } + i.CloseWithError(err) + return + } + case <-i.Done(): + // stream closed by other goroutine + return + } + } +} + +func (i *downstreamICS) Send(ctx context.Context, msg proto.UpstreamInventoryMessage) error { + errC := make(chan error, 1) + select { + case i.sendC <- upstreamSend{msg: msg, errC: errC}: + select { + case err := <-errC: + return trace.Wrap(err) + case <-ctx.Done(): + return trace.Errorf("inventory control msg send result skipped: %v", ctx.Err()) + } + case <-ctx.Done(): + return trace.Errorf("inventory control msg not sent: %v", ctx.Err()) + case <-i.Done(): + err := i.Error() + if err == nil { + return trace.Errorf("inventory control stream externally closed during send") + } + return trace.Errorf("inventory control msg not sent: %v", err) + } +} + +func (i *downstreamICS) Recv() <-chan proto.DownstreamInventoryMessage { + return i.recvC +} + +func (i *downstreamICS) Done() <-chan struct{} { + return i.doneC +} + +func (i *downstreamICS) Close() error { + return i.CloseWithError(nil) +} + +func (i *downstreamICS) CloseWithError(err error) error { + i.mu.Lock() + defer i.mu.Unlock() + if i.err != nil { + // already closed + return nil + } + if err != nil { + i.err = err + } else { + i.err = io.EOF + } + i.cancel() + close(i.doneC) + return nil +} + +func (i *downstreamICS) Error() error { + i.mu.Lock() + defer i.mu.Unlock() + return i.err +} + +// NewUpstreamInventoryControlStream wraps the server-side control stream handle. For use as part of the internals +// of the auth server's GRPC API implementation. +func NewUpstreamInventoryControlStream(stream proto.AuthService_InventoryControlStreamServer, peerAddr string) UpstreamInventoryControlStream { + ics := &upstreamICS{ + sendC: make(chan downstreamSend), + recvC: make(chan proto.UpstreamInventoryMessage), + doneC: make(chan struct{}), + peerAddr: peerAddr, + } + + go ics.runRecvLoop(stream) + go ics.runSendLoop(stream) + + return ics +} + +// downstreamSend is a helper message used to help us inject per-send context cancellation +type downstreamSend struct { + msg proto.DownstreamInventoryMessage + errC chan error +} + +// upstreamICS is a helper which manages a proto.AuthService_InventoryControlStreamServer +// stream and wraps its API to use friendlier types and support select/cancellation. +type upstreamICS struct { + sendC chan downstreamSend + recvC chan proto.UpstreamInventoryMessage + peerAddr string + mu sync.Mutex + doneC chan struct{} + err error +} + +// runRecvLoop waits for incoming messages, converts them to the friendlier UpstreamInventoryMessage +// type, and pushes them to the recvC channel. +func (i *upstreamICS) runRecvLoop(stream proto.AuthService_InventoryControlStreamServer) { + for { + oneOf, err := stream.Recv() + if err != nil { + // preserve eof errors + if !trace.IsEOF(err) { + err = trace.Errorf("inventory control stream recv failed: %v", trail.FromGRPC(err)) + } + i.CloseWithError(err) + return + } + + var msg proto.UpstreamInventoryMessage + + switch { + case oneOf.GetHello() != nil: + msg = *oneOf.GetHello() + case oneOf.GetHeartbeat() != nil: + msg = *oneOf.GetHeartbeat() + case oneOf.GetPong() != nil: + msg = *oneOf.GetPong() + default: + // TODO: log unknown message variants once we have a better story around + // logging in api/* packages. + continue + } + + select { + case i.recvC <- msg: + case <-i.Done(): + // stream closed by other goroutine + return + } + } +} + +// runSendLoop pulls messages off of the sendC channel, applies the appropriate protobuf wrapper types, +// and sends them over the channel. +func (i *upstreamICS) runSendLoop(stream proto.AuthService_InventoryControlStreamServer) { + for { + select { + case sendMsg := <-i.sendC: + var oneOf proto.DownstreamInventoryOneOf + switch msg := sendMsg.msg.(type) { + case proto.DownstreamInventoryHello: + oneOf.Msg = &proto.DownstreamInventoryOneOf_Hello{ + Hello: &msg, + } + case proto.DownstreamInventoryPing: + oneOf.Msg = &proto.DownstreamInventoryOneOf_Ping{ + Ping: &msg, + } + default: + sendMsg.errC <- trace.BadParameter("cannot send unexpected upstream msg type: %T", msg) + continue + } + err := trail.FromGRPC(stream.Send(&oneOf)) + sendMsg.errC <- err + if err != nil { + // preserve eof errors + if !trace.IsEOF(err) { + err = trace.Errorf("downstream send failed: %v", err) + } + i.CloseWithError(err) + return + } + case <-i.Done(): + // stream closed by other goroutine + return + } + } +} + +func (i *upstreamICS) Send(ctx context.Context, msg proto.DownstreamInventoryMessage) error { + errC := make(chan error, 1) + select { + case i.sendC <- downstreamSend{msg: msg, errC: errC}: + select { + case err := <-errC: + return trace.Wrap(err) + case <-ctx.Done(): + return trace.Errorf("inventory control msg send result skipped: %v", ctx.Err()) + } + case <-ctx.Done(): + return trace.Errorf("inventory control msg not sent: %v", ctx.Err()) + case <-i.Done(): + err := i.Error() + if err == nil { + return trace.Errorf("inventory control stream externally closed during send") + } + return trace.Errorf("inventory control msg not sent: %v", err) + } +} + +func (i *upstreamICS) Recv() <-chan proto.UpstreamInventoryMessage { + return i.recvC +} + +func (i *upstreamICS) PeerAddr() string { + return i.peerAddr +} + +func (i *upstreamICS) Done() <-chan struct{} { + return i.doneC +} + +func (i *upstreamICS) Close() error { + return i.CloseWithError(nil) +} + +func (i *upstreamICS) CloseWithError(err error) error { + i.mu.Lock() + defer i.mu.Unlock() + if i.err != nil { + // already closed + return nil + } + if err != nil { + i.err = err + } else { + i.err = io.EOF + } + close(i.doneC) + return nil +} + +func (i *upstreamICS) Error() error { + i.mu.Lock() + defer i.mu.Unlock() + return i.err +} diff --git a/api/client/inventory_test.go b/api/client/inventory_test.go new file mode 100644 index 0000000000000..fa99979cc65eb --- /dev/null +++ b/api/client/inventory_test.go @@ -0,0 +1,103 @@ +/* +Copyright 2022 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "testing" + "time" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" +) + +// TestInventoryControlStreamPipe is a sanity-check to make sure that the in-memory +// pipe version of the ICS works as expected. This test is trivial but it helps to +// keep accidental breakage of the pipe abstraction from showing up in an obscure +// way inside the tests that rely upon it. +func TestInventoryControlStreamPipe(t *testing.T) { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + upstream, downstream := InventoryControlStreamPipe() + defer upstream.Close() + + upMsgs := []proto.UpstreamInventoryMessage{ + proto.UpstreamInventoryHello{}, + proto.UpstreamInventoryPong{}, + proto.InventoryHeartbeat{}, + } + + downMsgs := []proto.DownstreamInventoryMessage{ + proto.DownstreamInventoryHello{}, + proto.DownstreamInventoryPing{}, + proto.DownstreamInventoryPing{}, // duplicate to pad downMsgs to same length as upMsgs + } + + go func() { + for _, m := range upMsgs { + downstream.Send(ctx, m) + } + }() + + go func() { + for _, m := range downMsgs { + upstream.Send(ctx, m) + } + }() + + timeout := time.NewTimer(time.Second * 5) + defer timeout.Stop() + for i := range upMsgs { + if !timeout.Stop() { + <-timeout.C + } + timeout.Reset(time.Second * 5) + + // upstream handle recv + select { + case msg := <-upstream.Recv(): + require.IsType(t, upMsgs[i], msg) + case <-timeout.C: + t.Fatalf("timeout waiting for message: %T", upMsgs[i]) + } + + // downstream handle recv + select { + case msg := <-downstream.Recv(): + require.IsType(t, downMsgs[i], msg) + case <-timeout.C: + t.Fatalf("timeout waiting for message: %T", downMsgs[i]) + } + } + + upstream.Close() + + if !timeout.Stop() { + <-timeout.C + } + timeout.Reset(time.Second * 5) + + select { + case <-downstream.Done(): + case <-timeout.C: + t.Fatal("timeout waiting for close") + } + + require.True(t, trace.IsEOF(downstream.Error())) +} diff --git a/api/client/proto/authservice.pb.go b/api/client/proto/authservice.pb.go index 6f556e8cffb64..e96479f7f0538 100644 --- a/api/client/proto/authservice.pb.go +++ b/api/client/proto/authservice.pb.go @@ -859,10 +859,20 @@ type HostCertsRequest struct { // clients request certs assuming one state and auth servers issue another. Rotation *types.Rotation `protobuf:"bytes,9,opt,name=Rotation,proto3" json:"rotation,omitempty"` // NoCache is argument that only local callers can supply to bypass cache - NoCache bool `protobuf:"varint,10,opt,name=NoCache,proto3" json:"-"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + NoCache bool `protobuf:"varint,10,opt,name=NoCache,proto3" json:"-"` + // SystemRoles is a list of system roles held by the host. Most host certs are + // single-role and only specify the Role field. The SystemRoles field is only + // currently used on Instance certs, which need to express all roles held by + // the instance. + SystemRoles []github_com_gravitational_teleport_api_types.SystemRole `protobuf:"bytes,11,rep,name=SystemRoles,proto3,casttype=github.com/gravitational/teleport/api/types.SystemRole" json:"system_roles,omitempty"` + // UnstableSystemRoleAssertionID is not a stable part of the public API. Used by + // older instances to requisition a multi-role cert by individually proving which + // system roles are held. + // DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) + UnstableSystemRoleAssertionID string `protobuf:"bytes,12,opt,name=UnstableSystemRoleAssertionID,proto3" json:"system_role_assertion_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *HostCertsRequest) Reset() { *m = HostCertsRequest{} } @@ -968,6 +978,20 @@ func (m *HostCertsRequest) GetNoCache() bool { return false } +func (m *HostCertsRequest) GetSystemRoles() []github_com_gravitational_teleport_api_types.SystemRole { + if m != nil { + return m.SystemRoles + } + return nil +} + +func (m *HostCertsRequest) GetUnstableSystemRoleAssertionID() string { + if m != nil { + return m.UnstableSystemRoleAssertionID + } + return "" +} + // UserCertRequest specifies certificate-generation parameters // for a user. type UserCertsRequest struct { @@ -1011,9 +1035,12 @@ type UserCertsRequest struct { // RouteToWindowsDesktop specifies the target windows desktop name to encode into // certificate so windows desktop client requests are routed appropriately. RouteToWindowsDesktop RouteToWindowsDesktop `protobuf:"bytes,13,opt,name=RouteToWindowsDesktop,proto3" json:"route_to_windows_desktop,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + // UseRoleRequests is used to ensure a certificate request is intended to + // use role impersonation, even if the list of role requests is empty. + UseRoleRequests bool `protobuf:"varint,14,opt,name=UseRoleRequests,proto3" json:"use_role_requests,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *UserCertsRequest) Reset() { *m = UserCertsRequest{} } @@ -1140,6 +1167,13 @@ func (m *UserCertsRequest) GetRouteToWindowsDesktop() RouteToWindowsDesktop { return RouteToWindowsDesktop{} } +func (m *UserCertsRequest) GetUseRoleRequests() bool { + if m != nil { + return m.UseRoleRequests + } + return false +} + // RouteToDatabase combines parameters for database service routing information. type RouteToDatabase struct { // ServiceName is the Teleport database proxy service name the cert is for. @@ -2328,10 +2362,14 @@ type Features struct { // Desktop enables desktop access product Desktop bool `protobuf:"varint,10,opt,name=Desktop,proto3" json:"desktop"` // ModeratedSessions enables moderated sessions product - ModeratedSessions bool `protobuf:"varint,11,opt,name=ModeratedSessions,proto3" json:"moderated_sessions"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ModeratedSessions bool `protobuf:"varint,11,opt,name=ModeratedSessions,proto3" json:"moderated_sessions"` + // MachineID enables MachineID product + MachineID bool `protobuf:"varint,12,opt,name=MachineID,proto3" json:"machine_id"` + // ResourceAccessRequests enables resource access requests product + ResourceAccessRequests bool `protobuf:"varint,13,opt,name=ResourceAccessRequests,proto3" json:"resource_access_requests"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Features) Reset() { *m = Features{} } @@ -2444,6 +2482,20 @@ func (m *Features) GetModeratedSessions() bool { return false } +func (m *Features) GetMachineID() bool { + if m != nil { + return m.MachineID + } + return false +} + +func (m *Features) GetResourceAccessRequests() bool { + if m != nil { + return m.ResourceAccessRequests + } + return false +} + // DeleteUserRequest is the input value for the DeleteUser method. type DeleteUserRequest struct { // Name is the user name to delete. @@ -11095,6 +11147,808 @@ func (m *GetSSODiagnosticInfoRequest) GetAuthRequestID() string { return "" } +// UnstableSystemRoleAssertion is not a stable part of the public API. Used by older instances +// to prove that they hold a given system role. +// DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) +type UnstableSystemRoleAssertion struct { + ServerID string `protobuf:"bytes,1,opt,name=ServerID,proto3" json:"server_id,omitempty"` + AssertionID string `protobuf:"bytes,2,opt,name=AssertionID,proto3" json:"assertion_id,omitempty"` + SystemRole github_com_gravitational_teleport_api_types.SystemRole `protobuf:"bytes,3,opt,name=SystemRole,proto3,casttype=github.com/gravitational/teleport/api/types.SystemRole" json:"system_role,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UnstableSystemRoleAssertion) Reset() { *m = UnstableSystemRoleAssertion{} } +func (m *UnstableSystemRoleAssertion) String() string { return proto.CompactTextString(m) } +func (*UnstableSystemRoleAssertion) ProtoMessage() {} +func (*UnstableSystemRoleAssertion) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{163} +} +func (m *UnstableSystemRoleAssertion) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UnstableSystemRoleAssertion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UnstableSystemRoleAssertion.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UnstableSystemRoleAssertion) XXX_Merge(src proto.Message) { + xxx_messageInfo_UnstableSystemRoleAssertion.Merge(m, src) +} +func (m *UnstableSystemRoleAssertion) XXX_Size() int { + return m.Size() +} +func (m *UnstableSystemRoleAssertion) XXX_DiscardUnknown() { + xxx_messageInfo_UnstableSystemRoleAssertion.DiscardUnknown(m) +} + +var xxx_messageInfo_UnstableSystemRoleAssertion proto.InternalMessageInfo + +func (m *UnstableSystemRoleAssertion) GetServerID() string { + if m != nil { + return m.ServerID + } + return "" +} + +func (m *UnstableSystemRoleAssertion) GetAssertionID() string { + if m != nil { + return m.AssertionID + } + return "" +} + +func (m *UnstableSystemRoleAssertion) GetSystemRole() github_com_gravitational_teleport_api_types.SystemRole { + if m != nil { + return m.SystemRole + } + return "" +} + +// UnstableSystemRoleAssertionSet is not a stable part of the public API. Records the sum of system +// role assertions provided by a given instance. +// DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) +type UnstableSystemRoleAssertionSet struct { + ServerID string `protobuf:"bytes,1,opt,name=ServerID,proto3" json:"server_id,omitempty"` + AssertionID string `protobuf:"bytes,2,opt,name=AssertionID,proto3" json:"assertion_id,omitempty"` + SystemRoles []github_com_gravitational_teleport_api_types.SystemRole `protobuf:"bytes,3,rep,name=SystemRoles,proto3,casttype=github.com/gravitational/teleport/api/types.SystemRole" json:"system_roles,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UnstableSystemRoleAssertionSet) Reset() { *m = UnstableSystemRoleAssertionSet{} } +func (m *UnstableSystemRoleAssertionSet) String() string { return proto.CompactTextString(m) } +func (*UnstableSystemRoleAssertionSet) ProtoMessage() {} +func (*UnstableSystemRoleAssertionSet) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{164} +} +func (m *UnstableSystemRoleAssertionSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UnstableSystemRoleAssertionSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UnstableSystemRoleAssertionSet.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UnstableSystemRoleAssertionSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_UnstableSystemRoleAssertionSet.Merge(m, src) +} +func (m *UnstableSystemRoleAssertionSet) XXX_Size() int { + return m.Size() +} +func (m *UnstableSystemRoleAssertionSet) XXX_DiscardUnknown() { + xxx_messageInfo_UnstableSystemRoleAssertionSet.DiscardUnknown(m) +} + +var xxx_messageInfo_UnstableSystemRoleAssertionSet proto.InternalMessageInfo + +func (m *UnstableSystemRoleAssertionSet) GetServerID() string { + if m != nil { + return m.ServerID + } + return "" +} + +func (m *UnstableSystemRoleAssertionSet) GetAssertionID() string { + if m != nil { + return m.AssertionID + } + return "" +} + +func (m *UnstableSystemRoleAssertionSet) GetSystemRoles() []github_com_gravitational_teleport_api_types.SystemRole { + if m != nil { + return m.SystemRoles + } + return nil +} + +// UpstreamInventoryOneOf is the upstream message for the inventory control stream, +// sent from teleport instances to the auth server. +type UpstreamInventoryOneOf struct { + // Types that are valid to be assigned to Msg: + // *UpstreamInventoryOneOf_Hello + // *UpstreamInventoryOneOf_Heartbeat + // *UpstreamInventoryOneOf_Pong + Msg isUpstreamInventoryOneOf_Msg `protobuf_oneof:"Msg"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpstreamInventoryOneOf) Reset() { *m = UpstreamInventoryOneOf{} } +func (m *UpstreamInventoryOneOf) String() string { return proto.CompactTextString(m) } +func (*UpstreamInventoryOneOf) ProtoMessage() {} +func (*UpstreamInventoryOneOf) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{165} +} +func (m *UpstreamInventoryOneOf) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UpstreamInventoryOneOf) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UpstreamInventoryOneOf.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UpstreamInventoryOneOf) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpstreamInventoryOneOf.Merge(m, src) +} +func (m *UpstreamInventoryOneOf) XXX_Size() int { + return m.Size() +} +func (m *UpstreamInventoryOneOf) XXX_DiscardUnknown() { + xxx_messageInfo_UpstreamInventoryOneOf.DiscardUnknown(m) +} + +var xxx_messageInfo_UpstreamInventoryOneOf proto.InternalMessageInfo + +type isUpstreamInventoryOneOf_Msg interface { + isUpstreamInventoryOneOf_Msg() + MarshalTo([]byte) (int, error) + Size() int +} + +type UpstreamInventoryOneOf_Hello struct { + Hello *UpstreamInventoryHello `protobuf:"bytes,1,opt,name=Hello,proto3,oneof" json:"Hello,omitempty"` +} +type UpstreamInventoryOneOf_Heartbeat struct { + Heartbeat *InventoryHeartbeat `protobuf:"bytes,2,opt,name=Heartbeat,proto3,oneof" json:"Heartbeat,omitempty"` +} +type UpstreamInventoryOneOf_Pong struct { + Pong *UpstreamInventoryPong `protobuf:"bytes,3,opt,name=Pong,proto3,oneof" json:"Pong,omitempty"` +} + +func (*UpstreamInventoryOneOf_Hello) isUpstreamInventoryOneOf_Msg() {} +func (*UpstreamInventoryOneOf_Heartbeat) isUpstreamInventoryOneOf_Msg() {} +func (*UpstreamInventoryOneOf_Pong) isUpstreamInventoryOneOf_Msg() {} + +func (m *UpstreamInventoryOneOf) GetMsg() isUpstreamInventoryOneOf_Msg { + if m != nil { + return m.Msg + } + return nil +} + +func (m *UpstreamInventoryOneOf) GetHello() *UpstreamInventoryHello { + if x, ok := m.GetMsg().(*UpstreamInventoryOneOf_Hello); ok { + return x.Hello + } + return nil +} + +func (m *UpstreamInventoryOneOf) GetHeartbeat() *InventoryHeartbeat { + if x, ok := m.GetMsg().(*UpstreamInventoryOneOf_Heartbeat); ok { + return x.Heartbeat + } + return nil +} + +func (m *UpstreamInventoryOneOf) GetPong() *UpstreamInventoryPong { + if x, ok := m.GetMsg().(*UpstreamInventoryOneOf_Pong); ok { + return x.Pong + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*UpstreamInventoryOneOf) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*UpstreamInventoryOneOf_Hello)(nil), + (*UpstreamInventoryOneOf_Heartbeat)(nil), + (*UpstreamInventoryOneOf_Pong)(nil), + } +} + +// DownstreamInventoryOneOf is the downstream message for the inventory control stream, +// sent from auth servers to teleport instances. +type DownstreamInventoryOneOf struct { + // Types that are valid to be assigned to Msg: + // *DownstreamInventoryOneOf_Hello + // *DownstreamInventoryOneOf_Ping + Msg isDownstreamInventoryOneOf_Msg `protobuf_oneof:"Msg"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DownstreamInventoryOneOf) Reset() { *m = DownstreamInventoryOneOf{} } +func (m *DownstreamInventoryOneOf) String() string { return proto.CompactTextString(m) } +func (*DownstreamInventoryOneOf) ProtoMessage() {} +func (*DownstreamInventoryOneOf) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{166} +} +func (m *DownstreamInventoryOneOf) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DownstreamInventoryOneOf) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DownstreamInventoryOneOf.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DownstreamInventoryOneOf) XXX_Merge(src proto.Message) { + xxx_messageInfo_DownstreamInventoryOneOf.Merge(m, src) +} +func (m *DownstreamInventoryOneOf) XXX_Size() int { + return m.Size() +} +func (m *DownstreamInventoryOneOf) XXX_DiscardUnknown() { + xxx_messageInfo_DownstreamInventoryOneOf.DiscardUnknown(m) +} + +var xxx_messageInfo_DownstreamInventoryOneOf proto.InternalMessageInfo + +type isDownstreamInventoryOneOf_Msg interface { + isDownstreamInventoryOneOf_Msg() + MarshalTo([]byte) (int, error) + Size() int +} + +type DownstreamInventoryOneOf_Hello struct { + Hello *DownstreamInventoryHello `protobuf:"bytes,1,opt,name=Hello,proto3,oneof" json:"Hello,omitempty"` +} +type DownstreamInventoryOneOf_Ping struct { + Ping *DownstreamInventoryPing `protobuf:"bytes,2,opt,name=Ping,proto3,oneof" json:"Ping,omitempty"` +} + +func (*DownstreamInventoryOneOf_Hello) isDownstreamInventoryOneOf_Msg() {} +func (*DownstreamInventoryOneOf_Ping) isDownstreamInventoryOneOf_Msg() {} + +func (m *DownstreamInventoryOneOf) GetMsg() isDownstreamInventoryOneOf_Msg { + if m != nil { + return m.Msg + } + return nil +} + +func (m *DownstreamInventoryOneOf) GetHello() *DownstreamInventoryHello { + if x, ok := m.GetMsg().(*DownstreamInventoryOneOf_Hello); ok { + return x.Hello + } + return nil +} + +func (m *DownstreamInventoryOneOf) GetPing() *DownstreamInventoryPing { + if x, ok := m.GetMsg().(*DownstreamInventoryOneOf_Ping); ok { + return x.Ping + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*DownstreamInventoryOneOf) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*DownstreamInventoryOneOf_Hello)(nil), + (*DownstreamInventoryOneOf_Ping)(nil), + } +} + +// DownstreamInventoryPing is sent down the inventory control stream for testing/debug +// purposes. +type DownstreamInventoryPing struct { + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DownstreamInventoryPing) Reset() { *m = DownstreamInventoryPing{} } +func (m *DownstreamInventoryPing) String() string { return proto.CompactTextString(m) } +func (*DownstreamInventoryPing) ProtoMessage() {} +func (*DownstreamInventoryPing) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{167} +} +func (m *DownstreamInventoryPing) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DownstreamInventoryPing) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DownstreamInventoryPing.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DownstreamInventoryPing) XXX_Merge(src proto.Message) { + xxx_messageInfo_DownstreamInventoryPing.Merge(m, src) +} +func (m *DownstreamInventoryPing) XXX_Size() int { + return m.Size() +} +func (m *DownstreamInventoryPing) XXX_DiscardUnknown() { + xxx_messageInfo_DownstreamInventoryPing.DiscardUnknown(m) +} + +var xxx_messageInfo_DownstreamInventoryPing proto.InternalMessageInfo + +func (m *DownstreamInventoryPing) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +// UpstreamInventoryPong is sent up the inventory control stream in response to a downstream +// ping (used for testing/debug purposes). +type UpstreamInventoryPong struct { + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpstreamInventoryPong) Reset() { *m = UpstreamInventoryPong{} } +func (m *UpstreamInventoryPong) String() string { return proto.CompactTextString(m) } +func (*UpstreamInventoryPong) ProtoMessage() {} +func (*UpstreamInventoryPong) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{168} +} +func (m *UpstreamInventoryPong) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UpstreamInventoryPong) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UpstreamInventoryPong.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UpstreamInventoryPong) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpstreamInventoryPong.Merge(m, src) +} +func (m *UpstreamInventoryPong) XXX_Size() int { + return m.Size() +} +func (m *UpstreamInventoryPong) XXX_DiscardUnknown() { + xxx_messageInfo_UpstreamInventoryPong.DiscardUnknown(m) +} + +var xxx_messageInfo_UpstreamInventoryPong proto.InternalMessageInfo + +func (m *UpstreamInventoryPong) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +// UpstreamInventoryHello is the hello message sent up the inventory control stream. +type UpstreamInventoryHello struct { + // Version advertises the teleport version of the instance. + Version string `protobuf:"bytes,1,opt,name=Version,proto3" json:"Version,omitempty"` + // ServerID advertises the server ID of the instance. + ServerID string `protobuf:"bytes,2,opt,name=ServerID,proto3" json:"ServerID,omitempty"` + // Services advertises the currently live services of the instance. note: this is + // distinct from the SystemRoles associated with a certificate in that a service may + // hold a system role that is not currently in use if it was granted that role by + // its auth token. i.e. Services is the subset of SystemRoles that are currently + // active. + Services []github_com_gravitational_teleport_api_types.SystemRole `protobuf:"bytes,3,rep,name=Services,proto3,casttype=github.com/gravitational/teleport/api/types.SystemRole" json:"Services,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpstreamInventoryHello) Reset() { *m = UpstreamInventoryHello{} } +func (m *UpstreamInventoryHello) String() string { return proto.CompactTextString(m) } +func (*UpstreamInventoryHello) ProtoMessage() {} +func (*UpstreamInventoryHello) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{169} +} +func (m *UpstreamInventoryHello) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UpstreamInventoryHello) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UpstreamInventoryHello.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UpstreamInventoryHello) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpstreamInventoryHello.Merge(m, src) +} +func (m *UpstreamInventoryHello) XXX_Size() int { + return m.Size() +} +func (m *UpstreamInventoryHello) XXX_DiscardUnknown() { + xxx_messageInfo_UpstreamInventoryHello.DiscardUnknown(m) +} + +var xxx_messageInfo_UpstreamInventoryHello proto.InternalMessageInfo + +func (m *UpstreamInventoryHello) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *UpstreamInventoryHello) GetServerID() string { + if m != nil { + return m.ServerID + } + return "" +} + +func (m *UpstreamInventoryHello) GetServices() []github_com_gravitational_teleport_api_types.SystemRole { + if m != nil { + return m.Services + } + return nil +} + +// DownstreamInventoryHello is the hello message sent down the inventory control stream. +type DownstreamInventoryHello struct { + // Version advertises the version of the auth server. + Version string `protobuf:"bytes,1,opt,name=Version,proto3" json:"Version,omitempty"` + // ServerID advertises the server ID of the auth server. + ServerID string `protobuf:"bytes,2,opt,name=ServerID,proto3" json:"ServerID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DownstreamInventoryHello) Reset() { *m = DownstreamInventoryHello{} } +func (m *DownstreamInventoryHello) String() string { return proto.CompactTextString(m) } +func (*DownstreamInventoryHello) ProtoMessage() {} +func (*DownstreamInventoryHello) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{170} +} +func (m *DownstreamInventoryHello) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DownstreamInventoryHello) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DownstreamInventoryHello.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DownstreamInventoryHello) XXX_Merge(src proto.Message) { + xxx_messageInfo_DownstreamInventoryHello.Merge(m, src) +} +func (m *DownstreamInventoryHello) XXX_Size() int { + return m.Size() +} +func (m *DownstreamInventoryHello) XXX_DiscardUnknown() { + xxx_messageInfo_DownstreamInventoryHello.DiscardUnknown(m) +} + +var xxx_messageInfo_DownstreamInventoryHello proto.InternalMessageInfo + +func (m *DownstreamInventoryHello) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *DownstreamInventoryHello) GetServerID() string { + if m != nil { + return m.ServerID + } + return "" +} + +// InventoryHeartbeat announces information about instance state. +type InventoryHeartbeat struct { + // SSHServer is a complete ssh server spec to be heartbeated (note: the full spec is heartbeated + // in the interest of simple conversion from the old logic of heartbeating via UpsertNode, but + // we should be able to cut down on network usage fairly significantly by moving static values + // to the hello message and only heartbeating dynamic values here). + SSHServer *types.ServerV2 `protobuf:"bytes,1,opt,name=SSHServer,proto3" json:"SSHServer,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InventoryHeartbeat) Reset() { *m = InventoryHeartbeat{} } +func (m *InventoryHeartbeat) String() string { return proto.CompactTextString(m) } +func (*InventoryHeartbeat) ProtoMessage() {} +func (*InventoryHeartbeat) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{171} +} +func (m *InventoryHeartbeat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *InventoryHeartbeat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InventoryHeartbeat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *InventoryHeartbeat) XXX_Merge(src proto.Message) { + xxx_messageInfo_InventoryHeartbeat.Merge(m, src) +} +func (m *InventoryHeartbeat) XXX_Size() int { + return m.Size() +} +func (m *InventoryHeartbeat) XXX_DiscardUnknown() { + xxx_messageInfo_InventoryHeartbeat.DiscardUnknown(m) +} + +var xxx_messageInfo_InventoryHeartbeat proto.InternalMessageInfo + +func (m *InventoryHeartbeat) GetSSHServer() *types.ServerV2 { + if m != nil { + return m.SSHServer + } + return nil +} + +// InventoryStatusRequest requests inventory status info. +type InventoryStatusRequest struct { + // Connected requests summary of the inventory control streams registered with + // the auth server that handles the request. + Connected bool `protobuf:"varint,1,opt,name=Connected,proto3" json:"Connected,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InventoryStatusRequest) Reset() { *m = InventoryStatusRequest{} } +func (m *InventoryStatusRequest) String() string { return proto.CompactTextString(m) } +func (*InventoryStatusRequest) ProtoMessage() {} +func (*InventoryStatusRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{172} +} +func (m *InventoryStatusRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *InventoryStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InventoryStatusRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *InventoryStatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_InventoryStatusRequest.Merge(m, src) +} +func (m *InventoryStatusRequest) XXX_Size() int { + return m.Size() +} +func (m *InventoryStatusRequest) XXX_DiscardUnknown() { + xxx_messageInfo_InventoryStatusRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_InventoryStatusRequest proto.InternalMessageInfo + +func (m *InventoryStatusRequest) GetConnected() bool { + if m != nil { + return m.Connected + } + return false +} + +// InventoryStatusSummary is the status summary returned by the GetInventoryStatus rpc. +type InventoryStatusSummary struct { + // Connected is a summary of the instances connected to the current auth server. Only set if + // the Connected flag in the status request is true. + Connected []UpstreamInventoryHello `protobuf:"bytes,1,rep,name=Connected,proto3" json:"Connected"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InventoryStatusSummary) Reset() { *m = InventoryStatusSummary{} } +func (m *InventoryStatusSummary) String() string { return proto.CompactTextString(m) } +func (*InventoryStatusSummary) ProtoMessage() {} +func (*InventoryStatusSummary) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{173} +} +func (m *InventoryStatusSummary) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *InventoryStatusSummary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InventoryStatusSummary.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *InventoryStatusSummary) XXX_Merge(src proto.Message) { + xxx_messageInfo_InventoryStatusSummary.Merge(m, src) +} +func (m *InventoryStatusSummary) XXX_Size() int { + return m.Size() +} +func (m *InventoryStatusSummary) XXX_DiscardUnknown() { + xxx_messageInfo_InventoryStatusSummary.DiscardUnknown(m) +} + +var xxx_messageInfo_InventoryStatusSummary proto.InternalMessageInfo + +func (m *InventoryStatusSummary) GetConnected() []UpstreamInventoryHello { + if m != nil { + return m.Connected + } + return nil +} + +// InventoryPingRequest is used to request that the specified server be sent an inventory ping +// if it has a control stream registered. +type InventoryPingRequest struct { + ServerID string `protobuf:"bytes,1,opt,name=ServerID,proto3" json:"ServerID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InventoryPingRequest) Reset() { *m = InventoryPingRequest{} } +func (m *InventoryPingRequest) String() string { return proto.CompactTextString(m) } +func (*InventoryPingRequest) ProtoMessage() {} +func (*InventoryPingRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{174} +} +func (m *InventoryPingRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *InventoryPingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InventoryPingRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *InventoryPingRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_InventoryPingRequest.Merge(m, src) +} +func (m *InventoryPingRequest) XXX_Size() int { + return m.Size() +} +func (m *InventoryPingRequest) XXX_DiscardUnknown() { + xxx_messageInfo_InventoryPingRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_InventoryPingRequest proto.InternalMessageInfo + +func (m *InventoryPingRequest) GetServerID() string { + if m != nil { + return m.ServerID + } + return "" +} + +// InventoryPingResponse returns the result of an inventory ping initiated via an +// inventory ping request. +type InventoryPingResponse struct { + Duration time.Duration `protobuf:"varint,1,opt,name=Duration,proto3,casttype=time.Duration" json:"Duration,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InventoryPingResponse) Reset() { *m = InventoryPingResponse{} } +func (m *InventoryPingResponse) String() string { return proto.CompactTextString(m) } +func (*InventoryPingResponse) ProtoMessage() {} +func (*InventoryPingResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ce8bd90b12161215, []int{175} +} +func (m *InventoryPingResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *InventoryPingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InventoryPingResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *InventoryPingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_InventoryPingResponse.Merge(m, src) +} +func (m *InventoryPingResponse) XXX_Size() int { + return m.Size() +} +func (m *InventoryPingResponse) XXX_DiscardUnknown() { + xxx_messageInfo_InventoryPingResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_InventoryPingResponse proto.InternalMessageInfo + +func (m *InventoryPingResponse) GetDuration() time.Duration { + if m != nil { + return m.Duration + } + return 0 +} + func init() { proto.RegisterEnum("proto.Operation", Operation_name, Operation_value) proto.RegisterEnum("proto.DeviceType", DeviceType_name, DeviceType_value) @@ -11268,655 +12122,704 @@ func init() { proto.RegisterType((*GetSAMLAuthRequestRequest)(nil), "proto.GetSAMLAuthRequestRequest") proto.RegisterType((*GetGithubAuthRequestRequest)(nil), "proto.GetGithubAuthRequestRequest") proto.RegisterType((*GetSSODiagnosticInfoRequest)(nil), "proto.GetSSODiagnosticInfoRequest") + proto.RegisterType((*UnstableSystemRoleAssertion)(nil), "proto.UnstableSystemRoleAssertion") + proto.RegisterType((*UnstableSystemRoleAssertionSet)(nil), "proto.UnstableSystemRoleAssertionSet") + proto.RegisterType((*UpstreamInventoryOneOf)(nil), "proto.UpstreamInventoryOneOf") + proto.RegisterType((*DownstreamInventoryOneOf)(nil), "proto.DownstreamInventoryOneOf") + proto.RegisterType((*DownstreamInventoryPing)(nil), "proto.DownstreamInventoryPing") + proto.RegisterType((*UpstreamInventoryPong)(nil), "proto.UpstreamInventoryPong") + proto.RegisterType((*UpstreamInventoryHello)(nil), "proto.UpstreamInventoryHello") + proto.RegisterType((*DownstreamInventoryHello)(nil), "proto.DownstreamInventoryHello") + proto.RegisterType((*InventoryHeartbeat)(nil), "proto.InventoryHeartbeat") + proto.RegisterType((*InventoryStatusRequest)(nil), "proto.InventoryStatusRequest") + proto.RegisterType((*InventoryStatusSummary)(nil), "proto.InventoryStatusSummary") + proto.RegisterType((*InventoryPingRequest)(nil), "proto.InventoryPingRequest") + proto.RegisterType((*InventoryPingResponse)(nil), "proto.InventoryPingResponse") } func init() { proto.RegisterFile("authservice.proto", fileDescriptor_ce8bd90b12161215) } var fileDescriptor_ce8bd90b12161215 = []byte{ - // 10275 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x7d, 0x5b, 0x6c, 0x1c, 0x49, - 0x92, 0x98, 0xba, 0xf9, 0x6a, 0x06, 0x1f, 0x6a, 0xa5, 0x48, 0xb1, 0xd5, 0xa2, 0xd8, 0x52, 0xcd, - 0x8c, 0x56, 0x33, 0xb7, 0x27, 0x69, 0xc8, 0x79, 0xcf, 0xec, 0xcc, 0x76, 0x37, 0x29, 0x92, 0x12, - 0x45, 0x71, 0xaa, 0xa9, 0xd6, 0xec, 0xee, 0xec, 0xf6, 0x16, 0xbb, 0x53, 0x64, 0x99, 0xcd, 0xae, - 0xde, 0xaa, 0xa2, 0x34, 0x82, 0x61, 0xc3, 0xaf, 0xb3, 0x0d, 0x03, 0xc6, 0x9d, 0x01, 0x1f, 0xec, - 0x83, 0x61, 0xf8, 0x00, 0xfb, 0xcb, 0x80, 0xfd, 0x61, 0x18, 0xf6, 0x8f, 0x81, 0x83, 0x01, 0xc3, - 0x5e, 0x1b, 0x30, 0xec, 0x9f, 0x83, 0x01, 0x7f, 0xd0, 0xeb, 0xfd, 0x32, 0xf8, 0x67, 0x18, 0x36, - 0xe0, 0xfd, 0x32, 0x32, 0xf2, 0x51, 0x99, 0xf5, 0xe8, 0x26, 0x25, 0xf9, 0xee, 0x47, 0x62, 0x65, - 0x66, 0x44, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0xc3, 0x25, 0xe7, 0x38, 0x3c, 0x08, - 0xa8, 0xff, 0xdc, 0x6d, 0xd3, 0x3b, 0x7d, 0xdf, 0x0b, 0x3d, 0x32, 0x86, 0xff, 0x95, 0xe7, 0xf6, - 0xbd, 0x7d, 0x0f, 0xff, 0xbc, 0xcb, 0xfe, 0xe2, 0x95, 0xe5, 0x6b, 0xfb, 0x9e, 0xb7, 0xdf, 0xa5, - 0x77, 0xf1, 0x6b, 0xef, 0xf8, 0xd9, 0x5d, 0x7a, 0xd4, 0x0f, 0x5f, 0x8a, 0xca, 0x4a, 0xbc, 0x32, - 0x74, 0x8f, 0x68, 0x10, 0x3a, 0x47, 0x7d, 0xd1, 0x60, 0xaa, 0x4d, 0xfd, 0x30, 0x10, 0x1f, 0x1f, - 0xef, 0xbb, 0xe1, 0xc1, 0xf1, 0xde, 0x9d, 0xb6, 0x77, 0x74, 0x77, 0xdf, 0x77, 0x9e, 0xbb, 0xa1, - 0x13, 0xba, 0x5e, 0xcf, 0xe9, 0xde, 0x0d, 0x69, 0x97, 0xf6, 0x3d, 0x3f, 0xbc, 0xeb, 0xf4, 0xdd, - 0xbb, 0xe1, 0xcb, 0x3e, 0x0d, 0xf8, 0xbf, 0x02, 0xb0, 0x7e, 0x1e, 0xc0, 0x17, 0x74, 0x8f, 0x0d, - 0xb1, 0xa7, 0xfe, 0x78, 0x25, 0x24, 0xbe, 0xd3, 0xef, 0x53, 0x3f, 0xfa, 0x43, 0x20, 0xf9, 0xea, - 0x3c, 0x48, 0xe8, 0x73, 0xda, 0x0b, 0xe5, 0x7f, 0x1c, 0x81, 0xf5, 0xbb, 0xf3, 0x30, 0xb6, 0xc6, - 0x0a, 0xc8, 0x27, 0x30, 0xba, 0xfb, 0xb2, 0x4f, 0x4b, 0xb9, 0x1b, 0xb9, 0xdb, 0xb3, 0xcb, 0x45, - 0x5e, 0x7f, 0xe7, 0x71, 0x9f, 0xfa, 0x88, 0xb2, 0x46, 0x4e, 0x4f, 0x2a, 0xb3, 0x0c, 0xd1, 0xf7, - 0xbd, 0x23, 0x37, 0x44, 0xae, 0xdb, 0x08, 0x41, 0x9e, 0xc2, 0xac, 0x4d, 0x03, 0xef, 0xd8, 0x6f, - 0xd3, 0x0d, 0xea, 0x74, 0xa8, 0x5f, 0xca, 0xdf, 0xc8, 0xdd, 0x9e, 0x5a, 0x9e, 0xbf, 0xc3, 0x99, - 0x66, 0x56, 0xd6, 0xae, 0x9c, 0x9e, 0x54, 0x88, 0x2f, 0xca, 0x22, 0x64, 0x1b, 0x17, 0xec, 0x18, - 0x1a, 0xf2, 0x2d, 0xcc, 0xd4, 0xa9, 0x1f, 0x56, 0x8f, 0xc3, 0x03, 0xcf, 0x77, 0xc3, 0x97, 0xa5, - 0x11, 0xc4, 0x7b, 0x45, 0xe0, 0x35, 0xea, 0x9a, 0xcb, 0xb5, 0xc5, 0xd3, 0x93, 0x4a, 0x89, 0x4d, - 0x70, 0xcb, 0x91, 0xa5, 0x06, 0x7a, 0x13, 0x19, 0xf9, 0x06, 0xa6, 0x1b, 0x8c, 0x5d, 0xed, 0x5d, - 0xef, 0x90, 0xf6, 0x82, 0xd2, 0xa8, 0x41, 0xb4, 0x5e, 0xd5, 0x5c, 0xae, 0x5d, 0x3b, 0x3d, 0xa9, - 0x2c, 0x04, 0x58, 0xd6, 0x0a, 0xb1, 0xd0, 0x40, 0x6d, 0x60, 0x22, 0x3f, 0x87, 0xd9, 0x1d, 0xdf, - 0x7b, 0xee, 0x06, 0xae, 0xd7, 0xc3, 0xa2, 0xd2, 0x18, 0xe2, 0x5e, 0x10, 0xb8, 0xcd, 0xca, 0xe6, - 0x72, 0xed, 0xfa, 0xe9, 0x49, 0xe5, 0x6a, 0x5f, 0x96, 0xf2, 0x0e, 0x4c, 0xce, 0x98, 0x20, 0x64, - 0x17, 0xa6, 0xea, 0xdd, 0xe3, 0x20, 0xa4, 0xfe, 0xb6, 0x73, 0x44, 0x4b, 0xe3, 0x88, 0x7e, 0x4e, - 0xf2, 0x25, 0xaa, 0x69, 0x2e, 0xd7, 0xca, 0xa7, 0x27, 0x95, 0x2b, 0x6d, 0x5e, 0xd4, 0xea, 0x39, - 0x47, 0x26, 0xcb, 0x75, 0x34, 0xe4, 0x63, 0x18, 0x7d, 0x12, 0x50, 0xbf, 0x54, 0x40, 0x74, 0x33, - 0x02, 0x1d, 0x2b, 0x6a, 0x2e, 0xf3, 0xf9, 0x3f, 0x0e, 0xa8, 0x6f, 0xc0, 0x23, 0x00, 0x03, 0xb4, - 0xbd, 0x2e, 0x2d, 0x4d, 0x1a, 0x80, 0xac, 0xa8, 0xf9, 0x21, 0x07, 0xf4, 0xbd, 0xae, 0xd9, 0x31, - 0x02, 0x90, 0x4d, 0x98, 0x64, 0x3d, 0x07, 0x7d, 0xa7, 0x4d, 0x4b, 0x80, 0xd0, 0x45, 0x01, 0xad, - 0xca, 0x6b, 0x0b, 0xa7, 0x27, 0x95, 0xcb, 0x3d, 0xf9, 0x69, 0x60, 0x89, 0xa0, 0xc9, 0x57, 0x30, - 0xde, 0xa0, 0xfe, 0x73, 0xea, 0x97, 0xa6, 0x10, 0xcf, 0x45, 0x39, 0x91, 0x58, 0xd8, 0x5c, 0xae, - 0xcd, 0x9d, 0x9e, 0x54, 0x8a, 0x01, 0x7e, 0x19, 0x38, 0x04, 0x18, 0x93, 0x36, 0x9b, 0x3e, 0xa7, - 0x7e, 0x40, 0x77, 0x8f, 0x7b, 0x3d, 0xda, 0x2d, 0x4d, 0x1b, 0xd2, 0x66, 0xd4, 0x49, 0x69, 0xf3, - 0x79, 0x61, 0x2b, 0xc4, 0x52, 0x53, 0xda, 0x0c, 0x00, 0x72, 0x00, 0x45, 0xfe, 0x57, 0xdd, 0xeb, - 0xf5, 0x68, 0x9b, 0x2d, 0xa9, 0xd2, 0x0c, 0x76, 0x70, 0x55, 0x74, 0x10, 0xaf, 0x6e, 0x2e, 0xd7, - 0x2a, 0xa7, 0x27, 0x95, 0x6b, 0x1c, 0x77, 0xab, 0xad, 0x2a, 0x8c, 0x6e, 0x12, 0x58, 0xd9, 0x38, - 0xaa, 0xed, 0x36, 0x0d, 0x02, 0x9b, 0xfe, 0xe2, 0x98, 0x06, 0x61, 0x69, 0xd6, 0x18, 0x87, 0x51, - 0xd7, 0x5c, 0xe1, 0xe3, 0x70, 0xb0, 0xb0, 0xe5, 0xf3, 0x52, 0x73, 0x1c, 0x06, 0x00, 0xd9, 0x01, - 0xa8, 0xf6, 0xfb, 0x0d, 0x1a, 0x30, 0x61, 0x2c, 0x5d, 0x44, 0xd4, 0x97, 0x05, 0xea, 0xa7, 0x74, - 0x4f, 0x54, 0x34, 0x97, 0x6b, 0x57, 0x4f, 0x4f, 0x2a, 0xf3, 0x4e, 0xbf, 0xdf, 0x0a, 0x78, 0x91, - 0x81, 0x54, 0xc3, 0xc1, 0xf9, 0x7e, 0xe4, 0x85, 0x54, 0x88, 0x62, 0xa9, 0x18, 0xe3, 0xbb, 0x56, - 0x27, 0xe9, 0xf5, 0xb1, 0xb0, 0x25, 0xc4, 0x3a, 0xce, 0x77, 0x0d, 0x80, 0xad, 0xc5, 0x55, 0x27, - 0x74, 0xf6, 0x9c, 0x80, 0x0a, 0xf1, 0xb8, 0x64, 0xac, 0x45, 0xb3, 0xb2, 0xb9, 0xc2, 0xd7, 0x62, - 0x47, 0x94, 0xb6, 0x52, 0xe4, 0x25, 0x86, 0x8f, 0x71, 0x24, 0x1a, 0x78, 0x89, 0x0c, 0xe1, 0xc8, - 0x0b, 0xba, 0x97, 0xce, 0x91, 0xa8, 0x29, 0xd9, 0x80, 0xc2, 0x53, 0xba, 0xc7, 0x35, 0xc7, 0x65, - 0xc4, 0x77, 0x29, 0xc2, 0xc7, 0x75, 0xc6, 0x0a, 0x5f, 0x15, 0x0c, 0x5b, 0x52, 0x5b, 0x28, 0x68, - 0xf2, 0x3b, 0x39, 0x58, 0x90, 0x2b, 0x9c, 0x86, 0x2f, 0x3c, 0xff, 0xd0, 0xed, 0xed, 0xd7, 0xbd, - 0xde, 0x33, 0x77, 0xbf, 0x34, 0x87, 0x98, 0x6f, 0xc4, 0x94, 0x46, 0xac, 0x55, 0x73, 0xb9, 0xf6, - 0xbd, 0xd3, 0x93, 0xca, 0x5b, 0x4a, 0x81, 0xa8, 0x7a, 0x26, 0x90, 0xcf, 0xdc, 0x7d, 0xa3, 0xe3, - 0xac, 0xbe, 0xc8, 0x5f, 0xcc, 0xc1, 0x15, 0x31, 0x3a, 0x9b, 0xb6, 0x3d, 0xbf, 0x13, 0x91, 0x31, - 0x8f, 0x64, 0x54, 0xd4, 0x6a, 0x4d, 0x6b, 0xd4, 0x5c, 0xae, 0xdd, 0x3a, 0x3d, 0xa9, 0x58, 0x82, - 0x71, 0x2d, 0x5f, 0x56, 0xa7, 0x11, 0x91, 0xd1, 0x11, 0x93, 0x04, 0xa6, 0xfc, 0x77, 0x7c, 0xfa, - 0x8c, 0xfa, 0xb4, 0xd7, 0xa6, 0xa5, 0x2b, 0x86, 0x24, 0x98, 0x95, 0x52, 0x2b, 0xb3, 0xad, 0xa4, - 0xd5, 0x57, 0xc5, 0xa6, 0x24, 0x98, 0x20, 0xe4, 0x17, 0x40, 0x04, 0x03, 0xaa, 0xc7, 0x1d, 0x37, - 0x14, 0x03, 0x5c, 0xc0, 0x5e, 0xae, 0x99, 0x7c, 0xd6, 0x1a, 0x34, 0x97, 0x6b, 0xd6, 0xe9, 0x49, - 0x65, 0x49, 0xb2, 0xd8, 0x61, 0x55, 0x69, 0x03, 0x4b, 0x41, 0xce, 0x34, 0xef, 0x96, 0xd7, 0x3e, - 0x2c, 0x95, 0x0c, 0xcd, 0xcb, 0x8a, 0xa4, 0xca, 0xee, 0x7a, 0xed, 0x43, 0x53, 0xf3, 0xb2, 0x5a, - 0x12, 0xc2, 0x65, 0x31, 0x4b, 0x36, 0x0d, 0x42, 0xdf, 0x45, 0xdd, 0x11, 0x94, 0xae, 0x22, 0x9e, - 0x45, 0xa9, 0x83, 0x93, 0x2d, 0x9a, 0x1f, 0x70, 0x6a, 0x85, 0x20, 0xb4, 0x7c, 0xad, 0xce, 0xe8, - 0x26, 0x0d, 0x3d, 0xf9, 0x73, 0x30, 0xff, 0xd4, 0xed, 0x75, 0xbc, 0x17, 0xc1, 0x2a, 0x0d, 0x0e, - 0x43, 0xaf, 0xdf, 0xe0, 0x96, 0x5f, 0xa9, 0x8c, 0xfd, 0x2e, 0x49, 0x31, 0x4f, 0x6b, 0xd3, 0x5c, - 0xa9, 0xbd, 0x73, 0x7a, 0x52, 0xb9, 0xf9, 0x82, 0x57, 0xb6, 0x3a, 0xbc, 0xb6, 0x25, 0x8c, 0x47, - 0xa3, 0xf3, 0xf4, 0x5e, 0x98, 0x08, 0x98, 0x15, 0xa5, 0x6b, 0x86, 0x08, 0x98, 0x95, 0x52, 0x19, - 0xc4, 0x3a, 0x34, 0x45, 0xc0, 0x04, 0x21, 0xeb, 0x50, 0x90, 0xea, 0xa1, 0xb4, 0x68, 0x2c, 0x5d, - 0x59, 0xdc, 0x5c, 0xe1, 0x16, 0x90, 0x54, 0x31, 0xe6, 0xca, 0x95, 0xad, 0xc8, 0x16, 0x4c, 0xa2, - 0x8e, 0x44, 0x95, 0x75, 0x1d, 0x31, 0x11, 0x29, 0xa8, 0xb2, 0xbc, 0xb9, 0x52, 0x2b, 0x9d, 0x9e, - 0x54, 0xe6, 0xb8, 0x96, 0x4d, 0x28, 0xaa, 0x08, 0x01, 0x59, 0x81, 0x91, 0x6a, 0xbf, 0x5f, 0x5a, - 0x42, 0x3c, 0xd3, 0x11, 0x9e, 0xe6, 0x4a, 0xed, 0xd2, 0xe9, 0x49, 0x65, 0xc6, 0xe9, 0x9b, 0xc3, - 0x62, 0xad, 0xc9, 0x1e, 0x14, 0x1b, 0x3d, 0xef, 0xc5, 0xb3, 0xae, 0x73, 0x48, 0xa5, 0x7a, 0xab, - 0x64, 0xab, 0x37, 0xdc, 0xac, 0x02, 0x09, 0x90, 0xaa, 0xe4, 0x12, 0xf8, 0x6a, 0x00, 0x05, 0x69, - 0xf4, 0x3d, 0x18, 0x2d, 0x4c, 0x14, 0x0b, 0xd6, 0x06, 0x8c, 0x3d, 0x75, 0xc2, 0xf6, 0x01, 0xf9, - 0x0a, 0xc6, 0x1e, 0xba, 0xbd, 0x4e, 0x50, 0xca, 0xdd, 0x18, 0x41, 0xbb, 0x80, 0x5b, 0xa4, 0x58, - 0xc9, 0x2a, 0x6a, 0x0b, 0xbf, 0x3c, 0xa9, 0x5c, 0x38, 0x3d, 0xa9, 0x5c, 0x3c, 0x64, 0xcd, 0x34, - 0xb3, 0x94, 0xc3, 0x59, 0xff, 0x3c, 0x0f, 0x93, 0xaa, 0x35, 0x59, 0x84, 0x51, 0xf6, 0x3f, 0xda, - 0xb7, 0x93, 0xb5, 0xc2, 0xe9, 0x49, 0x65, 0x94, 0xc1, 0xd9, 0x58, 0x4a, 0x96, 0x61, 0x6a, 0xcb, - 0x73, 0x3a, 0x0d, 0xda, 0xf6, 0x69, 0x18, 0xa0, 0x01, 0x5b, 0xa8, 0x15, 0x4f, 0x4f, 0x2a, 0xd3, - 0x5d, 0xcf, 0xe9, 0xb4, 0x02, 0x5e, 0x6e, 0xeb, 0x8d, 0x18, 0x46, 0xb4, 0xbe, 0x46, 0x22, 0x8c, - 0xcc, 0x4a, 0xb1, 0xb1, 0x94, 0x3c, 0x80, 0xf1, 0xfb, 0x6e, 0x97, 0xed, 0x67, 0xa3, 0x48, 0xff, - 0x62, 0x9c, 0xfe, 0x3b, 0xbc, 0x7a, 0xad, 0x17, 0xfa, 0x2f, 0xb9, 0x71, 0xf2, 0x0c, 0x0b, 0xb4, - 0x81, 0x08, 0x0c, 0xe4, 0x1e, 0x4c, 0x34, 0x8e, 0xf7, 0x90, 0xfc, 0x31, 0xec, 0x0c, 0x25, 0x28, - 0x38, 0xde, 0x6b, 0xb1, 0x21, 0x68, 0x00, 0xb2, 0x59, 0xf9, 0x53, 0x98, 0xd2, 0xd0, 0x93, 0x22, - 0x8c, 0x1c, 0xd2, 0x97, 0x7c, 0xec, 0x36, 0xfb, 0x93, 0xcc, 0xc1, 0xd8, 0x73, 0xa7, 0x7b, 0x4c, - 0x71, 0xa8, 0x93, 0x36, 0xff, 0xf8, 0x2c, 0xff, 0x49, 0xce, 0xfa, 0x4f, 0xa3, 0x50, 0xdc, 0xf0, - 0x82, 0x90, 0x59, 0xcb, 0x6a, 0xdb, 0x7f, 0x0b, 0xc6, 0x59, 0xd9, 0xe6, 0xaa, 0xe0, 0xdf, 0xd4, - 0xe9, 0x49, 0x65, 0xe2, 0xc0, 0x0b, 0xc2, 0x96, 0xdb, 0xb1, 0x45, 0x15, 0x79, 0x17, 0x0a, 0xdb, - 0x5e, 0x87, 0x22, 0x53, 0x10, 0x6d, 0x6d, 0xe6, 0xf4, 0xa4, 0x32, 0xd9, 0xf3, 0x3a, 0x14, 0x2d, - 0x4f, 0x5b, 0x55, 0x93, 0xa6, 0xb0, 0x18, 0x39, 0xef, 0x6a, 0x8c, 0x77, 0xcc, 0x44, 0xfc, 0xcd, - 0x49, 0xe5, 0xa3, 0x73, 0x1c, 0x69, 0xee, 0x34, 0x5e, 0x06, 0x21, 0x3d, 0x62, 0x98, 0x84, 0x41, - 0xf9, 0x14, 0xe6, 0xaa, 0x9d, 0x8e, 0xcb, 0x21, 0x76, 0x7c, 0xb7, 0xd7, 0x76, 0xfb, 0x4e, 0x37, - 0xc0, 0x39, 0x98, 0xac, 0xbd, 0x75, 0x7a, 0x52, 0xa9, 0x38, 0xaa, 0xbe, 0xd5, 0x57, 0x0d, 0x34, - 0x1e, 0xa6, 0x22, 0x20, 0x2b, 0x50, 0x58, 0xdd, 0x6e, 0xa0, 0xb9, 0x59, 0x1a, 0x43, 0x64, 0xb8, - 0x01, 0x77, 0x7a, 0x01, 0x0e, 0x4d, 0x47, 0xa0, 0x1a, 0x92, 0x8f, 0x60, 0x7a, 0xe7, 0x78, 0xaf, - 0xeb, 0xb6, 0x77, 0xb7, 0x1a, 0x0f, 0xe9, 0x4b, 0xb4, 0xd3, 0xa7, 0xb9, 0x5a, 0xee, 0x63, 0x79, - 0x2b, 0xec, 0x06, 0xad, 0x43, 0xfa, 0xd2, 0x36, 0xda, 0x45, 0x70, 0x8d, 0xc6, 0x06, 0x83, 0x9b, - 0x48, 0xc0, 0x05, 0xc1, 0x81, 0x0e, 0xc7, 0xdb, 0x91, 0xbb, 0x00, 0xdc, 0xfa, 0xa9, 0x76, 0x3a, - 0xdc, 0x8c, 0x9f, 0xac, 0x5d, 0x3c, 0x3d, 0xa9, 0x4c, 0x09, 0x7b, 0xc9, 0xe9, 0x74, 0x7c, 0x5b, - 0x6b, 0x42, 0xea, 0x50, 0xb0, 0x3d, 0xce, 0x60, 0x61, 0xbc, 0x5f, 0x54, 0xc6, 0x3b, 0x2f, 0x16, - 0xc7, 0x35, 0xf1, 0xa5, 0x8f, 0x52, 0xb6, 0x20, 0x15, 0x98, 0xd8, 0xf6, 0xea, 0x4e, 0xfb, 0x80, - 0x9b, 0xf0, 0x85, 0xda, 0xd8, 0xe9, 0x49, 0x25, 0xf7, 0xdb, 0xb6, 0x2c, 0xb5, 0xfe, 0x51, 0x01, - 0x8a, 0xec, 0x9c, 0x60, 0x48, 0xd4, 0xf7, 0x61, 0x92, 0xd3, 0xfe, 0x50, 0x08, 0xe6, 0x74, 0x6d, - 0xf6, 0xf4, 0xa4, 0x02, 0x62, 0x80, 0x6c, 0x70, 0x51, 0x03, 0x72, 0x1b, 0x0a, 0x0c, 0x43, 0x2f, - 0x12, 0xad, 0xe9, 0xd3, 0x93, 0x4a, 0xe1, 0x58, 0x94, 0xd9, 0xaa, 0x96, 0x34, 0x60, 0x62, 0xed, - 0xbb, 0xbe, 0xeb, 0xd3, 0x40, 0x1c, 0x17, 0xcb, 0x77, 0xb8, 0x57, 0xe0, 0x8e, 0xf4, 0x0a, 0xdc, - 0xd9, 0x95, 0x5e, 0x81, 0xda, 0x75, 0xa1, 0x42, 0x2e, 0x51, 0x0e, 0x12, 0x8d, 0xef, 0xf7, 0xfe, - 0x5b, 0x25, 0x67, 0x4b, 0x4c, 0xe4, 0xfb, 0x30, 0x7e, 0xdf, 0xf3, 0x8f, 0x9c, 0x10, 0x4f, 0x89, - 0x93, 0x62, 0xb9, 0x62, 0x89, 0xb1, 0x5c, 0xb1, 0x84, 0xdc, 0x87, 0x59, 0xdb, 0x3b, 0x0e, 0xe9, - 0xae, 0x27, 0x4d, 0x5a, 0xbe, 0x6a, 0x97, 0x4e, 0x4f, 0x2a, 0x65, 0x9f, 0xd5, 0xb4, 0x42, 0x2f, - 0x69, 0xbc, 0xda, 0x31, 0x28, 0xb2, 0x06, 0xb3, 0x86, 0xf1, 0x1d, 0x94, 0xc6, 0x51, 0xf2, 0xb8, - 0x61, 0x62, 0x98, 0xec, 0xba, 0xfc, 0xc5, 0x80, 0xc8, 0x36, 0x5c, 0x7a, 0x78, 0xbc, 0x47, 0xfd, - 0x1e, 0x0d, 0x69, 0x20, 0x29, 0x9a, 0x40, 0x8a, 0x6e, 0x9c, 0x9e, 0x54, 0x16, 0x0f, 0x55, 0x65, - 0x0a, 0x4d, 0x49, 0x50, 0x42, 0xe1, 0xa2, 0x20, 0x54, 0x6d, 0x75, 0x05, 0x61, 0xb2, 0x73, 0x15, - 0x17, 0xab, 0xad, 0xbd, 0x25, 0xb8, 0x7c, 0x4d, 0x8d, 0x3d, 0xb9, 0xf9, 0xd9, 0x71, 0x9c, 0x6c, - 0xc5, 0x29, 0x6d, 0x32, 0x89, 0xd4, 0xf2, 0x83, 0xa0, 0xd4, 0x26, 0xba, 0x2c, 0x2a, 0xbd, 0xb2, - 0x05, 0x63, 0x4f, 0x02, 0x67, 0x9f, 0x4b, 0xe2, 0xec, 0xf2, 0x4d, 0x41, 0x51, 0x5c, 0xfa, 0xd0, - 0x77, 0x80, 0x0d, 0x6b, 0x97, 0xd9, 0x0e, 0x72, 0xcc, 0xfe, 0xd4, 0x77, 0x10, 0xac, 0x23, 0x5f, - 0x03, 0x08, 0xaa, 0xd8, 0xee, 0x39, 0x25, 0xf6, 0x73, 0x63, 0x90, 0xd5, 0x7e, 0xbf, 0xb6, 0x24, - 0xc6, 0x77, 0x45, 0x8d, 0xcf, 0xd8, 0x4f, 0x6d, 0x0d, 0x09, 0xf9, 0x0a, 0xa6, 0x51, 0x5d, 0xc9, - 0x19, 0x9d, 0xc6, 0x19, 0x45, 0xf7, 0x02, 0x53, 0x80, 0x69, 0xf3, 0x69, 0x00, 0x90, 0x3f, 0x0f, - 0xf3, 0x02, 0x5d, 0xcc, 0x94, 0x99, 0x11, 0xa6, 0x9b, 0x41, 0x9e, 0xd9, 0xa6, 0xf6, 0x9e, 0xa0, - 0xd4, 0x52, 0x94, 0x66, 0x1a, 0x37, 0x76, 0x7a, 0x37, 0xd6, 0x37, 0x30, 0xa9, 0x98, 0x47, 0x26, - 0x60, 0xa4, 0xda, 0xed, 0x16, 0x2f, 0xb0, 0x3f, 0x1a, 0x8d, 0x8d, 0x62, 0x8e, 0xcc, 0x02, 0x44, - 0x12, 0x53, 0xcc, 0x93, 0xe9, 0xc8, 0x20, 0x2a, 0x8e, 0x60, 0xfb, 0x7e, 0xbf, 0x38, 0x4a, 0x48, - 0xdc, 0x12, 0x2b, 0x8e, 0x59, 0xff, 0x25, 0x97, 0x10, 0x2c, 0xb6, 0x2f, 0x0b, 0xe3, 0x0d, 0xe5, - 0x80, 0x6f, 0x3e, 0xb8, 0x2f, 0x0b, 0xb3, 0x8f, 0x6f, 0x2c, 0x7a, 0x23, 0xa6, 0x2b, 0x76, 0x18, - 0x0f, 0xda, 0x5e, 0x57, 0xd7, 0x15, 0x7d, 0x51, 0x66, 0xab, 0x5a, 0xb2, 0xac, 0x69, 0x95, 0x91, - 0x68, 0x63, 0x95, 0x5a, 0x45, 0x97, 0x30, 0xa5, 0x5f, 0x96, 0x35, 0x0b, 0x6f, 0x34, 0x82, 0x49, - 0x91, 0x68, 0xd5, 0xce, 0x3a, 0xce, 0x98, 0x33, 0xf2, 0x79, 0xc2, 0x20, 0xe5, 0x23, 0x44, 0xa1, - 0x8c, 0x4d, 0x4d, 0xc2, 0xd6, 0xac, 0xc0, 0xd8, 0x96, 0xb7, 0xef, 0xf6, 0xc4, 0x20, 0x27, 0x4f, - 0x4f, 0x2a, 0x63, 0x5d, 0x56, 0x60, 0xf3, 0x72, 0xeb, 0xff, 0xe6, 0x74, 0xf9, 0x55, 0xf6, 0x4a, - 0x2e, 0xd5, 0x5e, 0xf9, 0x3e, 0x4c, 0x0a, 0xa3, 0x6c, 0x73, 0x55, 0x60, 0x44, 0x7d, 0x2c, 0xcf, - 0x5c, 0x6e, 0xc7, 0x8e, 0x1a, 0xb0, 0x9d, 0x86, 0x2b, 0x67, 0xdc, 0x69, 0x46, 0xa2, 0x9d, 0x46, - 0xa8, 0x6f, 0xbe, 0xd3, 0x44, 0x4d, 0xd8, 0x44, 0xea, 0x1e, 0xab, 0xd1, 0x68, 0x22, 0x75, 0xdf, - 0x94, 0xe9, 0x8f, 0xfa, 0x0c, 0xa0, 0xfa, 0xb4, 0xc1, 0xa4, 0xbf, 0x6a, 0x6f, 0x0b, 0x1d, 0x8a, - 0xee, 0x2c, 0xe7, 0x45, 0xd0, 0xc2, 0xd5, 0xe2, 0xf8, 0xfa, 0x96, 0xa4, 0xb5, 0xb6, 0xba, 0x30, - 0xbb, 0x4e, 0x43, 0x36, 0x6b, 0x72, 0xc3, 0x19, 0x3c, 0xfc, 0x2f, 0x60, 0xea, 0xa9, 0x1b, 0x1e, - 0x98, 0x06, 0x20, 0x76, 0xf6, 0xc2, 0x0d, 0x0f, 0xa4, 0x01, 0xa8, 0x75, 0xa6, 0x37, 0xb7, 0xd6, - 0xe0, 0xa2, 0xe8, 0x4d, 0xed, 0x6f, 0xcb, 0x26, 0xc2, 0x5c, 0x64, 0x51, 0xea, 0x08, 0x4d, 0x34, - 0x34, 0xae, 0xf0, 0x49, 0x23, 0xb1, 0x05, 0x70, 0x6b, 0x38, 0xcb, 0x9b, 0x83, 0x82, 0x13, 0xdb, - 0x1a, 0xe2, 0x1b, 0x82, 0xf5, 0x04, 0x66, 0x76, 0xba, 0xc7, 0xfb, 0x6e, 0x8f, 0x09, 0x68, 0x83, - 0xfe, 0x82, 0xac, 0x02, 0x44, 0x05, 0xa2, 0x07, 0x69, 0xe3, 0x47, 0x15, 0xcd, 0x15, 0x31, 0xc5, - 0x58, 0x82, 0x3a, 0xdc, 0xd6, 0xe0, 0xac, 0xbf, 0x31, 0x02, 0x44, 0xf4, 0xd1, 0x08, 0x9d, 0x90, - 0x36, 0x68, 0xc8, 0xb6, 0x8b, 0x2b, 0x90, 0x57, 0x66, 0xe3, 0xf8, 0xe9, 0x49, 0x25, 0xef, 0x76, - 0xec, 0xfc, 0xe6, 0x2a, 0xf9, 0x00, 0xc6, 0xb0, 0x19, 0xf2, 0x7a, 0x56, 0xf5, 0xa7, 0x63, 0xe0, - 0x32, 0x1d, 0xb0, 0x3f, 0x6d, 0xde, 0x98, 0x7c, 0x08, 0x93, 0xab, 0xb4, 0x4b, 0xf7, 0x9d, 0xd0, - 0x93, 0x72, 0xc7, 0x0d, 0x31, 0x59, 0xa8, 0x4d, 0x51, 0xd4, 0x92, 0x6d, 0xe0, 0x36, 0x75, 0x02, - 0xaf, 0xa7, 0x6f, 0xe0, 0x3e, 0x96, 0xe8, 0x1b, 0x38, 0x6f, 0x43, 0x7e, 0x3f, 0x07, 0x53, 0xd5, - 0x5e, 0x4f, 0x18, 0x38, 0x81, 0x70, 0xdf, 0xce, 0xdf, 0x51, 0xde, 0xf7, 0x2d, 0x67, 0x8f, 0x76, - 0x9b, 0xcc, 0x64, 0x0e, 0x6a, 0xdf, 0x32, 0x9d, 0xfa, 0x5f, 0x4f, 0x2a, 0x9f, 0xbf, 0x8a, 0x43, - 0xff, 0xce, 0xae, 0xef, 0xb8, 0x61, 0x80, 0xbe, 0xb2, 0xa8, 0x43, 0x5d, 0xcc, 0x34, 0x3a, 0xc8, - 0xbb, 0x30, 0xc6, 0xe4, 0x5b, 0xda, 0x01, 0x38, 0xd9, 0x6c, 0x1d, 0x18, 0x87, 0x1f, 0x6c, 0x61, - 0xbd, 0x05, 0x93, 0x82, 0x93, 0x9b, 0xab, 0x59, 0x53, 0x60, 0xad, 0xc2, 0x75, 0xb4, 0xe2, 0x28, - 0x93, 0x5c, 0xf4, 0x18, 0x09, 0x49, 0x8c, 0xcc, 0xfe, 0x09, 0x2c, 0x56, 0xd0, 0x38, 0x21, 0xe8, - 0x71, 0xb2, 0x65, 0x8d, 0x55, 0x87, 0xc5, 0x75, 0x1a, 0xda, 0x34, 0xa0, 0xe1, 0x8e, 0x13, 0x04, - 0x2f, 0x3c, 0xbf, 0x83, 0x55, 0xe7, 0x42, 0xf2, 0x57, 0x72, 0x50, 0xa9, 0xfb, 0x94, 0xcd, 0x74, - 0x26, 0xa2, 0xc1, 0x2b, 0x78, 0x51, 0x5c, 0x60, 0xe4, 0xa3, 0x5a, 0xc6, 0x6b, 0x71, 0x49, 0xf1, - 0x0e, 0x8c, 0xec, 0xee, 0x6e, 0xa1, 0xc4, 0x8c, 0x20, 0xe3, 0x46, 0xc2, 0xb0, 0xfb, 0x9b, 0x93, - 0x4a, 0x61, 0xf5, 0x98, 0x5f, 0x70, 0xd8, 0xac, 0xde, 0x7a, 0x06, 0xf3, 0x36, 0xed, 0xd1, 0x17, - 0xce, 0x5e, 0x97, 0x1a, 0xe6, 0x6a, 0x05, 0xc6, 0xb8, 0x43, 0x2e, 0x31, 0x04, 0x5e, 0x6e, 0xda, - 0xb3, 0xf9, 0x21, 0xf6, 0xac, 0xf5, 0x87, 0x39, 0x28, 0xf2, 0xe1, 0xd6, 0xbc, 0xf0, 0x6c, 0xe3, - 0x13, 0x23, 0xc8, 0x0f, 0x1e, 0x01, 0xb9, 0x15, 0x71, 0x7b, 0x24, 0xda, 0xfc, 0x90, 0x54, 0xa6, - 0xc3, 0x65, 0x25, 0x1b, 0x10, 0x97, 0x25, 0x7e, 0x34, 0xc2, 0x01, 0xa1, 0x2c, 0x49, 0x09, 0xfa, - 0x27, 0x79, 0xb8, 0xa4, 0x91, 0x18, 0xf4, 0xbd, 0x5e, 0x40, 0xd9, 0x19, 0x8f, 0x09, 0x8b, 0x46, - 0x27, 0x9e, 0xf1, 0xd8, 0x96, 0xd9, 0x8a, 0x2c, 0x71, 0x24, 0xf8, 0x5d, 0x76, 0xb8, 0xe8, 0x26, - 0x8e, 0x83, 0xa8, 0xb8, 0x79, 0x53, 0x59, 0x7d, 0x66, 0xa2, 0xef, 0x42, 0x01, 0xff, 0x64, 0x8c, - 0x18, 0xcd, 0x66, 0x84, 0x6a, 0x44, 0x5c, 0x80, 0x07, 0x9e, 0xdb, 0x7b, 0x44, 0xc3, 0x03, 0x4f, - 0x1e, 0x9e, 0x37, 0x99, 0x12, 0xfb, 0x33, 0x9e, 0xdb, 0x6b, 0x1d, 0x61, 0xf1, 0x79, 0x0f, 0x9d, - 0x11, 0x42, 0x5b, 0x43, 0x6e, 0xdd, 0x83, 0x22, 0xd3, 0x37, 0x67, 0x9f, 0x51, 0x6b, 0x0e, 0xc8, - 0x3a, 0x0d, 0x6b, 0x9e, 0xb1, 0x71, 0x58, 0x33, 0x30, 0xb5, 0xe3, 0xf6, 0xf6, 0xe5, 0xe7, 0xbf, - 0xc8, 0xc3, 0x34, 0xff, 0x16, 0x33, 0x10, 0xdb, 0x49, 0x73, 0x67, 0xd9, 0x49, 0x3f, 0x81, 0x19, - 0xe1, 0x32, 0xa2, 0x3e, 0xfa, 0x71, 0xf8, 0x7c, 0xe0, 0x89, 0x92, 0x7b, 0x8e, 0x5a, 0xcf, 0x79, - 0x8d, 0x6d, 0x36, 0x24, 0x5b, 0x30, 0xcb, 0x0b, 0xee, 0x53, 0x27, 0x3c, 0x8e, 0x4e, 0x55, 0x17, - 0x85, 0x9d, 0x29, 0x8b, 0xb9, 0x32, 0x12, 0xb8, 0x9e, 0x89, 0x42, 0x3b, 0x06, 0x4b, 0xbe, 0x82, - 0x8b, 0x3b, 0xbe, 0xf7, 0xdd, 0x4b, 0xcd, 0x76, 0xe0, 0xfa, 0x78, 0x9e, 0x1d, 0xc2, 0xfa, 0xac, - 0xaa, 0xa5, 0x5b, 0x10, 0xf1, 0xd6, 0x4c, 0xa6, 0x36, 0x83, 0x9a, 0xe7, 0xbb, 0xbd, 0x7d, 0x9c, - 0xcd, 0x02, 0x97, 0x29, 0x37, 0x68, 0xed, 0x61, 0xa1, 0xad, 0xaa, 0xad, 0xff, 0x31, 0x02, 0x05, - 0xd5, 0xf1, 0x1d, 0xdd, 0x2c, 0x15, 0x9b, 0x31, 0x2e, 0xcf, 0xe8, 0xf0, 0x63, 0x6b, 0x2d, 0xc8, - 0x55, 0xee, 0x30, 0xe3, 0x66, 0xc0, 0x04, 0x93, 0x31, 0xa7, 0xdf, 0xe7, 0x6e, 0xb1, 0x2b, 0x90, - 0x5f, 0xad, 0x21, 0x17, 0x0a, 0x5c, 0x99, 0x76, 0xf6, 0xec, 0xfc, 0x6a, 0x8d, 0xcd, 0xf5, 0xe3, - 0xcd, 0xd5, 0x3a, 0x0e, 0xa8, 0xc0, 0xe7, 0xda, 0x73, 0x3b, 0x6d, 0x1b, 0x4b, 0x59, 0x6d, 0xa3, - 0xfa, 0x68, 0x4b, 0x10, 0x8d, 0xb5, 0x81, 0x73, 0xd4, 0xb5, 0xb1, 0x94, 0xd9, 0x81, 0x7c, 0x8f, - 0xae, 0x7b, 0xbd, 0xd0, 0xf7, 0xba, 0x01, 0xba, 0x0a, 0x0a, 0xc6, 0x76, 0xde, 0x16, 0x55, 0x76, - 0xac, 0x29, 0x79, 0x0a, 0x0b, 0xd5, 0xce, 0x73, 0xa7, 0xd7, 0xa6, 0x1d, 0x5e, 0xf3, 0xd4, 0xf3, - 0x0f, 0x9f, 0x75, 0xbd, 0x17, 0x01, 0x9e, 0xf2, 0x0a, 0xe2, 0xbc, 0x28, 0x9a, 0xb4, 0x04, 0xba, - 0x17, 0xb2, 0x91, 0x9d, 0x05, 0xcd, 0x54, 0x44, 0xbd, 0xeb, 0x1d, 0x77, 0xf0, 0x78, 0x57, 0xe0, - 0x2a, 0xa2, 0xcd, 0x0a, 0x6c, 0x5e, 0xce, 0xb8, 0xb4, 0xd1, 0x78, 0x84, 0xa7, 0x33, 0xc1, 0xa5, - 0x83, 0xe0, 0xc8, 0x66, 0x65, 0xe4, 0x1d, 0x98, 0x90, 0x26, 0x2d, 0x77, 0x0a, 0xa0, 0xc7, 0x48, - 0x9a, 0xb2, 0xb2, 0x8e, 0xac, 0xc2, 0xa5, 0x47, 0x5e, 0x87, 0xfa, 0x4e, 0x48, 0x3b, 0xc2, 0xba, - 0x0c, 0xf0, 0xa0, 0x55, 0xe0, 0x66, 0xf5, 0x91, 0xac, 0x94, 0xfe, 0xc4, 0xc0, 0x4e, 0x02, 0x58, - 0xef, 0xc3, 0x25, 0xbe, 0xf4, 0xce, 0x6c, 0xef, 0x59, 0x3b, 0x00, 0x0d, 0x7a, 0xe4, 0xf4, 0x0f, - 0x3c, 0x26, 0x1e, 0x35, 0xfd, 0x4b, 0x18, 0x40, 0x44, 0x5d, 0x49, 0x88, 0x8a, 0xe6, 0x8a, 0xb4, - 0x88, 0x65, 0x4b, 0x5b, 0x83, 0xb2, 0xfe, 0x63, 0x1e, 0x08, 0xba, 0xe6, 0x1b, 0xa1, 0x4f, 0x9d, - 0x23, 0x49, 0xc6, 0xa7, 0x30, 0xcd, 0xb5, 0x28, 0x2f, 0x46, 0x72, 0x98, 0x75, 0xc5, 0x97, 0x8f, - 0x5e, 0xb5, 0x71, 0xc1, 0x36, 0x9a, 0x32, 0x50, 0x9b, 0x06, 0xc7, 0x47, 0x12, 0x34, 0x6f, 0x80, - 0xea, 0x55, 0x0c, 0x54, 0xff, 0x26, 0x5f, 0xc1, 0x6c, 0xdd, 0x3b, 0xea, 0x33, 0x9e, 0x08, 0xe0, - 0x11, 0x61, 0xc3, 0x88, 0x7e, 0x8d, 0xca, 0x8d, 0x0b, 0x76, 0xac, 0x39, 0xd9, 0x86, 0xcb, 0xf7, - 0xbb, 0xc7, 0xc1, 0x41, 0xb5, 0xd7, 0xa9, 0x77, 0xbd, 0x40, 0x62, 0x19, 0x15, 0x2e, 0x15, 0xb1, - 0xf8, 0x93, 0x2d, 0x36, 0x2e, 0xd8, 0x69, 0x80, 0xe4, 0x1d, 0x11, 0x67, 0x20, 0x6c, 0xa9, 0x99, - 0x3b, 0x22, 0x0c, 0xe1, 0x71, 0x8f, 0x3e, 0x7e, 0xb6, 0x71, 0xc1, 0xe6, 0xb5, 0xb5, 0x49, 0x98, - 0x90, 0x8a, 0xef, 0x2e, 0x5c, 0xd2, 0xd8, 0xc9, 0xac, 0xbf, 0xe3, 0x80, 0x94, 0xa1, 0xf0, 0xa4, - 0xdf, 0xf5, 0x9c, 0x8e, 0x34, 0x26, 0x6c, 0xf5, 0x6d, 0x7d, 0xdf, 0xe4, 0x34, 0x59, 0xd4, 0x4f, - 0x34, 0xbc, 0x71, 0x54, 0x60, 0x6d, 0x98, 0xcc, 0x1d, 0xdc, 0xda, 0xe8, 0x37, 0x1f, 0xeb, 0xb7, - 0x18, 0xe7, 0xb5, 0x35, 0x9f, 0xca, 0x3c, 0xeb, 0x21, 0x1a, 0x4a, 0xd5, 0x7e, 0xbf, 0xeb, 0xb6, - 0x71, 0x7f, 0xe1, 0xda, 0x51, 0xd9, 0x18, 0xbf, 0xa5, 0xdf, 0x86, 0x6b, 0x9b, 0xab, 0xba, 0xfb, - 0xd6, 0xee, 0xbb, 0xad, 0x1f, 0xc3, 0xf5, 0x0c, 0x64, 0x62, 0x9f, 0xf8, 0x14, 0x26, 0x44, 0x51, - 0x4c, 0xa0, 0xf5, 0xfb, 0x03, 0x5c, 0x95, 0x81, 0x80, 0x94, 0xed, 0xad, 0x6f, 0x60, 0xe9, 0x49, - 0x3f, 0xa0, 0x7e, 0x12, 0xbd, 0x24, 0xf5, 0x23, 0x75, 0xdb, 0x9e, 0xcb, 0xbc, 0x9b, 0x80, 0xd3, - 0x93, 0xca, 0x38, 0xc7, 0x2d, 0x2f, 0xd9, 0xad, 0xdf, 0xcb, 0xc1, 0x12, 0x5f, 0xaa, 0x99, 0xa8, - 0xcf, 0xc3, 0x05, 0xcd, 0x2f, 0x9d, 0xcf, 0xf6, 0x4b, 0x0f, 0x74, 0xd4, 0x5b, 0x5f, 0x83, 0x25, - 0x28, 0xea, 0x76, 0xdf, 0xd0, 0xdc, 0xfc, 0xa5, 0x1c, 0xcc, 0xf1, 0xc9, 0x79, 0x0d, 0x2c, 0xe4, - 0x07, 0x30, 0xdb, 0x38, 0x74, 0xfb, 0x4d, 0xa7, 0xeb, 0x76, 0xb8, 0x8b, 0x96, 0x6f, 0x47, 0xf3, - 0xb8, 0xd3, 0x1e, 0xba, 0xfd, 0xd6, 0xf3, 0xa8, 0x2a, 0x67, 0xc7, 0x1a, 0x5b, 0x8f, 0x61, 0x3e, - 0x46, 0x83, 0x10, 0x8c, 0x8f, 0xe2, 0x82, 0x91, 0x08, 0x95, 0x48, 0x97, 0x8a, 0x47, 0x70, 0x45, - 0x49, 0x85, 0x39, 0x65, 0x2b, 0x31, 0x69, 0x48, 0x20, 0x4c, 0x13, 0x85, 0x36, 0x5c, 0x51, 0x92, - 0xf0, 0x1a, 0x12, 0x20, 0x27, 0x37, 0x9f, 0x3a, 0xb9, 0x9b, 0x50, 0xd6, 0x27, 0xf7, 0x75, 0x26, - 0xf5, 0x3f, 0xe4, 0x60, 0x61, 0x9d, 0xf6, 0x70, 0xeb, 0xa9, 0xf6, 0xfb, 0xc6, 0xc9, 0x44, 0x77, - 0x4f, 0xe7, 0x06, 0xba, 0xa7, 0x95, 0xd9, 0x9d, 0x4f, 0x37, 0xbb, 0xd9, 0x9e, 0xfa, 0xc4, 0xde, - 0x14, 0xb2, 0x8a, 0x7b, 0xea, 0xb1, 0xef, 0xda, 0xac, 0x8c, 0x6c, 0x46, 0xae, 0xed, 0xd1, 0xa1, - 0xae, 0xed, 0xcb, 0xc2, 0xd5, 0x37, 0x21, 0x5c, 0xdb, 0x86, 0x43, 0xdb, 0xfa, 0x1c, 0x4a, 0xc9, - 0xb1, 0x08, 0xf9, 0x18, 0x76, 0xd4, 0xb1, 0x56, 0x23, 0xe9, 0x16, 0x37, 0xed, 0xca, 0xa5, 0x1f, - 0x53, 0xa1, 0x03, 0x5c, 0x48, 0x56, 0x23, 0x92, 0x4f, 0x81, 0x45, 0xf4, 0xff, 0x19, 0x93, 0x4f, - 0x7e, 0xdd, 0x98, 0xcb, 0xbe, 0x6e, 0x14, 0x32, 0xca, 0x41, 0x25, 0x80, 0xf5, 0x14, 0xae, 0x18, - 0x48, 0x23, 0xa9, 0xff, 0x01, 0x14, 0x94, 0x81, 0x61, 0x7a, 0x38, 0x0c, 0xb4, 0x38, 0x6f, 0xca, - 0xd6, 0x50, 0x20, 0xd6, 0x4f, 0x51, 0x77, 0xc7, 0xef, 0x2f, 0xdf, 0x18, 0xfa, 0x5f, 0xe5, 0x60, - 0x81, 0x6f, 0x5e, 0x49, 0xb6, 0x9e, 0x5d, 0xb8, 0xfe, 0x44, 0xbc, 0x72, 0xf7, 0x52, 0xbc, 0x72, - 0x08, 0xa2, 0x7b, 0xe5, 0x74, 0x5f, 0xdc, 0x83, 0xd1, 0x42, 0xbe, 0x38, 0x62, 0x35, 0xa1, 0x94, - 0x1c, 0xe1, 0x1b, 0x98, 0xf2, 0x7f, 0x99, 0x83, 0xeb, 0x62, 0xdf, 0x8f, 0xcd, 0xce, 0xf9, 0x19, - 0xf8, 0x21, 0x4c, 0x0b, 0x58, 0xbe, 0x02, 0xb8, 0x52, 0xc1, 0x2b, 0x72, 0x29, 0xc4, 0x7c, 0x25, - 0x18, 0xcd, 0xc8, 0x87, 0xda, 0xb1, 0x94, 0x7b, 0x18, 0xae, 0x32, 0x35, 0xc2, 0xcf, 0xaf, 0x99, - 0x87, 0x53, 0xeb, 0x5b, 0x58, 0xca, 0x22, 0xfc, 0x0d, 0xf0, 0xe5, 0x01, 0x94, 0x53, 0x24, 0xf6, - 0xd5, 0xd6, 0xea, 0x8f, 0xe0, 0x5a, 0x2a, 0xae, 0x37, 0x40, 0xe6, 0x3a, 0x2c, 0x68, 0xdb, 0xc0, - 0x6b, 0xd0, 0xf8, 0x08, 0xae, 0x73, 0x44, 0x6f, 0x66, 0xc8, 0x1b, 0xb0, 0x18, 0x9d, 0x29, 0x0c, - 0x85, 0x72, 0x4e, 0xa1, 0x12, 0x8a, 0x2e, 0x62, 0xc5, 0x1b, 0x54, 0x74, 0x51, 0xc3, 0x37, 0xa6, - 0x89, 0x36, 0xe1, 0x32, 0x47, 0x6c, 0x6e, 0x0a, 0xcb, 0xfa, 0xa6, 0x90, 0x1a, 0x90, 0x96, 0xdc, - 0x27, 0x1e, 0xe1, 0x3e, 0x21, 0x9b, 0x44, 0x14, 0x7e, 0x08, 0xe3, 0x22, 0xe6, 0x96, 0xd3, 0x97, - 0x82, 0x0c, 0x0d, 0x06, 0x1e, 0x68, 0x6b, 0x8b, 0xc6, 0x56, 0x09, 0x87, 0xcc, 0x0e, 0xe9, 0xe2, - 0xb6, 0x47, 0xb9, 0x4c, 0xbe, 0x66, 0x3b, 0x73, 0xac, 0xe6, 0x35, 0x8d, 0x9d, 0xc7, 0x50, 0xe2, - 0xc6, 0x8e, 0x86, 0xf5, 0xb5, 0xcc, 0x9d, 0x4f, 0xa0, 0xc4, 0xe5, 0x29, 0x05, 0xe1, 0x60, 0x1b, - 0x66, 0x49, 0x4a, 0x62, 0xb5, 0xdb, 0x4d, 0x1b, 0xfd, 0x5f, 0xcb, 0xc1, 0xd5, 0x75, 0x1a, 0x9a, - 0x61, 0x89, 0x7f, 0x2a, 0x26, 0xe7, 0xb7, 0xa8, 0x72, 0x12, 0x84, 0x88, 0xa9, 0xf8, 0x32, 0x3e, - 0x15, 0x99, 0x31, 0x98, 0xe9, 0x53, 0xf2, 0x63, 0xb8, 0xc6, 0xa7, 0xc4, 0x6c, 0x2f, 0x07, 0xfa, - 0x79, 0x6c, 0x56, 0x32, 0xb1, 0xa7, 0xcd, 0xce, 0xdf, 0xcc, 0xc1, 0x35, 0xce, 0xe4, 0x74, 0xe4, - 0x7f, 0xd2, 0x87, 0x92, 0x6d, 0xa8, 0xa8, 0x39, 0x7f, 0x03, 0x13, 0x6b, 0xfd, 0xd3, 0x1c, 0x10, - 0x89, 0xa7, 0xde, 0xb0, 0x25, 0x8e, 0xab, 0x30, 0x52, 0x6f, 0xd8, 0x22, 0xfc, 0x02, 0x8d, 0xcd, - 0x76, 0xe0, 0xdb, 0xac, 0x2c, 0x6e, 0x1a, 0xe4, 0xcf, 0x62, 0x1a, 0x6c, 0x02, 0x69, 0xb8, 0xfb, - 0xbd, 0xa7, 0x6e, 0x78, 0xa0, 0x3a, 0xab, 0x0a, 0x57, 0x19, 0x46, 0xbf, 0x06, 0xee, 0x7e, 0xaf, - 0x85, 0xf7, 0x5f, 0x2a, 0xc2, 0xb6, 0xed, 0xd8, 0x29, 0x40, 0xd6, 0x4f, 0xe0, 0xb2, 0x41, 0xaf, - 0x90, 0xa1, 0x45, 0x18, 0xad, 0x53, 0x3f, 0x14, 0x14, 0x23, 0xd7, 0xda, 0xd4, 0x0f, 0x6d, 0x2c, - 0x25, 0xb7, 0x60, 0xa2, 0x5e, 0x45, 0xb7, 0x3d, 0x9a, 0xd7, 0xd3, 0x5c, 0xc9, 0xb5, 0x9d, 0x16, - 0x3e, 0xfb, 0xb0, 0x65, 0xa5, 0xf5, 0x6f, 0xf3, 0x1a, 0x76, 0x06, 0x3e, 0x9c, 0x1d, 0xef, 0x03, - 0x70, 0xfe, 0x6b, 0xdc, 0x60, 0x76, 0xc1, 0x94, 0x70, 0x79, 0xf2, 0x7d, 0xc0, 0xd6, 0x1a, 0x9d, - 0xf1, 0xca, 0x41, 0x5e, 0x71, 0x73, 0x20, 0xe9, 0x8e, 0x57, 0x57, 0xdc, 0x02, 0x75, 0x60, 0xeb, - 0x8d, 0xc8, 0xcf, 0x60, 0x46, 0xd0, 0x2c, 0x08, 0x1a, 0xc3, 0x3b, 0xb4, 0xb7, 0x85, 0x5f, 0x26, - 0x65, 0x6c, 0x77, 0x54, 0x7b, 0x11, 0x90, 0x2f, 0x3f, 0xf9, 0x34, 0x9a, 0xe8, 0xac, 0x5b, 0xea, - 0xf6, 0x88, 0xfa, 0xe4, 0x22, 0x4c, 0x3d, 0xd9, 0x6e, 0xec, 0xac, 0xd5, 0x37, 0xef, 0x6f, 0xae, - 0xad, 0x16, 0x2f, 0x90, 0x02, 0x8c, 0xee, 0xd6, 0x77, 0xb7, 0x8a, 0x39, 0xeb, 0x5b, 0x98, 0x33, - 0xfb, 0x7a, 0xa3, 0xd3, 0x14, 0xc2, 0x65, 0xb5, 0x97, 0x3f, 0x78, 0xba, 0xab, 0xdd, 0xac, 0x56, - 0xdb, 0x6d, 0xef, 0xb8, 0x17, 0xc6, 0x1d, 0xe0, 0x0e, 0x2f, 0x16, 0x92, 0xa9, 0x35, 0x32, 0xae, - 0x2d, 0xf2, 0x03, 0xaf, 0x2d, 0xac, 0x8f, 0x61, 0xce, 0xec, 0xf5, 0xac, 0xc7, 0xa2, 0xb7, 0xf1, - 0xca, 0x59, 0x0b, 0xd6, 0x20, 0x44, 0x77, 0x41, 0x8a, 0x95, 0xfd, 0x31, 0x14, 0x45, 0xab, 0x48, - 0x33, 0xbe, 0x25, 0x0f, 0x85, 0x5c, 0x2f, 0x9a, 0x0f, 0x28, 0xe4, 0x7d, 0xcc, 0xf7, 0xa4, 0x93, - 0x73, 0x58, 0x0f, 0x7f, 0x27, 0x07, 0xa5, 0x47, 0xf7, 0xab, 0xd5, 0xe3, 0xf0, 0x80, 0xf6, 0x42, - 0xb7, 0xed, 0x84, 0xb4, 0x7e, 0xe0, 0x74, 0xbb, 0xb4, 0xb7, 0x4f, 0xc9, 0x6d, 0x18, 0xdd, 0x7d, - 0xbc, 0xbb, 0x23, 0x7c, 0x89, 0x73, 0x42, 0x60, 0x58, 0x91, 0x6a, 0x63, 0x63, 0x0b, 0xf2, 0x10, - 0x2e, 0x3d, 0x15, 0x4f, 0x96, 0x54, 0x95, 0xf0, 0x22, 0x5e, 0xbf, 0xa3, 0x1e, 0x33, 0xd5, 0x7d, - 0xda, 0x61, 0xbd, 0x38, 0xdd, 0x6a, 0xc0, 0x74, 0x33, 0x13, 0xeb, 0x24, 0xdc, 0x83, 0xd1, 0x42, - 0xae, 0x98, 0xb7, 0x7e, 0x3f, 0x07, 0x0b, 0x31, 0xca, 0xb4, 0x8b, 0x25, 0x9d, 0xb0, 0xcb, 0x1a, - 0x61, 0xb2, 0xc9, 0xc6, 0x05, 0x41, 0x59, 0x1d, 0xe3, 0xe3, 0xb1, 0x07, 0x41, 0xd0, 0x3b, 0x83, - 0x09, 0x8a, 0x10, 0x28, 0x40, 0x11, 0x79, 0x8a, 0xe5, 0xd6, 0x45, 0x98, 0x31, 0x38, 0x60, 0x59, - 0x30, 0xad, 0xf7, 0xcc, 0xd8, 0x5c, 0xf7, 0x3a, 0x8a, 0xcd, 0xec, 0x6f, 0xeb, 0x6f, 0xe5, 0x60, - 0xee, 0xd1, 0xfd, 0xaa, 0x4d, 0xf7, 0x5d, 0xb6, 0x4c, 0x22, 0x16, 0x2f, 0x1b, 0x23, 0x59, 0x34, - 0x46, 0x12, 0x6b, 0xab, 0x86, 0xf4, 0x59, 0x62, 0x48, 0x8b, 0x69, 0x43, 0xc2, 0xe3, 0x82, 0xeb, - 0xf5, 0x8c, 0x91, 0x68, 0x3e, 0xd3, 0xbf, 0x9b, 0x83, 0xcb, 0x1a, 0x4d, 0x8a, 0xfe, 0xf7, 0x0d, - 0x92, 0xae, 0xa5, 0x90, 0x94, 0x60, 0x72, 0x2d, 0x41, 0xd1, 0xdb, 0x83, 0x28, 0x1a, 0xca, 0xe3, - 0x3f, 0xce, 0xc1, 0x7c, 0x2a, 0x0f, 0xc8, 0x15, 0xb6, 0x71, 0xb7, 0x7d, 0x1a, 0x0a, 0xf6, 0x8a, - 0x2f, 0x56, 0xbe, 0x19, 0x04, 0xc7, 0xe2, 0x3d, 0xd9, 0xa4, 0x2d, 0xbe, 0xc8, 0xdb, 0x30, 0xb3, - 0x43, 0x7d, 0xd7, 0xeb, 0x34, 0x68, 0xdb, 0xeb, 0x75, 0xf8, 0x8d, 0xd4, 0x8c, 0x6d, 0x16, 0x92, - 0x45, 0x98, 0xac, 0x76, 0xf7, 0x3d, 0xdf, 0x0d, 0x0f, 0xb8, 0xdb, 0x7a, 0xd2, 0x8e, 0x0a, 0x18, - 0xee, 0x55, 0x77, 0xdf, 0x0d, 0xf9, 0xdd, 0xfe, 0x8c, 0x2d, 0xbe, 0x48, 0x09, 0x26, 0x84, 0xda, - 0xc0, 0x1b, 0x98, 0x49, 0x5b, 0x7e, 0x32, 0x88, 0xaf, 0x6d, 0x14, 0x02, 0x8c, 0xc6, 0xb4, 0xc5, - 0x97, 0xf5, 0x1e, 0xcc, 0xa5, 0xf1, 0x31, 0x55, 0x64, 0xfe, 0x42, 0x1e, 0x2e, 0x57, 0x3b, 0x9d, - 0x47, 0xf7, 0xab, 0xab, 0x54, 0xb7, 0xff, 0x3e, 0x80, 0xd1, 0xcd, 0x9e, 0x1b, 0x0a, 0xc3, 0x65, - 0x49, 0x4c, 0x4f, 0x4a, 0x4b, 0xd6, 0x8a, 0xcd, 0x10, 0xfb, 0x9f, 0xd8, 0x70, 0x79, 0xed, 0x3b, - 0x37, 0x08, 0xdd, 0xde, 0x3e, 0xce, 0x39, 0xef, 0x58, 0xcc, 0xb1, 0x44, 0x92, 0xb1, 0xdc, 0x36, - 0x2e, 0xd8, 0x69, 0xc0, 0x64, 0x17, 0xae, 0x6c, 0xd3, 0x17, 0x29, 0x22, 0xa4, 0x82, 0x29, 0x15, - 0xda, 0x14, 0xc9, 0xc9, 0x80, 0xd5, 0x25, 0xf4, 0xaf, 0xe6, 0x31, 0x42, 0x57, 0x1b, 0x98, 0xe8, - 0xf9, 0x09, 0xcc, 0x69, 0x04, 0x45, 0x1a, 0x27, 0x27, 0xde, 0x87, 0xa4, 0x0e, 0x47, 0x5f, 0x48, - 0xa9, 0xe0, 0xe4, 0x29, 0x2c, 0x98, 0x44, 0x45, 0x98, 0xcd, 0xc5, 0x90, 0xd6, 0x64, 0xe3, 0x82, - 0x9d, 0x05, 0x4d, 0x96, 0x61, 0xa4, 0xda, 0x3e, 0x14, 0x6c, 0x49, 0x9f, 0x32, 0x3e, 0xb2, 0x6a, - 0xfb, 0x10, 0x23, 0xea, 0xdb, 0x87, 0xc6, 0x7a, 0xf8, 0x37, 0x39, 0x58, 0xc8, 0x98, 0x61, 0xb2, - 0x04, 0xc0, 0x0b, 0x35, 0xdd, 0xae, 0x95, 0x30, 0x63, 0x84, 0x7f, 0x61, 0xc0, 0xc3, 0x08, 0xee, - 0xfd, 0x32, 0x2e, 0x31, 0xaa, 0xb0, 0xb5, 0x46, 0x64, 0x07, 0xa6, 0xf8, 0x17, 0x0f, 0x8f, 0x1c, - 0x45, 0x18, 0x62, 0xc0, 0xf0, 0x78, 0x48, 0x8c, 0x79, 0xea, 0x60, 0x41, 0x2b, 0x1e, 0x16, 0xa9, - 0xa3, 0x10, 0x5e, 0x9d, 0x7a, 0x7c, 0x14, 0x6a, 0xd0, 0xe4, 0x36, 0x8c, 0xf3, 0x42, 0x31, 0x87, - 0xf2, 0x65, 0x5f, 0xd4, 0x58, 0xd4, 0x5b, 0x7f, 0x98, 0x93, 0xbe, 0xe0, 0xc4, 0xd2, 0xf8, 0xd8, - 0x58, 0x1a, 0x37, 0x15, 0xc1, 0x69, 0x8d, 0x8d, 0xd5, 0x51, 0x83, 0xa9, 0x57, 0x59, 0x15, 0x3a, - 0x90, 0x2e, 0xb7, 0xff, 0x30, 0x27, 0xfd, 0x14, 0x49, 0xd1, 0x5d, 0x83, 0xe9, 0x57, 0x13, 0x59, - 0x03, 0x8c, 0x7c, 0xc8, 0x25, 0x2a, 0x3f, 0x78, 0xa4, 0x03, 0x85, 0xea, 0x0b, 0xe9, 0xee, 0x7e, - 0x15, 0xb1, 0xb2, 0x16, 0x53, 0xa0, 0x55, 0x77, 0xd6, 0x71, 0xa2, 0xb6, 0xf1, 0xb2, 0xd7, 0x96, - 0xf3, 0x74, 0x2b, 0x1e, 0xe4, 0x93, 0x19, 0xc1, 0xa1, 0xd3, 0x90, 0x8f, 0x5c, 0x94, 0x42, 0xe4, - 0xd0, 0x18, 0xd3, 0x89, 0xfa, 0x57, 0x79, 0x53, 0xc2, 0x5e, 0xa5, 0xd3, 0x3a, 0xcc, 0x6c, 0xd3, - 0x17, 0x89, 0x7e, 0xf1, 0x5e, 0xbc, 0x47, 0x5f, 0xb4, 0xb4, 0xbe, 0x35, 0x69, 0x37, 0x61, 0xc8, - 0x1e, 0xcc, 0x4a, 0x5d, 0x70, 0x56, 0x95, 0xc8, 0x23, 0xbe, 0x59, 0x0f, 0x47, 0xcf, 0x9c, 0x96, - 0x2f, 0x4a, 0xf5, 0x50, 0x6d, 0x13, 0xe3, 0x9b, 0x5f, 0xa5, 0xd6, 0x0e, 0x94, 0x92, 0xdc, 0x13, - 0xbd, 0x7d, 0x30, 0x6c, 0x81, 0xf2, 0xa3, 0x72, 0xc7, 0x5c, 0xac, 0x1b, 0xe8, 0xd5, 0x51, 0x6d, - 0xd4, 0x79, 0xf4, 0x5e, 0x7c, 0x32, 0xf0, 0x02, 0x5f, 0x4e, 0x86, 0xfe, 0x48, 0x25, 0x0a, 0x1c, - 0x9b, 0x8f, 0x61, 0x12, 0x84, 0xbd, 0x07, 0x13, 0xa2, 0x48, 0x3d, 0xfe, 0x89, 0xab, 0x0e, 0xd9, - 0xc0, 0xfa, 0x83, 0x1c, 0x5c, 0x65, 0xb6, 0x7b, 0xc3, 0xed, 0xed, 0x77, 0xe9, 0x93, 0xc0, 0x0c, - 0xdb, 0xfa, 0x6d, 0x43, 0x7d, 0x2c, 0x64, 0x84, 0x83, 0xff, 0xff, 0x52, 0x1a, 0xff, 0x20, 0x07, - 0xe5, 0x34, 0xda, 0xde, 0xac, 0xde, 0xb8, 0x23, 0x0e, 0x5b, 0x9c, 0xda, 0x92, 0x00, 0x57, 0x7d, - 0xca, 0xc1, 0xb2, 0x41, 0xb2, 0xff, 0x0d, 0x85, 0xf1, 0x7f, 0x72, 0x30, 0xb7, 0x19, 0x20, 0xf9, - 0xbf, 0x38, 0x76, 0x7d, 0xda, 0x91, 0x8c, 0xbb, 0x93, 0xf6, 0x68, 0x00, 0xe7, 0x75, 0xe3, 0x42, - 0xda, 0xa3, 0x80, 0x0f, 0xb4, 0xb0, 0xe8, 0xfc, 0xa0, 0xd7, 0x00, 0xc6, 0x2b, 0xb7, 0x5b, 0x30, - 0xba, 0xcd, 0x8c, 0xa4, 0x11, 0x21, 0x7f, 0x1c, 0x82, 0x15, 0x61, 0x04, 0x33, 0x23, 0x99, 0x7d, - 0x90, 0xfb, 0x89, 0x38, 0xe9, 0xd1, 0xe1, 0xd1, 0xee, 0xc9, 0xe7, 0x79, 0xb5, 0x02, 0x8c, 0xef, - 0x3a, 0xfe, 0x3e, 0x0d, 0xad, 0x1f, 0x43, 0x59, 0x04, 0x16, 0x70, 0xc7, 0x27, 0x86, 0x1f, 0x04, - 0x91, 0x43, 0x6e, 0x50, 0x30, 0xc0, 0x12, 0x40, 0x23, 0x74, 0xfc, 0x70, 0xb3, 0xd7, 0xa1, 0xdf, - 0xe1, 0x68, 0xc7, 0x6c, 0xad, 0xc4, 0xfa, 0x10, 0x26, 0xd5, 0x10, 0xf0, 0x84, 0xa6, 0xd9, 0x81, - 0x38, 0x9c, 0x39, 0x23, 0x72, 0x5b, 0x86, 0x6b, 0xaf, 0xc0, 0x7c, 0x6c, 0x2a, 0x84, 0x9c, 0x94, - 0xd9, 0x84, 0xf1, 0x32, 0x1e, 0xba, 0x64, 0xab, 0x6f, 0xab, 0x0e, 0x97, 0x12, 0x33, 0x4d, 0x08, - 0x46, 0xe3, 0xf3, 0xd3, 0x37, 0xdb, 0x26, 0x1a, 0x8d, 0x0d, 0x56, 0xb6, 0xbb, 0xd5, 0xe0, 0x91, - 0x89, 0xac, 0x6c, 0x77, 0xab, 0x51, 0x1b, 0xe7, 0x92, 0x63, 0xfd, 0xe3, 0x3c, 0x1e, 0x4a, 0x13, - 0x3c, 0x88, 0xf9, 0x97, 0x74, 0x1f, 0x57, 0x0d, 0x26, 0x71, 0xc4, 0xab, 0x32, 0x82, 0x77, 0xf0, - 0x6d, 0x64, 0xe1, 0x97, 0x27, 0x95, 0x0b, 0x78, 0x05, 0x19, 0x81, 0x91, 0x2f, 0x61, 0x62, 0xad, - 0xd7, 0x41, 0x0c, 0x23, 0xe7, 0xc0, 0x20, 0x81, 0xd8, 0x3c, 0x20, 0xc9, 0xcc, 0xc0, 0x11, 0x8e, - 0x13, 0x5b, 0x2b, 0x41, 0x36, 0xbb, 0x47, 0x2e, 0x8f, 0x39, 0x19, 0xb3, 0xf9, 0x07, 0xe3, 0x26, - 0x92, 0x20, 0x1f, 0x64, 0x4d, 0xda, 0xea, 0x9b, 0x58, 0x30, 0xf6, 0xd8, 0xef, 0x88, 0xe7, 0x31, - 0xb3, 0xcb, 0xd3, 0x32, 0x0b, 0x06, 0x2b, 0xb3, 0x79, 0x95, 0xf5, 0xbf, 0xf0, 0x1e, 0x38, 0x4c, - 0x95, 0x1b, 0x83, 0x2b, 0xb9, 0xd7, 0xe6, 0x4a, 0xfe, 0x55, 0xb8, 0xa2, 0x46, 0x3d, 0x92, 0x35, - 0xea, 0xd1, 0xac, 0x51, 0x8f, 0x65, 0x8f, 0x7a, 0x1d, 0xc6, 0xf9, 0x50, 0xc9, 0x5b, 0x30, 0xb6, - 0x19, 0xd2, 0xa3, 0xc8, 0x59, 0xa1, 0x47, 0xf2, 0xd8, 0xbc, 0x8e, 0x9d, 0xa3, 0xb6, 0x9c, 0x20, - 0x94, 0xb1, 0xb0, 0x93, 0xb6, 0xfc, 0xb4, 0x7e, 0x8e, 0xa1, 0xf2, 0x5b, 0x5e, 0xfb, 0x50, 0xf3, - 0x64, 0x4e, 0xf0, 0x55, 0x19, 0xbf, 0x10, 0x60, 0xad, 0x78, 0x8d, 0x2d, 0x5b, 0x90, 0x1b, 0x30, - 0xb5, 0xd9, 0xbb, 0xef, 0xf9, 0x6d, 0xfa, 0xb8, 0xd7, 0xe5, 0xd8, 0x0b, 0xb6, 0x5e, 0x24, 0x3c, - 0x2c, 0xa2, 0x87, 0xc8, 0xc3, 0x82, 0x05, 0x31, 0x0f, 0x0b, 0x7f, 0x28, 0x6d, 0xf3, 0x3a, 0xe1, - 0xc0, 0x61, 0x7f, 0x0f, 0x72, 0xaf, 0x28, 0x3f, 0xcc, 0xb0, 0x86, 0x7b, 0x70, 0xd5, 0xa6, 0xfd, - 0xae, 0xc3, 0xcc, 0xa8, 0x23, 0x8f, 0xb7, 0x57, 0x63, 0xbe, 0x91, 0x12, 0xc5, 0x69, 0x3a, 0x53, - 0x15, 0xc9, 0xf9, 0x01, 0x24, 0x1f, 0xc1, 0xcd, 0x75, 0x1a, 0xa6, 0xbe, 0x76, 0x8e, 0x06, 0xbf, - 0x01, 0x05, 0xf1, 0x5a, 0x46, 0x8e, 0x7f, 0xd8, 0x43, 0x6b, 0x71, 0x39, 0x24, 0xf0, 0xa8, 0xbf, - 0xac, 0xaf, 0xa0, 0x92, 0xd5, 0xdd, 0xd9, 0xc2, 0xee, 0x5c, 0xb8, 0x91, 0x8d, 0x40, 0x6d, 0x8b, - 0x13, 0xa2, 0x43, 0x75, 0x20, 0x1e, 0x4c, 0xad, 0xba, 0x2e, 0x40, 0xc3, 0x40, 0xfc, 0x61, 0xd5, - 0x64, 0x5c, 0xcf, 0x6b, 0x90, 0xdb, 0xc2, 0x0b, 0x0d, 0x13, 0x41, 0xc4, 0xd7, 0x2a, 0x14, 0x64, - 0x59, 0xec, 0x46, 0x23, 0xf1, 0x90, 0x1c, 0x19, 0xda, 0x91, 0x08, 0x14, 0x98, 0xf5, 0x73, 0x79, - 0xed, 0x60, 0x42, 0x9c, 0x2d, 0x22, 0xfc, 0x2c, 0xf7, 0x0c, 0x96, 0x07, 0x57, 0x4d, 0xdc, 0xba, - 0xc3, 0xbb, 0xa8, 0x39, 0xbc, 0xb9, 0x9f, 0x9b, 0xc9, 0xa5, 0xbd, 0xb5, 0xd6, 0xeb, 0xf4, 0x3d, - 0xb7, 0x17, 0x8a, 0xc5, 0xab, 0x17, 0x91, 0x25, 0xdd, 0xad, 0x3d, 0x9d, 0x0c, 0xa1, 0xbf, 0x07, - 0xe5, 0xb4, 0x0e, 0x35, 0xb7, 0x88, 0xf2, 0x0c, 0x73, 0x83, 0xc4, 0x3a, 0x80, 0x39, 0x23, 0x35, - 0x4f, 0x94, 0x6b, 0x24, 0x4a, 0x49, 0x34, 0x59, 0xfb, 0xe2, 0x37, 0x27, 0x95, 0x4f, 0xce, 0x13, - 0xa7, 0x2d, 0x71, 0xee, 0xaa, 0x57, 0x00, 0xd6, 0x02, 0x8c, 0xd4, 0xed, 0x2d, 0x1c, 0xb6, 0xbd, - 0xa5, 0x86, 0x6d, 0x6f, 0x59, 0x7f, 0x94, 0x87, 0x4a, 0xfd, 0xc0, 0xe9, 0xed, 0xf3, 0xeb, 0xde, - 0xc8, 0xee, 0xd2, 0xee, 0x8f, 0xcf, 0x7a, 0xda, 0x58, 0x86, 0xa9, 0x6d, 0xfa, 0x42, 0xbe, 0x60, - 0x10, 0x6f, 0x01, 0xd0, 0x3f, 0xcd, 0x4e, 0x02, 0x7d, 0x51, 0x6e, 0xeb, 0x8d, 0xc8, 0x9f, 0x7d, - 0x75, 0xbf, 0x0b, 0x4f, 0xd0, 0x11, 0x1d, 0x32, 0x78, 0x6d, 0xda, 0x69, 0x23, 0xa3, 0x8b, 0xe4, - 0xf1, 0x68, 0xf4, 0xfc, 0xc7, 0x23, 0xeb, 0x9f, 0xe5, 0xe0, 0x46, 0x36, 0x07, 0x45, 0x4f, 0xab, - 0x46, 0xae, 0x94, 0x01, 0x97, 0xde, 0x78, 0x24, 0xd4, 0x72, 0xa5, 0xc4, 0xf3, 0xa3, 0xd8, 0xb4, - 0xed, 0x3d, 0xa7, 0xfe, 0xcb, 0x98, 0x1f, 0x5b, 0x16, 0xd7, 0xbd, 0x0e, 0x0d, 0x64, 0xa6, 0x29, - 0x5e, 0x64, 0x3c, 0x5d, 0x16, 0x65, 0xd6, 0xbf, 0xcf, 0xc1, 0x35, 0xdc, 0x06, 0x85, 0x97, 0x4f, - 0x56, 0xbc, 0x52, 0xe4, 0x88, 0xde, 0xb9, 0x98, 0x75, 0x8c, 0x1c, 0x91, 0x14, 0xb4, 0xda, 0x5e, - 0x87, 0xda, 0x46, 0x33, 0xb2, 0x09, 0x53, 0xe2, 0x5b, 0x73, 0xe5, 0xcc, 0x6b, 0x99, 0x97, 0x50, - 0xa8, 0xf8, 0x99, 0x0f, 0x45, 0x48, 0x20, 0x6b, 0xe1, 0xd3, 0x16, 0x1d, 0xd6, 0xfa, 0x75, 0x1e, - 0x16, 0x9b, 0xd4, 0x77, 0x9f, 0xbd, 0xcc, 0x18, 0xcc, 0x63, 0x98, 0x93, 0x45, 0x38, 0x66, 0x53, - 0x98, 0xf9, 0x13, 0x54, 0x49, 0x6a, 0xc0, 0x1a, 0xb4, 0x94, 0x6c, 0xa7, 0x02, 0x9e, 0xe3, 0x51, - 0xf6, 0x07, 0x50, 0x50, 0xeb, 0x61, 0x04, 0x39, 0x83, 0x73, 0x23, 0xd7, 0x82, 0x99, 0x03, 0x43, - 0x2d, 0x8a, 0xbf, 0x9c, 0x7d, 0x5d, 0x20, 0xec, 0xff, 0x21, 0x47, 0x33, 0xbe, 0x34, 0xd8, 0xb2, - 0x70, 0xb4, 0xda, 0x94, 0xa5, 0xb1, 0x71, 0xc1, 0xce, 0xea, 0xa9, 0x36, 0x05, 0x93, 0x55, 0xbc, - 0xcc, 0x60, 0xe6, 0xf6, 0xff, 0xce, 0xc3, 0x92, 0x0c, 0xf6, 0xcd, 0x60, 0xf3, 0x37, 0xb0, 0x20, - 0x8b, 0xaa, 0xfd, 0xbe, 0xef, 0x3d, 0xa7, 0x1d, 0x93, 0xd3, 0xfc, 0x19, 0xb8, 0xe4, 0xb4, 0x23, - 0xda, 0x44, 0xcc, 0xce, 0x02, 0x7f, 0x33, 0x6e, 0x8c, 0x2f, 0x4d, 0xed, 0xc4, 0x67, 0x03, 0xdd, - 0x09, 0xba, 0x76, 0x32, 0x93, 0x84, 0xe9, 0x9a, 0xaa, 0x93, 0x70, 0x83, 0x8c, 0xbe, 0xae, 0x1b, - 0x84, 0x1d, 0xd4, 0x4c, 0x9c, 0xb5, 0x59, 0x98, 0xde, 0xa6, 0x2f, 0x22, 0xbe, 0xff, 0x4e, 0x0e, - 0x66, 0x8c, 0xc5, 0x4d, 0xde, 0x85, 0x31, 0xfc, 0x03, 0x77, 0x5e, 0xf1, 0x16, 0x8e, 0x2d, 0x30, - 0xe3, 0x2d, 0x1c, 0x6f, 0xba, 0x09, 0x13, 0x3c, 0xce, 0xaa, 0x73, 0x06, 0x8b, 0x5a, 0xc5, 0x4d, - 0xb6, 0x39, 0x08, 0x37, 0xae, 0x05, 0xbc, 0xf5, 0x10, 0x6e, 0x8a, 0x20, 0x36, 0x73, 0xf2, 0xb1, - 0xa3, 0x73, 0x6e, 0x14, 0x96, 0x03, 0x4b, 0xeb, 0x34, 0xae, 0x7a, 0x8c, 0xb8, 0xd2, 0xaf, 0xe0, - 0xa2, 0x51, 0xae, 0x30, 0xe2, 0x7b, 0x19, 0x25, 0x43, 0x0a, 0x75, 0xbc, 0xb5, 0x75, 0x23, 0xad, - 0x0b, 0x9d, 0x58, 0x8b, 0xc2, 0x45, 0x3c, 0x37, 0xaa, 0x1b, 0x9d, 0xe0, 0x1c, 0x5a, 0xef, 0xb6, - 0xb6, 0xae, 0xb9, 0xc6, 0xe3, 0x4f, 0xad, 0xe5, 0x1e, 0xa7, 0x6a, 0xad, 0x19, 0x98, 0xaa, 0x7b, - 0xbd, 0x90, 0x7e, 0x87, 0x8f, 0x9d, 0xac, 0x59, 0x98, 0x96, 0x55, 0x5d, 0x1a, 0x04, 0xd6, 0xdf, - 0x1b, 0x01, 0x4b, 0x30, 0x36, 0xcd, 0xe7, 0x21, 0xf9, 0xb1, 0x97, 0x20, 0x56, 0x6c, 0x22, 0x57, - 0x74, 0xcf, 0x4e, 0x54, 0xcb, 0x25, 0x0f, 0x6f, 0x79, 0xdb, 0x51, 0xa9, 0x21, 0x79, 0x89, 0xd1, - 0xff, 0x24, 0x43, 0x4d, 0xf2, 0xc5, 0x86, 0x29, 0x88, 0x32, 0xd4, 0xa4, 0x81, 0x37, 0x5d, 0x65, - 0xda, 0x06, 0x1b, 0xc4, 0xe6, 0x4e, 0xd4, 0xa3, 0x0c, 0x55, 0x23, 0xd2, 0xf6, 0xf1, 0x82, 0x56, - 0x22, 0xed, 0x9e, 0x8e, 0x84, 0x3c, 0x31, 0x79, 0x29, 0xd6, 0xa3, 0xbc, 0x41, 0xd5, 0xab, 0x38, - 0xd6, 0xbe, 0x56, 0x62, 0x66, 0x31, 0x34, 0xda, 0x6a, 0x7e, 0xac, 0xbf, 0x9d, 0x83, 0x6b, 0x7c, - 0x76, 0x76, 0x7c, 0xf7, 0xb9, 0xdb, 0xa5, 0xfb, 0xd4, 0x10, 0xd3, 0xe3, 0xf4, 0x9b, 0xa8, 0xdc, - 0x99, 0x74, 0x34, 0x26, 0x65, 0xa1, 0x02, 0x3c, 0xcb, 0x51, 0x9a, 0x86, 0xdf, 0x3a, 0xc9, 0xc9, - 0x00, 0xca, 0xc4, 0xf5, 0xcc, 0x79, 0x6d, 0xb6, 0x9a, 0x71, 0xa3, 0x92, 0xcf, 0xb8, 0x51, 0x31, - 0x3c, 0xd5, 0xe1, 0x90, 0x2b, 0x96, 0x91, 0xd7, 0x77, 0xde, 0xfe, 0x6a, 0x04, 0x2e, 0xed, 0x38, - 0xfb, 0x6e, 0x8f, 0xe9, 0x1e, 0x99, 0x27, 0x89, 0x54, 0x13, 0x29, 0xed, 0x06, 0x07, 0x3c, 0xa5, - 0xe4, 0xac, 0x5b, 0xd6, 0xb3, 0x4b, 0xe5, 0xb3, 0x5e, 0x70, 0x98, 0x39, 0xa4, 0x3e, 0x35, 0x7c, - 0x75, 0x89, 0x98, 0x37, 0x8c, 0x2a, 0xe9, 0x79, 0x9d, 0x58, 0x9a, 0x47, 0xf4, 0x77, 0x3d, 0x86, - 0x29, 0x2d, 0x70, 0x4d, 0x08, 0x68, 0x02, 0x03, 0xb2, 0xe5, 0xf0, 0x78, 0x8f, 0xa6, 0xa6, 0xf4, - 0xd2, 0x31, 0xa4, 0x24, 0xf2, 0x1a, 0x7b, 0xc3, 0x89, 0xbc, 0x7e, 0xcc, 0x49, 0x96, 0x9e, 0xcf, - 0x71, 0xb1, 0x6f, 0x70, 0xf4, 0x09, 0xf7, 0x67, 0x73, 0x45, 0xa3, 0x3e, 0x2d, 0x2b, 0xa1, 0x8e, - 0xac, 0x06, 0x50, 0x90, 0xf9, 0x4f, 0xad, 0xff, 0x39, 0x0e, 0x73, 0x5b, 0x6e, 0x10, 0xca, 0xd9, - 0x0d, 0x22, 0xd5, 0x3f, 0x2d, 0xcb, 0xb4, 0x43, 0x90, 0xb0, 0xd2, 0x78, 0x79, 0x2b, 0x96, 0x8e, - 0xd5, 0x00, 0x20, 0x1f, 0xea, 0xfe, 0xbb, 0xbc, 0x96, 0x40, 0x25, 0x99, 0x49, 0x53, 0x77, 0xec, - 0xbd, 0x6b, 0xb8, 0x8f, 0xf8, 0xbe, 0xda, 0x65, 0x05, 0xfa, 0xbe, 0xca, 0x7d, 0x4a, 0x2b, 0x71, - 0x9f, 0x12, 0xef, 0x80, 0x2b, 0xc5, 0x43, 0x6a, 0x98, 0xdc, 0xca, 0xd9, 0xf4, 0x04, 0xc6, 0xf1, - 0xf5, 0x3c, 0x4f, 0xa3, 0x34, 0xb5, 0xfc, 0x3d, 0xb1, 0x40, 0xd2, 0x98, 0xc0, 0xdf, 0xd9, 0x07, - 0x5a, 0x8a, 0xac, 0x2e, 0x16, 0xe8, 0x4f, 0xf6, 0x79, 0x13, 0xb2, 0x0b, 0x97, 0x77, 0x7c, 0xda, - 0x41, 0xd5, 0xb2, 0xf6, 0x5d, 0xdf, 0x17, 0x47, 0x0c, 0x74, 0xf0, 0xf1, 0x8c, 0x75, 0x7d, 0x59, - 0xdd, 0xa2, 0xaa, 0x5e, 0xd7, 0x30, 0x29, 0xe0, 0x64, 0x0d, 0x66, 0x1b, 0xd4, 0xf1, 0xdb, 0x07, - 0x0f, 0xe9, 0x4b, 0xa6, 0x18, 0x83, 0xd2, 0x44, 0x94, 0x81, 0x27, 0xc0, 0x1a, 0x36, 0x50, 0xac, - 0xd2, 0xaf, 0x75, 0x4c, 0x20, 0xf2, 0x43, 0x18, 0x6f, 0x78, 0x7e, 0x58, 0x7b, 0x19, 0x4b, 0xad, - 0xca, 0x0b, 0x6b, 0x57, 0x65, 0x16, 0xa2, 0xc0, 0xf3, 0xc3, 0xd6, 0x9e, 0xce, 0x37, 0x01, 0x47, - 0xee, 0x33, 0xab, 0x8b, 0x59, 0x82, 0xa1, 0xd3, 0xad, 0x63, 0x78, 0x02, 0x7f, 0x74, 0x29, 0x2c, - 0x2b, 0x34, 0x1f, 0x43, 0xa7, 0xdb, 0xc2, 0x7d, 0xde, 0xbc, 0x60, 0xd2, 0xa1, 0xc8, 0x4b, 0x98, - 0x33, 0x05, 0x5d, 0xe4, 0x28, 0x03, 0x23, 0x49, 0x61, 0x5a, 0x93, 0xda, 0x6d, 0x41, 0xe5, 0x8d, - 0x78, 0x02, 0xbe, 0x44, 0xda, 0xb2, 0xd4, 0x2e, 0xc8, 0x23, 0x4c, 0x02, 0xc5, 0x39, 0x53, 0x0d, - 0x78, 0xbc, 0x13, 0x7f, 0xe9, 0x79, 0xf3, 0xf4, 0xa4, 0x72, 0xfd, 0x18, 0xb3, 0x6d, 0x22, 0x47, - 0x1d, 0xfe, 0x8e, 0x40, 0xe7, 0x68, 0x02, 0xb4, 0xfc, 0x29, 0x4c, 0x69, 0xd2, 0x71, 0xae, 0x0c, - 0x67, 0x7f, 0x9c, 0x83, 0xf9, 0x98, 0xb8, 0x89, 0xf3, 0xe9, 0x63, 0x98, 0x54, 0x85, 0xc2, 0xa5, - 0x53, 0x52, 0xfb, 0x68, 0x4c, 0x0f, 0x73, 0x61, 0x97, 0x6b, 0x51, 0x27, 0x36, 0xc2, 0x41, 0xee, - 0xc1, 0xc4, 0x36, 0xfd, 0x2e, 0xf2, 0x83, 0xf2, 0x73, 0x4f, 0x8f, 0x6d, 0xea, 0xe6, 0x02, 0x91, - 0xcd, 0xc8, 0xa7, 0x00, 0xda, 0x2c, 0xf3, 0x45, 0x88, 0xb1, 0x93, 0xe9, 0x13, 0xac, 0x35, 0xb6, - 0xfe, 0x68, 0x42, 0x6e, 0xd3, 0xf2, 0x75, 0x82, 0xef, 0xb4, 0x0f, 0xa3, 0x20, 0xd6, 0x0f, 0x93, - 0x11, 0xa3, 0x67, 0xd1, 0x08, 0xb7, 0x8c, 0xc4, 0x0a, 0xd9, 0x79, 0xa0, 0xa3, 0x1c, 0x1b, 0x23, - 0x67, 0xc8, 0xb1, 0x71, 0x17, 0x26, 0x36, 0x7b, 0xcf, 0x5d, 0x66, 0x94, 0xf3, 0x90, 0x47, 0x34, - 0x69, 0x5d, 0x5e, 0xa4, 0x33, 0x46, 0xb4, 0x22, 0x9f, 0x42, 0x61, 0xc3, 0x0b, 0xc2, 0x9e, 0x0c, - 0x77, 0x14, 0xab, 0x30, 0x44, 0xbf, 0x70, 0xeb, 0x40, 0x54, 0xe9, 0x3a, 0x47, 0x36, 0x27, 0x1f, - 0xc1, 0x44, 0xb5, 0xd3, 0x61, 0x8b, 0x5a, 0x28, 0x04, 0x4c, 0x22, 0x2b, 0x20, 0x1d, 0x5e, 0xa3, - 0x77, 0x29, 0x1a, 0x93, 0x2f, 0x4c, 0x27, 0xed, 0x44, 0x94, 0x81, 0x26, 0x3d, 0xa1, 0xb2, 0xe9, - 0xc0, 0x7d, 0x57, 0xde, 0xf2, 0x14, 0xa2, 0x9c, 0x3e, 0x98, 0x9f, 0xc7, 0xd0, 0xa4, 0x78, 0x49, - 0xb4, 0x09, 0x93, 0x9b, 0x3d, 0x37, 0x74, 0x31, 0xab, 0xc9, 0xa4, 0xb1, 0x1f, 0xef, 0x38, 0x7e, - 0xe8, 0xb6, 0xdd, 0xbe, 0xd3, 0x0b, 0xf9, 0x6c, 0xb9, 0xb2, 0xa1, 0x3e, 0x5b, 0x0a, 0x5a, 0xcf, - 0x7f, 0x06, 0x6f, 0x2c, 0xff, 0x59, 0x6a, 0x0a, 0xb1, 0xa9, 0x57, 0x4f, 0x21, 0xb6, 0xc2, 0xe7, - 0x12, 0x6d, 0xe0, 0xe9, 0x48, 0x10, 0xd1, 0x77, 0x69, 0x1a, 0xbb, 0xb6, 0x6a, 0x48, 0x6e, 0x60, - 0x16, 0x93, 0x99, 0x28, 0xdc, 0xd3, 0xb8, 0x55, 0xce, 0x6f, 0xae, 0x92, 0x16, 0x4c, 0xb3, 0xd6, - 0x3b, 0x5e, 0xd7, 0x6d, 0xbb, 0x34, 0x28, 0xcd, 0x1a, 0xce, 0x6e, 0x73, 0x51, 0x60, 0xa3, 0x97, - 0x0d, 0x1a, 0xf2, 0x3d, 0x15, 0xbb, 0xee, 0x0b, 0x40, 0x7d, 0x4f, 0xd5, 0x11, 0x92, 0x9f, 0xb1, - 0xfd, 0x40, 0xc7, 0x22, 0x32, 0x20, 0x2f, 0xa4, 0x76, 0xd1, 0x7c, 0x5f, 0x6e, 0x14, 0xe2, 0xe9, - 0x10, 0x2f, 0x36, 0x37, 0x0a, 0x1d, 0xc0, 0xb2, 0xa1, 0x14, 0x5d, 0x2d, 0xc5, 0x56, 0xef, 0x47, - 0xc9, 0xe7, 0x2b, 0x98, 0xfd, 0x33, 0x7a, 0xbe, 0xa2, 0x0b, 0x44, 0xf4, 0x90, 0xe5, 0x09, 0x5c, - 0xb3, 0xe9, 0x91, 0xf7, 0x9c, 0xbe, 0x59, 0xb4, 0x3f, 0x81, 0xab, 0x26, 0xc2, 0x27, 0xfd, 0x0e, - 0xbe, 0xbd, 0xe6, 0x77, 0x58, 0xa9, 0xb9, 0x7d, 0x04, 0x00, 0xcf, 0xed, 0xc3, 0x13, 0x46, 0xb0, - 0x3f, 0xf5, 0xf5, 0x80, 0x75, 0x96, 0x07, 0x8b, 0x26, 0xf2, 0x6a, 0xa7, 0xa3, 0x2d, 0x04, 0x66, - 0x50, 0x6a, 0x9f, 0x31, 0x0b, 0x56, 0x5f, 0x31, 0xa8, 0x39, 0xfb, 0x51, 0x81, 0xbe, 0x56, 0xb5, - 0x76, 0x16, 0x85, 0x4a, 0x9c, 0x3d, 0x8c, 0x65, 0x7a, 0x9f, 0x35, 0x98, 0xd1, 0x3e, 0xd5, 0x81, - 0x10, 0x55, 0x89, 0xd6, 0x83, 0xc9, 0x30, 0x13, 0xc4, 0x6a, 0x43, 0x39, 0x8d, 0x69, 0xb8, 0xcc, - 0x5e, 0x92, 0xb5, 0x68, 0xe9, 0x0e, 0xbf, 0x3b, 0xbc, 0x98, 0xf9, 0xb6, 0xf3, 0x77, 0x47, 0xe1, - 0x9a, 0x98, 0x8c, 0x37, 0x39, 0xe3, 0xe4, 0xe7, 0x30, 0xa5, 0xcd, 0xb1, 0x60, 0xfa, 0x0d, 0x19, - 0x6e, 0x90, 0x25, 0x0b, 0x5c, 0x5f, 0x1e, 0x63, 0x41, 0x2b, 0x36, 0xdd, 0xcc, 0x30, 0xd6, 0xc5, - 0xa6, 0x0b, 0xb3, 0xe6, 0x44, 0x8b, 0xc3, 0xc6, 0x5b, 0xa9, 0x9d, 0x98, 0x4d, 0x65, 0x96, 0x8b, - 0x4e, 0x2b, 0x75, 0xba, 0x31, 0x5d, 0xb3, 0x29, 0x44, 0xdf, 0xc1, 0xa5, 0xc4, 0x2c, 0x8b, 0xb3, - 0xc9, 0xad, 0xd4, 0x0e, 0x13, 0xad, 0xb9, 0xf2, 0xf3, 0xb1, 0x38, 0xb3, 0xdb, 0x64, 0x27, 0xa4, - 0x03, 0xd3, 0xfa, 0xc4, 0x8b, 0xc3, 0xcb, 0xcd, 0x01, 0xac, 0xe4, 0x0d, 0xb9, 0xaa, 0x12, 0xbc, - 0xc4, 0xb9, 0x37, 0x7f, 0xe1, 0xc0, 0xc0, 0x5a, 0x2b, 0xc0, 0x38, 0xff, 0x66, 0x2a, 0x60, 0xc7, - 0xa7, 0x01, 0xed, 0xb5, 0xa9, 0x1e, 0x39, 0xf2, 0xba, 0x2a, 0xe0, 0xdf, 0xe5, 0xa0, 0x94, 0x86, - 0xb7, 0x41, 0x7b, 0x1d, 0xb2, 0x03, 0xc5, 0x78, 0x47, 0x42, 0xaa, 0x2d, 0x69, 0x51, 0x65, 0x93, - 0xb4, 0x71, 0xc1, 0x4e, 0x40, 0xb3, 0x4d, 0x48, 0x2b, 0x3b, 0x67, 0x88, 0x4e, 0x12, 0x54, 0x77, - 0x70, 0x6c, 0x60, 0x24, 0xd2, 0xaa, 0x77, 0xe4, 0xb8, 0x3d, 0xb6, 0x77, 0x2b, 0x83, 0xf0, 0x2e, - 0x40, 0x54, 0x2a, 0x78, 0xc3, 0x9d, 0x00, 0x58, 0x2a, 0xc3, 0xd5, 0x54, 0x13, 0xeb, 0x0b, 0xd4, - 0xe0, 0x62, 0x9f, 0xe3, 0x0f, 0x19, 0x14, 0xb2, 0x1b, 0x30, 0xb6, 0xbb, 0xd5, 0xa8, 0x57, 0xc5, - 0xb3, 0x08, 0xfe, 0xc6, 0xad, 0x1b, 0xb4, 0xda, 0x8e, 0xcd, 0x2b, 0xac, 0x7f, 0x9d, 0x87, 0x39, - 0xf9, 0x2e, 0xdb, 0xf0, 0xb0, 0x0c, 0x4d, 0x3f, 0xf5, 0x23, 0xf3, 0x5d, 0x79, 0x5d, 0xbd, 0x2b, - 0x7f, 0x8d, 0x94, 0xba, 0xe2, 0x45, 0xfa, 0x19, 0xdf, 0xb1, 0x3c, 0x54, 0x07, 0xbb, 0x51, 0xe3, - 0x60, 0x97, 0x36, 0x1e, 0xe3, 0x60, 0x87, 0x7c, 0xe0, 0x07, 0x3b, 0x79, 0x9c, 0x7b, 0x1d, 0xeb, - 0xfe, 0x13, 0x36, 0x97, 0x46, 0x97, 0x67, 0x7d, 0xc0, 0xb1, 0x85, 0xef, 0xe8, 0x1e, 0x6f, 0xae, - 0xd6, 0x99, 0x10, 0x09, 0x52, 0xe5, 0x0c, 0xdc, 0xc5, 0xa0, 0x1f, 0x81, 0x53, 0x97, 0x04, 0xd4, - 0x69, 0xe2, 0x59, 0xb0, 0xd6, 0xc4, 0x5a, 0x41, 0x6c, 0x8d, 0xea, 0xa3, 0xad, 0x14, 0x6c, 0x59, - 0x19, 0xd9, 0xb6, 0xf1, 0xa1, 0xed, 0x3a, 0xce, 0xd7, 0x9b, 0x20, 0xe2, 0x0f, 0x72, 0xfc, 0xe5, - 0x6e, 0xe3, 0xf1, 0xaa, 0xeb, 0xec, 0xf7, 0xbc, 0x20, 0x74, 0xdb, 0x9b, 0xbd, 0x67, 0x9e, 0xe6, - 0x60, 0xd6, 0xba, 0xd1, 0x12, 0x64, 0xa3, 0x35, 0x8e, 0xc9, 0xef, 0xc5, 0x4b, 0x21, 0x4c, 0x35, - 0x6d, 0xc7, 0x5b, 0x93, 0x4f, 0x61, 0x46, 0x2b, 0x52, 0xbb, 0x22, 0x4f, 0x5c, 0xa4, 0x83, 0xbb, - 0x1d, 0xdb, 0x6c, 0xf9, 0xde, 0x7b, 0x30, 0xa9, 0x7e, 0x5e, 0x86, 0x14, 0x60, 0x74, 0x73, 0x7b, - 0x73, 0x97, 0xa7, 0x12, 0xdd, 0x79, 0xb2, 0x5b, 0xcc, 0x11, 0x80, 0xf1, 0xd5, 0xb5, 0xad, 0xb5, - 0xdd, 0xb5, 0x62, 0xfe, 0xbd, 0x96, 0xee, 0x9f, 0x23, 0xd7, 0x60, 0x61, 0x75, 0xad, 0xb9, 0x59, - 0x5f, 0x6b, 0xed, 0xfe, 0x68, 0x67, 0xad, 0x65, 0xbe, 0x4e, 0x9a, 0x83, 0xa2, 0x5e, 0xb9, 0xfb, - 0x78, 0x77, 0xa7, 0x98, 0x23, 0x25, 0x98, 0xd3, 0x4b, 0x9f, 0xae, 0xd5, 0xaa, 0x4f, 0x76, 0x37, - 0xb6, 0x8b, 0x23, 0xd6, 0x68, 0x21, 0x5f, 0xcc, 0xbf, 0xf7, 0x73, 0xc3, 0x79, 0x47, 0x16, 0xa1, - 0x24, 0x9a, 0x3f, 0x69, 0x54, 0xd7, 0xb3, 0xbb, 0xe0, 0xb5, 0x8f, 0xee, 0x57, 0x8b, 0x39, 0x72, - 0x1d, 0xae, 0x1a, 0xa5, 0x3b, 0xd5, 0x46, 0xe3, 0xe9, 0x63, 0x7b, 0x75, 0x6b, 0xad, 0xd1, 0x28, - 0xe6, 0xdf, 0xbb, 0x25, 0xa2, 0x6c, 0xc8, 0x2c, 0xc0, 0xea, 0x5a, 0xa3, 0xbe, 0xb6, 0xbd, 0xba, - 0xb9, 0xbd, 0x5e, 0xbc, 0x40, 0x66, 0x60, 0xb2, 0xaa, 0x3e, 0x73, 0xcb, 0x7f, 0xff, 0x10, 0xa6, - 0x18, 0xa3, 0xa4, 0xaf, 0xab, 0x05, 0x0b, 0x8f, 0x1c, 0xb7, 0x17, 0x3a, 0x6e, 0x4f, 0xa8, 0x5e, - 0xa9, 0x38, 0x49, 0x65, 0x80, 0x26, 0x65, 0x4a, 0xb8, 0x3c, 0x2c, 0x96, 0xf0, 0x76, 0xee, 0x5e, - 0x8e, 0x34, 0x60, 0x2e, 0xed, 0xd4, 0x48, 0x2c, 0x33, 0x47, 0x51, 0x9a, 0x2d, 0x51, 0xce, 0x32, - 0x7c, 0xc9, 0x23, 0xb8, 0x94, 0xb0, 0x64, 0x15, 0xbd, 0x59, 0x36, 0xee, 0x20, 0x74, 0x25, 0xbc, - 0xc7, 0x08, 0xdd, 0xb8, 0x1d, 0x1b, 0x90, 0x2b, 0x09, 0x2b, 0x69, 0x8d, 0xed, 0x54, 0x99, 0xc8, - 0xee, 0xe5, 0x88, 0x0d, 0x73, 0x69, 0x36, 0xb1, 0x1a, 0xf2, 0x00, 0x83, 0xb9, 0x9c, 0xd1, 0x1d, - 0xc3, 0x99, 0x66, 0x75, 0x29, 0x9c, 0x03, 0x4c, 0xb2, 0x4c, 0x9c, 0x5f, 0xb0, 0xf3, 0x46, 0xaf, - 0xf3, 0x90, 0xd2, 0x7e, 0xb5, 0xeb, 0x3e, 0xa7, 0x01, 0x91, 0x91, 0xb0, 0xaa, 0x28, 0x0b, 0xf6, - 0x76, 0x8e, 0xfc, 0x16, 0x4c, 0x61, 0xb6, 0x79, 0x11, 0xb8, 0x35, 0xad, 0x67, 0xa0, 0x2f, 0xcb, - 0x2f, 0xac, 0xbc, 0x97, 0x23, 0x3f, 0x80, 0x89, 0x75, 0x1a, 0xa2, 0xbb, 0xf6, 0x66, 0xec, 0x87, - 0x9b, 0x36, 0x7b, 0xca, 0x19, 0x20, 0x09, 0x8e, 0x3b, 0x6f, 0x99, 0x66, 0xe2, 0x8f, 0x73, 0x11, - 0x43, 0xbc, 0xba, 0x9c, 0x20, 0x9b, 0xac, 0xb3, 0x15, 0xdd, 0xa5, 0x21, 0x3d, 0x6b, 0x97, 0x59, - 0x3c, 0xda, 0x82, 0x59, 0xf5, 0x54, 0x76, 0x1b, 0xef, 0xfb, 0xac, 0x18, 0xb2, 0xe0, 0x1c, 0xd8, - 0x3e, 0x63, 0x72, 0xcb, 0x77, 0x0f, 0x15, 0x25, 0x4c, 0xb2, 0xe2, 0x86, 0x15, 0x13, 0x79, 0x33, - 0x0d, 0x56, 0x25, 0xd0, 0x57, 0xb0, 0xf1, 0x94, 0xfa, 0x31, 0x58, 0x0a, 0x65, 0xbd, 0x5f, 0x33, - 0x62, 0x98, 0xdc, 0xd0, 0x08, 0x48, 0x0d, 0x74, 0x2e, 0xdf, 0x1c, 0xd0, 0x82, 0xef, 0x7f, 0xb8, - 0xd6, 0x1f, 0xc0, 0x8c, 0x11, 0x63, 0x4a, 0xe4, 0xf3, 0x97, 0xb4, 0x20, 0xe0, 0xf2, 0x62, 0x7a, - 0xa5, 0xd8, 0x4f, 0xef, 0xe3, 0x12, 0x8f, 0x25, 0xac, 0x2d, 0xa7, 0x25, 0xa6, 0xe5, 0x1e, 0xc0, - 0xb2, 0x4c, 0x3e, 0x16, 0x03, 0x79, 0x88, 0x19, 0x07, 0xcc, 0xc2, 0xe6, 0xf2, 0x40, 0x4c, 0x19, - 0xe9, 0x6f, 0xef, 0xe5, 0xc8, 0x1a, 0x5c, 0x56, 0x17, 0xb4, 0xda, 0xcf, 0x16, 0x65, 0x00, 0x64, - 0x8a, 0xc1, 0x57, 0x70, 0x59, 0x08, 0x95, 0x81, 0xa6, 0xa8, 0xf4, 0x83, 0xd8, 0xc4, 0x32, 0x11, - 0x3c, 0x80, 0xf9, 0x46, 0x6c, 0x50, 0xfc, 0x8c, 0x73, 0xd5, 0x44, 0xa1, 0x65, 0xca, 0xcd, 0xc4, - 0xf5, 0x10, 0x48, 0xe3, 0x78, 0xef, 0xc8, 0x55, 0xe8, 0x9e, 0xbb, 0xf4, 0x05, 0xb9, 0x1e, 0x1b, - 0x12, 0x2b, 0xc4, 0x66, 0xa8, 0x60, 0xb2, 0x58, 0x44, 0x76, 0x79, 0xda, 0x1d, 0x9e, 0x42, 0xd0, - 0xe9, 0x3b, 0x7b, 0x6e, 0xd7, 0x0d, 0x5d, 0xca, 0x64, 0x4c, 0x07, 0xd0, 0xab, 0xa4, 0x38, 0x5c, - 0xcd, 0x6c, 0x41, 0xbe, 0x84, 0x99, 0x75, 0x1a, 0x46, 0xc9, 0x80, 0xc9, 0x42, 0x22, 0x7d, 0xb0, - 0x98, 0x3a, 0x19, 0xaa, 0x63, 0x66, 0x20, 0xde, 0x84, 0x22, 0xd7, 0x8f, 0x1a, 0x8a, 0xeb, 0x09, - 0x14, 0xa2, 0x89, 0xe3, 0x3b, 0x47, 0x41, 0x26, 0xb7, 0xee, 0xc2, 0xe8, 0x8e, 0xdb, 0xdb, 0x27, - 0xf2, 0xe6, 0x4d, 0x4b, 0xa6, 0x59, 0xbe, 0x6c, 0x94, 0x09, 0x39, 0xde, 0x83, 0x0a, 0xcf, 0x82, - 0x9b, 0xcc, 0x3c, 0x2b, 0x7f, 0xea, 0xe3, 0x6d, 0x15, 0x67, 0x3e, 0x20, 0x5b, 0xae, 0xe2, 0x4f, - 0xbc, 0xbe, 0xb9, 0x42, 0x76, 0x90, 0xeb, 0xc9, 0x0e, 0xc8, 0x5b, 0xd1, 0x96, 0x98, 0x99, 0xf8, - 0xb6, 0x4c, 0xe2, 0x88, 0x9b, 0x2b, 0x44, 0xa5, 0xd3, 0x49, 0x41, 0x7a, 0xcb, 0xd8, 0xb9, 0xcf, - 0x87, 0xf7, 0x4b, 0x98, 0x54, 0x59, 0x5f, 0x95, 0xf2, 0x8a, 0xa7, 0xaa, 0x2d, 0x97, 0x92, 0x15, - 0x82, 0x9b, 0x5f, 0xf0, 0x04, 0xcd, 0x26, 0x7c, 0x3c, 0x31, 0x6a, 0xe6, 0xe4, 0x7d, 0x0a, 0x53, - 0x5a, 0x4a, 0x54, 0xb5, 0x58, 0x92, 0x69, 0x52, 0xcb, 0xe6, 0xcf, 0xd3, 0xdd, 0xcb, 0x91, 0xbb, - 0xb8, 0x81, 0xa1, 0xa7, 0x70, 0x3e, 0x02, 0xd3, 0x32, 0x42, 0xc6, 0x40, 0xc8, 0xc7, 0x18, 0xee, - 0x5b, 0x3f, 0xf6, 0x7d, 0xda, 0xe3, 0x70, 0x59, 0x96, 0x44, 0x0c, 0x70, 0x05, 0x0a, 0x32, 0xdb, - 0x37, 0xb9, 0x62, 0x76, 0x95, 0x4d, 0xde, 0x0a, 0x00, 0x67, 0x16, 0xf6, 0x64, 0x56, 0x67, 0xb2, - 0x63, 0x85, 0xed, 0xaa, 0x9d, 0x73, 0x02, 0x7d, 0x29, 0x77, 0x56, 0x04, 0x2a, 0x19, 0x53, 0xa0, - 0xb3, 0x23, 0x0b, 0x7e, 0x13, 0x8a, 0xd5, 0x36, 0xea, 0x7a, 0x95, 0xdd, 0x92, 0x2c, 0xa9, 0xa5, - 0x6f, 0x56, 0x48, 0x5c, 0xf3, 0xf1, 0x64, 0x99, 0x5b, 0xd4, 0xc1, 0xc8, 0xe3, 0x05, 0xb5, 0xe3, - 0xc7, 0xaa, 0xd2, 0x21, 0x32, 0x89, 0x5a, 0x83, 0xb9, 0xba, 0xd3, 0x6b, 0xd3, 0xee, 0xeb, 0xa1, - 0xf9, 0x0c, 0xf5, 0x94, 0x96, 0xf9, 0xf3, 0x4a, 0x1c, 0x5e, 0xa8, 0xa9, 0x4b, 0xca, 0x19, 0xa3, - 0x9a, 0x56, 0xe1, 0xa2, 0x48, 0x30, 0xa4, 0xd8, 0x92, 0x05, 0x9d, 0xd5, 0xfd, 0xc7, 0x30, 0xbb, - 0xc6, 0xf4, 0xf8, 0x71, 0xc7, 0xe5, 0xaf, 0x2d, 0x88, 0x19, 0x3e, 0x9f, 0x09, 0xb8, 0x21, 0x73, - 0x31, 0x6b, 0x29, 0x31, 0xd5, 0xea, 0x48, 0x66, 0x1d, 0x2d, 0xcf, 0x49, 0xb4, 0x7a, 0xf6, 0x4c, - 0xb4, 0x00, 0xf6, 0x65, 0xda, 0xb5, 0x58, 0xa2, 0x43, 0x5d, 0x13, 0x65, 0xa6, 0x41, 0x2c, 0xbf, - 0x3d, 0xb8, 0x91, 0x08, 0xcc, 0x18, 0xf9, 0xeb, 0x79, 0x66, 0x63, 0x2f, 0x64, 0x24, 0x91, 0x24, - 0xef, 0x28, 0x93, 0x78, 0x50, 0x92, 0xc9, 0x14, 0xa3, 0xf1, 0x1b, 0x2d, 0x59, 0x54, 0x06, 0xce, - 0xc1, 0xd9, 0x25, 0x33, 0x19, 0xac, 0x02, 0xb1, 0x53, 0xb3, 0x40, 0x92, 0x77, 0x4d, 0xec, 0x03, - 0x32, 0x45, 0x66, 0xf6, 0xf0, 0x18, 0x45, 0x2f, 0x4a, 0x42, 0xa8, 0x4c, 0xaf, 0xb4, 0x4c, 0x91, - 0xca, 0xf4, 0x4a, 0x4d, 0xe1, 0xc8, 0x19, 0xbc, 0x0e, 0x17, 0x63, 0xf9, 0x18, 0xc9, 0xf5, 0x38, - 0x63, 0x87, 0x30, 0x94, 0x23, 0x7a, 0x24, 0x05, 0x3b, 0x89, 0x28, 0x3d, 0x43, 0x63, 0xd6, 0x18, - 0x39, 0xba, 0x27, 0xca, 0x76, 0xd2, 0x73, 0x2e, 0x92, 0x9b, 0x29, 0x2c, 0x3c, 0x1b, 0xeb, 0x38, - 0xda, 0x06, 0x14, 0xe3, 0x29, 0x0b, 0xc9, 0x52, 0xcc, 0xc7, 0x14, 0xcb, 0xcb, 0x58, 0xae, 0x64, - 0xd6, 0x8b, 0xdd, 0xea, 0x41, 0x34, 0x29, 0xfc, 0xc6, 0x3f, 0x3e, 0x29, 0x7a, 0x06, 0xb1, 0xc4, - 0xa4, 0x98, 0xe9, 0xbc, 0xd6, 0x71, 0x3f, 0xd1, 0x52, 0x85, 0x65, 0xee, 0x27, 0xd7, 0xd3, 0xf0, - 0x44, 0xb7, 0xd0, 0x0d, 0x99, 0x1b, 0x5e, 0xa3, 0x6b, 0xc9, 0xd8, 0x70, 0x93, 0xa4, 0x55, 0x32, - 0xeb, 0xd5, 0x48, 0x8b, 0xf1, 0x3c, 0x6b, 0x0a, 0x69, 0x46, 0x02, 0xb6, 0x4c, 0x51, 0xbe, 0x0f, - 0x73, 0xe6, 0x2c, 0x0e, 0x19, 0x6f, 0x16, 0x9e, 0x5d, 0x98, 0x4f, 0xcd, 0xb1, 0xa6, 0x74, 0xd1, - 0xa0, 0x0c, 0x6c, 0x99, 0x58, 0x29, 0x5c, 0x49, 0x4f, 0xab, 0xa7, 0xcc, 0xb8, 0x81, 0xe9, 0x02, - 0xcb, 0xef, 0x0c, 0x69, 0x25, 0x18, 0xfa, 0x2d, 0x1e, 0x5b, 0x12, 0x7d, 0xdc, 0xd4, 0x7c, 0x1c, - 0x19, 0x1d, 0x58, 0x83, 0x9a, 0x28, 0x19, 0x98, 0x4b, 0xcb, 0x37, 0x99, 0xc9, 0xe2, 0xb7, 0xb2, - 0x71, 0x46, 0x82, 0xd5, 0x94, 0xcf, 0xec, 0x33, 0x39, 0x33, 0x30, 0x83, 0xde, 0x80, 0x23, 0x78, - 0x94, 0x65, 0xf5, 0xec, 0x24, 0x67, 0x1f, 0x9d, 0x66, 0x8c, 0xd4, 0x76, 0x44, 0x86, 0xa5, 0xc4, - 0xb2, 0xe8, 0x25, 0xd6, 0x64, 0x4a, 0x8a, 0x3d, 0xbe, 0x26, 0xb5, 0x34, 0x79, 0x67, 0x59, 0x93, - 0x69, 0x59, 0xf5, 0xd4, 0xf2, 0xd1, 0xe8, 0x92, 0x46, 0x51, 0xbc, 0xe2, 0x3c, 0xcb, 0xe7, 0x2c, - 0xa4, 0x65, 0xe1, 0x59, 0x45, 0x63, 0x59, 0xfd, 0xd8, 0xeb, 0x55, 0x83, 0x4d, 0x86, 0x1e, 0x2c, - 0x1b, 0x83, 0x33, 0x55, 0x60, 0x1d, 0xa6, 0xf5, 0x2c, 0x7d, 0x99, 0x54, 0x5c, 0x4b, 0xe2, 0x08, - 0x34, 0x5f, 0xc0, 0xac, 0xe2, 0x02, 0xa7, 0x66, 0x31, 0xce, 0x1c, 0x83, 0xa0, 0xec, 0x21, 0x11, - 0x9d, 0x35, 0x43, 0x48, 0xca, 0x36, 0x16, 0x2f, 0x73, 0xb3, 0xd9, 0xfc, 0x2d, 0xe0, 0x8c, 0x9f, - 0x14, 0xce, 0x44, 0xf3, 0x04, 0x9f, 0x2a, 0xea, 0x29, 0xf7, 0x88, 0x26, 0x25, 0x29, 0xa9, 0xf8, - 0xca, 0x4b, 0x59, 0xd5, 0xfa, 0xbe, 0xfd, 0x35, 0x5c, 0x4a, 0xa4, 0x16, 0x54, 0xae, 0xd1, 0xac, - 0xa4, 0x83, 0x83, 0xf7, 0xc6, 0x0d, 0x36, 0xe0, 0x18, 0x60, 0x73, 0x79, 0x38, 0xd2, 0xa4, 0x85, - 0xb5, 0x25, 0x5f, 0x37, 0xa6, 0x11, 0x97, 0x95, 0xc0, 0x70, 0xb8, 0x82, 0x8f, 0xa5, 0x2e, 0x8c, - 0x29, 0xf8, 0xf4, 0xc4, 0x86, 0x99, 0x58, 0x7f, 0x86, 0xbf, 0x9b, 0x11, 0x4b, 0x8b, 0xa7, 0x7c, - 0x64, 0x99, 0xa9, 0x10, 0xcb, 0x37, 0x07, 0xb4, 0xd0, 0x27, 0x68, 0x0b, 0xe6, 0xd2, 0x12, 0x0d, - 0x6a, 0x9e, 0xdc, 0xcc, 0x2c, 0x84, 0x29, 0x1c, 0xb5, 0xe5, 0x6a, 0xcf, 0xc0, 0x36, 0x20, 0xed, - 0x60, 0x26, 0x07, 0x7e, 0x2c, 0x93, 0x49, 0x26, 0xd3, 0x03, 0xaa, 0xc3, 0xff, 0x90, 0xfc, 0x81, - 0x03, 0x8e, 0x1a, 0x17, 0x1b, 0xee, 0x7e, 0x4f, 0xcb, 0xbe, 0xa7, 0x0e, 0x1a, 0xc9, 0x0c, 0x82, - 0x4a, 0xb3, 0xa4, 0x25, 0xeb, 0x7b, 0x1c, 0x5d, 0x66, 0xea, 0x59, 0xe2, 0x48, 0x39, 0x3b, 0x4d, - 0x9d, 0xd2, 0x32, 0xa9, 0x69, 0xe5, 0x34, 0x84, 0x7a, 0x8a, 0x36, 0x85, 0x30, 0x25, 0x5b, 0x9c, - 0x42, 0x98, 0x9a, 0xd3, 0x8d, 0xfb, 0x0c, 0xf0, 0x97, 0x43, 0x35, 0x9f, 0x81, 0x96, 0x60, 0xad, - 0x6c, 0xe6, 0x62, 0x23, 0x9f, 0xe3, 0xd1, 0x9f, 0xdf, 0x8b, 0x66, 0xdf, 0x3b, 0x18, 0x98, 0x22, - 0x25, 0xb9, 0x22, 0x7d, 0xe4, 0xd8, 0xa1, 0x89, 0x79, 0xf8, 0x69, 0x1e, 0x81, 0xcc, 0xd3, 0xbc, - 0x4e, 0x68, 0xb6, 0xf3, 0x70, 0x5a, 0x4f, 0x00, 0xa2, 0x78, 0x95, 0x92, 0x7b, 0x48, 0xf1, 0x2a, - 0x2d, 0xa3, 0x0f, 0x1e, 0x1e, 0x77, 0xe5, 0x49, 0x21, 0xc2, 0x77, 0x7d, 0x60, 0x4a, 0x9e, 0xf2, - 0xd2, 0xe0, 0x3c, 0x36, 0xe2, 0x02, 0xaa, 0x18, 0xcf, 0x51, 0x42, 0xd2, 0x32, 0x2a, 0x69, 0xa9, - 0x5f, 0x94, 0xbd, 0x9b, 0x99, 0xdc, 0x64, 0x47, 0x9e, 0x42, 0x4c, 0xbc, 0x19, 0x79, 0x75, 0x74, - 0xd4, 0x83, 0xed, 0x92, 0x28, 0x5d, 0x89, 0x7e, 0x56, 0x48, 0xa4, 0x43, 0xd1, 0xed, 0x92, 0x94, - 0x0c, 0x27, 0xae, 0x8c, 0xd4, 0x4c, 0xcf, 0xd2, 0xf7, 0xae, 0x69, 0xcd, 0x0f, 0x78, 0x12, 0x33, - 0xf4, 0x8a, 0x8f, 0xfc, 0x54, 0x66, 0x16, 0x4f, 0xe6, 0xb0, 0x7a, 0x27, 0xe6, 0x27, 0x4c, 0x7f, - 0x44, 0x51, 0x1e, 0x94, 0x22, 0x8b, 0x3c, 0xc2, 0xd7, 0xf6, 0x8f, 0x37, 0x57, 0xeb, 0x75, 0xaf, - 0xd7, 0xa3, 0xed, 0xd0, 0xf3, 0x13, 0xb7, 0x39, 0xda, 0x6f, 0xdc, 0x45, 0x4c, 0xe6, 0x4d, 0x0c, - 0xc0, 0xe6, 0x0a, 0x69, 0xe0, 0xa5, 0x82, 0x51, 0x9a, 0x72, 0xa1, 0x93, 0x82, 0xb0, 0x9c, 0x8e, - 0x70, 0xcb, 0x0d, 0x42, 0x6e, 0x0f, 0xb0, 0x85, 0x67, 0x92, 0x99, 0x41, 0xc3, 0x20, 0xb3, 0x82, - 0x8b, 0x4d, 0x3a, 0x1a, 0x49, 0xdd, 0x30, 0x39, 0x5a, 0x87, 0x79, 0xce, 0xf0, 0x58, 0xa4, 0x81, - 0x41, 0x8f, 0x56, 0x5e, 0xce, 0x28, 0x27, 0xdb, 0xb8, 0x0f, 0xc6, 0x4b, 0xb5, 0x7d, 0x30, 0x3d, - 0x94, 0x21, 0x13, 0x1f, 0x9f, 0xca, 0x46, 0xf5, 0xd1, 0xd6, 0x2b, 0x4d, 0xa5, 0x01, 0xd8, 0x5c, - 0x16, 0x53, 0x69, 0x94, 0x9e, 0x6f, 0x2a, 0x63, 0x08, 0xcd, 0xa9, 0x34, 0xc9, 0xcc, 0xa0, 0x61, - 0xf8, 0x54, 0xa6, 0xa3, 0x39, 0xf7, 0x54, 0xc6, 0xc2, 0x3c, 0x0c, 0x7a, 0xd2, 0xa6, 0x32, 0xde, - 0x9e, 0x4f, 0x65, 0xbc, 0x54, 0x9b, 0xca, 0xf4, 0x38, 0x92, 0x4c, 0x7c, 0x5f, 0x23, 0x3e, 0x1e, - 0x47, 0x72, 0xae, 0xc9, 0x2c, 0xc9, 0x43, 0x84, 0x09, 0xda, 0x5c, 0x21, 0x4f, 0xf1, 0xbc, 0x1b, - 0x2b, 0x3f, 0xdb, 0x84, 0x2e, 0x66, 0x21, 0xc5, 0x29, 0xdd, 0x84, 0x79, 0x3e, 0xa5, 0x71, 0x72, - 0x33, 0x69, 0x19, 0x34, 0x1f, 0x7c, 0x5a, 0xe3, 0xa8, 0xce, 0x3b, 0xb1, 0x8f, 0xa4, 0xd2, 0x4c, - 0x84, 0xe2, 0xc4, 0xa8, 0xd2, 0x27, 0x37, 0xb3, 0x86, 0xec, 0xe2, 0x69, 0x3e, 0x59, 0xae, 0x79, - 0x02, 0xb2, 0x62, 0x7e, 0x86, 0x62, 0x4d, 0xc4, 0xf6, 0xe8, 0x58, 0xb3, 0x02, 0x7f, 0x14, 0xd6, - 0x24, 0xf4, 0x2a, 0x2e, 0xdb, 0x5d, 0x9f, 0x9d, 0x8e, 0x3a, 0xc9, 0xa3, 0x93, 0xc9, 0x3f, 0x79, - 0xcd, 0x67, 0x36, 0x6f, 0x2e, 0x93, 0x4d, 0x14, 0x40, 0xb3, 0x78, 0xd0, 0xd9, 0x32, 0x1d, 0x0d, - 0xca, 0xc7, 0x86, 0x34, 0xc7, 0x63, 0x34, 0x65, 0xf5, 0x9d, 0x4d, 0x94, 0x3a, 0x78, 0x9f, 0x71, - 0x74, 0x59, 0xd2, 0xc1, 0xad, 0x40, 0x7e, 0xce, 0x1d, 0xc6, 0x99, 0x1d, 0xdf, 0x7b, 0xee, 0xaa, - 0x9f, 0x8a, 0x68, 0x2e, 0x93, 0x1f, 0xc2, 0xa4, 0x04, 0x1e, 0xce, 0x90, 0x38, 0x34, 0x32, 0xe4, - 0x4b, 0x98, 0x12, 0x0c, 0x41, 0x0a, 0xb2, 0x7a, 0x1a, 0x6c, 0xc8, 0x68, 0x11, 0x72, 0x9a, 0x21, - 0x93, 0x0c, 0xd5, 0xd3, 0x0c, 0x99, 0xb4, 0xa0, 0xba, 0x1f, 0xc0, 0x94, 0x60, 0xe9, 0x40, 0x6e, - 0x64, 0x7b, 0x8e, 0xe6, 0xa3, 0x70, 0x49, 0xbc, 0xc7, 0xa8, 0x7b, 0xbd, 0x67, 0xee, 0xfe, 0x50, - 0xc6, 0x24, 0x41, 0x9a, 0xcb, 0xa4, 0x89, 0xe9, 0x5a, 0xe4, 0x1b, 0x0c, 0x1a, 0xbe, 0xf0, 0xfc, - 0x43, 0xb7, 0xb7, 0x3f, 0x04, 0xe5, 0x0d, 0x13, 0x65, 0x1c, 0x8e, 0xe3, 0x6d, 0x64, 0xe3, 0x1d, - 0x0a, 0x9f, 0x39, 0xfa, 0x6d, 0x58, 0xc4, 0xcb, 0xd9, 0xf3, 0x52, 0x9c, 0x7d, 0xdc, 0xbe, 0x1a, - 0x85, 0x56, 0xd9, 0xb4, 0xed, 0xf9, 0x9d, 0xe1, 0xc8, 0x2a, 0x66, 0x98, 0x54, 0x0c, 0xac, 0xb9, - 0xcc, 0xb0, 0x36, 0x32, 0xb1, 0x0e, 0x83, 0x1e, 0xa0, 0x61, 0xaf, 0xe1, 0xd8, 0xcf, 0x49, 0x6d, - 0xb6, 0xe3, 0x08, 0x83, 0x51, 0x8e, 0xc3, 0x83, 0x1d, 0x9f, 0x3e, 0xa3, 0x3e, 0xc6, 0xc7, 0x0d, - 0x8b, 0x0c, 0x33, 0x9b, 0x37, 0x97, 0x19, 0x96, 0x46, 0x02, 0x4b, 0x56, 0xeb, 0x41, 0xc6, 0x05, - 0x0e, 0xed, 0x8c, 0xd4, 0x64, 0x5f, 0xfe, 0x4e, 0xaa, 0xa4, 0x6c, 0x44, 0x3b, 0x54, 0x1a, 0x29, - 0xc7, 0xca, 0x33, 0x7a, 0x1c, 0x57, 0x40, 0xaa, 0xdc, 0x86, 0xd3, 0x93, 0x93, 0x69, 0xb7, 0x24, - 0xa9, 0x59, 0xcb, 0xe2, 0x28, 0xf8, 0xa1, 0x78, 0xcb, 0x6b, 0x1f, 0xea, 0x87, 0x62, 0x2d, 0xdb, - 0x55, 0xd9, 0xcc, 0x45, 0x25, 0xd4, 0x21, 0x26, 0xa4, 0xd2, 0xef, 0xc3, 0xf5, 0x7c, 0x57, 0xfa, - 0xa1, 0xd8, 0xcc, 0xcc, 0xa5, 0x0e, 0xc5, 0xd8, 0xa1, 0x89, 0x79, 0xf8, 0xa1, 0x18, 0x81, 0xcc, - 0x43, 0xb1, 0x4e, 0x68, 0xf6, 0xc2, 0x23, 0xc9, 0xd4, 0x5c, 0xca, 0xdc, 0xca, 0xcc, 0xda, 0x35, - 0xe0, 0xca, 0xfc, 0x72, 0x4a, 0x36, 0x41, 0x75, 0xd8, 0xcc, 0xce, 0x34, 0x58, 0x36, 0xef, 0x7f, - 0xef, 0xe5, 0xc8, 0x36, 0xfe, 0xca, 0x89, 0x50, 0x05, 0x36, 0x0d, 0x42, 0xdf, 0x6d, 0x87, 0x03, - 0xdd, 0xc3, 0xd2, 0xba, 0x4a, 0x81, 0x69, 0x7e, 0xc0, 0xf0, 0x35, 0xd2, 0xf1, 0x0d, 0x84, 0x1b, - 0xe0, 0x4f, 0xb8, 0x2a, 0xe2, 0xf6, 0xce, 0x41, 0x62, 0xb6, 0x88, 0x4f, 0xf0, 0x3b, 0xb0, 0x6c, - 0xd0, 0x62, 0xf4, 0x2e, 0x5d, 0xd8, 0x8b, 0x77, 0x60, 0x9c, 0x03, 0x65, 0xee, 0x36, 0xd3, 0x3a, - 0x0c, 0x79, 0x5f, 0x46, 0xb4, 0x30, 0x10, 0xa3, 0x2a, 0x93, 0xae, 0xf7, 0x61, 0x92, 0x3b, 0x90, - 0xcf, 0x0e, 0xf2, 0xb9, 0x8c, 0x7b, 0x19, 0x44, 0x58, 0x76, 0xb8, 0xd9, 0x8c, 0x7e, 0xa1, 0x76, - 0x7e, 0x46, 0xfe, 0x00, 0x9d, 0xf8, 0xd2, 0x69, 0x96, 0x0d, 0x3f, 0x1f, 0xcb, 0x11, 0x20, 0x58, - 0xfa, 0x09, 0xde, 0x24, 0xa8, 0xb4, 0x9c, 0x59, 0xe4, 0x5f, 0x4a, 0x40, 0x93, 0xcf, 0x61, 0x96, - 0x33, 0x57, 0x01, 0x27, 0x1b, 0x0d, 0xe0, 0xd9, 0x2c, 0x67, 0xf3, 0xab, 0x00, 0xff, 0x50, 0x5e, - 0x39, 0x0c, 0x25, 0xfb, 0x2c, 0x97, 0x0d, 0xc3, 0x59, 0x97, 0x85, 0xe5, 0xa7, 0xb8, 0xe9, 0xa6, - 0xa7, 0xe0, 0xcb, 0x44, 0x76, 0x5b, 0xbb, 0x4c, 0x19, 0x9c, 0xbc, 0xef, 0x10, 0x23, 0x9f, 0x53, - 0x1b, 0x29, 0x57, 0xef, 0x90, 0x9c, 0x7c, 0xe5, 0xef, 0x0d, 0x6d, 0xa7, 0x1c, 0xac, 0xe2, 0x27, - 0x76, 0xd2, 0xfb, 0x1b, 0x92, 0x88, 0x2f, 0xc5, 0xf9, 0x9d, 0x91, 0xdf, 0x4e, 0x22, 0x34, 0xc3, - 0x2a, 0x06, 0x8e, 0x21, 0x8b, 0xfd, 0x5f, 0x6b, 0xbf, 0x94, 0x73, 0xce, 0x49, 0xc8, 0x36, 0xa3, - 0x48, 0x32, 0xeb, 0x1f, 0x19, 0xf4, 0x38, 0x5e, 0xbf, 0x5a, 0xc8, 0xca, 0x16, 0xb8, 0x2e, 0xc3, - 0xec, 0x63, 0x99, 0x26, 0xb2, 0x72, 0x56, 0x0c, 0x38, 0xe4, 0x8a, 0x40, 0xf3, 0x37, 0x82, 0x28, - 0x39, 0xdb, 0xe7, 0x47, 0xa4, 0xae, 0x38, 0x62, 0x88, 0xac, 0x01, 0xd3, 0x3b, 0xdc, 0xdb, 0x5a, - 0xca, 0x98, 0xd7, 0xf3, 0x4f, 0xa8, 0x13, 0x05, 0x57, 0x27, 0x53, 0x13, 0xaa, 0x6d, 0x3f, 0x33, - 0x4d, 0xa2, 0x9a, 0xdd, 0x01, 0x79, 0x0d, 0xeb, 0xd1, 0x0f, 0x6a, 0x1a, 0xb9, 0x0c, 0xeb, 0xf6, - 0x96, 0x3a, 0x5e, 0xa5, 0x25, 0x39, 0x2c, 0x83, 0xac, 0xb4, 0xb7, 0xd8, 0x5a, 0xcf, 0x4a, 0xa1, - 0x17, 0xc5, 0x74, 0x0e, 0xce, 0x52, 0xa8, 0xd6, 0xfa, 0xd0, 0x5c, 0x7c, 0xdb, 0x30, 0x97, 0x96, - 0xfa, 0x4e, 0x4d, 0xda, 0x80, 0xbc, 0x78, 0xa9, 0x81, 0xa3, 0x3b, 0x30, 0x9f, 0x9a, 0x7e, 0x4e, - 0xdd, 0xf5, 0x0d, 0x4a, 0x4e, 0x97, 0x8a, 0xf1, 0x1b, 0x58, 0xc8, 0xc8, 0xb5, 0x16, 0x79, 0xae, - 0x07, 0xe6, 0x62, 0xcb, 0x14, 0x88, 0x6f, 0xa1, 0x9c, 0x9d, 0xc6, 0x8b, 0xdc, 0x36, 0xbd, 0xef, - 0xd9, 0xc9, 0xb3, 0xca, 0xa9, 0x79, 0x07, 0xc9, 0x2e, 0x26, 0x08, 0x4e, 0xcb, 0xeb, 0xa5, 0xe8, - 0x1e, 0x9c, 0xf7, 0x2b, 0x23, 0xe0, 0x77, 0x21, 0x23, 0x95, 0xd7, 0x00, 0xac, 0x67, 0xa0, 0x76, - 0x5b, 0xea, 0x25, 0x33, 0xb7, 0x53, 0xec, 0xf9, 0x4f, 0x6a, 0xe2, 0xa7, 0x54, 0x3a, 0x1f, 0xc0, - 0x8c, 0x91, 0x5c, 0x43, 0x89, 0x7f, 0x5a, 0x86, 0x17, 0xe5, 0x5d, 0x48, 0xcf, 0xc7, 0xb1, 0x86, - 0x57, 0x2e, 0xd1, 0xf3, 0xca, 0x01, 0x36, 0x70, 0x74, 0xb5, 0x9b, 0x7c, 0xc5, 0xf9, 0x10, 0x0f, - 0x45, 0xc6, 0xa3, 0xcc, 0x01, 0xc7, 0x61, 0x85, 0x29, 0xf5, 0x15, 0x67, 0xad, 0xf8, 0xcb, 0xff, - 0xbe, 0x94, 0xfb, 0xe5, 0xaf, 0x97, 0x72, 0xff, 0xf9, 0xd7, 0x4b, 0xb9, 0x5f, 0xfd, 0x7a, 0x29, - 0xb7, 0x37, 0x8e, 0x10, 0x2b, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x23, 0x18, 0x56, 0x17, 0xcc, - 0x9e, 0x00, 0x00, + // 10858 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0xbd, 0x5b, 0x6c, 0x1c, 0x49, + 0xb2, 0x18, 0xaa, 0x6e, 0x92, 0x22, 0x19, 0x7c, 0xa8, 0x95, 0x22, 0xc5, 0x56, 0x8b, 0x62, 0x4b, + 0x35, 0x8f, 0xd5, 0xcc, 0xd9, 0x95, 0x34, 0xe4, 0xbc, 0x67, 0x76, 0xe6, 0x74, 0x37, 0x29, 0x91, + 0x12, 0x45, 0x71, 0xaa, 0xa9, 0xd6, 0xec, 0xee, 0xec, 0xf6, 0x16, 0xbb, 0x53, 0x64, 0x5d, 0x36, + 0xab, 0x7a, 0xab, 0x8a, 0xd2, 0x08, 0x17, 0x36, 0xfc, 0x5a, 0xdb, 0xb0, 0x61, 0x9c, 0x35, 0xe0, + 0x03, 0xfb, 0xc0, 0x1f, 0x3e, 0x80, 0x01, 0x7f, 0x18, 0xb0, 0x3f, 0xfc, 0xfc, 0x31, 0x70, 0x60, + 0xc0, 0x8f, 0xb5, 0x01, 0x03, 0xfe, 0x39, 0x30, 0xe0, 0x0f, 0x7a, 0xbd, 0x9f, 0x84, 0x01, 0xc3, + 0x30, 0x6c, 0xc0, 0xfb, 0x65, 0x64, 0xe4, 0xa3, 0x32, 0xeb, 0xd1, 0x4d, 0x4a, 0xf2, 0x9e, 0x1f, + 0x89, 0x95, 0x19, 0x11, 0x99, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x0d, 0x17, 0x9d, 0xa3, + 0x68, 0x3f, 0xa4, 0xc1, 0x33, 0xb7, 0x43, 0x6f, 0xf5, 0x03, 0x3f, 0xf2, 0xc9, 0x18, 0xfe, 0x57, + 0x99, 0xdb, 0xf3, 0xf7, 0x7c, 0xfc, 0xf3, 0x36, 0xfb, 0x8b, 0x57, 0x56, 0xae, 0xee, 0xf9, 0xfe, + 0x5e, 0x8f, 0xde, 0xc6, 0xaf, 0xdd, 0xa3, 0xa7, 0xb7, 0xe9, 0x61, 0x3f, 0x7a, 0x21, 0x2a, 0xab, + 0xc9, 0xca, 0xc8, 0x3d, 0xa4, 0x61, 0xe4, 0x1c, 0xf6, 0x05, 0xc0, 0x54, 0x87, 0x06, 0x51, 0x28, + 0x3e, 0x3e, 0xda, 0x73, 0xa3, 0xfd, 0xa3, 0xdd, 0x5b, 0x1d, 0xff, 0xf0, 0xf6, 0x5e, 0xe0, 0x3c, + 0x73, 0x23, 0x27, 0x72, 0x7d, 0xcf, 0xe9, 0xdd, 0x8e, 0x68, 0x8f, 0xf6, 0xfd, 0x20, 0xba, 0xed, + 0xf4, 0xdd, 0xdb, 0xd1, 0x8b, 0x3e, 0x0d, 0xf9, 0xbf, 0x02, 0xb1, 0x71, 0x16, 0xc4, 0xe7, 0x74, + 0x97, 0x0d, 0xd1, 0x53, 0x7f, 0xbc, 0x14, 0x91, 0xc0, 0xe9, 0xf7, 0x69, 0x10, 0xff, 0x21, 0x88, + 0x7c, 0x79, 0x16, 0x22, 0xf4, 0x19, 0xf5, 0x22, 0xf9, 0x1f, 0x27, 0x60, 0xfd, 0xde, 0x3c, 0x8c, + 0xad, 0xb1, 0x02, 0xf2, 0x31, 0x8c, 0xee, 0xbc, 0xe8, 0xd3, 0x72, 0xe1, 0x7a, 0xe1, 0xe6, 0xec, + 0x72, 0x89, 0xd7, 0xdf, 0x7a, 0xd4, 0xa7, 0x01, 0x92, 0xac, 0x93, 0x93, 0xe3, 0xea, 0x2c, 0x23, + 0xf4, 0x5d, 0xff, 0xd0, 0x8d, 0x90, 0xeb, 0x36, 0x62, 0x90, 0x27, 0x30, 0x6b, 0xd3, 0xd0, 0x3f, + 0x0a, 0x3a, 0x74, 0x9d, 0x3a, 0x5d, 0x1a, 0x94, 0x8b, 0xd7, 0x0b, 0x37, 0xa7, 0x96, 0xe7, 0x6f, + 0x71, 0xa6, 0x99, 0x95, 0xf5, 0xcb, 0x27, 0xc7, 0x55, 0x12, 0x88, 0xb2, 0x98, 0xd8, 0xfa, 0x39, + 0x3b, 0x41, 0x86, 0x7c, 0x03, 0x33, 0x0d, 0x1a, 0x44, 0xb5, 0xa3, 0x68, 0xdf, 0x0f, 0xdc, 0xe8, + 0x45, 0x79, 0x04, 0xe9, 0x5e, 0x16, 0x74, 0x8d, 0xba, 0xd6, 0x72, 0x7d, 0xf1, 0xe4, 0xb8, 0x5a, + 0x66, 0x13, 0xdc, 0x76, 0x64, 0xa9, 0x41, 0xde, 0x24, 0x46, 0xbe, 0x86, 0xe9, 0x26, 0x63, 0x57, + 0x67, 0xc7, 0x3f, 0xa0, 0x5e, 0x58, 0x1e, 0x35, 0x3a, 0xad, 0x57, 0xb5, 0x96, 0xeb, 0x57, 0x4f, + 0x8e, 0xab, 0x0b, 0x21, 0x96, 0xb5, 0x23, 0x2c, 0x34, 0x48, 0x1b, 0x94, 0xc8, 0x4f, 0x61, 0x76, + 0x3b, 0xf0, 0x9f, 0xb9, 0xa1, 0xeb, 0x7b, 0x58, 0x54, 0x1e, 0x43, 0xda, 0x0b, 0x82, 0xb6, 0x59, + 0xd9, 0x5a, 0xae, 0x5f, 0x3b, 0x39, 0xae, 0x5e, 0xe9, 0xcb, 0x52, 0xde, 0x80, 0xc9, 0x19, 0x13, + 0x85, 0xec, 0xc0, 0x54, 0xa3, 0x77, 0x14, 0x46, 0x34, 0xd8, 0x72, 0x0e, 0x69, 0xf9, 0x3c, 0x92, + 0x9f, 0x93, 0x7c, 0x89, 0x6b, 0x5a, 0xcb, 0xf5, 0xca, 0xc9, 0x71, 0xf5, 0x72, 0x87, 0x17, 0xb5, + 0x3d, 0xe7, 0xd0, 0x64, 0xb9, 0x4e, 0x86, 0x7c, 0x04, 0xa3, 0x8f, 0x43, 0x1a, 0x94, 0x27, 0x90, + 0xdc, 0x8c, 0x20, 0xc7, 0x8a, 0x5a, 0xcb, 0x7c, 0xfe, 0x8f, 0x42, 0x1a, 0x18, 0xf8, 0x88, 0xc0, + 0x10, 0x6d, 0xbf, 0x47, 0xcb, 0x93, 0x06, 0x22, 0x2b, 0x6a, 0x7d, 0xc0, 0x11, 0x03, 0xbf, 0x67, + 0x36, 0x8c, 0x08, 0x64, 0x03, 0x26, 0x59, 0xcb, 0x61, 0xdf, 0xe9, 0xd0, 0x32, 0x20, 0x76, 0x49, + 0x60, 0xab, 0xf2, 0xfa, 0xc2, 0xc9, 0x71, 0xf5, 0x92, 0x27, 0x3f, 0x0d, 0x2a, 0x31, 0x36, 0xf9, + 0x12, 0xce, 0x37, 0x69, 0xf0, 0x8c, 0x06, 0xe5, 0x29, 0xa4, 0x73, 0x41, 0x4e, 0x24, 0x16, 0xb6, + 0x96, 0xeb, 0x73, 0x27, 0xc7, 0xd5, 0x52, 0x88, 0x5f, 0x06, 0x0d, 0x81, 0xc6, 0xa4, 0xcd, 0xa6, + 0xcf, 0x68, 0x10, 0xd2, 0x9d, 0x23, 0xcf, 0xa3, 0xbd, 0xf2, 0xb4, 0x21, 0x6d, 0x46, 0x9d, 0x94, + 0xb6, 0x80, 0x17, 0xb6, 0x23, 0x2c, 0x35, 0xa5, 0xcd, 0x40, 0x20, 0xfb, 0x50, 0xe2, 0x7f, 0x35, + 0x7c, 0xcf, 0xa3, 0x1d, 0xb6, 0xa4, 0xca, 0x33, 0xd8, 0xc0, 0x15, 0xd1, 0x40, 0xb2, 0xba, 0xb5, + 0x5c, 0xaf, 0x9e, 0x1c, 0x57, 0xaf, 0x72, 0xda, 0xed, 0x8e, 0xaa, 0x30, 0x9a, 0x49, 0x51, 0x65, + 0xe3, 0xa8, 0x75, 0x3a, 0x34, 0x0c, 0x6d, 0xfa, 0xb3, 0x23, 0x1a, 0x46, 0xe5, 0x59, 0x63, 0x1c, + 0x46, 0x5d, 0x6b, 0x85, 0x8f, 0xc3, 0xc1, 0xc2, 0x76, 0xc0, 0x4b, 0xcd, 0x71, 0x18, 0x08, 0x64, + 0x1b, 0xa0, 0xd6, 0xef, 0x37, 0x69, 0xc8, 0x84, 0xb1, 0x7c, 0x01, 0x49, 0x5f, 0x12, 0xa4, 0x9f, + 0xd0, 0x5d, 0x51, 0xd1, 0x5a, 0xae, 0x5f, 0x39, 0x39, 0xae, 0xce, 0x3b, 0xfd, 0x7e, 0x3b, 0xe4, + 0x45, 0x06, 0x51, 0x8d, 0x06, 0xe7, 0xfb, 0xa1, 0x1f, 0x51, 0x21, 0x8a, 0xe5, 0x52, 0x82, 0xef, + 0x5a, 0x9d, 0xec, 0x6f, 0x80, 0x85, 0x6d, 0x21, 0xd6, 0x49, 0xbe, 0x6b, 0x08, 0x6c, 0x2d, 0xae, + 0x3a, 0x91, 0xb3, 0xeb, 0x84, 0x54, 0x88, 0xc7, 0x45, 0x63, 0x2d, 0x9a, 0x95, 0xad, 0x15, 0xbe, + 0x16, 0xbb, 0xa2, 0xb4, 0x9d, 0x21, 0x2f, 0x09, 0x7a, 0x8c, 0x23, 0xf1, 0xc0, 0xcb, 0x64, 0x08, + 0x47, 0x9e, 0xd3, 0xdd, 0x6c, 0x8e, 0xc4, 0xa0, 0x64, 0x1d, 0x26, 0x9e, 0xd0, 0x5d, 0xae, 0x39, + 0x2e, 0x21, 0xbd, 0x8b, 0x31, 0x3d, 0xae, 0x33, 0x56, 0xf8, 0xaa, 0x60, 0xd4, 0xd2, 0xda, 0x42, + 0x61, 0x93, 0x9f, 0x17, 0x60, 0x41, 0xae, 0x70, 0x1a, 0x3d, 0xf7, 0x83, 0x03, 0xd7, 0xdb, 0x6b, + 0xf8, 0xde, 0x53, 0x77, 0xaf, 0x3c, 0x87, 0x94, 0xaf, 0x27, 0x94, 0x46, 0x02, 0xaa, 0xb5, 0x5c, + 0xff, 0xce, 0xc9, 0x71, 0xf5, 0x0d, 0xa5, 0x40, 0x54, 0x3d, 0x13, 0xc8, 0xa7, 0xee, 0x9e, 0xd1, + 0x70, 0x5e, 0x5b, 0xe4, 0xcf, 0x16, 0xe0, 0xb2, 0x18, 0x9d, 0x4d, 0x3b, 0x7e, 0xd0, 0x8d, 0xbb, + 0x31, 0x8f, 0xdd, 0xa8, 0xaa, 0xd5, 0x9a, 0x05, 0xd4, 0x5a, 0xae, 0xbf, 0x7d, 0x72, 0x5c, 0xb5, + 0x04, 0xe3, 0xda, 0x81, 0xac, 0xce, 0xea, 0x44, 0x4e, 0x43, 0x4c, 0x12, 0x98, 0xf2, 0xdf, 0x0e, + 0xe8, 0x53, 0x1a, 0x50, 0xaf, 0x43, 0xcb, 0x97, 0x0d, 0x49, 0x30, 0x2b, 0xa5, 0x56, 0x66, 0x5b, + 0x49, 0xbb, 0xaf, 0x8a, 0x4d, 0x49, 0x30, 0x51, 0xc8, 0xcf, 0x80, 0x08, 0x06, 0xd4, 0x8e, 0xba, + 0x6e, 0x24, 0x06, 0xb8, 0x80, 0xad, 0x5c, 0x35, 0xf9, 0xac, 0x01, 0xb4, 0x96, 0xeb, 0xd6, 0xc9, + 0x71, 0x75, 0x49, 0xb2, 0xd8, 0x61, 0x55, 0x59, 0x03, 0xcb, 0x20, 0xce, 0x34, 0xef, 0xa6, 0xdf, + 0x39, 0x28, 0x97, 0x0d, 0xcd, 0xcb, 0x8a, 0xa4, 0xca, 0xee, 0xf9, 0x9d, 0x03, 0x53, 0xf3, 0xb2, + 0x5a, 0x12, 0xc1, 0x25, 0x31, 0x4b, 0x36, 0x0d, 0xa3, 0xc0, 0x45, 0xdd, 0x11, 0x96, 0xaf, 0x20, + 0x9d, 0x45, 0xa9, 0x83, 0xd3, 0x10, 0xad, 0xf7, 0x79, 0x6f, 0x85, 0x20, 0xb4, 0x03, 0xad, 0xce, + 0x68, 0x26, 0x8b, 0x3c, 0xf9, 0x53, 0x30, 0xff, 0xc4, 0xf5, 0xba, 0xfe, 0xf3, 0x70, 0x95, 0x86, + 0x07, 0x91, 0xdf, 0x6f, 0x72, 0xcb, 0xaf, 0x5c, 0xc1, 0x76, 0x97, 0xa4, 0x98, 0x67, 0xc1, 0xb4, + 0x56, 0xea, 0x6f, 0x9d, 0x1c, 0x57, 0x6f, 0x3c, 0xe7, 0x95, 0xed, 0x2e, 0xaf, 0x6d, 0x0b, 0xe3, + 0xd1, 0x68, 0x3c, 0xbb, 0x15, 0x26, 0x02, 0x66, 0x45, 0xf9, 0xaa, 0x21, 0x02, 0x66, 0xa5, 0x54, + 0x06, 0x89, 0x06, 0x4d, 0x11, 0x30, 0x51, 0xc8, 0x3d, 0x98, 0x90, 0xea, 0xa1, 0xbc, 0x68, 0x2c, + 0x5d, 0x59, 0xdc, 0x5a, 0xe1, 0x16, 0x90, 0x54, 0x31, 0xe6, 0xca, 0x95, 0x50, 0x64, 0x13, 0x26, + 0x51, 0x47, 0xa2, 0xca, 0xba, 0x86, 0x94, 0x88, 0x14, 0x54, 0x59, 0xde, 0x5a, 0xa9, 0x97, 0x4f, + 0x8e, 0xab, 0x73, 0x5c, 0xcb, 0xa6, 0x14, 0x55, 0x4c, 0x80, 0xac, 0xc0, 0x48, 0xad, 0xdf, 0x2f, + 0x2f, 0x21, 0x9d, 0xe9, 0x98, 0x4e, 0x6b, 0xa5, 0x7e, 0xf1, 0xe4, 0xb8, 0x3a, 0xe3, 0xf4, 0xcd, + 0x61, 0x31, 0x68, 0xb2, 0x0b, 0xa5, 0xa6, 0xe7, 0x3f, 0x7f, 0xda, 0x73, 0x0e, 0xa8, 0x54, 0x6f, + 0xd5, 0x7c, 0xf5, 0x86, 0x9b, 0x55, 0x28, 0x11, 0x32, 0x95, 0x5c, 0x8a, 0x5e, 0x1d, 0x60, 0x42, + 0x1a, 0x7d, 0xf7, 0x47, 0x27, 0xc6, 0x4b, 0x13, 0xd6, 0x3a, 0x8c, 0x3d, 0x71, 0xa2, 0xce, 0x3e, + 0xf9, 0x12, 0xc6, 0x1e, 0xb8, 0x5e, 0x37, 0x2c, 0x17, 0xae, 0x8f, 0xa0, 0x5d, 0xc0, 0x2d, 0x52, + 0xac, 0x64, 0x15, 0xf5, 0x85, 0x5f, 0x1e, 0x57, 0xcf, 0x9d, 0x1c, 0x57, 0x2f, 0x1c, 0x30, 0x30, + 0xcd, 0x2c, 0xe5, 0x78, 0xd6, 0x3f, 0x29, 0xc2, 0xa4, 0x82, 0x26, 0x8b, 0x30, 0xca, 0xfe, 0x47, + 0xfb, 0x76, 0xb2, 0x3e, 0x71, 0x72, 0x5c, 0x1d, 0x65, 0x78, 0x36, 0x96, 0x92, 0x65, 0x98, 0xda, + 0xf4, 0x9d, 0x6e, 0x93, 0x76, 0x02, 0x1a, 0x85, 0x68, 0xc0, 0x4e, 0xd4, 0x4b, 0x27, 0xc7, 0xd5, + 0xe9, 0x9e, 0xef, 0x74, 0xdb, 0x21, 0x2f, 0xb7, 0x75, 0x20, 0x46, 0x11, 0xad, 0xaf, 0x91, 0x98, + 0x22, 0xb3, 0x52, 0x6c, 0x2c, 0x25, 0xf7, 0xe1, 0xfc, 0x5d, 0xb7, 0xc7, 0xf6, 0xb3, 0x51, 0xec, + 0xff, 0x62, 0xb2, 0xff, 0xb7, 0x78, 0xf5, 0x9a, 0x17, 0x05, 0x2f, 0xb8, 0x71, 0xf2, 0x14, 0x0b, + 0xb4, 0x81, 0x08, 0x0a, 0xe4, 0x0e, 0x8c, 0x37, 0x8f, 0x76, 0xb1, 0xfb, 0x63, 0xd8, 0x18, 0x4a, + 0x50, 0x78, 0xb4, 0xdb, 0x66, 0x43, 0xd0, 0x10, 0x24, 0x58, 0xe5, 0x13, 0x98, 0xd2, 0xc8, 0x93, + 0x12, 0x8c, 0x1c, 0xd0, 0x17, 0x7c, 0xec, 0x36, 0xfb, 0x93, 0xcc, 0xc1, 0xd8, 0x33, 0xa7, 0x77, + 0x44, 0x71, 0xa8, 0x93, 0x36, 0xff, 0xf8, 0xb4, 0xf8, 0x71, 0xc1, 0xfa, 0xa7, 0xe7, 0xa1, 0xb4, + 0xee, 0x87, 0x11, 0xb3, 0x96, 0xd5, 0xb6, 0xff, 0x06, 0x9c, 0x67, 0x65, 0x1b, 0xab, 0x82, 0x7f, + 0x53, 0x27, 0xc7, 0xd5, 0xf1, 0x7d, 0x3f, 0x8c, 0xda, 0x6e, 0xd7, 0x16, 0x55, 0xe4, 0x1d, 0x98, + 0xd8, 0xf2, 0xbb, 0x14, 0x99, 0x82, 0x64, 0xeb, 0x33, 0x27, 0xc7, 0xd5, 0x49, 0xcf, 0xef, 0x52, + 0xb4, 0x3c, 0x6d, 0x55, 0x4d, 0x5a, 0xc2, 0x62, 0xe4, 0xbc, 0xab, 0x33, 0xde, 0x31, 0x13, 0xf1, + 0x37, 0xc7, 0xd5, 0x0f, 0xcf, 0x70, 0xa4, 0xb9, 0xd5, 0x7c, 0x11, 0x46, 0xf4, 0x90, 0x51, 0x12, + 0x06, 0xe5, 0x13, 0x98, 0xab, 0x75, 0xbb, 0x2e, 0xc7, 0xd8, 0x0e, 0x5c, 0xaf, 0xe3, 0xf6, 0x9d, + 0x5e, 0x88, 0x73, 0x30, 0x59, 0x7f, 0xe3, 0xe4, 0xb8, 0x5a, 0x75, 0x54, 0x7d, 0xbb, 0xaf, 0x00, + 0x34, 0x1e, 0x66, 0x12, 0x20, 0x2b, 0x30, 0xb1, 0xba, 0xd5, 0x44, 0x73, 0xb3, 0x3c, 0x86, 0xc4, + 0x70, 0x03, 0xee, 0x7a, 0x21, 0x0e, 0x4d, 0x27, 0xa0, 0x00, 0xc9, 0x87, 0x30, 0xbd, 0x7d, 0xb4, + 0xdb, 0x73, 0x3b, 0x3b, 0x9b, 0xcd, 0x07, 0xf4, 0x05, 0xda, 0xe9, 0xd3, 0x5c, 0x2d, 0xf7, 0xb1, + 0xbc, 0x1d, 0xf5, 0xc2, 0xf6, 0x01, 0x7d, 0x61, 0x1b, 0x70, 0x31, 0x5e, 0xb3, 0xb9, 0xce, 0xf0, + 0xc6, 0x53, 0x78, 0x61, 0xb8, 0xaf, 0xe3, 0x71, 0x38, 0x72, 0x1b, 0x80, 0x5b, 0x3f, 0xb5, 0x6e, + 0x97, 0x9b, 0xf1, 0x93, 0xf5, 0x0b, 0x27, 0xc7, 0xd5, 0x29, 0x61, 0x2f, 0x39, 0xdd, 0x6e, 0x60, + 0x6b, 0x20, 0xa4, 0x01, 0x13, 0xb6, 0xcf, 0x19, 0x2c, 0x8c, 0xf7, 0x0b, 0xca, 0x78, 0xe7, 0xc5, + 0xe2, 0xb8, 0x26, 0xbe, 0xf4, 0x51, 0x4a, 0x08, 0x52, 0x85, 0xf1, 0x2d, 0xbf, 0xe1, 0x74, 0xf6, + 0xb9, 0x09, 0x3f, 0x51, 0x1f, 0x3b, 0x39, 0xae, 0x16, 0xbe, 0x67, 0xcb, 0x52, 0xf2, 0x0c, 0xa6, + 0xe2, 0x89, 0x0a, 0xcb, 0x53, 0xc8, 0xbe, 0x1d, 0x76, 0x2e, 0x09, 0xb1, 0xb8, 0xcd, 0xa6, 0x5e, + 0xe3, 0xe0, 0x2b, 0x48, 0x81, 0xde, 0x10, 0xe9, 0xc1, 0xb5, 0xc7, 0x5e, 0x18, 0x39, 0xbb, 0x3d, + 0x1a, 0x17, 0xd7, 0xc2, 0x90, 0x06, 0x8c, 0xd6, 0xc6, 0x2a, 0x5a, 0xf8, 0x93, 0xc2, 0xb4, 0x88, + 0x7b, 0xd2, 0x76, 0x24, 0x48, 0xdb, 0xd5, 0x17, 0xd7, 0x60, 0x62, 0xd6, 0x7f, 0x9f, 0x80, 0x12, + 0x3b, 0x0d, 0x19, 0xeb, 0xe6, 0xbb, 0x30, 0xc9, 0x67, 0xe8, 0x81, 0x58, 0x7e, 0xd3, 0xf5, 0xd9, + 0x93, 0xe3, 0x2a, 0x88, 0x69, 0x64, 0x53, 0x18, 0x03, 0x90, 0x9b, 0x30, 0xc1, 0x28, 0x78, 0xf1, + 0x02, 0x9a, 0x3e, 0x39, 0xae, 0x4e, 0x1c, 0x89, 0x32, 0x5b, 0xd5, 0x92, 0x26, 0x8c, 0xaf, 0x7d, + 0xdb, 0x77, 0x03, 0x1a, 0x8a, 0x43, 0x71, 0xe5, 0x16, 0xf7, 0x7d, 0xdc, 0x92, 0xbe, 0x8f, 0x5b, + 0x3b, 0xd2, 0xf7, 0x51, 0xbf, 0x26, 0x14, 0xe5, 0x45, 0xca, 0x51, 0xe2, 0x31, 0xfd, 0xe2, 0xbf, + 0x54, 0x0b, 0xb6, 0xa4, 0x44, 0xbe, 0x0b, 0xe7, 0xef, 0xfa, 0xc1, 0xa1, 0x13, 0xe1, 0x59, 0x78, + 0x52, 0x28, 0x25, 0x2c, 0x31, 0x94, 0x12, 0x96, 0x90, 0xbb, 0x30, 0x6b, 0xfb, 0x47, 0x11, 0xdd, + 0xf1, 0xa5, 0xe1, 0xce, 0x75, 0xd3, 0xd2, 0xc9, 0x71, 0xb5, 0x12, 0xb0, 0x9a, 0x76, 0xe4, 0xa7, + 0x4d, 0x74, 0x3b, 0x81, 0x45, 0xd6, 0x60, 0xd6, 0x38, 0x62, 0x84, 0xe5, 0xf3, 0x28, 0x20, 0xdc, + 0xfc, 0x32, 0x0e, 0x26, 0xfa, 0x2a, 0x4b, 0x20, 0x91, 0x2d, 0xb8, 0xf8, 0xe0, 0x68, 0x97, 0x06, + 0x1e, 0x8d, 0x68, 0x28, 0x7b, 0x34, 0x8e, 0x3d, 0xba, 0x7e, 0x72, 0x5c, 0x5d, 0x3c, 0x50, 0x95, + 0x19, 0x7d, 0x4a, 0xa3, 0x12, 0x0a, 0x17, 0x44, 0x47, 0xd5, 0x86, 0x3e, 0x21, 0x0e, 0x26, 0x5c, + 0x91, 0x27, 0x6a, 0xeb, 0x6f, 0x08, 0x2e, 0x5f, 0x55, 0x63, 0x4f, 0x6f, 0xf1, 0x76, 0x92, 0x26, + 0xd3, 0x2b, 0x4a, 0x67, 0x4e, 0x62, 0x6f, 0xf9, 0x71, 0x57, 0xea, 0x4c, 0x7d, 0xc5, 0x29, 0xed, + 0xb9, 0x09, 0x63, 0x8f, 0x43, 0x67, 0x8f, 0xaf, 0xb7, 0xd9, 0xe5, 0x1b, 0xa2, 0x47, 0x49, 0xe9, + 0x43, 0x0f, 0x09, 0x02, 0xd6, 0x2f, 0xb1, 0x7d, 0xf2, 0x88, 0xfd, 0xa9, 0xef, 0x93, 0x58, 0x47, + 0xbe, 0x02, 0x10, 0xbd, 0x62, 0x36, 0xc2, 0x94, 0xb0, 0x5a, 0x8c, 0x41, 0xd6, 0xfa, 0xfd, 0xfa, + 0x92, 0x18, 0xdf, 0x65, 0x35, 0x3e, 0xc3, 0x6a, 0xb0, 0x35, 0x22, 0xe4, 0x4b, 0x98, 0xc6, 0xe5, + 0x28, 0x67, 0x74, 0x1a, 0x67, 0x14, 0x9d, 0x28, 0xb8, 0xc2, 0x32, 0xe6, 0xd3, 0x40, 0x20, 0x7f, + 0x1a, 0xe6, 0x05, 0xb9, 0x84, 0xc1, 0x36, 0x23, 0x0c, 0x54, 0xa3, 0x7b, 0x26, 0x4c, 0xfd, 0x5d, + 0xd1, 0x53, 0x4b, 0xf5, 0x34, 0xd7, 0x84, 0xb3, 0xb3, 0x9b, 0x21, 0x1b, 0x70, 0xe1, 0x71, 0x48, + 0x8d, 0x31, 0xcc, 0xa2, 0x6e, 0x43, 0x2b, 0xe7, 0x28, 0xa4, 0xed, 0xbc, 0x71, 0x24, 0xf1, 0xac, + 0xaf, 0x61, 0x52, 0xcd, 0x03, 0x19, 0x87, 0x91, 0x5a, 0xaf, 0x57, 0x3a, 0xc7, 0xfe, 0x68, 0x36, + 0xd7, 0x4b, 0x05, 0x32, 0x0b, 0x10, 0x0b, 0x5f, 0xa9, 0x48, 0xa6, 0x63, 0x0b, 0xb2, 0x34, 0x82, + 0xf0, 0xfd, 0x7e, 0x69, 0x94, 0x90, 0xa4, 0xe9, 0x5a, 0x1a, 0xb3, 0xfe, 0x53, 0x21, 0x25, 0xa3, + 0xcc, 0x90, 0x11, 0xd6, 0x2e, 0x8a, 0x14, 0xdf, 0xad, 0xd1, 0x90, 0x11, 0x76, 0x32, 0xdf, 0x89, + 0x75, 0x20, 0xa6, 0x76, 0xb6, 0x19, 0x3b, 0x3b, 0x7e, 0x4f, 0x57, 0x3b, 0x7d, 0x51, 0x66, 0xab, + 0x5a, 0xb2, 0xac, 0x29, 0xa8, 0x91, 0xd8, 0x12, 0x91, 0x0a, 0x4a, 0x17, 0x56, 0xa5, 0xaa, 0x96, + 0x35, 0x93, 0x78, 0x34, 0xc6, 0xc9, 0x58, 0x1c, 0x0a, 0xce, 0x3a, 0xca, 0x99, 0x7e, 0xf2, 0x59, + 0xca, 0x82, 0xe7, 0x23, 0x44, 0xf9, 0x4e, 0xcc, 0x72, 0xca, 0x38, 0xaf, 0xc2, 0xd8, 0xa6, 0xbf, + 0xe7, 0x7a, 0x62, 0x90, 0x93, 0x27, 0xc7, 0xd5, 0xb1, 0x1e, 0x2b, 0xb0, 0x79, 0xb9, 0xf5, 0x7f, + 0x0a, 0xfa, 0x52, 0x50, 0x06, 0x5e, 0x21, 0xd3, 0xc0, 0xfb, 0x2e, 0x4c, 0x0a, 0x2b, 0x76, 0x63, + 0x55, 0x50, 0x44, 0xd5, 0x2e, 0x0f, 0xa9, 0x6e, 0xd7, 0x8e, 0x01, 0xd8, 0xd6, 0xcc, 0xf5, 0x3c, + 0x6e, 0xcd, 0x23, 0xf1, 0xd6, 0x2c, 0x76, 0x02, 0xbe, 0x35, 0xc7, 0x20, 0x6c, 0x22, 0x75, 0x17, + 0xdf, 0x68, 0x3c, 0x91, 0xba, 0x33, 0xcf, 0x74, 0xe0, 0x7d, 0x0a, 0x50, 0x7b, 0xd2, 0xc4, 0x8d, + 0xc9, 0xde, 0x12, 0xea, 0x18, 0xfd, 0x7f, 0xce, 0xf3, 0x50, 0x6c, 0x6d, 0x81, 0xbe, 0x87, 0x6b, + 0xd0, 0x56, 0x0f, 0x66, 0xef, 0xd1, 0x88, 0xcd, 0x9a, 0xdc, 0xbb, 0x06, 0x0f, 0xff, 0x73, 0x98, + 0x7a, 0xe2, 0x46, 0xfb, 0xa6, 0xc5, 0x8c, 0x8d, 0x3d, 0x77, 0xa3, 0x7d, 0x69, 0x31, 0x6b, 0x8d, + 0xe9, 0xe0, 0xd6, 0x1a, 0x5c, 0x10, 0xad, 0xa9, 0xad, 0x72, 0xd9, 0x24, 0x58, 0x88, 0x4d, 0x70, + 0x9d, 0xa0, 0x49, 0x86, 0x26, 0xf7, 0x0e, 0xd2, 0x4c, 0xed, 0x26, 0xfc, 0xf8, 0x90, 0xe7, 0xfe, + 0x42, 0xc1, 0x49, 0xec, 0x32, 0xc9, 0xbd, 0xc5, 0x7a, 0x0c, 0x33, 0xdb, 0xbd, 0xa3, 0x3d, 0xd7, + 0x63, 0x02, 0xda, 0xa4, 0x3f, 0x23, 0xab, 0x00, 0x71, 0x81, 0x68, 0x41, 0x1e, 0x8a, 0xe2, 0x8a, + 0xd6, 0x8a, 0x98, 0x62, 0x2c, 0xc1, 0xed, 0xc0, 0xd6, 0xf0, 0xac, 0xbf, 0x32, 0x02, 0x44, 0xb4, + 0xd1, 0x8c, 0x9c, 0x88, 0x36, 0x69, 0xc4, 0x76, 0x9e, 0xcb, 0x50, 0x54, 0x76, 0xf6, 0xf9, 0x93, + 0xe3, 0x6a, 0xd1, 0xed, 0xda, 0xc5, 0x8d, 0x55, 0xf2, 0x3e, 0x8c, 0x21, 0x18, 0xf2, 0x7a, 0x56, + 0xb5, 0xa7, 0x53, 0xe0, 0x32, 0x1d, 0xb2, 0x3f, 0x6d, 0x0e, 0x4c, 0x3e, 0x80, 0xc9, 0x55, 0xda, + 0xa3, 0x7b, 0x4e, 0xe4, 0x4b, 0xb9, 0xe3, 0x96, 0xab, 0x2c, 0xd4, 0xa6, 0x28, 0x86, 0x64, 0xb6, + 0x80, 0x4d, 0x9d, 0xd0, 0xf7, 0x74, 0x5b, 0x20, 0xc0, 0x12, 0xdd, 0x16, 0xe0, 0x30, 0xe4, 0xf7, + 0x0b, 0x30, 0x55, 0xf3, 0x3c, 0x61, 0x11, 0x86, 0xc2, 0xdf, 0x3d, 0x7f, 0x4b, 0x5d, 0x57, 0x6c, + 0x3a, 0xbb, 0xb4, 0xd7, 0x62, 0x67, 0x8c, 0xb0, 0xfe, 0x0d, 0x53, 0xcf, 0xff, 0xf9, 0xb8, 0xfa, + 0xd9, 0xcb, 0xdc, 0x80, 0xdc, 0xda, 0x09, 0x1c, 0x37, 0x0a, 0xd1, 0xb9, 0x18, 0x37, 0xa8, 0x8b, + 0x99, 0xd6, 0x0f, 0xf2, 0x0e, 0x8c, 0x71, 0x9b, 0x93, 0x9b, 0x14, 0x38, 0xd9, 0x09, 0x63, 0xd3, + 0xe6, 0x10, 0xd6, 0x1b, 0x30, 0x29, 0x38, 0xb9, 0xb1, 0x9a, 0x37, 0x05, 0xd6, 0x2a, 0x5c, 0x43, + 0xb3, 0x97, 0x32, 0xc9, 0x45, 0x17, 0x9b, 0x90, 0xc4, 0xf8, 0x9c, 0x34, 0x8e, 0xc5, 0x0a, 0x1b, + 0x27, 0x04, 0x5d, 0x74, 0xb6, 0xac, 0xb1, 0x1a, 0xb0, 0x78, 0x8f, 0x46, 0x36, 0x0d, 0x69, 0xb4, + 0xed, 0x84, 0xe1, 0x73, 0x3f, 0xe8, 0x62, 0xd5, 0x99, 0x88, 0xfc, 0x85, 0x02, 0x54, 0x1b, 0x01, + 0x65, 0x33, 0x9d, 0x4b, 0x68, 0xf0, 0x0a, 0x5e, 0x14, 0x37, 0x3e, 0xc5, 0xb8, 0x96, 0xf1, 0x5a, + 0xdc, 0xea, 0xbc, 0x05, 0x23, 0x3b, 0x3b, 0x9b, 0x28, 0x31, 0x23, 0xc8, 0xb8, 0x91, 0x28, 0xea, + 0xfd, 0xe6, 0xb8, 0x3a, 0xb1, 0x7a, 0xc4, 0x6f, 0x84, 0x6c, 0x56, 0x6f, 0x3d, 0x85, 0x79, 0x9b, + 0x7a, 0xf4, 0x39, 0xb3, 0x8b, 0x0d, 0xcb, 0xb7, 0x0a, 0x63, 0xdc, 0x83, 0x99, 0x1a, 0x02, 0x2f, + 0x37, 0x4d, 0xe3, 0xe2, 0x10, 0xd3, 0xd8, 0xfa, 0xc3, 0x02, 0x94, 0xf8, 0x70, 0xeb, 0x7e, 0x74, + 0xba, 0xf1, 0x89, 0x11, 0x14, 0x07, 0x8f, 0x80, 0xbc, 0x1d, 0x73, 0x7b, 0x24, 0xde, 0xfc, 0xb0, + 0xab, 0x4c, 0x87, 0xcb, 0x4a, 0x36, 0x20, 0x2e, 0x4b, 0xfc, 0x2c, 0x89, 0x03, 0x42, 0x59, 0x92, + 0x12, 0xf4, 0x0f, 0x8a, 0x70, 0x51, 0xeb, 0x62, 0xd8, 0xf7, 0xbd, 0x90, 0xb2, 0x43, 0x31, 0x13, + 0x16, 0xad, 0x9f, 0x78, 0x28, 0x66, 0x5b, 0x66, 0x3b, 0x36, 0xea, 0xb1, 0xc3, 0xef, 0xb0, 0xd3, + 0x58, 0x2f, 0x75, 0x7e, 0x46, 0xc5, 0xcd, 0x41, 0x65, 0xf5, 0xa9, 0x3b, 0x7d, 0x1b, 0x26, 0xf0, + 0x4f, 0xc6, 0x88, 0xd1, 0x7c, 0x46, 0x28, 0x20, 0xe2, 0x02, 0xdc, 0xf7, 0x5d, 0xef, 0x21, 0x8d, + 0xf6, 0x7d, 0xe9, 0x6d, 0xd8, 0x60, 0x4a, 0xec, 0xff, 0xf3, 0x5d, 0xaf, 0x7d, 0x88, 0xc5, 0x67, + 0x3d, 0x9f, 0xc5, 0x04, 0x6d, 0x8d, 0xb8, 0x75, 0x07, 0x4a, 0x4c, 0xdf, 0x9c, 0x7e, 0x46, 0xad, + 0x39, 0x20, 0xf7, 0x68, 0x54, 0xf7, 0x8d, 0x8d, 0xc3, 0x9a, 0x81, 0xa9, 0x6d, 0xd7, 0xdb, 0x93, + 0x9f, 0xff, 0xac, 0x08, 0xd3, 0xfc, 0x5b, 0xcc, 0x40, 0x62, 0x27, 0x2d, 0x9c, 0x66, 0x27, 0xfd, + 0x18, 0x66, 0x84, 0x8f, 0x8d, 0x06, 0xe8, 0xf8, 0xe2, 0xf3, 0x81, 0x47, 0x70, 0xee, 0x6a, 0x6b, + 0x3f, 0xe3, 0x35, 0xb6, 0x09, 0x48, 0x36, 0x61, 0x96, 0x17, 0xdc, 0xa5, 0x4e, 0x74, 0x14, 0x1f, + 0xd0, 0x2e, 0x08, 0x93, 0x55, 0x16, 0x73, 0x65, 0x24, 0x68, 0x3d, 0x15, 0x85, 0x76, 0x02, 0x97, + 0x7c, 0x09, 0x17, 0xb6, 0x03, 0xff, 0xdb, 0x17, 0x9a, 0xed, 0xc0, 0xf5, 0xf1, 0x3c, 0x3b, 0xcf, + 0xf5, 0x59, 0x55, 0x5b, 0xb7, 0x20, 0x92, 0xd0, 0x4c, 0xa6, 0x36, 0xc2, 0xba, 0x1f, 0xb8, 0xde, + 0x1e, 0xce, 0xe6, 0x04, 0x97, 0x29, 0x37, 0x6c, 0xef, 0x62, 0xa1, 0xad, 0xaa, 0xad, 0xff, 0x36, + 0x0a, 0x13, 0xaa, 0xe1, 0x5b, 0xba, 0x59, 0x2a, 0x36, 0x63, 0x5c, 0x9e, 0xf1, 0x39, 0xca, 0xd6, + 0x20, 0xc8, 0x15, 0xee, 0x61, 0xe4, 0x66, 0xc0, 0x38, 0x93, 0x31, 0xa7, 0xdf, 0xe7, 0x7e, 0xc4, + 0xcb, 0x50, 0x5c, 0xad, 0x23, 0x17, 0x26, 0xb8, 0x32, 0xed, 0xee, 0xda, 0xc5, 0xd5, 0x3a, 0x9b, + 0xeb, 0x47, 0x1b, 0xab, 0x0d, 0x1c, 0xd0, 0x04, 0x9f, 0x6b, 0xdf, 0xed, 0x76, 0x6c, 0x2c, 0x65, + 0xb5, 0xcd, 0xda, 0xc3, 0x4d, 0xd1, 0x69, 0xac, 0x0d, 0x9d, 0xc3, 0x9e, 0x8d, 0xa5, 0xcc, 0x0e, + 0xe4, 0x7b, 0x74, 0xc3, 0xf7, 0xa2, 0xc0, 0xef, 0x85, 0xe8, 0x5b, 0x99, 0x30, 0xb6, 0xf3, 0x8e, + 0xa8, 0xb2, 0x13, 0xa0, 0xe4, 0x09, 0x2c, 0xd4, 0xba, 0xcf, 0x1c, 0xaf, 0x43, 0xbb, 0xbc, 0xe6, + 0x89, 0x1f, 0x1c, 0x3c, 0xed, 0xf9, 0xcf, 0x43, 0x3c, 0x30, 0x4e, 0x88, 0xa3, 0xa7, 0x00, 0x69, + 0x0b, 0x72, 0xcf, 0x25, 0x90, 0x9d, 0x87, 0xcd, 0x54, 0x44, 0xa3, 0xe7, 0x1f, 0x75, 0xf1, 0xa4, + 0x38, 0xc1, 0x55, 0x44, 0x87, 0x15, 0xd8, 0xbc, 0x9c, 0x71, 0x69, 0xbd, 0xf9, 0x10, 0x0f, 0x7a, + 0x82, 0x4b, 0xfb, 0xe1, 0xa1, 0xcd, 0xca, 0xc8, 0x5b, 0x30, 0x2e, 0x4d, 0x5a, 0xee, 0x45, 0x41, + 0x17, 0x9b, 0x34, 0x65, 0x65, 0x1d, 0x59, 0x85, 0x8b, 0x0f, 0xfd, 0x2e, 0x0d, 0x9c, 0x88, 0x76, + 0x85, 0x75, 0x19, 0xe2, 0x99, 0x6d, 0x82, 0x9b, 0xd5, 0x87, 0xb2, 0x52, 0x3a, 0x60, 0x43, 0x3b, + 0x8d, 0xc0, 0x74, 0xef, 0x43, 0xa7, 0xb3, 0xef, 0x7a, 0x54, 0x78, 0x41, 0xc4, 0xe4, 0x1e, 0xf2, + 0x42, 0xb4, 0x5d, 0x15, 0x00, 0xd9, 0x81, 0xcb, 0xd2, 0x49, 0x9b, 0xb0, 0xad, 0x66, 0x10, 0x55, + 0x5c, 0xc9, 0x71, 0x88, 0x76, 0xd2, 0x98, 0xca, 0xc1, 0xb5, 0xde, 0x83, 0x8b, 0x7c, 0xf9, 0x9f, + 0xda, 0xe6, 0xb4, 0xb6, 0x01, 0x9a, 0xf4, 0xd0, 0xe9, 0xef, 0xfb, 0x4c, 0x44, 0xeb, 0xfa, 0x97, + 0x30, 0xc2, 0x88, 0xba, 0x47, 0x12, 0x15, 0xad, 0x15, 0x69, 0x95, 0x4b, 0x48, 0x5b, 0xc3, 0xb2, + 0xfe, 0x43, 0x11, 0x08, 0xde, 0xa7, 0x34, 0xa3, 0x80, 0x3a, 0x87, 0xb2, 0x1b, 0x9f, 0xc0, 0x34, + 0xd7, 0xe4, 0xbc, 0x18, 0xbb, 0xc3, 0x2c, 0x3c, 0xbe, 0x84, 0xf5, 0xaa, 0xf5, 0x73, 0xb6, 0x01, + 0xca, 0x50, 0x6d, 0x1a, 0x1e, 0x1d, 0x4a, 0xd4, 0xa2, 0x81, 0xaa, 0x57, 0x31, 0x54, 0xfd, 0x9b, + 0x7c, 0x09, 0xb3, 0x0d, 0xff, 0xb0, 0xcf, 0x78, 0x22, 0x90, 0x47, 0x84, 0x1d, 0x25, 0xda, 0x35, + 0x2a, 0xd7, 0xcf, 0xd9, 0x09, 0x70, 0xb2, 0x05, 0x97, 0xee, 0xf6, 0x8e, 0xc2, 0xfd, 0x9a, 0xd7, + 0x6d, 0xf4, 0xfc, 0x50, 0x52, 0x19, 0x15, 0x1e, 0x22, 0xa1, 0x80, 0xd2, 0x10, 0xeb, 0xe7, 0xec, + 0x2c, 0x44, 0xf2, 0x96, 0x08, 0x0e, 0x11, 0xf6, 0xdc, 0xcc, 0x2d, 0x11, 0x3b, 0xf2, 0xc8, 0xa3, + 0x8f, 0x9e, 0xae, 0x9f, 0xb3, 0x79, 0x6d, 0x7d, 0x12, 0xc6, 0xa5, 0xf2, 0xbd, 0x0d, 0x17, 0x35, + 0x76, 0x32, 0x0b, 0xf4, 0x28, 0x24, 0x15, 0x98, 0x78, 0xdc, 0xef, 0xf9, 0x4e, 0x57, 0x1a, 0x34, + 0xb6, 0xfa, 0xb6, 0xbe, 0x6b, 0x72, 0x9a, 0x2c, 0xea, 0xa7, 0x2a, 0x0e, 0x1c, 0x17, 0x58, 0xeb, + 0x26, 0x73, 0x07, 0x43, 0x1b, 0xed, 0x16, 0x13, 0xed, 0x96, 0x92, 0xbc, 0xb6, 0xe6, 0x33, 0x99, + 0x67, 0x3d, 0x40, 0x63, 0xad, 0xd6, 0xef, 0xf7, 0xdc, 0x0e, 0xee, 0x71, 0x5c, 0x43, 0x2b, 0x3b, + 0xe7, 0x77, 0xf4, 0x10, 0x06, 0x6d, 0x83, 0x57, 0x01, 0x0b, 0x5a, 0x90, 0x82, 0xf5, 0x43, 0xb8, + 0x96, 0x43, 0x4c, 0xec, 0x55, 0x9f, 0xc0, 0xb8, 0x28, 0x4a, 0x08, 0xb4, 0x7e, 0xe9, 0x83, 0x9a, + 0x21, 0x14, 0x98, 0x12, 0xde, 0xfa, 0x1a, 0x96, 0x1e, 0xf7, 0x43, 0x1a, 0xa4, 0xc9, 0xcb, 0xae, + 0x7e, 0xa8, 0x42, 0x24, 0x0a, 0xb9, 0x17, 0x4a, 0x70, 0x72, 0x5c, 0x3d, 0xcf, 0x69, 0xcb, 0xc8, + 0x08, 0xeb, 0x17, 0x05, 0x58, 0xe2, 0x4b, 0x35, 0x97, 0xf4, 0x59, 0xb8, 0xa0, 0x5d, 0x26, 0x14, + 0xf3, 0x2f, 0x13, 0x06, 0xde, 0xae, 0x58, 0x5f, 0x81, 0x25, 0x7a, 0xd4, 0xeb, 0xbd, 0xa6, 0xb9, + 0xf9, 0x73, 0x05, 0x98, 0xe3, 0x93, 0xf3, 0x0a, 0x54, 0xc8, 0xf7, 0x61, 0xb6, 0x79, 0xe0, 0xf6, + 0x5b, 0x4e, 0xcf, 0xed, 0x72, 0xbf, 0x3a, 0xdf, 0x12, 0xe7, 0x71, 0xb7, 0x3f, 0x70, 0xfb, 0xed, + 0x67, 0x71, 0x55, 0xc1, 0x4e, 0x00, 0x5b, 0x8f, 0x60, 0x3e, 0xd1, 0x07, 0x21, 0x18, 0x1f, 0x26, + 0x05, 0x23, 0x15, 0xdf, 0x92, 0x2d, 0x15, 0x0f, 0xe1, 0xb2, 0x92, 0x0a, 0x73, 0xca, 0x56, 0x12, + 0xd2, 0x90, 0x22, 0x98, 0x25, 0x0a, 0x1d, 0xb8, 0xac, 0x24, 0xe1, 0x15, 0x24, 0x40, 0x4e, 0x6e, + 0x31, 0x73, 0x72, 0x37, 0xa0, 0xa2, 0x4f, 0xee, 0xab, 0x4c, 0xea, 0xbf, 0x2f, 0xc0, 0xc2, 0x3d, + 0xea, 0xe1, 0xf6, 0x57, 0xeb, 0xf7, 0x8d, 0xd3, 0x91, 0xee, 0x6d, 0x2f, 0x0c, 0xf4, 0xb6, 0x2b, + 0xd3, 0xbf, 0x98, 0x6d, 0xfa, 0xb3, 0x7d, 0xfd, 0xb1, 0xbd, 0x21, 0x64, 0x15, 0xf7, 0xf5, 0xa3, + 0xc0, 0xb5, 0x59, 0x19, 0xd9, 0x88, 0x3d, 0xf5, 0xa3, 0x43, 0x3d, 0xf5, 0x97, 0x84, 0xe7, 0x72, + 0x5c, 0x78, 0xea, 0x0d, 0xff, 0xbc, 0xf5, 0x19, 0x94, 0xd3, 0x63, 0x11, 0xf2, 0x31, 0xec, 0xb8, + 0x65, 0xad, 0xc6, 0xd2, 0x2d, 0xc2, 0x23, 0xd4, 0x0d, 0x45, 0x42, 0x85, 0x0e, 0x70, 0x63, 0x59, + 0xcd, 0x58, 0x3e, 0x05, 0x15, 0xd1, 0xfe, 0xa7, 0x4c, 0x3e, 0xf9, 0x1d, 0x71, 0x21, 0xff, 0x8e, + 0x58, 0xc8, 0x28, 0x47, 0x95, 0x08, 0xd6, 0x13, 0xb8, 0x6c, 0x10, 0x8d, 0xa5, 0xfe, 0xfb, 0x30, + 0xa1, 0x8c, 0x1c, 0xd3, 0xcb, 0x62, 0x90, 0xc5, 0x79, 0x53, 0xf6, 0x8e, 0x42, 0xb1, 0x7e, 0x8c, + 0xba, 0x3b, 0x79, 0xe9, 0xfc, 0xda, 0xc8, 0xff, 0xaa, 0x00, 0x0b, 0x7c, 0xf3, 0x4a, 0xb3, 0xf5, + 0xf4, 0xc2, 0xf5, 0x5b, 0xf1, 0x0c, 0xde, 0xc9, 0xf0, 0x0c, 0x22, 0x8a, 0xee, 0x19, 0xd4, 0xfd, + 0x81, 0xf7, 0x47, 0x27, 0x8a, 0xa5, 0x11, 0xab, 0x05, 0xe5, 0xf4, 0x08, 0x5f, 0xc3, 0x94, 0xff, + 0xf3, 0x02, 0x5c, 0x13, 0xfb, 0x7e, 0x62, 0x76, 0xce, 0xce, 0xc0, 0x0f, 0x60, 0x5a, 0xe0, 0xf2, + 0x15, 0xc0, 0x95, 0x0a, 0xc6, 0x35, 0x48, 0x21, 0xe6, 0x2b, 0xc1, 0x00, 0x23, 0x1f, 0x68, 0x47, + 0x63, 0xee, 0xe5, 0xb8, 0xc2, 0xd4, 0x08, 0x3f, 0x43, 0xe7, 0x1e, 0x90, 0xad, 0x6f, 0x60, 0x29, + 0xaf, 0xe3, 0xaf, 0x81, 0x2f, 0xf7, 0xa1, 0x92, 0x21, 0xb1, 0x2f, 0xb7, 0x56, 0x7f, 0x00, 0x57, + 0x33, 0x69, 0xbd, 0x86, 0x6e, 0xde, 0x83, 0x05, 0x6d, 0x1b, 0x78, 0x85, 0x3e, 0x3e, 0x84, 0x6b, + 0x9c, 0xd0, 0xeb, 0x19, 0xf2, 0x3a, 0x2c, 0xc6, 0x67, 0x0a, 0x43, 0xa1, 0x9c, 0x51, 0xa8, 0x84, + 0xa2, 0x8b, 0x59, 0xf1, 0x1a, 0x15, 0x5d, 0x0c, 0xf8, 0xda, 0x34, 0xd1, 0x06, 0x5c, 0xe2, 0x84, + 0xcd, 0x4d, 0x61, 0x59, 0xdf, 0x14, 0x32, 0xa3, 0x08, 0xd3, 0xfb, 0xc4, 0x43, 0xdc, 0x27, 0x24, + 0x48, 0xdc, 0xc3, 0x0f, 0xe0, 0xbc, 0x08, 0x94, 0xe6, 0xfd, 0xcb, 0x20, 0x86, 0x06, 0x03, 0x8f, + 0x8e, 0xb6, 0x05, 0xb0, 0x55, 0xc6, 0x21, 0x3f, 0x38, 0xda, 0xa5, 0xe2, 0xc6, 0x49, 0xb9, 0x6d, + 0xbe, 0x62, 0x3b, 0x73, 0xa2, 0xe6, 0x15, 0x8d, 0x9d, 0x47, 0x50, 0xe6, 0xc6, 0x8e, 0x46, 0xf5, + 0x95, 0xcc, 0x9d, 0x8f, 0xa1, 0xcc, 0xe5, 0x29, 0x83, 0xe0, 0x60, 0x1b, 0x66, 0x49, 0x4a, 0x62, + 0xad, 0xd7, 0xcb, 0x1a, 0xfd, 0x5f, 0x2a, 0xc0, 0x95, 0x7b, 0x34, 0x32, 0x63, 0x49, 0xff, 0x44, + 0x4c, 0xce, 0x6f, 0x50, 0xe5, 0xa4, 0x3a, 0x22, 0xa6, 0xe2, 0x8b, 0xe4, 0x54, 0xe4, 0x06, 0xce, + 0x66, 0x4f, 0xc9, 0x0f, 0xe1, 0x2a, 0x9f, 0x12, 0x13, 0x5e, 0x0e, 0xf4, 0xb3, 0xc4, 0xac, 0xe4, + 0x52, 0xcf, 0x9a, 0x9d, 0xbf, 0x56, 0x80, 0xab, 0x9c, 0xc9, 0xd9, 0xc4, 0x7f, 0xdb, 0x87, 0x92, + 0x2d, 0xa8, 0xaa, 0x39, 0x7f, 0x0d, 0x13, 0x6b, 0xfd, 0xc3, 0x02, 0x10, 0x49, 0xa7, 0xd1, 0xb4, + 0x25, 0x8d, 0x2b, 0x30, 0xd2, 0x68, 0xda, 0x22, 0x9a, 0x04, 0x8d, 0xcd, 0x4e, 0x18, 0xd8, 0xac, + 0x2c, 0x69, 0x1a, 0x14, 0x4f, 0x63, 0x1a, 0x6c, 0x00, 0x69, 0xba, 0x7b, 0xde, 0x13, 0x37, 0xda, + 0x57, 0x8d, 0xd5, 0x84, 0xbb, 0x0e, 0x43, 0x96, 0x43, 0x77, 0xcf, 0x6b, 0xe3, 0x1d, 0x9c, 0x0a, + 0x8b, 0xee, 0x38, 0x76, 0x06, 0x92, 0xf5, 0x23, 0xb8, 0x64, 0xf4, 0x57, 0xc8, 0xd0, 0x22, 0x8c, + 0x36, 0x68, 0x10, 0x89, 0x1e, 0x23, 0xd7, 0x3a, 0x34, 0x88, 0x6c, 0x2c, 0x25, 0x6f, 0xc3, 0x78, + 0xa3, 0x86, 0x57, 0x07, 0x68, 0x5e, 0x4f, 0x73, 0x25, 0xd7, 0x71, 0xda, 0xf8, 0x56, 0xc7, 0x96, + 0x95, 0xd6, 0xbf, 0x29, 0x6a, 0xd4, 0x19, 0xfa, 0x70, 0x76, 0xbc, 0x07, 0xc0, 0xf9, 0xaf, 0x71, + 0x83, 0xd9, 0x05, 0x53, 0xc2, 0xed, 0xca, 0xf7, 0x01, 0x5b, 0x03, 0x3a, 0xe5, 0xb5, 0x87, 0xbc, + 0x66, 0xe7, 0x48, 0xf2, 0x4a, 0x40, 0x5d, 0xb3, 0x0b, 0xd2, 0xa1, 0xad, 0x03, 0x91, 0x9f, 0xc0, + 0x8c, 0xe8, 0xb3, 0xe8, 0xd0, 0x18, 0xde, 0xe3, 0xbd, 0x29, 0xfc, 0x32, 0x19, 0x63, 0xbb, 0xa5, + 0xe0, 0xc5, 0x2b, 0x0a, 0xf9, 0xc9, 0xa7, 0xd1, 0x24, 0x67, 0xbd, 0xad, 0x6e, 0xb0, 0x68, 0x40, + 0x2e, 0xc0, 0xd4, 0xe3, 0xad, 0xe6, 0xf6, 0x5a, 0x63, 0xe3, 0xee, 0xc6, 0xda, 0x6a, 0xe9, 0x1c, + 0x99, 0x80, 0xd1, 0x9d, 0xc6, 0xce, 0x66, 0xa9, 0x60, 0x7d, 0x03, 0x73, 0x66, 0x5b, 0xaf, 0x75, + 0x9a, 0x22, 0xb8, 0xa4, 0xf6, 0xf2, 0xfb, 0x4f, 0x76, 0xb4, 0xdb, 0xdd, 0x5a, 0xa7, 0xe3, 0x1f, + 0x79, 0x51, 0xd2, 0x09, 0xef, 0xf0, 0x62, 0x21, 0x99, 0x1a, 0x90, 0x71, 0x75, 0x52, 0x1c, 0x78, + 0x75, 0x62, 0x7d, 0x04, 0x73, 0x66, 0xab, 0xa7, 0x3d, 0x16, 0xbd, 0x89, 0xd7, 0xde, 0x5a, 0xc0, + 0x06, 0x21, 0xba, 0x0b, 0x52, 0xac, 0xec, 0x8f, 0xa0, 0x24, 0xa0, 0x62, 0xcd, 0xf8, 0x86, 0x3c, + 0x14, 0x72, 0xbd, 0x68, 0xbe, 0x7a, 0x91, 0x77, 0x42, 0xdf, 0x91, 0x4e, 0xce, 0x61, 0x2d, 0xfc, + 0xcd, 0x02, 0x94, 0x1f, 0xde, 0xad, 0xd5, 0x8e, 0xa2, 0x7d, 0xea, 0x45, 0x6e, 0xc7, 0x89, 0x68, + 0x63, 0xdf, 0xe9, 0xf5, 0xa8, 0xb7, 0x47, 0xc9, 0x4d, 0x18, 0xdd, 0x79, 0xb4, 0xb3, 0x2d, 0x7c, + 0x89, 0x73, 0x42, 0x60, 0x58, 0x91, 0x82, 0xb1, 0x11, 0x82, 0x3c, 0x80, 0x8b, 0x4f, 0xc4, 0x3b, + 0x33, 0x55, 0x25, 0xbc, 0x88, 0xd7, 0x6e, 0xa9, 0x17, 0x68, 0x8d, 0x80, 0x76, 0x59, 0x2b, 0x4e, + 0x4f, 0x05, 0xb0, 0xd9, 0x69, 0xbc, 0xfb, 0xa3, 0x13, 0x85, 0x52, 0xd1, 0xfa, 0xfd, 0x02, 0x2c, + 0x24, 0x7a, 0xa6, 0x5d, 0x6e, 0xe9, 0x1d, 0xbb, 0xa4, 0x75, 0x4c, 0x82, 0xac, 0x9f, 0x13, 0x3d, + 0x6b, 0xe0, 0xa3, 0x06, 0x6c, 0x41, 0x74, 0xe8, 0xad, 0xc1, 0x1d, 0x8a, 0x09, 0x28, 0x44, 0x11, + 0x2e, 0x8c, 0xe5, 0xd6, 0x05, 0x98, 0x31, 0x38, 0x60, 0x59, 0x30, 0xad, 0xb7, 0xcc, 0xd8, 0xdc, + 0xf0, 0xbb, 0x8a, 0xcd, 0xec, 0x6f, 0xeb, 0xaf, 0x17, 0x60, 0xee, 0xe1, 0xdd, 0x9a, 0x4d, 0xf7, + 0x5c, 0xb6, 0x4c, 0x62, 0x16, 0x2f, 0x1b, 0x23, 0x59, 0x34, 0x46, 0x92, 0x80, 0x55, 0x43, 0xfa, + 0x34, 0x35, 0xa4, 0xc5, 0xac, 0x21, 0xe1, 0x71, 0xc1, 0xf5, 0x3d, 0x63, 0x24, 0x9a, 0xcf, 0xf4, + 0x6f, 0x15, 0xe0, 0x92, 0xd6, 0x27, 0xd5, 0xff, 0xf7, 0x8c, 0x2e, 0x5d, 0xcd, 0xe8, 0x52, 0x8a, + 0xc9, 0xf5, 0x54, 0x8f, 0xde, 0x1c, 0xd4, 0xa3, 0xa1, 0x3c, 0xfe, 0xe3, 0x02, 0xcc, 0x67, 0xf2, + 0x80, 0x5c, 0x66, 0x1b, 0x77, 0x27, 0xa0, 0x91, 0x60, 0xaf, 0xf8, 0x62, 0xe5, 0x1b, 0x61, 0x78, + 0x24, 0x1e, 0x01, 0x4e, 0xda, 0xe2, 0x8b, 0xbc, 0x09, 0x33, 0xdb, 0x34, 0x70, 0xfd, 0x6e, 0x93, + 0x76, 0x7c, 0xaf, 0xcb, 0x6f, 0xc5, 0x66, 0x6c, 0xb3, 0x90, 0x2c, 0xc2, 0x64, 0xad, 0xb7, 0xe7, + 0x07, 0x6e, 0xb4, 0xcf, 0xdd, 0xd6, 0x93, 0x76, 0x5c, 0xc0, 0x68, 0xaf, 0xba, 0x7b, 0x6e, 0xc4, + 0xe3, 0x0b, 0x66, 0x6c, 0xf1, 0x45, 0xca, 0x30, 0x2e, 0xd4, 0x06, 0xde, 0x02, 0x4d, 0xda, 0xf2, + 0x93, 0x61, 0x7c, 0x65, 0xa3, 0x10, 0x60, 0x08, 0xad, 0x2d, 0xbe, 0xac, 0x77, 0x61, 0x2e, 0x8b, + 0x8f, 0x99, 0x22, 0xf3, 0x67, 0x8a, 0x70, 0xa9, 0xd6, 0xed, 0x3e, 0xbc, 0x5b, 0x5b, 0xa5, 0xba, + 0xfd, 0xf7, 0x3e, 0x8c, 0x6e, 0x78, 0x6e, 0x24, 0x0c, 0x97, 0x25, 0x31, 0x3d, 0x19, 0x90, 0x0c, + 0x8a, 0xcd, 0x10, 0xfb, 0x9f, 0xd8, 0x70, 0x69, 0xed, 0x5b, 0x37, 0x8c, 0x5c, 0x6f, 0x0f, 0xe7, + 0x9c, 0x37, 0x2c, 0xe6, 0x58, 0x12, 0xc9, 0x59, 0x6e, 0xeb, 0xe7, 0xec, 0x2c, 0x64, 0xb2, 0x03, + 0x97, 0xb7, 0xe8, 0xf3, 0x0c, 0x11, 0x52, 0xb1, 0xa1, 0x8a, 0x6c, 0x86, 0xe4, 0xe4, 0xe0, 0xea, + 0x12, 0xfa, 0x17, 0x8b, 0x18, 0x56, 0xad, 0x0d, 0x4c, 0xb4, 0xfc, 0x18, 0xe6, 0xb4, 0x0e, 0xc5, + 0x1a, 0xa7, 0x20, 0x1e, 0xf5, 0x64, 0x0e, 0x47, 0x5f, 0x48, 0x99, 0xe8, 0xe4, 0x09, 0x2c, 0x98, + 0x9d, 0x8a, 0x29, 0x9b, 0x8b, 0x21, 0x0b, 0x64, 0xfd, 0x9c, 0x9d, 0x87, 0x4d, 0x96, 0x61, 0xa4, + 0xd6, 0x39, 0x10, 0x6c, 0xc9, 0x9e, 0x32, 0x3e, 0xb2, 0x5a, 0xe7, 0x00, 0x9f, 0x41, 0x74, 0x0e, + 0x8c, 0xf5, 0xf0, 0xaf, 0x0a, 0xb0, 0x90, 0x33, 0xc3, 0x64, 0x09, 0x80, 0x17, 0x6a, 0xba, 0x5d, + 0x2b, 0x61, 0xc6, 0x08, 0xff, 0xc2, 0xa0, 0x8b, 0x11, 0xdc, 0xfb, 0x65, 0x98, 0x65, 0x5c, 0x61, + 0x6b, 0x40, 0x64, 0x1b, 0xa6, 0xf8, 0x17, 0x8f, 0xf6, 0x1c, 0x45, 0x1c, 0x62, 0xe0, 0xf0, 0xf0, + 0x4e, 0x8c, 0xbb, 0xea, 0x62, 0x41, 0x3b, 0x19, 0xe5, 0xa9, 0x93, 0x10, 0x5e, 0x9d, 0x46, 0x72, + 0x14, 0x6a, 0xd0, 0xe4, 0x26, 0x9c, 0xe7, 0x85, 0x62, 0x0e, 0xe5, 0x73, 0xcc, 0x18, 0x58, 0xd4, + 0x5b, 0x7f, 0x58, 0x90, 0xbe, 0xe0, 0xd4, 0xd2, 0xf8, 0xc8, 0x58, 0x1a, 0x37, 0x54, 0x87, 0xb3, + 0x80, 0x8d, 0xd5, 0x51, 0x87, 0xa9, 0x97, 0x59, 0x15, 0x3a, 0x92, 0x2e, 0xb7, 0x7f, 0xb7, 0x20, + 0xfd, 0x14, 0x69, 0xd1, 0x5d, 0x83, 0xe9, 0x97, 0x13, 0x59, 0x03, 0x8d, 0x7c, 0xc0, 0x25, 0xaa, + 0x38, 0x78, 0xa4, 0x03, 0x85, 0xea, 0x73, 0xe9, 0xee, 0x7e, 0x19, 0xb1, 0xb2, 0x16, 0x33, 0xb0, + 0x55, 0x73, 0xd6, 0x51, 0xaa, 0xb6, 0xf9, 0xc2, 0xeb, 0xc8, 0x79, 0x7a, 0x3b, 0x19, 0x68, 0x94, + 0x1b, 0x45, 0xa2, 0xf7, 0xa1, 0x18, 0xbb, 0x28, 0x85, 0xc8, 0xa1, 0x31, 0xa6, 0x77, 0xea, 0x5f, + 0x14, 0x4d, 0x09, 0x7b, 0x99, 0x46, 0x1b, 0x30, 0xb3, 0x45, 0x9f, 0xa7, 0xda, 0xc5, 0xbb, 0x79, + 0x8f, 0x3e, 0x6f, 0x6b, 0x6d, 0x6b, 0xd2, 0x6e, 0xe2, 0x90, 0x5d, 0x98, 0x95, 0xba, 0xe0, 0xb4, + 0x2a, 0x91, 0x07, 0xb0, 0xb3, 0x16, 0x0e, 0x9f, 0x3a, 0xed, 0x40, 0x94, 0xea, 0x91, 0xe7, 0x26, + 0xc5, 0xd7, 0xbf, 0x4a, 0xad, 0x6d, 0x28, 0xa7, 0xb9, 0x27, 0x5a, 0x7b, 0x7f, 0xd8, 0x02, 0xe5, + 0x47, 0xe5, 0xae, 0xb9, 0x58, 0xd7, 0xd1, 0xab, 0xa3, 0x60, 0xd4, 0x79, 0xf4, 0x4e, 0x72, 0x32, + 0x30, 0x88, 0x40, 0x4e, 0x86, 0xfe, 0xb2, 0x28, 0x0e, 0x5e, 0x9b, 0x4f, 0x50, 0x12, 0x1d, 0x7b, + 0x17, 0xc6, 0x45, 0x91, 0x7a, 0xb1, 0x95, 0x54, 0x1d, 0x12, 0xc0, 0xfa, 0x83, 0x02, 0x5c, 0x61, + 0xb6, 0x7b, 0xd3, 0xf5, 0xf6, 0x7a, 0xf4, 0x71, 0x68, 0x86, 0x8e, 0x7d, 0xcf, 0x50, 0x1f, 0x0b, + 0x39, 0xd1, 0xed, 0xff, 0xaf, 0x94, 0xc6, 0xdf, 0x29, 0x40, 0x25, 0xab, 0x6f, 0xaf, 0x57, 0x6f, + 0xdc, 0x12, 0x87, 0x2d, 0xde, 0xdb, 0xb2, 0x40, 0x57, 0x6d, 0xca, 0xc1, 0xb2, 0x41, 0xb2, 0xff, + 0x0d, 0x85, 0xf1, 0xbf, 0x0b, 0x30, 0xb7, 0x11, 0x62, 0xf7, 0x7f, 0x76, 0xe4, 0x06, 0xb4, 0x2b, + 0x19, 0x77, 0x2b, 0xeb, 0x0d, 0x04, 0xce, 0xeb, 0xfa, 0xb9, 0xac, 0x37, 0x0e, 0xef, 0x6b, 0xa1, + 0xd9, 0xc5, 0x41, 0x8f, 0x1b, 0x8c, 0xa7, 0x89, 0x6f, 0xc3, 0xe8, 0x16, 0x33, 0x92, 0x46, 0x84, + 0xfc, 0x71, 0x0c, 0x56, 0x84, 0x51, 0xd4, 0xac, 0xcb, 0xec, 0x83, 0xdc, 0x4d, 0xc5, 0x6a, 0x8f, + 0x0e, 0x0f, 0xde, 0x4f, 0xbf, 0xa9, 0xac, 0x4f, 0xc0, 0xf9, 0x1d, 0x27, 0xd8, 0xa3, 0x91, 0xf5, + 0x43, 0xa8, 0x88, 0xc0, 0x02, 0xee, 0xf8, 0xc4, 0xf0, 0x83, 0x30, 0x76, 0xc8, 0x0d, 0x0a, 0x06, + 0x58, 0x02, 0x68, 0x46, 0x4e, 0x10, 0x6d, 0x78, 0x5d, 0xfa, 0x2d, 0x8e, 0x76, 0xcc, 0xd6, 0x4a, + 0xac, 0x0f, 0x60, 0x52, 0x0d, 0x01, 0x4f, 0x68, 0x9a, 0x1d, 0x88, 0xc3, 0x99, 0x33, 0xa2, 0xc7, + 0x65, 0xc8, 0xf8, 0x0a, 0xcc, 0x27, 0xa6, 0x42, 0xc8, 0x49, 0x85, 0x4d, 0x18, 0x2f, 0xe3, 0xe1, + 0x53, 0xb6, 0xfa, 0xb6, 0x1a, 0x70, 0x31, 0x35, 0xd3, 0x84, 0xe0, 0x8b, 0x00, 0x7e, 0xfa, 0x66, + 0xdb, 0x44, 0xb3, 0xb9, 0xce, 0xca, 0x76, 0x36, 0x9b, 0x3c, 0x3a, 0x92, 0x95, 0xed, 0x6c, 0x36, + 0xeb, 0xe7, 0xb9, 0xe4, 0x58, 0x7f, 0xbf, 0x88, 0x87, 0xd2, 0x14, 0x0f, 0x12, 0xfe, 0x25, 0xdd, + 0xc7, 0x55, 0x87, 0x49, 0x1c, 0xf1, 0xaa, 0x8c, 0x22, 0x1e, 0x7c, 0x1b, 0x39, 0xf1, 0xcb, 0xe3, + 0xea, 0x39, 0xbc, 0x82, 0x8c, 0xd1, 0xc8, 0x17, 0x30, 0xbe, 0xe6, 0x75, 0x91, 0xc2, 0xc8, 0x19, + 0x28, 0x48, 0x24, 0x36, 0x0f, 0xd8, 0x65, 0x66, 0xe0, 0x08, 0xc7, 0x89, 0xad, 0x95, 0x20, 0x9b, + 0xdd, 0x43, 0x97, 0xc7, 0x9c, 0x8c, 0xd9, 0xfc, 0x83, 0x71, 0x13, 0xbb, 0x20, 0x5f, 0xd1, 0x4d, + 0xda, 0xea, 0x9b, 0x58, 0x30, 0xf6, 0x28, 0xe8, 0x8a, 0xd7, 0x3e, 0xb3, 0xcb, 0xd3, 0x32, 0x75, + 0x09, 0x2b, 0xb3, 0x79, 0x95, 0xf5, 0x3f, 0xf1, 0x1e, 0x38, 0xca, 0x94, 0x1b, 0x83, 0x2b, 0x85, + 0x57, 0xe6, 0x4a, 0xf1, 0x65, 0xb8, 0xa2, 0x46, 0x3d, 0x92, 0x37, 0xea, 0xd1, 0xbc, 0x51, 0x8f, + 0xe5, 0x8f, 0xfa, 0x1e, 0x9c, 0xe7, 0x43, 0x25, 0x6f, 0xc0, 0xd8, 0x46, 0x44, 0x0f, 0x63, 0x67, + 0x85, 0x1e, 0xc9, 0x63, 0xf3, 0x3a, 0x76, 0x8e, 0xda, 0x74, 0xc2, 0x48, 0xc6, 0xe3, 0x4e, 0xda, + 0xf2, 0xd3, 0xfa, 0x29, 0x86, 0xeb, 0x6f, 0xfa, 0x9d, 0x03, 0xcd, 0x93, 0x39, 0xce, 0x57, 0x65, + 0xf2, 0x42, 0x80, 0x41, 0xf1, 0x1a, 0x5b, 0x42, 0x90, 0xeb, 0x30, 0xb5, 0xe1, 0xdd, 0xf5, 0x83, + 0x0e, 0x7d, 0xe4, 0xf5, 0x38, 0xf5, 0x09, 0x5b, 0x2f, 0x12, 0x1e, 0x16, 0xd1, 0x42, 0xec, 0x61, + 0xc1, 0x82, 0x84, 0x87, 0x85, 0xbf, 0x6e, 0xb7, 0x79, 0x9d, 0x70, 0xe0, 0xb0, 0xbf, 0x07, 0xb9, + 0x57, 0x94, 0x1f, 0x66, 0x18, 0xe0, 0x2e, 0x5c, 0xb1, 0x69, 0xbf, 0xe7, 0x30, 0x33, 0xea, 0xd0, + 0xe7, 0xf0, 0x6a, 0xcc, 0xd7, 0x33, 0x22, 0x49, 0x4d, 0x67, 0xaa, 0xea, 0x72, 0x71, 0x40, 0x97, + 0x0f, 0xe1, 0xc6, 0x3d, 0x1a, 0x65, 0x3e, 0x51, 0x8f, 0x07, 0xbf, 0x0e, 0x13, 0xe2, 0xc5, 0x8e, + 0x1c, 0xff, 0xb0, 0xd7, 0xf1, 0xe2, 0x72, 0x48, 0xd0, 0x51, 0x7f, 0x59, 0x5f, 0x42, 0x35, 0xaf, + 0xb9, 0xd3, 0x85, 0xdd, 0xb9, 0x70, 0x3d, 0x9f, 0x80, 0xda, 0x16, 0xc7, 0x45, 0x83, 0xea, 0x40, + 0x3c, 0xb8, 0xb7, 0xea, 0xba, 0x00, 0x0d, 0x03, 0xf1, 0x87, 0x55, 0x97, 0x71, 0x3d, 0xaf, 0xd0, + 0xdd, 0x36, 0x5e, 0x68, 0x98, 0x04, 0x62, 0xbe, 0xd6, 0x60, 0x42, 0x96, 0x25, 0x6e, 0x34, 0x52, + 0xaf, 0xff, 0x91, 0xa1, 0x5d, 0x49, 0x40, 0xa1, 0x59, 0x3f, 0x95, 0xd7, 0x0e, 0x26, 0xc6, 0xe9, + 0xa2, 0xd2, 0x4f, 0x73, 0xcf, 0x60, 0xf9, 0x70, 0xc5, 0xa4, 0xad, 0x3b, 0xbc, 0x4b, 0x9a, 0xc3, + 0x9b, 0xfb, 0xb9, 0x99, 0x5c, 0xda, 0x9b, 0x6b, 0x5e, 0xb7, 0xef, 0xbb, 0x5e, 0x24, 0x16, 0xaf, + 0x5e, 0x44, 0x96, 0x74, 0xb7, 0xf6, 0x74, 0x3a, 0x8c, 0xff, 0x0e, 0x54, 0xb2, 0x1a, 0xd4, 0xdc, + 0x22, 0xca, 0x33, 0xcc, 0x0d, 0x12, 0x6b, 0x1f, 0xe6, 0x8c, 0x7c, 0x4a, 0x71, 0x82, 0x98, 0x38, + 0x8f, 0xd4, 0x64, 0xfd, 0xf3, 0xdf, 0x1c, 0x57, 0x3f, 0x3e, 0x4b, 0xac, 0xb8, 0xa4, 0xb9, 0xa3, + 0x5e, 0x22, 0x58, 0x0b, 0x30, 0xd2, 0xb0, 0x37, 0x71, 0xd8, 0xf6, 0xa6, 0x1a, 0xb6, 0xbd, 0x69, + 0xfd, 0x51, 0x11, 0xaa, 0x8d, 0x7d, 0xc7, 0xdb, 0xe3, 0xd7, 0xbd, 0xb1, 0xdd, 0xa5, 0xdd, 0x1f, + 0x9f, 0xf6, 0xb4, 0xb1, 0x0c, 0x53, 0x5b, 0xf4, 0xb9, 0x7c, 0x45, 0x21, 0xde, 0x23, 0xa0, 0x7f, + 0x9a, 0x9d, 0x04, 0xfa, 0xa2, 0xdc, 0xd6, 0x81, 0xc8, 0xff, 0xff, 0xf2, 0x7e, 0x17, 0x9e, 0x55, + 0x25, 0x3e, 0x64, 0xf0, 0xda, 0xac, 0xd3, 0x46, 0x4e, 0x13, 0xe9, 0xe3, 0xd1, 0xe8, 0xd9, 0x8f, + 0x47, 0xd6, 0x3f, 0x2a, 0xc0, 0xf5, 0x7c, 0x0e, 0x8a, 0x96, 0x56, 0x8d, 0x04, 0x37, 0x03, 0x2e, + 0xbd, 0xf1, 0x48, 0xa8, 0x25, 0xb8, 0x49, 0x26, 0xb5, 0xb1, 0x69, 0xc7, 0x7f, 0x46, 0x83, 0x17, + 0x09, 0x3f, 0xb6, 0x2c, 0x6e, 0xf8, 0x5d, 0x1a, 0xca, 0xf4, 0x60, 0xbc, 0xc8, 0x78, 0x6f, 0x2e, + 0xca, 0xac, 0x7f, 0x57, 0x80, 0xab, 0xb8, 0x0d, 0x0a, 0x2f, 0x9f, 0xac, 0x78, 0xa9, 0xc8, 0x11, + 0xbd, 0x71, 0x31, 0xeb, 0x18, 0x39, 0x22, 0x7b, 0xd0, 0xee, 0xf8, 0x5d, 0x6a, 0x1b, 0x60, 0x64, + 0x03, 0xa6, 0xc4, 0xb7, 0xe6, 0xca, 0x99, 0xd7, 0xd2, 0x65, 0xa1, 0x50, 0xf1, 0x33, 0x1f, 0x8a, + 0x90, 0x20, 0xd6, 0xc6, 0xe7, 0x35, 0x3a, 0xae, 0xf5, 0xeb, 0x22, 0x2c, 0xb6, 0x68, 0xe0, 0x3e, + 0x7d, 0x91, 0x33, 0x98, 0x47, 0x30, 0x27, 0x8b, 0x70, 0xcc, 0xa6, 0x30, 0xf3, 0x17, 0xb5, 0xb2, + 0xab, 0x21, 0x03, 0x68, 0x2b, 0xd9, 0xce, 0x44, 0x3c, 0xc3, 0x1b, 0xf3, 0xf7, 0x61, 0x42, 0xad, + 0x87, 0x11, 0xe4, 0x0c, 0xce, 0x8d, 0x5c, 0x0b, 0x66, 0xe2, 0x12, 0xb5, 0x28, 0xfe, 0x7c, 0xfe, + 0x75, 0x81, 0xb0, 0xff, 0x87, 0x1c, 0xcd, 0xf8, 0xd2, 0x60, 0xcb, 0xc2, 0xd1, 0x6a, 0x33, 0x96, + 0xc6, 0xfa, 0x39, 0x3b, 0xaf, 0xa5, 0xfa, 0x14, 0x4c, 0xd6, 0xf0, 0x32, 0x83, 0x99, 0xdb, 0xff, + 0xab, 0x08, 0x4b, 0x32, 0xd8, 0x37, 0x87, 0xcd, 0x5f, 0xc3, 0x82, 0x2c, 0xaa, 0xf5, 0xfb, 0x81, + 0xff, 0x8c, 0x76, 0x4d, 0x4e, 0xf3, 0x57, 0xed, 0x92, 0xd3, 0x8e, 0x80, 0x89, 0x99, 0x9d, 0x87, + 0xfe, 0x7a, 0xdc, 0x18, 0x5f, 0x98, 0xda, 0x89, 0xcf, 0x06, 0xba, 0x13, 0x74, 0xed, 0x64, 0x66, + 0x76, 0xd3, 0x35, 0x55, 0x37, 0xe5, 0x06, 0x19, 0x7d, 0x55, 0x37, 0x08, 0x3b, 0xa8, 0x99, 0x34, + 0xeb, 0xb3, 0x30, 0xbd, 0x45, 0x9f, 0xc7, 0x7c, 0xff, 0x79, 0x01, 0x66, 0x8c, 0xc5, 0x4d, 0xde, + 0x81, 0x31, 0xfc, 0x03, 0x77, 0x5e, 0xf1, 0x1e, 0x8f, 0x2d, 0x30, 0xe3, 0x3d, 0x1e, 0x07, 0xdd, + 0x80, 0x71, 0x1e, 0x67, 0xd5, 0x3d, 0x85, 0x45, 0xad, 0xe2, 0x26, 0x3b, 0x1c, 0x85, 0x1b, 0xd7, + 0x02, 0xdf, 0x7a, 0x00, 0x37, 0x44, 0x10, 0x9b, 0x39, 0xf9, 0xd8, 0xd0, 0x19, 0x37, 0x0a, 0xcb, + 0x81, 0xa5, 0x7b, 0x34, 0xa9, 0x7a, 0x8c, 0xb8, 0xd2, 0x2f, 0xe1, 0x82, 0x51, 0xae, 0x28, 0xe2, + 0x9b, 0x1d, 0x25, 0x43, 0x8a, 0x74, 0x12, 0xda, 0xba, 0x9e, 0xd5, 0x84, 0xde, 0x59, 0x8b, 0xe2, + 0xf3, 0xf4, 0x20, 0xbe, 0xd1, 0x09, 0xcf, 0xa0, 0xf5, 0x6e, 0x6a, 0xeb, 0x9a, 0x6b, 0x3c, 0xfe, + 0xdc, 0x5b, 0xee, 0x71, 0xaa, 0xd6, 0x9a, 0x81, 0xa9, 0x86, 0xef, 0x45, 0xf4, 0x5b, 0x7c, 0x70, + 0x65, 0xcd, 0xc2, 0xb4, 0xac, 0xea, 0xd1, 0x30, 0xb4, 0xfe, 0xf6, 0x08, 0x58, 0x82, 0xb1, 0x59, + 0x3e, 0x0f, 0xc9, 0x8f, 0xdd, 0x54, 0x67, 0xc5, 0x26, 0x72, 0x59, 0xf7, 0xec, 0xc4, 0xb5, 0x5c, + 0xf2, 0xf0, 0x96, 0xb7, 0x13, 0x97, 0x1a, 0x92, 0x97, 0x1a, 0xfd, 0x8f, 0x72, 0xd4, 0x24, 0x5f, + 0x6c, 0x98, 0x37, 0x2a, 0x47, 0x4d, 0x1a, 0x74, 0xb3, 0x55, 0xa6, 0x6d, 0xb0, 0x41, 0x6c, 0xee, + 0x44, 0x3d, 0xca, 0x50, 0x35, 0x22, 0xd7, 0x22, 0x2f, 0x68, 0xa7, 0x72, 0x25, 0xea, 0x44, 0xc8, + 0x63, 0x93, 0x97, 0x62, 0x3d, 0xca, 0x1b, 0x54, 0xbd, 0x8a, 0x53, 0xed, 0x6b, 0x25, 0x66, 0xea, + 0x49, 0x03, 0x56, 0xf3, 0x63, 0xfd, 0x8d, 0x02, 0x5c, 0xe5, 0xb3, 0xb3, 0x1d, 0xb8, 0xcf, 0xdc, + 0x1e, 0xdd, 0xa3, 0x86, 0x98, 0x1e, 0x65, 0xdf, 0x44, 0x15, 0x4e, 0xa5, 0xa3, 0x31, 0x93, 0x0e, + 0x15, 0xe8, 0x79, 0x8e, 0xd2, 0x2c, 0xfa, 0xd6, 0x71, 0x41, 0x06, 0x50, 0xa6, 0xae, 0x67, 0xce, + 0x6a, 0xb3, 0xd5, 0x8d, 0x1b, 0x95, 0x62, 0xce, 0x8d, 0x8a, 0xe1, 0xa9, 0x8e, 0x86, 0x5c, 0xb1, + 0x8c, 0xbc, 0xba, 0xf3, 0xf6, 0x57, 0x23, 0x70, 0x71, 0xdb, 0xd9, 0x73, 0x3d, 0xa6, 0x7b, 0xe4, + 0xdb, 0x27, 0x52, 0x4b, 0xe5, 0x21, 0x1c, 0x1c, 0xf0, 0x94, 0x91, 0x68, 0x70, 0x59, 0x4f, 0x09, + 0x56, 0xcc, 0x7b, 0xc1, 0x61, 0x26, 0xfe, 0xfa, 0xc4, 0xf0, 0xd5, 0xa5, 0x62, 0xde, 0x30, 0xaa, + 0xc4, 0xf3, 0xbb, 0x89, 0xdc, 0x9c, 0xe8, 0xef, 0x7a, 0x04, 0x53, 0x5a, 0xe0, 0x9a, 0x10, 0xd0, + 0x14, 0x05, 0x64, 0xcb, 0xc1, 0xd1, 0x2e, 0xcd, 0xcc, 0xc3, 0xa6, 0x53, 0xc8, 0xc8, 0xbe, 0x36, + 0xf6, 0x9a, 0xb3, 0xaf, 0xfd, 0x90, 0x77, 0x59, 0x7a, 0x3e, 0xcf, 0x8b, 0x7d, 0x83, 0x93, 0x4f, + 0xb9, 0x3f, 0x5b, 0x2b, 0x5a, 0xef, 0xb3, 0x52, 0x49, 0xea, 0xc4, 0xea, 0x00, 0x13, 0xf2, 0x89, + 0x9b, 0xf5, 0x3f, 0xce, 0xc3, 0xdc, 0xa6, 0x1b, 0x46, 0x72, 0x76, 0xc3, 0x58, 0xf5, 0x4f, 0xcb, + 0x32, 0xed, 0x10, 0x24, 0xac, 0x34, 0xf1, 0x3e, 0x2e, 0x91, 0x43, 0xd7, 0x40, 0x20, 0x1f, 0xe8, + 0xfe, 0xbb, 0xa2, 0x96, 0x0f, 0x26, 0x9d, 0xfe, 0x54, 0x77, 0xec, 0xbd, 0x63, 0xb8, 0x8f, 0xf8, + 0xbe, 0xda, 0x63, 0x05, 0xfa, 0xbe, 0xca, 0x7d, 0x4a, 0x2b, 0x49, 0x9f, 0x12, 0x6f, 0x80, 0x2b, + 0xc5, 0x03, 0x6a, 0x98, 0xdc, 0xca, 0xd9, 0xf4, 0x18, 0xce, 0xe3, 0x0b, 0x7e, 0x9e, 0xfb, 0x6a, + 0x6a, 0xf9, 0x3b, 0x62, 0x81, 0x64, 0x31, 0x81, 0xbf, 0xf5, 0x0f, 0xb5, 0xbc, 0x66, 0x3d, 0x2c, + 0xd0, 0xd3, 0x06, 0x70, 0x10, 0xb2, 0x03, 0x97, 0xb6, 0x03, 0xda, 0x45, 0xd5, 0xb2, 0xf6, 0x6d, + 0x3f, 0x10, 0x47, 0x0c, 0x74, 0xf0, 0xf1, 0x34, 0x83, 0x7d, 0x59, 0xdd, 0xa6, 0xaa, 0x5e, 0xd7, + 0x30, 0x19, 0xe8, 0x64, 0x0d, 0x66, 0x9b, 0xd4, 0x09, 0x3a, 0xfb, 0x0f, 0xe8, 0x0b, 0xa6, 0x18, + 0xc3, 0xf2, 0x78, 0x9c, 0x50, 0x28, 0xc4, 0x1a, 0x36, 0x50, 0xac, 0xd2, 0xaf, 0x75, 0x4c, 0x24, + 0xf2, 0xbb, 0x70, 0xbe, 0xe9, 0x07, 0x51, 0xfd, 0x45, 0x22, 0x1f, 0x2e, 0x2f, 0xac, 0x5f, 0x91, + 0x49, 0x95, 0x42, 0x3f, 0x88, 0xda, 0xbb, 0x3a, 0xdf, 0x04, 0x1e, 0xb9, 0xcb, 0xac, 0x2e, 0x66, + 0x09, 0x46, 0x4e, 0xaf, 0x81, 0xe1, 0x09, 0xfc, 0xe1, 0xa7, 0xb0, 0xac, 0xd0, 0x7c, 0x8c, 0x9c, + 0x5e, 0x1b, 0xf7, 0x79, 0xf3, 0x82, 0x49, 0xc7, 0x22, 0x2f, 0x60, 0xce, 0x14, 0x74, 0x91, 0x58, + 0x0e, 0x8c, 0xcc, 0x92, 0x59, 0x20, 0xf5, 0x9b, 0xa2, 0x97, 0xd7, 0x93, 0x59, 0x13, 0x53, 0xb9, + 0xe6, 0x32, 0x9b, 0x20, 0x0f, 0x31, 0xa7, 0x15, 0xe7, 0x4c, 0x2d, 0x94, 0xf9, 0xbb, 0xd8, 0x20, + 0x6e, 0x9c, 0x1c, 0x57, 0xaf, 0x1d, 0x61, 0x8a, 0x54, 0xe4, 0xa8, 0x13, 0x26, 0xd3, 0x78, 0xd9, + 0x29, 0xd4, 0xca, 0x27, 0x30, 0xa5, 0x49, 0xc7, 0x99, 0xd2, 0xd2, 0xfd, 0x71, 0x01, 0xe6, 0x13, + 0xe2, 0x26, 0xce, 0xa7, 0x8f, 0x60, 0x52, 0x15, 0x0a, 0x97, 0x4e, 0x59, 0xed, 0xa3, 0x09, 0x3d, + 0xcc, 0x85, 0x5d, 0xae, 0x45, 0xbd, 0xb3, 0x31, 0x0d, 0x72, 0x07, 0xc6, 0xb7, 0xe8, 0xb7, 0xb1, + 0x1f, 0x94, 0x9f, 0x7b, 0x3c, 0xb6, 0xa9, 0x9b, 0x0b, 0x44, 0x82, 0x91, 0x4f, 0x00, 0xb4, 0x59, + 0xe6, 0x8b, 0x10, 0x63, 0x27, 0xb3, 0x27, 0x58, 0x03, 0xb6, 0xfe, 0x68, 0x5c, 0x6e, 0xd3, 0xf2, + 0x75, 0x42, 0xe0, 0x74, 0x0e, 0xe2, 0x20, 0xd6, 0x0f, 0xd2, 0x11, 0xa3, 0xa7, 0xd1, 0x08, 0x6f, + 0x1b, 0xc9, 0x1d, 0xf2, 0x93, 0x77, 0xc7, 0x79, 0x3e, 0x46, 0x4e, 0x91, 0xe7, 0xe3, 0x36, 0x8c, + 0x6f, 0x78, 0xcf, 0x5c, 0x66, 0x94, 0xf3, 0x90, 0x47, 0x34, 0x69, 0x5d, 0x5e, 0xa4, 0x33, 0x46, + 0x40, 0x91, 0x4f, 0x60, 0x62, 0xdd, 0x0f, 0x23, 0x4f, 0x86, 0x3b, 0x8a, 0x55, 0x18, 0xa1, 0x5f, + 0xb8, 0xbd, 0x2f, 0xaa, 0x74, 0x9d, 0x23, 0xc1, 0xc9, 0x87, 0x30, 0x5e, 0xeb, 0x76, 0xd9, 0xa2, + 0x16, 0x0a, 0x01, 0x9f, 0x19, 0x0b, 0x4c, 0x87, 0xd7, 0xe8, 0x4d, 0x0a, 0x60, 0xf2, 0xb9, 0xe9, + 0xa4, 0x1d, 0x8f, 0xb3, 0xe0, 0x64, 0x67, 0xc1, 0x36, 0x1d, 0xb8, 0xef, 0xc8, 0x5b, 0x9e, 0x89, + 0x38, 0xaf, 0x10, 0xe6, 0x08, 0x32, 0x34, 0x29, 0x5e, 0x12, 0x6d, 0xc0, 0xe4, 0x86, 0xe7, 0x46, + 0x2e, 0x66, 0x56, 0x99, 0x34, 0xf6, 0xe3, 0x6d, 0x27, 0x88, 0xdc, 0x8e, 0xdb, 0x77, 0xbc, 0x88, + 0xcf, 0x96, 0x2b, 0x01, 0xf5, 0xd9, 0x52, 0xd8, 0x7a, 0x3a, 0x37, 0x78, 0x6d, 0xe9, 0xdc, 0x32, + 0x33, 0xa2, 0x4d, 0xbd, 0x7c, 0x46, 0xb4, 0x15, 0x3e, 0x97, 0x68, 0x03, 0x4f, 0xc7, 0x82, 0x88, + 0xbe, 0x4b, 0xd3, 0xd8, 0xb5, 0x15, 0x20, 0xb9, 0x8e, 0x99, 0x54, 0x66, 0xe2, 0x70, 0x4f, 0xe3, + 0x56, 0xb9, 0xb8, 0xb1, 0x4a, 0xda, 0x30, 0xcd, 0xa0, 0xb7, 0xfd, 0x9e, 0xdb, 0x71, 0x69, 0x58, + 0x9e, 0x35, 0x9c, 0xdd, 0xe6, 0xa2, 0x40, 0xa0, 0x17, 0x4d, 0x1a, 0xf1, 0x3d, 0x15, 0x9b, 0xee, + 0x0b, 0x44, 0x7d, 0x4f, 0xd5, 0x09, 0x92, 0x9f, 0xb0, 0xfd, 0x40, 0xa7, 0x22, 0xd2, 0x56, 0x2f, + 0x64, 0x36, 0xd1, 0x7a, 0x4f, 0x6e, 0x14, 0xe2, 0xe9, 0x10, 0x2f, 0x36, 0x37, 0x0a, 0x1d, 0xc1, + 0xb2, 0xa1, 0x1c, 0x5f, 0x2d, 0x25, 0x56, 0xef, 0x87, 0xe9, 0xe7, 0x2b, 0x98, 0xb2, 0x35, 0x7e, + 0xbe, 0xa2, 0x0b, 0x44, 0xfc, 0x90, 0xe5, 0x31, 0x5c, 0xb5, 0xe9, 0xa1, 0xff, 0x8c, 0xbe, 0x5e, + 0xb2, 0x3f, 0x82, 0x2b, 0x26, 0xc1, 0xc7, 0xfd, 0x2e, 0xbe, 0xbd, 0xe6, 0x77, 0x58, 0x99, 0xf9, + 0x85, 0x04, 0x02, 0xcf, 0x2f, 0xc4, 0x93, 0x56, 0xb0, 0x3f, 0xf5, 0xf5, 0x80, 0x75, 0x96, 0x0f, + 0x8b, 0x26, 0xf1, 0x5a, 0xb7, 0xab, 0x2d, 0x04, 0x66, 0x50, 0x6a, 0x9f, 0x09, 0x0b, 0x56, 0x5f, + 0x31, 0xa8, 0x39, 0xfb, 0x71, 0x81, 0xbe, 0x56, 0x35, 0x38, 0x8b, 0x42, 0x35, 0xc9, 0x1e, 0xc6, + 0x32, 0xbd, 0xcd, 0x3a, 0xcc, 0x68, 0x9f, 0xea, 0x40, 0x88, 0xaa, 0x44, 0x6b, 0xc1, 0x64, 0x98, + 0x89, 0x62, 0x75, 0xa0, 0x92, 0xc5, 0x34, 0x5c, 0x66, 0x2f, 0xc8, 0x5a, 0xbc, 0x74, 0x87, 0xdf, + 0x1d, 0x5e, 0xc8, 0x7d, 0xdb, 0xf9, 0x7b, 0xa3, 0x70, 0x55, 0x4c, 0xc6, 0xeb, 0x9c, 0x71, 0xf2, + 0x53, 0x98, 0xd2, 0xe6, 0x58, 0x30, 0xfd, 0xba, 0x0c, 0x37, 0xc8, 0x93, 0x05, 0xae, 0x2f, 0x8f, + 0xb0, 0xa0, 0x9d, 0x98, 0x6e, 0x66, 0x18, 0xeb, 0x62, 0xd3, 0x83, 0x59, 0x73, 0xa2, 0xc5, 0x61, + 0xe3, 0x8d, 0xcc, 0x46, 0x4c, 0x50, 0x99, 0x69, 0xa3, 0xdb, 0xce, 0x9c, 0x6e, 0xcc, 0xb1, 0x6d, + 0x0a, 0xd1, 0xb7, 0x70, 0x31, 0x35, 0xcb, 0xe2, 0x6c, 0xf2, 0x76, 0x66, 0x83, 0x29, 0x68, 0xae, + 0xfc, 0x02, 0x2c, 0xce, 0x6d, 0x36, 0xdd, 0x08, 0xe9, 0xc2, 0xb4, 0x3e, 0xf1, 0xe2, 0xf0, 0x72, + 0x63, 0x00, 0x2b, 0x39, 0x20, 0x57, 0x55, 0x82, 0x97, 0x38, 0xf7, 0xe6, 0xcf, 0x52, 0x18, 0x54, + 0xeb, 0x13, 0x70, 0x9e, 0x7f, 0x33, 0x15, 0xb0, 0x1d, 0xd0, 0x90, 0x7a, 0x1d, 0xaa, 0x47, 0x8e, + 0xbc, 0xaa, 0x0a, 0xf8, 0xb7, 0x05, 0x28, 0x67, 0xd1, 0x6d, 0x52, 0xaf, 0x4b, 0xb6, 0xa1, 0x94, + 0x6c, 0x48, 0x48, 0xb5, 0x25, 0x2d, 0xaa, 0xfc, 0x2e, 0xad, 0x9f, 0xb3, 0x53, 0xd8, 0x6c, 0x13, + 0xd2, 0xca, 0xce, 0x18, 0xa2, 0x93, 0x46, 0xd5, 0x1d, 0x1c, 0xeb, 0x18, 0x89, 0xb4, 0xea, 0x1f, + 0x3a, 0xae, 0xc7, 0xf6, 0x6e, 0x65, 0x10, 0xde, 0x06, 0x88, 0x4b, 0x05, 0x6f, 0xb8, 0x13, 0x00, + 0x4b, 0x65, 0xb8, 0x9a, 0x02, 0xb1, 0x3e, 0x47, 0x0d, 0x2e, 0xf6, 0x39, 0xfe, 0x90, 0x41, 0x11, + 0xbb, 0x0e, 0x63, 0x3b, 0x9b, 0xcd, 0x46, 0x4d, 0x3c, 0x8b, 0xe0, 0x6f, 0xdc, 0x7a, 0x61, 0xbb, + 0xe3, 0xd8, 0xbc, 0xc2, 0xfa, 0x97, 0x45, 0x98, 0x93, 0xef, 0xb2, 0x0d, 0x0f, 0xcb, 0xd0, 0x14, + 0x58, 0x3f, 0x30, 0xdf, 0x95, 0x37, 0xd4, 0xbb, 0xf2, 0x57, 0xc8, 0x80, 0x2b, 0x5e, 0xa4, 0x9f, + 0xf2, 0x1d, 0xcb, 0x03, 0x75, 0xb0, 0x1b, 0x35, 0x0e, 0x76, 0x59, 0xe3, 0x31, 0x0e, 0x76, 0xc8, + 0x07, 0x7e, 0xb0, 0x93, 0xc7, 0xb9, 0x57, 0xb1, 0xee, 0x3f, 0x66, 0x73, 0x69, 0x34, 0x79, 0xda, + 0x07, 0x1c, 0x9b, 0xf8, 0x8e, 0xee, 0xd1, 0xc6, 0x6a, 0x83, 0x09, 0x91, 0xe8, 0xaa, 0x9c, 0x81, + 0xdb, 0x18, 0xf4, 0x23, 0x68, 0xea, 0x92, 0x80, 0x3a, 0x4d, 0x3c, 0x0b, 0xd6, 0x40, 0xac, 0x15, + 0xa4, 0xd6, 0xac, 0x3d, 0xdc, 0xcc, 0xa0, 0x96, 0x97, 0x15, 0x6e, 0x0b, 0x1f, 0xda, 0xde, 0xc3, + 0xf9, 0x7a, 0x1d, 0x9d, 0xf8, 0x83, 0x02, 0x7f, 0xb9, 0xdb, 0x7c, 0xb4, 0xea, 0x3a, 0x7b, 0x9e, + 0x1f, 0x46, 0x6e, 0x67, 0xc3, 0x7b, 0xea, 0x6b, 0x0e, 0x66, 0xad, 0x19, 0x2d, 0xab, 0x39, 0x5a, + 0xe3, 0xf8, 0x8b, 0x05, 0xe2, 0xa5, 0x10, 0xe6, 0x07, 0xb7, 0x93, 0xd0, 0xe4, 0x13, 0x98, 0xd1, + 0x8a, 0xd4, 0xae, 0xc8, 0x93, 0x27, 0xe9, 0xe8, 0x6e, 0xd7, 0x36, 0x21, 0xad, 0x9f, 0x17, 0xe1, + 0xea, 0x80, 0x3c, 0xc8, 0xe8, 0x5e, 0x40, 0xdf, 0x90, 0xe2, 0x14, 0x77, 0x2f, 0xf0, 0x57, 0x51, + 0x86, 0x52, 0x52, 0x80, 0xcc, 0x64, 0xd7, 0xd3, 0x32, 0x17, 0xb5, 0xc4, 0x95, 0xd9, 0xa9, 0x98, + 0x75, 0x70, 0x12, 0x02, 0xc4, 0x3d, 0x11, 0xc7, 0x98, 0x26, 0x3e, 0x5c, 0x8b, 0x73, 0x3a, 0xbf, + 0x96, 0xe4, 0xd2, 0x5a, 0x33, 0xd6, 0x5f, 0x2d, 0xc2, 0xd2, 0x00, 0x3e, 0x34, 0x69, 0xf4, 0x27, + 0xc1, 0x8a, 0x44, 0xa6, 0xed, 0x91, 0xdf, 0x52, 0xa6, 0x6d, 0xeb, 0x5f, 0x17, 0x30, 0xcd, 0x08, + 0xc6, 0xe6, 0x6d, 0x78, 0xcf, 0xa8, 0x17, 0xf9, 0xc1, 0x0b, 0x8c, 0x2d, 0x22, 0x1f, 0xc0, 0xd8, + 0x3a, 0xed, 0xf5, 0x7c, 0xb1, 0x8f, 0x5c, 0x93, 0x3e, 0xff, 0x24, 0x34, 0x02, 0xad, 0x9f, 0xb3, + 0x39, 0x34, 0xf9, 0x04, 0x26, 0xd7, 0xa9, 0x13, 0x44, 0xbb, 0xd4, 0x91, 0xa6, 0xe2, 0x15, 0x81, + 0xaa, 0xa1, 0x08, 0x80, 0xf5, 0x73, 0x76, 0x0c, 0x4d, 0x96, 0x61, 0x74, 0xdb, 0xf7, 0xf6, 0xd4, + 0x93, 0x9c, 0x9c, 0x06, 0x19, 0xcc, 0xfa, 0x39, 0x1b, 0x61, 0xeb, 0x63, 0x30, 0xf2, 0x30, 0xdc, + 0xb3, 0x7e, 0x51, 0x80, 0xf2, 0xaa, 0xff, 0xdc, 0xcb, 0x1c, 0xc9, 0x47, 0xe6, 0x48, 0x64, 0xc8, + 0x67, 0x06, 0x7c, 0x62, 0x2c, 0xef, 0xc3, 0xe8, 0xb6, 0xeb, 0xed, 0x25, 0xb6, 0xbd, 0x0c, 0x3c, + 0x06, 0x85, 0x5d, 0x72, 0xe3, 0x2e, 0xbd, 0x03, 0x0b, 0x39, 0x90, 0x64, 0x56, 0xe9, 0xa3, 0x51, + 0xd4, 0x43, 0xdf, 0x81, 0xf9, 0xcc, 0x51, 0xa6, 0x00, 0xff, 0x5e, 0xd6, 0x74, 0xf1, 0xbe, 0x96, + 0x61, 0x5c, 0xa6, 0xbc, 0xe3, 0x8a, 0x5b, 0x7e, 0x62, 0x30, 0x9a, 0x14, 0x67, 0x91, 0x4d, 0x49, + 0x49, 0x6d, 0x8b, 0xd7, 0x61, 0xb0, 0x12, 0x17, 0xba, 0x4f, 0x5f, 0x41, 0xb4, 0x14, 0x2d, 0x6b, + 0x3b, 0x73, 0x3a, 0x5e, 0xa1, 0xa7, 0x56, 0x03, 0x48, 0x5a, 0x7e, 0xc8, 0xf7, 0x60, 0xb2, 0xd9, + 0x5c, 0x1f, 0xf8, 0x3e, 0xdc, 0x8e, 0x21, 0xac, 0x0f, 0xe1, 0xb2, 0x22, 0xc2, 0x73, 0x5c, 0x69, + 0xf1, 0x97, 0xe2, 0xa7, 0x98, 0x54, 0xd8, 0x67, 0x5c, 0x60, 0xfd, 0x28, 0x85, 0xd7, 0x3c, 0x3a, + 0x3c, 0x74, 0x82, 0x17, 0xa4, 0x66, 0xe2, 0x8d, 0x0c, 0x5d, 0x29, 0xf5, 0xd1, 0x5f, 0x1e, 0x57, + 0xcf, 0xe9, 0xc4, 0x97, 0x61, 0xce, 0x10, 0x0f, 0xd9, 0xa5, 0x4a, 0x52, 0x0d, 0x69, 0xdc, 0xb8, + 0x0b, 0xf3, 0x09, 0x1c, 0xb1, 0xed, 0x7e, 0x0f, 0x94, 0xa1, 0x80, 0x48, 0x23, 0xf5, 0x8b, 0xbf, + 0x39, 0xae, 0xce, 0x44, 0xee, 0x21, 0xbd, 0x15, 0x27, 0xc5, 0x90, 0x7f, 0xbd, 0xfb, 0x2e, 0x4c, + 0xaa, 0x5f, 0x8a, 0x23, 0x13, 0x30, 0xba, 0xb1, 0xb5, 0xb1, 0xc3, 0x93, 0x5c, 0x6f, 0x3f, 0xde, + 0x29, 0x15, 0x08, 0xc0, 0xf9, 0xd5, 0xb5, 0xcd, 0xb5, 0x9d, 0xb5, 0x52, 0xf1, 0xdd, 0xb6, 0x7e, + 0x6b, 0x43, 0xae, 0xc2, 0xc2, 0xea, 0x5a, 0x6b, 0xa3, 0xb1, 0xd6, 0xde, 0xf9, 0xc1, 0xf6, 0x5a, + 0xdb, 0x7c, 0xb3, 0x3a, 0x07, 0x25, 0xbd, 0x72, 0xe7, 0xd1, 0xce, 0x76, 0xa9, 0x40, 0xca, 0x30, + 0xa7, 0x97, 0x3e, 0x59, 0xab, 0xd7, 0x1e, 0xef, 0xac, 0x6f, 0x95, 0x46, 0xac, 0xd1, 0x89, 0x62, + 0xa9, 0xf8, 0xee, 0x4f, 0x8d, 0x2b, 0x1d, 0xb2, 0x08, 0x65, 0x01, 0xfe, 0xb8, 0x59, 0xbb, 0x97, + 0xdf, 0x04, 0xaf, 0x7d, 0x78, 0xb7, 0x56, 0x2a, 0x90, 0x6b, 0x70, 0xc5, 0x28, 0xdd, 0xae, 0x35, + 0x9b, 0x4f, 0x1e, 0xd9, 0xab, 0x9b, 0x6b, 0xcd, 0x66, 0xa9, 0xf8, 0xee, 0xdb, 0x22, 0xf6, 0x92, + 0xcc, 0x02, 0xac, 0xae, 0x35, 0x1b, 0x6b, 0x5b, 0xab, 0x1b, 0x5b, 0xf7, 0x4a, 0xe7, 0xc8, 0x0c, + 0x4c, 0xd6, 0xd4, 0x67, 0x61, 0xf9, 0x1f, 0x7b, 0x30, 0xc5, 0xb6, 0x4f, 0x79, 0x03, 0xf2, 0x8d, + 0x36, 0xff, 0x22, 0x1b, 0xa1, 0x48, 0x64, 0x96, 0x3b, 0xd9, 0xa8, 0x7a, 0x2a, 0x03, 0x74, 0x0d, + 0x02, 0xdc, 0x2c, 0xdc, 0x29, 0x10, 0x1b, 0xb3, 0x63, 0x26, 0x04, 0x4c, 0x51, 0xce, 0x16, 0xd8, + 0x4a, 0x4e, 0xb5, 0x94, 0xcb, 0xfb, 0x30, 0xc3, 0xe4, 0x42, 0xd5, 0x92, 0xab, 0x49, 0x78, 0x4d, + 0xd4, 0x2a, 0x8b, 0xd9, 0x95, 0x42, 0xa6, 0xda, 0xb0, 0xf0, 0xd0, 0x71, 0xbd, 0xc8, 0x71, 0x3d, + 0x71, 0x1c, 0x91, 0x87, 0x09, 0x52, 0x1d, 0x70, 0xba, 0x60, 0x07, 0x93, 0xca, 0xb0, 0xf8, 0x7a, + 0x64, 0x40, 0x13, 0xe6, 0xb2, 0x3c, 0xa9, 0xc4, 0x32, 0xf3, 0xf6, 0x65, 0x9d, 0xaf, 0x2b, 0x79, + 0xce, 0x20, 0xf2, 0x10, 0x2e, 0xa6, 0xbc, 0x3b, 0xaa, 0xbf, 0x79, 0x7e, 0x9f, 0x41, 0xe4, 0xca, + 0x78, 0xb7, 0x1f, 0xb9, 0x49, 0xdf, 0x4e, 0x48, 0x2e, 0xa7, 0x3c, 0x07, 0x6b, 0x6c, 0x93, 0xce, + 0x25, 0x86, 0x73, 0x3e, 0x97, 0xe5, 0x27, 0x52, 0x43, 0x1e, 0xe0, 0x44, 0xaa, 0xe4, 0x34, 0xc7, + 0x68, 0x66, 0x79, 0x22, 0x14, 0xcd, 0x01, 0x6e, 0x8a, 0x5c, 0x9a, 0x9f, 0xc3, 0x2c, 0x9b, 0xc7, + 0x07, 0x94, 0xf6, 0x6b, 0x3d, 0xf7, 0x19, 0x0d, 0x89, 0x7c, 0x1d, 0xa2, 0x8a, 0xf2, 0x70, 0x6f, + 0x16, 0xc8, 0xef, 0xc0, 0x14, 0xfe, 0x6c, 0x8e, 0x08, 0x66, 0x9e, 0xd6, 0x7f, 0x4a, 0xa7, 0x22, + 0xbf, 0xb0, 0xf2, 0x4e, 0x81, 0x7c, 0x1f, 0xc6, 0xef, 0xd1, 0x08, 0xaf, 0x30, 0x6f, 0x24, 0x7e, + 0x81, 0x72, 0xc3, 0x53, 0x0e, 0x72, 0xd9, 0xe1, 0xa4, 0x9a, 0x67, 0xd6, 0x3a, 0x4f, 0x58, 0x81, + 0x14, 0x92, 0xd5, 0x95, 0x54, 0xb7, 0xc9, 0x3d, 0xa6, 0xcf, 0x7a, 0x34, 0xa2, 0xa7, 0x6d, 0x32, + 0x8f, 0x47, 0x9b, 0x30, 0xab, 0xd2, 0x47, 0x6c, 0x61, 0x0c, 0x8c, 0x95, 0x20, 0x16, 0x9e, 0x81, + 0xda, 0xa7, 0x4c, 0x6e, 0xf9, 0x89, 0x4a, 0xbd, 0x9c, 0x21, 0x79, 0x6f, 0x69, 0x14, 0x13, 0x39, + 0x98, 0x86, 0xab, 0x7e, 0x09, 0x48, 0xe1, 0x26, 0x7f, 0x1b, 0x28, 0x81, 0x4b, 0xa1, 0xa2, 0xb7, + 0x6b, 0xbe, 0xa2, 0x21, 0xd7, 0xb5, 0x0e, 0x64, 0x3e, 0xfe, 0xa9, 0xdc, 0x18, 0x00, 0xc1, 0x15, + 0x09, 0xae, 0xf5, 0xfb, 0x30, 0x63, 0xbc, 0xbb, 0x88, 0x15, 0x53, 0xc6, 0xc3, 0x98, 0x58, 0x31, + 0x65, 0x3e, 0xd5, 0xb8, 0x8b, 0x4b, 0x3c, 0x91, 0x48, 0xbe, 0x92, 0x95, 0x30, 0x9e, 0xdf, 0x8a, + 0x55, 0x64, 0x42, 0xce, 0x04, 0xca, 0x03, 0xcc, 0xc2, 0x63, 0x16, 0xb6, 0x96, 0x07, 0x52, 0xca, + 0x49, 0x4b, 0x7f, 0xa7, 0x40, 0xd6, 0xe0, 0x92, 0x0a, 0x5a, 0xd2, 0x7e, 0x7f, 0x31, 0x07, 0x21, + 0x57, 0x0c, 0xbe, 0x84, 0x4b, 0x42, 0xa8, 0x0c, 0x32, 0x25, 0xa5, 0x1f, 0xc4, 0xc1, 0x2e, 0x97, + 0xc0, 0x7d, 0x98, 0x6f, 0x26, 0x06, 0xc5, 0xfd, 0x7e, 0x57, 0x4c, 0x12, 0x5a, 0x06, 0xfb, 0x5c, + 0x5a, 0x0f, 0x80, 0x34, 0x8f, 0x76, 0x0f, 0x5d, 0x45, 0xee, 0x99, 0x4b, 0x9f, 0x93, 0x6b, 0x89, + 0x21, 0xb1, 0x42, 0x04, 0x43, 0x05, 0x93, 0xc7, 0x22, 0xb2, 0xc3, 0x53, 0xd1, 0xf1, 0xd4, 0xbe, + 0x4e, 0xdf, 0xd9, 0x75, 0x7b, 0x6e, 0xe4, 0x52, 0x26, 0x63, 0x3a, 0x82, 0x5e, 0x25, 0xc5, 0xe1, + 0x4a, 0x2e, 0x04, 0xf9, 0x02, 0x66, 0xee, 0xd1, 0x28, 0x4e, 0xd2, 0x4f, 0x16, 0x52, 0x69, 0xfd, + 0xc5, 0xd4, 0xc9, 0xf0, 0x55, 0xf3, 0x97, 0x01, 0x36, 0xa0, 0xc4, 0xf5, 0xa3, 0x46, 0xe2, 0x5a, + 0x8a, 0x84, 0x00, 0x71, 0x02, 0xe7, 0x30, 0xcc, 0xe5, 0xd6, 0x6d, 0x7e, 0x6c, 0x20, 0x32, 0x1a, + 0x45, 0xdf, 0x69, 0x2f, 0x19, 0x65, 0x42, 0x8e, 0x77, 0xa1, 0xca, 0xb3, 0xd3, 0xa7, 0x33, 0xc2, + 0xcb, 0xdf, 0x2c, 0x7b, 0x53, 0xbd, 0xbd, 0x1a, 0x90, 0xc5, 0x5e, 0xf1, 0x27, 0x59, 0xdf, 0x5a, + 0x21, 0xdb, 0xc8, 0xf5, 0x74, 0x03, 0xe4, 0x8d, 0x78, 0x4b, 0xcc, 0x4d, 0x48, 0x5f, 0x21, 0x49, + 0xc2, 0xad, 0x15, 0xa2, 0x52, 0xcc, 0x65, 0x10, 0x7d, 0xdb, 0xd8, 0xb9, 0xcf, 0x46, 0xf7, 0x0b, + 0x98, 0x54, 0xd9, 0xd8, 0x95, 0xf2, 0x4a, 0xa6, 0x90, 0xaf, 0x94, 0xd3, 0x15, 0x82, 0x9b, 0x9f, + 0xf3, 0x1f, 0x4e, 0x30, 0xf1, 0x93, 0x09, 0xcb, 0x73, 0x27, 0xef, 0x13, 0x98, 0xd2, 0x52, 0x95, + 0xab, 0xc5, 0x92, 0x4e, 0x5f, 0x5e, 0x31, 0x7f, 0x67, 0xf7, 0x4e, 0x81, 0xdc, 0xc6, 0x0d, 0x0c, + 0x6f, 0xcf, 0xe6, 0x63, 0x34, 0x2d, 0x4b, 0x72, 0x02, 0x85, 0x7c, 0x84, 0x4f, 0x60, 0x1a, 0x47, + 0x41, 0x40, 0x3d, 0x8e, 0x97, 0x67, 0x49, 0x24, 0x10, 0xbf, 0x40, 0x85, 0xa5, 0x21, 0x72, 0xdf, + 0xe1, 0x30, 0x6c, 0x9e, 0xe2, 0xe4, 0x4e, 0x81, 0xac, 0xc0, 0x84, 0xfc, 0x15, 0x0f, 0x72, 0xd9, + 0xec, 0x6a, 0xfe, 0xf0, 0x56, 0x00, 0x38, 0xb3, 0xb1, 0xa7, 0x66, 0x75, 0x2e, 0x3b, 0x57, 0xd8, + 0xae, 0xdc, 0x3d, 0x23, 0xd2, 0x17, 0x72, 0x67, 0x46, 0xa4, 0xb2, 0x31, 0x85, 0x3a, 0x3b, 0xf3, + 0xf0, 0x37, 0xa0, 0x54, 0xeb, 0xe0, 0x5e, 0xa1, 0x32, 0x46, 0x93, 0x25, 0xa5, 0x3a, 0xcc, 0x0a, + 0x49, 0x6b, 0x3e, 0x99, 0x80, 0x7a, 0x93, 0x3a, 0xf8, 0x9a, 0x67, 0x41, 0x59, 0x0c, 0x89, 0xaa, + 0x6c, 0x8c, 0xdc, 0x4e, 0xad, 0xc1, 0x5c, 0xc3, 0xf1, 0x3a, 0xb4, 0xf7, 0x6a, 0x64, 0x3e, 0x45, + 0x3d, 0xa7, 0x65, 0xd3, 0xbe, 0x9c, 0xc4, 0x17, 0x6a, 0xee, 0xa2, 0xba, 0xe0, 0x50, 0xa0, 0x35, + 0xb8, 0x20, 0x92, 0xf6, 0x29, 0xb6, 0xe4, 0x61, 0xe7, 0x35, 0xff, 0x11, 0xcc, 0xae, 0xb1, 0x7d, + 0xe0, 0xa8, 0xeb, 0xf2, 0x17, 0x8c, 0xc4, 0x7c, 0x92, 0x96, 0x8b, 0xb8, 0x2e, 0x7f, 0x63, 0x41, + 0x4b, 0x33, 0xad, 0x56, 0x57, 0x3a, 0x93, 0x77, 0x65, 0x4e, 0x92, 0xd5, 0x33, 0x52, 0xa3, 0x05, + 0xb1, 0x27, 0x53, 0x99, 0x26, 0x92, 0x07, 0xeb, 0x9a, 0x2c, 0x37, 0xb5, 0x70, 0xe5, 0xcd, 0xc1, + 0x40, 0x22, 0xd8, 0x71, 0xe4, 0x2f, 0x17, 0x99, 0x8d, 0xbe, 0x90, 0x93, 0x98, 0x99, 0xbc, 0x15, + 0x1f, 0xfb, 0x06, 0x24, 0x6e, 0xce, 0x30, 0x3a, 0xbf, 0xd6, 0x12, 0x30, 0xe6, 0xd0, 0x1c, 0x9c, + 0xb1, 0x39, 0x97, 0xc1, 0xea, 0x71, 0x53, 0x66, 0x66, 0x65, 0xf2, 0x8e, 0x49, 0x7d, 0x40, 0xf6, + 0xe5, 0xdc, 0x16, 0x1e, 0xa1, 0xe8, 0xc5, 0x89, 0x7d, 0x95, 0xe9, 0x96, 0x95, 0x7d, 0x59, 0x99, + 0x6e, 0x99, 0x69, 0x91, 0x39, 0x83, 0xef, 0xc1, 0x85, 0x44, 0x8e, 0x63, 0xfd, 0x3c, 0x9d, 0x91, + 0xfb, 0x38, 0xcd, 0x50, 0x4e, 0xe8, 0xa1, 0x14, 0xec, 0x34, 0xa1, 0xec, 0xac, 0xc7, 0x79, 0x63, + 0xe4, 0xe4, 0x1e, 0x2b, 0xdb, 0x4b, 0xcf, 0x63, 0x4c, 0x6e, 0x64, 0xb0, 0xf0, 0x74, 0xac, 0xe3, + 0x64, 0x9b, 0x50, 0x4a, 0xa6, 0x01, 0x26, 0x4b, 0x89, 0x7b, 0x9b, 0x44, 0xae, 0xe3, 0x4a, 0x35, + 0xb7, 0x5e, 0xec, 0x76, 0xf7, 0xe3, 0x49, 0xe1, 0x51, 0x74, 0xc9, 0x49, 0xd1, 0xb3, 0x72, 0xa6, + 0x26, 0xc5, 0x4c, 0x91, 0x79, 0x0f, 0xf7, 0x23, 0x2d, 0xfd, 0x66, 0xee, 0x8e, 0x72, 0x2d, 0x8b, + 0x4e, 0x1c, 0xd9, 0xd5, 0x94, 0xbf, 0xf9, 0xa2, 0xf5, 0x6b, 0xc9, 0xd8, 0xb0, 0xd3, 0x5d, 0xab, + 0xe6, 0xd6, 0xab, 0x91, 0x96, 0x92, 0xb9, 0x4b, 0x15, 0xd1, 0x9c, 0xa4, 0xa6, 0xb9, 0xa2, 0x7c, + 0x17, 0xe6, 0xcc, 0x59, 0x1c, 0x32, 0xde, 0x3c, 0x3a, 0x3b, 0x30, 0x9f, 0x99, 0xb7, 0x54, 0xe9, + 0xa2, 0x41, 0x59, 0x4d, 0x73, 0xa9, 0x52, 0xb8, 0x9c, 0x9d, 0xaa, 0x56, 0x99, 0x81, 0x03, 0x53, + 0xf0, 0x56, 0xde, 0x1a, 0x02, 0x25, 0x18, 0xfa, 0x0d, 0x5a, 0x11, 0xa9, 0x36, 0x6e, 0x68, 0x3e, + 0x92, 0x9c, 0x06, 0xac, 0x41, 0x20, 0x4a, 0x06, 0xe6, 0xb2, 0x72, 0x38, 0xe7, 0xb2, 0xf8, 0x8d, + 0x7c, 0x9a, 0xb1, 0x60, 0xb5, 0x64, 0xea, 0x9a, 0x5c, 0xce, 0x0c, 0xcc, 0x4a, 0x3b, 0xe0, 0x08, + 0x1f, 0x67, 0x2e, 0x3f, 0x7d, 0x97, 0xf3, 0x8f, 0x5e, 0x33, 0x46, 0xba, 0x58, 0x22, 0x43, 0x3d, + 0x13, 0x99, 0x69, 0x53, 0x6b, 0x32, 0x23, 0x6d, 0x2d, 0x5f, 0x93, 0x5a, 0xea, 0xd9, 0xd3, 0xac, + 0xc9, 0xac, 0x4c, 0xb5, 0x6a, 0xf9, 0x68, 0xfd, 0x92, 0x46, 0x51, 0xb2, 0xe2, 0x2c, 0xcb, 0xe7, + 0x34, 0x5d, 0xcb, 0xa3, 0xb3, 0x8a, 0xc6, 0xb6, 0xfa, 0xd5, 0xfb, 0x2b, 0x06, 0x9b, 0x0c, 0x3d, + 0x58, 0x31, 0x06, 0x67, 0xaa, 0xc0, 0x06, 0x4c, 0xeb, 0x99, 0x6f, 0x73, 0x7b, 0x71, 0x35, 0x4d, + 0x23, 0xd4, 0x7c, 0x09, 0xb3, 0x8a, 0x0b, 0xbc, 0x37, 0x8b, 0x49, 0xe6, 0x18, 0x1d, 0xca, 0x1f, + 0x12, 0xd1, 0x59, 0x33, 0xa4, 0x4b, 0xf9, 0xc6, 0xe2, 0x25, 0x6e, 0x36, 0xf3, 0xc7, 0xec, 0x32, + 0x92, 0xef, 0xb2, 0xf2, 0x2b, 0x69, 0xa5, 0x03, 0x9c, 0x08, 0x8f, 0xf1, 0xf9, 0xbf, 0x9e, 0xc6, + 0x96, 0x68, 0x52, 0x92, 0x91, 0xde, 0xb6, 0xb2, 0x94, 0x57, 0xad, 0xef, 0xdb, 0x5f, 0xc1, 0xc5, + 0x54, 0xba, 0x5e, 0xe5, 0x5a, 0xcd, 0x4b, 0xe4, 0x3b, 0x78, 0x6f, 0x5c, 0x67, 0x03, 0x4e, 0x20, + 0xb6, 0x96, 0x87, 0x13, 0x4d, 0x5b, 0x58, 0x9b, 0x32, 0x63, 0x40, 0x56, 0xe7, 0xf2, 0x92, 0x02, + 0x0f, 0x57, 0xf0, 0x89, 0x74, 0xc0, 0x09, 0x05, 0x9f, 0x9d, 0x2c, 0x38, 0x97, 0xea, 0x4f, 0xd0, + 0xe3, 0x9f, 0x48, 0x35, 0xab, 0x7c, 0x6c, 0xb9, 0xe9, 0x85, 0x2b, 0x37, 0x06, 0x40, 0xe8, 0x13, + 0xb4, 0x09, 0x73, 0x59, 0xc9, 0x7b, 0x35, 0x4f, 0x70, 0x6e, 0x66, 0xdf, 0x0c, 0x8e, 0xda, 0x72, + 0xb5, 0xe7, 0x50, 0x1b, 0x90, 0xca, 0x37, 0x97, 0x03, 0x3f, 0x94, 0x09, 0x9a, 0xd3, 0x29, 0x77, + 0x95, 0xf3, 0x60, 0x48, 0x4e, 0xde, 0x01, 0x47, 0x8d, 0x0b, 0x4d, 0x77, 0xcf, 0xd3, 0x32, 0xda, + 0xaa, 0x83, 0x46, 0x3a, 0x2b, 0xaf, 0xd2, 0x2c, 0x59, 0x09, 0x70, 0x1f, 0xc5, 0x01, 0x42, 0x7a, + 0xe6, 0x55, 0x52, 0xc9, 0x4f, 0xfd, 0xaa, 0xb4, 0x4c, 0x66, 0xaa, 0x56, 0x8d, 0xa0, 0x9e, 0xf6, + 0x54, 0x11, 0xcc, 0xc8, 0xc0, 0xaa, 0x08, 0x66, 0xe6, 0x49, 0xe5, 0x3e, 0x07, 0xfc, 0x09, 0x75, + 0xcd, 0xe7, 0xa0, 0x25, 0x2d, 0x4d, 0x1c, 0xfe, 0xc9, 0x67, 0x78, 0xf4, 0x1f, 0xec, 0x2f, 0x58, + 0x30, 0x29, 0xc5, 0x4a, 0x72, 0x45, 0xfa, 0xd8, 0xb1, 0x41, 0x93, 0xf2, 0xf0, 0xd3, 0x3c, 0x22, + 0x99, 0xa7, 0x79, 0xbd, 0xa3, 0xf9, 0xce, 0xc7, 0x69, 0x3d, 0xa9, 0x96, 0xe2, 0x55, 0x46, 0x3e, + 0x3f, 0xc5, 0xab, 0xac, 0x2c, 0x79, 0x78, 0x78, 0xdc, 0x91, 0x27, 0x85, 0x98, 0xde, 0xb5, 0x81, + 0x69, 0xee, 0x2a, 0x4b, 0x83, 0x73, 0xc3, 0x89, 0x0b, 0xac, 0x52, 0x32, 0xef, 0x17, 0xc9, 0xca, + 0x52, 0xa8, 0xa5, 0x53, 0x53, 0xf6, 0x6e, 0x6e, 0xc2, 0xb0, 0x6d, 0x79, 0x0a, 0x31, 0xe9, 0xe6, + 0xe4, 0xaa, 0xd3, 0x49, 0x0f, 0xb6, 0x4b, 0xe2, 0x14, 0x60, 0xfa, 0x59, 0x21, 0x95, 0x62, 0x4c, + 0xb7, 0x4b, 0x32, 0xb2, 0x86, 0xb9, 0xf2, 0xf5, 0x43, 0x76, 0xe6, 0xdb, 0x77, 0x4c, 0x6b, 0x7e, + 0xc0, 0x33, 0xd3, 0xa1, 0x57, 0x84, 0xe4, 0xc7, 0xf2, 0xd7, 0x3a, 0xd2, 0x79, 0x21, 0xdf, 0x4a, + 0xf8, 0x19, 0xb3, 0x1f, 0x26, 0x56, 0x06, 0xa5, 0x9d, 0x24, 0x0f, 0x31, 0x83, 0xcd, 0xa3, 0x8d, + 0xd5, 0x86, 0xb8, 0x93, 0xf7, 0x83, 0xd4, 0x6d, 0x90, 0xf6, 0xdb, 0xb5, 0x31, 0x93, 0x39, 0x88, + 0x81, 0xd8, 0x5a, 0x21, 0x4d, 0xbc, 0x94, 0x30, 0x4a, 0x33, 0x2e, 0x84, 0x32, 0x08, 0x56, 0xb2, + 0x09, 0x6e, 0xba, 0x61, 0xc4, 0xed, 0x01, 0xb6, 0xf0, 0xcc, 0x6e, 0xe6, 0xf4, 0x61, 0x90, 0x59, + 0xc1, 0xc5, 0x26, 0x9b, 0x8c, 0xec, 0xdd, 0x30, 0x39, 0xba, 0x07, 0xf3, 0x9c, 0xe1, 0x89, 0xe8, + 0x3d, 0xa3, 0x3f, 0x5a, 0x79, 0x25, 0xa7, 0x9c, 0x6c, 0xe1, 0x3e, 0x98, 0x2c, 0xd5, 0xf6, 0xc1, + 0xec, 0xf0, 0xc0, 0x5c, 0x7a, 0x7c, 0x2a, 0x9b, 0xb5, 0x87, 0x9b, 0x2f, 0x35, 0x95, 0x06, 0x62, + 0x6b, 0x59, 0x4c, 0xa5, 0x51, 0x7a, 0xb6, 0xa9, 0x4c, 0x10, 0x34, 0xa7, 0xd2, 0xec, 0x66, 0x4e, + 0x1f, 0x86, 0x4f, 0x65, 0x36, 0x99, 0x33, 0x4f, 0x65, 0x22, 0x74, 0xd2, 0xe8, 0x4f, 0xd6, 0x54, + 0x26, 0xe1, 0xf9, 0x54, 0x26, 0x4b, 0xb5, 0xa9, 0xcc, 0x8e, 0xcd, 0xcc, 0xa5, 0xf7, 0x15, 0xd2, + 0xe3, 0xb1, 0x99, 0x67, 0x9a, 0xcc, 0xb2, 0x3c, 0x44, 0x98, 0xa8, 0xad, 0x15, 0xf2, 0x04, 0xcf, + 0xbb, 0x89, 0xf2, 0xd3, 0x4d, 0xe8, 0x62, 0x1e, 0x51, 0x9c, 0xd2, 0x0d, 0x8c, 0xdf, 0xa2, 0x41, + 0xaa, 0xbb, 0xb9, 0x7d, 0x19, 0x34, 0x1f, 0x7c, 0x5a, 0x93, 0xa4, 0xce, 0x3a, 0xb1, 0x0f, 0xa5, + 0xd2, 0x4c, 0x85, 0xb7, 0x26, 0x7a, 0xa5, 0x4f, 0x6e, 0x6e, 0x0d, 0xd9, 0xc1, 0xd3, 0x7c, 0xba, + 0x5c, 0xf3, 0x04, 0xe4, 0xc5, 0xd1, 0x0e, 0xa5, 0x9a, 0x8a, 0x97, 0xd5, 0xa9, 0xe6, 0x05, 0xd3, + 0x2a, 0xaa, 0x69, 0xec, 0x55, 0x5c, 0xb6, 0x3b, 0x01, 0x3b, 0x1d, 0x75, 0xd3, 0x47, 0x27, 0x93, + 0x7f, 0xf2, 0x9a, 0xd0, 0x04, 0x6f, 0x2d, 0x93, 0x0d, 0x14, 0x40, 0xb3, 0x78, 0xd0, 0xd9, 0x32, + 0x9b, 0x0c, 0xca, 0xc7, 0xba, 0x34, 0xc7, 0x13, 0x7d, 0xca, 0x6b, 0x3b, 0xbf, 0x53, 0xea, 0xe0, + 0x7d, 0xca, 0xd1, 0xe5, 0x49, 0x07, 0xb7, 0x02, 0xf9, 0x39, 0x77, 0x18, 0x67, 0xb6, 0x03, 0xff, + 0x99, 0xab, 0x7e, 0x7e, 0xa9, 0xb5, 0x4c, 0x7e, 0x17, 0x26, 0x25, 0xf2, 0x70, 0x86, 0x24, 0xb1, + 0x91, 0x21, 0x5f, 0xc0, 0x94, 0x60, 0x08, 0xf6, 0x20, 0xaf, 0xa5, 0xc1, 0x86, 0x8c, 0x16, 0x75, + 0xae, 0x19, 0x32, 0xe9, 0xf0, 0x77, 0xcd, 0x90, 0xc9, 0x0a, 0x54, 0xff, 0x3e, 0x4c, 0x09, 0x96, + 0x0e, 0xe4, 0x46, 0xbe, 0xe7, 0x68, 0x3e, 0x7e, 0x82, 0x80, 0xf7, 0x18, 0x0d, 0xdf, 0x7b, 0xea, + 0xee, 0x0d, 0x65, 0x4c, 0x1a, 0xa5, 0xb5, 0x4c, 0x5a, 0x98, 0x02, 0x4d, 0xbe, 0x6b, 0xa4, 0xd1, + 0x73, 0x3f, 0x38, 0x70, 0xbd, 0xbd, 0x21, 0x24, 0xaf, 0x9b, 0x24, 0x93, 0x78, 0x9c, 0x6e, 0x33, + 0x9f, 0xee, 0x50, 0xfc, 0xdc, 0xd1, 0x6f, 0xc1, 0x22, 0x5e, 0xee, 0x9e, 0xb5, 0xc7, 0xf9, 0xc7, + 0xed, 0x2b, 0x71, 0x68, 0x96, 0x4d, 0x3b, 0x7e, 0xd0, 0x1d, 0x4e, 0xac, 0x6a, 0x86, 0x59, 0x25, + 0xd0, 0x5a, 0xcb, 0x8c, 0x6a, 0x33, 0x97, 0xea, 0x30, 0xec, 0x01, 0x1a, 0xf6, 0x2a, 0x8e, 0xfd, + 0x8c, 0xbd, 0xcd, 0x77, 0x1c, 0x61, 0x30, 0xcb, 0x51, 0xb4, 0xbf, 0x1d, 0xd0, 0xa7, 0x34, 0xc0, + 0xf8, 0xba, 0x61, 0x91, 0x65, 0x26, 0x78, 0x6b, 0x99, 0x51, 0x69, 0xa6, 0xa8, 0xe4, 0x41, 0x0f, + 0x32, 0x2e, 0x70, 0x68, 0xa7, 0xec, 0x4d, 0xfe, 0xe5, 0xef, 0xa4, 0x4a, 0x74, 0x4a, 0xb4, 0x43, + 0xa5, 0x91, 0xc6, 0xb3, 0x32, 0xa3, 0xc7, 0x81, 0x85, 0xa4, 0xc6, 0x6d, 0x38, 0x3d, 0xe1, 0xa7, + 0x76, 0x4b, 0x92, 0x99, 0x09, 0x34, 0x49, 0x82, 0x1f, 0x8a, 0x37, 0xfd, 0xce, 0x81, 0x7e, 0x28, + 0xd6, 0x32, 0x48, 0x56, 0xcc, 0xfc, 0x8e, 0x42, 0x1d, 0x62, 0x92, 0x47, 0xfd, 0x3e, 0x5c, 0xcf, + 0x21, 0xa9, 0x1f, 0x8a, 0xcd, 0x6c, 0x97, 0xea, 0x50, 0x8c, 0x0d, 0x9a, 0x94, 0x87, 0x1f, 0x8a, + 0x11, 0xc9, 0x3c, 0x14, 0xeb, 0x1d, 0xcd, 0x5f, 0x78, 0x24, 0x9d, 0xee, 0x52, 0x99, 0x5b, 0xb9, + 0x99, 0x30, 0x07, 0x5c, 0x99, 0x5f, 0xca, 0xc8, 0xd0, 0xab, 0x0e, 0x9b, 0xf9, 0xd9, 0x7b, 0x2b, + 0xe6, 0xfd, 0xef, 0x9d, 0x02, 0xd9, 0xc2, 0x5f, 0x0e, 0x13, 0xaa, 0xc0, 0xa6, 0x61, 0x14, 0xb8, + 0x9d, 0x68, 0xa0, 0x7b, 0x58, 0x5a, 0x57, 0x19, 0x38, 0xad, 0xf7, 0x19, 0xbd, 0x66, 0x36, 0xbd, + 0x81, 0x78, 0x03, 0xfc, 0x09, 0x57, 0x44, 0xdc, 0xdf, 0x19, 0xba, 0x98, 0x2f, 0xe2, 0xe3, 0xfc, + 0x0e, 0x2c, 0x1f, 0xb5, 0x14, 0xe7, 0x7a, 0x11, 0xf6, 0xe2, 0x2d, 0x38, 0xcf, 0x91, 0x72, 0x77, + 0x9b, 0x69, 0x1d, 0x87, 0xbc, 0x27, 0x23, 0x62, 0x18, 0x8a, 0x51, 0x95, 0xdb, 0xaf, 0xf7, 0x60, + 0x92, 0x3b, 0x90, 0x4f, 0x8f, 0xf2, 0x99, 0x8c, 0x9b, 0x19, 0xd4, 0xb1, 0xfc, 0x70, 0xb5, 0x19, + 0xfd, 0x42, 0xed, 0xec, 0x8c, 0xfc, 0x3e, 0x3a, 0xf1, 0xa5, 0xd3, 0x2c, 0x1f, 0x7f, 0x3e, 0x91, + 0x77, 0x47, 0xb0, 0xf4, 0x63, 0xbc, 0x49, 0x50, 0xa9, 0xae, 0xf3, 0xba, 0x7f, 0x31, 0x85, 0x4d, + 0x3e, 0x83, 0x59, 0xce, 0x5c, 0x85, 0x9c, 0x06, 0x1a, 0xc0, 0xb3, 0x59, 0xce, 0xe6, 0x97, 0x41, + 0xfe, 0x5d, 0x79, 0xe5, 0x30, 0xb4, 0xdb, 0xa7, 0xb9, 0x6c, 0x18, 0xce, 0xba, 0x3c, 0x2a, 0x3f, + 0xc6, 0x4d, 0x37, 0x3b, 0xad, 0x6d, 0x2e, 0xb1, 0x9b, 0xda, 0x65, 0xca, 0xe0, 0x84, 0xb8, 0x07, + 0x18, 0x39, 0x9d, 0x09, 0xa4, 0x5c, 0xbd, 0x43, 0xf2, 0xdc, 0x56, 0xbe, 0x33, 0x14, 0x4e, 0x39, + 0x58, 0xc5, 0xcf, 0xd6, 0x65, 0xb7, 0x37, 0x24, 0xb9, 0x6d, 0x86, 0xf3, 0x3b, 0x27, 0x67, 0xac, + 0x24, 0x68, 0x86, 0x55, 0x0c, 0x1c, 0x43, 0x1e, 0xfb, 0xbf, 0xd2, 0x7e, 0x7d, 0xee, 0x8c, 0x93, + 0x90, 0x6f, 0x46, 0x91, 0x74, 0x26, 0x5d, 0x32, 0x28, 0xe1, 0x8c, 0x7e, 0xb5, 0x90, 0x97, 0x81, + 0xf7, 0x9e, 0x0c, 0xd3, 0x4f, 0x64, 0x6f, 0xca, 0xcb, 0x03, 0x35, 0xe0, 0x90, 0x2b, 0x02, 0xd5, + 0x5f, 0x0b, 0xa1, 0xf4, 0x6c, 0x9f, 0x9d, 0x90, 0xba, 0xe2, 0x48, 0x10, 0xb2, 0x06, 0x4c, 0xef, + 0x70, 0x6f, 0x6b, 0x39, 0x67, 0x5e, 0xcf, 0x3e, 0xa1, 0x4e, 0x1c, 0x9c, 0x9d, 0x4e, 0xf7, 0xab, + 0xb6, 0xfd, 0xdc, 0xd4, 0xc3, 0x6a, 0x76, 0x07, 0xe4, 0x0a, 0x6e, 0xc4, 0x3f, 0x52, 0x6d, 0xe4, + 0x07, 0x6e, 0xd8, 0x9b, 0xea, 0x78, 0x95, 0x95, 0x38, 0xb8, 0x02, 0xb2, 0xd2, 0xde, 0x64, 0x6b, + 0x3d, 0x2f, 0x2d, 0x6d, 0x1c, 0x13, 0x3a, 0x38, 0xf3, 0xaf, 0x5a, 0xeb, 0x43, 0xf3, 0xdb, 0x6e, + 0xc1, 0x5c, 0x56, 0x3a, 0x59, 0x35, 0x69, 0x03, 0x72, 0xcd, 0x66, 0x06, 0x9e, 0x6e, 0xc3, 0x7c, + 0x66, 0x4a, 0x57, 0x75, 0xd7, 0x37, 0x28, 0xe1, 0x6b, 0x26, 0xc5, 0xaf, 0x61, 0x21, 0x27, 0x7f, + 0x69, 0xec, 0xb9, 0x1e, 0x98, 0xdf, 0x34, 0x57, 0x20, 0xbe, 0x81, 0x4a, 0x7e, 0x6a, 0x4c, 0x72, + 0xd3, 0xf4, 0xbe, 0xe7, 0x27, 0xa4, 0xac, 0x64, 0xe6, 0xf2, 0x25, 0x3b, 0x98, 0x74, 0x3f, 0x2b, + 0x57, 0xa6, 0xea, 0xf7, 0xe0, 0x5c, 0x9a, 0x39, 0x01, 0xc3, 0x0b, 0x39, 0xe9, 0x31, 0x07, 0x50, + 0x3d, 0x45, 0x6f, 0xb7, 0xa4, 0x5e, 0x32, 0xf3, 0x25, 0x26, 0x9e, 0x0f, 0x65, 0x26, 0x53, 0xcc, + 0xec, 0xe7, 0x7d, 0x98, 0x31, 0x12, 0x56, 0x29, 0xf1, 0xcf, 0xca, 0x9a, 0xa6, 0xbc, 0x0b, 0xd9, + 0x39, 0xae, 0xd6, 0xf0, 0xca, 0x25, 0x4e, 0x59, 0x30, 0xc0, 0x06, 0x8e, 0xaf, 0x76, 0xd3, 0x99, + 0x11, 0x1e, 0xe0, 0xa1, 0xc8, 0x48, 0x74, 0x30, 0xe0, 0x38, 0xac, 0x28, 0x65, 0x67, 0x46, 0x68, + 0x41, 0x59, 0xbe, 0x80, 0xe6, 0x6f, 0x90, 0xe3, 0x27, 0x9c, 0xf1, 0x0d, 0x71, 0xfe, 0x13, 0xe9, + 0x3c, 0x99, 0xac, 0x97, 0x7e, 0xf9, 0x5f, 0x97, 0x0a, 0xbf, 0xfc, 0xf5, 0x52, 0xe1, 0x3f, 0xfe, + 0x7a, 0xa9, 0xf0, 0xab, 0x5f, 0x2f, 0x15, 0x76, 0xcf, 0x23, 0xc4, 0xca, 0xff, 0x0d, 0x00, 0x00, + 0xff, 0xff, 0x6d, 0xc4, 0x2b, 0x8b, 0x2d, 0xa8, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -11931,6 +12834,13 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type AuthServiceClient interface { + // InventoryControlStream is the per-instance stream used to advertise teleport instance + // presence/version/etc to the auth server. + InventoryControlStream(ctx context.Context, opts ...grpc.CallOption) (AuthService_InventoryControlStreamClient, error) + // GetInventoryStatus gets information about current instance inventory. + GetInventoryStatus(ctx context.Context, in *InventoryStatusRequest, opts ...grpc.CallOption) (*InventoryStatusSummary, error) + // PingInventory attempts to trigger a downstream inventory ping (used in testing/debug). + PingInventory(ctx context.Context, in *InventoryPingRequest, opts ...grpc.CallOption) (*InventoryPingResponse, error) // MaintainSessionPresence establishes a channel used to continously verify the presence for a // session. MaintainSessionPresence(ctx context.Context, opts ...grpc.CallOption) (AuthService_MaintainSessionPresenceClient, error) @@ -12008,6 +12918,8 @@ type AuthServiceClient interface { // GetCurrentUser returns current user as seen by the server. // Useful especially in the context of remote clusters which perform role and trait mapping. GetCurrentUser(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*types.UserV2, error) + // GetCurrentUserRoles returns current user's roles. + GetCurrentUserRoles(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (AuthService_GetCurrentUserRolesClient, error) // GetUsers gets all current user resources. GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (AuthService_GetUsersClient, error) // CreateUser inserts a new user entry to a backend. @@ -12388,6 +13300,10 @@ type AuthServiceClient interface { // without signing keys. If the cluster has multiple TLS certs, they will // all be appended. GetClusterCACert(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GetClusterCACertResponse, error) + // UnstableAssertSystemRole is not a stable part of the public API. Used by older + // instances to prove that they hold a given system role. + // DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) + UnstableAssertSystemRole(ctx context.Context, in *UnstableSystemRoleAssertion, opts ...grpc.CallOption) (*empty.Empty, error) } type authServiceClient struct { @@ -12398,8 +13314,57 @@ func NewAuthServiceClient(cc *grpc.ClientConn) AuthServiceClient { return &authServiceClient{cc} } +func (c *authServiceClient) InventoryControlStream(ctx context.Context, opts ...grpc.CallOption) (AuthService_InventoryControlStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[0], "/proto.AuthService/InventoryControlStream", opts...) + if err != nil { + return nil, err + } + x := &authServiceInventoryControlStreamClient{stream} + return x, nil +} + +type AuthService_InventoryControlStreamClient interface { + Send(*UpstreamInventoryOneOf) error + Recv() (*DownstreamInventoryOneOf, error) + grpc.ClientStream +} + +type authServiceInventoryControlStreamClient struct { + grpc.ClientStream +} + +func (x *authServiceInventoryControlStreamClient) Send(m *UpstreamInventoryOneOf) error { + return x.ClientStream.SendMsg(m) +} + +func (x *authServiceInventoryControlStreamClient) Recv() (*DownstreamInventoryOneOf, error) { + m := new(DownstreamInventoryOneOf) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *authServiceClient) GetInventoryStatus(ctx context.Context, in *InventoryStatusRequest, opts ...grpc.CallOption) (*InventoryStatusSummary, error) { + out := new(InventoryStatusSummary) + err := c.cc.Invoke(ctx, "/proto.AuthService/GetInventoryStatus", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) PingInventory(ctx context.Context, in *InventoryPingRequest, opts ...grpc.CallOption) (*InventoryPingResponse, error) { + out := new(InventoryPingResponse) + err := c.cc.Invoke(ctx, "/proto.AuthService/PingInventory", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *authServiceClient) MaintainSessionPresence(ctx context.Context, opts ...grpc.CallOption) (AuthService_MaintainSessionPresenceClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[0], "/proto.AuthService/MaintainSessionPresence", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[1], "/proto.AuthService/MaintainSessionPresence", opts...) if err != nil { return nil, err } @@ -12448,7 +13413,7 @@ func (c *authServiceClient) GetSessionTracker(ctx context.Context, in *GetSessio } func (c *authServiceClient) GetActiveSessionTrackers(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (AuthService_GetActiveSessionTrackersClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[1], "/proto.AuthService/GetActiveSessionTrackers", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[2], "/proto.AuthService/GetActiveSessionTrackers", opts...) if err != nil { return nil, err } @@ -12498,7 +13463,7 @@ func (c *authServiceClient) UpdateSessionTracker(ctx context.Context, in *Update } func (c *authServiceClient) SendKeepAlives(ctx context.Context, opts ...grpc.CallOption) (AuthService_SendKeepAlivesClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[2], "/proto.AuthService/SendKeepAlives", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[3], "/proto.AuthService/SendKeepAlives", opts...) if err != nil { return nil, err } @@ -12532,7 +13497,7 @@ func (x *authServiceSendKeepAlivesClient) CloseAndRecv() (*empty.Empty, error) { } func (c *authServiceClient) WatchEvents(ctx context.Context, in *Watch, opts ...grpc.CallOption) (AuthService_WatchEventsClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[3], "/proto.AuthService/WatchEvents", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[4], "/proto.AuthService/WatchEvents", opts...) if err != nil { return nil, err } @@ -12618,7 +13583,7 @@ func (c *authServiceClient) GenerateHostCerts(ctx context.Context, in *HostCerts } func (c *authServiceClient) GenerateUserSingleUseCerts(ctx context.Context, opts ...grpc.CallOption) (AuthService_GenerateUserSingleUseCertsClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[4], "/proto.AuthService/GenerateUserSingleUseCerts", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[5], "/proto.AuthService/GenerateUserSingleUseCerts", opts...) if err != nil { return nil, err } @@ -12667,7 +13632,7 @@ func (c *authServiceClient) GetAccessRequests(ctx context.Context, in *types.Acc } func (c *authServiceClient) GetAccessRequestsV2(ctx context.Context, in *types.AccessRequestFilter, opts ...grpc.CallOption) (AuthService_GetAccessRequestsV2Client, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[5], "/proto.AuthService/GetAccessRequestsV2", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[6], "/proto.AuthService/GetAccessRequestsV2", opts...) if err != nil { return nil, err } @@ -12816,7 +13781,7 @@ func (c *authServiceClient) DeleteBot(ctx context.Context, in *DeleteBotRequest, } func (c *authServiceClient) GetBotUsers(ctx context.Context, in *GetBotUsersRequest, opts ...grpc.CallOption) (AuthService_GetBotUsersClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[6], "/proto.AuthService/GetBotUsers", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[7], "/proto.AuthService/GetBotUsers", opts...) if err != nil { return nil, err } @@ -12865,8 +13830,40 @@ func (c *authServiceClient) GetCurrentUser(ctx context.Context, in *empty.Empty, return out, nil } +func (c *authServiceClient) GetCurrentUserRoles(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (AuthService_GetCurrentUserRolesClient, error) { + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[8], "/proto.AuthService/GetCurrentUserRoles", opts...) + if err != nil { + return nil, err + } + x := &authServiceGetCurrentUserRolesClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type AuthService_GetCurrentUserRolesClient interface { + Recv() (*types.RoleV5, error) + grpc.ClientStream +} + +type authServiceGetCurrentUserRolesClient struct { + grpc.ClientStream +} + +func (x *authServiceGetCurrentUserRolesClient) Recv() (*types.RoleV5, error) { + m := new(types.RoleV5) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *authServiceClient) GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (AuthService_GetUsersClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[7], "/proto.AuthService/GetUsers", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[9], "/proto.AuthService/GetUsers", opts...) if err != nil { return nil, err } @@ -12979,7 +13976,7 @@ func (c *authServiceClient) EmitAuditEvent(ctx context.Context, in *events.OneOf } func (c *authServiceClient) CreateAuditStream(ctx context.Context, opts ...grpc.CallOption) (AuthService_CreateAuditStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[8], "/proto.AuthService/CreateAuditStream", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[10], "/proto.AuthService/CreateAuditStream", opts...) if err != nil { return nil, err } @@ -13423,7 +14420,7 @@ func (c *authServiceClient) DeleteRole(ctx context.Context, in *DeleteRoleReques } func (c *authServiceClient) AddMFADevice(ctx context.Context, opts ...grpc.CallOption) (AuthService_AddMFADeviceClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[9], "/proto.AuthService/AddMFADevice", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[11], "/proto.AuthService/AddMFADevice", opts...) if err != nil { return nil, err } @@ -13454,7 +14451,7 @@ func (x *authServiceAddMFADeviceClient) Recv() (*AddMFADeviceResponse, error) { } func (c *authServiceClient) DeleteMFADevice(ctx context.Context, opts ...grpc.CallOption) (AuthService_DeleteMFADeviceClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[10], "/proto.AuthService/DeleteMFADevice", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[12], "/proto.AuthService/DeleteMFADevice", opts...) if err != nil { return nil, err } @@ -13935,7 +14932,7 @@ func (c *authServiceClient) ReplaceRemoteLocks(ctx context.Context, in *ReplaceR } func (c *authServiceClient) StreamSessionEvents(ctx context.Context, in *StreamSessionEventsRequest, opts ...grpc.CallOption) (AuthService_StreamSessionEventsClient, error) { - stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[11], "/proto.AuthService/StreamSessionEvents", opts...) + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[13], "/proto.AuthService/StreamSessionEvents", opts...) if err != nil { return nil, err } @@ -14317,8 +15314,24 @@ func (c *authServiceClient) GetClusterCACert(ctx context.Context, in *empty.Empt return out, nil } +func (c *authServiceClient) UnstableAssertSystemRole(ctx context.Context, in *UnstableSystemRoleAssertion, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) + err := c.cc.Invoke(ctx, "/proto.AuthService/UnstableAssertSystemRole", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // AuthServiceServer is the server API for AuthService service. type AuthServiceServer interface { + // InventoryControlStream is the per-instance stream used to advertise teleport instance + // presence/version/etc to the auth server. + InventoryControlStream(AuthService_InventoryControlStreamServer) error + // GetInventoryStatus gets information about current instance inventory. + GetInventoryStatus(context.Context, *InventoryStatusRequest) (*InventoryStatusSummary, error) + // PingInventory attempts to trigger a downstream inventory ping (used in testing/debug). + PingInventory(context.Context, *InventoryPingRequest) (*InventoryPingResponse, error) // MaintainSessionPresence establishes a channel used to continously verify the presence for a // session. MaintainSessionPresence(AuthService_MaintainSessionPresenceServer) error @@ -14396,6 +15409,8 @@ type AuthServiceServer interface { // GetCurrentUser returns current user as seen by the server. // Useful especially in the context of remote clusters which perform role and trait mapping. GetCurrentUser(context.Context, *empty.Empty) (*types.UserV2, error) + // GetCurrentUserRoles returns current user's roles. + GetCurrentUserRoles(*empty.Empty, AuthService_GetCurrentUserRolesServer) error // GetUsers gets all current user resources. GetUsers(*GetUsersRequest, AuthService_GetUsersServer) error // CreateUser inserts a new user entry to a backend. @@ -14776,12 +15791,25 @@ type AuthServiceServer interface { // without signing keys. If the cluster has multiple TLS certs, they will // all be appended. GetClusterCACert(context.Context, *empty.Empty) (*GetClusterCACertResponse, error) + // UnstableAssertSystemRole is not a stable part of the public API. Used by older + // instances to prove that they hold a given system role. + // DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) + UnstableAssertSystemRole(context.Context, *UnstableSystemRoleAssertion) (*empty.Empty, error) } // UnimplementedAuthServiceServer can be embedded to have forward compatible implementations. type UnimplementedAuthServiceServer struct { } +func (*UnimplementedAuthServiceServer) InventoryControlStream(srv AuthService_InventoryControlStreamServer) error { + return status.Errorf(codes.Unimplemented, "method InventoryControlStream not implemented") +} +func (*UnimplementedAuthServiceServer) GetInventoryStatus(ctx context.Context, req *InventoryStatusRequest) (*InventoryStatusSummary, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInventoryStatus not implemented") +} +func (*UnimplementedAuthServiceServer) PingInventory(ctx context.Context, req *InventoryPingRequest) (*InventoryPingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PingInventory not implemented") +} func (*UnimplementedAuthServiceServer) MaintainSessionPresence(srv AuthService_MaintainSessionPresenceServer) error { return status.Errorf(codes.Unimplemented, "method MaintainSessionPresence not implemented") } @@ -14884,6 +15912,9 @@ func (*UnimplementedAuthServiceServer) GetUser(ctx context.Context, req *GetUser func (*UnimplementedAuthServiceServer) GetCurrentUser(ctx context.Context, req *empty.Empty) (*types.UserV2, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCurrentUser not implemented") } +func (*UnimplementedAuthServiceServer) GetCurrentUserRoles(req *empty.Empty, srv AuthService_GetCurrentUserRolesServer) error { + return status.Errorf(codes.Unimplemented, "method GetCurrentUserRoles not implemented") +} func (*UnimplementedAuthServiceServer) GetUsers(req *GetUsersRequest, srv AuthService_GetUsersServer) error { return status.Errorf(codes.Unimplemented, "method GetUsers not implemented") } @@ -15328,11 +16359,76 @@ func (*UnimplementedAuthServiceServer) GetDomainName(ctx context.Context, req *e func (*UnimplementedAuthServiceServer) GetClusterCACert(ctx context.Context, req *empty.Empty) (*GetClusterCACertResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetClusterCACert not implemented") } +func (*UnimplementedAuthServiceServer) UnstableAssertSystemRole(ctx context.Context, req *UnstableSystemRoleAssertion) (*empty.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnstableAssertSystemRole not implemented") +} func RegisterAuthServiceServer(s *grpc.Server, srv AuthServiceServer) { s.RegisterService(&_AuthService_serviceDesc, srv) } +func _AuthService_InventoryControlStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(AuthServiceServer).InventoryControlStream(&authServiceInventoryControlStreamServer{stream}) +} + +type AuthService_InventoryControlStreamServer interface { + Send(*DownstreamInventoryOneOf) error + Recv() (*UpstreamInventoryOneOf, error) + grpc.ServerStream +} + +type authServiceInventoryControlStreamServer struct { + grpc.ServerStream +} + +func (x *authServiceInventoryControlStreamServer) Send(m *DownstreamInventoryOneOf) error { + return x.ServerStream.SendMsg(m) +} + +func (x *authServiceInventoryControlStreamServer) Recv() (*UpstreamInventoryOneOf, error) { + m := new(UpstreamInventoryOneOf) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _AuthService_GetInventoryStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InventoryStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).GetInventoryStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/GetInventoryStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).GetInventoryStatus(ctx, req.(*InventoryStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_PingInventory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InventoryPingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).PingInventory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/PingInventory", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).PingInventory(ctx, req.(*InventoryPingRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AuthService_MaintainSessionPresence_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(AuthServiceServer).MaintainSessionPresence(&authServiceMaintainSessionPresenceServer{stream}) } @@ -15981,6 +17077,27 @@ func _AuthService_GetCurrentUser_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _AuthService_GetCurrentUserRoles_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(empty.Empty) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AuthServiceServer).GetCurrentUserRoles(m, &authServiceGetCurrentUserRolesServer{stream}) +} + +type AuthService_GetCurrentUserRolesServer interface { + Send(*types.RoleV5) error + grpc.ServerStream +} + +type authServiceGetCurrentUserRolesServer struct { + grpc.ServerStream +} + +func (x *authServiceGetCurrentUserRolesServer) Send(m *types.RoleV5) error { + return x.ServerStream.SendMsg(m) +} + func _AuthService_GetUsers_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(GetUsersRequest) if err := stream.RecvMsg(m); err != nil { @@ -18675,10 +19792,36 @@ func _AuthService_GetClusterCACert_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _AuthService_UnstableAssertSystemRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnstableSystemRoleAssertion) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).UnstableAssertSystemRole(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/UnstableAssertSystemRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).UnstableAssertSystemRole(ctx, req.(*UnstableSystemRoleAssertion)) + } + return interceptor(ctx, in, info, handler) +} + var _AuthService_serviceDesc = grpc.ServiceDesc{ ServiceName: "proto.AuthService", HandlerType: (*AuthServiceServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "GetInventoryStatus", + Handler: _AuthService_GetInventoryStatus_Handler, + }, + { + MethodName: "PingInventory", + Handler: _AuthService_PingInventory_Handler, + }, { MethodName: "CreateSessionTracker", Handler: _AuthService_CreateSessionTracker_Handler, @@ -19359,8 +20502,18 @@ var _AuthService_serviceDesc = grpc.ServiceDesc{ MethodName: "GetClusterCACert", Handler: _AuthService_GetClusterCACert_Handler, }, + { + MethodName: "UnstableAssertSystemRole", + Handler: _AuthService_UnstableAssertSystemRole_Handler, + }, }, Streams: []grpc.StreamDesc{ + { + StreamName: "InventoryControlStream", + Handler: _AuthService_InventoryControlStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, { StreamName: "MaintainSessionPresence", Handler: _AuthService_MaintainSessionPresence_Handler, @@ -19398,6 +20551,11 @@ var _AuthService_serviceDesc = grpc.ServiceDesc{ Handler: _AuthService_GetBotUsers_Handler, ServerStreams: true, }, + { + StreamName: "GetCurrentUserRoles", + Handler: _AuthService_GetCurrentUserRoles_Handler, + ServerStreams: true, + }, { StreamName: "GetUsers", Handler: _AuthService_GetUsers_Handler, @@ -20254,6 +21412,22 @@ func (m *HostCertsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.UnstableSystemRoleAssertionID) > 0 { + i -= len(m.UnstableSystemRoleAssertionID) + copy(dAtA[i:], m.UnstableSystemRoleAssertionID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.UnstableSystemRoleAssertionID))) + i-- + dAtA[i] = 0x62 + } + if len(m.SystemRoles) > 0 { + for iNdEx := len(m.SystemRoles) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SystemRoles[iNdEx]) + copy(dAtA[i:], m.SystemRoles[iNdEx]) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.SystemRoles[iNdEx]))) + i-- + dAtA[i] = 0x5a + } + } if m.NoCache { i-- if m.NoCache { @@ -20363,6 +21537,16 @@ func (m *UserCertsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.UseRoleRequests { + i-- + if m.UseRoleRequests { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x70 + } { size, err := m.RouteToWindowsDesktop.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -21348,6 +22532,26 @@ func (m *Features) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.ResourceAccessRequests { + i-- + if m.ResourceAccessRequests { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x68 + } + if m.MachineID { + i-- + if m.MachineID { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x60 + } if m.ModeratedSessions { i-- if m.ModeratedSessions { @@ -28155,150 +29359,763 @@ func (m *GetSSODiagnosticInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } -func encodeVarintAuthservice(dAtA []byte, offset int, v uint64) int { - offset -= sovAuthservice(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *UnstableSystemRoleAssertion) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Event) Size() (n int) { - if m == nil { - return 0 - } + +func (m *UnstableSystemRoleAssertion) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UnstableSystemRoleAssertion) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Type != 0 { - n += 1 + sovAuthservice(uint64(m.Type)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - if m.Resource != nil { - n += m.Resource.Size() + if len(m.SystemRole) > 0 { + i -= len(m.SystemRole) + copy(dAtA[i:], m.SystemRole) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.SystemRole))) + i-- + dAtA[i] = 0x1a } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if len(m.AssertionID) > 0 { + i -= len(m.AssertionID) + copy(dAtA[i:], m.AssertionID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.AssertionID))) + i-- + dAtA[i] = 0x12 } - return n + if len(m.ServerID) > 0 { + i -= len(m.ServerID) + copy(dAtA[i:], m.ServerID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ServerID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *Event_ResourceHeader) Size() (n int) { - if m == nil { - return 0 +func (m *UnstableSystemRoleAssertionSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *UnstableSystemRoleAssertionSet) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UnstableSystemRoleAssertionSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.ResourceHeader != nil { - l = m.ResourceHeader.Size() - n += 1 + l + sovAuthservice(uint64(l)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n -} -func (m *Event_CertAuthority) Size() (n int) { - if m == nil { - return 0 + if len(m.SystemRoles) > 0 { + for iNdEx := len(m.SystemRoles) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SystemRoles[iNdEx]) + copy(dAtA[i:], m.SystemRoles[iNdEx]) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.SystemRoles[iNdEx]))) + i-- + dAtA[i] = 0x1a + } } - var l int - _ = l - if m.CertAuthority != nil { - l = m.CertAuthority.Size() - n += 1 + l + sovAuthservice(uint64(l)) + if len(m.AssertionID) > 0 { + i -= len(m.AssertionID) + copy(dAtA[i:], m.AssertionID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.AssertionID))) + i-- + dAtA[i] = 0x12 } - return n + if len(m.ServerID) > 0 { + i -= len(m.ServerID) + copy(dAtA[i:], m.ServerID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ServerID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *Event_StaticTokens) Size() (n int) { - if m == nil { - return 0 + +func (m *UpstreamInventoryOneOf) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *UpstreamInventoryOneOf) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpstreamInventoryOneOf) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.StaticTokens != nil { - l = m.StaticTokens.Size() - n += 1 + l + sovAuthservice(uint64(l)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n -} -func (m *Event_ProvisionToken) Size() (n int) { - if m == nil { - return 0 + if m.Msg != nil { + { + size := m.Msg.Size() + i -= size + if _, err := m.Msg.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } } - var l int - _ = l - if m.ProvisionToken != nil { - l = m.ProvisionToken.Size() - n += 1 + l + sovAuthservice(uint64(l)) + return len(dAtA) - i, nil +} + +func (m *UpstreamInventoryOneOf_Hello) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpstreamInventoryOneOf_Hello) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Hello != nil { + { + size, err := m.Hello.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *Event_ClusterName) Size() (n int) { - if m == nil { - return 0 +func (m *UpstreamInventoryOneOf_Heartbeat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpstreamInventoryOneOf_Heartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Heartbeat != nil { + { + size, err := m.Heartbeat.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - var l int - _ = l - if m.ClusterName != nil { - l = m.ClusterName.Size() - n += 1 + l + sovAuthservice(uint64(l)) + return len(dAtA) - i, nil +} +func (m *UpstreamInventoryOneOf_Pong) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpstreamInventoryOneOf_Pong) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Pong != nil { + { + size, err := m.Pong.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a } - return n + return len(dAtA) - i, nil } -func (m *Event_User) Size() (n int) { - if m == nil { - return 0 +func (m *DownstreamInventoryOneOf) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *DownstreamInventoryOneOf) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DownstreamInventoryOneOf) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.User != nil { - l = m.User.Size() - n += 1 + l + sovAuthservice(uint64(l)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n + if m.Msg != nil { + { + size := m.Msg.Size() + i -= size + if _, err := m.Msg.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil } -func (m *Event_Role) Size() (n int) { - if m == nil { - return 0 + +func (m *DownstreamInventoryOneOf_Hello) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DownstreamInventoryOneOf_Hello) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Hello != nil { + { + size, err := m.Hello.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - var l int - _ = l - if m.Role != nil { - l = m.Role.Size() - n += 1 + l + sovAuthservice(uint64(l)) + return len(dAtA) - i, nil +} +func (m *DownstreamInventoryOneOf_Ping) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DownstreamInventoryOneOf_Ping) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Ping != nil { + { + size, err := m.Ping.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - return n + return len(dAtA) - i, nil } -func (m *Event_Namespace) Size() (n int) { - if m == nil { - return 0 +func (m *DownstreamInventoryPing) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *DownstreamInventoryPing) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DownstreamInventoryPing) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Namespace != nil { - l = m.Namespace.Size() - n += 1 + l + sovAuthservice(uint64(l)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n + if m.ID != 0 { + i = encodeVarintAuthservice(dAtA, i, uint64(m.ID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil } -func (m *Event_Server) Size() (n int) { - if m == nil { - return 0 + +func (m *UpstreamInventoryPong) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *UpstreamInventoryPong) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpstreamInventoryPong) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Server != nil { - l = m.Server.Size() - n += 1 + l + sovAuthservice(uint64(l)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n + if m.ID != 0 { + i = encodeVarintAuthservice(dAtA, i, uint64(m.ID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil } -func (m *Event_ReverseTunnel) Size() (n int) { - if m == nil { - return 0 + +func (m *UpstreamInventoryHello) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *UpstreamInventoryHello) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpstreamInventoryHello) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.ReverseTunnel != nil { + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Services) > 0 { + for iNdEx := len(m.Services) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Services[iNdEx]) + copy(dAtA[i:], m.Services[iNdEx]) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Services[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.ServerID) > 0 { + i -= len(m.ServerID) + copy(dAtA[i:], m.ServerID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ServerID))) + i-- + dAtA[i] = 0x12 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DownstreamInventoryHello) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DownstreamInventoryHello) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DownstreamInventoryHello) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ServerID) > 0 { + i -= len(m.ServerID) + copy(dAtA[i:], m.ServerID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ServerID))) + i-- + dAtA[i] = 0x12 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *InventoryHeartbeat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InventoryHeartbeat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InventoryHeartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.SSHServer != nil { + { + size, err := m.SSHServer.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *InventoryStatusRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InventoryStatusRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InventoryStatusRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Connected { + i-- + if m.Connected { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *InventoryStatusSummary) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InventoryStatusSummary) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InventoryStatusSummary) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Connected) > 0 { + for iNdEx := len(m.Connected) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Connected[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *InventoryPingRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InventoryPingRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InventoryPingRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ServerID) > 0 { + i -= len(m.ServerID) + copy(dAtA[i:], m.ServerID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ServerID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *InventoryPingResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InventoryPingResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InventoryPingResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Duration != 0 { + i = encodeVarintAuthservice(dAtA, i, uint64(m.Duration)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintAuthservice(dAtA []byte, offset int, v uint64) int { + offset -= sovAuthservice(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Event) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != 0 { + n += 1 + sovAuthservice(uint64(m.Type)) + } + if m.Resource != nil { + n += m.Resource.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Event_ResourceHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ResourceHeader != nil { + l = m.ResourceHeader.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_CertAuthority) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CertAuthority != nil { + l = m.CertAuthority.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_StaticTokens) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StaticTokens != nil { + l = m.StaticTokens.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_ProvisionToken) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ProvisionToken != nil { + l = m.ProvisionToken.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_ClusterName) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ClusterName != nil { + l = m.ClusterName.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_User) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.User != nil { + l = m.User.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_Role) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Role != nil { + l = m.Role.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_Namespace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Namespace != nil { + l = m.Namespace.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_Server) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Server != nil { + l = m.Server.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *Event_ReverseTunnel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ReverseTunnel != nil { l = m.ReverseTunnel.Size() n += 1 + l + sovAuthservice(uint64(l)) } @@ -28634,6 +30451,16 @@ func (m *HostCertsRequest) Size() (n int) { if m.NoCache { n += 2 } + if len(m.SystemRoles) > 0 { + for _, s := range m.SystemRoles { + l = len(s) + n += 1 + l + sovAuthservice(uint64(l)) + } + } + l = len(m.UnstableSystemRoleAssertionID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -28693,6 +30520,9 @@ func (m *UserCertsRequest) Size() (n int) { } l = m.RouteToWindowsDesktop.Size() n += 1 + l + sovAuthservice(uint64(l)) + if m.UseRoleRequests { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -29145,6 +30975,12 @@ func (m *Features) Size() (n int) { if m.ModeratedSessions { n += 2 } + if m.MachineID { + n += 2 + } + if m.ResourceAccessRequests { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -32335,6 +34171,302 @@ func (m *GetSSODiagnosticInfoRequest) Size() (n int) { return n } +func (m *UnstableSystemRoleAssertion) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ServerID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.AssertionID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.SystemRole) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UnstableSystemRoleAssertionSet) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ServerID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.AssertionID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if len(m.SystemRoles) > 0 { + for _, s := range m.SystemRoles { + l = len(s) + n += 1 + l + sovAuthservice(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UpstreamInventoryOneOf) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Msg != nil { + n += m.Msg.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UpstreamInventoryOneOf_Hello) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Hello != nil { + l = m.Hello.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *UpstreamInventoryOneOf_Heartbeat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Heartbeat != nil { + l = m.Heartbeat.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *UpstreamInventoryOneOf_Pong) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pong != nil { + l = m.Pong.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *DownstreamInventoryOneOf) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Msg != nil { + n += m.Msg.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DownstreamInventoryOneOf_Hello) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Hello != nil { + l = m.Hello.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *DownstreamInventoryOneOf_Ping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Ping != nil { + l = m.Ping.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *DownstreamInventoryPing) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ID != 0 { + n += 1 + sovAuthservice(uint64(m.ID)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UpstreamInventoryPong) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ID != 0 { + n += 1 + sovAuthservice(uint64(m.ID)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UpstreamInventoryHello) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.ServerID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if len(m.Services) > 0 { + for _, s := range m.Services { + l = len(s) + n += 1 + l + sovAuthservice(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DownstreamInventoryHello) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.ServerID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *InventoryHeartbeat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SSHServer != nil { + l = m.SSHServer.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *InventoryStatusRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Connected { + n += 2 + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *InventoryStatusSummary) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Connected) > 0 { + for _, e := range m.Connected { + l = e.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *InventoryPingRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ServerID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *InventoryPingResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Duration != 0 { + n += 1 + sovAuthservice(uint64(m.Duration)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovAuthservice(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -34150,6 +36282,70 @@ func (m *HostCertsRequest) Unmarshal(dAtA []byte) error { } } m.NoCache = bool(v != 0) + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SystemRoles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SystemRoles = append(m.SystemRoles, github_com_gravitational_teleport_api_types.SystemRole(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnstableSystemRoleAssertionID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UnstableSystemRoleAssertionID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -34610,6 +36806,26 @@ func (m *UserCertsRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UseRoleRequests", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.UseRoleRequests = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -37213,62 +39429,11 @@ func (m *Features) Unmarshal(dAtA []byte) error { } } m.ModeratedSessions = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipAuthservice(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthservice - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeleteUserRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeleteUserRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeleteUserRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MachineID", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -37278,80 +39443,17 @@ func (m *DeleteUserRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAuthservice(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthservice - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Semaphores) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Semaphores: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Semaphores: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Semaphores", wireType) + m.MachineID = bool(v != 0) + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceAccessRequests", wireType) } - var msglen int + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -37361,26 +39463,12 @@ func (m *Semaphores) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Semaphores = append(m.Semaphores, &types.SemaphoreV3{}) - if err := m.Semaphores[len(m.Semaphores)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex + m.ResourceAccessRequests = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -37403,7 +39491,7 @@ func (m *Semaphores) Unmarshal(dAtA []byte) error { } return nil } -func (m *AuditStreamRequest) Unmarshal(dAtA []byte) error { +func (m *DeleteUserRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -37426,157 +39514,17 @@ func (m *AuditStreamRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuditStreamRequest: wiretype end group for non-group") + return fmt.Errorf("proto: DeleteUserRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuditStreamRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeleteUserRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CreateStream", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &CreateStream{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Request = &AuditStreamRequest_CreateStream{v} - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResumeStream", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ResumeStream{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Request = &AuditStreamRequest_ResumeStream{v} - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CompleteStream", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &CompleteStream{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Request = &AuditStreamRequest_CompleteStream{v} - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FlushAndCloseStream", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &FlushAndCloseStream{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Request = &AuditStreamRequest_FlushAndCloseStream{v} - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -37586,26 +39534,334 @@ func (m *AuditStreamRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - v := &events.OneOf{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Request = &AuditStreamRequest_Event{v} + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Semaphores) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Semaphores: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Semaphores: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Semaphores", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Semaphores = append(m.Semaphores, &types.SemaphoreV3{}) + if err := m.Semaphores[len(m.Semaphores)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuditStreamRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuditStreamRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuditStreamRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreateStream", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &CreateStream{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &AuditStreamRequest_CreateStream{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResumeStream", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ResumeStream{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &AuditStreamRequest_ResumeStream{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CompleteStream", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &CompleteStream{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &AuditStreamRequest_CompleteStream{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FlushAndCloseStream", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &FlushAndCloseStream{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &AuditStreamRequest_FlushAndCloseStream{v} + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &events.OneOf{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &AuditStreamRequest_Event{v} iNdEx = postIndex default: iNdEx = preIndex @@ -51584,48 +53840,1431 @@ func (m *UpdateSessionTrackerRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SessionID = string(dAtA[iNdEx:postIndex]) + m.SessionID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdateState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SessionTrackerUpdateState{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Update = &UpdateSessionTrackerRequest_UpdateState{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AddParticipant", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SessionTrackerAddParticipant{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Update = &UpdateSessionTrackerRequest_AddParticipant{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RemoveParticipant", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SessionTrackerRemoveParticipant{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Update = &UpdateSessionTrackerRequest_RemoveParticipant{v} + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdateExpiry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SessionTrackerUpdateExpiry{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Update = &UpdateSessionTrackerRequest_UpdateExpiry{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PresenceMFAChallengeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PresenceMFAChallengeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PresenceMFAChallengeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SessionID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SessionID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PresenceMFAChallengeSend) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PresenceMFAChallengeSend: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PresenceMFAChallengeSend: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChallengeRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &PresenceMFAChallengeRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &PresenceMFAChallengeSend_ChallengeRequest{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChallengeResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &MFAAuthenticateResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &PresenceMFAChallengeSend_ChallengeResponse{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetDomainNameResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetDomainNameResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetDomainNameResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DomainName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DomainName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetClusterCACertResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetClusterCACertResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetClusterCACertResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TLSCA", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TLSCA = append(m.TLSCA[:0], dAtA[iNdEx:postIndex]...) + if m.TLSCA == nil { + m.TLSCA = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenerateTokenRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenerateTokenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, github_com_gravitational_teleport_api_types.SystemRole(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) + } + m.TTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TTL |= Duration(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Labels == nil { + m.Labels = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthAuthservice + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthAuthservice + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthAuthservice + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthAuthservice + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Labels[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenerateTokenResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenerateTokenResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenerateTokenResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetOIDCAuthRequestRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetOIDCAuthRequestRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetOIDCAuthRequestRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StateToken", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StateToken = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetSAMLAuthRequestRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetSAMLAuthRequestRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetSAMLAuthRequestRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetGithubAuthRequestRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetGithubAuthRequestRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetGithubAuthRequestRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StateToken", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StateToken = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetSSODiagnosticInfoRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetSSODiagnosticInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetSSODiagnosticInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRequestKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AuthRequestKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRequestID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AuthRequestID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UnstableSystemRoleAssertion) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UnstableSystemRoleAssertion: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UnstableSystemRoleAssertion: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServerID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ServerID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssertionID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssertionID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SystemRole", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SystemRole = github_com_gravitational_teleport_api_types.SystemRole(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdateState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err } - if msglen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthservice + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UnstableSystemRoleAssertionSet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - v := &SessionTrackerUpdateState{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - m.Update = &UpdateSessionTrackerRequest_UpdateState{v} - iNdEx = postIndex - case 3: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UnstableSystemRoleAssertionSet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UnstableSystemRoleAssertionSet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AddParticipant", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServerID", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -51635,32 +55274,29 @@ func (m *UpdateSessionTrackerRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - v := &SessionTrackerAddParticipant{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Update = &UpdateSessionTrackerRequest_AddParticipant{v} + m.ServerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RemoveParticipant", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AssertionID", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -51670,32 +55306,29 @@ func (m *UpdateSessionTrackerRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - v := &SessionTrackerRemoveParticipant{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Update = &UpdateSessionTrackerRequest_RemoveParticipant{v} + m.AssertionID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdateExpiry", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SystemRoles", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -51705,26 +55338,23 @@ func (m *UpdateSessionTrackerRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - v := &SessionTrackerUpdateExpiry{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Update = &UpdateSessionTrackerRequest_UpdateExpiry{v} + m.SystemRoles = append(m.SystemRoles, github_com_gravitational_teleport_api_types.SystemRole(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -51748,7 +55378,7 @@ func (m *UpdateSessionTrackerRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *PresenceMFAChallengeRequest) Unmarshal(dAtA []byte) error { +func (m *UpstreamInventoryOneOf) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -51771,17 +55401,17 @@ func (m *PresenceMFAChallengeRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PresenceMFAChallengeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: UpstreamInventoryOneOf: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PresenceMFAChallengeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UpstreamInventoryOneOf: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hello", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -51791,23 +55421,96 @@ func (m *PresenceMFAChallengeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - m.SessionID = string(dAtA[iNdEx:postIndex]) + v := &UpstreamInventoryHello{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Msg = &UpstreamInventoryOneOf_Hello{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Heartbeat", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &InventoryHeartbeat{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Msg = &UpstreamInventoryOneOf_Heartbeat{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pong", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &UpstreamInventoryPong{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Msg = &UpstreamInventoryOneOf_Pong{v} iNdEx = postIndex default: iNdEx = preIndex @@ -51831,7 +55534,7 @@ func (m *PresenceMFAChallengeRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *PresenceMFAChallengeSend) Unmarshal(dAtA []byte) error { +func (m *DownstreamInventoryOneOf) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -51854,15 +55557,15 @@ func (m *PresenceMFAChallengeSend) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PresenceMFAChallengeSend: wiretype end group for non-group") + return fmt.Errorf("proto: DownstreamInventoryOneOf: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PresenceMFAChallengeSend: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DownstreamInventoryOneOf: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChallengeRequest", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hello", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -51889,15 +55592,15 @@ func (m *PresenceMFAChallengeSend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &PresenceMFAChallengeRequest{} + v := &DownstreamInventoryHello{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Request = &PresenceMFAChallengeSend_ChallengeRequest{v} + m.Msg = &DownstreamInventoryOneOf_Hello{v} iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChallengeResponse", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -51924,11 +55627,11 @@ func (m *PresenceMFAChallengeSend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &MFAAuthenticateResponse{} + v := &DownstreamInventoryPing{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Request = &PresenceMFAChallengeSend_ChallengeResponse{v} + m.Msg = &DownstreamInventoryOneOf_Ping{v} iNdEx = postIndex default: iNdEx = preIndex @@ -51952,7 +55655,7 @@ func (m *PresenceMFAChallengeSend) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetDomainNameResponse) Unmarshal(dAtA []byte) error { +func (m *DownstreamInventoryPing) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -51975,17 +55678,17 @@ func (m *GetDomainNameResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetDomainNameResponse: wiretype end group for non-group") + return fmt.Errorf("proto: DownstreamInventoryPing: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetDomainNameResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DownstreamInventoryPing: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DomainName", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) } - var stringLen uint64 + m.ID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -51995,24 +55698,11 @@ func (m *GetDomainNameResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ID |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.DomainName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -52035,7 +55725,7 @@ func (m *GetDomainNameResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetClusterCACertResponse) Unmarshal(dAtA []byte) error { +func (m *UpstreamInventoryPong) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52058,17 +55748,17 @@ func (m *GetClusterCACertResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetClusterCACertResponse: wiretype end group for non-group") + return fmt.Errorf("proto: UpstreamInventoryPong: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetClusterCACertResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UpstreamInventoryPong: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLSCA", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) } - var byteLen int + m.ID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -52078,26 +55768,11 @@ func (m *GetClusterCACertResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + m.ID |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TLSCA = append(m.TLSCA[:0], dAtA[iNdEx:postIndex]...) - if m.TLSCA == nil { - m.TLSCA = []byte{} - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -52120,7 +55795,7 @@ func (m *GetClusterCACertResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { +func (m *UpstreamInventoryHello) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52143,15 +55818,15 @@ func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GenerateTokenRequest: wiretype end group for non-group") + return fmt.Errorf("proto: UpstreamInventoryHello: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GenerateTokenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UpstreamInventoryHello: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -52179,11 +55854,11 @@ func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Token = string(dAtA[iNdEx:postIndex]) + m.Version = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServerID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -52211,32 +55886,13 @@ func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Roles = append(m.Roles, github_com_gravitational_teleport_api_types.SystemRole(dAtA[iNdEx:postIndex])) + m.ServerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) - } - m.TTL = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TTL |= Duration(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Services", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -52246,118 +55902,23 @@ func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Labels == nil { - m.Labels = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthAuthservice - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthAuthservice - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthservice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthAuthservice - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthAuthservice - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipAuthservice(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthservice - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Labels[mapkey] = mapvalue + m.Services = append(m.Services, github_com_gravitational_teleport_api_types.SystemRole(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -52381,7 +55942,7 @@ func (m *GenerateTokenRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *GenerateTokenResponse) Unmarshal(dAtA []byte) error { +func (m *DownstreamInventoryHello) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52404,15 +55965,15 @@ func (m *GenerateTokenResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GenerateTokenResponse: wiretype end group for non-group") + return fmt.Errorf("proto: DownstreamInventoryHello: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GenerateTokenResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DownstreamInventoryHello: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -52440,7 +56001,39 @@ func (m *GenerateTokenResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Token = string(dAtA[iNdEx:postIndex]) + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServerID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ServerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -52464,7 +56057,7 @@ func (m *GenerateTokenResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetOIDCAuthRequestRequest) Unmarshal(dAtA []byte) error { +func (m *InventoryHeartbeat) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52487,17 +56080,17 @@ func (m *GetOIDCAuthRequestRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetOIDCAuthRequestRequest: wiretype end group for non-group") + return fmt.Errorf("proto: InventoryHeartbeat: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetOIDCAuthRequestRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: InventoryHeartbeat: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StateToken", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SSHServer", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -52507,23 +56100,27 @@ func (m *GetOIDCAuthRequestRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - m.StateToken = string(dAtA[iNdEx:postIndex]) + if m.SSHServer == nil { + m.SSHServer = &types.ServerV2{} + } + if err := m.SSHServer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -52547,7 +56144,7 @@ func (m *GetOIDCAuthRequestRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetSAMLAuthRequestRequest) Unmarshal(dAtA []byte) error { +func (m *InventoryStatusRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52570,17 +56167,17 @@ func (m *GetSAMLAuthRequestRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetSAMLAuthRequestRequest: wiretype end group for non-group") + return fmt.Errorf("proto: InventoryStatusRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetSAMLAuthRequestRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: InventoryStatusRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Connected", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -52590,24 +56187,12 @@ func (m *GetSAMLAuthRequestRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex + m.Connected = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -52630,7 +56215,7 @@ func (m *GetSAMLAuthRequestRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetGithubAuthRequestRequest) Unmarshal(dAtA []byte) error { +func (m *InventoryStatusSummary) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52653,17 +56238,17 @@ func (m *GetGithubAuthRequestRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetGithubAuthRequestRequest: wiretype end group for non-group") + return fmt.Errorf("proto: InventoryStatusSummary: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetGithubAuthRequestRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: InventoryStatusSummary: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StateToken", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Connected", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -52673,23 +56258,25 @@ func (m *GetGithubAuthRequestRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - m.StateToken = string(dAtA[iNdEx:postIndex]) + m.Connected = append(m.Connected, UpstreamInventoryHello{}) + if err := m.Connected[len(m.Connected)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -52713,7 +56300,7 @@ func (m *GetGithubAuthRequestRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetSSODiagnosticInfoRequest) Unmarshal(dAtA []byte) error { +func (m *InventoryPingRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52736,15 +56323,15 @@ func (m *GetSSODiagnosticInfoRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetSSODiagnosticInfoRequest: wiretype end group for non-group") + return fmt.Errorf("proto: InventoryPingRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetSSODiagnosticInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: InventoryPingRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuthRequestKind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServerID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -52772,13 +56359,64 @@ func (m *GetSSODiagnosticInfoRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AuthRequestKind = string(dAtA[iNdEx:postIndex]) + m.ServerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuthRequestID", wireType) + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err } - var stringLen uint64 + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *InventoryPingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: InventoryPingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: InventoryPingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + } + m.Duration = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -52788,24 +56426,11 @@ func (m *GetSSODiagnosticInfoRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Duration |= time.Duration(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAuthservice - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthservice - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AuthRequestID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) diff --git a/api/client/proto/authservice.proto b/api/client/proto/authservice.proto index e26ab0f70d931..086ca1018b0bd 100644 --- a/api/client/proto/authservice.proto +++ b/api/client/proto/authservice.proto @@ -184,6 +184,20 @@ message HostCertsRequest { types.Rotation Rotation = 9 [ (gogoproto.jsontag) = "rotation,omitempty" ]; // NoCache is argument that only local callers can supply to bypass cache bool NoCache = 10 [ (gogoproto.jsontag) = "-" ]; + // SystemRoles is a list of system roles held by the host. Most host certs are + // single-role and only specify the Role field. The SystemRoles field is only + // currently used on Instance certs, which need to express all roles held by + // the instance. + repeated string SystemRoles = 11 [ + (gogoproto.jsontag) = "system_roles,omitempty", + (gogoproto.casttype) = "github.com/gravitational/teleport/api/types.SystemRole" + ]; + // UnstableSystemRoleAssertionID is not a stable part of the public API. Used by + // older instances to requisition a multi-role cert by individually proving which + // system roles are held. + // DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) + string UnstableSystemRoleAssertionID = 12 + [ (gogoproto.jsontag) = "system_role_assertion_id,omitempty" ]; } // UserCertRequest specifies certificate-generation parameters @@ -264,6 +278,10 @@ message UserCertsRequest { (gogoproto.nullable) = false, (gogoproto.jsontag) = "route_to_windows_desktop,omitempty" ]; + + // UseRoleRequests is used to ensure a certificate request is intended to + // use role impersonation, even if the list of role requests is empty. + bool UseRoleRequests = 14 [ (gogoproto.jsontag) = "use_role_requests,omitempty" ]; } // RouteToDatabase combines parameters for database service routing information. @@ -470,6 +488,10 @@ message Features { bool Desktop = 10 [ (gogoproto.jsontag) = "desktop" ]; // ModeratedSessions enables moderated sessions product bool ModeratedSessions = 11 [ (gogoproto.jsontag) = "moderated_sessions" ]; + // MachineID enables MachineID product + bool MachineID = 12 [ (gogoproto.jsontag) = "machine_id" ]; + // ResourceAccessRequests enables resource access requests product + bool ResourceAccessRequests = 13 [ (gogoproto.jsontag) = "resource_access_requests" ]; } // DeleteUserRequest is the input value for the DeleteUser method. @@ -1777,8 +1799,133 @@ message GetSSODiagnosticInfoRequest { string AuthRequestID = 2 [ (gogoproto.jsontag) = "auth_request_id" ]; } +// UnstableSystemRoleAssertion is not a stable part of the public API. Used by older instances +// to prove that they hold a given system role. +// DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) +message UnstableSystemRoleAssertion { + string ServerID = 1 [ (gogoproto.jsontag) = "server_id,omitempty" ]; + string AssertionID = 2 [ (gogoproto.jsontag) = "assertion_id,omitempty" ]; + string SystemRole = 3 [ + (gogoproto.jsontag) = "system_role,omitempty", + (gogoproto.casttype) = "github.com/gravitational/teleport/api/types.SystemRole" + ]; +} + +// UnstableSystemRoleAssertionSet is not a stable part of the public API. Records the sum of system +// role assertions provided by a given instance. +// DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) +message UnstableSystemRoleAssertionSet { + string ServerID = 1 [ (gogoproto.jsontag) = "server_id,omitempty" ]; + string AssertionID = 2 [ (gogoproto.jsontag) = "assertion_id,omitempty" ]; + repeated string SystemRoles = 3 [ + (gogoproto.jsontag) = "system_roles,omitempty", + (gogoproto.casttype) = "github.com/gravitational/teleport/api/types.SystemRole" + ]; +} + +// UpstreamInventoryOneOf is the upstream message for the inventory control stream, +// sent from teleport instances to the auth server. +message UpstreamInventoryOneOf { + oneof Msg { + // Hello is the first message sent up the control stream. + UpstreamInventoryHello Hello = 1; + // Heartbeat advertises instance status/liveness. + InventoryHeartbeat Heartbeat = 2; + // UpstreamInventoryPong is a response to a ping (used for testing/debug). + UpstreamInventoryPong Pong = 3; + } +} + +// DownstreamInventoryOneOf is the downstream message for the inventory control stream, +// sent from auth servers to teleport instances. +message DownstreamInventoryOneOf { + oneof Msg { + // Hello is the first message sent down the control stream. + DownstreamInventoryHello Hello = 1; + // Ping triggers an upstream pong (used for testing/debug). + DownstreamInventoryPing Ping = 2; + } +} + +// DownstreamInventoryPing is sent down the inventory control stream for testing/debug +// purposes. +message DownstreamInventoryPing { uint64 ID = 1; } + +// UpstreamInventoryPong is sent up the inventory control stream in response to a downstream +// ping (used for testing/debug purposes). +message UpstreamInventoryPong { uint64 ID = 1; } + +// UpstreamInventoryHello is the hello message sent up the inventory control stream. +message UpstreamInventoryHello { + // Version advertises the teleport version of the instance. + string Version = 1; + // ServerID advertises the server ID of the instance. + string ServerID = 2; + // Services advertises the currently live services of the instance. note: this is + // distinct from the SystemRoles associated with a certificate in that a service may + // hold a system role that is not currently in use if it was granted that role by + // its auth token. i.e. Services is the subset of SystemRoles that are currently + // active. + repeated string Services = 3 + [ (gogoproto.casttype) = "github.com/gravitational/teleport/api/types.SystemRole" ]; + + // TODO(fspmarshall): look into what other info can safely be stated here once, instead of + // being repeatedly announced (e.g. addrs, static labels, etc). may be able to achieve a + // non-trivial reduction in network usage by doing this. +} + +// DownstreamInventoryHello is the hello message sent down the inventory control stream. +message DownstreamInventoryHello { + // Version advertises the version of the auth server. + string Version = 1; + // ServerID advertises the server ID of the auth server. + string ServerID = 2; +} + +// InventoryHeartbeat announces information about instance state. +message InventoryHeartbeat { + // SSHServer is a complete ssh server spec to be heartbeated (note: the full spec is heartbeated + // in the interest of simple conversion from the old logic of heartbeating via UpsertNode, but + // we should be able to cut down on network usage fairly significantly by moving static values + // to the hello message and only heartbeating dynamic values here). + types.ServerV2 SSHServer = 1; +} + +// InventoryStatusRequest requests inventory status info. +message InventoryStatusRequest { + // Connected requests summary of the inventory control streams registered with + // the auth server that handles the request. + bool Connected = 1; +} + +// InventoryStatusSummary is the status summary returned by the GetInventoryStatus rpc. +message InventoryStatusSummary { + // Connected is a summary of the instances connected to the current auth server. Only set if + // the Connected flag in the status request is true. + repeated UpstreamInventoryHello Connected = 1 [ (gogoproto.nullable) = false ]; +} + +// InventoryPingRequest is used to request that the specified server be sent an inventory ping +// if it has a control stream registered. +message InventoryPingRequest { string ServerID = 1; } + +// InventoryPingResponse returns the result of an inventory ping initiated via an +// inventory ping request. +message InventoryPingResponse { int64 Duration = 1 [ (gogoproto.casttype) = "time.Duration" ]; } + // AuthService is authentication/authorization service implementation service AuthService { + // InventoryControlStream is the per-instance stream used to advertise teleport instance + // presence/version/etc to the auth server. + rpc InventoryControlStream(stream UpstreamInventoryOneOf) + returns (stream DownstreamInventoryOneOf); + + // GetInventoryStatus gets information about current instance inventory. + rpc GetInventoryStatus(InventoryStatusRequest) returns (InventoryStatusSummary); + + // PingInventory attempts to trigger a downstream inventory ping (used in testing/debug). + rpc PingInventory(InventoryPingRequest) returns (InventoryPingResponse); + // MaintainSessionPresence establishes a channel used to continously verify the presence for a // session. rpc MaintainSessionPresence(stream PresenceMFAChallengeSend) @@ -1872,6 +2019,8 @@ service AuthService { // GetCurrentUser returns current user as seen by the server. // Useful especially in the context of remote clusters which perform role and trait mapping. rpc GetCurrentUser(google.protobuf.Empty) returns (types.UserV2); + // GetCurrentUserRoles returns current user's roles. + rpc GetCurrentUserRoles(google.protobuf.Empty) returns (stream types.RoleV5); // GetUsers gets all current user resources. rpc GetUsers(GetUsersRequest) returns (stream types.UserV2); // CreateUser inserts a new user entry to a backend. @@ -2316,4 +2465,9 @@ service AuthService { // without signing keys. If the cluster has multiple TLS certs, they will // all be appended. rpc GetClusterCACert(google.protobuf.Empty) returns (GetClusterCACertResponse); + + // UnstableAssertSystemRole is not a stable part of the public API. Used by older + // instances to prove that they hold a given system role. + // DELETE IN: 12.0 (deprecated in v11, but required for back-compat with v10 clients) + rpc UnstableAssertSystemRole(UnstableSystemRoleAssertion) returns (google.protobuf.Empty); } diff --git a/api/client/proto/types.go b/api/client/proto/types.go index 9e1b789474628..4ceed66177e24 100644 --- a/api/client/proto/types.go +++ b/api/client/proto/types.go @@ -90,3 +90,25 @@ func (req *ListResourcesRequest) CheckAndSetDefaults() error { func (req *ListResourcesRequest) RequiresFakePagination() bool { return req.SortBy.Field != "" || req.NeedTotalCount || req.ResourceType == types.KindKubernetesCluster } + +// UpstreamInventoryMessage is a sealed interface representing the possible +// upstream messages of the inventory control stream after the initial hello. +type UpstreamInventoryMessage interface { + sealedUpstreamInventoryMessage() +} + +func (h UpstreamInventoryHello) sealedUpstreamInventoryMessage() {} + +func (h InventoryHeartbeat) sealedUpstreamInventoryMessage() {} + +func (p UpstreamInventoryPong) sealedUpstreamInventoryMessage() {} + +// DownstreamInventoryMessage is a sealed interface representing the possible +// downstream messages of the inventory controls sream after initial hello. +type DownstreamInventoryMessage interface { + sealedDownstreamInventoryMessage() +} + +func (h DownstreamInventoryHello) sealedDownstreamInventoryMessage() {} + +func (p DownstreamInventoryPing) sealedDownstreamInventoryMessage() {} diff --git a/api/client/proxy.go b/api/client/proxy.go index e6c61164ffbff..c0b92c550a912 100644 --- a/api/client/proxy.go +++ b/api/client/proxy.go @@ -19,6 +19,7 @@ package client import ( "bufio" "context" + "encoding/base64" "net" "net/http" "net/url" @@ -28,23 +29,37 @@ import ( ) // DialProxy creates a connection to a server via an HTTP Proxy. -func DialProxy(ctx context.Context, proxyAddr, addr string) (net.Conn, error) { - return DialProxyWithDialer(ctx, proxyAddr, addr, &net.Dialer{}) +func DialProxy(ctx context.Context, proxyURL *url.URL, addr string) (net.Conn, error) { + return DialProxyWithDialer(ctx, proxyURL, addr, &net.Dialer{}) } // DialProxyWithDialer creates a connection to a server via an HTTP Proxy using a specified dialer. -func DialProxyWithDialer(ctx context.Context, proxyAddr, addr string, dialer ContextDialer) (net.Conn, error) { - conn, err := dialer.DialContext(ctx, "tcp", proxyAddr) +func DialProxyWithDialer(ctx context.Context, proxyURL *url.URL, addr string, dialer ContextDialer) (net.Conn, error) { + if proxyURL == nil { + return nil, trace.BadParameter("missing proxy url") + } + conn, err := dialer.DialContext(ctx, "tcp", proxyURL.Host) if err != nil { - log.Warnf("Unable to dial to proxy: %v: %v.", proxyAddr, err) + log.Warnf("Unable to dial to proxy: %v: %v.", proxyURL.Host, err) return nil, trace.ConvertSystemError(err) } + header := make(http.Header) + if proxyURL.User != nil { + // dont use User.String() because it performs url encoding (rfc 1738), + // which we don't want in our header + password, _ := proxyURL.User.Password() + // empty user/pass is permitted by the spec. The minimum required is a single colon. + // see: https://datatracker.ietf.org/doc/html/rfc1945#section-11 + creds := proxyURL.User.Username() + ":" + password + basicAuth := "Basic " + base64.StdEncoding.EncodeToString([]byte(creds)) + header.Add("Proxy-Authorization", basicAuth) + } connectReq := &http.Request{ Method: http.MethodConnect, URL: &url.URL{Opaque: addr}, Host: addr, - Header: make(http.Header), + Header: header, } if err := connectReq.Write(conn); err != nil { diff --git a/api/client/proxy/proxy.go b/api/client/proxy/proxy.go index 017833ac37108..7b95b3ba8a4df 100644 --- a/api/client/proxy/proxy.go +++ b/api/client/proxy/proxy.go @@ -25,8 +25,8 @@ import ( "golang.org/x/net/http/httpproxy" ) -// GetProxyAddress gets the HTTP proxy address to use for a given address, if any. -func GetProxyAddress(dialAddr string) *url.URL { +// GetProxyURL gets the HTTP proxy address to use for a given address, if any. +func GetProxyURL(dialAddr string) *url.URL { addrURL, err := parse(dialAddr) if err != nil || addrURL == nil { return nil diff --git a/api/client/proxy/proxy_test.go b/api/client/proxy/proxy_test.go index 89d30b077e242..633ce6d0c74d2 100644 --- a/api/client/proxy/proxy_test.go +++ b/api/client/proxy/proxy_test.go @@ -21,8 +21,10 @@ import ( "fmt" "net/http" "net/url" + "strings" "testing" + "github.com/gravitational/trace" "github.com/stretchr/testify/require" "golang.org/x/net/http/httpproxy" ) @@ -106,20 +108,69 @@ func TestGetProxyAddress(t *testing.T) { }, } + // used to augment test cases with auth credentials + authTests := []struct { + info string + user string + password string + }{ + {info: "no credentials", user: "", password: ""}, + {info: "plain password", user: "alice", password: "password"}, + {info: "special characters in password", user: "alice", password: " !@#$%^&*()_+-=[]{};:,.<>/?`~\"\\ abc123"}, + } + for i, tt := range tests { - t.Run(fmt.Sprintf("%v: %v", i, tt.info), func(t *testing.T) { - for _, env := range tt.env { - t.Setenv(env.name, env.val) - } - p := GetProxyAddress(tt.targetAddr) - if tt.proxyAddr == "" { - require.Nil(t, p) - } else { + for j, authTest := range authTests { + t.Run(fmt.Sprintf("%v %v: %v with %v", i, j, tt.info, authTest.info), func(t *testing.T) { + for _, env := range tt.env { + switch strings.ToLower(env.name) { + case "http_proxy", "https_proxy": + // add auth test credentials into http(s)_proxy env vars + val, err := buildProxyAddr(env.val, authTest.user, authTest.password) + require.NoError(t, err) + t.Setenv(env.name, val) + case "no_proxy": + t.Setenv(env.name, env.val) + } + } + p := GetProxyURL(tt.targetAddr) + + // is a proxy expected? + if tt.proxyAddr == "" { + require.Nil(t, p) + return + } require.NotNil(t, p) require.Equal(t, tt.proxyAddr, p.Host) - } - }) + + // are auth credentials expected? + if authTest.user == "" && authTest.password == "" { + require.Nil(t, p.User) + return + } + require.NotNil(t, p.User) + require.Equal(t, authTest.user, p.User.Username()) + password, _ := p.User.Password() + require.Equal(t, authTest.password, password) + }) + } + } +} + +func buildProxyAddr(addr, user, pass string) (string, error) { + if user == "" && pass == "" { + return addr, nil + } + userInfo := url.UserPassword(user, pass) + if strings.HasPrefix(addr, "http") { + u, err := url.Parse(addr) + if err != nil { + return "", trace.Wrap(err) + } + u.User = userInfo + return u.String(), nil } + return fmt.Sprintf("%v@%v", userInfo.String(), addr), nil } func TestProxyAwareRoundTripper(t *testing.T) { diff --git a/api/constants/constants.go b/api/constants/constants.go index 65ef473e00d73..31bc5ae65e32b 100644 --- a/api/constants/constants.go +++ b/api/constants/constants.go @@ -131,6 +131,9 @@ const ( // DatabaseCAMinVersion is the minimum Teleport version that supports Database Certificate Authority. DatabaseCAMinVersion = "10.0.0" + + // SSHRSAType is the string which specifies an "ssh-rsa" formatted keypair + SSHRSAType = "ssh-rsa" ) // SystemConnectors lists the names of the system-reserved connectors. diff --git a/api/go.mod b/api/go.mod index 084ea4a210b71..578e40f237228 100644 --- a/api/go.mod +++ b/api/go.mod @@ -17,6 +17,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 go.opentelemetry.io/otel/trace v1.7.0 + go.opentelemetry.io/proto/otlp v0.16.0 golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd google.golang.org/grpc v1.46.0 diff --git a/api/observability/tracing/client.go b/api/observability/tracing/client.go index acc3bd3b1f30e..9d778ff47b43d 100644 --- a/api/observability/tracing/client.go +++ b/api/observability/tracing/client.go @@ -15,9 +15,13 @@ package tracing import ( + "context" + "sync/atomic" + "github.com/gravitational/trace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + otlp "go.opentelemetry.io/proto/otlp/trace/v1" "google.golang.org/grpc" ) @@ -25,9 +29,18 @@ import ( // close the underlying grpc.ClientConn. When an otlpgrpc.Client is constructed with // the WithGRPCConn option, it is up to the caller to close the provided grpc.ClientConn. // As such, we wrap and implement io.Closer to allow users to have a way to close the connection. +// +// In the event the client receives a trace.NotImplemented error when uploading spans, it will prevent +// any future spans from being sent. The server receiving the span is not going to change for the life +// of the grpc.ClientConn. In an effort to reduce wasted bandwidth, the client merely drops any spans in +// that case and returns nil. type Client struct { otlptrace.Client conn *grpc.ClientConn + + // notImplementedFlag is set to indicate that the server does + // accept traces. + notImplementedFlag int32 } // NewClient returns a new Client that uses the provided grpc.ClientConn to @@ -39,6 +52,20 @@ func NewClient(conn *grpc.ClientConn) *Client { } } +func (c *Client) UploadTraces(ctx context.Context, protoSpans []*otlp.ResourceSpans) error { + if len(protoSpans) == 0 || atomic.LoadInt32(&c.notImplementedFlag) == 1 { + return nil + } + + err := c.Client.UploadTraces(ctx, protoSpans) + if err != nil && trace.IsNotImplemented(err) { + atomic.StoreInt32(&c.notImplementedFlag, 1) + return nil + } + + return trace.Wrap(err) +} + // Close closes the underlying grpc.ClientConn. This is required since when // using otlptracegrpc.WithGRPCConn the otlptrace.Client does not // close the connection when Shutdown is called. diff --git a/api/observability/tracing/client_test.go b/api/observability/tracing/client_test.go new file mode 100644 index 0000000000000..b7a73d8eeb5c2 --- /dev/null +++ b/api/observability/tracing/client_test.go @@ -0,0 +1,109 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tracing + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + otlp "go.opentelemetry.io/proto/otlp/trace/v1" +) + +var _ otlptrace.Client = (*mockClient)(nil) + +type mockClient struct { + uploadError error + spans []*otlp.ResourceSpans +} + +func (m mockClient) Start(ctx context.Context) error { + return nil +} + +func (m mockClient) Stop(ctx context.Context) error { + return nil +} + +func (m *mockClient) UploadTraces(ctx context.Context, protoSpans []*otlp.ResourceSpans) error { + m.spans = append(m.spans, protoSpans...) + return m.uploadError +} + +func TestUploadTraces(t *testing.T) { + const ( + spanCount = 10 + uploadCount = 5 + ) + + cases := []struct { + name string + client mockClient + spans []*otlp.ResourceSpans + errorAssertion require.ErrorAssertionFunc + spanAssertion require.ValueAssertionFunc + }{ + { + name: "no spans to upload", + spans: make([]*otlp.ResourceSpans, 0, spanCount), + errorAssertion: require.NoError, + spanAssertion: require.Empty, + }, + { + name: "successfully uploads spans", + spans: make([]*otlp.ResourceSpans, spanCount), + errorAssertion: require.NoError, + spanAssertion: func(t require.TestingT, i interface{}, i2 ...interface{}) { + require.NotEmpty(t, i, i2...) + require.Len(t, i, spanCount*uploadCount, i2...) + }, + }, + { + name: "error uploading spans", + spans: make([]*otlp.ResourceSpans, spanCount), + client: mockClient{uploadError: trace.ConnectionProblem(nil, "test")}, + errorAssertion: require.Error, + spanAssertion: func(t require.TestingT, i interface{}, i2 ...interface{}) { + require.NotEmpty(t, i, i2...) + require.Len(t, i, spanCount*uploadCount, i2...) + }, + }, + { + name: "not implemented", + spans: make([]*otlp.ResourceSpans, spanCount), + client: mockClient{uploadError: trace.NotImplemented("test")}, + errorAssertion: require.NoError, + spanAssertion: func(t require.TestingT, i interface{}, i2 ...interface{}) { + require.NotEmpty(t, i, i2...) + require.Len(t, i, spanCount, i2...) + }, + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + Client: &tt.client, + } + + for i := 0; i < uploadCount; i++ { + tt.errorAssertion(t, client.UploadTraces(context.Background(), tt.spans)) + } + tt.spanAssertion(t, tt.client.spans) + }) + } +} diff --git a/api/profile/profile.go b/api/profile/profile.go index acd08fa99ab7e..9a46275bcdc13 100644 --- a/api/profile/profile.go +++ b/api/profile/profile.go @@ -407,6 +407,11 @@ func (p *Profile) SSHCertPath() string { return keypaths.SSHCertPath(p.Dir, p.Name(), p.Username, p.SiteName) } +// PPKFilePath returns the path to the profile's PuTTY PPK-formatted keypair. +func (p *Profile) PPKFilePath() string { + return keypaths.PPKFilePath(p.Dir, p.Name(), p.Username) +} + // KnownHostsPath returns the path to the profile's ssh certificate authorities. func (p *Profile) KnownHostsPath() string { return keypaths.KnownHostsPath(p.Dir) diff --git a/api/types/access_request.go b/api/types/access_request.go index 2bcedc52f1210..dfabdb57c866a 100644 --- a/api/types/access_request.go +++ b/api/types/access_request.go @@ -98,6 +98,11 @@ type AccessRequest interface { GetLoginHint() string // SetLoginHint sets the requested login hint. SetLoginHint(string) + // GetDryRun returns true if this request should not be created and is only + // a dry run to validate request capabilities. + GetDryRun() bool + // SetDryRun sets the dry run flag on the request. + SetDryRun(bool) } // NewAccessRequest assembles an AccessRequest resource. @@ -396,6 +401,17 @@ func (r *AccessRequestV3) SetLoginHint(login string) { r.Spec.LoginHint = login } +// GetDryRun returns true if this request should not be created and is only +// a dry run to validate request capabilities. +func (r *AccessRequestV3) GetDryRun() bool { + return r.Spec.DryRun +} + +// SetDryRun sets the dry run flag on the request. +func (r *AccessRequestV3) SetDryRun(dryRun bool) { + r.Spec.DryRun = dryRun +} + // String returns a text representation of this AccessRequest func (r *AccessRequestV3) String() string { return fmt.Sprintf("AccessRequest(user=%v,roles=%+v)", r.Spec.User, r.Spec.Roles) diff --git a/api/types/audit.go b/api/types/audit.go index 3c524edc0d43f..2a6e37a207443 100644 --- a/api/types/audit.go +++ b/api/types/audit.go @@ -52,6 +52,11 @@ type ClusterAuditConfig interface { // SetAuditEventsURIs sets the audit events URIs. SetAuditEventsURIs([]string) + // SetUseFIPSEndpoint sets the FIPS endpoint state for S3/Dynamo backends. + SetUseFIPSEndpoint(state ClusterAuditConfigSpecV2_FIPSEndpointState) + // GetUseFIPSEndpoint gets the current FIPS endpoint setting + GetUseFIPSEndpoint() ClusterAuditConfigSpecV2_FIPSEndpointState + // EnableContinuousBackups is used to enable (or disable) PITR (Point-In-Time Recovery). EnableContinuousBackups() bool // EnableAutoScaling is used to enable (or disable) auto scaling policy. @@ -190,6 +195,16 @@ func (c *ClusterAuditConfigV2) SetAuditEventsURIs(uris []string) { c.Spec.AuditEventsURI = uris } +// SetUseFIPSEndpoint sets the FIPS endpoint state for S3/Dynamo backends. +func (c *ClusterAuditConfigV2) SetUseFIPSEndpoint(state ClusterAuditConfigSpecV2_FIPSEndpointState) { + c.Spec.UseFIPSEndpoint = state +} + +// GetUseFIPSEndpoint gets the current FIPS endpoint setting +func (c *ClusterAuditConfigV2) GetUseFIPSEndpoint() ClusterAuditConfigSpecV2_FIPSEndpointState { + return c.Spec.UseFIPSEndpoint +} + // EnableContinuousBackups is used to enable (or disable) PITR (Point-In-Time Recovery). func (c *ClusterAuditConfigV2) EnableContinuousBackups() bool { return c.Spec.EnableContinuousBackups diff --git a/api/types/databaseserver.go b/api/types/databaseserver.go index 67db0dda917f0..d78f78e92f8bc 100644 --- a/api/types/databaseserver.go +++ b/api/types/databaseserver.go @@ -386,3 +386,12 @@ func (s DatabaseServers) GetFieldVals(field string) ([]string, error) { return vals, nil } + +// ToDatabases converts database servers to a list of databases. +func (s DatabaseServers) ToDatabases() []Database { + databases := make([]Database, 0, len(s)) + for _, server := range s { + databases = append(databases, server.GetDatabase()) + } + return databases +} diff --git a/api/types/events/events.pb.go b/api/types/events/events.pb.go index d13084d991625..8e57ed85ae0f5 100644 --- a/api/types/events/events.pb.go +++ b/api/types/events/events.pb.go @@ -6835,7 +6835,7 @@ type SQLServerRPCRequest struct { // Database contains database related metadata. DatabaseMetadata `protobuf:"bytes,4,opt,name=Database,proto3,embedded=Database" json:""` // Procname is the RPC SQL Server procedure name. - Procname string `protobuf:"bytes,5,opt,name=Procname,proto3" json:"procname,omitempty"` + Procname string `protobuf:"bytes,5,opt,name=Procname,proto3" json:"proc_name,omitempty"` // Parameters are the RPC parameters used to execute RPC Procedure.. Parameters []string `protobuf:"bytes,6,rep,name=Parameters,proto3" json:"parameters,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -7052,7 +7052,7 @@ func init() { func init() { proto.RegisterFile("events.proto", fileDescriptor_8f22242cb04491f9) } var fileDescriptor_8f22242cb04491f9 = []byte{ - // 7723 bytes of a gzipped FileDescriptorProto + // 7724 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5d, 0x6c, 0x1c, 0xc9, 0x79, 0x20, 0x67, 0x86, 0x3f, 0xc3, 0x1a, 0xfe, 0x96, 0x28, 0xa9, 0x57, 0xab, 0xd5, 0xec, 0xb6, 0x6c, 0xad, 0xe4, 0xd5, 0x92, 0xd6, 0xcf, 0x5a, 0xbb, 0xeb, 0x5d, 0xaf, 0x86, 0x33, 0xd4, 0x72, @@ -7060,482 +7060,482 @@ var fileDescriptor_8f22242cb04491f9 = []byte{ 0x77, 0xbb, 0xbb, 0x47, 0x14, 0xf7, 0xe9, 0x0e, 0xe7, 0xbb, 0x33, 0x0e, 0xbe, 0xc3, 0xc1, 0xf7, 0x70, 0x0f, 0xf7, 0xe0, 0x83, 0x71, 0x07, 0x24, 0x88, 0x11, 0x27, 0x41, 0x62, 0xc7, 0x48, 0x5e, 0x12, 0x3b, 0xc1, 0x26, 0x81, 0x1d, 0x27, 0x0e, 0x1c, 0x20, 0x0f, 0xe3, 0xc4, 0x41, 0x5e, 0x06, - 0x09, 0x62, 0x24, 0x01, 0xe2, 0xfc, 0x3c, 0x04, 0xf5, 0x55, 0x75, 0x77, 0x55, 0x77, 0x0f, 0x25, - 0x8a, 0xda, 0x30, 0x5c, 0xf2, 0x89, 0x9c, 0xef, 0xaf, 0xbb, 0xbf, 0xaa, 0xfa, 0xea, 0xab, 0xaf, - 0xbe, 0xfa, 0x0a, 0x8d, 0xd1, 0x7b, 0xd4, 0x0e, 0xfc, 0x59, 0xd7, 0x73, 0x02, 0x07, 0x0f, 0xf3, - 0x5f, 0xa7, 0x66, 0x36, 0x9c, 0x0d, 0x07, 0x40, 0x73, 0xec, 0x3f, 0x8e, 0x3d, 0x55, 0xde, 0x70, - 0x9c, 0x8d, 0x16, 0x9d, 0x83, 0x5f, 0xeb, 0x9d, 0x3b, 0x73, 0x81, 0xd5, 0xa6, 0x7e, 0x60, 0xb4, - 0x5d, 0x41, 0x70, 0x3a, 0x49, 0xe0, 0x07, 0x5e, 0xa7, 0x19, 0x08, 0x6c, 0x75, 0xc3, 0x0a, 0x36, - 0x3b, 0xeb, 0xb3, 0x4d, 0xa7, 0x3d, 0xb7, 0xe1, 0x19, 0xf7, 0xac, 0xc0, 0x08, 0x2c, 0xc7, 0x36, - 0x5a, 0x73, 0x01, 0x6d, 0x51, 0xd7, 0xf1, 0x82, 0x39, 0xc3, 0xb5, 0xe6, 0x82, 0x6d, 0x97, 0xfa, - 0x73, 0x5b, 0x9e, 0xe1, 0xba, 0xd4, 0x8b, 0xff, 0xe1, 0x42, 0xf4, 0x2f, 0xe7, 0x51, 0xf1, 0x26, - 0x0d, 0x0c, 0xd3, 0x08, 0x0c, 0x7c, 0x1a, 0x0d, 0xd5, 0x6d, 0x93, 0xde, 0xd7, 0x72, 0x4f, 0xe7, - 0xce, 0x17, 0xe6, 0x87, 0x7b, 0xdd, 0x72, 0x9e, 0x5a, 0x84, 0x03, 0xf1, 0x53, 0x68, 0x70, 0x6d, - 0xdb, 0xa5, 0x5a, 0xfe, 0xe9, 0xdc, 0xf9, 0xd1, 0xf9, 0xd1, 0x5e, 0xb7, 0x3c, 0x04, 0x9f, 0x47, - 0x00, 0x8c, 0x9f, 0x41, 0xf9, 0x7a, 0x4d, 0x2b, 0x00, 0x72, 0xba, 0xd7, 0x2d, 0x8f, 0x77, 0x2c, - 0xf3, 0xa2, 0xd3, 0xb6, 0x02, 0xda, 0x76, 0x83, 0x6d, 0x92, 0xaf, 0xd7, 0xf0, 0x39, 0x34, 0x58, - 0x75, 0x4c, 0xaa, 0x0d, 0x02, 0x11, 0xee, 0x75, 0xcb, 0x13, 0x4d, 0xc7, 0xa4, 0x12, 0x15, 0xe0, - 0xf1, 0x75, 0x34, 0xb8, 0x66, 0xb5, 0xa9, 0x36, 0xf4, 0x74, 0xee, 0x7c, 0xe9, 0xf2, 0xa9, 0x59, - 0xae, 0x86, 0xd9, 0x50, 0x0d, 0xb3, 0x6b, 0xa1, 0x9e, 0xe6, 0xa7, 0xde, 0xef, 0x96, 0x07, 0x7a, - 0xdd, 0xf2, 0x20, 0x53, 0xdd, 0xff, 0xfc, 0x51, 0x39, 0x47, 0x80, 0x13, 0xbf, 0x82, 0x4a, 0xd5, - 0x56, 0xc7, 0x0f, 0xa8, 0x77, 0xcb, 0x68, 0x53, 0x6d, 0x18, 0x1e, 0x78, 0xaa, 0xd7, 0x2d, 0x9f, - 0x68, 0x72, 0x70, 0xc3, 0x36, 0xda, 0xf2, 0x83, 0x65, 0x72, 0xfd, 0x5d, 0x34, 0xb9, 0x4a, 0x7d, - 0xdf, 0x72, 0xec, 0x48, 0x35, 0x1f, 0x45, 0xa3, 0x02, 0x54, 0xaf, 0x81, 0x7a, 0x46, 0xe7, 0x47, - 0x7a, 0xdd, 0x72, 0xc1, 0xb7, 0x4c, 0x12, 0x63, 0xf0, 0xc7, 0xd1, 0xc8, 0xdb, 0x56, 0xb0, 0x79, - 0xf3, 0x46, 0x45, 0xa8, 0xe9, 0x44, 0xaf, 0x5b, 0xc6, 0x5b, 0x56, 0xb0, 0xd9, 0x68, 0xdf, 0x31, - 0xa4, 0xe7, 0x85, 0x64, 0xfa, 0xff, 0xcb, 0xa3, 0xb1, 0xdb, 0x3e, 0xf5, 0xa2, 0x27, 0x9d, 0x43, - 0x83, 0xec, 0xb7, 0x78, 0x08, 0x28, 0xa9, 0xe3, 0x53, 0x4f, 0x56, 0x12, 0xc3, 0xe3, 0x0b, 0x68, - 0x68, 0xc9, 0xd9, 0xb0, 0x6c, 0xf1, 0xa0, 0x63, 0xbd, 0x6e, 0x79, 0xb2, 0xc5, 0x00, 0x12, 0x25, - 0xa7, 0xc0, 0x9f, 0x42, 0x63, 0xf5, 0x36, 0x6b, 0x74, 0xc7, 0x36, 0x02, 0xc7, 0x13, 0x8d, 0x04, - 0xea, 0xb0, 0x24, 0xb8, 0xc4, 0xa8, 0xd0, 0xe3, 0x97, 0x11, 0xaa, 0xbc, 0xbd, 0x4a, 0x9c, 0x16, - 0xad, 0x90, 0x5b, 0xa2, 0xf5, 0x80, 0xdb, 0xd8, 0xf2, 0x1b, 0x9e, 0xd3, 0xa2, 0x0d, 0xc3, 0x93, - 0x1f, 0x2b, 0x51, 0xe3, 0x05, 0x34, 0x51, 0x69, 0x36, 0xa9, 0xef, 0x13, 0xfa, 0xf9, 0x0e, 0xf5, - 0x03, 0x5f, 0x1b, 0x7a, 0xba, 0x70, 0x7e, 0x74, 0xfe, 0xa9, 0x5e, 0xb7, 0xfc, 0x84, 0x01, 0x98, - 0x86, 0x27, 0x50, 0x92, 0x88, 0x04, 0x93, 0xfe, 0x0b, 0x05, 0x34, 0xb1, 0x4a, 0xbd, 0x7b, 0x92, - 0xa2, 0x2a, 0xac, 0x95, 0x18, 0x84, 0xb5, 0x99, 0xef, 0x1a, 0x4d, 0x2a, 0x74, 0x76, 0xb2, 0xd7, - 0x2d, 0x1f, 0xb3, 0x43, 0xa0, 0x24, 0x34, 0x49, 0x8f, 0x2f, 0xa0, 0x22, 0x07, 0xd5, 0x6b, 0x42, - 0x8d, 0xe3, 0xbd, 0x6e, 0x79, 0xd4, 0x07, 0x58, 0xc3, 0x32, 0x49, 0x84, 0x66, 0xdf, 0xc1, 0xff, - 0x5f, 0x74, 0xfc, 0x80, 0x09, 0x17, 0x5a, 0x84, 0xef, 0x10, 0x0c, 0x9b, 0x02, 0x25, 0x7f, 0x87, - 0xca, 0x84, 0x5f, 0x42, 0x88, 0x43, 0x2a, 0xa6, 0xe9, 0x09, 0x55, 0x3e, 0xd1, 0xeb, 0x96, 0x8f, - 0x0b, 0x11, 0x86, 0x69, 0xca, 0xed, 0x20, 0x11, 0xe3, 0x36, 0x1a, 0xe3, 0xbf, 0x96, 0x8c, 0x75, - 0xda, 0xe2, 0x7a, 0x2c, 0x5d, 0x3e, 0x3f, 0x2b, 0x2c, 0x8e, 0xaa, 0x9d, 0x59, 0x99, 0x74, 0xc1, - 0x0e, 0xbc, 0xed, 0xf9, 0xb2, 0x18, 0x2b, 0x27, 0xc5, 0xa3, 0x5a, 0x80, 0x93, 0x1b, 0x5d, 0xe6, - 0x39, 0xf5, 0x1a, 0x9a, 0x4e, 0xc9, 0xc0, 0x53, 0xa8, 0x70, 0x97, 0x6e, 0x73, 0x3d, 0x13, 0xf6, - 0x2f, 0x9e, 0x41, 0x43, 0xf7, 0x8c, 0x56, 0x47, 0x98, 0x05, 0xc2, 0x7f, 0xbc, 0x9c, 0x7f, 0x31, - 0xa7, 0xff, 0x6a, 0x0e, 0xe1, 0xaa, 0x63, 0xdb, 0xb4, 0x19, 0xc8, 0x23, 0xe9, 0x13, 0x68, 0x74, - 0xc9, 0x69, 0x1a, 0x2d, 0x50, 0x00, 0x6f, 0x30, 0xad, 0xd7, 0x2d, 0xcf, 0xb0, 0x2f, 0x9f, 0x6d, - 0x31, 0x8c, 0xf4, 0x4a, 0x31, 0x29, 0xd3, 0x1c, 0xa1, 0x6d, 0x27, 0xa0, 0xc0, 0x98, 0x8f, 0x35, - 0x07, 0x8c, 0x1e, 0xa0, 0x64, 0xcd, 0xc5, 0xc4, 0x78, 0x0e, 0x15, 0x57, 0x98, 0xed, 0x68, 0x3a, - 0x2d, 0xd1, 0x6a, 0x30, 0x5a, 0xc0, 0x9e, 0x48, 0x2c, 0x11, 0x91, 0xbe, 0x88, 0x26, 0xaa, 0x2d, - 0x8b, 0xda, 0x81, 0xfc, 0xd6, 0x6c, 0xd4, 0x55, 0x36, 0xa8, 0x1d, 0xc8, 0x6f, 0xcd, 0x86, 0x66, - 0xc3, 0x60, 0x50, 0xf9, 0xad, 0x23, 0x52, 0xfd, 0x7b, 0x05, 0xf4, 0xc4, 0x1b, 0x9d, 0x75, 0xea, - 0xd9, 0x34, 0xa0, 0xbe, 0x30, 0x32, 0x91, 0xd4, 0x5b, 0x68, 0x3a, 0x85, 0x14, 0xd2, 0x9f, 0xee, - 0x75, 0xcb, 0xa7, 0xef, 0x46, 0xc8, 0x86, 0xb0, 0x5b, 0xd2, 0x53, 0xd2, 0xac, 0x78, 0x11, 0x4d, - 0xc6, 0x40, 0xf6, 0x12, 0xbe, 0x96, 0x87, 0xd1, 0x76, 0xa6, 0xd7, 0x2d, 0x9f, 0x92, 0xa4, 0xb1, - 0xd7, 0x96, 0x9b, 0x3e, 0xc9, 0x86, 0xdf, 0x40, 0x53, 0x31, 0xe8, 0x75, 0xcf, 0xe9, 0xb8, 0xbe, - 0x56, 0x00, 0x51, 0xe5, 0x5e, 0xb7, 0xfc, 0xa4, 0x24, 0x6a, 0x03, 0x90, 0x92, 0xac, 0x14, 0x23, - 0xfe, 0x42, 0x4e, 0x96, 0x26, 0xba, 0xef, 0x20, 0x74, 0xdf, 0x6b, 0x61, 0xf7, 0xed, 0xab, 0xa4, - 0xd9, 0x24, 0xa7, 0xe8, 0xcd, 0x89, 0xd7, 0x48, 0xf5, 0xe6, 0xd4, 0x13, 0x4f, 0x55, 0xd1, 0xf1, - 0x4c, 0x59, 0xbb, 0xea, 0xd5, 0x7f, 0x51, 0x90, 0xa5, 0xac, 0x38, 0x66, 0xd4, 0x98, 0xcb, 0x72, - 0x63, 0xae, 0x38, 0x26, 0xcc, 0x3c, 0xbc, 0x31, 0x9f, 0xe9, 0x75, 0xcb, 0x4f, 0x49, 0x2f, 0xeb, - 0x3a, 0x66, 0x72, 0x02, 0x4a, 0xf3, 0xe2, 0x77, 0xd0, 0x89, 0x14, 0x90, 0xdb, 0x39, 0xde, 0xfb, - 0xcf, 0xf5, 0xba, 0x65, 0x3d, 0x43, 0x6a, 0xd2, 0xec, 0xf5, 0x91, 0x82, 0x0d, 0x74, 0x52, 0xd2, - 0xba, 0x63, 0x07, 0x86, 0x65, 0x8b, 0x09, 0x93, 0x8f, 0x92, 0x67, 0x7b, 0xdd, 0xf2, 0x59, 0xb9, - 0x0f, 0x86, 0x34, 0xc9, 0x97, 0xef, 0x27, 0x07, 0x9b, 0x48, 0xcb, 0x40, 0xd5, 0xdb, 0xc6, 0x46, - 0xe8, 0x05, 0x9c, 0xef, 0x75, 0xcb, 0x1f, 0xc9, 0x7c, 0x86, 0xc5, 0xa8, 0xa4, 0x87, 0xf4, 0x95, - 0x84, 0x09, 0xc2, 0x31, 0xee, 0x96, 0x63, 0x52, 0xf8, 0x86, 0x21, 0x90, 0xaf, 0xf7, 0xba, 0xe5, - 0x33, 0x92, 0x7c, 0xdb, 0x31, 0x69, 0xf2, 0xf5, 0x33, 0xb8, 0xf5, 0x1f, 0x0d, 0x31, 0x73, 0x0b, - 0xf3, 0xfa, 0x6a, 0x60, 0x78, 0x01, 0x7e, 0x39, 0x76, 0x94, 0xa0, 0x55, 0x4b, 0x97, 0xa7, 0xc2, - 0xbe, 0x1b, 0xc2, 0xe7, 0xc7, 0x98, 0x89, 0xfd, 0x7e, 0xb7, 0x9c, 0xeb, 0x75, 0xcb, 0x03, 0xa4, - 0x28, 0x59, 0x0f, 0x3e, 0xa7, 0xe7, 0x81, 0x6f, 0x26, 0xe4, 0x93, 0xe7, 0xfd, 0x04, 0x2f, 0x9f, - 0xe3, 0x5f, 0x43, 0x23, 0xe2, 0x1d, 0xa0, 0x45, 0x4a, 0x97, 0x4f, 0xc6, 0xd6, 0x5e, 0xf1, 0x4f, - 0x12, 0xdc, 0x21, 0x17, 0x7e, 0x05, 0x0d, 0x73, 0x23, 0x0e, 0xda, 0x2e, 0x5d, 0x3e, 0x91, 0x3d, - 0x5b, 0x24, 0xd8, 0x05, 0x0f, 0x5e, 0x44, 0x28, 0x36, 0xe0, 0x91, 0x37, 0x26, 0x24, 0xa4, 0x4d, - 0x7b, 0x42, 0x8a, 0xc4, 0x8b, 0x3f, 0x81, 0xc6, 0xd6, 0xa8, 0xd7, 0xb6, 0x6c, 0xa3, 0xb5, 0x6a, - 0xbd, 0x17, 0x3a, 0x64, 0xe0, 0xdc, 0xf8, 0xd6, 0x7b, 0x72, 0x5b, 0x28, 0x74, 0xf8, 0x73, 0x59, - 0x06, 0x72, 0x04, 0x5e, 0xe4, 0x99, 0x07, 0x5a, 0x8e, 0xc4, 0xfb, 0x64, 0xd8, 0xcb, 0x37, 0xd1, - 0xb8, 0x32, 0x36, 0xb4, 0x22, 0x88, 0x7e, 0x2a, 0x2d, 0x5a, 0x1a, 0xe8, 0x09, 0xb1, 0xaa, 0x04, - 0xe6, 0x27, 0xd4, 0x6d, 0x2b, 0xb0, 0x8c, 0x56, 0xd5, 0x69, 0xb7, 0x0d, 0xdb, 0xd4, 0x46, 0x63, - 0x7f, 0xc7, 0xe2, 0x98, 0x46, 0x93, 0xa3, 0x64, 0x3f, 0x41, 0x65, 0x62, 0xf6, 0x57, 0xb4, 0x21, - 0xa1, 0x4d, 0xc7, 0x33, 0x2d, 0x7b, 0x43, 0x43, 0xa0, 0x34, 0x30, 0x7c, 0x3e, 0xc7, 0x35, 0xbc, - 0x10, 0x29, 0x1b, 0xbe, 0x24, 0xe3, 0xa7, 0x07, 0x8b, 0xa5, 0xa9, 0xb1, 0x94, 0x4b, 0xf5, 0xb3, - 0x05, 0x54, 0x12, 0xa4, 0x9f, 0x76, 0x2c, 0xfb, 0xa8, 0x83, 0xef, 0xa5, 0x83, 0x67, 0x76, 0xd4, - 0xe1, 0xc7, 0xd5, 0x51, 0xf5, 0x2f, 0xe5, 0x23, 0x6b, 0xb4, 0xe2, 0x59, 0xf6, 0xde, 0xac, 0xd1, - 0x39, 0x84, 0xaa, 0x9b, 0x1d, 0xfb, 0x2e, 0x5f, 0xeb, 0xe5, 0xe3, 0xb5, 0x5e, 0xd3, 0x22, 0x12, - 0x86, 0x2d, 0xf8, 0x6a, 0x4c, 0x3e, 0x6b, 0x99, 0xb1, 0xf9, 0xd1, 0xf7, 0xb9, 0xa4, 0xdc, 0xf3, - 0x04, 0xc0, 0xb8, 0x8c, 0x86, 0xe6, 0xb7, 0x03, 0xea, 0x83, 0xe6, 0x0b, 0x7c, 0x41, 0xb8, 0xce, - 0x00, 0x84, 0xc3, 0xf1, 0x55, 0x34, 0x5d, 0xa3, 0x2d, 0x63, 0xfb, 0xa6, 0xd5, 0x6a, 0x59, 0x3e, - 0x6d, 0x3a, 0xb6, 0xe9, 0x83, 0x92, 0xc5, 0xe3, 0xda, 0x3e, 0x49, 0x13, 0x60, 0x1d, 0x0d, 0x2f, - 0xdf, 0xb9, 0xe3, 0xd3, 0x00, 0xd4, 0x57, 0x98, 0x47, 0xbd, 0x6e, 0x79, 0xd8, 0x01, 0x08, 0x11, - 0x18, 0xfd, 0xeb, 0x39, 0x34, 0x55, 0xa3, 0xfe, 0xdd, 0xc0, 0x71, 0xa3, 0x5e, 0xbe, 0x27, 0x95, - 0x5c, 0x40, 0x23, 0x37, 0xa9, 0xef, 0xb3, 0x69, 0x29, 0x0f, 0x5f, 0x3b, 0x29, 0xbe, 0x76, 0xa4, - 0xcd, 0xc1, 0x24, 0xc4, 0x67, 0x7f, 0x55, 0xe1, 0x01, 0x5f, 0xa5, 0xff, 0x24, 0x8f, 0x4e, 0x8a, - 0x37, 0xae, 0xb6, 0x2c, 0x77, 0xdd, 0x31, 0x3c, 0x93, 0xd0, 0x26, 0xb5, 0xee, 0xd1, 0x83, 0x39, - 0xf0, 0xd4, 0xa1, 0x33, 0xb8, 0x87, 0xa1, 0x73, 0x19, 0x95, 0x84, 0x66, 0xc0, 0xb3, 0xe7, 0xd3, - 0xf6, 0x54, 0xaf, 0x5b, 0x1e, 0x33, 0x39, 0x18, 0x16, 0x45, 0x44, 0x26, 0x62, 0x9d, 0x64, 0x89, - 0xda, 0x1b, 0xc1, 0x26, 0x74, 0x92, 0x21, 0xde, 0x49, 0x5a, 0x00, 0x21, 0x02, 0xa3, 0xff, 0x55, - 0x1e, 0xcd, 0x24, 0x55, 0xbe, 0x4a, 0x6d, 0xf3, 0x48, 0xdf, 0x1f, 0x8c, 0xbe, 0xff, 0x30, 0x8f, - 0xc6, 0xa3, 0xa9, 0xe7, 0x5d, 0xda, 0xdc, 0x1f, 0x97, 0x29, 0x9e, 0x10, 0x0a, 0x7b, 0x9e, 0x10, - 0xf6, 0xa2, 0x65, 0x1d, 0x0d, 0x13, 0x6a, 0xf8, 0x62, 0x5a, 0x19, 0xe5, 0x1a, 0xf3, 0x00, 0x42, - 0x04, 0x06, 0x3f, 0x83, 0x46, 0x6e, 0x1a, 0xf7, 0xad, 0x76, 0xa7, 0x2d, 0x6c, 0x1d, 0x84, 0x94, - 0xda, 0xc6, 0x7d, 0x12, 0xc2, 0xf5, 0x3f, 0xca, 0xa1, 0x09, 0xa1, 0x54, 0x21, 0x7c, 0x4f, 0x5a, - 0x8d, 0xb5, 0x93, 0xdf, 0xb3, 0x76, 0x0a, 0x8f, 0xae, 0x1d, 0xfd, 0xeb, 0x83, 0x4c, 0x3d, 0xcc, - 0xf5, 0x3b, 0xec, 0xa3, 0x31, 0x6e, 0x91, 0xa1, 0x47, 0x68, 0x91, 0x43, 0xe3, 0x57, 0xeb, 0x7f, - 0x3f, 0x82, 0x90, 0xd0, 0xfe, 0xc2, 0x91, 0x0d, 0xdf, 0x5b, 0xaf, 0xa9, 0xa1, 0xe9, 0x05, 0x7b, - 0xd3, 0xb0, 0x9b, 0xd4, 0x8c, 0x57, 0x17, 0xac, 0xeb, 0x14, 0x79, 0xbc, 0x9a, 0x0a, 0x64, 0xbc, - 0xbc, 0x20, 0x69, 0x06, 0x7c, 0x09, 0x95, 0xea, 0x76, 0x40, 0x3d, 0xa3, 0x19, 0x58, 0xf7, 0x28, - 0xf4, 0x9e, 0xe2, 0xfc, 0x64, 0xaf, 0x5b, 0x2e, 0x59, 0x31, 0x98, 0xc8, 0x34, 0xf8, 0x2a, 0x1a, - 0x5b, 0x31, 0xbc, 0xc0, 0x6a, 0x5a, 0xae, 0x61, 0x07, 0xbe, 0x56, 0x84, 0xa5, 0x11, 0xcc, 0x3d, - 0xae, 0x04, 0x27, 0x0a, 0x15, 0xfe, 0x1c, 0x1a, 0x85, 0x25, 0x38, 0xec, 0x09, 0x8c, 0x3e, 0x70, - 0x4f, 0xe0, 0x6c, 0x1c, 0xe7, 0xe4, 0x8b, 0x24, 0x9f, 0x31, 0xc7, 0x43, 0x01, 0xb6, 0x09, 0x62, - 0x89, 0xf8, 0x33, 0x68, 0x64, 0xc1, 0x36, 0x41, 0x38, 0x7a, 0xa0, 0x70, 0x5d, 0x08, 0x3f, 0x11, - 0x0b, 0x77, 0xdc, 0x84, 0xec, 0x50, 0x5c, 0xf6, 0x28, 0x2b, 0x7d, 0x70, 0xa3, 0x6c, 0xec, 0x03, - 0x58, 0xbd, 0x8e, 0x3f, 0xae, 0xd5, 0xeb, 0xc4, 0x23, 0xae, 0x5e, 0xf5, 0xf7, 0x50, 0x69, 0x7e, - 0xe5, 0x46, 0x34, 0x7a, 0x9f, 0x40, 0x85, 0x15, 0xb1, 0x07, 0x33, 0xc8, 0x27, 0x4c, 0xd7, 0x32, - 0x09, 0x83, 0xe1, 0x0b, 0xa8, 0x58, 0x85, 0x70, 0xa4, 0x08, 0xe7, 0x0f, 0xf2, 0x70, 0x7e, 0x13, - 0x60, 0x10, 0xce, 0x0f, 0xd1, 0xf8, 0xa3, 0x68, 0x64, 0xc5, 0x73, 0x36, 0x3c, 0xa3, 0x2d, 0x62, - 0x5d, 0x25, 0xe6, 0xec, 0xbb, 0x1c, 0x44, 0x42, 0x9c, 0xfe, 0xbf, 0x72, 0x68, 0x78, 0x35, 0x30, - 0x82, 0x8e, 0xcf, 0x38, 0x56, 0x3b, 0xb0, 0x82, 0x86, 0x67, 0x17, 0x39, 0x87, 0xcf, 0x41, 0x24, - 0xc4, 0xe1, 0x0b, 0x68, 0x68, 0xc1, 0xf3, 0x1c, 0x4f, 0xde, 0x96, 0xa1, 0x0c, 0x20, 0x6f, 0xcb, - 0x00, 0x05, 0xbe, 0x86, 0x4a, 0xdc, 0xe6, 0xf0, 0x85, 0x07, 0x7f, 0x8f, 0xe3, 0xbd, 0x6e, 0x79, - 0x5a, 0x2c, 0x3a, 0xe4, 0xfd, 0x29, 0x89, 0x52, 0xff, 0x76, 0x41, 0x72, 0x0a, 0xb8, 0xc6, 0x0f, - 0xe1, 0xe2, 0xfd, 0x0a, 0x2a, 0xcc, 0xaf, 0xdc, 0x10, 0x06, 0xf0, 0x58, 0xc8, 0x2a, 0x75, 0x95, - 0x04, 0x1f, 0xa3, 0xc6, 0xa7, 0xd1, 0xe0, 0x0a, 0xeb, 0x3e, 0xc3, 0xd0, 0x3d, 0x8a, 0xbd, 0x6e, - 0x79, 0xd0, 0x65, 0xfd, 0x07, 0xa0, 0x80, 0x35, 0x82, 0x4d, 0xb0, 0x65, 0xa3, 0x02, 0x6b, 0x04, - 0x9b, 0x04, 0xa0, 0x0c, 0x5b, 0xf1, 0x36, 0xee, 0x09, 0xab, 0x05, 0x58, 0xc3, 0xdb, 0xb8, 0x47, - 0x00, 0x8a, 0xe7, 0x10, 0x22, 0x34, 0xe8, 0x78, 0x36, 0x6c, 0x71, 0x8e, 0x82, 0x9b, 0x0c, 0xd6, - 0xd0, 0x03, 0x68, 0xa3, 0xe9, 0x98, 0x94, 0x48, 0x24, 0xfa, 0xff, 0x8f, 0xe3, 0x2f, 0x35, 0xcb, - 0xbf, 0x7b, 0xd4, 0x84, 0xbb, 0x68, 0x42, 0x43, 0xac, 0x44, 0xd2, 0x8d, 0x54, 0x46, 0x43, 0x37, - 0x5a, 0xc6, 0x86, 0x0f, 0x6d, 0x38, 0xc4, 0xa3, 0x12, 0x77, 0x18, 0x80, 0x70, 0x78, 0xa2, 0x9d, - 0x8a, 0x0f, 0x6e, 0xa7, 0xff, 0x3d, 0x14, 0x8d, 0xb6, 0x5b, 0x34, 0xd8, 0x72, 0xbc, 0xa3, 0xa6, - 0x7a, 0xd8, 0xa6, 0x3a, 0x87, 0x46, 0x56, 0xbd, 0x26, 0x2c, 0x33, 0x79, 0x6b, 0x8d, 0xf5, 0xba, - 0xe5, 0xa2, 0xef, 0x35, 0xf9, 0x12, 0x33, 0x44, 0x32, 0xba, 0x9a, 0x1f, 0x00, 0xdd, 0x48, 0x4c, - 0x67, 0xfa, 0x81, 0xa0, 0x13, 0x48, 0x41, 0xb7, 0xe2, 0x78, 0x81, 0x68, 0xb8, 0x88, 0xce, 0x75, - 0xbc, 0x80, 0x84, 0x48, 0xfc, 0x1c, 0x42, 0x6b, 0xd5, 0x95, 0xb7, 0xa8, 0x07, 0xea, 0xe2, 0x63, - 0x11, 0xcc, 0xf5, 0x3d, 0x0e, 0x22, 0x12, 0x1a, 0xaf, 0xa1, 0xd1, 0x65, 0x97, 0x7a, 0x90, 0x3c, - 0x01, 0x1e, 0xc0, 0xc4, 0xe5, 0x67, 0x13, 0xaa, 0x15, 0xed, 0x3e, 0x2b, 0xfe, 0x46, 0xe4, 0x7c, - 0x7e, 0x71, 0xc2, 0x9f, 0x24, 0x16, 0x84, 0xaf, 0xa1, 0xe1, 0x0a, 0xf7, 0xf3, 0x4a, 0x20, 0x32, - 0x52, 0xd9, 0x02, 0xfb, 0xc3, 0x51, 0x7c, 0x51, 0x68, 0xc0, 0xff, 0x44, 0x90, 0xeb, 0x17, 0xd0, - 0x54, 0xf2, 0x31, 0xb8, 0x84, 0x46, 0xaa, 0xcb, 0xb7, 0x6e, 0x2d, 0x54, 0xd7, 0xa6, 0x06, 0x70, - 0x11, 0x0d, 0xae, 0x2e, 0xdc, 0xaa, 0x4d, 0xe5, 0xf4, 0xaf, 0x49, 0x16, 0x84, 0x75, 0xad, 0xa3, - 0x08, 0xee, 0x9e, 0xc2, 0x22, 0x53, 0x10, 0xb6, 0x5c, 0xf3, 0x0c, 0xdb, 0x6f, 0x5b, 0x41, 0x40, - 0x4d, 0x31, 0x4b, 0x40, 0x58, 0x2f, 0xb8, 0x4f, 0x52, 0x78, 0x7c, 0x11, 0x8d, 0x03, 0x4c, 0x44, - 0xf2, 0x4c, 0xe8, 0xbd, 0x82, 0xc1, 0xbb, 0x4f, 0x54, 0xa4, 0xfe, 0x7b, 0x71, 0x10, 0x77, 0x89, - 0x1a, 0x07, 0x35, 0xf0, 0xf7, 0x6f, 0xa4, 0xbd, 0xf4, 0x9f, 0x1b, 0xe4, 0x5b, 0xf2, 0x3c, 0xc5, - 0x65, 0x3f, 0x54, 0x79, 0x35, 0xf4, 0x0d, 0x85, 0x26, 0x27, 0x22, 0x4d, 0x00, 0x34, 0xa5, 0x01, - 0xee, 0x47, 0x5e, 0x44, 0xc3, 0x37, 0x69, 0xb0, 0xe9, 0x98, 0x62, 0x03, 0x74, 0xa6, 0xd7, 0x2d, - 0x4f, 0xb5, 0x01, 0x22, 0xf9, 0x7b, 0x82, 0x06, 0xdf, 0x45, 0xb8, 0x6e, 0x52, 0x3b, 0xb0, 0x82, - 0xed, 0x4a, 0x10, 0x78, 0xd6, 0x7a, 0x27, 0xa0, 0xbe, 0xd0, 0xdb, 0xc9, 0xd4, 0x3a, 0x65, 0x15, - 0xf2, 0xc3, 0x60, 0xcf, 0x73, 0xc6, 0x88, 0xc8, 0x63, 0xb1, 0xff, 0xd8, 0x2d, 0x0f, 0x73, 0x1a, - 0x92, 0x21, 0x16, 0xbf, 0x89, 0x46, 0x6f, 0xde, 0xa8, 0xd4, 0xe8, 0x3d, 0xab, 0x49, 0xc5, 0xe6, - 0xc5, 0x13, 0x91, 0x16, 0x43, 0x44, 0xa4, 0x12, 0xc8, 0x7f, 0x68, 0xdf, 0x31, 0x1a, 0x26, 0xc0, - 0xe5, 0xfc, 0x87, 0x88, 0x98, 0xf5, 0x16, 0x9e, 0x49, 0x21, 0xa2, 0x0b, 0x51, 0x6f, 0x51, 0xf3, - 0x2b, 0x92, 0xba, 0xe2, 0xd8, 0x44, 0x6f, 0x29, 0xee, 0xa1, 0xb7, 0xfc, 0x65, 0x0e, 0x4d, 0x11, - 0xea, 0x3b, 0x1d, 0x2f, 0xfe, 0x02, 0x7c, 0x0e, 0x0d, 0x4a, 0x9b, 0xf4, 0x10, 0x35, 0x49, 0xec, - 0x0c, 0x03, 0x1e, 0xaf, 0xa2, 0x91, 0x85, 0xfb, 0xae, 0xe5, 0x51, 0x5f, 0xf4, 0x91, 0x9d, 0x56, - 0x88, 0x4f, 0x89, 0x15, 0xe2, 0x34, 0xe5, 0x2c, 0xa9, 0xc5, 0x21, 0x07, 0x43, 0x46, 0x89, 0x6b, - 0x1a, 0x01, 0x35, 0xe7, 0xb7, 0x85, 0xef, 0xcf, 0x33, 0x4a, 0x38, 0xb0, 0xb1, 0xbe, 0xad, 0x64, - 0x94, 0x84, 0xa4, 0xf8, 0x2c, 0x2a, 0xac, 0xad, 0x2d, 0x89, 0xce, 0x03, 0x89, 0x76, 0x41, 0x20, - 0xa7, 0xcc, 0x30, 0xac, 0xfe, 0xe5, 0x3c, 0x42, 0xac, 0x8f, 0x56, 0x3d, 0x6a, 0x04, 0xfb, 0x63, - 0x68, 0xe6, 0x51, 0x31, 0x54, 0xb8, 0x18, 0x1f, 0x5a, 0xc8, 0x9b, 0x6c, 0x88, 0xe4, 0xb3, 0x43, - 0x3c, 0x73, 0xe6, 0x88, 0xd3, 0xa2, 0x3c, 0x59, 0x44, 0xe4, 0x1c, 0x7a, 0x0c, 0x40, 0x38, 0x1c, - 0x3f, 0x87, 0x46, 0x45, 0x23, 0x3b, 0x61, 0x24, 0x9b, 0x2f, 0xf9, 0x42, 0x20, 0x89, 0xf1, 0xfa, - 0x77, 0x72, 0x5c, 0x29, 0x35, 0xda, 0xa2, 0x07, 0x57, 0x29, 0xfa, 0x17, 0x73, 0x08, 0x33, 0x61, - 0x2b, 0x86, 0xef, 0x6f, 0x39, 0x9e, 0x59, 0xdd, 0x34, 0xec, 0x8d, 0x7d, 0xf9, 0x1c, 0xfd, 0x6f, - 0x86, 0xd0, 0x31, 0x65, 0x57, 0xf9, 0x80, 0xf7, 0xb7, 0x0b, 0x6a, 0x7f, 0x83, 0xc5, 0x3b, 0xf4, - 0x37, 0x79, 0xf1, 0xce, 0x7b, 0xde, 0x47, 0xd0, 0xa8, 0xf8, 0xe6, 0x7a, 0x4d, 0xf4, 0x3c, 0x98, - 0xf6, 0x2d, 0x93, 0xc4, 0x08, 0xfc, 0x3c, 0x1a, 0x13, 0x3f, 0x98, 0xf5, 0x0f, 0xe3, 0xb3, 0xd0, - 0x8f, 0x7d, 0x06, 0x20, 0x0a, 0x1a, 0xbf, 0x80, 0x46, 0x59, 0xe7, 0xdc, 0x80, 0x2c, 0xcd, 0x91, - 0x38, 0x99, 0xd1, 0x0c, 0x81, 0xb2, 0x49, 0x88, 0x28, 0xd9, 0x94, 0x22, 0xf6, 0x1a, 0x8a, 0xf1, - 0x94, 0xc2, 0xf7, 0x1a, 0xe4, 0x29, 0x45, 0xec, 0x3a, 0xbc, 0x83, 0x4a, 0x15, 0xdb, 0x76, 0x78, - 0xb6, 0xb0, 0x2f, 0x02, 0x6a, 0x7d, 0xe7, 0x92, 0xb3, 0x90, 0x62, 0x17, 0xd3, 0x67, 0x4e, 0x26, - 0xb2, 0x40, 0x7c, 0x99, 0x35, 0xc4, 0x3d, 0x8b, 0x6e, 0x51, 0x4f, 0xa4, 0x2c, 0x40, 0x50, 0xd1, - 0x13, 0x30, 0x39, 0xe1, 0x2e, 0xa4, 0xc3, 0xf3, 0x68, 0x7c, 0xc5, 0x73, 0x5c, 0xc7, 0xa7, 0x26, - 0x57, 0x54, 0x09, 0x18, 0x4f, 0xf7, 0xba, 0x65, 0xcd, 0x15, 0x88, 0x06, 0x68, 0x4c, 0x62, 0x57, - 0x59, 0xf0, 0x1d, 0x34, 0x23, 0x94, 0x49, 0xcd, 0xb0, 0x45, 0xeb, 0x35, 0x5f, 0x1b, 0x83, 0x44, - 0x33, 0x9c, 0xec, 0x0c, 0xf5, 0xda, 0xfc, 0x99, 0x30, 0x98, 0xe7, 0x09, 0x58, 0xc3, 0x32, 0xe5, - 0xa6, 0xce, 0x94, 0xa7, 0x6f, 0xb1, 0x05, 0x64, 0xf8, 0x13, 0x3f, 0xaf, 0x66, 0x1a, 0xe7, 0xe2, - 0x60, 0x92, 0xc8, 0xd8, 0x53, 0x52, 0x8b, 0xd9, 0xe2, 0xf5, 0x0d, 0xcb, 0x36, 0x45, 0x74, 0x08, - 0x16, 0xaf, 0x77, 0x2d, 0xdb, 0x24, 0x00, 0x65, 0x58, 0x29, 0xfd, 0x0a, 0xb0, 0x6c, 0x42, 0xe2, - 0xd3, 0x90, 0xfe, 0xf5, 0x5c, 0x62, 0xb4, 0xed, 0xa3, 0x21, 0x53, 0xba, 0x7f, 0xa1, 0x4f, 0xf7, - 0xd7, 0xbf, 0x92, 0x47, 0x25, 0xb6, 0x20, 0xbb, 0xe1, 0x78, 0x5b, 0x86, 0xb7, 0x3f, 0x51, 0xaa, - 0xc7, 0xb6, 0x69, 0x25, 0xf9, 0x7b, 0x83, 0xbb, 0xf0, 0xf7, 0x4e, 0xa3, 0x41, 0x69, 0x9f, 0x95, - 0x47, 0x8d, 0xd8, 0xa2, 0x16, 0xa0, 0xfa, 0x7f, 0xc8, 0x23, 0xf4, 0x99, 0x4b, 0x97, 0x0e, 0xb1, - 0x82, 0xf4, 0xff, 0x93, 0x43, 0x93, 0x22, 0x8c, 0x29, 0xa5, 0xdb, 0x8f, 0x84, 0x01, 0x68, 0x79, - 0x44, 0x71, 0x10, 0x09, 0x71, 0xcc, 0xd4, 0x2c, 0xdc, 0xb7, 0x02, 0x88, 0xe4, 0x48, 0xf9, 0xf6, - 0x54, 0xc0, 0x64, 0x53, 0x13, 0xd2, 0xe1, 0xe7, 0xc3, 0x00, 0x6d, 0x21, 0xb6, 0xaf, 0x8c, 0x61, - 0x21, 0x33, 0x48, 0xab, 0x7f, 0x63, 0x10, 0x0d, 0x2e, 0xdc, 0xa7, 0xcd, 0x03, 0xde, 0x34, 0xd2, - 0xb2, 0x6f, 0x70, 0x8f, 0xcb, 0xbe, 0x47, 0xd9, 0x71, 0x7a, 0x2d, 0x6e, 0xcf, 0x61, 0xf5, 0xf1, - 0x89, 0x96, 0x4f, 0x3e, 0x3e, 0x6c, 0xe9, 0x83, 0xb7, 0x61, 0xf9, 0x5b, 0x05, 0x54, 0x58, 0xad, - 0xae, 0x1c, 0xf5, 0x9b, 0x7d, 0xed, 0x37, 0x3b, 0x47, 0xf4, 0xf5, 0x28, 0x48, 0x57, 0x8c, 0x93, - 0x34, 0x12, 0xf1, 0xb8, 0x2f, 0xe5, 0xd1, 0xe8, 0x6a, 0x67, 0xdd, 0xdf, 0xf6, 0x03, 0xda, 0x3e, - 0xe0, 0xad, 0x19, 0xfa, 0x17, 0x83, 0x59, 0xfe, 0x05, 0x3e, 0x1b, 0x5a, 0x46, 0x69, 0x21, 0x15, - 0x59, 0xc6, 0xd0, 0x1e, 0xfe, 0x52, 0x1e, 0x4d, 0xf1, 0xd5, 0x79, 0xcd, 0xf2, 0x9b, 0x8f, 0x21, - 0x25, 0x65, 0xff, 0xb5, 0xb2, 0xb7, 0x88, 0xd6, 0x43, 0x24, 0xfa, 0xe8, 0xff, 0x31, 0x8f, 0x4a, - 0x95, 0x4e, 0xb0, 0x59, 0x09, 0x60, 0x72, 0x39, 0x94, 0xd3, 0xfc, 0xef, 0xe4, 0xd0, 0x24, 0x7b, - 0x91, 0x35, 0xe7, 0x2e, 0xb5, 0x1f, 0xc3, 0x3a, 0x51, 0x5e, 0xef, 0xe5, 0x1f, 0x71, 0xbd, 0x17, - 0xea, 0xb2, 0xb0, 0xcb, 0x75, 0xef, 0x77, 0x72, 0x08, 0xb1, 0x65, 0xe0, 0x87, 0xe4, 0x33, 0x1e, - 0xc3, 0x3a, 0x62, 0x3f, 0x3f, 0xe3, 0x7b, 0x39, 0x34, 0xb3, 0xe6, 0xb1, 0x89, 0xdc, 0x14, 0xf3, - 0xf9, 0x01, 0x6f, 0x97, 0xf4, 0x07, 0x1d, 0xf0, 0x16, 0xfa, 0x41, 0x0e, 0x3d, 0xa1, 0x7e, 0xd0, - 0x87, 0xc1, 0x0a, 0xfc, 0x7e, 0x0e, 0x1d, 0x7f, 0x1d, 0xce, 0x60, 0x47, 0x31, 0xc6, 0x0f, 0xdf, - 0x17, 0x1d, 0xf0, 0x9e, 0xf7, 0xdd, 0x1c, 0x3a, 0xb6, 0x5c, 0xaf, 0x55, 0x3f, 0x2c, 0x2d, 0x94, - 0xfa, 0x9e, 0x0f, 0x41, 0xfb, 0xac, 0x56, 0x6e, 0x2e, 0x7d, 0x98, 0xda, 0x47, 0xf9, 0x9e, 0x03, - 0xde, 0x3e, 0xff, 0x69, 0x18, 0x95, 0xd8, 0xba, 0x56, 0xc4, 0xf4, 0x0e, 0xb5, 0xa7, 0x7f, 0x19, - 0x95, 0x84, 0x1a, 0x60, 0x49, 0x29, 0x1d, 0x9c, 0x10, 0x05, 0x0c, 0x1a, 0xb0, 0xb4, 0x94, 0x89, - 0xd8, 0x8a, 0xeb, 0x2d, 0xea, 0xad, 0xcb, 0xc9, 0x4a, 0xf7, 0xa8, 0xb7, 0x4e, 0x00, 0x8a, 0x97, - 0xe2, 0x4d, 0xc9, 0xca, 0x4a, 0x1d, 0x4e, 0x4b, 0x8b, 0x95, 0x2a, 0x1c, 0xff, 0x8e, 0xc2, 0xd2, - 0x86, 0x6b, 0xf1, 0x73, 0xd6, 0x72, 0xa2, 0x64, 0x92, 0x13, 0xdf, 0x42, 0xd3, 0x21, 0x2c, 0x3e, - 0x2a, 0x5c, 0xcc, 0x10, 0x97, 0x75, 0x48, 0x38, 0xcd, 0x8a, 0x5f, 0x43, 0x63, 0x21, 0x10, 0x62, - 0xd6, 0xa3, 0x20, 0xea, 0xc9, 0x5e, 0xb7, 0x7c, 0x32, 0x12, 0x75, 0xd7, 0x52, 0x12, 0x41, 0x15, - 0x06, 0x59, 0x00, 0x2c, 0x3b, 0x51, 0x86, 0x80, 0xc4, 0x86, 0xab, 0xc2, 0x80, 0x5f, 0x00, 0x01, - 0xae, 0x63, 0xfb, 0x14, 0x62, 0x7c, 0x25, 0xc8, 0xe4, 0x81, 0x4d, 0x4f, 0x4f, 0xc0, 0x79, 0xbe, - 0x96, 0x42, 0x86, 0x97, 0x11, 0x8a, 0x63, 0x31, 0x22, 0x2b, 0x76, 0xd7, 0x51, 0x22, 0x49, 0x84, - 0xfe, 0x07, 0x6c, 0xfd, 0xe6, 0xba, 0x51, 0x4f, 0x7e, 0x1e, 0x0d, 0x57, 0x5c, 0xf7, 0x36, 0xa9, - 0x8b, 0xe8, 0x24, 0x24, 0x6d, 0x1a, 0xae, 0xdb, 0xe8, 0x78, 0x96, 0xbc, 0xe3, 0xc2, 0x89, 0x70, - 0x15, 0x8d, 0x57, 0x5c, 0x77, 0xa5, 0xb3, 0xde, 0xb2, 0x9a, 0x52, 0xf5, 0x02, 0x5e, 0x02, 0xc3, - 0x75, 0x1b, 0x2e, 0x60, 0x92, 0xb5, 0x1f, 0x54, 0x1e, 0xfc, 0x0e, 0x1a, 0xad, 0xb8, 0xae, 0x38, - 0x3c, 0x5f, 0x80, 0x3d, 0x0d, 0x3d, 0xfc, 0x26, 0xe9, 0xdd, 0x66, 0x23, 0x22, 0x7e, 0x4e, 0xfe, - 0xb4, 0xd8, 0xe3, 0x98, 0x61, 0x0f, 0x4a, 0x1d, 0x92, 0x8f, 0x45, 0xe2, 0x8f, 0xa3, 0x91, 0x8a, - 0xeb, 0x4a, 0xe1, 0x01, 0x08, 0xa5, 0x32, 0xae, 0x44, 0x13, 0x85, 0x64, 0xa7, 0x5e, 0x41, 0x13, - 0xea, 0xc3, 0x76, 0x75, 0x90, 0xfe, 0xa7, 0x39, 0xf8, 0xa0, 0x03, 0xbe, 0x63, 0x78, 0x05, 0x15, - 0x2a, 0xae, 0x2b, 0xcc, 0xc9, 0xb1, 0x8c, 0xf6, 0x48, 0xa6, 0xc5, 0x55, 0x5c, 0x37, 0xfc, 0x74, - 0xbe, 0xa7, 0x7f, 0xb8, 0x3e, 0xfd, 0xdb, 0xfc, 0xd3, 0x0f, 0xf8, 0x16, 0xfc, 0x37, 0x0a, 0x68, - 0xb2, 0xe2, 0xba, 0x47, 0xf5, 0x01, 0x1e, 0x57, 0xf2, 0xdd, 0x25, 0x84, 0x24, 0xf3, 0x38, 0x12, - 0xe5, 0xb6, 0x94, 0x24, 0xd3, 0xa8, 0xe5, 0x88, 0x44, 0x14, 0x76, 0xbf, 0xe2, 0xae, 0xba, 0xdf, - 0x6f, 0x28, 0x0d, 0x07, 0x67, 0x9d, 0x8f, 0x1a, 0x6e, 0x68, 0x4f, 0x1e, 0xd5, 0x84, 0xac, 0x4c, - 0x91, 0x59, 0x2f, 0x52, 0x10, 0xc2, 0x73, 0x1e, 0x4d, 0x86, 0x6a, 0x58, 0x26, 0x49, 0xd0, 0x86, - 0x6d, 0x38, 0xb2, 0xab, 0x36, 0xfc, 0x6a, 0x1e, 0x4d, 0xc7, 0x6d, 0xf8, 0x38, 0x1c, 0xd3, 0x39, - 0x84, 0x78, 0x90, 0x32, 0xda, 0x48, 0x1c, 0xe7, 0x29, 0xe1, 0x3e, 0x40, 0x45, 0x4a, 0x78, 0x4c, - 0x12, 0xed, 0x2a, 0x14, 0x32, 0x77, 0x15, 0x2e, 0xa0, 0x22, 0x31, 0xb6, 0xde, 0xec, 0x50, 0x6f, - 0x5b, 0x4c, 0xa5, 0x10, 0x4a, 0xf7, 0x8c, 0xad, 0xc6, 0xe7, 0x19, 0x90, 0x44, 0x68, 0xac, 0x47, - 0xc9, 0x80, 0x52, 0xf0, 0x98, 0x27, 0x03, 0x46, 0x29, 0x80, 0x42, 0x49, 0xc3, 0xbb, 0x52, 0xd2, - 0x0f, 0x86, 0xd1, 0x54, 0xcd, 0x08, 0x8c, 0x75, 0xc3, 0xa7, 0xd2, 0x42, 0x62, 0x32, 0x84, 0xb1, - 0x8e, 0x60, 0x45, 0x15, 0xb3, 0x20, 0xf1, 0xcc, 0x5c, 0x6f, 0xf8, 0x1c, 0x2a, 0x17, 0x06, 0x4a, - 0x30, 0xe0, 0x4f, 0xc6, 0x72, 0xa3, 0x9a, 0x4a, 0xdc, 0x9d, 0x01, 0x8d, 0x99, 0xeb, 0x0d, 0x57, - 0x80, 0x49, 0x8a, 0x10, 0x5f, 0x44, 0xa5, 0x10, 0xc6, 0x9c, 0xa7, 0x42, 0xfc, 0xcd, 0xe6, 0x3a, - 0xf3, 0x9d, 0x88, 0x8c, 0xc6, 0x2f, 0xa1, 0xb1, 0xf0, 0xa7, 0xe4, 0x96, 0x80, 0xaf, 0x65, 0xae, - 0xa7, 0x1c, 0x47, 0x99, 0x54, 0x66, 0x85, 0xf1, 0x39, 0xa4, 0xb0, 0x26, 0xea, 0xa9, 0x29, 0xa4, - 0xf8, 0xf3, 0x68, 0x22, 0xfc, 0x2d, 0x9c, 0xad, 0x61, 0x70, 0xb6, 0x2e, 0x86, 0x9a, 0x4f, 0xaa, - 0x75, 0x56, 0x25, 0xe7, 0x6e, 0xd7, 0x93, 0xc2, 0xed, 0x3a, 0x66, 0xae, 0xa7, 0xbd, 0xae, 0xc4, - 0x03, 0x70, 0x1d, 0x4d, 0x87, 0x90, 0xca, 0xdb, 0xab, 0x84, 0x6e, 0xb0, 0x51, 0x39, 0x12, 0x3b, - 0xcb, 0xe6, 0x7a, 0x03, 0x2a, 0xad, 0x01, 0x42, 0xf6, 0xd9, 0x53, 0x5c, 0xb8, 0x85, 0x4e, 0x2b, - 0x40, 0xd3, 0xdf, 0xb4, 0xee, 0x04, 0xc2, 0xd3, 0xad, 0xd7, 0xc4, 0x72, 0x00, 0x8a, 0xee, 0x44, - 0x52, 0x39, 0x4d, 0x58, 0x61, 0xaa, 0xa1, 0x94, 0xed, 0xdb, 0x51, 0x1a, 0x5e, 0x45, 0x33, 0x21, - 0xfe, 0xf5, 0xea, 0xca, 0x8a, 0xe7, 0xbc, 0x4b, 0x9b, 0x41, 0xbd, 0x26, 0x56, 0x0a, 0x70, 0xd6, - 0xcb, 0x5c, 0x6f, 0x6c, 0x34, 0x5d, 0xd6, 0x29, 0x18, 0x4e, 0x15, 0x9e, 0xc9, 0x8c, 0xdf, 0x42, - 0xc7, 0x25, 0x78, 0xdd, 0xf6, 0x03, 0xc3, 0x6e, 0xd2, 0x7a, 0x4d, 0x2c, 0x1f, 0x60, 0x29, 0x23, - 0xa4, 0x5a, 0x02, 0xa9, 0x8a, 0xcd, 0x66, 0x3f, 0x55, 0x41, 0xc7, 0x32, 0x5a, 0x6a, 0x57, 0x3e, - 0xeb, 0x97, 0xf2, 0x71, 0xe7, 0x38, 0xe0, 0x8e, 0xeb, 0x3c, 0x2a, 0x86, 0x5f, 0x22, 0xa6, 0x10, - 0xad, 0x5f, 0x07, 0x4f, 0xca, 0x08, 0xf1, 0x8a, 0x3a, 0x0e, 0xb8, 0x33, 0xfb, 0x38, 0xd4, 0xf1, - 0x7e, 0x2e, 0x56, 0xc7, 0x01, 0x77, 0x70, 0xbf, 0x5b, 0x88, 0x47, 0xf6, 0x91, 0x97, 0xfb, 0xb8, - 0x9c, 0xa5, 0x78, 0xe3, 0x74, 0x78, 0x17, 0x09, 0x64, 0x72, 0xd7, 0x1c, 0x79, 0xc4, 0xae, 0xf9, - 0xc3, 0x74, 0x7b, 0x72, 0x07, 0xe4, 0x40, 0xb6, 0xe7, 0x63, 0x18, 0xac, 0xf8, 0x32, 0x1a, 0x0f, - 0xff, 0xe7, 0x9e, 0xda, 0x90, 0x74, 0xf0, 0x6c, 0x5d, 0x38, 0x6a, 0x2a, 0x09, 0xfe, 0x2c, 0x3a, - 0xa9, 0x00, 0x56, 0x0c, 0xcf, 0x68, 0xd3, 0x80, 0x7a, 0xdc, 0x47, 0x10, 0x75, 0xfe, 0x42, 0xee, - 0x86, 0x1b, 0xa1, 0xe5, 0x52, 0x79, 0x7d, 0x24, 0x48, 0x9d, 0x63, 0x64, 0x17, 0xbb, 0xea, 0x7f, - 0x9e, 0x47, 0xe3, 0x2b, 0x8e, 0x1f, 0x6c, 0x78, 0xd4, 0x5f, 0x31, 0x3c, 0x9f, 0x1e, 0xde, 0x16, - 0x7d, 0x11, 0x8d, 0x43, 0x22, 0x70, 0x9b, 0xda, 0x81, 0x54, 0x00, 0x90, 0x17, 0xc3, 0x08, 0x11, - 0xe0, 0x36, 0x12, 0x95, 0x10, 0x97, 0xd1, 0x10, 0xef, 0x03, 0x52, 0x7a, 0x36, 0xef, 0x00, 0x1c, - 0xae, 0x7f, 0xb5, 0x80, 0xc6, 0x42, 0x2d, 0xcf, 0x5b, 0x07, 0xf5, 0xb8, 0xf5, 0xfe, 0x2a, 0x79, - 0x0e, 0xa1, 0x15, 0xc7, 0x0b, 0x8c, 0x96, 0x54, 0x91, 0x19, 0x96, 0x0c, 0x2e, 0x40, 0x39, 0x8f, - 0x44, 0x82, 0x67, 0x11, 0x92, 0x06, 0xd8, 0x08, 0x0c, 0xb0, 0x89, 0x5e, 0xb7, 0x8c, 0xe2, 0x71, - 0x45, 0x24, 0x0a, 0xfd, 0xd7, 0xf2, 0x68, 0x32, 0x6c, 0xa4, 0x85, 0xfb, 0xb4, 0xd9, 0x09, 0x0e, - 0xf1, 0x60, 0x50, 0xb5, 0x3d, 0xf4, 0x40, 0x6d, 0xeb, 0x7f, 0x2b, 0x19, 0x92, 0x6a, 0xcb, 0x39, - 0x32, 0x24, 0xff, 0x1a, 0x7d, 0x5c, 0xff, 0x42, 0x01, 0xcd, 0x84, 0x5a, 0xbf, 0xd1, 0xb1, 0xc1, - 0x4d, 0xa8, 0x1a, 0xad, 0xd6, 0x61, 0x9e, 0x97, 0x4b, 0xa1, 0x22, 0x96, 0xc5, 0xc9, 0x9a, 0x71, - 0xbe, 0xc9, 0x76, 0x47, 0x80, 0x1b, 0x8e, 0x65, 0x12, 0x99, 0x08, 0xbf, 0x86, 0xc6, 0xc2, 0x9f, - 0x15, 0x6f, 0x23, 0x9c, 0x8c, 0x61, 0xe9, 0x1c, 0x31, 0x19, 0xde, 0x86, 0x52, 0xeb, 0x5a, 0x66, - 0xd0, 0xbf, 0x32, 0x8c, 0x4e, 0xbd, 0x6d, 0xd9, 0xa6, 0xb3, 0xe5, 0x8b, 0xaa, 0x67, 0x07, 0xdf, - 0xe9, 0x7d, 0x7c, 0xc5, 0x86, 0x62, 0xcf, 0x64, 0x68, 0x17, 0x6e, 0xeb, 0x9b, 0xe8, 0x78, 0x52, - 0xa5, 0x5e, 0x74, 0xb0, 0x54, 0xb4, 0xce, 0x16, 0x27, 0x68, 0x84, 0x85, 0xe7, 0x44, 0xfc, 0x89, - 0x64, 0x73, 0x26, 0x2b, 0xd7, 0x8d, 0x3c, 0x4c, 0xe5, 0xba, 0x8f, 0xa1, 0xe1, 0x9a, 0xd3, 0x36, - 0xac, 0x30, 0xc5, 0x17, 0x46, 0x71, 0xf4, 0x5c, 0xc0, 0x10, 0x41, 0xc1, 0xe4, 0x8b, 0x07, 0x43, - 0x93, 0x8d, 0xc6, 0xf2, 0x43, 0x86, 0x8e, 0x4f, 0x3d, 0x22, 0x13, 0x61, 0x07, 0x8d, 0x8b, 0xc7, - 0x89, 0x68, 0x11, 0x82, 0x68, 0xd1, 0x0b, 0xa1, 0x8e, 0xfa, 0x77, 0xab, 0x59, 0x85, 0x8f, 0x87, - 0x8d, 0xe0, 0xed, 0xc2, 0x8f, 0xe1, 0x71, 0x23, 0xa2, 0xca, 0x97, 0x94, 0x00, 0x46, 0xa6, 0x94, - 0x56, 0x02, 0x58, 0x19, 0x99, 0xe8, 0xd4, 0x75, 0x84, 0xd3, 0x0f, 0xdb, 0x55, 0xe4, 0xe3, 0xbf, - 0xe7, 0x11, 0x4e, 0x2c, 0x20, 0x16, 0x0e, 0xb1, 0x1f, 0xa4, 0xff, 0x7c, 0x0e, 0x4d, 0xa7, 0x8e, - 0x44, 0xe3, 0x2b, 0x08, 0x71, 0x88, 0x74, 0x16, 0x0c, 0x0e, 0x11, 0xc6, 0xc7, 0xa4, 0xc5, 0x1c, - 0x10, 0x93, 0xe1, 0x39, 0x54, 0xe4, 0xbf, 0xa2, 0x4b, 0x08, 0x92, 0x2c, 0x9d, 0x8e, 0x65, 0x92, - 0x88, 0x28, 0x7e, 0x0a, 0x5c, 0xc7, 0x51, 0xc8, 0x64, 0x09, 0xb6, 0xdd, 0xe8, 0x29, 0x8c, 0x4c, - 0xff, 0x76, 0x0e, 0x8d, 0x45, 0x2f, 0x5c, 0x31, 0xf7, 0xab, 0xe9, 0x86, 0xc5, 0xe9, 0xf2, 0xc2, - 0x83, 0x4e, 0x97, 0x27, 0x8c, 0x0a, 0xc7, 0xea, 0xbf, 0x9d, 0x43, 0x93, 0x11, 0xed, 0x3e, 0xc6, - 0x58, 0xf6, 0xfc, 0x21, 0xff, 0x23, 0x87, 0xb4, 0x79, 0xab, 0xd5, 0xb2, 0xec, 0x8d, 0xba, 0x7d, - 0xc7, 0xf1, 0xda, 0x70, 0x78, 0x72, 0xff, 0x82, 0x68, 0xfa, 0x7f, 0xcd, 0xa1, 0x69, 0xf1, 0x42, - 0x55, 0xc3, 0x33, 0xf7, 0x2f, 0xba, 0x99, 0x7c, 0x93, 0xfd, 0x6b, 0x65, 0xc8, 0x8f, 0x5e, 0x72, - 0x9a, 0x77, 0x3f, 0x04, 0x69, 0xde, 0xec, 0x33, 0x0e, 0x78, 0x2a, 0xda, 0x7f, 0xcb, 0xa1, 0x19, - 0x42, 0x9b, 0xce, 0x3d, 0xea, 0x6d, 0x57, 0x1d, 0x93, 0xbe, 0x4e, 0x6d, 0xea, 0xed, 0x57, 0x27, - 0xfd, 0x75, 0xa8, 0x27, 0x11, 0xbf, 0xcc, 0x6d, 0x9f, 0x9a, 0x07, 0xa7, 0x08, 0x89, 0xfe, 0xcb, - 0x23, 0x48, 0xcb, 0xf4, 0x4c, 0x0e, 0xec, 0xa4, 0xde, 0xd7, 0xdd, 0x1c, 0x7c, 0x5c, 0xee, 0xe6, - 0xd0, 0xee, 0xdc, 0xcd, 0xe1, 0xdd, 0xba, 0x9b, 0x23, 0x0f, 0xe3, 0x6e, 0xb6, 0x93, 0xee, 0x66, - 0x11, 0xdc, 0xcd, 0x2b, 0x3b, 0xba, 0x9b, 0x0b, 0xb6, 0xf9, 0x88, 0xce, 0xe6, 0x81, 0x2d, 0xbd, - 0xf9, 0x08, 0x5e, 0x32, 0x3e, 0xcf, 0x8c, 0x5b, 0xd3, 0xf1, 0x4c, 0xca, 0x4b, 0x69, 0x16, 0x79, - 0x34, 0xd8, 0x13, 0x30, 0x12, 0x61, 0x53, 0x75, 0x4c, 0xc7, 0x1f, 0xa6, 0x8e, 0xe9, 0x63, 0xf0, - 0xc2, 0xbf, 0x97, 0x43, 0xd3, 0x55, 0xea, 0x05, 0xd6, 0x1d, 0xab, 0x69, 0x04, 0x8f, 0x63, 0x0b, - 0xb2, 0x82, 0x26, 0x25, 0x81, 0xd2, 0xfd, 0x6e, 0x70, 0x2e, 0xba, 0x49, 0xbd, 0x00, 0x5c, 0x49, - 0x39, 0x23, 0x20, 0x41, 0xcf, 0x1e, 0x1f, 0xd6, 0x12, 0x12, 0x63, 0x37, 0x7a, 0x7c, 0x08, 0xe7, - 0x8a, 0xb4, 0xc4, 0x2f, 0x12, 0xd1, 0xeb, 0x5f, 0xcb, 0xa1, 0x73, 0x84, 0xda, 0x74, 0xcb, 0x58, - 0x6f, 0x51, 0x49, 0xb0, 0xb0, 0xed, 0x6c, 0xdc, 0x5b, 0x7e, 0xdb, 0x08, 0x9a, 0x9b, 0x7b, 0xfa, - 0xca, 0x1b, 0xea, 0x1d, 0x6b, 0xbb, 0xb0, 0x4e, 0x0a, 0x9f, 0xfe, 0xc3, 0x1c, 0x1a, 0xb9, 0x6d, - 0xdf, 0xb5, 0x9d, 0xad, 0xbd, 0x55, 0x9c, 0xba, 0x82, 0x4a, 0x42, 0x8c, 0xa4, 0x71, 0x7e, 0x69, - 0x1e, 0x07, 0x37, 0xf8, 0xcd, 0x7a, 0x32, 0x15, 0x7e, 0x25, 0x62, 0x82, 0x34, 0x15, 0xe9, 0x12, - 0xb7, 0x90, 0x29, 0x71, 0x99, 0x9e, 0x4c, 0x8e, 0x4f, 0x8b, 0xcb, 0x1c, 0xa4, 0xa3, 0x9f, 0xec, - 0x55, 0xf8, 0x5d, 0x0e, 0xfa, 0x5f, 0x5f, 0x42, 0x43, 0xcb, 0x36, 0x5d, 0xbe, 0x83, 0x2f, 0x49, - 0x55, 0xb5, 0xc4, 0x77, 0x4d, 0xcb, 0x7a, 0x02, 0xc4, 0xe2, 0x00, 0x91, 0x6a, 0x6f, 0x5d, 0x95, - 0x6b, 0x0d, 0x09, 0xdd, 0x62, 0x99, 0x87, 0x63, 0x16, 0x07, 0x88, 0x5c, 0x93, 0xe8, 0xaa, 0x5c, - 0x8c, 0x47, 0x74, 0x1c, 0x85, 0x8b, 0x63, 0x42, 0x2e, 0xe1, 0xbc, 0x2c, 0x65, 0xd5, 0xbe, 0x49, - 0x46, 0x37, 0xd2, 0x14, 0x8b, 0x03, 0x24, 0xbb, 0x66, 0x8e, 0x72, 0xc7, 0x8f, 0x88, 0x6f, 0xcc, - 0x24, 0xa6, 0x1e, 0xc0, 0x2d, 0x0e, 0x10, 0xf5, 0x3e, 0xa0, 0x6b, 0xca, 0xed, 0x29, 0xc9, 0xf4, - 0x1c, 0x09, 0xb5, 0x38, 0x40, 0x12, 0xf7, 0xac, 0x28, 0x57, 0x79, 0x88, 0xed, 0x9e, 0xe4, 0x43, - 0x01, 0x27, 0x3d, 0x94, 0x5f, 0xfb, 0xf1, 0x6a, 0xa2, 0xc4, 0xbe, 0x48, 0x7f, 0x3b, 0x9e, 0x60, - 0xe6, 0xc8, 0xc5, 0x01, 0x92, 0x28, 0xc8, 0x7f, 0x3e, 0xac, 0xba, 0x2e, 0x6c, 0xf9, 0x84, 0xe4, - 0xbc, 0x59, 0xef, 0x31, 0x2d, 0x85, 0x55, 0xd9, 0xaf, 0xca, 0xd5, 0xb6, 0x85, 0x71, 0xc6, 0x89, - 0xa7, 0x2c, 0xd8, 0x26, 0x6b, 0x1d, 0xc9, 0x73, 0xb8, 0x9e, 0xac, 0x4b, 0x2b, 0xaa, 0x1d, 0x9f, - 0x48, 0x70, 0x0a, 0xec, 0xe2, 0x00, 0x49, 0xd6, 0xb1, 0xbd, 0xa6, 0xd4, 0x44, 0x15, 0xb9, 0xdb, - 0x49, 0xad, 0x32, 0x94, 0xa4, 0x55, 0xa8, 0x9e, 0x7a, 0x3d, 0x59, 0xa4, 0x53, 0x1b, 0xcf, 0x7c, - 0xb4, 0xc0, 0x4a, 0x8f, 0x0e, 0x8b, 0x7a, 0x5e, 0x53, 0x8a, 0x29, 0x42, 0xbd, 0xe2, 0x8c, 0x47, - 0x1b, 0x81, 0x21, 0x3f, 0x9a, 0x97, 0x5d, 0x54, 0xca, 0xfa, 0x69, 0x93, 0x99, 0x0d, 0x0a, 0x38, - 0xa9, 0x41, 0x79, 0x09, 0xc0, 0x6b, 0x4a, 0x81, 0x14, 0x6d, 0x4a, 0x7d, 0xa8, 0x84, 0x62, 0x0f, - 0x95, 0x4b, 0xa9, 0x5c, 0x95, 0xeb, 0x86, 0x68, 0xd3, 0x6a, 0x03, 0xc5, 0x18, 0xd6, 0x40, 0x52, - 0x7d, 0x91, 0x32, 0xd4, 0x24, 0xd0, 0x30, 0x90, 0x97, 0xa2, 0x37, 0xac, 0xae, 0x2c, 0x0e, 0x10, - 0xa8, 0x56, 0xa0, 0xf3, 0x6a, 0x17, 0xda, 0x31, 0xa0, 0x18, 0x8b, 0x8a, 0x56, 0xde, 0xa7, 0xcd, - 0xc5, 0x01, 0xc2, 0x2b, 0x61, 0x5c, 0x92, 0x0e, 0xc4, 0x6b, 0x33, 0xaa, 0x89, 0x88, 0x10, 0xcc, - 0x44, 0xc4, 0xc7, 0xe6, 0x6f, 0xa4, 0x0f, 0x8d, 0x6b, 0xc7, 0xd5, 0xf5, 0x43, 0x12, 0xbf, 0x38, - 0x40, 0xd2, 0x07, 0xcd, 0xaf, 0x29, 0xe7, 0xa8, 0xb5, 0x13, 0x89, 0x9c, 0xb8, 0x18, 0xc5, 0xd4, - 0x25, 0x9f, 0xb8, 0x5e, 0xce, 0x2c, 0x54, 0xa5, 0x9d, 0x04, 0x01, 0x4f, 0x46, 0x02, 0xd2, 0x24, - 0x8b, 0x03, 0x24, 0xb3, 0xc4, 0x55, 0x35, 0x75, 0x9a, 0x59, 0xd3, 0x54, 0xc7, 0x35, 0x81, 0x5e, - 0x1c, 0x20, 0xa9, 0xf3, 0xcf, 0x57, 0xe5, 0x63, 0xc4, 0xda, 0x13, 0x6a, 0x23, 0xc6, 0x18, 0xd6, - 0x88, 0xd2, 0x71, 0xe3, 0xab, 0xf2, 0xa9, 0x5d, 0xed, 0x54, 0x9a, 0x2b, 0xb6, 0x9c, 0xd2, 0xe9, - 0x5e, 0x92, 0x7d, 0x48, 0x56, 0x7b, 0x12, 0xf8, 0x4f, 0x87, 0xfc, 0x59, 0x34, 0x8b, 0x03, 0x24, - 0xfb, 0x80, 0x2d, 0xc9, 0x3e, 0xa7, 0xaa, 0x9d, 0xde, 0x49, 0x66, 0xf4, 0x76, 0xd9, 0x67, 0x5c, - 0x8d, 0x1d, 0x8e, 0x8a, 0x6a, 0x4f, 0xa9, 0x67, 0x39, 0xfa, 0x12, 0x2e, 0x0e, 0x90, 0x1d, 0x0e, - 0x9c, 0xde, 0xee, 0x73, 0x6e, 0x53, 0x3b, 0xa3, 0x56, 0xfd, 0xc8, 0x24, 0x5a, 0x1c, 0x20, 0x7d, - 0x4e, 0x7d, 0xde, 0xee, 0x73, 0x78, 0x52, 0x2b, 0xef, 0x28, 0x36, 0xd2, 0x47, 0x9f, 0xa3, 0x97, - 0xcb, 0x99, 0x27, 0x18, 0xb5, 0xa7, 0xd5, 0xae, 0x9b, 0x41, 0xc2, 0xba, 0x6e, 0xd6, 0xd9, 0xc7, - 0xe5, 0xcc, 0x23, 0x84, 0xda, 0x33, 0x3b, 0x08, 0x8c, 0xde, 0x31, 0xf3, 0xf0, 0xe1, 0x72, 0xe6, - 0x19, 0x3e, 0x4d, 0x57, 0x05, 0x66, 0x90, 0x30, 0x81, 0x59, 0xa7, 0xff, 0x96, 0x33, 0x0f, 0xd1, - 0x69, 0x67, 0x77, 0x10, 0x18, 0xbf, 0x61, 0xd6, 0xf1, 0xbb, 0x6b, 0xca, 0x29, 0x36, 0xed, 0x23, - 0xaa, 0xdd, 0x90, 0x50, 0xcc, 0x6e, 0xc8, 0xe7, 0xdd, 0xaa, 0xa9, 0x44, 0x7f, 0xed, 0xa3, 0xea, - 0x30, 0x4f, 0xa0, 0xd9, 0x30, 0x4f, 0x1e, 0x0d, 0xa8, 0xa6, 0x92, 0xce, 0xb5, 0x73, 0xfd, 0x84, - 0x00, 0x5a, 0x15, 0xc2, 0xd3, 0xd4, 0xeb, 0x19, 0x59, 0xcf, 0xda, 0xb3, 0x6a, 0xf4, 0x31, 0x45, - 0xb0, 0x38, 0x40, 0x32, 0x72, 0xa5, 0x49, 0x76, 0x72, 0x97, 0x76, 0x5e, 0x1d, 0xb6, 0x59, 0x34, - 0x6c, 0xd8, 0x66, 0x26, 0x86, 0x2d, 0x65, 0xed, 0x0f, 0x68, 0x17, 0x54, 0xc7, 0x2c, 0x4d, 0xc1, - 0x1c, 0xb3, 0x8c, 0x7d, 0x05, 0x92, 0x9d, 0xae, 0xa4, 0x7d, 0x6c, 0xc7, 0x37, 0x04, 0x9a, 0x8c, - 0x37, 0xe4, 0xd9, 0x3b, 0xb1, 0xef, 0x74, 0xdb, 0x6d, 0x39, 0x86, 0xa9, 0x3d, 0x97, 0xe9, 0x3b, - 0x71, 0xa4, 0xe4, 0x3b, 0x71, 0x00, 0x9b, 0xe5, 0xe5, 0xf8, 0xb9, 0x76, 0x51, 0x9d, 0xe5, 0x65, - 0x1c, 0x9b, 0xe5, 0x95, 0x58, 0x7b, 0x35, 0x15, 0xb5, 0xd6, 0x9e, 0x57, 0x3b, 0x40, 0x02, 0xcd, - 0x3a, 0x40, 0x32, 0xce, 0xfd, 0x4e, 0xff, 0x88, 0xb1, 0x36, 0x0b, 0xd2, 0x9e, 0x8e, 0xca, 0x72, - 0xf7, 0xa1, 0x5b, 0x1c, 0x20, 0xfd, 0xa3, 0xce, 0xf5, 0x8c, 0x00, 0xb0, 0x36, 0xa7, 0x76, 0xb0, - 0x14, 0x01, 0xeb, 0x60, 0xe9, 0xb0, 0x71, 0x3d, 0x23, 0x82, 0xab, 0x7d, 0xbc, 0xaf, 0xa8, 0xe8, - 0x9b, 0x33, 0xe2, 0xbe, 0x57, 0xe5, 0x10, 0xac, 0x76, 0x49, 0x9d, 0xec, 0x62, 0x0c, 0x9b, 0xec, - 0xa4, 0x50, 0xed, 0x55, 0x39, 0xe2, 0xa9, 0x5d, 0x4e, 0x73, 0xc5, 0x53, 0xa4, 0x14, 0x19, 0x25, - 0xd9, 0x01, 0x46, 0xed, 0x8a, 0xda, 0xeb, 0xb2, 0x68, 0x58, 0xaf, 0xcb, 0x0c, 0x4e, 0xde, 0x48, - 0xc7, 0x09, 0xb5, 0xab, 0xc9, 0xc8, 0xa9, 0x8a, 0x67, 0x9e, 0x4f, 0x2a, 0xb6, 0x78, 0x3d, 0x99, - 0x79, 0xac, 0xbd, 0xa0, 0xfa, 0xb7, 0x2a, 0x96, 0xf9, 0xb7, 0x89, 0x4c, 0xe5, 0xeb, 0xc9, 0x64, - 0x5d, 0xed, 0x13, 0xd9, 0x12, 0xa2, 0xbe, 0x92, 0x4c, 0xee, 0xbd, 0x9e, 0xcc, 0x6f, 0xd5, 0xae, - 0x65, 0x4b, 0x88, 0xb4, 0x9b, 0xcc, 0x87, 0xbd, 0x24, 0x9d, 0xf9, 0xd3, 0x5e, 0x54, 0x5d, 0xc7, - 0x08, 0xc1, 0x5c, 0xc7, 0xf8, 0x64, 0xe0, 0x25, 0xe9, 0xac, 0x9c, 0xf6, 0x52, 0x8a, 0x25, 0x7a, - 0x59, 0xe9, 0x44, 0xdd, 0x25, 0xe9, 0x8c, 0x99, 0xf6, 0x72, 0x8a, 0x25, 0x7a, 0x3b, 0xe9, 0x24, - 0x9a, 0xb9, 0x53, 0x02, 0x80, 0xf6, 0x49, 0x90, 0xa1, 0x3f, 0x78, 0x4f, 0x77, 0x71, 0x80, 0xec, - 0x94, 0x48, 0xf0, 0x4e, 0xff, 0xa8, 0xab, 0xf6, 0x8a, 0x3a, 0x84, 0xfb, 0xd1, 0xb1, 0x21, 0xdc, - 0x37, 0x72, 0xfb, 0x6a, 0x22, 0x19, 0x50, 0x7b, 0x55, 0x35, 0x71, 0x0a, 0x92, 0x99, 0xb8, 0x64, - 0xea, 0xa0, 0x92, 0xe5, 0xa6, 0x7d, 0x4a, 0x35, 0x71, 0x32, 0x8e, 0x99, 0x38, 0x25, 0x23, 0xae, - 0x9a, 0x4a, 0xbe, 0xd2, 0x5e, 0x53, 0x4d, 0x5c, 0x02, 0xcd, 0x4c, 0x5c, 0x32, 0x5d, 0xeb, 0xd5, - 0x44, 0x0e, 0x92, 0x76, 0x3d, 0xfb, 0xfd, 0x01, 0x29, 0xbf, 0x3f, 0xcf, 0x58, 0x22, 0xd9, 0xc9, - 0x34, 0x5a, 0x45, 0x1d, 0xbf, 0x59, 0x34, 0x6c, 0xfc, 0x66, 0x26, 0xe2, 0x2c, 0x67, 0xd6, 0xdc, - 0xd4, 0xe6, 0x77, 0x58, 0x38, 0xc4, 0xae, 0x48, 0x56, 0xb5, 0xce, 0xeb, 0xc9, 0x0b, 0xdd, 0xb4, - 0x6a, 0x9f, 0x35, 0x72, 0xb8, 0x0c, 0x4a, 0x5e, 0x00, 0x57, 0xcf, 0x08, 0x02, 0x6a, 0x35, 0xd5, - 0xba, 0xa6, 0x08, 0x98, 0x75, 0x4d, 0x87, 0x0e, 0x6f, 0xa4, 0xef, 0xd1, 0xd4, 0x16, 0x12, 0x5b, - 0xe2, 0x09, 0x3c, 0xb3, 0x4e, 0xa9, 0xbb, 0x37, 0x49, 0xf6, 0x55, 0x8b, 0xda, 0x8d, 0xc4, 0x7c, - 0x9d, 0x41, 0x03, 0xf3, 0x75, 0xd6, 0x35, 0x8d, 0x9f, 0xed, 0x7b, 0x63, 0xa6, 0xf6, 0x3a, 0x88, - 0x2d, 0xf7, 0x13, 0x2b, 0xc8, 0x16, 0x07, 0x48, 0xdf, 0x3b, 0x37, 0x6f, 0xa3, 0xe3, 0x37, 0xb7, - 0x57, 0xdf, 0x5c, 0x8a, 0xf2, 0xb7, 0x56, 0x3c, 0xea, 0x1a, 0x1e, 0xd5, 0x16, 0x55, 0x5f, 0x3d, - 0x93, 0x88, 0xf9, 0xea, 0x99, 0x88, 0xb4, 0xd8, 0x70, 0x2c, 0xd4, 0x77, 0x12, 0x1b, 0x8f, 0x88, - 0x6c, 0x6e, 0x66, 0x9d, 0x54, 0x04, 0x53, 0xd0, 0x92, 0x63, 0x6f, 0x40, 0xa4, 0xe2, 0xd3, 0xaa, - 0x75, 0xea, 0x4f, 0xc9, 0xac, 0x53, 0x7f, 0x2c, 0xeb, 0xea, 0x2a, 0x96, 0x8f, 0xc1, 0x37, 0xd4, - 0xae, 0x9e, 0x41, 0xc2, 0xba, 0x7a, 0x06, 0x38, 0x2d, 0x90, 0x50, 0x9f, 0x06, 0xda, 0xd2, 0x4e, - 0x02, 0x81, 0x24, 0x2d, 0x10, 0xc0, 0x69, 0x81, 0x37, 0x68, 0xd0, 0xdc, 0xd4, 0x6e, 0xee, 0x24, - 0x10, 0x48, 0xd2, 0x02, 0x01, 0xcc, 0x16, 0x9b, 0x2a, 0x78, 0xbe, 0xd3, 0xba, 0x1b, 0xb6, 0xd9, - 0x2d, 0x75, 0xb1, 0xd9, 0x97, 0x90, 0x2d, 0x36, 0xfb, 0x22, 0xf1, 0x17, 0x1f, 0x3a, 0xc4, 0xad, - 0x2d, 0xc3, 0x03, 0x67, 0x63, 0xbf, 0xe0, 0x61, 0xb8, 0x16, 0x07, 0xc8, 0xc3, 0x86, 0xd0, 0x9f, - 0x8b, 0xa2, 0xd7, 0xda, 0x0a, 0x3c, 0x6a, 0x32, 0x8a, 0x55, 0x70, 0xf0, 0xe2, 0x00, 0x89, 0xe2, - 0xdb, 0xd7, 0x50, 0x09, 0x3e, 0xaa, 0x6e, 0x5b, 0x41, 0x6d, 0x5e, 0x7b, 0x53, 0x5d, 0x32, 0x49, - 0x28, 0xb6, 0x64, 0x92, 0x7e, 0x32, 0x23, 0x0e, 0x3f, 0xb9, 0x89, 0xa9, 0xcd, 0x6b, 0x44, 0x35, - 0xe2, 0x0a, 0x92, 0x19, 0x71, 0x05, 0x10, 0x3d, 0xb7, 0xe6, 0x39, 0x6e, 0x6d, 0x5e, 0x5b, 0xcd, - 0x78, 0x2e, 0x47, 0x45, 0xcf, 0xe5, 0x3f, 0xa3, 0xe7, 0xae, 0x6e, 0x76, 0x82, 0x1a, 0xfb, 0xc6, - 0xb5, 0x8c, 0xe7, 0x86, 0xc8, 0xe8, 0xb9, 0x21, 0x80, 0x99, 0x42, 0x00, 0xac, 0x78, 0x0e, 0x33, - 0xda, 0x6f, 0x58, 0xad, 0x96, 0x76, 0x5b, 0x35, 0x85, 0x49, 0x3c, 0x33, 0x85, 0x49, 0x18, 0x73, - 0x3d, 0xf9, 0x5b, 0xd1, 0xf5, 0xce, 0x86, 0xf6, 0x96, 0xea, 0x7a, 0xc6, 0x18, 0xe6, 0x7a, 0xc6, - 0xbf, 0x60, 0x75, 0xc1, 0x7e, 0x11, 0x7a, 0xc7, 0xa3, 0xfe, 0xa6, 0xf6, 0x76, 0x62, 0x75, 0x21, - 0xe1, 0x60, 0x75, 0x21, 0xfd, 0xc6, 0x1b, 0xe8, 0x49, 0x65, 0xa2, 0x09, 0x77, 0xda, 0x57, 0xa9, - 0xe1, 0x35, 0x37, 0xb5, 0xcf, 0x80, 0xa8, 0xb3, 0x99, 0x53, 0x95, 0x4a, 0xba, 0x38, 0x40, 0x76, - 0x92, 0x04, 0xcb, 0xf2, 0x37, 0x97, 0xf8, 0xb1, 0x18, 0xb2, 0x52, 0x0d, 0x17, 0xa1, 0xff, 0x2e, - 0xb1, 0x2c, 0x4f, 0x93, 0xc0, 0xb2, 0x3c, 0x0d, 0xc6, 0x2e, 0x3a, 0x93, 0x58, 0xaa, 0xdd, 0x34, - 0x5a, 0x6c, 0x5d, 0x42, 0xcd, 0x15, 0xa3, 0x79, 0x97, 0x06, 0xda, 0xbf, 0x07, 0xd9, 0xe7, 0xfa, - 0x2c, 0xf8, 0x12, 0xd4, 0x8b, 0x03, 0xe4, 0x01, 0xf2, 0xe6, 0x47, 0xd0, 0x10, 0x5c, 0xc0, 0xa3, - 0xff, 0xdf, 0x1c, 0x1a, 0x5b, 0x0d, 0x3c, 0x6a, 0xb4, 0x45, 0xbe, 0xe2, 0x29, 0x54, 0xe4, 0x2b, - 0x3d, 0x71, 0xb9, 0xdc, 0x28, 0x89, 0x7e, 0xe3, 0x73, 0x68, 0x62, 0xc9, 0xf0, 0x03, 0xe0, 0x94, - 0x6e, 0xcd, 0x26, 0x09, 0x28, 0x5e, 0xe2, 0x74, 0x9c, 0x0f, 0xb6, 0x35, 0x0b, 0x0f, 0xdc, 0xd6, - 0x2c, 0xbe, 0xdf, 0x2d, 0x0f, 0xc0, 0xe6, 0x65, 0x82, 0x57, 0xef, 0xe5, 0x50, 0x6a, 0x0d, 0xfa, - 0xe8, 0x7b, 0x4e, 0xcb, 0x68, 0x32, 0xb1, 0x95, 0x2e, 0xb6, 0x6a, 0x1e, 0x72, 0xa7, 0x3d, 0xc9, - 0x8d, 0xcf, 0xa2, 0xc2, 0xed, 0x7a, 0x4d, 0xbe, 0x88, 0xa2, 0xa3, 0x1c, 0xc3, 0x64, 0x58, 0xfc, - 0x6c, 0xb4, 0x8f, 0x70, 0x9b, 0x2c, 0x89, 0x2d, 0x74, 0xb8, 0xb4, 0xaf, 0xe3, 0xb5, 0x88, 0x84, - 0xd2, 0x7f, 0x65, 0x2c, 0xde, 0x46, 0xc4, 0xe7, 0x44, 0x16, 0x81, 0x74, 0x31, 0x47, 0xe2, 0xcc, - 0x2e, 0xcf, 0x1a, 0xf8, 0x14, 0x1a, 0xab, 0xb7, 0x5d, 0xea, 0xf9, 0x8e, 0x0d, 0x25, 0xf3, 0xf3, - 0xf1, 0x9e, 0x98, 0x25, 0xc1, 0xe5, 0xbc, 0x5f, 0x99, 0x3e, 0xae, 0xf7, 0x5f, 0x78, 0x60, 0xbd, - 0xff, 0x0b, 0x68, 0xe8, 0x36, 0x5c, 0xd3, 0x27, 0x5d, 0x0d, 0xd0, 0x49, 0x5c, 0xd2, 0xc7, 0x29, - 0xf0, 0x45, 0x34, 0x0c, 0x1b, 0x63, 0xbe, 0x36, 0x04, 0xb4, 0x70, 0x16, 0xbe, 0x05, 0x10, 0xb9, - 0x38, 0x0c, 0xa7, 0xc1, 0x6f, 0xa0, 0xa9, 0xb8, 0xd2, 0x0c, 0x14, 0xf2, 0x09, 0x13, 0x98, 0xe1, - 0xfc, 0xec, 0xdd, 0x08, 0xc7, 0x2b, 0x00, 0xc9, 0x22, 0x52, 0x8c, 0x78, 0x11, 0x4d, 0xc6, 0x30, - 0xa6, 0xa2, 0xf0, 0xe0, 0xc4, 0x99, 0x5e, 0xb7, 0x7c, 0x4a, 0x92, 0xc5, 0xd4, 0x29, 0x8b, 0x4a, - 0xb2, 0xe1, 0x7a, 0x7c, 0xe7, 0x49, 0xf1, 0x81, 0x7d, 0xf8, 0x98, 0xd8, 0x9a, 0x1f, 0x11, 0x77, - 0x9e, 0xa8, 0x37, 0x9d, 0xdc, 0x40, 0x13, 0xc4, 0xe9, 0x04, 0x74, 0xcd, 0x09, 0x0b, 0x37, 0xf3, - 0xcc, 0x5a, 0x78, 0x27, 0x8f, 0x61, 0x1a, 0x81, 0x13, 0x1e, 0x3f, 0x96, 0x8f, 0x49, 0xab, 0x5c, - 0xf8, 0x56, 0x56, 0x0d, 0x68, 0xe9, 0x50, 0xb0, 0xf4, 0x79, 0x69, 0x61, 0x19, 0x45, 0x9f, 0xff, - 0x4b, 0x0e, 0x0d, 0xaf, 0x79, 0x86, 0x15, 0xf8, 0x62, 0x9b, 0xea, 0xf8, 0xec, 0x96, 0x67, 0xb8, - 0xac, 0x7f, 0xcc, 0xc2, 0x0e, 0xfd, 0x5b, 0x46, 0xab, 0x43, 0xfd, 0xf9, 0xb7, 0xd9, 0xd7, 0xfd, - 0x49, 0xb7, 0xfc, 0xc9, 0x0d, 0x88, 0xcf, 0xce, 0x36, 0x9d, 0xf6, 0xdc, 0x86, 0x67, 0xdc, 0xb3, - 0xf8, 0x8d, 0x07, 0x46, 0x6b, 0x2e, 0xa0, 0x2d, 0xea, 0x3a, 0x5e, 0x30, 0x67, 0xb8, 0xd6, 0x5c, - 0xb0, 0xed, 0x52, 0x7f, 0x2e, 0x92, 0xc4, 0x9f, 0xc0, 0xba, 0x40, 0x00, 0xff, 0xc9, 0x5d, 0x80, - 0xe3, 0xf0, 0x2d, 0x84, 0xc4, 0xa7, 0x56, 0x5c, 0x57, 0xec, 0x79, 0x49, 0x01, 0xfd, 0x10, 0xc3, - 0x3b, 0x76, 0xa4, 0x30, 0xc3, 0x95, 0xcb, 0x41, 0x49, 0x12, 0x58, 0x2f, 0x58, 0x13, 0x6f, 0x14, - 0xaa, 0x69, 0x3c, 0xd6, 0x78, 0xf8, 0xb2, 0x19, 0x4a, 0x4a, 0xb2, 0xe1, 0x75, 0x34, 0x29, 0xe4, - 0x46, 0x19, 0xb3, 0x13, 0xaa, 0xd1, 0x48, 0xa0, 0x79, 0xa7, 0x8d, 0xde, 0xd1, 0x14, 0x60, 0xf9, - 0x19, 0x09, 0x0e, 0x3c, 0x1f, 0x9f, 0xc4, 0x83, 0xda, 0x53, 0xda, 0x24, 0xf4, 0x58, 0xb8, 0xfb, - 0x21, 0xe4, 0xe7, 0x25, 0xab, 0xe4, 0xe2, 0x48, 0x0a, 0x8b, 0x2c, 0x83, 0xf7, 0xfa, 0xa9, 0x0c, - 0x19, 0xc9, 0x3e, 0xaf, 0xb2, 0xe0, 0x2a, 0x1a, 0x8f, 0x42, 0x6e, 0xb7, 0x99, 0x65, 0x9b, 0x8e, - 0xab, 0x34, 0x25, 0x92, 0x71, 0x65, 0x21, 0x0a, 0x0f, 0xbe, 0x82, 0x8a, 0x7c, 0xd3, 0xaa, 0xce, - 0x77, 0xd9, 0xc2, 0x44, 0x0a, 0x80, 0x35, 0x2c, 0xb9, 0xc5, 0x22, 0x42, 0xfc, 0x2a, 0x2a, 0x55, - 0xde, 0x5e, 0x65, 0x76, 0xa6, 0x42, 0x6e, 0xf9, 0xda, 0xb1, 0xf8, 0xf8, 0x02, 0x1c, 0xd0, 0x77, - 0x5a, 0xb4, 0x61, 0x78, 0x8a, 0xf1, 0x90, 0xe9, 0xf1, 0x02, 0x9a, 0x50, 0x66, 0x6d, 0x5f, 0x9b, - 0x89, 0x2f, 0x6d, 0x35, 0x00, 0xd3, 0x10, 0x15, 0xca, 0x94, 0x2a, 0x04, 0x2a, 0x13, 0xeb, 0x35, - 0x35, 0xcb, 0x37, 0x5a, 0x2d, 0x67, 0x8b, 0x50, 0xcb, 0xf7, 0x3b, 0x14, 0xb6, 0xe8, 0x8a, 0xbc, - 0xd7, 0x98, 0x02, 0xd5, 0xf0, 0x38, 0x4e, 0xa9, 0x11, 0xa1, 0xb2, 0xe1, 0x77, 0x11, 0xae, 0xb0, - 0xdf, 0xea, 0x3d, 0x1c, 0x27, 0xfa, 0xde, 0xc3, 0x71, 0x4e, 0x98, 0x8f, 0x33, 0x06, 0xe7, 0x6a, - 0xf4, 0xb9, 0x8f, 0x23, 0x43, 0xaa, 0xfe, 0x0f, 0x39, 0x79, 0xf0, 0x44, 0x15, 0xae, 0x73, 0x99, - 0x15, 0xae, 0x2f, 0xa2, 0x51, 0x31, 0xe5, 0x44, 0xb9, 0xd6, 0x70, 0xa2, 0x2c, 0xcc, 0x28, 0xb2, - 0x4c, 0x12, 0x13, 0xc0, 0x69, 0x9e, 0xb8, 0x28, 0x4d, 0x41, 0x3a, 0xcd, 0x13, 0x17, 0xa5, 0x51, - 0x4a, 0xd2, 0x5c, 0x56, 0xef, 0x02, 0x19, 0x8c, 0x93, 0x8e, 0xc2, 0xda, 0x0a, 0x3c, 0xe9, 0x48, - 0xbe, 0x10, 0xe4, 0x65, 0x84, 0xe2, 0xb6, 0x14, 0x13, 0x24, 0x8c, 0x73, 0xb9, 0xe9, 0xe5, 0x71, - 0x1e, 0x53, 0xeb, 0x7f, 0x9c, 0x4b, 0x0d, 0x4f, 0xf6, 0x0e, 0x22, 0x7f, 0x4d, 0xd2, 0x03, 0xbc, - 0x83, 0xc8, 0x76, 0x13, 0xef, 0x20, 0x11, 0xe1, 0xf3, 0xa8, 0x98, 0xa8, 0xe5, 0x01, 0xf9, 0x3a, - 0x51, 0x21, 0x8f, 0x08, 0x8b, 0x2f, 0xa3, 0x22, 0x1b, 0x2c, 0x76, 0x7c, 0x49, 0x09, 0x54, 0x09, - 0xeb, 0x08, 0x98, 0xdc, 0xbb, 0x43, 0x3a, 0xc6, 0xa3, 0xa4, 0xdb, 0x0b, 0x9e, 0x0c, 0xd3, 0x10, - 0xa7, 0xd7, 0xff, 0xd3, 0xe0, 0x8e, 0x3e, 0xed, 0xbe, 0xa4, 0x28, 0xbe, 0xc4, 0xbc, 0x31, 0xf6, - 0xf4, 0x8a, 0x9f, 0x72, 0x1a, 0x7c, 0x40, 0x34, 0x0c, 0xde, 0x64, 0x3e, 0x51, 0x29, 0xe5, 0x42, - 0x78, 0x90, 0xf0, 0x33, 0x98, 0x51, 0x08, 0x2f, 0x91, 0x66, 0xa5, 0x30, 0xe0, 0x17, 0xd0, 0x68, - 0x5c, 0xd2, 0x6f, 0x28, 0xb6, 0x2b, 0x59, 0x95, 0xfc, 0x62, 0x4a, 0xfc, 0x39, 0x34, 0xac, 0xd4, - 0x30, 0x99, 0x7b, 0x88, 0x45, 0xc0, 0xac, 0x9c, 0x22, 0xc8, 0x5d, 0x97, 0x64, 0xfd, 0x12, 0x21, - 0x14, 0xaf, 0xa1, 0x63, 0x2b, 0x1e, 0x35, 0x61, 0xb9, 0xb9, 0x70, 0xdf, 0xf5, 0x44, 0x02, 0x27, - 0x4f, 0x64, 0xd4, 0xd9, 0x80, 0x76, 0x43, 0x74, 0x83, 0x46, 0x78, 0x49, 0x50, 0x16, 0x3b, 0x33, - 0x67, 0xfc, 0x4d, 0xde, 0xa0, 0xdb, 0x5b, 0x8e, 0x67, 0x86, 0xd7, 0x84, 0x83, 0x39, 0x13, 0x8a, - 0xbe, 0x2b, 0x50, 0xb2, 0x39, 0x53, 0x99, 0x4e, 0xbd, 0x84, 0x4a, 0x8f, 0x9a, 0x66, 0xf7, 0x8b, - 0xf9, 0x3e, 0xd1, 0xa1, 0xc3, 0x7b, 0x2c, 0x2f, 0x3a, 0x22, 0x3d, 0xd4, 0xe7, 0x88, 0xf4, 0xdf, - 0xe5, 0xfb, 0x84, 0xbe, 0x0e, 0xf5, 0x51, 0xc6, 0x48, 0x19, 0xea, 0x51, 0xc6, 0xf8, 0x14, 0xa9, - 0x65, 0x12, 0x99, 0x28, 0x71, 0xe8, 0x79, 0xf8, 0x81, 0x87, 0x9e, 0x7f, 0xa6, 0xb0, 0x53, 0x68, - 0xf0, 0x48, 0xf7, 0xbb, 0xd1, 0xfd, 0x65, 0x54, 0x8a, 0x34, 0x2b, 0x0a, 0x99, 0x8d, 0x47, 0x49, - 0xbd, 0x1c, 0x0c, 0x3c, 0x12, 0x11, 0xbe, 0xc0, 0xdf, 0x75, 0xd5, 0x7a, 0x8f, 0x17, 0xe7, 0x18, - 0xe7, 0xb5, 0xbe, 0xd8, 0xbb, 0x35, 0x7c, 0xeb, 0x3d, 0x4a, 0x22, 0xb4, 0xfe, 0x9b, 0xf9, 0xcc, - 0xf8, 0xea, 0x51, 0x1b, 0xed, 0xa2, 0x8d, 0x32, 0x94, 0xc8, 0x23, 0xc3, 0x47, 0x4a, 0xdc, 0x85, - 0x12, 0x7f, 0x92, 0xcf, 0x8c, 0xa3, 0x1f, 0x29, 0x71, 0x37, 0xd6, 0xe2, 0x22, 0x1a, 0x25, 0xce, - 0x96, 0x5f, 0x75, 0x3a, 0x76, 0x20, 0x6c, 0x05, 0x18, 0x6a, 0xcf, 0xd9, 0xf2, 0x1b, 0x4d, 0x06, - 0x25, 0x31, 0x81, 0xfe, 0xd3, 0xfc, 0x0e, 0x3b, 0x0d, 0x47, 0x8a, 0xff, 0x20, 0xa7, 0xc8, 0x6f, - 0xe6, 0x95, 0x9d, 0x8c, 0x43, 0x5d, 0x13, 0x64, 0xb5, 0xb9, 0x49, 0xdb, 0x46, 0xb2, 0x26, 0x88, - 0x0f, 0x50, 0x71, 0x32, 0x39, 0x26, 0xd1, 0xbf, 0x95, 0x4f, 0x6c, 0xe5, 0x1c, 0xe9, 0xee, 0xa1, - 0x75, 0x17, 0xf5, 0x3a, 0xb1, 0x3b, 0x75, 0xa4, 0xb9, 0x87, 0xd5, 0xdc, 0x17, 0xf3, 0x89, 0x8d, - 0xbc, 0xc3, 0x5b, 0x65, 0xe0, 0x5b, 0xf9, 0xf4, 0xa6, 0xe4, 0xe1, 0xed, 0x49, 0x17, 0xd1, 0xa8, - 0xd0, 0x43, 0x34, 0x55, 0x70, 0xbb, 0xcf, 0x81, 0x10, 0xbd, 0x8b, 0x08, 0xf4, 0xff, 0x9c, 0x47, - 0xea, 0x06, 0xeb, 0x21, 0xed, 0x43, 0xdf, 0xcc, 0xab, 0x5b, 0xcb, 0x87, 0xb7, 0xff, 0xcc, 0x22, - 0xb4, 0xda, 0x59, 0x17, 0x97, 0xc8, 0x0a, 0x4b, 0xc4, 0xc3, 0xbf, 0x11, 0x94, 0x48, 0x14, 0xfa, - 0x3f, 0xe7, 0x33, 0xf7, 0xbb, 0x0f, 0xb3, 0xb7, 0x56, 0x64, 0xe3, 0xcb, 0x8e, 0x0d, 0x39, 0x44, - 0x72, 0x5d, 0x01, 0x93, 0x23, 0xb9, 0x21, 0x1d, 0x7e, 0x31, 0xc3, 0x5b, 0x83, 0x72, 0xd3, 0x99, - 0xd5, 0x11, 0x65, 0xbf, 0xed, 0x77, 0xf3, 0x0f, 0xca, 0x0e, 0x38, 0xcc, 0x93, 0xea, 0xc8, 0x8a, - 0xb1, 0x0d, 0x59, 0xec, 0xac, 0x21, 0xc6, 0x78, 0x69, 0x6b, 0x97, 0x83, 0xe4, 0xbb, 0x3a, 0x04, - 0xd5, 0xc7, 0x9e, 0x45, 0x25, 0xc8, 0x53, 0xe0, 0x97, 0x9a, 0xe2, 0x31, 0x54, 0x5c, 0x9e, 0x5f, - 0x5d, 0x20, 0x6f, 0x2d, 0xd4, 0xa6, 0x06, 0x30, 0x42, 0xc3, 0xb5, 0x85, 0x5b, 0xf5, 0x85, 0xda, - 0x54, 0x6e, 0x7e, 0xea, 0xfd, 0x3f, 0x3b, 0x33, 0xf0, 0xfe, 0x8f, 0xcf, 0xe4, 0xbe, 0xff, 0xe3, - 0x33, 0xb9, 0x3f, 0xfd, 0xf1, 0x99, 0xdc, 0xfa, 0x30, 0xec, 0x03, 0x5c, 0xf9, 0x97, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xd3, 0x8b, 0x48, 0xb1, 0xdb, 0xaa, 0x00, 0x00, + 0x09, 0x62, 0x24, 0x01, 0xe2, 0x24, 0x08, 0x10, 0xd4, 0x57, 0xd5, 0xdd, 0x55, 0xdd, 0x3d, 0x94, + 0x28, 0x6a, 0xc3, 0x70, 0xc9, 0x27, 0x72, 0xbe, 0xbf, 0xee, 0xfe, 0xaa, 0xea, 0xab, 0xaf, 0xbe, + 0xfa, 0xea, 0x2b, 0x34, 0x46, 0xef, 0x51, 0x3b, 0xf0, 0x67, 0x5d, 0xcf, 0x09, 0x1c, 0x3c, 0xcc, + 0x7f, 0x9d, 0x9a, 0xd9, 0x70, 0x36, 0x1c, 0x00, 0xcd, 0xb1, 0xff, 0x38, 0xf6, 0x54, 0x79, 0xc3, + 0x71, 0x36, 0x5a, 0x74, 0x0e, 0x7e, 0xad, 0x77, 0xee, 0xcc, 0x05, 0x56, 0x9b, 0xfa, 0x81, 0xd1, + 0x76, 0x05, 0xc1, 0xe9, 0x24, 0x81, 0x1f, 0x78, 0x9d, 0x66, 0x20, 0xb0, 0xd5, 0x0d, 0x2b, 0xd8, + 0xec, 0xac, 0xcf, 0x36, 0x9d, 0xf6, 0xdc, 0x86, 0x67, 0xdc, 0xb3, 0x02, 0x23, 0xb0, 0x1c, 0xdb, + 0x68, 0xcd, 0x05, 0xb4, 0x45, 0x5d, 0xc7, 0x0b, 0xe6, 0x0c, 0xd7, 0x9a, 0x0b, 0xb6, 0x5d, 0xea, + 0xcf, 0x6d, 0x79, 0x86, 0xeb, 0x52, 0x2f, 0xfe, 0x87, 0x0b, 0xd1, 0xbf, 0x9c, 0x47, 0xc5, 0x9b, + 0x34, 0x30, 0x4c, 0x23, 0x30, 0xf0, 0x69, 0x34, 0x54, 0xb7, 0x4d, 0x7a, 0x5f, 0xcb, 0x3d, 0x9d, + 0x3b, 0x5f, 0x98, 0x1f, 0xee, 0x75, 0xcb, 0x79, 0x6a, 0x11, 0x0e, 0xc4, 0x4f, 0xa1, 0xc1, 0xb5, + 0x6d, 0x97, 0x6a, 0xf9, 0xa7, 0x73, 0xe7, 0x47, 0xe7, 0x47, 0x7b, 0xdd, 0xf2, 0x10, 0x7c, 0x1e, + 0x01, 0x30, 0x7e, 0x06, 0xe5, 0xeb, 0x35, 0xad, 0x00, 0xc8, 0xe9, 0x5e, 0xb7, 0x3c, 0xde, 0xb1, + 0xcc, 0x8b, 0x4e, 0xdb, 0x0a, 0x68, 0xdb, 0x0d, 0xb6, 0x49, 0xbe, 0x5e, 0xc3, 0xe7, 0xd0, 0x60, + 0xd5, 0x31, 0xa9, 0x36, 0x08, 0x44, 0xb8, 0xd7, 0x2d, 0x4f, 0x34, 0x1d, 0x93, 0x4a, 0x54, 0x80, + 0xc7, 0xd7, 0xd1, 0xe0, 0x9a, 0xd5, 0xa6, 0xda, 0xd0, 0xd3, 0xb9, 0xf3, 0xa5, 0xcb, 0xa7, 0x66, + 0xb9, 0x1a, 0x66, 0x43, 0x35, 0xcc, 0xae, 0x85, 0x7a, 0x9a, 0x9f, 0x7a, 0xbf, 0x5b, 0x1e, 0xe8, + 0x75, 0xcb, 0x83, 0x4c, 0x75, 0xff, 0xf3, 0x47, 0xe5, 0x1c, 0x01, 0x4e, 0xfc, 0x0a, 0x2a, 0x55, + 0x5b, 0x1d, 0x3f, 0xa0, 0xde, 0x2d, 0xa3, 0x4d, 0xb5, 0x61, 0x78, 0xe0, 0xa9, 0x5e, 0xb7, 0x7c, + 0xa2, 0xc9, 0xc1, 0x0d, 0xdb, 0x68, 0xcb, 0x0f, 0x96, 0xc9, 0xf5, 0x77, 0xd1, 0xe4, 0x2a, 0xf5, + 0x7d, 0xcb, 0xb1, 0x23, 0xd5, 0x7c, 0x14, 0x8d, 0x0a, 0x50, 0xbd, 0x06, 0xea, 0x19, 0x9d, 0x1f, + 0xe9, 0x75, 0xcb, 0x05, 0xdf, 0x32, 0x49, 0x8c, 0xc1, 0x1f, 0x47, 0x23, 0x6f, 0x5b, 0xc1, 0xe6, + 0xcd, 0x1b, 0x15, 0xa1, 0xa6, 0x13, 0xbd, 0x6e, 0x19, 0x6f, 0x59, 0xc1, 0x66, 0xa3, 0x7d, 0xc7, + 0x90, 0x9e, 0x17, 0x92, 0xe9, 0xff, 0x2f, 0x8f, 0xc6, 0x6e, 0xfb, 0xd4, 0x8b, 0x9e, 0x74, 0x0e, + 0x0d, 0xb2, 0xdf, 0xe2, 0x21, 0xa0, 0xa4, 0x8e, 0x4f, 0x3d, 0x59, 0x49, 0x0c, 0x8f, 0x2f, 0xa0, + 0xa1, 0x25, 0x67, 0xc3, 0xb2, 0xc5, 0x83, 0x8e, 0xf5, 0xba, 0xe5, 0xc9, 0x16, 0x03, 0x48, 0x94, + 0x9c, 0x02, 0x7f, 0x0a, 0x8d, 0xd5, 0xdb, 0xac, 0xd1, 0x1d, 0xdb, 0x08, 0x1c, 0x4f, 0x34, 0x12, + 0xa8, 0xc3, 0x92, 0xe0, 0x12, 0xa3, 0x42, 0x8f, 0x5f, 0x46, 0xa8, 0xf2, 0xf6, 0x2a, 0x71, 0x5a, + 0xb4, 0x42, 0x6e, 0x89, 0xd6, 0x03, 0x6e, 0x63, 0xcb, 0x6f, 0x78, 0x4e, 0x8b, 0x36, 0x0c, 0x4f, + 0x7e, 0xac, 0x44, 0x8d, 0x17, 0xd0, 0x44, 0xa5, 0xd9, 0xa4, 0xbe, 0x4f, 0xe8, 0xe7, 0x3b, 0xd4, + 0x0f, 0x7c, 0x6d, 0xe8, 0xe9, 0xc2, 0xf9, 0xd1, 0xf9, 0xa7, 0x7a, 0xdd, 0xf2, 0x13, 0x06, 0x60, + 0x1a, 0x9e, 0x40, 0x49, 0x22, 0x12, 0x4c, 0xfa, 0x2f, 0x14, 0xd0, 0xc4, 0x2a, 0xf5, 0xee, 0x49, + 0x8a, 0xaa, 0xb0, 0x56, 0x62, 0x10, 0xd6, 0x66, 0xbe, 0x6b, 0x34, 0xa9, 0xd0, 0xd9, 0xc9, 0x5e, + 0xb7, 0x7c, 0xcc, 0x0e, 0x81, 0x92, 0xd0, 0x24, 0x3d, 0xbe, 0x80, 0x8a, 0x1c, 0x54, 0xaf, 0x09, + 0x35, 0x8e, 0xf7, 0xba, 0xe5, 0x51, 0x1f, 0x60, 0x0d, 0xcb, 0x24, 0x11, 0x9a, 0x7d, 0x07, 0xff, + 0x7f, 0xd1, 0xf1, 0x03, 0x26, 0x5c, 0x68, 0x11, 0xbe, 0x43, 0x30, 0x6c, 0x0a, 0x94, 0xfc, 0x1d, + 0x2a, 0x13, 0x7e, 0x09, 0x21, 0x0e, 0xa9, 0x98, 0xa6, 0x27, 0x54, 0xf9, 0x44, 0xaf, 0x5b, 0x3e, + 0x2e, 0x44, 0x18, 0xa6, 0x29, 0xb7, 0x83, 0x44, 0x8c, 0xdb, 0x68, 0x8c, 0xff, 0x5a, 0x32, 0xd6, + 0x69, 0x8b, 0xeb, 0xb1, 0x74, 0xf9, 0xfc, 0xac, 0xb0, 0x38, 0xaa, 0x76, 0x66, 0x65, 0xd2, 0x05, + 0x3b, 0xf0, 0xb6, 0xe7, 0xcb, 0x62, 0xac, 0x9c, 0x14, 0x8f, 0x6a, 0x01, 0x4e, 0x6e, 0x74, 0x99, + 0xe7, 0xd4, 0x6b, 0x68, 0x3a, 0x25, 0x03, 0x4f, 0xa1, 0xc2, 0x5d, 0xba, 0xcd, 0xf5, 0x4c, 0xd8, + 0xbf, 0x78, 0x06, 0x0d, 0xdd, 0x33, 0x5a, 0x1d, 0x61, 0x16, 0x08, 0xff, 0xf1, 0x72, 0xfe, 0xc5, + 0x9c, 0xfe, 0xab, 0x39, 0x84, 0xab, 0x8e, 0x6d, 0xd3, 0x66, 0x20, 0x8f, 0xa4, 0x4f, 0xa0, 0xd1, + 0x25, 0xa7, 0x69, 0xb4, 0x40, 0x01, 0xbc, 0xc1, 0xb4, 0x5e, 0xb7, 0x3c, 0xc3, 0xbe, 0x7c, 0xb6, + 0xc5, 0x30, 0xd2, 0x2b, 0xc5, 0xa4, 0x4c, 0x73, 0x84, 0xb6, 0x9d, 0x80, 0x02, 0x63, 0x3e, 0xd6, + 0x1c, 0x30, 0x7a, 0x80, 0x92, 0x35, 0x17, 0x13, 0xe3, 0x39, 0x54, 0x5c, 0x61, 0xb6, 0xa3, 0xe9, + 0xb4, 0x44, 0xab, 0xc1, 0x68, 0x01, 0x7b, 0x22, 0xb1, 0x44, 0x44, 0xfa, 0x22, 0x9a, 0xa8, 0xb6, + 0x2c, 0x6a, 0x07, 0xf2, 0x5b, 0xb3, 0x51, 0x57, 0xd9, 0xa0, 0x76, 0x20, 0xbf, 0x35, 0x1b, 0x9a, + 0x0d, 0x83, 0x41, 0xe5, 0xb7, 0x8e, 0x48, 0xf5, 0xef, 0x15, 0xd0, 0x13, 0x6f, 0x74, 0xd6, 0xa9, + 0x67, 0xd3, 0x80, 0xfa, 0xc2, 0xc8, 0x44, 0x52, 0x6f, 0xa1, 0xe9, 0x14, 0x52, 0x48, 0x7f, 0xba, + 0xd7, 0x2d, 0x9f, 0xbe, 0x1b, 0x21, 0x1b, 0xc2, 0x6e, 0x49, 0x4f, 0x49, 0xb3, 0xe2, 0x45, 0x34, + 0x19, 0x03, 0xd9, 0x4b, 0xf8, 0x5a, 0x1e, 0x46, 0xdb, 0x99, 0x5e, 0xb7, 0x7c, 0x4a, 0x92, 0xc6, + 0x5e, 0x5b, 0x6e, 0xfa, 0x24, 0x1b, 0x7e, 0x03, 0x4d, 0xc5, 0xa0, 0xd7, 0x3d, 0xa7, 0xe3, 0xfa, + 0x5a, 0x01, 0x44, 0x95, 0x7b, 0xdd, 0xf2, 0x93, 0x92, 0xa8, 0x0d, 0x40, 0x4a, 0xb2, 0x52, 0x8c, + 0xf8, 0x0b, 0x39, 0x59, 0x9a, 0xe8, 0xbe, 0x83, 0xd0, 0x7d, 0xaf, 0x85, 0xdd, 0xb7, 0xaf, 0x92, + 0x66, 0x93, 0x9c, 0xa2, 0x37, 0x27, 0x5e, 0x23, 0xd5, 0x9b, 0x53, 0x4f, 0x3c, 0x55, 0x45, 0xc7, + 0x33, 0x65, 0xed, 0xaa, 0x57, 0xff, 0x45, 0x41, 0x96, 0xb2, 0xe2, 0x98, 0x51, 0x63, 0x2e, 0xcb, + 0x8d, 0xb9, 0xe2, 0x98, 0x30, 0xf3, 0xf0, 0xc6, 0x7c, 0xa6, 0xd7, 0x2d, 0x3f, 0x25, 0xbd, 0xac, + 0xeb, 0x98, 0xc9, 0x09, 0x28, 0xcd, 0x8b, 0xdf, 0x41, 0x27, 0x52, 0x40, 0x6e, 0xe7, 0x78, 0xef, + 0x3f, 0xd7, 0xeb, 0x96, 0xf5, 0x0c, 0xa9, 0x49, 0xb3, 0xd7, 0x47, 0x0a, 0x36, 0xd0, 0x49, 0x49, + 0xeb, 0x8e, 0x1d, 0x18, 0x96, 0x2d, 0x26, 0x4c, 0x3e, 0x4a, 0x9e, 0xed, 0x75, 0xcb, 0x67, 0xe5, + 0x3e, 0x18, 0xd2, 0x24, 0x5f, 0xbe, 0x9f, 0x1c, 0x6c, 0x22, 0x2d, 0x03, 0x55, 0x6f, 0x1b, 0x1b, + 0xa1, 0x17, 0x70, 0xbe, 0xd7, 0x2d, 0x7f, 0x24, 0xf3, 0x19, 0x16, 0xa3, 0x92, 0x1e, 0xd2, 0x57, + 0x12, 0x26, 0x08, 0xc7, 0xb8, 0x5b, 0x8e, 0x49, 0xe1, 0x1b, 0x86, 0x40, 0xbe, 0xde, 0xeb, 0x96, + 0xcf, 0x48, 0xf2, 0x6d, 0xc7, 0xa4, 0xc9, 0xd7, 0xcf, 0xe0, 0xd6, 0x7f, 0x34, 0xc4, 0xcc, 0x2d, + 0xcc, 0xeb, 0xab, 0x81, 0xe1, 0x05, 0xf8, 0xe5, 0xd8, 0x51, 0x82, 0x56, 0x2d, 0x5d, 0x9e, 0x0a, + 0xfb, 0x6e, 0x08, 0x9f, 0x1f, 0x63, 0x26, 0xf6, 0xfb, 0xdd, 0x72, 0xae, 0xd7, 0x2d, 0x0f, 0x90, + 0xa2, 0x64, 0x3d, 0xf8, 0x9c, 0x9e, 0x07, 0xbe, 0x99, 0x90, 0x4f, 0x9e, 0xf7, 0x13, 0xbc, 0x7c, + 0x8e, 0x7f, 0x0d, 0x8d, 0x88, 0x77, 0x80, 0x16, 0x29, 0x5d, 0x3e, 0x19, 0x5b, 0x7b, 0xc5, 0x3f, + 0x49, 0x70, 0x87, 0x5c, 0xf8, 0x15, 0x34, 0xcc, 0x8d, 0x38, 0x68, 0xbb, 0x74, 0xf9, 0x44, 0xf6, + 0x6c, 0x91, 0x60, 0x17, 0x3c, 0x78, 0x11, 0xa1, 0xd8, 0x80, 0x47, 0xde, 0x98, 0x90, 0x90, 0x36, + 0xed, 0x09, 0x29, 0x12, 0x2f, 0xfe, 0x04, 0x1a, 0x5b, 0xa3, 0x5e, 0xdb, 0xb2, 0x8d, 0xd6, 0xaa, + 0xf5, 0x5e, 0xe8, 0x90, 0x81, 0x73, 0xe3, 0x5b, 0xef, 0xc9, 0x6d, 0xa1, 0xd0, 0xe1, 0xcf, 0x65, + 0x19, 0xc8, 0x11, 0x78, 0x91, 0x67, 0x1e, 0x68, 0x39, 0x12, 0xef, 0x93, 0x61, 0x2f, 0xdf, 0x44, + 0xe3, 0xca, 0xd8, 0xd0, 0x8a, 0x20, 0xfa, 0xa9, 0xb4, 0x68, 0x69, 0xa0, 0x27, 0xc4, 0xaa, 0x12, + 0x98, 0x9f, 0x50, 0xb7, 0xad, 0xc0, 0x32, 0x5a, 0x55, 0xa7, 0xdd, 0x36, 0x6c, 0x53, 0x1b, 0x8d, + 0xfd, 0x1d, 0x8b, 0x63, 0x1a, 0x4d, 0x8e, 0x92, 0xfd, 0x04, 0x95, 0x89, 0xd9, 0x5f, 0xd1, 0x86, + 0x84, 0x36, 0x1d, 0xcf, 0xb4, 0xec, 0x0d, 0x0d, 0x81, 0xd2, 0xc0, 0xf0, 0xf9, 0x1c, 0xd7, 0xf0, + 0x42, 0xa4, 0x6c, 0xf8, 0x92, 0x8c, 0x9f, 0x1e, 0x2c, 0x96, 0xa6, 0xc6, 0x52, 0x2e, 0xd5, 0xcf, + 0x16, 0x50, 0x49, 0x90, 0x7e, 0xda, 0xb1, 0xec, 0xa3, 0x0e, 0xbe, 0x97, 0x0e, 0x9e, 0xd9, 0x51, + 0x87, 0x1f, 0x57, 0x47, 0xd5, 0xbf, 0x94, 0x8f, 0xac, 0xd1, 0x8a, 0x67, 0xd9, 0x7b, 0xb3, 0x46, + 0xe7, 0x10, 0xaa, 0x6e, 0x76, 0xec, 0xbb, 0x7c, 0xad, 0x97, 0x8f, 0xd7, 0x7a, 0x4d, 0x8b, 0x48, + 0x18, 0xb6, 0xe0, 0xab, 0x31, 0xf9, 0xac, 0x65, 0xc6, 0xe6, 0x47, 0xdf, 0xe7, 0x92, 0x72, 0xcf, + 0x13, 0x00, 0xe3, 0x32, 0x1a, 0x9a, 0xdf, 0x0e, 0xa8, 0x0f, 0x9a, 0x2f, 0xf0, 0x05, 0xe1, 0x3a, + 0x03, 0x10, 0x0e, 0xc7, 0x57, 0xd1, 0x74, 0x8d, 0xb6, 0x8c, 0xed, 0x9b, 0x56, 0xab, 0x65, 0xf9, + 0xb4, 0xe9, 0xd8, 0xa6, 0x0f, 0x4a, 0x16, 0x8f, 0x6b, 0xfb, 0x24, 0x4d, 0x80, 0x75, 0x34, 0xbc, + 0x7c, 0xe7, 0x8e, 0x4f, 0x03, 0x50, 0x5f, 0x61, 0x1e, 0xf5, 0xba, 0xe5, 0x61, 0x07, 0x20, 0x44, + 0x60, 0xf4, 0xaf, 0xe7, 0xd0, 0x54, 0x8d, 0xfa, 0x77, 0x03, 0xc7, 0x8d, 0x7a, 0xf9, 0x9e, 0x54, + 0x72, 0x01, 0x8d, 0xdc, 0xa4, 0xbe, 0xcf, 0xa6, 0xa5, 0x3c, 0x7c, 0xed, 0xa4, 0xf8, 0xda, 0x91, + 0x36, 0x07, 0x93, 0x10, 0x9f, 0xfd, 0x55, 0x85, 0x07, 0x7c, 0x95, 0xfe, 0x93, 0x3c, 0x3a, 0x29, + 0xde, 0xb8, 0xda, 0xb2, 0xdc, 0x75, 0xc7, 0xf0, 0x4c, 0x42, 0x9b, 0xd4, 0xba, 0x47, 0x0f, 0xe6, + 0xc0, 0x53, 0x87, 0xce, 0xe0, 0x1e, 0x86, 0xce, 0x65, 0x54, 0x12, 0x9a, 0x01, 0xcf, 0x9e, 0x4f, + 0xdb, 0x53, 0xbd, 0x6e, 0x79, 0xcc, 0xe4, 0x60, 0x58, 0x14, 0x11, 0x99, 0x88, 0x75, 0x92, 0x25, + 0x6a, 0x6f, 0x04, 0x9b, 0xd0, 0x49, 0x86, 0x78, 0x27, 0x69, 0x01, 0x84, 0x08, 0x8c, 0xfe, 0x57, + 0x79, 0x34, 0x93, 0x54, 0xf9, 0x2a, 0xb5, 0xcd, 0x23, 0x7d, 0x7f, 0x30, 0xfa, 0xfe, 0xc3, 0x3c, + 0x1a, 0x8f, 0xa6, 0x9e, 0x77, 0x69, 0x73, 0x7f, 0x5c, 0xa6, 0x78, 0x42, 0x28, 0xec, 0x79, 0x42, + 0xd8, 0x8b, 0x96, 0x75, 0x34, 0x4c, 0xa8, 0xe1, 0x8b, 0x69, 0x65, 0x94, 0x6b, 0xcc, 0x03, 0x08, + 0x11, 0x18, 0xfc, 0x0c, 0x1a, 0xb9, 0x69, 0xdc, 0xb7, 0xda, 0x9d, 0xb6, 0xb0, 0x75, 0x10, 0x52, + 0x6a, 0x1b, 0xf7, 0x49, 0x08, 0xd7, 0xff, 0x28, 0x87, 0x26, 0x84, 0x52, 0x85, 0xf0, 0x3d, 0x69, + 0x35, 0xd6, 0x4e, 0x7e, 0xcf, 0xda, 0x29, 0x3c, 0xba, 0x76, 0xf4, 0xaf, 0x0f, 0x32, 0xf5, 0x30, + 0xd7, 0xef, 0xb0, 0x8f, 0xc6, 0xb8, 0x45, 0x86, 0x1e, 0xa1, 0x45, 0x0e, 0x8d, 0x5f, 0xad, 0xff, + 0xfd, 0x08, 0x42, 0x42, 0xfb, 0x0b, 0x47, 0x36, 0x7c, 0x6f, 0xbd, 0xa6, 0x86, 0xa6, 0x17, 0xec, + 0x4d, 0xc3, 0x6e, 0x52, 0x33, 0x5e, 0x5d, 0xb0, 0xae, 0x53, 0xe4, 0xf1, 0x6a, 0x2a, 0x90, 0xf1, + 0xf2, 0x82, 0xa4, 0x19, 0xf0, 0x25, 0x54, 0xaa, 0xdb, 0x01, 0xf5, 0x8c, 0x66, 0x60, 0xdd, 0xa3, + 0xd0, 0x7b, 0x8a, 0xf3, 0x93, 0xbd, 0x6e, 0xb9, 0x64, 0xc5, 0x60, 0x22, 0xd3, 0xe0, 0xab, 0x68, + 0x6c, 0xc5, 0xf0, 0x02, 0xab, 0x69, 0xb9, 0x86, 0x1d, 0xf8, 0x5a, 0x11, 0x96, 0x46, 0x30, 0xf7, + 0xb8, 0x12, 0x9c, 0x28, 0x54, 0xf8, 0x73, 0x68, 0x14, 0x96, 0xe0, 0xb0, 0x27, 0x30, 0xfa, 0xc0, + 0x3d, 0x81, 0xb3, 0x71, 0x9c, 0x93, 0x2f, 0x92, 0x7c, 0xc6, 0x1c, 0x0f, 0x05, 0xd8, 0x26, 0x88, + 0x25, 0xe2, 0xcf, 0xa0, 0x91, 0x05, 0xdb, 0x04, 0xe1, 0xe8, 0x81, 0xc2, 0x75, 0x21, 0xfc, 0x44, + 0x2c, 0xdc, 0x71, 0x13, 0xb2, 0x43, 0x71, 0xd9, 0xa3, 0xac, 0xf4, 0xc1, 0x8d, 0xb2, 0xb1, 0x0f, + 0x60, 0xf5, 0x3a, 0xfe, 0xb8, 0x56, 0xaf, 0x13, 0x8f, 0xb8, 0x7a, 0xd5, 0xdf, 0x43, 0xa5, 0xf9, + 0x95, 0x1b, 0xd1, 0xe8, 0x7d, 0x02, 0x15, 0x56, 0xc4, 0x1e, 0xcc, 0x20, 0x9f, 0x30, 0x5d, 0xcb, + 0x24, 0x0c, 0x86, 0x2f, 0xa0, 0x62, 0x15, 0xc2, 0x91, 0x22, 0x9c, 0x3f, 0xc8, 0xc3, 0xf9, 0x4d, + 0x80, 0x41, 0x38, 0x3f, 0x44, 0xe3, 0x8f, 0xa2, 0x91, 0x15, 0xcf, 0xd9, 0xf0, 0x8c, 0xb6, 0x88, + 0x75, 0x95, 0x98, 0xb3, 0xef, 0x72, 0x10, 0x09, 0x71, 0xfa, 0xff, 0xca, 0xa1, 0xe1, 0xd5, 0xc0, + 0x08, 0x3a, 0x3e, 0xe3, 0x58, 0xed, 0xc0, 0x0a, 0x1a, 0x9e, 0x5d, 0xe4, 0x1c, 0x3e, 0x07, 0x91, + 0x10, 0x87, 0x2f, 0xa0, 0xa1, 0x05, 0xcf, 0x73, 0x3c, 0x79, 0x5b, 0x86, 0x32, 0x80, 0xbc, 0x2d, + 0x03, 0x14, 0xf8, 0x1a, 0x2a, 0x71, 0x9b, 0xc3, 0x17, 0x1e, 0xfc, 0x3d, 0x8e, 0xf7, 0xba, 0xe5, + 0x69, 0xb1, 0xe8, 0x90, 0xf7, 0xa7, 0x24, 0x4a, 0xfd, 0xdb, 0x05, 0xc9, 0x29, 0xe0, 0x1a, 0x3f, + 0x84, 0x8b, 0xf7, 0x2b, 0xa8, 0x30, 0xbf, 0x72, 0x43, 0x18, 0xc0, 0x63, 0x21, 0xab, 0xd4, 0x55, + 0x12, 0x7c, 0x8c, 0x1a, 0x9f, 0x46, 0x83, 0x2b, 0xac, 0xfb, 0x0c, 0x43, 0xf7, 0x28, 0xf6, 0xba, + 0xe5, 0x41, 0x97, 0xf5, 0x1f, 0x80, 0x02, 0xd6, 0x08, 0x36, 0xc1, 0x96, 0x8d, 0x0a, 0xac, 0x11, + 0x6c, 0x12, 0x80, 0x32, 0x6c, 0xc5, 0xdb, 0xb8, 0x27, 0xac, 0x16, 0x60, 0x0d, 0x6f, 0xe3, 0x1e, + 0x01, 0x28, 0x9e, 0x43, 0x88, 0xd0, 0xa0, 0xe3, 0xd9, 0xb0, 0xc5, 0x39, 0x0a, 0x6e, 0x32, 0x58, + 0x43, 0x0f, 0xa0, 0x8d, 0xa6, 0x63, 0x52, 0x22, 0x91, 0xe8, 0xff, 0x3f, 0x8e, 0xbf, 0xd4, 0x2c, + 0xff, 0xee, 0x51, 0x13, 0xee, 0xa2, 0x09, 0x0d, 0xb1, 0x12, 0x49, 0x37, 0x52, 0x19, 0x0d, 0xdd, + 0x68, 0x19, 0x1b, 0x3e, 0xb4, 0xe1, 0x10, 0x8f, 0x4a, 0xdc, 0x61, 0x00, 0xc2, 0xe1, 0x89, 0x76, + 0x2a, 0x3e, 0xb8, 0x9d, 0xfe, 0xf7, 0x50, 0x34, 0xda, 0x6e, 0xd1, 0x60, 0xcb, 0xf1, 0x8e, 0x9a, + 0xea, 0x61, 0x9b, 0xea, 0x1c, 0x1a, 0x59, 0xf5, 0x9a, 0xb0, 0xcc, 0xe4, 0xad, 0x35, 0xd6, 0xeb, + 0x96, 0x8b, 0xbe, 0xd7, 0xe4, 0x4b, 0xcc, 0x10, 0xc9, 0xe8, 0x6a, 0x7e, 0x00, 0x74, 0x23, 0x31, + 0x9d, 0xe9, 0x07, 0x82, 0x4e, 0x20, 0x05, 0xdd, 0x8a, 0xe3, 0x05, 0xa2, 0xe1, 0x22, 0x3a, 0xd7, + 0xf1, 0x02, 0x12, 0x22, 0xf1, 0x73, 0x08, 0xad, 0x55, 0x57, 0xde, 0xa2, 0x1e, 0xa8, 0x8b, 0x8f, + 0x45, 0x30, 0xd7, 0xf7, 0x38, 0x88, 0x48, 0x68, 0xbc, 0x86, 0x46, 0x97, 0x5d, 0xea, 0x41, 0xf2, + 0x04, 0x78, 0x00, 0x13, 0x97, 0x9f, 0x4d, 0xa8, 0x56, 0xb4, 0xfb, 0xac, 0xf8, 0x1b, 0x91, 0xf3, + 0xf9, 0xc5, 0x09, 0x7f, 0x92, 0x58, 0x10, 0xbe, 0x86, 0x86, 0x2b, 0xdc, 0xcf, 0x2b, 0x81, 0xc8, + 0x48, 0x65, 0x0b, 0xec, 0x0f, 0x47, 0xf1, 0x45, 0xa1, 0x01, 0xff, 0x13, 0x41, 0xae, 0x5f, 0x40, + 0x53, 0xc9, 0xc7, 0xe0, 0x12, 0x1a, 0xa9, 0x2e, 0xdf, 0xba, 0xb5, 0x50, 0x5d, 0x9b, 0x1a, 0xc0, + 0x45, 0x34, 0xb8, 0xba, 0x70, 0xab, 0x36, 0x95, 0xd3, 0xbf, 0x26, 0x59, 0x10, 0xd6, 0xb5, 0x8e, + 0x22, 0xb8, 0x7b, 0x0a, 0x8b, 0x4c, 0x41, 0xd8, 0x72, 0xcd, 0x33, 0x6c, 0xbf, 0x6d, 0x05, 0x01, + 0x35, 0xc5, 0x2c, 0x01, 0x61, 0xbd, 0xe0, 0x3e, 0x49, 0xe1, 0xf1, 0x45, 0x34, 0x0e, 0x30, 0x11, + 0xc9, 0x33, 0xa1, 0xf7, 0x0a, 0x06, 0xef, 0x3e, 0x51, 0x91, 0xfa, 0xef, 0xc5, 0x41, 0xdc, 0x25, + 0x6a, 0x1c, 0xd4, 0xc0, 0xdf, 0xbf, 0x91, 0xf6, 0xd2, 0x7f, 0x6e, 0x90, 0x6f, 0xc9, 0xf3, 0x14, + 0x97, 0xfd, 0x50, 0xe5, 0xd5, 0xd0, 0x37, 0x14, 0x9a, 0x9c, 0x88, 0x34, 0x01, 0xd0, 0x94, 0x06, + 0xb8, 0x1f, 0x79, 0x11, 0x0d, 0xdf, 0xa4, 0xc1, 0xa6, 0x63, 0x8a, 0x0d, 0xd0, 0x99, 0x5e, 0xb7, + 0x3c, 0xd5, 0x06, 0x88, 0xe4, 0xef, 0x09, 0x1a, 0x7c, 0x17, 0xe1, 0xba, 0x49, 0xed, 0xc0, 0x0a, + 0xb6, 0x2b, 0x41, 0xe0, 0x59, 0xeb, 0x9d, 0x80, 0xfa, 0x42, 0x6f, 0x27, 0x53, 0xeb, 0x94, 0x55, + 0xc8, 0x0f, 0x83, 0x3d, 0xcf, 0x19, 0x23, 0x22, 0x8f, 0xc5, 0xfe, 0x63, 0xb7, 0x3c, 0xcc, 0x69, + 0x48, 0x86, 0x58, 0xfc, 0x26, 0x1a, 0xbd, 0x79, 0xa3, 0x52, 0xa3, 0xf7, 0xac, 0x26, 0x15, 0x9b, + 0x17, 0x4f, 0x44, 0x5a, 0x0c, 0x11, 0x91, 0x4a, 0x20, 0xff, 0xa1, 0x7d, 0xc7, 0x68, 0x98, 0x00, + 0x97, 0xf3, 0x1f, 0x22, 0x62, 0xd6, 0x5b, 0x78, 0x26, 0x85, 0x88, 0x2e, 0x44, 0xbd, 0x45, 0xcd, + 0xaf, 0x48, 0xea, 0x8a, 0x63, 0x13, 0xbd, 0xa5, 0xb8, 0x87, 0xde, 0xf2, 0x97, 0x39, 0x34, 0x45, + 0xa8, 0xef, 0x74, 0xbc, 0xf8, 0x0b, 0xf0, 0x39, 0x34, 0x28, 0x6d, 0xd2, 0x43, 0xd4, 0x24, 0xb1, + 0x33, 0x0c, 0x78, 0xbc, 0x8a, 0x46, 0x16, 0xee, 0xbb, 0x96, 0x47, 0x7d, 0xd1, 0x47, 0x76, 0x5a, + 0x21, 0x3e, 0x25, 0x56, 0x88, 0xd3, 0x94, 0xb3, 0xa4, 0x16, 0x87, 0x1c, 0x0c, 0x19, 0x25, 0xae, + 0x69, 0x04, 0xd4, 0x9c, 0xdf, 0x16, 0xbe, 0x3f, 0xcf, 0x28, 0xe1, 0xc0, 0xc6, 0xfa, 0xb6, 0x92, + 0x51, 0x12, 0x92, 0xe2, 0xb3, 0xa8, 0xb0, 0xb6, 0xb6, 0x24, 0x3a, 0x0f, 0x24, 0xda, 0x05, 0x81, + 0x9c, 0x32, 0xc3, 0xb0, 0xfa, 0x97, 0xf3, 0x08, 0xb1, 0x3e, 0x5a, 0xf5, 0xa8, 0x11, 0xec, 0x8f, + 0xa1, 0x99, 0x47, 0xc5, 0x50, 0xe1, 0x62, 0x7c, 0x68, 0x21, 0x6f, 0xb2, 0x21, 0x92, 0xcf, 0x0e, + 0xf1, 0xcc, 0x99, 0x23, 0x4e, 0x8b, 0xf2, 0x64, 0x11, 0x91, 0x73, 0xe8, 0x31, 0x00, 0xe1, 0x70, + 0xfc, 0x1c, 0x1a, 0x15, 0x8d, 0xec, 0x84, 0x91, 0x6c, 0xbe, 0xe4, 0x0b, 0x81, 0x24, 0xc6, 0xeb, + 0xdf, 0xc9, 0x71, 0xa5, 0xd4, 0x68, 0x8b, 0x1e, 0x5c, 0xa5, 0xe8, 0x5f, 0xcc, 0x21, 0xcc, 0x84, + 0xad, 0x18, 0xbe, 0xbf, 0xe5, 0x78, 0x66, 0x75, 0xd3, 0xb0, 0x37, 0xf6, 0xe5, 0x73, 0xf4, 0xbf, + 0x19, 0x42, 0xc7, 0x94, 0x5d, 0xe5, 0x03, 0xde, 0xdf, 0x2e, 0xa8, 0xfd, 0x0d, 0x16, 0xef, 0xd0, + 0xdf, 0xe4, 0xc5, 0x3b, 0xef, 0x79, 0x1f, 0x41, 0xa3, 0xe2, 0x9b, 0xeb, 0x35, 0xd1, 0xf3, 0x60, + 0xda, 0xb7, 0x4c, 0x12, 0x23, 0xf0, 0xf3, 0x68, 0x4c, 0xfc, 0x60, 0xd6, 0x3f, 0x8c, 0xcf, 0x42, + 0x3f, 0xf6, 0x19, 0x80, 0x28, 0x68, 0xfc, 0x02, 0x1a, 0x65, 0x9d, 0x73, 0x03, 0xb2, 0x34, 0x47, + 0xe2, 0x64, 0x46, 0x33, 0x04, 0xca, 0x26, 0x21, 0xa2, 0x64, 0x53, 0x8a, 0xd8, 0x6b, 0x28, 0xc6, + 0x53, 0x0a, 0xdf, 0x6b, 0x90, 0xa7, 0x14, 0xb1, 0xeb, 0xf0, 0x0e, 0x2a, 0x55, 0x6c, 0xdb, 0xe1, + 0xd9, 0xc2, 0xbe, 0x08, 0xa8, 0xf5, 0x9d, 0x4b, 0xce, 0x42, 0x8a, 0x5d, 0x4c, 0x9f, 0x39, 0x99, + 0xc8, 0x02, 0xf1, 0x65, 0xd6, 0x10, 0xf7, 0x2c, 0xba, 0x45, 0x3d, 0x91, 0xb2, 0x00, 0x41, 0x45, + 0x4f, 0xc0, 0xe4, 0x84, 0xbb, 0x90, 0x0e, 0xcf, 0xa3, 0xf1, 0x15, 0xcf, 0x71, 0x1d, 0x9f, 0x9a, + 0x5c, 0x51, 0x25, 0x60, 0x3c, 0xdd, 0xeb, 0x96, 0x35, 0x57, 0x20, 0x1a, 0xa0, 0x31, 0x89, 0x5d, + 0x65, 0xc1, 0x77, 0xd0, 0x8c, 0x50, 0x26, 0x35, 0xc3, 0x16, 0xad, 0xd7, 0x7c, 0x6d, 0x0c, 0x12, + 0xcd, 0x70, 0xb2, 0x33, 0xd4, 0x6b, 0xf3, 0x67, 0xc2, 0x60, 0x9e, 0x27, 0x60, 0x0d, 0xcb, 0x94, + 0x9b, 0x3a, 0x53, 0x9e, 0xbe, 0xc5, 0x16, 0x90, 0xe1, 0x4f, 0xfc, 0xbc, 0x9a, 0x69, 0x9c, 0x8b, + 0x83, 0x49, 0x22, 0x63, 0x4f, 0x49, 0x2d, 0x66, 0x8b, 0xd7, 0x37, 0x2c, 0xdb, 0x14, 0xd1, 0x21, + 0x58, 0xbc, 0xde, 0xb5, 0x6c, 0x93, 0x00, 0x94, 0x61, 0xa5, 0xf4, 0x2b, 0xc0, 0xb2, 0x09, 0x89, + 0x4f, 0x43, 0xfa, 0xd7, 0x73, 0x89, 0xd1, 0xb6, 0x8f, 0x86, 0x4c, 0xe9, 0xfe, 0x85, 0x3e, 0xdd, + 0x5f, 0xff, 0x4a, 0x1e, 0x95, 0xd8, 0x82, 0xec, 0x86, 0xe3, 0x6d, 0x19, 0xde, 0xfe, 0x44, 0xa9, + 0x1e, 0xdb, 0xa6, 0x95, 0xe4, 0xef, 0x0d, 0xee, 0xc2, 0xdf, 0x3b, 0x8d, 0x06, 0xa5, 0x7d, 0x56, + 0x1e, 0x35, 0x62, 0x8b, 0x5a, 0x80, 0xea, 0xff, 0x21, 0x8f, 0xd0, 0x67, 0x2e, 0x5d, 0x3a, 0xc4, + 0x0a, 0xd2, 0xff, 0x4f, 0x0e, 0x4d, 0x8a, 0x30, 0xa6, 0x94, 0x6e, 0x3f, 0x12, 0x06, 0xa0, 0xe5, + 0x11, 0xc5, 0x41, 0x24, 0xc4, 0x31, 0x53, 0xb3, 0x70, 0xdf, 0x0a, 0x20, 0x92, 0x23, 0xe5, 0xdb, + 0x53, 0x01, 0x93, 0x4d, 0x4d, 0x48, 0x87, 0x9f, 0x0f, 0x03, 0xb4, 0x85, 0xd8, 0xbe, 0x32, 0x86, + 0x85, 0xcc, 0x20, 0xad, 0xfe, 0x8d, 0x41, 0x34, 0xb8, 0x70, 0x9f, 0x36, 0x0f, 0x78, 0xd3, 0x48, + 0xcb, 0xbe, 0xc1, 0x3d, 0x2e, 0xfb, 0x1e, 0x65, 0xc7, 0xe9, 0xb5, 0xb8, 0x3d, 0x87, 0xd5, 0xc7, + 0x27, 0x5a, 0x3e, 0xf9, 0xf8, 0xb0, 0xa5, 0x0f, 0xde, 0x86, 0xe5, 0x6f, 0x15, 0x50, 0x61, 0xb5, + 0xba, 0x72, 0xd4, 0x6f, 0xf6, 0xb5, 0xdf, 0xec, 0x1c, 0xd1, 0xd7, 0xa3, 0x20, 0x5d, 0x31, 0x4e, + 0xd2, 0x48, 0xc4, 0xe3, 0xbe, 0x94, 0x47, 0xa3, 0xab, 0x9d, 0x75, 0x7f, 0xdb, 0x0f, 0x68, 0xfb, + 0x80, 0xb7, 0x66, 0xe8, 0x5f, 0x0c, 0x66, 0xf9, 0x17, 0xf8, 0x6c, 0x68, 0x19, 0xa5, 0x85, 0x54, + 0x64, 0x19, 0x43, 0x7b, 0xf8, 0x4b, 0x79, 0x34, 0xc5, 0x57, 0xe7, 0x35, 0xcb, 0x6f, 0x3e, 0x86, + 0x94, 0x94, 0xfd, 0xd7, 0xca, 0xde, 0x22, 0x5a, 0x0f, 0x91, 0xe8, 0xa3, 0xff, 0xc7, 0x3c, 0x2a, + 0x55, 0x3a, 0xc1, 0x66, 0x25, 0x80, 0xc9, 0xe5, 0x50, 0x4e, 0xf3, 0xbf, 0x93, 0x43, 0x93, 0xec, + 0x45, 0xd6, 0x9c, 0xbb, 0xd4, 0x7e, 0x0c, 0xeb, 0x44, 0x79, 0xbd, 0x97, 0x7f, 0xc4, 0xf5, 0x5e, + 0xa8, 0xcb, 0xc2, 0x2e, 0xd7, 0xbd, 0xdf, 0xc9, 0x21, 0xc4, 0x96, 0x81, 0x1f, 0x92, 0xcf, 0x78, + 0x0c, 0xeb, 0x88, 0xfd, 0xfc, 0x8c, 0xef, 0xe5, 0xd0, 0xcc, 0x9a, 0xc7, 0x26, 0x72, 0x53, 0xcc, + 0xe7, 0x07, 0xbc, 0x5d, 0xd2, 0x1f, 0x74, 0xc0, 0x5b, 0xe8, 0x07, 0x39, 0xf4, 0x84, 0xfa, 0x41, + 0x1f, 0x06, 0x2b, 0xf0, 0xfb, 0x39, 0x74, 0xfc, 0x75, 0x38, 0x83, 0x1d, 0xc5, 0x18, 0x3f, 0x7c, + 0x5f, 0x74, 0xc0, 0x7b, 0xde, 0x77, 0x73, 0xe8, 0xd8, 0x72, 0xbd, 0x56, 0xfd, 0xb0, 0xb4, 0x50, + 0xea, 0x7b, 0x3e, 0x04, 0xed, 0xb3, 0x5a, 0xb9, 0xb9, 0xf4, 0x61, 0x6a, 0x1f, 0xe5, 0x7b, 0x0e, + 0x78, 0xfb, 0xfc, 0xa7, 0x61, 0x54, 0x62, 0xeb, 0x5a, 0x11, 0xd3, 0x3b, 0xd4, 0x9e, 0xfe, 0x65, + 0x54, 0x12, 0x6a, 0x80, 0x25, 0xa5, 0x74, 0x70, 0x42, 0x14, 0x30, 0x68, 0xc0, 0xd2, 0x52, 0x26, + 0x62, 0x2b, 0xae, 0xb7, 0xa8, 0xb7, 0x2e, 0x27, 0x2b, 0xdd, 0xa3, 0xde, 0x3a, 0x01, 0x28, 0x5e, + 0x8a, 0x37, 0x25, 0x2b, 0x2b, 0x75, 0x38, 0x2d, 0x2d, 0x56, 0xaa, 0x70, 0xfc, 0x3b, 0x0a, 0x4b, + 0x1b, 0xae, 0xc5, 0xcf, 0x59, 0xcb, 0x89, 0x92, 0x49, 0x4e, 0x7c, 0x0b, 0x4d, 0x87, 0xb0, 0xf8, + 0xa8, 0x70, 0x31, 0x43, 0x5c, 0xd6, 0x21, 0xe1, 0x34, 0x2b, 0x7e, 0x0d, 0x8d, 0x85, 0x40, 0x88, + 0x59, 0x8f, 0x82, 0xa8, 0x27, 0x7b, 0xdd, 0xf2, 0xc9, 0x48, 0xd4, 0x5d, 0x4b, 0x49, 0x04, 0x55, + 0x18, 0x64, 0x01, 0xb0, 0xec, 0x44, 0x19, 0x02, 0x12, 0x1b, 0xae, 0x0a, 0x03, 0x7e, 0x01, 0x04, + 0xb8, 0x8e, 0xed, 0x53, 0x88, 0xf1, 0x95, 0x20, 0x93, 0x07, 0x36, 0x3d, 0x3d, 0x01, 0xe7, 0xf9, + 0x5a, 0x0a, 0x19, 0x5e, 0x46, 0x28, 0x8e, 0xc5, 0x88, 0xac, 0xd8, 0x5d, 0x47, 0x89, 0x24, 0x11, + 0xfa, 0x1f, 0xb0, 0xf5, 0x9b, 0xeb, 0x46, 0x3d, 0xf9, 0x79, 0x34, 0x5c, 0x71, 0xdd, 0xdb, 0xa4, + 0x2e, 0xa2, 0x93, 0x90, 0xb4, 0x69, 0xb8, 0x6e, 0xa3, 0xe3, 0x59, 0xf2, 0x8e, 0x0b, 0x27, 0xc2, + 0x55, 0x34, 0x5e, 0x71, 0xdd, 0x95, 0xce, 0x7a, 0xcb, 0x6a, 0x4a, 0xd5, 0x0b, 0x78, 0x09, 0x0c, + 0xd7, 0x6d, 0xb8, 0x80, 0x49, 0xd6, 0x7e, 0x50, 0x79, 0xf0, 0x3b, 0x68, 0xb4, 0xe2, 0xba, 0xe2, + 0xf0, 0x7c, 0x01, 0xf6, 0x34, 0xf4, 0xf0, 0x9b, 0xa4, 0x77, 0x9b, 0x8d, 0x88, 0xf8, 0x39, 0xf9, + 0xd3, 0x62, 0x8f, 0x63, 0x86, 0x3d, 0x28, 0x75, 0x48, 0x3e, 0x16, 0x89, 0x3f, 0x8e, 0x46, 0x2a, + 0xae, 0x2b, 0x85, 0x07, 0x20, 0x94, 0xca, 0xb8, 0x12, 0x4d, 0x14, 0x92, 0x9d, 0x7a, 0x05, 0x4d, + 0xa8, 0x0f, 0xdb, 0xd5, 0x41, 0xfa, 0x9f, 0xe6, 0xe0, 0x83, 0x0e, 0xf8, 0x8e, 0xe1, 0x15, 0x54, + 0xa8, 0xb8, 0xae, 0x30, 0x27, 0xc7, 0x32, 0xda, 0x23, 0x99, 0x16, 0x57, 0x71, 0xdd, 0xf0, 0xd3, + 0xf9, 0x9e, 0xfe, 0xe1, 0xfa, 0xf4, 0x6f, 0xf3, 0x4f, 0x3f, 0xe0, 0x5b, 0xf0, 0xdf, 0x28, 0xa0, + 0xc9, 0x8a, 0xeb, 0x1e, 0xd5, 0x07, 0x78, 0x5c, 0xc9, 0x77, 0x97, 0x10, 0x92, 0xcc, 0xe3, 0x48, + 0x94, 0xdb, 0x52, 0x92, 0x4c, 0xa3, 0x96, 0x23, 0x12, 0x51, 0xd8, 0xfd, 0x8a, 0xbb, 0xea, 0x7e, + 0xbf, 0xa1, 0x34, 0x1c, 0x9c, 0x75, 0x3e, 0x6a, 0xb8, 0xa1, 0x3d, 0x79, 0x54, 0x13, 0xb2, 0x32, + 0x45, 0x66, 0xbd, 0x48, 0x41, 0x08, 0xcf, 0x79, 0x34, 0x19, 0xaa, 0x61, 0x99, 0x24, 0x41, 0x1b, + 0xb6, 0xe1, 0xc8, 0xae, 0xda, 0xf0, 0xab, 0x79, 0x34, 0x1d, 0xb7, 0xe1, 0xe3, 0x70, 0x4c, 0xe7, + 0x10, 0xe2, 0x41, 0xca, 0x68, 0x23, 0x71, 0x9c, 0xa7, 0x84, 0xfb, 0x00, 0x15, 0x29, 0xe1, 0x31, + 0x49, 0xb4, 0xab, 0x50, 0xc8, 0xdc, 0x55, 0xb8, 0x80, 0x8a, 0xc4, 0xd8, 0x7a, 0xb3, 0x43, 0xbd, + 0x6d, 0x31, 0x95, 0x42, 0x28, 0xdd, 0x33, 0xb6, 0x1a, 0x9f, 0x67, 0x40, 0x12, 0xa1, 0xb1, 0x1e, + 0x25, 0x03, 0x4a, 0xc1, 0x63, 0x9e, 0x0c, 0x18, 0xa5, 0x00, 0x0a, 0x25, 0x0d, 0xef, 0x4a, 0x49, + 0x3f, 0x18, 0x46, 0x53, 0x35, 0x23, 0x30, 0xd6, 0x0d, 0x9f, 0x4a, 0x0b, 0x89, 0xc9, 0x10, 0xc6, + 0x3a, 0x82, 0x15, 0x55, 0xcc, 0x82, 0xc4, 0x33, 0x73, 0xbd, 0xe1, 0x73, 0xa8, 0x5c, 0x18, 0x28, + 0xc1, 0x80, 0x3f, 0x19, 0xcb, 0x8d, 0x6a, 0x2a, 0x71, 0x77, 0x06, 0x34, 0x66, 0xae, 0x37, 0x5c, + 0x01, 0x26, 0x29, 0x42, 0x7c, 0x11, 0x95, 0x42, 0x18, 0x73, 0x9e, 0x0a, 0xf1, 0x37, 0x9b, 0xeb, + 0xcc, 0x77, 0x22, 0x32, 0x1a, 0xbf, 0x84, 0xc6, 0xc2, 0x9f, 0x92, 0x5b, 0x02, 0xbe, 0x96, 0xb9, + 0x9e, 0x72, 0x1c, 0x65, 0x52, 0x99, 0x15, 0xc6, 0xe7, 0x90, 0xc2, 0x9a, 0xa8, 0xa7, 0xa6, 0x90, + 0xe2, 0xcf, 0xa3, 0x89, 0xf0, 0xb7, 0x70, 0xb6, 0x86, 0xc1, 0xd9, 0xba, 0x18, 0x6a, 0x3e, 0xa9, + 0xd6, 0x59, 0x95, 0x9c, 0xbb, 0x5d, 0x4f, 0x0a, 0xb7, 0xeb, 0x98, 0xb9, 0x9e, 0xf6, 0xba, 0x12, + 0x0f, 0xc0, 0x75, 0x34, 0x1d, 0x42, 0x2a, 0x6f, 0xaf, 0x12, 0xba, 0xc1, 0x46, 0xe5, 0x48, 0xec, + 0x2c, 0x9b, 0xeb, 0x0d, 0xa8, 0xb4, 0x06, 0x08, 0xd9, 0x67, 0x4f, 0x71, 0xe1, 0x16, 0x3a, 0xad, + 0x00, 0x4d, 0x7f, 0xd3, 0xba, 0x13, 0x08, 0x4f, 0xb7, 0x5e, 0x13, 0xcb, 0x01, 0x28, 0xba, 0x13, + 0x49, 0xe5, 0x34, 0x61, 0x85, 0xa9, 0x86, 0x52, 0xb6, 0x6f, 0x47, 0x69, 0x78, 0x15, 0xcd, 0x84, + 0xf8, 0xd7, 0xab, 0x2b, 0x2b, 0x9e, 0xf3, 0x2e, 0x6d, 0x06, 0xf5, 0x9a, 0x58, 0x29, 0xc0, 0x59, + 0x2f, 0x73, 0xbd, 0xb1, 0xd1, 0x74, 0x59, 0xa7, 0x60, 0x38, 0x55, 0x78, 0x26, 0x33, 0x7e, 0x0b, + 0x1d, 0x97, 0xe0, 0x75, 0xdb, 0x0f, 0x0c, 0xbb, 0x49, 0xeb, 0x35, 0xb1, 0x7c, 0x80, 0xa5, 0x8c, + 0x90, 0x6a, 0x09, 0xa4, 0x2a, 0x36, 0x9b, 0xfd, 0x54, 0x05, 0x1d, 0xcb, 0x68, 0xa9, 0x5d, 0xf9, + 0xac, 0x5f, 0xca, 0xc7, 0x9d, 0xe3, 0x80, 0x3b, 0xae, 0xf3, 0xa8, 0x18, 0x7e, 0x89, 0x98, 0x42, + 0xb4, 0x7e, 0x1d, 0x3c, 0x29, 0x23, 0xc4, 0x2b, 0xea, 0x38, 0xe0, 0xce, 0xec, 0xe3, 0x50, 0xc7, + 0xfb, 0xb9, 0x58, 0x1d, 0x07, 0xdc, 0xc1, 0xfd, 0x6e, 0x21, 0x1e, 0xd9, 0x47, 0x5e, 0xee, 0xe3, + 0x72, 0x96, 0xe2, 0x8d, 0xd3, 0xe1, 0x5d, 0x24, 0x90, 0xc9, 0x5d, 0x73, 0xe4, 0x11, 0xbb, 0xe6, + 0x0f, 0xd3, 0xed, 0xc9, 0x1d, 0x90, 0x03, 0xd9, 0x9e, 0x8f, 0x61, 0xb0, 0xe2, 0xcb, 0x68, 0x3c, + 0xfc, 0x9f, 0x7b, 0x6a, 0x43, 0xd2, 0xc1, 0xb3, 0x75, 0xe1, 0xa8, 0xa9, 0x24, 0xf8, 0xb3, 0xe8, + 0xa4, 0x02, 0x58, 0x31, 0x3c, 0xa3, 0x4d, 0x03, 0xea, 0x71, 0x1f, 0x41, 0xd4, 0xf9, 0x0b, 0xb9, + 0x1b, 0x6e, 0x84, 0x96, 0x4b, 0xe5, 0xf5, 0x91, 0x20, 0x75, 0x8e, 0x91, 0x5d, 0xec, 0xaa, 0xff, + 0x79, 0x1e, 0x8d, 0xaf, 0x38, 0x7e, 0xb0, 0xe1, 0x51, 0x7f, 0xc5, 0xf0, 0x7c, 0x7a, 0x78, 0x5b, + 0xf4, 0x45, 0x34, 0x0e, 0x89, 0xc0, 0x6d, 0x6a, 0x07, 0x52, 0x01, 0x40, 0x5e, 0x0c, 0x23, 0x44, + 0x80, 0xdb, 0x48, 0x54, 0x42, 0x5c, 0x46, 0x43, 0xbc, 0x0f, 0x48, 0xe9, 0xd9, 0xbc, 0x03, 0x70, + 0xb8, 0xfe, 0xd5, 0x02, 0x1a, 0x0b, 0xb5, 0x3c, 0x6f, 0x1d, 0xd4, 0xe3, 0xd6, 0xfb, 0xab, 0xe4, + 0x39, 0x84, 0x56, 0x1c, 0x2f, 0x30, 0x5a, 0x52, 0x45, 0x66, 0x58, 0x32, 0xb8, 0x00, 0xe5, 0x3c, + 0x12, 0x09, 0x9e, 0x45, 0x48, 0x1a, 0x60, 0x23, 0x30, 0xc0, 0x26, 0x7a, 0xdd, 0x32, 0x8a, 0xc7, + 0x15, 0x91, 0x28, 0xf4, 0x5f, 0xcb, 0xa3, 0xc9, 0xb0, 0x91, 0x16, 0xee, 0xd3, 0x66, 0x27, 0x38, + 0xc4, 0x83, 0x41, 0xd5, 0xf6, 0xd0, 0x03, 0xb5, 0xad, 0xff, 0xad, 0x64, 0x48, 0xaa, 0x2d, 0xe7, + 0xc8, 0x90, 0xfc, 0x6b, 0xf4, 0x71, 0xfd, 0x0b, 0x05, 0x34, 0x13, 0x6a, 0xfd, 0x46, 0xc7, 0x06, + 0x37, 0xa1, 0x6a, 0xb4, 0x5a, 0x87, 0x79, 0x5e, 0x2e, 0x85, 0x8a, 0x58, 0x16, 0x27, 0x6b, 0xc6, + 0xf9, 0x26, 0xdb, 0x1d, 0x01, 0x6e, 0x38, 0x96, 0x49, 0x64, 0x22, 0xfc, 0x1a, 0x1a, 0x0b, 0x7f, + 0x56, 0xbc, 0x8d, 0x70, 0x32, 0x86, 0xa5, 0x73, 0xc4, 0x64, 0x78, 0x1b, 0x4a, 0xad, 0x6b, 0x99, + 0x41, 0xff, 0xca, 0x30, 0x3a, 0xf5, 0xb6, 0x65, 0x9b, 0xce, 0x96, 0x2f, 0xaa, 0x9e, 0x1d, 0x7c, + 0xa7, 0xf7, 0xf1, 0x15, 0x1b, 0x8a, 0x3d, 0x93, 0xa1, 0x5d, 0xb8, 0xad, 0x6f, 0xa2, 0xe3, 0x49, + 0x95, 0x7a, 0xd1, 0xc1, 0x52, 0xd1, 0x3a, 0x5b, 0x9c, 0xa0, 0x11, 0x16, 0x9e, 0x13, 0xf1, 0x27, + 0x92, 0xcd, 0x99, 0xac, 0x5c, 0x37, 0xf2, 0x30, 0x95, 0xeb, 0x3e, 0x86, 0x86, 0x6b, 0x4e, 0xdb, + 0xb0, 0xc2, 0x14, 0x5f, 0x18, 0xc5, 0xd1, 0x73, 0x01, 0x43, 0x04, 0x05, 0x93, 0x2f, 0x1e, 0x0c, + 0x4d, 0x36, 0x1a, 0xcb, 0x0f, 0x19, 0x3a, 0x3e, 0xf5, 0x88, 0x4c, 0x84, 0x1d, 0x34, 0x2e, 0x1e, + 0x27, 0xa2, 0x45, 0x08, 0xa2, 0x45, 0x2f, 0x84, 0x3a, 0xea, 0xdf, 0xad, 0x66, 0x15, 0x3e, 0x1e, + 0x36, 0x82, 0xb7, 0x0b, 0x3f, 0x86, 0xc7, 0x8d, 0x88, 0x2a, 0x5f, 0x52, 0x02, 0x18, 0x99, 0x52, + 0x5a, 0x09, 0x60, 0x65, 0x64, 0xa2, 0x53, 0xd7, 0x11, 0x4e, 0x3f, 0x6c, 0x57, 0x91, 0x8f, 0xff, + 0x9e, 0x47, 0x38, 0xb1, 0x80, 0x58, 0x38, 0xc4, 0x7e, 0x90, 0xfe, 0xf3, 0x39, 0x34, 0x9d, 0x3a, + 0x12, 0x8d, 0xaf, 0x20, 0xc4, 0x21, 0xd2, 0x59, 0x30, 0x38, 0x44, 0x18, 0x1f, 0x93, 0x16, 0x73, + 0x40, 0x4c, 0x86, 0xe7, 0x50, 0x91, 0xff, 0x8a, 0x2e, 0x21, 0x48, 0xb2, 0x74, 0x3a, 0x96, 0x49, + 0x22, 0xa2, 0xf8, 0x29, 0x70, 0x1d, 0x47, 0x21, 0x93, 0x25, 0xd8, 0x76, 0xa3, 0xa7, 0x30, 0x32, + 0xfd, 0xdb, 0x39, 0x34, 0x16, 0xbd, 0x70, 0xc5, 0xdc, 0xaf, 0xa6, 0x1b, 0x16, 0xa7, 0xcb, 0x0b, + 0x0f, 0x3a, 0x5d, 0x9e, 0x30, 0x2a, 0x1c, 0xab, 0xff, 0x76, 0x0e, 0x4d, 0x46, 0xb4, 0xfb, 0x18, + 0x63, 0xd9, 0xf3, 0x87, 0xfc, 0x8f, 0x1c, 0xd2, 0xe6, 0xad, 0x56, 0xcb, 0xb2, 0x37, 0xea, 0xf6, + 0x1d, 0xc7, 0x6b, 0xc3, 0xe1, 0xc9, 0xfd, 0x0b, 0xa2, 0xe9, 0xff, 0x35, 0x87, 0xa6, 0xc5, 0x0b, + 0x55, 0x0d, 0xcf, 0xdc, 0xbf, 0xe8, 0x66, 0xf2, 0x4d, 0xf6, 0xaf, 0x95, 0x21, 0x3f, 0x7a, 0xc9, + 0x69, 0xde, 0xfd, 0x10, 0xa4, 0x79, 0xb3, 0xcf, 0x38, 0xe0, 0xa9, 0x68, 0xff, 0x2d, 0x87, 0x66, + 0x08, 0x6d, 0x3a, 0xf7, 0xa8, 0xb7, 0x5d, 0x75, 0x4c, 0xfa, 0x3a, 0xb5, 0xa9, 0xb7, 0x5f, 0x9d, + 0xf4, 0xd7, 0xa1, 0x9e, 0x44, 0xfc, 0x32, 0xb7, 0x7d, 0x6a, 0x1e, 0x9c, 0x22, 0x24, 0xfa, 0x2f, + 0x8f, 0x20, 0x2d, 0xd3, 0x33, 0x39, 0xb0, 0x93, 0x7a, 0x5f, 0x77, 0x73, 0xf0, 0x71, 0xb9, 0x9b, + 0x43, 0xbb, 0x73, 0x37, 0x87, 0x77, 0xeb, 0x6e, 0x8e, 0x3c, 0x8c, 0xbb, 0xd9, 0x4e, 0xba, 0x9b, + 0x45, 0x70, 0x37, 0xaf, 0xec, 0xe8, 0x6e, 0x2e, 0xd8, 0xe6, 0x23, 0x3a, 0x9b, 0x07, 0xb6, 0xf4, + 0xe6, 0x23, 0x78, 0xc9, 0xf8, 0x3c, 0x33, 0x6e, 0x4d, 0xc7, 0x33, 0x29, 0x2f, 0xa5, 0x59, 0xe4, + 0xd1, 0x60, 0x4f, 0xc0, 0x48, 0x84, 0x4d, 0xd5, 0x31, 0x1d, 0x7f, 0x98, 0x3a, 0xa6, 0x8f, 0xc1, + 0x0b, 0xff, 0x5e, 0x0e, 0x4d, 0x57, 0xa9, 0x17, 0x58, 0x77, 0xac, 0xa6, 0x11, 0x3c, 0x8e, 0x2d, + 0xc8, 0x0a, 0x9a, 0x94, 0x04, 0x4a, 0xf7, 0xbb, 0xc1, 0xb9, 0xe8, 0x26, 0xf5, 0x02, 0x70, 0x25, + 0xe5, 0x8c, 0x80, 0x04, 0x3d, 0x7b, 0x7c, 0x58, 0x4b, 0x48, 0x8c, 0xdd, 0xe8, 0xf1, 0x21, 0x9c, + 0x2b, 0xd2, 0x12, 0xbf, 0x48, 0x44, 0xaf, 0x7f, 0x2d, 0x87, 0xce, 0x11, 0x6a, 0xd3, 0x2d, 0x63, + 0xbd, 0x45, 0x25, 0xc1, 0xc2, 0xb6, 0xb3, 0x71, 0x6f, 0xf9, 0x6d, 0x23, 0x68, 0x6e, 0xee, 0xe9, + 0x2b, 0x6f, 0xa8, 0x77, 0xac, 0xed, 0xc2, 0x3a, 0x29, 0x7c, 0xfa, 0x0f, 0x73, 0x68, 0xe4, 0xb6, + 0x7d, 0xd7, 0x76, 0xb6, 0xf6, 0x56, 0x71, 0xea, 0x0a, 0x2a, 0x09, 0x31, 0x92, 0xc6, 0xf9, 0xa5, + 0x79, 0x1c, 0xdc, 0xe0, 0x37, 0xeb, 0xc9, 0x54, 0xf8, 0x95, 0x88, 0x09, 0xd2, 0x54, 0xa4, 0x4b, + 0xdc, 0x42, 0xa6, 0xc4, 0x65, 0x7a, 0x32, 0x39, 0x3e, 0x2d, 0x2e, 0x73, 0x90, 0x8e, 0x7e, 0xb2, + 0x57, 0xe1, 0x77, 0x39, 0xe8, 0x7f, 0x7d, 0x09, 0x0d, 0x2d, 0xdb, 0x74, 0xf9, 0x0e, 0xbe, 0x24, + 0x55, 0xd5, 0x12, 0xdf, 0x35, 0x2d, 0xeb, 0x09, 0x10, 0x8b, 0x03, 0x44, 0xaa, 0xbd, 0x75, 0x55, + 0xae, 0x35, 0x24, 0x74, 0x8b, 0x65, 0x1e, 0x8e, 0x59, 0x1c, 0x20, 0x72, 0x4d, 0xa2, 0xab, 0x72, + 0x31, 0x1e, 0xd1, 0x71, 0x14, 0x2e, 0x8e, 0x09, 0xb9, 0x84, 0xf3, 0xb2, 0x94, 0x55, 0xfb, 0x26, + 0x19, 0xdd, 0x48, 0x53, 0x2c, 0x0e, 0x90, 0xec, 0x9a, 0x39, 0xca, 0x1d, 0x3f, 0x22, 0xbe, 0x31, + 0x93, 0x98, 0x7a, 0x00, 0xb7, 0x38, 0x40, 0xd4, 0xfb, 0x80, 0xae, 0x29, 0xb7, 0xa7, 0x24, 0xd3, + 0x73, 0x24, 0xd4, 0xe2, 0x00, 0x49, 0xdc, 0xb3, 0xa2, 0x5c, 0xe5, 0x21, 0xb6, 0x7b, 0x92, 0x0f, + 0x05, 0x9c, 0xf4, 0x50, 0x7e, 0xed, 0xc7, 0xab, 0x89, 0x12, 0xfb, 0x22, 0xfd, 0xed, 0x78, 0x82, + 0x99, 0x23, 0x17, 0x07, 0x48, 0xa2, 0x20, 0xff, 0xf9, 0xb0, 0xea, 0xba, 0xb0, 0xe5, 0x13, 0x92, + 0xf3, 0x66, 0xbd, 0xc7, 0xb4, 0x14, 0x56, 0x65, 0xbf, 0x2a, 0x57, 0xdb, 0x16, 0xc6, 0x19, 0x27, + 0x9e, 0xb2, 0x60, 0x9b, 0xac, 0x75, 0x24, 0xcf, 0xe1, 0x7a, 0xb2, 0x2e, 0xad, 0xa8, 0x76, 0x7c, + 0x22, 0xc1, 0x29, 0xb0, 0x8b, 0x03, 0x24, 0x59, 0xc7, 0xf6, 0x9a, 0x52, 0x13, 0x55, 0xe4, 0x6e, + 0x27, 0xb5, 0xca, 0x50, 0x92, 0x56, 0xa1, 0x7a, 0xea, 0xf5, 0x64, 0x91, 0x4e, 0x6d, 0x3c, 0xf3, + 0xd1, 0x02, 0x2b, 0x3d, 0x3a, 0x2c, 0xea, 0x79, 0x4d, 0x29, 0xa6, 0x08, 0xf5, 0x8a, 0x33, 0x1e, + 0x6d, 0x04, 0x86, 0xfc, 0x68, 0x5e, 0x76, 0x51, 0x29, 0xeb, 0xa7, 0x4d, 0x66, 0x36, 0x28, 0xe0, + 0xa4, 0x06, 0xe5, 0x25, 0x00, 0xaf, 0x29, 0x05, 0x52, 0xb4, 0x29, 0xf5, 0xa1, 0x12, 0x8a, 0x3d, + 0x54, 0x2e, 0xa5, 0x72, 0x55, 0xae, 0x1b, 0xa2, 0x4d, 0xab, 0x0d, 0x14, 0x63, 0x58, 0x03, 0x49, + 0xf5, 0x45, 0xca, 0x50, 0x93, 0x40, 0xc3, 0x40, 0x5e, 0x8a, 0xde, 0xb0, 0xba, 0xb2, 0x38, 0x40, + 0xa0, 0x5a, 0x81, 0xce, 0xab, 0x5d, 0x68, 0xc7, 0x80, 0x62, 0x2c, 0x2a, 0x5a, 0x79, 0x9f, 0x36, + 0x17, 0x07, 0x08, 0xaf, 0x84, 0x71, 0x49, 0x3a, 0x10, 0xaf, 0xcd, 0xa8, 0x26, 0x22, 0x42, 0x30, + 0x13, 0x11, 0x1f, 0x9b, 0xbf, 0x91, 0x3e, 0x34, 0xae, 0x1d, 0x57, 0xd7, 0x0f, 0x49, 0xfc, 0xe2, + 0x00, 0x49, 0x1f, 0x34, 0xbf, 0xa6, 0x9c, 0xa3, 0xd6, 0x4e, 0x24, 0x72, 0xe2, 0x62, 0x14, 0x53, + 0x97, 0x7c, 0xe2, 0x7a, 0x39, 0xb3, 0x50, 0x95, 0x76, 0x12, 0x04, 0x3c, 0x19, 0x09, 0x48, 0x93, + 0x2c, 0x0e, 0x90, 0xcc, 0x12, 0x57, 0xd5, 0xd4, 0x69, 0x66, 0x4d, 0x53, 0x1d, 0xd7, 0x04, 0x7a, + 0x71, 0x80, 0xa4, 0xce, 0x3f, 0x5f, 0x95, 0x8f, 0x11, 0x6b, 0x4f, 0xa8, 0x8d, 0x18, 0x63, 0x58, + 0x23, 0x4a, 0xc7, 0x8d, 0xaf, 0xca, 0xa7, 0x76, 0xb5, 0x53, 0x69, 0xae, 0xd8, 0x72, 0x4a, 0xa7, + 0x7b, 0x49, 0xf6, 0x21, 0x59, 0xed, 0x49, 0xe0, 0x3f, 0x1d, 0xf2, 0x67, 0xd1, 0x2c, 0x0e, 0x90, + 0xec, 0x03, 0xb6, 0x24, 0xfb, 0x9c, 0xaa, 0x76, 0x7a, 0x27, 0x99, 0xd1, 0xdb, 0x65, 0x9f, 0x71, + 0x35, 0x76, 0x38, 0x2a, 0xaa, 0x3d, 0xa5, 0x9e, 0xe5, 0xe8, 0x4b, 0xb8, 0x38, 0x40, 0x76, 0x38, + 0x70, 0x7a, 0xbb, 0xcf, 0xb9, 0x4d, 0xed, 0x8c, 0x5a, 0xf5, 0x23, 0x93, 0x68, 0x71, 0x80, 0xf4, + 0x39, 0xf5, 0x79, 0xbb, 0xcf, 0xe1, 0x49, 0xad, 0xbc, 0xa3, 0xd8, 0x48, 0x1f, 0x7d, 0x8e, 0x5e, + 0x2e, 0x67, 0x9e, 0x60, 0xd4, 0x9e, 0x56, 0xbb, 0x6e, 0x06, 0x09, 0xeb, 0xba, 0x59, 0x67, 0x1f, + 0x97, 0x33, 0x8f, 0x10, 0x6a, 0xcf, 0xec, 0x20, 0x30, 0x7a, 0xc7, 0xcc, 0xc3, 0x87, 0xcb, 0x99, + 0x67, 0xf8, 0x34, 0x5d, 0x15, 0x98, 0x41, 0xc2, 0x04, 0x66, 0x9d, 0xfe, 0x5b, 0xce, 0x3c, 0x44, + 0xa7, 0x9d, 0xdd, 0x41, 0x60, 0xfc, 0x86, 0x59, 0xc7, 0xef, 0xae, 0x29, 0xa7, 0xd8, 0xb4, 0x8f, + 0xa8, 0x76, 0x43, 0x42, 0x31, 0xbb, 0x21, 0x9f, 0x77, 0xab, 0xa6, 0x12, 0xfd, 0xb5, 0x8f, 0xaa, + 0xc3, 0x3c, 0x81, 0x66, 0xc3, 0x3c, 0x79, 0x34, 0xa0, 0x9a, 0x4a, 0x3a, 0xd7, 0xce, 0xf5, 0x13, + 0x02, 0x68, 0x55, 0x08, 0x4f, 0x53, 0xaf, 0x67, 0x64, 0x3d, 0x6b, 0xcf, 0xaa, 0xd1, 0xc7, 0x14, + 0xc1, 0xe2, 0x00, 0xc9, 0xc8, 0x95, 0x26, 0xd9, 0xc9, 0x5d, 0xda, 0x79, 0x75, 0xd8, 0x66, 0xd1, + 0xb0, 0x61, 0x9b, 0x99, 0x18, 0xb6, 0x94, 0xb5, 0x3f, 0xa0, 0x5d, 0x50, 0x1d, 0xb3, 0x34, 0x05, + 0x73, 0xcc, 0x32, 0xf6, 0x15, 0x48, 0x76, 0xba, 0x92, 0xf6, 0xb1, 0x1d, 0xdf, 0x10, 0x68, 0x32, + 0xde, 0x90, 0x67, 0xef, 0xc4, 0xbe, 0xd3, 0x6d, 0xb7, 0xe5, 0x18, 0xa6, 0xf6, 0x5c, 0xa6, 0xef, + 0xc4, 0x91, 0x92, 0xef, 0xc4, 0x01, 0x6c, 0x96, 0x97, 0xe3, 0xe7, 0xda, 0x45, 0x75, 0x96, 0x97, + 0x71, 0x6c, 0x96, 0x57, 0x62, 0xed, 0xd5, 0x54, 0xd4, 0x5a, 0x7b, 0x5e, 0xed, 0x00, 0x09, 0x34, + 0xeb, 0x00, 0xc9, 0x38, 0xf7, 0x3b, 0xfd, 0x23, 0xc6, 0xda, 0x2c, 0x48, 0x7b, 0x3a, 0x2a, 0xcb, + 0xdd, 0x87, 0x6e, 0x71, 0x80, 0xf4, 0x8f, 0x3a, 0xd7, 0x33, 0x02, 0xc0, 0xda, 0x9c, 0xda, 0xc1, + 0x52, 0x04, 0xac, 0x83, 0xa5, 0xc3, 0xc6, 0xf5, 0x8c, 0x08, 0xae, 0xf6, 0xf1, 0xbe, 0xa2, 0xa2, + 0x6f, 0xce, 0x88, 0xfb, 0x5e, 0x95, 0x43, 0xb0, 0xda, 0x25, 0x75, 0xb2, 0x8b, 0x31, 0x6c, 0xb2, + 0x93, 0x42, 0xb5, 0x57, 0xe5, 0x88, 0xa7, 0x76, 0x39, 0xcd, 0x15, 0x4f, 0x91, 0x52, 0x64, 0x94, + 0x64, 0x07, 0x18, 0xb5, 0x2b, 0x6a, 0xaf, 0xcb, 0xa2, 0x61, 0xbd, 0x2e, 0x33, 0x38, 0x79, 0x23, + 0x1d, 0x27, 0xd4, 0xae, 0x26, 0x23, 0xa7, 0x2a, 0x9e, 0x79, 0x3e, 0xa9, 0xd8, 0xe2, 0xf5, 0x64, + 0xe6, 0xb1, 0xf6, 0x82, 0xea, 0xdf, 0xaa, 0x58, 0xe6, 0xdf, 0x26, 0x32, 0x95, 0xaf, 0x27, 0x93, + 0x75, 0xb5, 0x4f, 0x64, 0x4b, 0x88, 0xfa, 0x4a, 0x32, 0xb9, 0xf7, 0x7a, 0x32, 0xbf, 0x55, 0xbb, + 0x96, 0x2d, 0x21, 0xd2, 0x6e, 0x32, 0x1f, 0xf6, 0x92, 0x74, 0xe6, 0x4f, 0x7b, 0x51, 0x75, 0x1d, + 0x23, 0x04, 0x73, 0x1d, 0xe3, 0x93, 0x81, 0x97, 0xa4, 0xb3, 0x72, 0xda, 0x4b, 0x29, 0x96, 0xe8, + 0x65, 0xa5, 0x13, 0x75, 0x97, 0xa4, 0x33, 0x66, 0xda, 0xcb, 0x29, 0x96, 0xe8, 0xed, 0xa4, 0x93, + 0x68, 0xe6, 0x4e, 0x09, 0x00, 0xda, 0x27, 0x41, 0x86, 0xfe, 0xe0, 0x3d, 0xdd, 0xc5, 0x01, 0xb2, + 0x53, 0x22, 0xc1, 0x3b, 0xfd, 0xa3, 0xae, 0xda, 0x2b, 0xea, 0x10, 0xee, 0x47, 0xc7, 0x86, 0x70, + 0xdf, 0xc8, 0xed, 0xab, 0x89, 0x64, 0x40, 0xed, 0x55, 0xd5, 0xc4, 0x29, 0x48, 0x66, 0xe2, 0x92, + 0xa9, 0x83, 0x4a, 0x96, 0x9b, 0xf6, 0x29, 0xd5, 0xc4, 0xc9, 0x38, 0x66, 0xe2, 0x94, 0x8c, 0xb8, + 0x6a, 0x2a, 0xf9, 0x4a, 0x7b, 0x4d, 0x35, 0x71, 0x09, 0x34, 0x33, 0x71, 0xc9, 0x74, 0xad, 0x57, + 0x13, 0x39, 0x48, 0xda, 0xf5, 0xec, 0xf7, 0x07, 0xa4, 0xfc, 0xfe, 0x3c, 0x63, 0x89, 0x64, 0x27, + 0xd3, 0x68, 0x15, 0x75, 0xfc, 0x66, 0xd1, 0xb0, 0xf1, 0x9b, 0x99, 0x88, 0xb3, 0x9c, 0x59, 0x73, + 0x53, 0x9b, 0xdf, 0x61, 0xe1, 0x10, 0xbb, 0x22, 0x59, 0xd5, 0x3a, 0xaf, 0x27, 0x2f, 0x74, 0xd3, + 0xaa, 0x7d, 0xd6, 0xc8, 0xe1, 0x32, 0x28, 0x79, 0x01, 0x5c, 0x3d, 0x23, 0x08, 0xa8, 0xd5, 0x54, + 0xeb, 0x9a, 0x22, 0x60, 0xd6, 0x35, 0x1d, 0x3a, 0xbc, 0x91, 0xbe, 0x47, 0x53, 0x5b, 0x48, 0x6c, + 0x89, 0x27, 0xf0, 0xcc, 0x3a, 0xa5, 0xee, 0xde, 0x24, 0xd9, 0x57, 0x2d, 0x6a, 0x37, 0x12, 0xf3, + 0x75, 0x06, 0x0d, 0xcc, 0xd7, 0x59, 0xd7, 0x34, 0x7e, 0xb6, 0xef, 0x8d, 0x99, 0xda, 0xeb, 0x20, + 0xb6, 0xdc, 0x4f, 0xac, 0x20, 0x5b, 0x1c, 0x20, 0x7d, 0xef, 0xdc, 0xbc, 0x8d, 0x8e, 0xdf, 0xdc, + 0x5e, 0x7d, 0x73, 0x29, 0xca, 0xdf, 0x5a, 0xf1, 0xa8, 0x6b, 0x78, 0x54, 0x5b, 0x54, 0x7d, 0xf5, + 0x4c, 0x22, 0xe6, 0xab, 0x67, 0x22, 0xd2, 0x62, 0xc3, 0xb1, 0x50, 0xdf, 0x49, 0x6c, 0x3c, 0x22, + 0xb2, 0xb9, 0x99, 0x75, 0x52, 0x11, 0x4c, 0x41, 0x4b, 0x8e, 0xbd, 0x01, 0x91, 0x8a, 0x4f, 0xab, + 0xd6, 0xa9, 0x3f, 0x25, 0xb3, 0x4e, 0xfd, 0xb1, 0xac, 0xab, 0xab, 0x58, 0x3e, 0x06, 0xdf, 0x50, + 0xbb, 0x7a, 0x06, 0x09, 0xeb, 0xea, 0x19, 0xe0, 0xb4, 0x40, 0x42, 0x7d, 0x1a, 0x68, 0x4b, 0x3b, + 0x09, 0x04, 0x92, 0xb4, 0x40, 0x00, 0xa7, 0x05, 0xde, 0xa0, 0x41, 0x73, 0x53, 0xbb, 0xb9, 0x93, + 0x40, 0x20, 0x49, 0x0b, 0x04, 0x30, 0x5b, 0x6c, 0xaa, 0xe0, 0xf9, 0x4e, 0xeb, 0x6e, 0xd8, 0x66, + 0xb7, 0xd4, 0xc5, 0x66, 0x5f, 0x42, 0xb6, 0xd8, 0xec, 0x8b, 0xc4, 0x5f, 0x7c, 0xe8, 0x10, 0xb7, + 0xb6, 0x0c, 0x0f, 0x9c, 0x8d, 0xfd, 0x82, 0x87, 0xe1, 0x5a, 0x1c, 0x20, 0x0f, 0x1b, 0x42, 0x7f, + 0x2e, 0x8a, 0x5e, 0x6b, 0x2b, 0xf0, 0xa8, 0xc9, 0x28, 0x56, 0xc1, 0xc1, 0x8b, 0x03, 0x24, 0x8a, + 0x6f, 0x5f, 0x43, 0x25, 0xf8, 0xa8, 0xba, 0x6d, 0x05, 0xb5, 0x79, 0xed, 0x4d, 0x75, 0xc9, 0x24, + 0xa1, 0xd8, 0x92, 0x49, 0xfa, 0xc9, 0x8c, 0x38, 0xfc, 0xe4, 0x26, 0xa6, 0x36, 0xaf, 0x11, 0xd5, + 0x88, 0x2b, 0x48, 0x66, 0xc4, 0x15, 0x40, 0xf4, 0xdc, 0x9a, 0xe7, 0xb8, 0xb5, 0x79, 0x6d, 0x35, + 0xe3, 0xb9, 0x1c, 0x15, 0x3d, 0x97, 0xff, 0x8c, 0x9e, 0xbb, 0xba, 0xd9, 0x09, 0x6a, 0xec, 0x1b, + 0xd7, 0x32, 0x9e, 0x1b, 0x22, 0xa3, 0xe7, 0x86, 0x00, 0x66, 0x0a, 0x01, 0xb0, 0xe2, 0x39, 0xcc, + 0x68, 0xbf, 0x61, 0xb5, 0x5a, 0xda, 0x6d, 0xd5, 0x14, 0x26, 0xf1, 0xcc, 0x14, 0x26, 0x61, 0xcc, + 0xf5, 0xe4, 0x6f, 0x45, 0xd7, 0x3b, 0x1b, 0xda, 0x5b, 0xaa, 0xeb, 0x19, 0x63, 0x98, 0xeb, 0x19, + 0xff, 0x82, 0xd5, 0x05, 0xfb, 0x45, 0xe8, 0x1d, 0x8f, 0xfa, 0x9b, 0xda, 0xdb, 0x89, 0xd5, 0x85, + 0x84, 0x83, 0xd5, 0x85, 0xf4, 0x1b, 0x6f, 0xa0, 0x27, 0x95, 0x89, 0x26, 0xdc, 0x69, 0x5f, 0xa5, + 0x86, 0xd7, 0xdc, 0xd4, 0x3e, 0x03, 0xa2, 0xce, 0x66, 0x4e, 0x55, 0x2a, 0xe9, 0xe2, 0x00, 0xd9, + 0x49, 0x12, 0x2c, 0xcb, 0xdf, 0x5c, 0xe2, 0xc7, 0x62, 0xc8, 0x4a, 0x35, 0x5c, 0x84, 0xfe, 0xbb, + 0xc4, 0xb2, 0x3c, 0x4d, 0x02, 0xcb, 0xf2, 0x34, 0x18, 0xbb, 0xe8, 0x4c, 0x62, 0xa9, 0x76, 0xd3, + 0x68, 0xb1, 0x75, 0x09, 0x35, 0x57, 0x8c, 0xe6, 0x5d, 0x1a, 0x68, 0xff, 0x1e, 0x64, 0x9f, 0xeb, + 0xb3, 0xe0, 0x4b, 0x50, 0x2f, 0x0e, 0x90, 0x07, 0xc8, 0x9b, 0x1f, 0x41, 0x43, 0x70, 0x01, 0x8f, + 0xfe, 0x7f, 0x73, 0x68, 0x6c, 0x35, 0xf0, 0xa8, 0xd1, 0x16, 0xf9, 0x8a, 0xa7, 0x50, 0x91, 0xaf, + 0xf4, 0xc4, 0xe5, 0x72, 0xa3, 0x24, 0xfa, 0x8d, 0xcf, 0xa1, 0x89, 0x25, 0xc3, 0x0f, 0x80, 0x53, + 0xba, 0x35, 0x9b, 0x24, 0xa0, 0x78, 0x89, 0xd3, 0x71, 0x3e, 0xd8, 0xd6, 0x2c, 0x3c, 0x70, 0x5b, + 0xb3, 0xf8, 0x7e, 0xb7, 0x3c, 0x00, 0x9b, 0x97, 0x09, 0x5e, 0xbd, 0x97, 0x43, 0xa9, 0x35, 0xe8, + 0xa3, 0xef, 0x39, 0x2d, 0xa3, 0xc9, 0xc4, 0x56, 0xba, 0xd8, 0xaa, 0x79, 0xc8, 0x9d, 0xf6, 0x24, + 0x37, 0x3e, 0x8b, 0x0a, 0xb7, 0xeb, 0x35, 0xf9, 0x22, 0x8a, 0x8e, 0x72, 0x0c, 0x93, 0x61, 0xf1, + 0xb3, 0xd1, 0x3e, 0xc2, 0x6d, 0xb2, 0x24, 0xb6, 0xd0, 0xe1, 0xd2, 0xbe, 0x8e, 0xd7, 0x22, 0x12, + 0x4a, 0xff, 0x95, 0xb1, 0x78, 0x1b, 0x11, 0x9f, 0x13, 0x59, 0x04, 0xd2, 0xc5, 0x1c, 0x89, 0x33, + 0xbb, 0x3c, 0x6b, 0xe0, 0x53, 0x68, 0xac, 0xde, 0x76, 0xa9, 0xe7, 0x3b, 0x36, 0x94, 0xcc, 0xcf, + 0xc7, 0x7b, 0x62, 0x96, 0x04, 0x97, 0xf3, 0x7e, 0x65, 0xfa, 0xb8, 0xde, 0x7f, 0xe1, 0x81, 0xf5, + 0xfe, 0x2f, 0xa0, 0xa1, 0xdb, 0x70, 0x4d, 0x9f, 0x74, 0x35, 0x40, 0x27, 0x71, 0x49, 0x1f, 0xa7, + 0xc0, 0x17, 0xd1, 0x30, 0x6c, 0x8c, 0xf9, 0xda, 0x10, 0xd0, 0xc2, 0x59, 0xf8, 0x16, 0x40, 0xe4, + 0xe2, 0x30, 0x9c, 0x06, 0xbf, 0x81, 0xa6, 0xe2, 0x4a, 0x33, 0x50, 0xc8, 0x27, 0x4c, 0x60, 0x86, + 0xf3, 0xb3, 0x77, 0x23, 0x1c, 0xaf, 0x00, 0x24, 0x8b, 0x48, 0x31, 0xe2, 0x45, 0x34, 0x19, 0xc3, + 0x98, 0x8a, 0xc2, 0x83, 0x13, 0x67, 0x7a, 0xdd, 0xf2, 0x29, 0x49, 0x16, 0x53, 0xa7, 0x2c, 0x2a, + 0xc9, 0x86, 0xeb, 0xf1, 0x9d, 0x27, 0xc5, 0x07, 0xf6, 0xe1, 0x63, 0x62, 0x6b, 0x7e, 0x44, 0xdc, + 0x79, 0xa2, 0xde, 0x74, 0x72, 0x03, 0x4d, 0x10, 0xa7, 0x13, 0xd0, 0x35, 0x27, 0x2c, 0xdc, 0xcc, + 0x33, 0x6b, 0xe1, 0x9d, 0x3c, 0x86, 0x69, 0x04, 0x4e, 0x78, 0xfc, 0x58, 0x3e, 0x26, 0xad, 0x72, + 0xe1, 0x5b, 0x59, 0x35, 0xa0, 0xa5, 0x43, 0xc1, 0xd2, 0xe7, 0xa5, 0x85, 0x65, 0x14, 0x7d, 0xfe, + 0x2f, 0x39, 0x34, 0xbc, 0xe6, 0x19, 0x56, 0xe0, 0x8b, 0x6d, 0xaa, 0xe3, 0xb3, 0x5b, 0x9e, 0xe1, + 0xb2, 0xfe, 0x31, 0x0b, 0x3b, 0xf4, 0x6f, 0x19, 0xad, 0x0e, 0xf5, 0xe7, 0xdf, 0x66, 0x5f, 0xf7, + 0x27, 0xdd, 0xf2, 0x27, 0x37, 0x20, 0x3e, 0x3b, 0xdb, 0x74, 0xda, 0x73, 0x1b, 0x9e, 0x71, 0xcf, + 0xe2, 0x37, 0x1e, 0x18, 0xad, 0xb9, 0x80, 0xb6, 0xa8, 0xeb, 0x78, 0xc1, 0x9c, 0xe1, 0x5a, 0x73, + 0xc1, 0xb6, 0x4b, 0xfd, 0xb9, 0x48, 0x12, 0x7f, 0x02, 0xeb, 0x02, 0x01, 0xfc, 0x27, 0x77, 0x01, + 0x8e, 0xc3, 0xb7, 0x10, 0x12, 0x9f, 0x5a, 0x71, 0x5d, 0xb1, 0xe7, 0x25, 0x05, 0xf4, 0x43, 0x0c, + 0xef, 0xd8, 0x91, 0xc2, 0x0c, 0x57, 0x2e, 0x07, 0x25, 0x49, 0x60, 0xbd, 0x60, 0x4d, 0xbc, 0x51, + 0xa8, 0xa6, 0xf1, 0x58, 0xe3, 0xe1, 0xcb, 0x66, 0x28, 0x29, 0xc9, 0x86, 0xd7, 0xd1, 0xa4, 0x90, + 0x1b, 0x65, 0xcc, 0x4e, 0xa8, 0x46, 0x23, 0x81, 0xe6, 0x9d, 0x36, 0x7a, 0x47, 0x53, 0x80, 0xe5, + 0x67, 0x24, 0x38, 0xf0, 0x7c, 0x7c, 0x12, 0x0f, 0x6a, 0x4f, 0x69, 0x93, 0xd0, 0x63, 0xe1, 0xee, + 0x87, 0x90, 0x9f, 0x97, 0xac, 0x92, 0x8b, 0x23, 0x29, 0x2c, 0xb2, 0x0c, 0xde, 0xeb, 0xa7, 0x32, + 0x64, 0x24, 0xfb, 0xbc, 0xca, 0x82, 0xab, 0x68, 0x3c, 0x0a, 0xb9, 0xdd, 0x66, 0x96, 0x6d, 0x3a, + 0xae, 0xd2, 0x94, 0x48, 0xc6, 0x95, 0x85, 0x28, 0x3c, 0xf8, 0x0a, 0x2a, 0xf2, 0x4d, 0xab, 0x3a, + 0xdf, 0x65, 0x0b, 0x13, 0x29, 0x00, 0xd6, 0xb0, 0xe4, 0x16, 0x8b, 0x08, 0xf1, 0xab, 0xa8, 0x54, + 0x79, 0x7b, 0x95, 0xd9, 0x99, 0x0a, 0xb9, 0xe5, 0x6b, 0xc7, 0xe2, 0xe3, 0x0b, 0x70, 0x40, 0xdf, + 0x69, 0xd1, 0x86, 0xe1, 0x29, 0xc6, 0x43, 0xa6, 0xc7, 0x0b, 0x68, 0x42, 0x99, 0xb5, 0x7d, 0x6d, + 0x26, 0xbe, 0xb4, 0xd5, 0x00, 0x4c, 0x43, 0x54, 0x28, 0x53, 0xaa, 0x10, 0xa8, 0x4c, 0xac, 0xd7, + 0xd4, 0x2c, 0xdf, 0x68, 0xb5, 0x9c, 0x2d, 0x42, 0x2d, 0xdf, 0xef, 0x50, 0xd8, 0xa2, 0x2b, 0xf2, + 0x5e, 0x63, 0x0a, 0x54, 0xc3, 0xe3, 0x38, 0xa5, 0x46, 0x84, 0xca, 0x86, 0xdf, 0x45, 0xb8, 0xc2, + 0x7e, 0xab, 0xf7, 0x70, 0x9c, 0xe8, 0x7b, 0x0f, 0xc7, 0x39, 0x61, 0x3e, 0xce, 0x18, 0x9c, 0xab, + 0xd1, 0xe7, 0x3e, 0x8e, 0x0c, 0xa9, 0xfa, 0x3f, 0xe4, 0xe4, 0xc1, 0x13, 0x55, 0xb8, 0xce, 0x65, + 0x56, 0xb8, 0xbe, 0x88, 0x46, 0xc5, 0x94, 0x13, 0xe5, 0x5a, 0xc3, 0x89, 0xb2, 0x30, 0xa3, 0xc8, + 0x32, 0x49, 0x4c, 0x00, 0xa7, 0x79, 0xe2, 0xa2, 0x34, 0x05, 0xe9, 0x34, 0x4f, 0x5c, 0x94, 0x46, + 0x29, 0x49, 0x73, 0x59, 0xbd, 0x0b, 0x64, 0x30, 0x4e, 0x3a, 0x0a, 0x6b, 0x2b, 0xf0, 0xa4, 0x23, + 0xf9, 0x42, 0x90, 0x97, 0x11, 0x8a, 0xdb, 0x52, 0x4c, 0x90, 0x30, 0xce, 0xe5, 0xa6, 0x97, 0xc7, + 0x79, 0x4c, 0xad, 0xff, 0x71, 0x2e, 0x35, 0x3c, 0xd9, 0x3b, 0x88, 0xfc, 0x35, 0x49, 0x0f, 0xf0, + 0x0e, 0x22, 0xdb, 0x4d, 0xbc, 0x83, 0x44, 0x84, 0xcf, 0xa3, 0x62, 0xa2, 0x96, 0x07, 0xe4, 0xeb, + 0x44, 0x85, 0x3c, 0x22, 0x2c, 0xbe, 0x8c, 0x8a, 0x6c, 0xb0, 0xd8, 0xf1, 0x25, 0x25, 0x50, 0x25, + 0xac, 0x23, 0x60, 0x72, 0xef, 0x0e, 0xe9, 0x18, 0x8f, 0x92, 0x6e, 0x2f, 0x78, 0x32, 0x4c, 0x43, + 0x9c, 0x5e, 0xff, 0x4f, 0x83, 0x3b, 0xfa, 0xb4, 0xfb, 0x92, 0xa2, 0xf8, 0x12, 0xf3, 0xc6, 0xd8, + 0xd3, 0x2b, 0x7e, 0xca, 0x69, 0xf0, 0x01, 0xd1, 0x30, 0x78, 0x93, 0xf9, 0x44, 0xa5, 0x94, 0x0b, + 0xe1, 0x41, 0xc2, 0xcf, 0x60, 0x46, 0x21, 0xbc, 0x44, 0x9a, 0x95, 0xc2, 0x80, 0x5f, 0x40, 0xa3, + 0x71, 0x49, 0xbf, 0xa1, 0xd8, 0xae, 0x64, 0x55, 0xf2, 0x8b, 0x29, 0xf1, 0xe7, 0xd0, 0xb0, 0x52, + 0xc3, 0x64, 0xee, 0x21, 0x16, 0x01, 0xb3, 0x72, 0x8a, 0x20, 0x77, 0x5d, 0x92, 0xf5, 0x4b, 0x84, + 0x50, 0xbc, 0x86, 0x8e, 0xad, 0x78, 0xd4, 0x84, 0xe5, 0xe6, 0xc2, 0x7d, 0xd7, 0x13, 0x09, 0x9c, + 0x3c, 0x91, 0x51, 0x67, 0x03, 0xda, 0x0d, 0xd1, 0x0d, 0x1a, 0xe1, 0x25, 0x41, 0x59, 0xec, 0xcc, + 0x9c, 0xf1, 0x37, 0x79, 0x83, 0x6e, 0x6f, 0x39, 0x9e, 0x19, 0x5e, 0x13, 0x0e, 0xe6, 0x4c, 0x28, + 0xfa, 0xae, 0x40, 0xc9, 0xe6, 0x4c, 0x65, 0x3a, 0xf5, 0x12, 0x2a, 0x3d, 0x6a, 0x9a, 0xdd, 0x2f, + 0xe6, 0xfb, 0x44, 0x87, 0x0e, 0xef, 0xb1, 0xbc, 0xe8, 0x88, 0xf4, 0x50, 0x9f, 0x23, 0xd2, 0x7f, + 0x97, 0xef, 0x13, 0xfa, 0x3a, 0xd4, 0x47, 0x19, 0x23, 0x65, 0xa8, 0x47, 0x19, 0xe3, 0x53, 0xa4, + 0x96, 0x49, 0x64, 0xa2, 0xc4, 0xa1, 0xe7, 0xe1, 0x07, 0x1e, 0x7a, 0xfe, 0x99, 0xc2, 0x4e, 0xa1, + 0xc1, 0x23, 0xdd, 0xef, 0x46, 0xf7, 0x97, 0x51, 0x29, 0xd2, 0xac, 0x28, 0x64, 0x36, 0x1e, 0x25, + 0xf5, 0x72, 0x30, 0xf0, 0x48, 0x44, 0xf8, 0x02, 0x7f, 0xd7, 0x55, 0xeb, 0x3d, 0x5e, 0x9c, 0x63, + 0x9c, 0xd7, 0xfa, 0x62, 0xef, 0xd6, 0xf0, 0xad, 0xf7, 0x28, 0x89, 0xd0, 0xfa, 0x6f, 0xe6, 0x33, + 0xe3, 0xab, 0x47, 0x6d, 0xb4, 0x8b, 0x36, 0xca, 0x50, 0x22, 0x8f, 0x0c, 0x1f, 0x29, 0x71, 0x17, + 0x4a, 0xfc, 0x49, 0x3e, 0x33, 0x8e, 0x7e, 0xa4, 0xc4, 0xdd, 0x58, 0x8b, 0x8b, 0x68, 0x94, 0x38, + 0x5b, 0x7e, 0xd5, 0xe9, 0xd8, 0x81, 0xb0, 0x15, 0x60, 0xa8, 0x3d, 0x67, 0xcb, 0x6f, 0x34, 0x19, + 0x94, 0xc4, 0x04, 0xfa, 0x4f, 0xf3, 0x3b, 0xec, 0x34, 0x1c, 0x29, 0xfe, 0x83, 0x9c, 0x22, 0xbf, + 0x99, 0x57, 0x76, 0x32, 0x0e, 0x75, 0x4d, 0x90, 0xd5, 0xe6, 0x26, 0x6d, 0x1b, 0xc9, 0x9a, 0x20, + 0x3e, 0x40, 0xc5, 0xc9, 0xe4, 0x98, 0x44, 0xff, 0x56, 0x3e, 0xb1, 0x95, 0x73, 0xa4, 0xbb, 0x87, + 0xd6, 0x5d, 0xd4, 0xeb, 0xc4, 0xee, 0xd4, 0x91, 0xe6, 0x1e, 0x56, 0x73, 0x5f, 0xcc, 0x27, 0x36, + 0xf2, 0x0e, 0x6f, 0x95, 0x81, 0x6f, 0xe5, 0xd3, 0x9b, 0x92, 0x87, 0xb7, 0x27, 0x5d, 0x44, 0xa3, + 0x42, 0x0f, 0xd1, 0x54, 0xc1, 0xed, 0x3e, 0x07, 0x42, 0xf4, 0x2e, 0x22, 0xd0, 0xff, 0x73, 0x1e, + 0xa9, 0x1b, 0xac, 0x87, 0xb4, 0x0f, 0x7d, 0x33, 0xaf, 0x6e, 0x2d, 0x1f, 0xde, 0xfe, 0x33, 0x8b, + 0xd0, 0x6a, 0x67, 0x5d, 0x5c, 0x22, 0x2b, 0x2c, 0x11, 0x0f, 0xff, 0x46, 0x50, 0x22, 0x51, 0xe8, + 0xff, 0x9c, 0xcf, 0xdc, 0xef, 0x3e, 0xbc, 0x0a, 0xbc, 0x02, 0x71, 0xe2, 0xa6, 0x1d, 0x1b, 0x72, + 0x08, 0x42, 0xb2, 0xf1, 0x97, 0x2c, 0xc7, 0x1c, 0x11, 0xe2, 0x17, 0x33, 0xdc, 0x35, 0xa8, 0x37, + 0x9d, 0x59, 0x1e, 0x51, 0x76, 0xdc, 0x7e, 0x37, 0xff, 0xa0, 0xf4, 0x80, 0xc3, 0x3c, 0xab, 0x8e, + 0xac, 0x18, 0xdb, 0x90, 0xc6, 0xce, 0x5a, 0x62, 0x8c, 0xd7, 0xb6, 0x76, 0x39, 0x48, 0xbe, 0xac, + 0x43, 0x50, 0x7d, 0xec, 0x59, 0x54, 0x82, 0x44, 0x05, 0x7e, 0xab, 0x29, 0x1e, 0x43, 0xc5, 0xe5, + 0xf9, 0xd5, 0x05, 0xf2, 0xd6, 0x42, 0x6d, 0x6a, 0x00, 0x23, 0x34, 0x5c, 0x5b, 0xb8, 0x55, 0x5f, + 0xa8, 0x4d, 0xe5, 0xe6, 0xa7, 0xde, 0xff, 0xb3, 0x33, 0x03, 0xef, 0xff, 0xf8, 0x4c, 0xee, 0xfb, + 0x3f, 0x3e, 0x93, 0xfb, 0xd3, 0x1f, 0x9f, 0xc9, 0xad, 0x0f, 0xc3, 0x46, 0xc0, 0x95, 0x7f, 0x09, + 0x00, 0x00, 0xff, 0xff, 0x90, 0x3b, 0x4c, 0x33, 0xdc, 0xaa, 0x00, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { diff --git a/api/types/events/events.proto b/api/types/events/events.proto index e828ca3b1aaf3..af7eb0ea5f13e 100644 --- a/api/types/events/events.proto +++ b/api/types/events/events.proto @@ -2363,7 +2363,7 @@ message SQLServerRPCRequest { DatabaseMetadata Database = 4 [ (gogoproto.nullable) = false, (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; // Procname is the RPC SQL Server procedure name. - string Procname = 5 [ (gogoproto.jsontag) = "procname,omitempty" ]; + string Procname = 5 [ (gogoproto.jsontag) = "proc_name,omitempty" ]; // Parameters are the RPC parameters used to execute RPC Procedure.. repeated string Parameters = 6 [ (gogoproto.jsontag) = "parameters,omitempty" ]; } diff --git a/api/types/github.go b/api/types/github.go index b4c954c68b04a..47f18a7a4ac4b 100644 --- a/api/types/github.go +++ b/api/types/github.go @@ -308,7 +308,7 @@ func (r *GithubAuthRequest) Check() error { if err != nil { return trace.BadParameter("bad PublicKey: %v", err) } - if (r.CertTTL.Duration() > defaults.MaxCertDuration) || (r.CertTTL.Duration() < defaults.MinCertDuration) { + if (r.CertTTL > defaults.MaxCertDuration) || (r.CertTTL < defaults.MinCertDuration) { return trace.BadParameter("wrong CertTTL") } } diff --git a/api/types/license.go b/api/types/license.go index 59ccbdfb2807a..630c094850568 100644 --- a/api/types/license.go +++ b/api/types/license.go @@ -76,6 +76,16 @@ type License interface { // SetSupportsModeratedSessions sets moderated sessions support flag SetSupportsModeratedSessions(Bool) + // GetSupportsMachineID returns MachineID support flag + GetSupportsMachineID() Bool + // SetSupportsMachineID sets MachineID support flag + SetSupportsMachineID(Bool) + + // GetSupportsResourceAccessRequests returns resource access requests support flag + GetSupportsResourceAccessRequests() Bool + // SetSupportsResourceAccessRequests sets resource access requests support flag + SetSupportsResourceAccessRequests(Bool) + // SetLabels sets metadata labels SetLabels(labels map[string]string) @@ -299,6 +309,26 @@ func (c *LicenseV3) SetSupportsModeratedSessions(value Bool) { c.Spec.SupportsModeratedSessions = value } +// GetSupportsMachineID returns MachineID support flag +func (c *LicenseV3) GetSupportsMachineID() Bool { + return c.Spec.SupportsMachineID +} + +// SetSupportsMachineID sets MachineID support flag +func (c *LicenseV3) SetSupportsMachineID(value Bool) { + c.Spec.SupportsMachineID = value +} + +// GetSupportsResourceAccessRequests returns resource access requests support flag +func (c *LicenseV3) GetSupportsResourceAccessRequests() Bool { + return c.Spec.SupportsResourceAccessRequests +} + +// SetSupportsResourceAccessRequests sets resource access requests support flag +func (c *LicenseV3) SetSupportsResourceAccessRequests(value Bool) { + c.Spec.SupportsResourceAccessRequests = value +} + // String represents a human readable version of license enabled features func (c *LicenseV3) String() string { var features []string @@ -323,6 +353,12 @@ func (c *LicenseV3) String() string { if c.GetSupportsModeratedSessions() { features = append(features, "supports moderated sessions") } + if c.GetSupportsMachineID() { + features = append(features, "supports Machine ID") + } + if c.GetSupportsResourceAccessRequests() { + features = append(features, "supports resource access requests") + } if c.GetCloud() { features = append(features, "is hosted by Gravitational") } @@ -361,4 +397,8 @@ type LicenseSpecV3 struct { Cloud Bool `json:"cloud,omitempty"` // SupportsModeratedSessions turns on moderated sessions SupportsModeratedSessions Bool `json:"moderated_sessions,omitempty"` + // SupportsMachineID turns MachineID support on or off + SupportsMachineID Bool `json:"machine_id,omitempty"` + // SupportsResourceAccessRequests turns resource access request support on or off + SupportsResourceAccessRequests Bool `json:"resource_access_requests,omitempty"` } diff --git a/api/types/oidc.go b/api/types/oidc.go index 4e5ec93a76a75..3fc378585c221 100644 --- a/api/types/oidc.go +++ b/api/types/oidc.go @@ -437,7 +437,7 @@ func (i *OIDCAuthRequest) Check() error { if err != nil { return trace.BadParameter("PublicKey: bad key: %v", err) } - if (i.CertTTL.Duration() > defaults.MaxCertDuration) || (i.CertTTL.Duration() < defaults.MinCertDuration) { + if (i.CertTTL > defaults.MaxCertDuration) || (i.CertTTL < defaults.MinCertDuration) { return trace.BadParameter("CertTTL: wrong certificate TTL") } } diff --git a/api/types/saml.go b/api/types/saml.go index bd9532854f9d3..fe8ecc8482301 100644 --- a/api/types/saml.go +++ b/api/types/saml.go @@ -380,7 +380,7 @@ func (i *SAMLAuthRequest) Check() error { if err != nil { return trace.BadParameter("PublicKey: bad key: %v", err) } - if (i.CertTTL.Duration() > defaults.MaxCertDuration) || (i.CertTTL.Duration() < defaults.MinCertDuration) { + if (i.CertTTL > defaults.MaxCertDuration) || (i.CertTTL < defaults.MinCertDuration) { return trace.BadParameter("CertTTL: wrong certificate TTL") } } diff --git a/api/types/session_tracker.go b/api/types/session_tracker.go index 37ad0984b2722..b4736d5e56519 100644 --- a/api/types/session_tracker.go +++ b/api/types/session_tracker.go @@ -106,6 +106,9 @@ type SessionTracker interface { // GetHostPolicySets returns a list of policy sets held by the host user at the time of session creation. // This a subset of a role that contains some versioning and naming information in addition to the require policies GetHostPolicySets() []*SessionTrackerPolicySet + + // GetLastActive returns the time at which the session was last active (i.e used by any participant). + GetLastActive() time.Time } func NewSessionTracker(spec SessionTrackerSpecV1) (SessionTracker, error) { @@ -333,3 +336,16 @@ func (s *SessionTrackerV1) UpdatePresence(user string) error { func (s *SessionTrackerV1) GetHostPolicySets() []*SessionTrackerPolicySet { return s.Spec.HostPolicies } + +// GetLastActive returns the time at which the session was last active (i.e used by any participant). +func (s *SessionTrackerV1) GetLastActive() time.Time { + var last time.Time + + for _, participant := range s.Spec.Participants { + if participant.LastActive.After(last) { + last = participant.LastActive + } + } + + return last +} diff --git a/api/types/system_role.go b/api/types/system_role.go index 4d53c8f2717bd..f7af625efd3f2 100644 --- a/api/types/system_role.go +++ b/api/types/system_role.go @@ -60,6 +60,14 @@ const ( RoleWindowsDesktop SystemRole = "WindowsDesktop" // RoleBot is a role for a bot. RoleBot SystemRole = "Bot" + // RoleInstance is a role implicitly held by teleport servers (i.e. any teleport + // auth token which grants a server role such as proxy/node/etc also implicitly + // grants the instance role, and any valid cert that proves that the caller holds + // a server role also implies that the caller holds the instance role). This role + // doesn't grant meaningful privileges on its own, but is a useful placeholder in + // contexts such as multi-role certs where there is no particular system role that + // is "primary". + RoleInstance SystemRole = "Instance" ) // roleMappings maps a set of allowed lowercase system role names @@ -82,6 +90,20 @@ var roleMappings = map[string]SystemRole{ "windowsdesktop": RoleWindowsDesktop, "windows_desktop": RoleWindowsDesktop, "bot": RoleBot, + "instance": RoleInstance, +} + +// localServiceMappings is the subset of role mappings which happen to be true +// teleport services (e.g. db, kube, etc), excluding those which represent remote +// services (i.e. remoteproxy). +var localServiceMappings = map[SystemRole]struct{}{ + RoleAuth: struct{}{}, + RoleNode: struct{}{}, + RoleProxy: struct{}{}, + RoleKube: struct{}{}, + RoleApp: struct{}{}, + RoleDatabase: struct{}{}, + RoleWindowsDesktop: struct{}{}, } // NewTeleportRoles return a list of teleport roles from slice of strings @@ -222,3 +244,11 @@ func (r *SystemRole) Check() error { return trace.BadParameter("role %v is not registered", *r) } + +// IsLocalService checks if the given system role is a teleport service (e.g. auth), +// as opposed to some non-service role (e.g. admin). Excludes remote services such +// as remoteproxy. +func (r *SystemRole) IsLocalService() bool { + _, ok := localServiceMappings[*r] + return ok +} diff --git a/api/types/trust.go b/api/types/trust.go index a2be4627b6e85..6f4fac3f90972 100644 --- a/api/types/trust.go +++ b/api/types/trust.go @@ -60,8 +60,8 @@ type CertAuthID struct { DomainName string `json:"domain_name"` } -func (c *CertAuthID) String() string { - return fmt.Sprintf("CA(type=%v, domain=%v)", c.Type, c.DomainName) +func (c CertAuthID) String() string { + return fmt.Sprintf("CA(type=%q, domain=%q)", c.Type, c.DomainName) } // Check returns error if any of the id parameters are bad, nil otherwise diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 74a2ee171cc69..76f4a420b7aad 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -382,6 +382,39 @@ func (CertAuthoritySpecV2_SigningAlgType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_d938547f84707355, []int{38, 0} } +// FIPSEndpointState represents an AWS FIPS endpoint state. +type ClusterAuditConfigSpecV2_FIPSEndpointState int32 + +const ( + // FIPS_UNSET allows setting FIPS state for AWS S3/Dynamo using configuration files or + // environment variables + ClusterAuditConfigSpecV2_FIPS_UNSET ClusterAuditConfigSpecV2_FIPSEndpointState = 0 + // FIPS_ENABLED explicitly enables FIPS support for AWS S3/Dynamo + ClusterAuditConfigSpecV2_FIPS_ENABLED ClusterAuditConfigSpecV2_FIPSEndpointState = 1 + // FIPS_DISABLED explicitly disables FIPS support for AWS S3/Dynamo + ClusterAuditConfigSpecV2_FIPS_DISABLED ClusterAuditConfigSpecV2_FIPSEndpointState = 2 +) + +var ClusterAuditConfigSpecV2_FIPSEndpointState_name = map[int32]string{ + 0: "FIPS_UNSET", + 1: "FIPS_ENABLED", + 2: "FIPS_DISABLED", +} + +var ClusterAuditConfigSpecV2_FIPSEndpointState_value = map[string]int32{ + "FIPS_UNSET": 0, + "FIPS_ENABLED": 1, + "FIPS_DISABLED": 2, +} + +func (x ClusterAuditConfigSpecV2_FIPSEndpointState) String() string { + return proto.EnumName(ClusterAuditConfigSpecV2_FIPSEndpointState_name, int32(x)) +} + +func (ClusterAuditConfigSpecV2_FIPSEndpointState) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{51, 0} +} + type KeepAlive struct { // Name of the resource to keep alive. Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"server_name"` @@ -2954,10 +2987,12 @@ type ClusterAuditConfigSpecV2 struct { // WriteTargetValue is the ratio of consumed write to provisioned capacity. WriteTargetValue float64 `protobuf:"fixed64,13,opt,name=WriteTargetValue,proto3" json:"write_target_value,omitempty"` // RetentionPeriod is the retention period for audit events. - RetentionPeriod Duration `protobuf:"varint,14,opt,name=RetentionPeriod,proto3,casttype=Duration" json:"retention_period"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + RetentionPeriod Duration `protobuf:"varint,14,opt,name=RetentionPeriod,proto3,casttype=Duration" json:"retention_period"` + // UseFIPSEndpoint configures AWS endpoints to use FIPS. + UseFIPSEndpoint ClusterAuditConfigSpecV2_FIPSEndpointState `protobuf:"varint,15,opt,name=UseFIPSEndpoint,proto3,enum=types.ClusterAuditConfigSpecV2_FIPSEndpointState" json:"use_fips_endpoint,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ClusterAuditConfigSpecV2) Reset() { *m = ClusterAuditConfigSpecV2{} } @@ -4225,7 +4260,10 @@ type AccessRequestSpecV3 struct { RequestedResourceIDs []ResourceID `protobuf:"bytes,14,rep,name=RequestedResourceIDs,proto3" json:"resource_ids,omitempty"` // LoginHint is used as a hint for search-based access requests to select // roles based on the login the user is attempting. - LoginHint string `protobuf:"bytes,15,opt,name=LoginHint,proto3" json:"login_hint,omitempty"` + LoginHint string `protobuf:"bytes,15,opt,name=LoginHint,proto3" json:"login_hint,omitempty"` + // DryRun indicates that the request should not actually be created, the + // auth server should only validate the access request. + DryRun bool `protobuf:"varint,16,opt,name=DryRun,proto3" json:"dry_run,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -7753,7 +7791,7 @@ type OIDCAuthRequest struct { // of successful auth PublicKey []byte `protobuf:"bytes,7,opt,name=PublicKey,proto3" json:"public_key"` // CertTTL is the TTL of the certificate user wants to get - CertTTL Duration `protobuf:"varint,8,opt,name=CertTTL,proto3,casttype=Duration" json:"cert_ttl"` + CertTTL time.Duration `protobuf:"varint,8,opt,name=CertTTL,proto3,casttype=time.Duration" json:"cert_ttl"` // CreateWebSession indicates if user wants to generate a web // session after successful authentication CreateWebSession bool `protobuf:"varint,9,opt,name=CreateWebSession,proto3" json:"create_web_session"` @@ -7992,7 +8030,7 @@ type SAMLAuthRequest struct { // of successful auth. PublicKey []byte `protobuf:"bytes,6,opt,name=PublicKey,proto3" json:"public_key"` // CertTTL is the TTL of the certificate user wants to get. - CertTTL Duration `protobuf:"varint,7,opt,name=CertTTL,proto3,casttype=Duration" json:"cert_ttl"` + CertTTL time.Duration `protobuf:"varint,7,opt,name=CertTTL,proto3,casttype=time.Duration" json:"cert_ttl"` // CSRFToken is associated with user web session token. CSRFToken string `protobuf:"bytes,8,opt,name=CSRFToken,proto3" json:"csrf_token"` // CreateWebSession indicates if user wants to generate a web @@ -8300,7 +8338,7 @@ type GithubAuthRequest struct { // PublicKey is an optional public key to sign in case of successful auth. PublicKey []byte `protobuf:"bytes,5,opt,name=PublicKey,proto3" json:"public_key"` // CertTTL is TTL of the cert that's generated in case of successful auth. - CertTTL Duration `protobuf:"varint,6,opt,name=CertTTL,proto3,casttype=Duration" json:"cert_ttl"` + CertTTL time.Duration `protobuf:"varint,6,opt,name=CertTTL,proto3,casttype=time.Duration" json:"cert_ttl"` // CreateWebSession indicates that a user wants to generate a web session // after successful authentication. CreateWebSession bool `protobuf:"varint,7,opt,name=CreateWebSession,proto3" json:"create_web_session"` @@ -9891,6 +9929,7 @@ func init() { proto.RegisterEnum("types.SessionState", SessionState_name, SessionState_value) proto.RegisterEnum("types.KeepAlive_KeepAliveType", KeepAlive_KeepAliveType_name, KeepAlive_KeepAliveType_value) proto.RegisterEnum("types.CertAuthoritySpecV2_SigningAlgType", CertAuthoritySpecV2_SigningAlgType_name, CertAuthoritySpecV2_SigningAlgType_value) + proto.RegisterEnum("types.ClusterAuditConfigSpecV2_FIPSEndpointState", ClusterAuditConfigSpecV2_FIPSEndpointState_name, ClusterAuditConfigSpecV2_FIPSEndpointState_value) proto.RegisterType((*KeepAlive)(nil), "types.KeepAlive") proto.RegisterType((*Metadata)(nil), "types.Metadata") proto.RegisterMapType((map[string]string)(nil), "types.Metadata.LabelsEntry") @@ -10097,880 +10136,887 @@ func init() { func init() { proto.RegisterFile("types.proto", fileDescriptor_d938547f84707355) } var fileDescriptor_d938547f84707355 = []byte{ - // 13957 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x1c, 0x49, - 0x76, 0x98, 0x7a, 0x66, 0x48, 0x0e, 0x1f, 0x87, 0xe4, 0xb0, 0x48, 0x49, 0x94, 0x56, 0xbb, 0xa3, - 0xed, 0xdd, 0xd5, 0x6a, 0xb5, 0xbb, 0xd2, 0x89, 0xba, 0xd5, 0x79, 0x6f, 0xbf, 0x6e, 0x86, 0xa4, - 0x56, 0x5c, 0x51, 0x24, 0xb7, 0x87, 0x22, 0xef, 0x7c, 0xb7, 0xd7, 0xd7, 0x9c, 0x2e, 0x92, 0xbd, - 0x9c, 0x99, 0x9e, 0xeb, 0xee, 0x91, 0x44, 0x5f, 0x0c, 0xdb, 0x08, 0x2e, 0x87, 0x83, 0xe1, 0x3b, - 0x9f, 0x71, 0x8e, 0xed, 0xc0, 0x81, 0x1d, 0x23, 0x0e, 0xe2, 0x24, 0xf6, 0x0f, 0x3b, 0x41, 0x62, - 0x24, 0x48, 0x62, 0x20, 0x30, 0x2e, 0x41, 0x82, 0xf8, 0x5f, 0x90, 0x4b, 0xc2, 0xc4, 0x77, 0xf9, - 0x11, 0x10, 0x08, 0x90, 0xc0, 0x40, 0x00, 0x9f, 0x6d, 0x20, 0xa8, 0x57, 0x55, 0xdd, 0x55, 0x3d, - 0x3d, 0xe4, 0x70, 0xa5, 0x45, 0xac, 0x45, 0x7e, 0x91, 0xf3, 0xea, 0xbd, 0x57, 0x5d, 0x55, 0xaf, - 0x5e, 0xbd, 0x7a, 0xf5, 0xea, 0x15, 0x8c, 0x45, 0xfb, 0x1d, 0x1a, 0x5e, 0xed, 0x04, 0x7e, 0xe4, - 0x93, 0x21, 0xfc, 0x71, 0x7e, 0x66, 0xc7, 0xdf, 0xf1, 0x11, 0x72, 0x8d, 0xfd, 0xc7, 0x0b, 0xcf, - 0x57, 0x76, 0x7c, 0x7f, 0xa7, 0x49, 0xaf, 0xe1, 0xaf, 0xad, 0xee, 0xf6, 0xb5, 0xc8, 0x6b, 0xd1, - 0x30, 0x72, 0x5a, 0x1d, 0x81, 0x30, 0xbf, 0xe3, 0x45, 0xbb, 0xdd, 0xad, 0xab, 0x0d, 0xbf, 0x75, - 0x6d, 0x27, 0x70, 0xee, 0x7b, 0x91, 0x13, 0x79, 0x7e, 0xdb, 0x69, 0x5e, 0x8b, 0x68, 0x93, 0x76, - 0xfc, 0x20, 0xba, 0xe6, 0x74, 0xbc, 0x6b, 0x58, 0xc7, 0xb5, 0x07, 0x81, 0xd3, 0xe9, 0xd0, 0x20, - 0xf9, 0x87, 0x33, 0x31, 0xff, 0x56, 0x1e, 0x46, 0xef, 0x50, 0xda, 0xa9, 0x36, 0xbd, 0xfb, 0x94, - 0x3c, 0x07, 0x85, 0x15, 0xa7, 0x45, 0x67, 0x8d, 0x8b, 0xc6, 0xe5, 0xd1, 0xda, 0xe4, 0xe1, 0x41, - 0x65, 0x2c, 0xa4, 0xc1, 0x7d, 0x1a, 0xd8, 0x6d, 0xa7, 0x45, 0x2d, 0x2c, 0x24, 0x2f, 0xc3, 0x28, - 0xfb, 0x1b, 0x76, 0x9c, 0x06, 0x9d, 0xcd, 0x21, 0xe6, 0xf8, 0xe1, 0x41, 0x65, 0xb4, 0x2d, 0x81, - 0x56, 0x52, 0x4e, 0x2e, 0xc1, 0xc8, 0x32, 0x75, 0x42, 0xba, 0xb4, 0x30, 0x9b, 0xbf, 0x68, 0x5c, - 0xce, 0xd7, 0x4a, 0x87, 0x07, 0x95, 0x62, 0x93, 0x81, 0x6c, 0xcf, 0xb5, 0x64, 0x21, 0x59, 0x82, - 0x91, 0xc5, 0x87, 0x1d, 0x2f, 0xa0, 0xe1, 0x6c, 0xe1, 0xa2, 0x71, 0x79, 0x6c, 0xee, 0xfc, 0x55, - 0xde, 0xfe, 0xab, 0xb2, 0xfd, 0x57, 0xd7, 0x65, 0xfb, 0x6b, 0xd3, 0xdf, 0x3b, 0xa8, 0x9c, 0x3a, - 0x3c, 0xa8, 0x8c, 0x50, 0x4e, 0xf2, 0xf3, 0xff, 0xb5, 0x62, 0x58, 0x92, 0x9e, 0xbc, 0x09, 0x85, - 0xf5, 0xfd, 0x0e, 0x9d, 0x1d, 0xbd, 0x68, 0x5c, 0x9e, 0x98, 0x7b, 0xe6, 0x2a, 0xef, 0xf1, 0xb8, - 0x91, 0xc9, 0x7f, 0x0c, 0xab, 0x56, 0x3c, 0x3c, 0xa8, 0x14, 0x18, 0x8a, 0x85, 0x54, 0xe4, 0x55, - 0x18, 0xbe, 0xed, 0x87, 0xd1, 0xd2, 0xc2, 0x2c, 0x60, 0xd3, 0x4e, 0x1f, 0x1e, 0x54, 0xa6, 0x76, - 0xfd, 0x30, 0xb2, 0x3d, 0xf7, 0x15, 0xbf, 0xe5, 0x45, 0xb4, 0xd5, 0x89, 0xf6, 0x2d, 0x81, 0x64, - 0x6e, 0xc1, 0xb8, 0xc6, 0x8f, 0x8c, 0xc1, 0xc8, 0xbd, 0x95, 0x3b, 0x2b, 0xab, 0x9b, 0x2b, 0xe5, - 0x53, 0xa4, 0x08, 0x85, 0x95, 0xd5, 0x85, 0xc5, 0xb2, 0x41, 0x46, 0x20, 0x5f, 0x5d, 0x5b, 0x2b, - 0xe7, 0x48, 0x09, 0x8a, 0x0b, 0xd5, 0xf5, 0x6a, 0xad, 0x5a, 0x5f, 0x2c, 0xe7, 0xc9, 0x34, 0x4c, - 0x6e, 0x2e, 0xad, 0x2c, 0xac, 0x6e, 0xd6, 0xed, 0x85, 0xc5, 0xfa, 0x9d, 0xf5, 0xd5, 0xb5, 0x72, - 0x81, 0x4c, 0x00, 0xdc, 0xb9, 0x57, 0x5b, 0xb4, 0x56, 0x16, 0xd7, 0x17, 0xeb, 0xe5, 0x21, 0xf3, - 0x1b, 0x79, 0x28, 0xde, 0xa5, 0x91, 0xe3, 0x3a, 0x91, 0x43, 0x2e, 0x68, 0x43, 0x84, 0x5f, 0xaf, - 0x8c, 0xcd, 0x73, 0xbd, 0x63, 0x33, 0x74, 0x78, 0x50, 0x31, 0x5e, 0x55, 0xc7, 0xe4, 0x0d, 0x18, - 0x5b, 0xa0, 0x61, 0x23, 0xf0, 0x3a, 0x4c, 0x5e, 0x70, 0x5c, 0x46, 0x6b, 0xe7, 0x0e, 0x0f, 0x2a, - 0xa7, 0xdd, 0x04, 0xac, 0xb4, 0x55, 0xc5, 0x26, 0x4b, 0x30, 0xbc, 0xec, 0x6c, 0xd1, 0x66, 0x38, - 0x3b, 0x74, 0x31, 0x7f, 0x79, 0x6c, 0xee, 0x29, 0xd1, 0xbf, 0xf2, 0x03, 0xaf, 0xf2, 0xd2, 0xc5, - 0x76, 0x14, 0xec, 0xd7, 0x66, 0x0e, 0x0f, 0x2a, 0xe5, 0x26, 0x02, 0xd4, 0xbe, 0xe3, 0x28, 0xa4, - 0x9e, 0x8c, 0xf9, 0xf0, 0xb1, 0x63, 0xfe, 0xf4, 0xf7, 0x0e, 0x2a, 0x06, 0x1b, 0x0b, 0x31, 0xe6, - 0x09, 0x3f, 0x7d, 0xf4, 0x2f, 0x42, 0x6e, 0x69, 0x61, 0x76, 0x04, 0x65, 0xad, 0x7c, 0x78, 0x50, - 0x29, 0x69, 0xc3, 0x96, 0x5b, 0x5a, 0x38, 0xff, 0x3a, 0x8c, 0x29, 0xdf, 0x48, 0xca, 0x90, 0xdf, - 0xa3, 0xfb, 0xbc, 0x3f, 0x2d, 0xf6, 0x2f, 0x99, 0x81, 0xa1, 0xfb, 0x4e, 0xb3, 0x2b, 0x3a, 0xd0, - 0xe2, 0x3f, 0x3e, 0x9b, 0xfb, 0x31, 0xc3, 0xfc, 0x85, 0x02, 0x14, 0x2d, 0x9f, 0xcf, 0x33, 0xf2, - 0x12, 0x0c, 0xd5, 0x23, 0x27, 0x92, 0x43, 0x31, 0x7d, 0x78, 0x50, 0x99, 0x0c, 0x19, 0x40, 0xa9, - 0x8f, 0x63, 0x30, 0xd4, 0xb5, 0x5d, 0x27, 0x94, 0x43, 0x82, 0xa8, 0x1d, 0x06, 0x50, 0x51, 0x11, - 0x83, 0x5c, 0x82, 0xc2, 0x5d, 0xdf, 0xa5, 0x62, 0x54, 0xc8, 0xe1, 0x41, 0x65, 0xa2, 0xe5, 0xbb, - 0x2a, 0x22, 0x96, 0x93, 0x57, 0x60, 0x74, 0xbe, 0x1b, 0x04, 0xb4, 0xcd, 0x44, 0xb5, 0x80, 0xc8, - 0x13, 0x87, 0x07, 0x15, 0x68, 0x70, 0x20, 0x9b, 0x5c, 0x09, 0x02, 0xeb, 0xea, 0x7a, 0xe4, 0x04, - 0x11, 0x75, 0x67, 0x87, 0x06, 0xea, 0x6a, 0x36, 0xbd, 0xa6, 0x42, 0x4e, 0x92, 0xee, 0x6a, 0xc1, - 0x89, 0xdc, 0x86, 0xb1, 0x77, 0x03, 0xa7, 0x41, 0xd7, 0x68, 0xe0, 0xf9, 0x2e, 0x8e, 0x61, 0xbe, - 0x76, 0xe9, 0xf0, 0xa0, 0x72, 0x66, 0x87, 0x81, 0xed, 0x0e, 0xc2, 0x13, 0xea, 0x1f, 0x1d, 0x54, - 0x8a, 0x0b, 0xdd, 0x00, 0x7b, 0xcf, 0x52, 0x49, 0xc9, 0x57, 0xd8, 0x90, 0x84, 0x11, 0x76, 0x2d, - 0x75, 0x71, 0xf4, 0x8e, 0xfe, 0x44, 0x53, 0x7c, 0xe2, 0x99, 0xa6, 0x13, 0x46, 0x76, 0xc0, 0xe9, - 0x52, 0xdf, 0xa9, 0xb2, 0x24, 0xab, 0x50, 0xac, 0x37, 0x76, 0xa9, 0xdb, 0x6d, 0xd2, 0xd9, 0x22, - 0xb2, 0x3f, 0x2b, 0x04, 0x57, 0x8e, 0xa7, 0x2c, 0xae, 0x9d, 0x17, 0xbc, 0x49, 0x28, 0x20, 0x4a, - 0xdf, 0xc7, 0x4c, 0x3e, 0x5b, 0xfc, 0xe5, 0x5f, 0xaf, 0x9c, 0xfa, 0xe9, 0xff, 0x7c, 0xf1, 0x94, - 0xf9, 0x8f, 0x73, 0x50, 0x4e, 0x33, 0x21, 0xdb, 0x30, 0x7e, 0xaf, 0xe3, 0x3a, 0x11, 0x9d, 0x6f, - 0x7a, 0xb4, 0x1d, 0x85, 0x28, 0x24, 0x47, 0xb7, 0xe9, 0x79, 0x51, 0xef, 0x6c, 0x17, 0x09, 0xed, - 0x06, 0xa7, 0x4c, 0xb5, 0x4a, 0x67, 0x9b, 0xd4, 0x53, 0x47, 0x3d, 0x1d, 0xa2, 0x84, 0x9d, 0xac, - 0x1e, 0xae, 0xe1, 0xfb, 0xd4, 0x23, 0xd8, 0x0a, 0x01, 0x6a, 0xbb, 0x5b, 0xfb, 0x28, 0x99, 0x83, - 0x0b, 0x10, 0x23, 0xc9, 0x10, 0x20, 0x06, 0x36, 0xff, 0xbb, 0x01, 0x13, 0x16, 0x0d, 0xfd, 0x6e, - 0xd0, 0xa0, 0xb7, 0xa9, 0xe3, 0xd2, 0x80, 0x89, 0xff, 0x1d, 0xaf, 0xed, 0x8a, 0x39, 0x85, 0xe2, - 0xbf, 0xe7, 0xb5, 0xd5, 0x29, 0x8c, 0xe5, 0xe4, 0x53, 0x30, 0x52, 0xef, 0x6e, 0x21, 0x2a, 0x9f, - 0x53, 0x67, 0x70, 0xc4, 0xba, 0x5b, 0x76, 0x0a, 0x5d, 0xa2, 0x91, 0x6b, 0x30, 0xb2, 0x41, 0x83, - 0x30, 0xd1, 0x78, 0xa8, 0xd9, 0xef, 0x73, 0x90, 0x4a, 0x20, 0xb0, 0xc8, 0xbb, 0x89, 0xd6, 0x15, - 0x6b, 0xd2, 0x64, 0x4a, 0xd7, 0x25, 0xa2, 0xd2, 0x12, 0x10, 0x55, 0x54, 0x24, 0x96, 0xf9, 0x9d, - 0x1c, 0x94, 0x17, 0x9c, 0xc8, 0xd9, 0x72, 0x42, 0xd1, 0x9f, 0x1b, 0x37, 0x98, 0x1e, 0x57, 0x1a, - 0x8a, 0x7a, 0x9c, 0x7d, 0xf9, 0x47, 0x6e, 0xde, 0x0b, 0xe9, 0xe6, 0x8d, 0xb1, 0x05, 0x52, 0x34, - 0x2f, 0x69, 0xd4, 0x5b, 0xc7, 0x37, 0xaa, 0x2c, 0x1a, 0x55, 0x94, 0x8d, 0x4a, 0x9a, 0x42, 0xde, - 0x82, 0x42, 0xbd, 0x43, 0x1b, 0x42, 0x89, 0x48, 0xdd, 0xaf, 0x37, 0x8e, 0x21, 0x6c, 0xdc, 0xa8, - 0x95, 0x04, 0x9b, 0x42, 0xd8, 0xa1, 0x0d, 0x0b, 0xc9, 0x94, 0x49, 0xf3, 0xaf, 0x87, 0x61, 0x26, - 0x8b, 0x8c, 0xbc, 0xa5, 0x2f, 0x4e, 0xbc, 0x7b, 0x9e, 0xea, 0xbb, 0x38, 0xcd, 0x1a, 0xfa, 0xf2, - 0x74, 0x05, 0x8a, 0x6b, 0x4c, 0x20, 0x1b, 0x7e, 0x53, 0xf4, 0x1c, 0xd3, 0x8a, 0xc5, 0x8e, 0x84, - 0x19, 0x56, 0x5c, 0x4e, 0x9e, 0x82, 0xfc, 0x3d, 0x6b, 0x49, 0x74, 0xd7, 0xe8, 0xe1, 0x41, 0x25, - 0xdf, 0x0d, 0xbc, 0x59, 0xc3, 0x62, 0x50, 0x72, 0x0d, 0x86, 0xe7, 0xab, 0xf3, 0x34, 0x88, 0xb0, - 0x9b, 0x4a, 0xb5, 0xb3, 0x4c, 0x5a, 0x1a, 0x8e, 0xdd, 0xa0, 0x41, 0xa4, 0x55, 0x2f, 0xd0, 0xc8, - 0xcb, 0x90, 0xaf, 0x6e, 0xd6, 0x45, 0xcf, 0x80, 0xe8, 0x99, 0xea, 0x66, 0xbd, 0x36, 0x2e, 0x3a, - 0x22, 0xef, 0x3c, 0x08, 0x19, 0xf7, 0xea, 0x66, 0x5d, 0x1d, 0xad, 0xe1, 0x23, 0x46, 0xeb, 0x32, - 0x14, 0x99, 0x9d, 0xc1, 0x16, 0x78, 0x54, 0x8a, 0xa3, 0xdc, 0x7c, 0xda, 0x15, 0x30, 0x2b, 0x2e, - 0x25, 0xcf, 0xc5, 0x66, 0x4b, 0x31, 0xe1, 0x27, 0xcc, 0x16, 0x69, 0xac, 0x90, 0x87, 0x30, 0xbe, - 0xb0, 0xdf, 0x76, 0x5a, 0x5e, 0x43, 0x2c, 0xe1, 0xa3, 0xb8, 0x84, 0x5f, 0x3d, 0x62, 0x18, 0xaf, - 0x6a, 0x04, 0x7c, 0x55, 0x97, 0xca, 0x77, 0xd6, 0xe5, 0x65, 0x76, 0x7a, 0x85, 0x9f, 0x35, 0x2c, - 0xbd, 0x22, 0x36, 0x97, 0xa4, 0x8a, 0x44, 0xbb, 0x2a, 0x11, 0x3b, 0x09, 0x4e, 0xe6, 0x52, 0x20, - 0x20, 0xea, 0x5c, 0x8a, 0x17, 0xdd, 0xb7, 0x20, 0xff, 0xee, 0xfc, 0xda, 0xec, 0x18, 0xf2, 0x20, - 0x82, 0xc7, 0xbb, 0xf3, 0x6b, 0xf3, 0x4d, 0xbf, 0xeb, 0xd6, 0xdf, 0x5f, 0xae, 0x9d, 0x15, 0x6c, - 0xc6, 0x77, 0x1a, 0x1d, 0xed, 0x8b, 0x18, 0x1d, 0x59, 0x84, 0xa2, 0x6c, 0xe5, 0x6c, 0x09, 0x79, - 0x4c, 0xa5, 0x1a, 0xbf, 0x71, 0x83, 0xcf, 0x35, 0x57, 0xfc, 0x56, 0xbf, 0x42, 0xe2, 0x90, 0x1b, - 0x28, 0x65, 0x0f, 0xf7, 0x97, 0x16, 0xc2, 0xd9, 0xf1, 0x8b, 0xf9, 0xcb, 0xa3, 0x28, 0x1e, 0xd3, - 0x1d, 0x06, 0xb3, 0x3d, 0x57, 0x35, 0x76, 0x62, 0xc4, 0xf3, 0x9b, 0x40, 0x7a, 0x3b, 0x33, 0xc3, - 0xfc, 0x78, 0x59, 0x35, 0x3f, 0xc6, 0xe6, 0x4e, 0x8b, 0x0f, 0x9c, 0xf7, 0x5b, 0x2d, 0xa7, 0xed, - 0x22, 0xed, 0xc6, 0x9c, 0x6a, 0x95, 0x54, 0x61, 0x22, 0xf9, 0xfa, 0x65, 0x2f, 0x8c, 0xc8, 0x35, - 0x18, 0x95, 0x10, 0xb6, 0xf2, 0xe4, 0x33, 0xdb, 0x69, 0x25, 0x38, 0xe6, 0x1f, 0xe6, 0x00, 0x92, - 0x92, 0x27, 0x54, 0x39, 0x7d, 0x46, 0x53, 0x4e, 0xa7, 0xd3, 0x52, 0xdd, 0x57, 0x2d, 0x91, 0x77, - 0x60, 0x98, 0xd9, 0x69, 0x5d, 0x69, 0x87, 0x9e, 0x4d, 0x93, 0x62, 0xe1, 0xc6, 0x8d, 0xda, 0x84, - 0x20, 0x1e, 0x0e, 0x11, 0x62, 0x09, 0x32, 0x45, 0xaf, 0xfd, 0xee, 0x50, 0x32, 0x18, 0x42, 0xa3, - 0x5d, 0x56, 0x54, 0x92, 0x91, 0x4c, 0x62, 0xa9, 0x92, 0x14, 0x85, 0x74, 0x8e, 0x2b, 0x24, 0xde, - 0xa9, 0x23, 0x42, 0x21, 0xa5, 0xd5, 0x11, 0xef, 0xc0, 0x63, 0xd5, 0x51, 0x27, 0x3d, 0xd7, 0x0b, - 0x28, 0x06, 0x97, 0x33, 0x7b, 0x25, 0x6b, 0x96, 0x5f, 0x3c, 0x6e, 0x96, 0xa7, 0xe7, 0xf8, 0x8d, - 0x7e, 0x0a, 0xf0, 0xb4, 0x9c, 0x92, 0xce, 0x03, 0x95, 0x1c, 0x15, 0xe1, 0x1b, 0x7c, 0x3e, 0x0f, - 0xf7, 0x9d, 0xcf, 0xa7, 0x33, 0xe7, 0x33, 0x9f, 0xcd, 0x6f, 0xc0, 0x50, 0xf5, 0x27, 0xba, 0x01, - 0x15, 0x06, 0x63, 0x49, 0xd6, 0xc9, 0x60, 0xb1, 0x22, 0x98, 0x74, 0xd8, 0x4f, 0xd5, 0xd0, 0xc6, - 0x72, 0x56, 0xf3, 0xfa, 0x72, 0x5d, 0x18, 0x83, 0x24, 0xd5, 0x2d, 0xeb, 0xcb, 0xca, 0x67, 0x47, - 0x5a, 0xab, 0x19, 0x15, 0xb9, 0x06, 0xb9, 0xea, 0x02, 0xee, 0x30, 0xc7, 0xe6, 0x46, 0x65, 0xb5, - 0x0b, 0xb5, 0x19, 0x41, 0x52, 0x72, 0xb4, 0x4d, 0x47, 0x75, 0x81, 0xd4, 0x60, 0xe8, 0xee, 0x7e, - 0xfd, 0xfd, 0x65, 0xa1, 0xfd, 0xa6, 0xa5, 0x5c, 0x33, 0xd8, 0x2a, 0x2e, 0x5d, 0x61, 0xf2, 0xc5, - 0xad, 0xfd, 0xf0, 0xab, 0x4d, 0xf5, 0x8b, 0x11, 0xed, 0xe3, 0x53, 0x20, 0xff, 0xdb, 0x50, 0x0c, - 0x14, 0x21, 0xeb, 0x6c, 0x23, 0x2c, 0x24, 0xce, 0x48, 0xcc, 0xa5, 0x1e, 0x89, 0x8b, 0xe5, 0xed, - 0x25, 0x3e, 0xfa, 0xb9, 0x9e, 0xd1, 0x1f, 0x53, 0x96, 0x3f, 0x3e, 0xe6, 0x71, 0x5f, 0xe4, 0x3f, - 0x72, 0x5f, 0x90, 0x77, 0xa0, 0x74, 0xd7, 0x69, 0x3b, 0x3b, 0xd4, 0xbd, 0x17, 0x32, 0xb3, 0xb7, - 0x80, 0x5a, 0x98, 0xd9, 0x09, 0x67, 0x5b, 0x1c, 0x6e, 0x77, 0x43, 0xcd, 0xaa, 0xb5, 0x34, 0x02, - 0xf3, 0xbf, 0xe4, 0xf1, 0x83, 0xc9, 0x2b, 0x30, 0x6c, 0xd1, 0x9d, 0xc4, 0xd4, 0xc0, 0x2d, 0x6b, - 0x80, 0x10, 0xb5, 0x95, 0x1c, 0x07, 0xd7, 0x31, 0xea, 0x86, 0xbb, 0xde, 0x76, 0x24, 0x9a, 0x1a, - 0xaf, 0x63, 0x02, 0xac, 0xac, 0x63, 0x02, 0xa2, 0xad, 0x63, 0x02, 0xc6, 0x26, 0x8b, 0xb5, 0x50, - 0x17, 0x3d, 0x20, 0xbb, 0xcb, 0x5a, 0x50, 0xa4, 0x2e, 0xd0, 0x96, 0x11, 0x86, 0x4d, 0x6e, 0xc2, - 0x68, 0xb5, 0xd1, 0xf0, 0xbb, 0xca, 0x9e, 0x6f, 0xf6, 0xf0, 0xa0, 0x32, 0xe3, 0x70, 0xa0, 0xee, - 0xa1, 0x48, 0x50, 0x49, 0x1d, 0xc6, 0x16, 0xd9, 0x46, 0xc9, 0x9b, 0x77, 0x1a, 0xbb, 0x54, 0xcc, - 0x50, 0x29, 0xf2, 0x4a, 0x49, 0x6c, 0xb8, 0x9f, 0xa6, 0x08, 0x6c, 0x30, 0xa0, 0xea, 0x08, 0x50, - 0x70, 0xc9, 0x3a, 0x8c, 0xd5, 0x69, 0x23, 0xa0, 0x51, 0x3d, 0xf2, 0x03, 0x9a, 0x9a, 0xc1, 0x4a, - 0x49, 0xed, 0x19, 0xb9, 0x57, 0x0b, 0x11, 0x68, 0x87, 0x0c, 0xaa, 0x72, 0x55, 0x90, 0xb9, 0xd1, - 0xdd, 0xf2, 0x83, 0xfd, 0x85, 0x9a, 0x98, 0xd5, 0xc9, 0x12, 0xc0, 0xc1, 0xaa, 0xd1, 0xcd, 0x20, - 0xee, 0x96, 0x6e, 0x74, 0x73, 0x2c, 0xf3, 0x6b, 0xda, 0xe7, 0xb1, 0xae, 0xbb, 0x43, 0xf7, 0xd7, - 0x02, 0xba, 0xed, 0x3d, 0x14, 0x23, 0x8d, 0x5d, 0xb7, 0x47, 0xf7, 0xed, 0x0e, 0x42, 0xd5, 0xae, - 0x8b, 0x51, 0xc9, 0xa7, 0xa1, 0x78, 0xe7, 0x6e, 0xfd, 0x0e, 0xdd, 0x5f, 0x5a, 0x10, 0x7a, 0x99, - 0x93, 0xb5, 0x42, 0x9b, 0x91, 0x6a, 0x3d, 0x1e, 0x63, 0x9a, 0xb5, 0x44, 0x4c, 0x58, 0xcd, 0xf3, - 0xcd, 0x6e, 0x18, 0xd1, 0x60, 0x69, 0x41, 0xad, 0xb9, 0xc1, 0x81, 0xa9, 0x41, 0x8b, 0x51, 0xcd, - 0xff, 0x64, 0xa0, 0x88, 0x90, 0xd7, 0x01, 0x96, 0xda, 0x6c, 0x23, 0xd5, 0xa0, 0x31, 0x03, 0x74, - 0xd6, 0x78, 0x02, 0xaa, 0x73, 0x50, 0x90, 0xf5, 0xaa, 0x73, 0x03, 0x57, 0xcd, 0xaa, 0x94, 0xdb, - 0x32, 0xe1, 0xb7, 0x13, 0x55, 0x06, 0x02, 0x9a, 0xaa, 0x32, 0x41, 0x26, 0x97, 0x60, 0x64, 0xa9, - 0x7a, 0xb7, 0xda, 0x8d, 0x76, 0x51, 0x40, 0x8b, 0x7c, 0xad, 0xf3, 0x9c, 0x96, 0xed, 0x74, 0xa3, - 0x5d, 0x4b, 0x16, 0x9a, 0xff, 0x26, 0xa7, 0xc9, 0x24, 0xb1, 0x80, 0x58, 0xb4, 0xd3, 0xf4, 0x1a, - 0x68, 0xe6, 0xbd, 0x1b, 0xf8, 0xdd, 0x4e, 0xdc, 0x5a, 0xf3, 0xf0, 0xa0, 0xf2, 0x4c, 0x90, 0x94, - 0xda, 0x3b, 0xac, 0x58, 0xff, 0x86, 0x0c, 0x6a, 0xf2, 0x39, 0x28, 0xb1, 0xb9, 0x2e, 0x7e, 0xb2, - 0xad, 0x31, 0xd3, 0x11, 0x17, 0x70, 0xeb, 0x1b, 0xd2, 0x20, 0x66, 0xa3, 0x29, 0x09, 0x95, 0x82, - 0xb8, 0x30, 0xbb, 0x1e, 0x38, 0xed, 0xd0, 0x8b, 0x16, 0xdb, 0x8d, 0x60, 0x1f, 0x75, 0xd3, 0x62, - 0xdb, 0xd9, 0x6a, 0x52, 0x17, 0xbb, 0xa5, 0x58, 0xbb, 0x7c, 0x78, 0x50, 0x79, 0x3e, 0xe2, 0x38, - 0x36, 0x8d, 0x91, 0x6c, 0xca, 0xb1, 0x14, 0xce, 0x7d, 0x39, 0x31, 0x5d, 0xb6, 0xd8, 0x76, 0x3b, - 0xbe, 0xd7, 0x8e, 0xd0, 0x71, 0x59, 0x88, 0xf7, 0x3c, 0x67, 0xa9, 0x80, 0xdb, 0x6c, 0x0e, 0xa8, - 0x9f, 0xa9, 0x12, 0x98, 0xff, 0xc7, 0x48, 0x66, 0x0d, 0x79, 0x13, 0xc6, 0xc4, 0x48, 0x2a, 0x7e, - 0xc2, 0xf3, 0x6c, 0xfe, 0xc9, 0x61, 0x67, 0x1b, 0x06, 0x75, 0xfe, 0x29, 0xe8, 0xcc, 0xb6, 0xab, - 0xce, 0x2f, 0x23, 0xa5, 0x62, 0xdb, 0x39, 0x8d, 0x66, 0x9a, 0x4a, 0xa2, 0x31, 0x61, 0x59, 0x5f, - 0xae, 0xeb, 0xbd, 0x82, 0xc2, 0x12, 0x35, 0xc3, 0x8c, 0x6e, 0x50, 0x90, 0x1f, 0xbd, 0xe1, 0x3f, - 0x6d, 0xc0, 0x98, 0x62, 0x2c, 0x30, 0x81, 0x5f, 0x0b, 0xfc, 0x0f, 0x69, 0x23, 0xd2, 0xe7, 0x5a, - 0x87, 0x03, 0x53, 0x02, 0x1f, 0xa3, 0xa6, 0xe6, 0x58, 0xee, 0x04, 0x73, 0xcc, 0xbc, 0x26, 0x6c, - 0x10, 0x72, 0x49, 0x73, 0xcc, 0xa2, 0xe7, 0x22, 0xd5, 0x65, 0x58, 0x6e, 0xfe, 0x96, 0xc1, 0x6c, - 0x07, 0x72, 0x0d, 0xe0, 0x0e, 0xdd, 0x8f, 0x9c, 0xad, 0x5b, 0x5e, 0x53, 0x73, 0xb8, 0xef, 0x21, - 0xd4, 0xde, 0xf6, 0x9a, 0xd4, 0x52, 0x50, 0xd8, 0x9e, 0xe3, 0x4e, 0xb0, 0xf5, 0x1a, 0xa2, 0xe7, - 0x62, 0x1b, 0x70, 0x7a, 0x2f, 0xd8, 0x7a, 0x0d, 0x91, 0x35, 0x45, 0x24, 0x10, 0x89, 0x09, 0xc3, - 0x0b, 0x7e, 0xcb, 0xf1, 0xa4, 0xdd, 0x0d, 0xcc, 0x78, 0x75, 0x11, 0x62, 0x89, 0x12, 0x66, 0x75, - 0xd6, 0xd7, 0x56, 0x44, 0xe7, 0xa3, 0xd5, 0x19, 0x76, 0xda, 0x16, 0x83, 0x99, 0xbf, 0x6d, 0xc0, - 0x98, 0x62, 0x12, 0x91, 0x4f, 0x0b, 0xe7, 0xa4, 0x81, 0xae, 0xf5, 0x33, 0xbd, 0x46, 0x13, 0x2b, - 0xe5, 0xfb, 0x85, 0x96, 0xef, 0x52, 0xe1, 0xaa, 0x4c, 0x2c, 0x89, 0xdc, 0x20, 0x96, 0xc4, 0xeb, - 0x00, 0x7c, 0x07, 0x8a, 0xdd, 0xa9, 0x68, 0x1f, 0xe5, 0x28, 0x42, 0x1d, 0x8c, 0x04, 0xd9, 0xb4, - 0xa0, 0xa4, 0x5a, 0x11, 0xa4, 0x06, 0xe3, 0xc2, 0xe1, 0x22, 0x76, 0x1f, 0xbc, 0x9f, 0x51, 0x05, - 0x08, 0x6e, 0xbd, 0x0e, 0x20, 0x9d, 0xc4, 0xfc, 0x99, 0x1c, 0x14, 0x05, 0x64, 0xee, 0x09, 0xdd, - 0x18, 0xbd, 0xa6, 0x6d, 0x8c, 0xa6, 0xe3, 0x35, 0x3a, 0xde, 0xe6, 0xcf, 0x1d, 0xe3, 0xad, 0x79, - 0x1d, 0x4a, 0xb2, 0x0b, 0x70, 0x7f, 0xf9, 0x12, 0x8c, 0x48, 0x7f, 0x23, 0xdf, 0x5d, 0x4e, 0x6a, - 0x3c, 0x37, 0xe6, 0x2c, 0x59, 0x6e, 0xfe, 0xd9, 0x90, 0xa4, 0xe5, 0x35, 0xb1, 0x2e, 0xac, 0xba, - 0x6e, 0xa0, 0x76, 0xa1, 0xe3, 0xba, 0x81, 0x85, 0x50, 0x36, 0xf8, 0x6b, 0xdd, 0xad, 0xa6, 0xd7, - 0x40, 0x1c, 0x65, 0x26, 0x76, 0x10, 0x6a, 0x33, 0x54, 0x75, 0xf0, 0x13, 0x64, 0xcd, 0x59, 0x92, - 0x3f, 0xd2, 0x59, 0xf2, 0x65, 0x18, 0x9d, 0x6f, 0xb9, 0xda, 0xbe, 0xc8, 0xcc, 0xe8, 0x94, 0xab, - 0x31, 0x12, 0xdf, 0x11, 0x5d, 0x10, 0x7d, 0x34, 0xd3, 0x68, 0xb9, 0xbd, 0xbb, 0xa1, 0x84, 0xa5, - 0xe6, 0xed, 0x18, 0x7a, 0x14, 0x6f, 0xc7, 0x4d, 0x18, 0xbd, 0x17, 0xd2, 0xf5, 0x6e, 0xbb, 0x4d, - 0x9b, 0x68, 0x61, 0x15, 0xb9, 0x3e, 0xeb, 0x86, 0xd4, 0x8e, 0x10, 0xaa, 0x7e, 0x40, 0x8c, 0xaa, - 0x8a, 0xd5, 0xc8, 0x11, 0x62, 0xf5, 0x69, 0x28, 0x54, 0x3b, 0x1d, 0xe9, 0x06, 0x8a, 0x8d, 0xf6, - 0x4e, 0x07, 0xad, 0xe0, 0x09, 0xa7, 0xd3, 0xd1, 0x9d, 0x3a, 0x88, 0x4d, 0x28, 0x90, 0x3b, 0xdd, - 0x2d, 0x1a, 0xb4, 0x69, 0x44, 0x43, 0xb1, 0x76, 0x84, 0xb3, 0x80, 0x3c, 0x66, 0xe5, 0x69, 0x5b, - 0x1a, 0x81, 0x6b, 0xf5, 0xbd, 0xee, 0x16, 0xb5, 0xc5, 0x32, 0xa4, 0xf6, 0x5d, 0x06, 0x43, 0xf4, - 0xb1, 0x50, 0x1a, 0xa0, 0x1c, 0x8c, 0x25, 0xfa, 0xae, 0x43, 0x69, 0x90, 0x96, 0x82, 0x18, 0x51, - 0x73, 0xcc, 0x94, 0x06, 0x75, 0xcc, 0xd4, 0x61, 0x42, 0x1f, 0xe9, 0xc7, 0xb0, 0xa7, 0x7a, 0xaf, - 0x50, 0x2c, 0x96, 0x47, 0xcd, 0x6f, 0xe4, 0x60, 0xac, 0xda, 0xe9, 0x3c, 0xe1, 0x5e, 0xdf, 0x1f, - 0xd3, 0xf4, 0xc7, 0x99, 0x44, 0x4e, 0x4e, 0xe0, 0xf0, 0xfd, 0x9d, 0x1c, 0x4c, 0xa6, 0x28, 0xd4, - 0xaf, 0x37, 0x06, 0xf4, 0x82, 0xe6, 0x06, 0xf4, 0x82, 0xe6, 0xfb, 0x7b, 0x41, 0xd5, 0xd9, 0x59, - 0x78, 0x94, 0xd9, 0xf9, 0x22, 0xe4, 0xab, 0x9d, 0x8e, 0xe8, 0x95, 0x52, 0xd2, 0x2b, 0x1b, 0x37, - 0xf8, 0x32, 0xea, 0x74, 0x3a, 0x16, 0xc3, 0xd0, 0xa4, 0x72, 0x78, 0x40, 0xa9, 0x34, 0x5f, 0x85, - 0x51, 0xe4, 0x85, 0x0a, 0xf7, 0xa2, 0x98, 0xa9, 0x5c, 0xdb, 0x6a, 0x75, 0xf1, 0x59, 0x69, 0xfe, - 0x99, 0x01, 0x43, 0xf8, 0xfb, 0x09, 0x95, 0xb1, 0x39, 0x4d, 0xc6, 0xca, 0x8a, 0x8c, 0x0d, 0x22, - 0x5d, 0xbf, 0x9b, 0xc7, 0xde, 0x12, 0x72, 0x25, 0xfc, 0x68, 0x46, 0x86, 0x1f, 0xed, 0x11, 0xd6, - 0x97, 0xbd, 0xb4, 0x47, 0x2d, 0x8f, 0x83, 0xf1, 0x5c, 0xfa, 0x53, 0x1f, 0x8b, 0x33, 0xed, 0x36, - 0x90, 0xa5, 0x76, 0x48, 0x1b, 0xdd, 0x80, 0xd6, 0xf7, 0xbc, 0xce, 0x06, 0x0d, 0xbc, 0xed, 0x7d, - 0xb1, 0xa5, 0xc2, 0x25, 0xc0, 0x13, 0xa5, 0x76, 0xb8, 0xe7, 0x75, 0x98, 0x15, 0xe3, 0x6d, 0xef, - 0x5b, 0x19, 0x34, 0xe4, 0x1d, 0x18, 0xb1, 0xe8, 0x83, 0xc0, 0x8b, 0xe4, 0xc6, 0x7f, 0x22, 0xf6, - 0x58, 0x20, 0x94, 0x9b, 0x63, 0x01, 0xff, 0xa1, 0x8e, 0xbf, 0x28, 0xff, 0xf8, 0xdc, 0x4e, 0xdf, - 0x1d, 0xc2, 0x09, 0x74, 0x4c, 0x48, 0xc3, 0x11, 0x4e, 0x51, 0x7d, 0x30, 0xf3, 0x27, 0x19, 0xcc, - 0x0d, 0x28, 0xd5, 0xd9, 0x34, 0xd6, 0xbd, 0xa3, 0x17, 0x92, 0xb1, 0xbc, 0xaa, 0x16, 0x1f, 0x15, - 0xcd, 0xa0, 0xf1, 0x21, 0x76, 0x5a, 0x48, 0x78, 0x94, 0xc4, 0xd3, 0x0a, 0xe3, 0x0c, 0xf1, 0x88, - 0xf5, 0x4d, 0x83, 0x77, 0xd6, 0x89, 0x05, 0x63, 0xf8, 0xd1, 0x04, 0x63, 0xe4, 0xa3, 0x08, 0x46, - 0x3a, 0x8e, 0xa4, 0x78, 0x92, 0x38, 0x92, 0xf3, 0xef, 0xc0, 0x54, 0x4f, 0x0f, 0x9f, 0x24, 0x16, - 0xe3, 0xe3, 0x13, 0xcb, 0x9f, 0x8c, 0xfb, 0x85, 0xcc, 0xa1, 0x1f, 0xc7, 0x0b, 0x68, 0x23, 0x42, - 0xd5, 0x2b, 0xb4, 0x65, 0x20, 0x60, 0x29, 0xcf, 0x1e, 0xc2, 0xc8, 0xdb, 0x30, 0xc2, 0xcf, 0xb2, - 0xb9, 0xc3, 0x61, 0x6c, 0x6e, 0x5c, 0xd4, 0xc8, 0xa1, 0x22, 0xa0, 0x88, 0x63, 0xa8, 0xbd, 0x2a, - 0x88, 0xcc, 0x77, 0x61, 0x58, 0x9c, 0x85, 0x1f, 0x3d, 0x2f, 0x2a, 0x30, 0xb4, 0x91, 0xf4, 0x0c, - 0x9e, 0x5f, 0xf2, 0x46, 0x58, 0x1c, 0x6e, 0xfe, 0xac, 0x01, 0x13, 0x7a, 0x2b, 0xc9, 0x55, 0x18, - 0x16, 0xc1, 0x1a, 0x06, 0x06, 0x6b, 0xb0, 0xd6, 0x0c, 0xf3, 0x30, 0x0d, 0x2d, 0x38, 0x43, 0x60, - 0x31, 0xd5, 0x2f, 0x38, 0x08, 0xe7, 0x09, 0xaa, 0x7e, 0x21, 0xa4, 0x96, 0x2c, 0x63, 0xbb, 0x4c, - 0x8b, 0x86, 0xdd, 0x66, 0xa4, 0xee, 0x32, 0x03, 0x84, 0x58, 0xa2, 0xc4, 0x3c, 0x30, 0x00, 0xea, - 0xf5, 0xdb, 0x77, 0xe8, 0xfe, 0x9a, 0xe3, 0x05, 0xb8, 0x53, 0xc7, 0xd9, 0x78, 0x47, 0x8c, 0x56, - 0x49, 0xec, 0xd4, 0xf9, 0xcc, 0xdd, 0xa3, 0xfb, 0xda, 0x4e, 0x5d, 0xa2, 0xe2, 0x94, 0x0f, 0xbc, - 0xfb, 0x4e, 0x44, 0x19, 0x61, 0x0e, 0x09, 0xf9, 0x94, 0xe7, 0xd0, 0x14, 0xa5, 0x82, 0x4c, 0x3e, - 0x80, 0x89, 0xe4, 0x17, 0xfa, 0x1b, 0xf2, 0xb8, 0x8d, 0x95, 0x12, 0xa1, 0x17, 0xd6, 0x9e, 0x39, - 0x3c, 0xa8, 0x9c, 0x57, 0xb8, 0xa6, 0x3d, 0x11, 0x29, 0x66, 0xe6, 0x6f, 0x18, 0xe8, 0x08, 0x91, - 0x0d, 0xbc, 0x04, 0x85, 0xd8, 0x79, 0x5e, 0xe2, 0xee, 0x80, 0xd4, 0x7e, 0x17, 0xcb, 0xc9, 0x73, - 0x90, 0x4f, 0x5a, 0x32, 0x75, 0x78, 0x50, 0x19, 0xd7, 0x5b, 0xc0, 0x4a, 0xc9, 0xbb, 0x30, 0x32, - 0xd0, 0x37, 0xa3, 0x74, 0x66, 0x7c, 0xab, 0xa4, 0xc6, 0x51, 0x78, 0x6f, 0x73, 0xfd, 0x93, 0x3b, - 0x0a, 0xdf, 0xce, 0xc1, 0x24, 0xeb, 0xd7, 0x6a, 0x37, 0xda, 0xf5, 0x03, 0x2f, 0xda, 0x7f, 0x62, - 0x37, 0xed, 0x6f, 0x6a, 0x06, 0xd1, 0x79, 0xa9, 0xb6, 0xd4, 0xb6, 0x0d, 0xb4, 0x77, 0xff, 0xe3, - 0x11, 0x98, 0xce, 0xa0, 0x22, 0xaf, 0x88, 0x30, 0xc9, 0xc4, 0x4d, 0x86, 0x61, 0x90, 0x3f, 0x3a, - 0xa8, 0x94, 0x24, 0xfa, 0x7a, 0x12, 0x16, 0x39, 0xa7, 0x7b, 0x15, 0x79, 0x4f, 0x61, 0x7c, 0x9d, - 0xea, 0x55, 0xd4, 0x7d, 0x89, 0x55, 0x28, 0xcd, 0xef, 0xd2, 0xc6, 0x9e, 0xd7, 0xde, 0xb9, 0x43, - 0xf7, 0xb9, 0xbd, 0x54, 0xaa, 0x3d, 0xcd, 0x36, 0x82, 0x0d, 0x01, 0x67, 0x43, 0xaa, 0xef, 0x31, - 0x35, 0x12, 0xf2, 0x36, 0x8c, 0xd5, 0xbd, 0x9d, 0xb6, 0xe4, 0x50, 0x40, 0x0e, 0x17, 0xf0, 0x30, - 0x81, 0x83, 0x7b, 0x19, 0xa8, 0x04, 0xe4, 0x25, 0x18, 0xb2, 0xfc, 0x26, 0xe5, 0xcb, 0xb0, 0x08, - 0xbc, 0x0b, 0x18, 0x40, 0x3d, 0x51, 0x42, 0x0c, 0x72, 0x1b, 0x46, 0xd8, 0x3f, 0x77, 0x9d, 0x0e, - 0xda, 0xe8, 0xc9, 0x59, 0x86, 0x80, 0x76, 0xbc, 0xf6, 0x8e, 0xba, 0x31, 0x68, 0x52, 0xbb, 0xe5, - 0x74, 0xb4, 0x75, 0x91, 0x23, 0x92, 0x0d, 0x18, 0x4b, 0x14, 0x41, 0x38, 0x3b, 0xa2, 0x9d, 0xbf, - 0x27, 0x25, 0xb5, 0x67, 0x05, 0xb3, 0xb3, 0x51, 0x93, 0x9f, 0x26, 0x74, 0x18, 0xbe, 0xde, 0x18, - 0x85, 0x91, 0xb6, 0x71, 0x29, 0xf6, 0xdf, 0xb8, 0x18, 0xc7, 0x6e, 0x5c, 0x5c, 0x00, 0xd1, 0x49, - 0xd5, 0xe6, 0x8e, 0x88, 0x93, 0x7d, 0xa9, 0xbf, 0x80, 0x5d, 0x4d, 0x90, 0x71, 0x4e, 0x72, 0x67, - 0x9c, 0xe8, 0x7f, 0xa7, 0xb9, 0xa3, 0x39, 0xe3, 0x62, 0x54, 0xd6, 0x0d, 0x89, 0xaa, 0x91, 0x0e, - 0x02, 0xd9, 0x0d, 0x49, 0x49, 0xd2, 0x0d, 0x1f, 0x3e, 0x88, 0xfa, 0x75, 0x83, 0xc2, 0x88, 0xac, - 0x00, 0x54, 0x1b, 0x91, 0x77, 0x9f, 0xa2, 0x48, 0x8c, 0x69, 0x1d, 0x31, 0x5f, 0xbd, 0x43, 0xf7, - 0xeb, 0x34, 0x4a, 0x4e, 0xb2, 0x1c, 0x44, 0x4d, 0x89, 0x89, 0xa5, 0x70, 0x20, 0x1d, 0x38, 0x5d, - 0x75, 0x5d, 0x8f, 0xc7, 0x4e, 0xaf, 0x07, 0x4c, 0x7e, 0x5d, 0x64, 0x5d, 0xca, 0x66, 0xfd, 0x92, - 0x60, 0xfd, 0xac, 0x13, 0x53, 0xd9, 0x11, 0x27, 0x4b, 0x57, 0x93, 0xcd, 0xd8, 0x5c, 0x85, 0x09, - 0xbd, 0x4b, 0xf5, 0xa8, 0xe1, 0x12, 0x14, 0xad, 0x7a, 0xd5, 0xae, 0xdf, 0xae, 0x5e, 0x2f, 0x1b, - 0xa4, 0x0c, 0x25, 0xf1, 0x6b, 0xce, 0x9e, 0x7b, 0xed, 0x66, 0x39, 0xa7, 0x41, 0x5e, 0xbb, 0x3e, - 0x57, 0xce, 0x9b, 0xbf, 0x6b, 0x40, 0x51, 0x7e, 0x1f, 0xb9, 0x09, 0xf9, 0x7a, 0xfd, 0x76, 0x2a, - 0xec, 0x23, 0x59, 0x7a, 0xf9, 0x22, 0x13, 0x86, 0xbb, 0xea, 0x22, 0x53, 0xaf, 0xdf, 0x66, 0x74, - 0xeb, 0xcb, 0x75, 0x61, 0xb4, 0x64, 0x88, 0xeb, 0x54, 0x9f, 0xb3, 0xf0, 0x9b, 0x90, 0x7f, 0x6f, - 0x73, 0x5d, 0xec, 0x86, 0x32, 0xc6, 0x17, 0xe9, 0x3e, 0x7c, 0xa0, 0x2e, 0x7d, 0x8c, 0xc0, 0xb4, - 0x60, 0x4c, 0x99, 0x5a, 0xdc, 0x88, 0x68, 0xf9, 0x71, 0x3c, 0xad, 0x30, 0x22, 0x18, 0xc4, 0x12, - 0x25, 0xcc, 0xe6, 0x59, 0xf6, 0x1b, 0x4e, 0x53, 0x58, 0x23, 0x68, 0xf3, 0x34, 0x19, 0xc0, 0xe2, - 0x70, 0xf3, 0x0f, 0x0c, 0x28, 0xaf, 0x05, 0xfe, 0x7d, 0x8f, 0x69, 0xe0, 0x75, 0x7f, 0x8f, 0xb6, - 0x37, 0xae, 0x93, 0x57, 0xa5, 0x12, 0x30, 0xe2, 0xbd, 0xf7, 0x10, 0x2a, 0x81, 0x1f, 0x1d, 0x54, - 0xa0, 0xbe, 0x1f, 0x46, 0xb4, 0xc5, 0xca, 0xa5, 0x22, 0x50, 0xc2, 0x92, 0x73, 0x83, 0x87, 0x3a, - 0x1e, 0x13, 0x96, 0x5c, 0x81, 0x21, 0xfc, 0x1c, 0x25, 0xda, 0x6c, 0x28, 0x62, 0x00, 0x8b, 0xc3, - 0x15, 0x85, 0xfd, 0x9d, 0x5c, 0x4f, 0x1b, 0xe6, 0x3e, 0x51, 0xe1, 0x82, 0x7a, 0xe3, 0x06, 0x5a, - 0xc4, 0xbe, 0x00, 0x33, 0xe9, 0x2e, 0x41, 0xbf, 0x48, 0x15, 0x26, 0x75, 0xb8, 0x74, 0x91, 0x9c, - 0xcd, 0xac, 0x6b, 0x63, 0xce, 0x4a, 0xe3, 0x9b, 0x3f, 0x30, 0x60, 0x14, 0xff, 0xb5, 0xba, 0x4d, - 0x3c, 0xcd, 0xaa, 0x6e, 0xd6, 0xc5, 0xd1, 0xb9, 0x7a, 0xda, 0xea, 0x3c, 0x08, 0x6d, 0x71, 0xce, - 0xae, 0xe9, 0x91, 0x18, 0x59, 0x90, 0xf2, 0x40, 0x01, 0x79, 0xd8, 0x18, 0x93, 0xf2, 0x88, 0x82, - 0x30, 0x45, 0x2a, 0x90, 0xf1, 0xd4, 0x6d, 0xb3, 0xce, 0xc4, 0x4f, 0x8c, 0x06, 0x3f, 0x75, 0x63, - 0x74, 0x7e, 0x53, 0x3f, 0x75, 0xe3, 0x68, 0xe4, 0x55, 0x18, 0x66, 0x55, 0x5b, 0xf2, 0xdc, 0x06, - 0x77, 0x15, 0xf8, 0x8d, 0x81, 0x16, 0xb7, 0xc0, 0x91, 0xcc, 0x7f, 0x92, 0x4b, 0x77, 0xa0, 0xb0, - 0x02, 0x4e, 0x38, 0x37, 0xde, 0x80, 0xa1, 0x6a, 0xb3, 0xe9, 0x3f, 0x10, 0x5a, 0x42, 0xba, 0x69, - 0xe2, 0xfe, 0xe3, 0x2b, 0xac, 0xc3, 0x50, 0xb4, 0x88, 0x1b, 0x06, 0x20, 0xf3, 0x30, 0x5a, 0xdd, - 0xac, 0x2f, 0x2d, 0x2d, 0xac, 0xaf, 0x2f, 0x8b, 0xdb, 0x20, 0x2f, 0xc8, 0xfe, 0xf1, 0x3c, 0xd7, - 0x8e, 0xa2, 0x66, 0x9f, 0x60, 0xf1, 0x84, 0x8e, 0xbc, 0x05, 0xf0, 0x9e, 0xef, 0xb5, 0xef, 0xd2, - 0x68, 0xd7, 0x77, 0x45, 0xe3, 0x99, 0x49, 0x31, 0xf6, 0xa1, 0xef, 0xb5, 0xed, 0x16, 0x82, 0xd9, - 0xb7, 0x27, 0x48, 0x96, 0xf2, 0x3f, 0xeb, 0xe9, 0x9a, 0x1f, 0xa1, 0x0d, 0x33, 0x94, 0xf4, 0xf4, - 0x96, 0x1f, 0xf5, 0x9c, 0x6f, 0x0a, 0x34, 0xf3, 0xe7, 0x72, 0x30, 0xc1, 0x77, 0xaa, 0x5c, 0x60, - 0x9e, 0xd8, 0xc9, 0xf8, 0x86, 0x36, 0x19, 0xcf, 0xc9, 0x85, 0x41, 0x69, 0xda, 0x40, 0x53, 0x71, - 0x17, 0x48, 0x2f, 0x0d, 0xb1, 0xa4, 0x3f, 0x65, 0x90, 0x59, 0x78, 0x3d, 0x89, 0x72, 0x09, 0x91, - 0xc8, 0x46, 0x55, 0x18, 0x5a, 0x1a, 0x0f, 0xf3, 0x67, 0x73, 0x30, 0xae, 0xd8, 0x93, 0x4f, 0x6c, - 0xc7, 0x7f, 0x56, 0xeb, 0x78, 0x79, 0x44, 0xa2, 0xb4, 0x6c, 0xa0, 0x7e, 0xef, 0xc2, 0x54, 0x0f, - 0x49, 0xda, 0x2c, 0x37, 0x06, 0x31, 0xcb, 0x5f, 0xe9, 0x8d, 0x0a, 0xe1, 0x37, 0x47, 0xe2, 0xa8, - 0x10, 0x35, 0x0c, 0xe5, 0xdb, 0x39, 0x98, 0x11, 0xbf, 0xaa, 0x5d, 0xd7, 0x8b, 0xe6, 0xfd, 0xf6, - 0xb6, 0xb7, 0xf3, 0xc4, 0x8e, 0x45, 0x55, 0x1b, 0x8b, 0x8a, 0x3e, 0x16, 0x4a, 0x03, 0xfb, 0x0f, - 0x89, 0xf9, 0xcf, 0x8a, 0x30, 0xdb, 0x8f, 0x80, 0x6d, 0xfb, 0x95, 0x5d, 0x15, 0x6e, 0xfb, 0x53, - 0x3b, 0x56, 0xbe, 0x9f, 0x4a, 0xc2, 0xce, 0x72, 0x03, 0x84, 0x9d, 0x2d, 0x43, 0x19, 0xab, 0xaa, - 0xd3, 0x90, 0x75, 0x42, 0x98, 0x84, 0xad, 0x5f, 0x3c, 0x3c, 0xa8, 0x5c, 0x70, 0x58, 0x99, 0x1d, - 0x8a, 0x42, 0xbb, 0x1b, 0x78, 0x0a, 0x8f, 0x1e, 0x4a, 0xf2, 0x1b, 0x06, 0x4c, 0x20, 0x70, 0xf1, - 0x3e, 0x6d, 0x47, 0xc8, 0xac, 0x20, 0x4e, 0x76, 0xe2, 0xdb, 0x81, 0xf5, 0x28, 0xf0, 0xda, 0x3b, - 0xe8, 0x48, 0x0a, 0x6b, 0x5b, 0xac, 0x17, 0xbe, 0x7f, 0x50, 0x79, 0xf3, 0xa3, 0xdc, 0x38, 0x14, - 0xac, 0x42, 0xb6, 0x91, 0xe7, 0x1f, 0x4a, 0xb1, 0xda, 0xd4, 0x67, 0xa6, 0xbe, 0x88, 0xfc, 0x38, - 0x9c, 0xe5, 0x61, 0x22, 0xf3, 0x7e, 0x3b, 0xf2, 0xda, 0x5d, 0xbf, 0x1b, 0xd6, 0x9c, 0xc6, 0x5e, - 0xb7, 0x13, 0x0a, 0x67, 0x27, 0xb6, 0xbc, 0x11, 0x17, 0xda, 0x5b, 0xbc, 0x54, 0x61, 0xd9, 0x8f, - 0x01, 0xb9, 0x0d, 0x53, 0xbc, 0xa8, 0xda, 0x8d, 0xfc, 0x7a, 0xc3, 0x69, 0x7a, 0xed, 0x1d, 0xf4, - 0x81, 0x16, 0x79, 0xa0, 0x8c, 0xd3, 0x8d, 0x7c, 0x3b, 0xe4, 0x70, 0x85, 0x5f, 0x2f, 0x11, 0x59, - 0x82, 0x49, 0x8b, 0x3a, 0xee, 0x5d, 0xe7, 0xe1, 0xbc, 0xd3, 0x71, 0x1a, 0x5e, 0xb4, 0x8f, 0x3b, - 0xb3, 0x7c, 0xad, 0x72, 0x78, 0x50, 0x79, 0x2a, 0xa0, 0x8e, 0x6b, 0xb7, 0x9c, 0x87, 0x76, 0x43, - 0x14, 0x2a, 0xcc, 0xd2, 0x74, 0x31, 0x2b, 0xaf, 0x1d, 0xb3, 0x1a, 0x4d, 0xb3, 0xf2, 0xda, 0xfd, - 0x59, 0x25, 0x74, 0x92, 0xd5, 0xba, 0x13, 0xec, 0xd0, 0x88, 0x3b, 0x09, 0xe1, 0xa2, 0x71, 0xd9, - 0x50, 0x58, 0x45, 0x58, 0x66, 0xa3, 0xc3, 0x30, 0xcd, 0x4a, 0xa1, 0x63, 0x92, 0xb7, 0x19, 0x78, - 0x11, 0x55, 0x5b, 0x38, 0x86, 0x9f, 0x85, 0xfd, 0x8f, 0x6e, 0xd2, 0x7e, 0x4d, 0xec, 0xa1, 0x4c, - 0xb8, 0x29, 0x8d, 0x2c, 0xf5, 0x70, 0xcb, 0x6e, 0x65, 0x0f, 0x65, 0xcc, 0x4d, 0x6d, 0xe7, 0x38, - 0xb6, 0x53, 0xe1, 0xd6, 0xa7, 0xa1, 0x3d, 0x94, 0x64, 0x85, 0x75, 0x5a, 0x44, 0xdb, 0x4c, 0xa2, - 0x85, 0x93, 0x74, 0x02, 0x3f, 0xed, 0x79, 0xb1, 0xa7, 0x2e, 0x07, 0xb2, 0xd8, 0xce, 0x70, 0x99, - 0xa6, 0x89, 0xdf, 0x2b, 0x14, 0x87, 0xca, 0xc3, 0x56, 0x99, 0x8b, 0x7c, 0xc4, 0x04, 0x07, 0x75, - 0xb1, 0xf9, 0x2b, 0x39, 0x38, 0x27, 0xd5, 0x31, 0x8d, 0x1e, 0xf8, 0xc1, 0x9e, 0xd7, 0xde, 0x79, - 0xc2, 0xb5, 0xea, 0x2d, 0x4d, 0xab, 0x3e, 0x9f, 0x5a, 0xe1, 0x52, 0xad, 0x3c, 0x42, 0xb5, 0xfe, - 0xfe, 0x30, 0x3c, 0x7d, 0x24, 0x15, 0x79, 0x9f, 0xad, 0x82, 0x1e, 0x6d, 0x47, 0x4b, 0x6e, 0x93, - 0xb2, 0x6d, 0x98, 0xdf, 0x8d, 0x84, 0x33, 0xfb, 0xb9, 0xc3, 0x83, 0xca, 0x34, 0xbf, 0x34, 0x67, - 0x7b, 0x6e, 0x93, 0xda, 0x11, 0x2f, 0xd6, 0x86, 0xa9, 0x97, 0x9a, 0xb1, 0x8c, 0xaf, 0xf0, 0x2e, - 0xb5, 0x23, 0x1a, 0xdc, 0x77, 0xf8, 0xdd, 0x21, 0xc1, 0x72, 0x8f, 0xd2, 0x8e, 0xed, 0xb0, 0x52, - 0xdb, 0x13, 0xc5, 0x3a, 0xcb, 0x1e, 0x6a, 0x72, 0x4b, 0x61, 0x39, 0xcf, 0x36, 0x07, 0x77, 0x9d, - 0x87, 0xc2, 0xe2, 0x15, 0x51, 0xa7, 0x31, 0x4b, 0x1e, 0xb9, 0xdb, 0x72, 0x1e, 0x5a, 0xbd, 0x24, - 0xe4, 0x03, 0x38, 0x2d, 0x14, 0x37, 0x53, 0x62, 0x81, 0xdf, 0x94, 0x2d, 0x2e, 0x20, 0xaf, 0x17, - 0x0f, 0x0f, 0x2a, 0x67, 0x85, 0xda, 0xb7, 0x1b, 0x1c, 0x23, 0xb3, 0xd5, 0xd9, 0x5c, 0xc8, 0x3a, - 0x5b, 0xc8, 0x52, 0xdd, 0x71, 0x97, 0x86, 0xa1, 0xb3, 0x23, 0xad, 0x63, 0x7e, 0xa2, 0xa4, 0x74, - 0xa6, 0xdd, 0xe2, 0xe5, 0x56, 0x5f, 0x4a, 0x72, 0x1b, 0x26, 0x36, 0xe9, 0x96, 0x3a, 0x3e, 0xc3, - 0xf1, 0x14, 0x2f, 0x3f, 0xa0, 0x5b, 0xfd, 0x07, 0x27, 0x45, 0x47, 0x3c, 0x98, 0xc2, 0xe3, 0x70, - 0xb6, 0xd5, 0xa3, 0x6d, 0x1a, 0x60, 0xec, 0xd9, 0x08, 0xba, 0xab, 0x66, 0x13, 0xcb, 0x52, 0x2f, - 0xaf, 0x3d, 0x7b, 0x78, 0x50, 0x79, 0x9a, 0x1f, 0xad, 0x37, 0x05, 0xdc, 0x4e, 0xdd, 0xa0, 0xed, - 0xe5, 0x4a, 0xbe, 0x02, 0x93, 0x96, 0xdf, 0x8d, 0xbc, 0xf6, 0x4e, 0x3d, 0x0a, 0x9c, 0x88, 0xee, - 0x70, 0x45, 0x9e, 0x04, 0xb9, 0xa5, 0x4a, 0xb9, 0x63, 0x3a, 0xe0, 0x40, 0x3b, 0x14, 0x50, 0x4d, - 0x93, 0xea, 0x04, 0xe4, 0xcb, 0x30, 0xc1, 0xa3, 0x73, 0xe2, 0x0a, 0x46, 0xb5, 0xcb, 0x26, 0x7a, - 0xe1, 0xc6, 0x75, 0xdc, 0xd5, 0x9c, 0xe3, 0x51, 0x3e, 0x59, 0x15, 0xa4, 0xb8, 0x99, 0x07, 0x06, - 0x94, 0xd3, 0x3c, 0xc8, 0xe7, 0x61, 0xb4, 0xba, 0x43, 0xdb, 0x6c, 0x6c, 0x76, 0xc5, 0x15, 0x54, - 0x79, 0x21, 0x3e, 0x86, 0xeb, 0x44, 0x22, 0xa2, 0x9c, 0x15, 0xb2, 0xb1, 0x56, 0xbc, 0x44, 0xb7, - 0x4f, 0x59, 0x09, 0x33, 0xe2, 0x42, 0x09, 0x7b, 0x71, 0x8d, 0x52, 0xb6, 0xbc, 0x0b, 0x57, 0xc9, - 0xb3, 0xea, 0xb0, 0x88, 0xa2, 0x14, 0x7f, 0x0c, 0x04, 0xe2, 0xe3, 0xd3, 0xe1, 0x08, 0x5a, 0x15, - 0x1a, 0xd7, 0x1a, 0x40, 0x31, 0x6e, 0xe0, 0x39, 0x38, 0xdb, 0xe7, 0x9b, 0xcd, 0xfb, 0x70, 0xbe, - 0x7f, 0x8d, 0xe4, 0xf3, 0x30, 0x83, 0x84, 0xf3, 0x7e, 0xbb, 0x4d, 0x1b, 0x11, 0xce, 0x03, 0xb9, - 0xbb, 0xcf, 0xd7, 0x9e, 0x3f, 0x3c, 0xa8, 0x5c, 0xe4, 0xed, 0x6d, 0xc4, 0x08, 0x76, 0x7a, 0xa3, - 0x9f, 0xc9, 0xc1, 0xfc, 0xa5, 0x1c, 0xcc, 0x8a, 0xa9, 0x65, 0xd1, 0x86, 0x1f, 0xb8, 0x4f, 0xbe, - 0x2a, 0x5f, 0xd4, 0x54, 0xf9, 0x73, 0x71, 0x58, 0x5c, 0x56, 0x23, 0x8f, 0xd0, 0xe4, 0xbf, 0x63, - 0xc0, 0x85, 0xa3, 0x88, 0x58, 0xef, 0xc4, 0xa1, 0xa4, 0xa3, 0x3d, 0x21, 0xa3, 0x1d, 0x98, 0xc6, - 0x01, 0xc5, 0xc3, 0x80, 0xf0, 0xb6, 0x1f, 0x46, 0xe8, 0x91, 0xcd, 0x69, 0xc1, 0x21, 0x35, 0xdf, - 0x6f, 0xe2, 0xda, 0x5d, 0x7b, 0x85, 0x2d, 0xd1, 0xdf, 0x3f, 0xa8, 0x00, 0x03, 0xf1, 0xe0, 0x4f, - 0x66, 0xc7, 0x71, 0x29, 0xc3, 0xb3, 0x86, 0xd0, 0xc6, 0x30, 0xa0, 0x3d, 0xba, 0x1f, 0x5a, 0x59, - 0xac, 0xd1, 0xeb, 0x56, 0xed, 0x46, 0xbb, 0x6b, 0x01, 0xdd, 0xa6, 0x01, 0x6d, 0x37, 0xe8, 0x27, - 0xcc, 0xeb, 0xa6, 0x37, 0x6e, 0xa0, 0x2d, 0xe7, 0x9f, 0x8c, 0xc0, 0x4c, 0x16, 0x19, 0xeb, 0x17, - 0x65, 0x97, 0x93, 0x4e, 0xa1, 0xf1, 0x57, 0x0d, 0x28, 0xd5, 0x69, 0xc3, 0x6f, 0xbb, 0xb7, 0x9c, - 0x46, 0xe4, 0xcb, 0x30, 0x1b, 0x9b, 0xaf, 0x56, 0x0c, 0x6e, 0x6f, 0x63, 0x81, 0xe6, 0xed, 0xf9, - 0xdc, 0x60, 0x9b, 0x8b, 0x86, 0x8f, 0xb1, 0xd7, 0x11, 0xde, 0x31, 0x89, 0xab, 0xc0, 0x93, 0x2a, - 0xad, 0x52, 0x52, 0x83, 0x71, 0x31, 0x5d, 0x7d, 0x35, 0x92, 0x18, 0x63, 0x7f, 0x1b, 0xb2, 0x20, - 0xed, 0xf5, 0xd1, 0x49, 0xc8, 0x0d, 0xc8, 0xdf, 0x9b, 0xbb, 0x25, 0xc6, 0x40, 0xc6, 0x47, 0xde, - 0x9b, 0xbb, 0x85, 0xfe, 0x0b, 0x66, 0x13, 0x8e, 0x77, 0xe7, 0xb6, 0x55, 0xbf, 0xf6, 0xbd, 0xb9, - 0x5b, 0x64, 0x15, 0xa6, 0x2c, 0xfa, 0xd5, 0xae, 0x17, 0x50, 0x31, 0x01, 0xee, 0xde, 0xaa, 0xe2, - 0x58, 0x14, 0xf9, 0xda, 0x14, 0xf0, 0x42, 0xb9, 0x5f, 0xb3, 0x5b, 0xdb, 0xea, 0xb5, 0xf1, 0x5e, - 0x5a, 0xf2, 0x53, 0x70, 0x7a, 0xc1, 0x0b, 0xc5, 0x37, 0x73, 0x87, 0xb2, 0x8b, 0x67, 0xcb, 0xc3, - 0x7d, 0xa6, 0xc3, 0x67, 0x32, 0xa7, 0xc3, 0xb3, 0x6e, 0xcc, 0xc4, 0xe6, 0xde, 0x6a, 0x37, 0x1d, - 0x82, 0x9d, 0x5d, 0x0f, 0xf9, 0x10, 0x26, 0xd0, 0x83, 0x87, 0x3e, 0x76, 0xbc, 0xdb, 0x31, 0xd2, - 0xa7, 0xe6, 0x4f, 0x65, 0xd6, 0x7c, 0x1e, 0x1d, 0x82, 0x36, 0x7a, 0xea, 0xf1, 0x1e, 0x88, 0xb6, - 0xef, 0xd3, 0x38, 0x93, 0xf7, 0x60, 0x52, 0x18, 0x12, 0xab, 0xdb, 0xeb, 0xbb, 0x74, 0xc1, 0xd9, - 0x17, 0x81, 0x25, 0x68, 0xd3, 0x0b, 0xeb, 0xc3, 0xf6, 0xb7, 0xed, 0x68, 0x97, 0xda, 0xae, 0xa3, - 0x2d, 0xb9, 0x29, 0x42, 0xf2, 0x35, 0x18, 0x5b, 0xf6, 0xf1, 0x30, 0x11, 0x55, 0xcd, 0x28, 0xf2, - 0xf9, 0x02, 0xa6, 0x8d, 0xe0, 0xe0, 0x94, 0x61, 0xf0, 0xa3, 0x83, 0xca, 0x1b, 0x27, 0x95, 0x42, - 0xa5, 0x02, 0x4b, 0xad, 0x8d, 0xcc, 0x43, 0x71, 0x93, 0x6e, 0xb1, 0xd6, 0xa6, 0xaf, 0x3c, 0x4b, - 0x30, 0xd7, 0x17, 0x0f, 0xc4, 0x2f, 0xf5, 0xa4, 0x4e, 0x62, 0x90, 0x00, 0xa6, 0xb0, 0x7f, 0xd6, - 0x9c, 0x30, 0x7c, 0xe0, 0x07, 0x6e, 0x93, 0x86, 0xf2, 0xc8, 0xab, 0xb7, 0xf3, 0xe7, 0x32, 0x3b, - 0xff, 0x02, 0xef, 0xfc, 0x8e, 0xc2, 0x41, 0x15, 0xb7, 0x1e, 0xf6, 0xe6, 0xef, 0x1b, 0x28, 0xf5, - 0xe4, 0x0a, 0x06, 0x14, 0xc6, 0x17, 0x29, 0xd0, 0x43, 0xe1, 0x74, 0x52, 0xf7, 0x6e, 0x38, 0x0a, - 0x79, 0x05, 0x86, 0x6f, 0x39, 0x0d, 0x1a, 0x49, 0xbf, 0x37, 0x22, 0x6f, 0x23, 0x44, 0x75, 0x67, - 0x70, 0x1c, 0xb6, 0x20, 0x2f, 0xd0, 0xfb, 0x5e, 0x83, 0x56, 0xa3, 0x88, 0x86, 0xbc, 0x87, 0xe7, - 0xab, 0xfc, 0x80, 0x78, 0x94, 0x2f, 0xc8, 0x2e, 0x96, 0xdb, 0x4e, 0x82, 0x60, 0x37, 0x1c, 0x95, - 0x57, 0x26, 0x07, 0xf3, 0x7f, 0x19, 0x49, 0xaf, 0x93, 0x17, 0xa1, 0x60, 0xad, 0xc5, 0xdf, 0xcf, - 0xcf, 0x7e, 0x53, 0x9f, 0x8f, 0x08, 0xe4, 0x8b, 0x70, 0x5a, 0xe1, 0x83, 0x3d, 0x42, 0x5d, 0xf6, - 0x41, 0xbc, 0x31, 0x2f, 0xe0, 0x61, 0x9f, 0xf2, 0x25, 0x0e, 0xc7, 0x48, 0x7d, 0x51, 0x36, 0x0f, - 0xb4, 0x3e, 0x92, 0x82, 0x05, 0xda, 0xf6, 0x38, 0x6f, 0xa5, 0xb1, 0x2a, 0x6f, 0x17, 0x11, 0xd2, - 0x8d, 0xcd, 0xe2, 0xf0, 0x5e, 0xa1, 0x58, 0x28, 0x0f, 0x99, 0x7f, 0x6a, 0x28, 0x39, 0x7f, 0x9e, - 0xd0, 0x15, 0xeb, 0xa6, 0xb6, 0x62, 0xcd, 0x08, 0xd2, 0xb8, 0x55, 0xac, 0x2c, 0xd3, 0xca, 0x98, - 0x84, 0x71, 0x0d, 0x09, 0xe3, 0xad, 0xef, 0x85, 0x34, 0xe0, 0x7e, 0xe6, 0x4f, 0x56, 0xbc, 0x75, - 0xdc, 0xae, 0x81, 0x22, 0x62, 0xff, 0xd8, 0x80, 0xc9, 0x14, 0x05, 0xeb, 0x0d, 0x06, 0x52, 0x7b, - 0xa3, 0x1b, 0xd2, 0xc0, 0x42, 0x28, 0x0f, 0xb4, 0x5c, 0xd6, 0x03, 0x2d, 0x9b, 0x16, 0x83, 0x91, - 0xcf, 0xc1, 0xd0, 0x3d, 0xdc, 0x15, 0xea, 0xb1, 0x3a, 0x31, 0x7f, 0x2c, 0xe4, 0x33, 0xac, 0xcb, - 0xfe, 0x55, 0x15, 0x04, 0x96, 0x91, 0x3a, 0x8c, 0xcc, 0x07, 0x14, 0xb3, 0xfb, 0x14, 0x06, 0x3f, - 0x54, 0x6d, 0x70, 0x92, 0xf4, 0xa1, 0xaa, 0xe0, 0x64, 0xfe, 0x62, 0x0e, 0x48, 0xd2, 0x46, 0xbc, - 0xed, 0x19, 0x3e, 0xb1, 0x83, 0xfe, 0x8e, 0x36, 0xe8, 0x4f, 0xf7, 0x0c, 0x3a, 0x6f, 0xde, 0x40, - 0x63, 0xff, 0x07, 0x06, 0x9c, 0xc9, 0x26, 0x24, 0xcf, 0xc1, 0xf0, 0xea, 0xfa, 0x9a, 0x0c, 0xf7, - 0x12, 0x4d, 0xf1, 0x3b, 0x68, 0x19, 0x5b, 0xa2, 0x88, 0xbc, 0x0a, 0xc3, 0xef, 0x5b, 0xf3, 0x6c, - 0xc9, 0x54, 0x2e, 0x6c, 0x7d, 0x35, 0xb0, 0x1b, 0xfa, 0x36, 0x5a, 0x20, 0xa9, 0x63, 0x9b, 0x7f, - 0x6c, 0x63, 0xfb, 0xed, 0x1c, 0x4c, 0x56, 0x1b, 0x0d, 0x1a, 0x86, 0xcc, 0x20, 0xa2, 0x61, 0xf4, - 0xc4, 0x0e, 0x6c, 0x76, 0x20, 0x97, 0xd6, 0xb6, 0x81, 0x46, 0xf5, 0x0f, 0x0d, 0x38, 0x2d, 0xa9, - 0xee, 0x7b, 0xf4, 0xc1, 0xfa, 0x6e, 0x40, 0xc3, 0x5d, 0xbf, 0xe9, 0x0e, 0x7a, 0xf5, 0x10, 0x57, - 0x69, 0xaf, 0x19, 0xd1, 0x40, 0x3d, 0x74, 0xd8, 0x46, 0x88, 0xb6, 0x4a, 0x23, 0x84, 0x5c, 0x83, - 0x91, 0x6a, 0xa7, 0x13, 0xf8, 0xf7, 0xf9, 0xb4, 0x1f, 0x17, 0x67, 0xcc, 0x1c, 0xa4, 0x9d, 0x49, - 0x73, 0x10, 0xfb, 0x8c, 0x05, 0xda, 0xe6, 0x51, 0xea, 0xe3, 0xfc, 0x33, 0x5c, 0xda, 0x56, 0x2d, - 0x34, 0x2c, 0x37, 0xbf, 0x55, 0x80, 0x92, 0xda, 0x10, 0x62, 0xc2, 0x30, 0x0f, 0x39, 0x52, 0x43, - 0x3f, 0x1c, 0x84, 0x58, 0xa2, 0x24, 0x89, 0xe4, 0xca, 0x1d, 0x1b, 0xc9, 0xb5, 0x09, 0xe3, 0x6b, - 0x81, 0xdf, 0xf1, 0x43, 0xea, 0xf2, 0x04, 0x6d, 0x5c, 0x6b, 0x4d, 0xc7, 0xe1, 0xcd, 0xbc, 0xcf, - 0x59, 0x11, 0xdf, 0x0e, 0x74, 0x04, 0xb6, 0x9d, 0x4e, 0xdf, 0xa6, 0xf3, 0xe1, 0x87, 0x36, 0x4e, - 0x28, 0xee, 0x8d, 0xc4, 0x87, 0x36, 0x0c, 0xa2, 0x1f, 0xda, 0x30, 0x88, 0x3a, 0x2d, 0x86, 0x1e, - 0xd7, 0xb4, 0x20, 0xbf, 0x68, 0xc0, 0x58, 0xb5, 0xdd, 0x16, 0x91, 0x5c, 0x32, 0x61, 0xc9, 0xe9, - 0xe4, 0xe0, 0x86, 0x87, 0xfa, 0xf2, 0x73, 0x9b, 0x2f, 0x89, 0x73, 0x9b, 0x37, 0x3e, 0xd2, 0xb9, - 0xcd, 0x7a, 0xe0, 0x78, 0x51, 0x88, 0x07, 0xf4, 0x49, 0x85, 0x6a, 0x38, 0xb7, 0xf2, 0x1d, 0xe4, - 0x0d, 0x28, 0xc7, 0xf2, 0xb8, 0xd4, 0x76, 0xe9, 0x43, 0xca, 0x03, 0xdf, 0xc6, 0xf9, 0xa5, 0x56, - 0xed, 0x40, 0x2a, 0x8d, 0x68, 0x7e, 0xdb, 0x80, 0x33, 0xaa, 0x40, 0xd4, 0xbb, 0x5b, 0x2d, 0x0f, - 0xb7, 0x3f, 0xe4, 0x2a, 0x8c, 0x8a, 0xf1, 0x8a, 0x0d, 0xb9, 0xde, 0xac, 0x7e, 0x09, 0x0a, 0x59, - 0x64, 0x43, 0xc4, 0x78, 0x08, 0x5f, 0xc1, 0x74, 0x6a, 0xba, 0xb1, 0xa2, 0xda, 0xac, 0xe8, 0xec, - 0x72, 0x80, 0xbf, 0xf5, 0xb1, 0x63, 0x10, 0xf3, 0x6d, 0x98, 0xd2, 0xbf, 0xb2, 0x4e, 0xf1, 0xd6, - 0xa3, 0x6c, 0x9a, 0x91, 0xdd, 0x34, 0x59, 0x6e, 0x6e, 0x02, 0xe9, 0xa1, 0x0f, 0xf1, 0xf0, 0x91, - 0x46, 0xf2, 0x70, 0x5c, 0xba, 0x30, 0x7b, 0x10, 0xe3, 0xfc, 0x96, 0x63, 0x6a, 0x77, 0x23, 0xa9, - 0xf9, 0xab, 0x63, 0x30, 0x9d, 0xa1, 0x3a, 0x8e, 0x59, 0xda, 0x2b, 0xfa, 0xe4, 0x19, 0x8d, 0xa3, - 0x3c, 0xe4, 0x94, 0x79, 0x5b, 0xe6, 0x32, 0x3c, 0x62, 0xaa, 0x1c, 0x95, 0xe0, 0xf0, 0xe3, 0x58, - 0xde, 0xd5, 0x40, 0xac, 0xa1, 0xc7, 0x16, 0x88, 0x55, 0x83, 0x71, 0xd1, 0x2a, 0x31, 0x95, 0x87, - 0x13, 0xb7, 0x40, 0xc0, 0x0b, 0xec, 0x9e, 0x29, 0xad, 0x93, 0x70, 0x1e, 0xa1, 0xdf, 0xbc, 0x4f, - 0x05, 0x8f, 0x11, 0x95, 0x07, 0x16, 0x64, 0xf2, 0x50, 0x48, 0xc8, 0xdf, 0x37, 0x80, 0x08, 0x88, - 0x3a, 0x9f, 0x8b, 0x47, 0xcd, 0x67, 0xf7, 0xf1, 0xcc, 0xe7, 0xa7, 0xe5, 0x37, 0x66, 0xcf, 0xeb, - 0x8c, 0xcf, 0x22, 0x7f, 0xd7, 0x80, 0x29, 0x1e, 0x0d, 0xa4, 0x7e, 0xec, 0xe8, 0x51, 0x1f, 0xdb, - 0x78, 0x3c, 0x1f, 0x7b, 0x21, 0xc4, 0x6a, 0xfb, 0x7c, 0x6b, 0xef, 0x47, 0x91, 0x1f, 0x07, 0x88, - 0x67, 0x94, 0x8c, 0x3a, 0xbd, 0x90, 0xa1, 0x05, 0x62, 0xa4, 0xe4, 0x5e, 0x6f, 0x14, 0xd3, 0x69, - 0x09, 0x0b, 0x62, 0x28, 0xf9, 0x29, 0x98, 0x61, 0xf3, 0x25, 0x86, 0x88, 0xd8, 0xc5, 0xd9, 0x31, - 0xac, 0xe5, 0xd3, 0xfd, 0x97, 0xf6, 0xab, 0x59, 0x64, 0xfc, 0xee, 0x4f, 0x92, 0xf0, 0x25, 0x6a, - 0xa9, 0x5b, 0xbe, 0x2c, 0x0a, 0x0c, 0x52, 0xc6, 0xaf, 0xe7, 0xd7, 0x5b, 0xfb, 0xe8, 0xb7, 0x73, - 0x72, 0x2e, 0x70, 0xfd, 0x16, 0xea, 0x97, 0x77, 0x10, 0x44, 0xde, 0x07, 0x52, 0xef, 0xee, 0xec, - 0xd0, 0x30, 0xa2, 0x2e, 0x87, 0xd1, 0x40, 0x26, 0x33, 0x43, 0x37, 0x55, 0x28, 0x4b, 0xed, 0x40, - 0x16, 0xab, 0x42, 0xd2, 0x4b, 0x4c, 0x28, 0xcc, 0x88, 0x46, 0x33, 0xa8, 0x4c, 0x09, 0x12, 0xce, - 0x4e, 0x68, 0x91, 0xa1, 0x49, 0x49, 0x92, 0x19, 0x46, 0xc9, 0x2b, 0xa2, 0x6d, 0x7b, 0xb3, 0xd8, - 0x91, 0x9b, 0x30, 0xba, 0xec, 0xef, 0x78, 0xed, 0xdb, 0x5e, 0x3b, 0x9a, 0x9d, 0x4c, 0x8e, 0xa9, - 0x9a, 0x0c, 0x68, 0xef, 0x7a, 0x9a, 0xdf, 0x3e, 0x41, 0x3d, 0xbf, 0x05, 0xe7, 0xfa, 0x8e, 0x42, - 0xc6, 0xbd, 0xa1, 0x6b, 0xfa, 0xbd, 0xa1, 0x73, 0xfd, 0xb4, 0x75, 0xa8, 0xde, 0x1d, 0xfa, 0x35, - 0x23, 0xa5, 0x9e, 0x85, 0x2d, 0xc5, 0xb3, 0xd2, 0xf6, 0x5b, 0xbf, 0x72, 0x98, 0x38, 0x85, 0x2b, - 0xf0, 0x5c, 0x62, 0xc3, 0x31, 0x05, 0xae, 0x2e, 0x00, 0xa8, 0xca, 0x1f, 0x51, 0x53, 0x9b, 0xff, - 0xd0, 0x00, 0xc2, 0xbf, 0x70, 0xde, 0xe9, 0x38, 0x5b, 0x5e, 0xd3, 0x8b, 0x3c, 0x1a, 0x92, 0x3b, - 0x50, 0x16, 0x2c, 0x9c, 0xad, 0x26, 0x55, 0x43, 0x02, 0x45, 0xcc, 0x40, 0x5c, 0x66, 0xa7, 0xad, - 0xae, 0x1e, 0xc2, 0x3e, 0xb2, 0x95, 0x7b, 0x04, 0xd9, 0x32, 0x7f, 0x68, 0xc0, 0xb9, 0xde, 0xcf, - 0x16, 0x35, 0xc7, 0x9d, 0x67, 0x1c, 0xd3, 0x79, 0x59, 0xad, 0xcc, 0xa1, 0x67, 0xf6, 0xb1, 0xb5, - 0x32, 0x9f, 0x38, 0x7a, 0x4f, 0xde, 0xca, 0x07, 0x6a, 0xe2, 0x1d, 0xf2, 0x6a, 0x56, 0x70, 0x17, - 0xbf, 0x81, 0xc5, 0xc1, 0x7a, 0x5c, 0x97, 0xdc, 0x1d, 0xe5, 0x32, 0x77, 0x47, 0xf2, 0x32, 0x59, - 0x3e, 0xeb, 0x32, 0x99, 0xf9, 0xcd, 0x1c, 0x94, 0xd6, 0x9a, 0xdd, 0x1d, 0xaf, 0xbd, 0xe0, 0x44, - 0xce, 0x13, 0xbb, 0xd5, 0x7a, 0x5d, 0xdb, 0x6a, 0xc5, 0xd1, 0x87, 0x71, 0xc3, 0x06, 0xda, 0x67, - 0x7d, 0xd7, 0x80, 0xc9, 0x84, 0x84, 0xab, 0x87, 0xdb, 0x50, 0x60, 0x3f, 0x84, 0xe5, 0x76, 0xb1, - 0x87, 0x31, 0x62, 0x5d, 0x8d, 0xff, 0x13, 0x9b, 0x1f, 0x3d, 0x21, 0x2c, 0x72, 0x38, 0xff, 0x19, - 0x9e, 0x9a, 0xf1, 0xe4, 0xb9, 0xa7, 0x7f, 0xcf, 0x80, 0x72, 0xba, 0x25, 0xe4, 0x0e, 0x8c, 0x30, - 0x4e, 0x5e, 0x9c, 0xe6, 0xf1, 0xf9, 0x3e, 0x6d, 0xbe, 0x2a, 0xd0, 0xf8, 0xe7, 0x61, 0xe7, 0x53, - 0x0e, 0xb1, 0x24, 0x87, 0xf3, 0x16, 0x94, 0x54, 0xac, 0x8c, 0xaf, 0x7b, 0x45, 0xd7, 0x89, 0x67, - 0xb2, 0xfb, 0x41, 0xfd, 0xea, 0x5f, 0xd5, 0xbe, 0x5a, 0x68, 0xc3, 0x41, 0x93, 0xfc, 0xe2, 0xf5, - 0x4b, 0x3e, 0x1d, 0x54, 0x39, 0x93, 0xab, 0x85, 0x7e, 0xfd, 0x92, 0xc3, 0xd8, 0x1e, 0x8d, 0xd7, - 0x27, 0xe4, 0x0c, 0xf7, 0x68, 0x1d, 0x84, 0xa8, 0x76, 0x3e, 0xc7, 0x31, 0xff, 0x66, 0x1e, 0xce, - 0x24, 0x9f, 0xc7, 0x53, 0x1e, 0xaf, 0x39, 0x81, 0xd3, 0x0a, 0x8f, 0x99, 0x01, 0x97, 0x7b, 0x3e, - 0x0d, 0x73, 0x12, 0xc8, 0x4f, 0x53, 0x3e, 0xc8, 0x4c, 0x7d, 0x10, 0x6e, 0x6e, 0xf9, 0x07, 0xc9, - 0xcf, 0x20, 0x77, 0x20, 0x5f, 0xa7, 0x91, 0xb8, 0x84, 0x7c, 0xa9, 0xa7, 0x57, 0xd5, 0xef, 0xba, - 0x5a, 0xa7, 0x11, 0x1f, 0x44, 0x7e, 0x8f, 0x83, 0x6a, 0xf7, 0x2a, 0xd8, 0x36, 0x65, 0x13, 0x86, - 0x17, 0x1f, 0x76, 0x68, 0x23, 0x12, 0x77, 0x8f, 0x5f, 0x3a, 0x9a, 0x1f, 0xc7, 0x55, 0x6e, 0x38, - 0x53, 0x04, 0xa8, 0x9d, 0xc5, 0x51, 0xce, 0xdf, 0x84, 0xa2, 0xac, 0xfc, 0x44, 0x37, 0x75, 0x5f, - 0x87, 0x31, 0xa5, 0x92, 0x13, 0x09, 0xfd, 0x5f, 0x18, 0x30, 0xcc, 0xb4, 0xed, 0xc6, 0x6b, 0x4f, - 0xa8, 0x46, 0xba, 0xa1, 0x69, 0xa4, 0x29, 0xe5, 0x4a, 0x19, 0xce, 0xcb, 0xd7, 0x8e, 0xd1, 0x45, - 0x07, 0x06, 0x40, 0x82, 0x4c, 0xde, 0x85, 0x11, 0x91, 0xda, 0x48, 0x04, 0x73, 0xa8, 0x77, 0xd4, - 0x64, 0xea, 0xc4, 0xd8, 0xfa, 0xf3, 0x3b, 0x69, 0x73, 0x59, 0x52, 0x93, 0x85, 0x24, 0x8e, 0x5f, - 0xbd, 0x14, 0xcd, 0xd8, 0xcc, 0xfb, 0x6d, 0x7e, 0x67, 0x49, 0x49, 0xc2, 0xd8, 0x27, 0xa0, 0xbf, - 0x2a, 0x1c, 0x3e, 0xf9, 0xa3, 0x98, 0x9c, 0x11, 0x4c, 0xb2, 0x7d, 0x41, 0xbf, 0x30, 0xc1, 0x6f, - 0x01, 0xc9, 0x0f, 0x7b, 0x0b, 0x4a, 0xb7, 0xfc, 0xe0, 0x81, 0x13, 0xb8, 0x18, 0x70, 0x81, 0xcd, - 0xe4, 0xf9, 0xc4, 0xc6, 0xb7, 0x39, 0xdc, 0xc6, 0x58, 0x8d, 0x1f, 0x1d, 0x54, 0x0a, 0x35, 0xdf, - 0x6f, 0x5a, 0x1a, 0x3a, 0x59, 0x85, 0xf1, 0xbb, 0xce, 0x43, 0x71, 0x76, 0xba, 0xbe, 0xbe, 0x2c, - 0xe2, 0xb8, 0x5e, 0x3a, 0x3c, 0xa8, 0x9c, 0x6b, 0x39, 0x0f, 0xe3, 0x33, 0xd7, 0xfe, 0x57, 0x0d, - 0x74, 0x7a, 0xe2, 0xc1, 0xc4, 0x9a, 0x1f, 0x44, 0xa2, 0x12, 0x66, 0xeb, 0xe7, 0xfb, 0x9c, 0xbe, - 0x5d, 0xcb, 0x3c, 0x7d, 0x3b, 0xc7, 0x36, 0x38, 0xf6, 0x76, 0x4c, 0xae, 0x5d, 0x5d, 0xd5, 0x18, - 0x93, 0xb7, 0x60, 0x6a, 0x9e, 0x06, 0x91, 0xb7, 0xed, 0x35, 0x9c, 0x88, 0xde, 0xf2, 0x83, 0x96, - 0x13, 0x09, 0x47, 0x13, 0x3a, 0x1a, 0x1a, 0x94, 0x73, 0x6a, 0x39, 0x91, 0xd5, 0x8b, 0x49, 0xbe, - 0x98, 0x15, 0x19, 0x37, 0x84, 0xcd, 0x7f, 0x95, 0x59, 0x23, 0x19, 0x91, 0x71, 0x7d, 0xba, 0x20, - 0x23, 0x46, 0x6e, 0xe7, 0xa8, 0x23, 0xe8, 0x62, 0xed, 0xba, 0x38, 0x0e, 0x3f, 0xfe, 0x88, 0x39, - 0x1e, 0xb7, 0x3e, 0x47, 0xcd, 0x73, 0x90, 0xaf, 0xad, 0xdd, 0x42, 0xd7, 0x91, 0x38, 0xf2, 0xa5, - 0xed, 0x5d, 0xa7, 0xdd, 0x40, 0x23, 0x4a, 0xc4, 0x91, 0xa8, 0x0a, 0xaf, 0xb6, 0x76, 0x8b, 0x38, - 0x30, 0xbd, 0x46, 0x83, 0x96, 0x17, 0x7d, 0xfe, 0xfa, 0x75, 0x65, 0xa0, 0x8a, 0xf8, 0x69, 0xd7, - 0xc4, 0xa7, 0x55, 0x3a, 0x88, 0x62, 0x3f, 0xbc, 0x7e, 0x3d, 0x73, 0x38, 0xe2, 0x0f, 0xcb, 0xe2, - 0x45, 0x16, 0x61, 0xe2, 0xae, 0xf3, 0x30, 0x09, 0xff, 0x09, 0x45, 0x6c, 0xee, 0xd3, 0x52, 0xb0, - 0x92, 0xd0, 0x21, 0x75, 0xbe, 0xa5, 0x88, 0xc8, 0x9b, 0x30, 0x96, 0x88, 0x57, 0x88, 0xc7, 0xc2, - 0x79, 0x1e, 0x72, 0xac, 0x08, 0xa7, 0xe6, 0x63, 0x53, 0xd0, 0xc9, 0xbd, 0xd8, 0x75, 0xc1, 0x2d, - 0x61, 0x91, 0x16, 0xe9, 0x9a, 0xea, 0xba, 0x70, 0xb0, 0x44, 0x6b, 0xd6, 0x64, 0xbc, 0x37, 0xe0, - 0xf1, 0x50, 0x96, 0xce, 0x45, 0xf1, 0x88, 0xac, 0x05, 0x7e, 0xab, 0x13, 0x61, 0x44, 0x6e, 0xca, - 0x23, 0xd2, 0xc1, 0x92, 0x0c, 0x8f, 0x08, 0x27, 0xc9, 0x8e, 0x79, 0x18, 0x7f, 0x84, 0x98, 0x07, - 0x0a, 0x85, 0x65, 0xbf, 0xb1, 0x87, 0x21, 0xb8, 0xa3, 0xb5, 0xf7, 0x99, 0xfe, 0x68, 0xfa, 0x8d, - 0xbd, 0xc7, 0x77, 0x56, 0x8f, 0xec, 0xc9, 0x0a, 0x6b, 0x3b, 0x13, 0x2b, 0x51, 0x35, 0xee, 0x27, - 0x93, 0x13, 0x48, 0xad, 0x8c, 0x1b, 0x2a, 0x5c, 0x0a, 0x65, 0x43, 0x2c, 0x9d, 0x9c, 0x50, 0x28, - 0x2f, 0xd0, 0x70, 0x2f, 0xf2, 0x3b, 0xf3, 0x4d, 0xaf, 0xb3, 0xe5, 0x3b, 0x81, 0x3b, 0x5b, 0xee, - 0xa3, 0x30, 0x5e, 0xcc, 0x54, 0x18, 0x53, 0x2e, 0xa7, 0xb7, 0x1b, 0x92, 0x81, 0xd5, 0xc3, 0x92, - 0x7c, 0x11, 0x26, 0xd8, 0x6c, 0x59, 0x7c, 0x18, 0xd1, 0x36, 0x17, 0xa5, 0x29, 0x5c, 0xea, 0x67, - 0x94, 0x4b, 0xbc, 0x71, 0x21, 0x17, 0x52, 0xd4, 0x1e, 0x34, 0x26, 0x50, 0x85, 0x54, 0x67, 0x45, - 0x5c, 0x98, 0xbd, 0xeb, 0x3c, 0x54, 0x32, 0x72, 0x29, 0x52, 0x4f, 0x50, 0x62, 0x31, 0xe9, 0x25, - 0x93, 0xd8, 0xbd, 0x18, 0xa9, 0xcf, 0x04, 0xe8, 0xcb, 0x89, 0x7c, 0x0d, 0xce, 0x8a, 0x66, 0x2d, - 0x60, 0xde, 0x0c, 0x3f, 0xd8, 0xaf, 0xef, 0x3a, 0x18, 0x4a, 0x38, 0x7d, 0x32, 0x0d, 0x2b, 0x3b, - 0xcc, 0x95, 0x7c, 0xec, 0x90, 0x33, 0xb2, 0xfa, 0xd5, 0x40, 0xbe, 0x02, 0x13, 0xdc, 0xc9, 0x78, - 0xdb, 0x0f, 0x23, 0xdc, 0x39, 0xce, 0xf4, 0xa9, 0xf3, 0x52, 0x66, 0x9d, 0x65, 0xee, 0xb9, 0xe4, - 0x31, 0x65, 0xe8, 0x67, 0x4d, 0xf1, 0x23, 0x6f, 0xc0, 0xd8, 0x9a, 0xd7, 0xae, 0xf3, 0xad, 0xdc, - 0xda, 0xec, 0xe9, 0x64, 0x19, 0xeb, 0x78, 0x6d, 0x5b, 0x7a, 0x3b, 0x3a, 0xb1, 0xd6, 0x51, 0xb1, - 0xcd, 0x7f, 0x99, 0x4b, 0x89, 0x25, 0x59, 0x82, 0x11, 0xd1, 0x16, 0xb1, 0xf0, 0xf7, 0x7e, 0xe9, - 0xd3, 0x99, 0x5f, 0x3a, 0x22, 0x7a, 0xc7, 0x92, 0xf4, 0xe4, 0x01, 0x63, 0xb5, 0xed, 0x74, 0x9b, - 0x32, 0x1d, 0xe3, 0x07, 0x5c, 0xea, 0x10, 0xa4, 0xcd, 0xaf, 0x85, 0x93, 0x47, 0x64, 0xe9, 0x01, - 0x7f, 0x38, 0xd1, 0x64, 0x6d, 0x64, 0x8f, 0xdf, 0x4b, 0xce, 0xc7, 0x51, 0x38, 0xfa, 0x25, 0xe4, - 0xc7, 0x56, 0x21, 0xab, 0xc5, 0xfc, 0xe7, 0x06, 0x8c, 0x6b, 0x72, 0x4d, 0x6e, 0x2a, 0x31, 0x6b, - 0x49, 0xfc, 0xb0, 0x86, 0x93, 0xf9, 0x20, 0xd4, 0x4d, 0x11, 0xa8, 0x98, 0xeb, 0x4f, 0x97, 0x99, - 0xf5, 0xf2, 0xc8, 0x0d, 0x77, 0x92, 0xbd, 0xa5, 0xd0, 0x27, 0x7b, 0xcb, 0x37, 0x27, 0x60, 0x42, - 0xb7, 0xa4, 0xd8, 0xd6, 0x06, 0xbd, 0x59, 0xd2, 0x33, 0xc3, 0xf3, 0x11, 0x21, 0x44, 0x7b, 0x5d, - 0x09, 0x21, 0xe4, 0x05, 0x80, 0x38, 0x36, 0x42, 0x3a, 0x5f, 0xc4, 0x5b, 0x50, 0x4a, 0x01, 0xf9, - 0x32, 0xc0, 0x8a, 0xef, 0xd2, 0x38, 0xa5, 0xd5, 0x11, 0x1e, 0xdd, 0x17, 0x85, 0x47, 0x57, 0xbc, - 0xdf, 0x74, 0x78, 0x50, 0x39, 0xdd, 0xf6, 0x5d, 0xda, 0x9b, 0xcb, 0x4a, 0xe1, 0x48, 0x3e, 0x0b, - 0x43, 0x56, 0xb7, 0x49, 0x65, 0x86, 0xa5, 0x31, 0xa9, 0x59, 0xbb, 0x4d, 0x25, 0x45, 0x7b, 0xd0, - 0x4d, 0x1f, 0xe4, 0x31, 0x00, 0x79, 0x07, 0x80, 0x29, 0x0f, 0x4c, 0xc7, 0x2b, 0x53, 0x38, 0xa0, - 0xa3, 0x46, 0xd1, 0x3b, 0x98, 0xc4, 0x57, 0xab, 0x3c, 0x21, 0x21, 0xab, 0x30, 0x22, 0xd6, 0x29, - 0x71, 0x50, 0xf6, 0x4c, 0x96, 0x8b, 0x56, 0x31, 0x56, 0x45, 0xca, 0x23, 0x04, 0xeb, 0x5e, 0x53, - 0xee, 0x68, 0x7a, 0x13, 0x46, 0x19, 0x7b, 0x9e, 0x73, 0x9c, 0x1b, 0x29, 0x18, 0x08, 0xae, 0x7c, - 0x50, 0x3a, 0xed, 0x78, 0x42, 0x40, 0xbe, 0x88, 0x49, 0xca, 0x44, 0x57, 0x1f, 0xe9, 0xe9, 0xbf, - 0xd4, 0xd3, 0xd5, 0x33, 0x4e, 0xa7, 0x93, 0x91, 0x74, 0x32, 0xe6, 0x47, 0x76, 0xe2, 0xcb, 0x92, - 0xf1, 0xe3, 0x1e, 0x47, 0x54, 0x70, 0xa5, 0xa7, 0x82, 0x59, 0x79, 0xff, 0xaf, 0x37, 0x35, 0x99, - 0xc6, 0x97, 0x74, 0xa0, 0x9c, 0xa8, 0x74, 0x51, 0x17, 0x1c, 0x55, 0xd7, 0xab, 0x3d, 0x75, 0xa9, - 0x03, 0xd8, 0x53, 0x5d, 0x0f, 0x77, 0xe2, 0x26, 0x6f, 0x2a, 0x88, 0xfa, 0xc6, 0x8e, 0xaa, 0xef, - 0x85, 0x9e, 0xfa, 0xa6, 0xdd, 0xad, 0xde, 0x7a, 0x52, 0x3c, 0xc9, 0x9b, 0x30, 0x2e, 0x21, 0x38, - 0x3f, 0x44, 0x02, 0x49, 0xfe, 0x1a, 0xc8, 0x16, 0x46, 0x8a, 0xea, 0x79, 0xb9, 0x54, 0x64, 0x95, - 0x9a, 0x4b, 0xc7, 0xb8, 0x46, 0x9d, 0x96, 0x0a, 0x1d, 0x99, 0x7c, 0x01, 0xc6, 0x96, 0x5a, 0xac, - 0x21, 0x7e, 0xdb, 0x89, 0x28, 0x5a, 0x3d, 0xc9, 0xa9, 0x85, 0x52, 0xa2, 0x88, 0x2a, 0xcf, 0x4f, - 0x9c, 0x14, 0xa9, 0x56, 0xa3, 0x42, 0xc1, 0x3a, 0x8f, 0x3b, 0x18, 0x85, 0x0c, 0x87, 0xc2, 0xc6, - 0x79, 0x3a, 0xe3, 0xe4, 0x40, 0x61, 0x8f, 0x46, 0x03, 0xf7, 0x5b, 0xda, 0x62, 0x42, 0x68, 0x9d, - 0xa7, 0xf3, 0x24, 0x6f, 0xc1, 0x98, 0xb8, 0x9a, 0x5e, 0xb5, 0x56, 0xc2, 0xd9, 0x72, 0x92, 0x8e, - 0x5f, 0xde, 0x62, 0xb7, 0x9d, 0x20, 0x75, 0x7c, 0x9c, 0xe0, 0x93, 0xcf, 0xc3, 0xcc, 0xa6, 0xd7, - 0x76, 0xfd, 0x07, 0xa1, 0x58, 0xa6, 0x84, 0xa2, 0x9b, 0x4a, 0x82, 0xe4, 0x1e, 0xf0, 0x72, 0x5b, - 0x2e, 0xf7, 0x3d, 0x8a, 0x2f, 0x93, 0x03, 0xf9, 0xc9, 0x1e, 0xce, 0x5c, 0x82, 0xc8, 0x51, 0x12, - 0x34, 0xd7, 0x23, 0x41, 0xbd, 0xd5, 0xa7, 0xc5, 0x29, 0xb3, 0x1a, 0xe2, 0x03, 0xd1, 0x8d, 0xdb, - 0xf7, 0x7c, 0xaf, 0x3d, 0x3b, 0xad, 0x3d, 0x9d, 0x17, 0xaf, 0x62, 0x88, 0xb7, 0xe6, 0x37, 0xbd, - 0xc6, 0xbe, 0x4c, 0x7a, 0xae, 0x9b, 0xcd, 0x1f, 0xfa, 0x9a, 0x17, 0x2b, 0x83, 0x35, 0xf9, 0x02, - 0x94, 0xd8, 0xdf, 0x78, 0x8f, 0x31, 0xa3, 0x9d, 0x35, 0x2b, 0x98, 0xa2, 0x1e, 0x1c, 0x23, 0xbc, - 0x3b, 0x9f, 0xb1, 0xfd, 0xd0, 0x58, 0x91, 0xd7, 0x01, 0x98, 0x7d, 0x23, 0xd4, 0xf1, 0xe9, 0x24, - 0xc1, 0x01, 0x9a, 0x41, 0xbd, 0x8a, 0x38, 0x41, 0x66, 0x1b, 0x1f, 0xf6, 0xab, 0xde, 0x75, 0x7d, - 0x36, 0x37, 0xce, 0x20, 0x2d, 0x6e, 0x7c, 0x90, 0x36, 0xe4, 0x70, 0x55, 0x3a, 0x14, 0x74, 0xf3, - 0x87, 0x06, 0xcc, 0x64, 0x75, 0xd2, 0x31, 0x19, 0xd2, 0xcc, 0x54, 0xb8, 0x0b, 0x7a, 0xde, 0x78, - 0xb8, 0x4b, 0x1c, 0xe4, 0x52, 0x81, 0xa1, 0x3b, 0x5e, 0xdb, 0x95, 0xe1, 0x98, 0xb8, 0x0e, 0xef, - 0x31, 0x80, 0xc5, 0xe1, 0x0c, 0x81, 0xdf, 0x16, 0x61, 0x0b, 0xf5, 0x10, 0x47, 0xc0, 0xcb, 0x21, - 0x16, 0x87, 0x33, 0x04, 0xb6, 0xde, 0xcb, 0xf5, 0x09, 0x11, 0x98, 0x19, 0x10, 0x5a, 0x1c, 0x4e, - 0x2e, 0xc1, 0xc8, 0x6a, 0x7b, 0x99, 0x3a, 0xf7, 0xa9, 0x38, 0x6b, 0x46, 0x4f, 0xa1, 0xdf, 0xb6, - 0x9b, 0x0c, 0x66, 0xc9, 0x42, 0xf3, 0xbb, 0x06, 0x4c, 0xf5, 0x8c, 0xcf, 0xf1, 0x49, 0xe0, 0x8e, - 0x3e, 0xd8, 0x1f, 0xa4, 0x7d, 0xfc, 0xf3, 0x0b, 0xd9, 0x9f, 0x6f, 0xfe, 0x4e, 0x01, 0xce, 0xf6, - 0x59, 0x2e, 0x93, 0xa0, 0x1c, 0xe3, 0xd8, 0xa0, 0x9c, 0x2f, 0xb1, 0xe5, 0xc9, 0xf1, 0x5a, 0xe1, - 0xba, 0x9f, 0x7c, 0x71, 0x72, 0x7e, 0x89, 0x65, 0x32, 0xcb, 0x92, 0xcc, 0x08, 0x74, 0xae, 0x81, - 0x14, 0x76, 0xe4, 0xf7, 0x1c, 0xc7, 0xe8, 0xcc, 0x7a, 0xc2, 0x62, 0xf2, 0x7f, 0x49, 0xc2, 0x62, - 0xf4, 0xc3, 0xe8, 0xc2, 0x63, 0x3d, 0x8c, 0xce, 0x3e, 0x7f, 0x1a, 0x7a, 0x94, 0x13, 0xdc, 0x79, - 0x18, 0xaf, 0x53, 0x27, 0x68, 0xec, 0x56, 0x43, 0x3e, 0x48, 0x3c, 0x5b, 0x2d, 0xae, 0x05, 0x21, - 0x16, 0xd8, 0x4e, 0xd8, 0x3b, 0x16, 0x1a, 0x8d, 0xf9, 0x6f, 0x53, 0xd1, 0x3c, 0x7f, 0x19, 0xe5, - 0xe5, 0x25, 0x18, 0xda, 0xdc, 0xa5, 0x81, 0xb4, 0xce, 0xf1, 0x43, 0x1e, 0x30, 0x80, 0xfa, 0x21, - 0x88, 0x61, 0x7e, 0x0d, 0x4a, 0x6a, 0x65, 0xa8, 0x10, 0xd8, 0x6f, 0x31, 0x23, 0xb9, 0x42, 0x60, - 0x00, 0x8b, 0xc3, 0x8f, 0x4d, 0xcc, 0x98, 0xf4, 0x42, 0xfe, 0xb8, 0x5e, 0x60, 0x95, 0xa3, 0xbc, - 0x29, 0x95, 0xe3, 0x6f, 0xb5, 0xf2, 0x88, 0x01, 0x2c, 0x0e, 0x7f, 0xac, 0x95, 0xff, 0x2b, 0x03, - 0x0a, 0x98, 0x14, 0xe7, 0x35, 0x18, 0x95, 0xc7, 0x19, 0x6a, 0xa2, 0x98, 0x69, 0x79, 0xda, 0x11, - 0xea, 0xb1, 0x58, 0x02, 0xc8, 0xaa, 0xda, 0xa0, 0xc1, 0x96, 0x16, 0xb2, 0x77, 0x9f, 0x01, 0xd4, - 0xaa, 0x10, 0xe3, 0x04, 0xe3, 0x81, 0x61, 0x89, 0xc2, 0x1b, 0xc1, 0x55, 0x16, 0x0f, 0x4b, 0xec, - 0x71, 0x3d, 0x48, 0x2c, 0xf3, 0x97, 0x0d, 0x38, 0x9d, 0x69, 0x42, 0xb1, 0x5a, 0xb9, 0xad, 0xa6, - 0x88, 0x63, 0xda, 0x50, 0xe3, 0x18, 0x27, 0x09, 0x3f, 0x3c, 0x81, 0x6c, 0x3d, 0x0b, 0xa3, 0xf1, - 0x06, 0x9e, 0xcc, 0xc8, 0xa1, 0x43, 0x9f, 0xb7, 0xdc, 0x07, 0xfe, 0x85, 0x01, 0xc3, 0xec, 0x13, - 0x9e, 0xd8, 0xdb, 0x68, 0xd9, 0x27, 0x20, 0xac, 0x49, 0x03, 0xdd, 0x41, 0xfb, 0x8d, 0x61, 0x80, - 0x04, 0x99, 0x6c, 0xc1, 0xc4, 0xea, 0xd2, 0xc2, 0xfc, 0x92, 0x4b, 0xdb, 0x11, 0x86, 0x00, 0xa4, - 0x32, 0xcd, 0xb0, 0x3d, 0x79, 0xd0, 0x76, 0x9a, 0x02, 0x61, 0x3f, 0xd1, 0x0d, 0xbe, 0xe7, 0x36, - 0x6c, 0x2f, 0xa6, 0x53, 0x6d, 0x59, 0x9d, 0x23, 0xab, 0xa3, 0x5e, 0xbd, 0xbb, 0xac, 0xd4, 0x91, - 0x1b, 0xb0, 0x8e, 0xd0, 0x69, 0x35, 0xfb, 0xd4, 0xa1, 0x73, 0x24, 0xbb, 0x50, 0x7e, 0x17, 0x57, - 0x1f, 0xa5, 0x96, 0xfc, 0xd1, 0xb5, 0x3c, 0x27, 0x6a, 0x79, 0x8a, 0x2f, 0x5b, 0xd9, 0xf5, 0xf4, - 0x70, 0x4d, 0x24, 0xb7, 0x70, 0xac, 0xe4, 0xfe, 0x35, 0x03, 0x86, 0xf9, 0xf2, 0x16, 0xbf, 0xa1, - 0x97, 0xb9, 0x80, 0x6e, 0x3e, 0x9e, 0x05, 0xb4, 0x8c, 0x9a, 0x4b, 0xf3, 0x5d, 0xf0, 0x32, 0xb2, - 0x90, 0x7a, 0x90, 0x4f, 0x1e, 0x73, 0xa1, 0x4d, 0xcf, 0x4b, 0x92, 0x20, 0x4e, 0xfe, 0x16, 0x9f, - 0xca, 0x85, 0x63, 0xa8, 0x6f, 0x8a, 0x8f, 0x3c, 0xe2, 0x9b, 0xe2, 0xcb, 0x30, 0x2a, 0xa2, 0x12, - 0x6b, 0xfb, 0x62, 0xe7, 0x2e, 0x3d, 0x70, 0x31, 0x5c, 0x79, 0x1f, 0x82, 0x83, 0xec, 0x2d, 0x2d, - 0x7d, 0x6a, 0x8c, 0x48, 0x56, 0x61, 0x34, 0xb9, 0x4a, 0xa7, 0xdf, 0x02, 0x8f, 0xe1, 0x22, 0x6c, - 0x5f, 0x86, 0x36, 0x65, 0xdc, 0x9c, 0x4b, 0x78, 0x98, 0xdf, 0x32, 0xa0, 0x9c, 0x96, 0x17, 0x7c, - 0x08, 0x48, 0xde, 0x66, 0x8c, 0x83, 0x8f, 0xf8, 0x43, 0x40, 0xf1, 0xf5, 0x47, 0x2d, 0x0c, 0x49, - 0x45, 0x27, 0x73, 0x50, 0x64, 0xd3, 0xae, 0x9d, 0x7a, 0x09, 0xa8, 0x2b, 0x60, 0xea, 0xd9, 0xbb, - 0xc4, 0x53, 0x66, 0xed, 0xbf, 0xcf, 0xc3, 0x98, 0x32, 0x58, 0xe4, 0x25, 0x28, 0x2e, 0x85, 0xcb, - 0x7e, 0x63, 0x8f, 0xba, 0xe2, 0x48, 0x0f, 0x9f, 0x8c, 0xf7, 0x42, 0xbb, 0x89, 0x40, 0x2b, 0x2e, - 0x26, 0x35, 0x18, 0xe7, 0xff, 0xc9, 0x4c, 0x04, 0xb9, 0xe4, 0x38, 0x82, 0x23, 0xcb, 0x1c, 0x04, - 0xea, 0xf2, 0xae, 0x91, 0x90, 0x0f, 0x00, 0x38, 0x80, 0x8d, 0xef, 0x00, 0x97, 0x12, 0xe4, 0x04, - 0x3e, 0x2d, 0x2a, 0x88, 0x3c, 0xb5, 0x85, 0x28, 0x0a, 0x0a, 0x43, 0x7c, 0xae, 0xda, 0x6f, 0xec, - 0x0d, 0xfe, 0x60, 0x7d, 0xf2, 0x5c, 0xb5, 0xdf, 0xd8, 0xb3, 0xb3, 0x23, 0x54, 0x55, 0x96, 0xe4, - 0xdb, 0x06, 0x9c, 0xb7, 0x68, 0xc3, 0xbf, 0x4f, 0x83, 0xfd, 0x6a, 0x84, 0x58, 0x6a, 0x8d, 0xc7, - 0x87, 0xc3, 0xde, 0x10, 0x35, 0xbe, 0x18, 0x08, 0x2e, 0x78, 0x95, 0xae, 0xd5, 0x89, 0xec, 0x23, - 0x3e, 0xe1, 0x88, 0x2a, 0xcd, 0xff, 0x68, 0x28, 0x53, 0x80, 0xac, 0xc0, 0x68, 0x2c, 0x2c, 0xc2, - 0x23, 0x1d, 0x5b, 0x66, 0x12, 0x6e, 0xd1, 0xed, 0xda, 0x53, 0xe2, 0xf4, 0x6d, 0x3a, 0x16, 0x39, - 0x6d, 0x46, 0x48, 0x20, 0xf9, 0x1c, 0x14, 0x70, 0xa8, 0x8e, 0x4f, 0xb8, 0x28, 0x97, 0x9a, 0x02, - 0x1b, 0x23, 0xfc, 0x6a, 0xa4, 0x24, 0x9f, 0x12, 0x21, 0x60, 0x79, 0x2d, 0x95, 0x39, 0x03, 0xb1, - 0xef, 0x88, 0xd7, 0x98, 0x24, 0x28, 0x5a, 0x91, 0xd6, 0xbf, 0x9e, 0x83, 0x72, 0x7a, 0xe2, 0x91, - 0x77, 0xa0, 0x24, 0xaf, 0x45, 0xde, 0x76, 0x44, 0xf6, 0x84, 0x92, 0xc8, 0x5e, 0x20, 0xe0, 0xf6, - 0xae, 0xa3, 0xa5, 0xd1, 0xd4, 0x08, 0xd8, 0x82, 0xbc, 0x2e, 0xee, 0xda, 0x28, 0x13, 0x28, 0xf2, - 0xa3, 0x4e, 0x2a, 0x3d, 0xb2, 0x44, 0x23, 0xaf, 0x41, 0x9e, 0xdf, 0x15, 0x56, 0x73, 0xeb, 0xdd, - 0xbd, 0x55, 0xe5, 0x57, 0x1d, 0x79, 0xc0, 0x87, 0x7e, 0x72, 0xc6, 0xf0, 0xc9, 0xb2, 0x72, 0xd3, - 0x74, 0x58, 0xcb, 0x31, 0x26, 0xc1, 0x71, 0xe3, 0x8e, 0xbf, 0x72, 0xfa, 0x5e, 0xa1, 0x98, 0x2f, - 0x17, 0xc4, 0xdd, 0xc2, 0xdf, 0xca, 0xc3, 0x68, 0x5c, 0x3f, 0x21, 0x80, 0xf6, 0x86, 0x88, 0xdc, - 0xc0, 0xff, 0xc9, 0x39, 0x28, 0x4a, 0x13, 0x43, 0x44, 0x6f, 0x8c, 0x84, 0xc2, 0xbc, 0x98, 0x05, - 0x69, 0x4b, 0x70, 0xf3, 0xc2, 0x92, 0x3f, 0xc9, 0x75, 0x88, 0x0d, 0x85, 0x7e, 0x16, 0x45, 0x81, - 0x0d, 0x98, 0x15, 0xa3, 0x91, 0x09, 0xc8, 0x79, 0xfc, 0x1e, 0xc5, 0xa8, 0x95, 0xf3, 0x5c, 0xf2, - 0x0e, 0x14, 0x1d, 0xd7, 0xa5, 0xae, 0xed, 0x48, 0xd7, 0xee, 0x51, 0x42, 0x53, 0x64, 0xdc, 0xb8, - 0x46, 0x47, 0xaa, 0x6a, 0x44, 0xaa, 0x30, 0x8a, 0x6f, 0xc7, 0x77, 0xc3, 0x81, 0x1e, 0x9c, 0x4f, - 0x38, 0x14, 0x19, 0xd9, 0xbd, 0x90, 0xba, 0xe4, 0x45, 0x28, 0xb0, 0xd1, 0x14, 0xeb, 0x41, 0x9c, - 0x31, 0x75, 0x75, 0x7d, 0x8d, 0x77, 0xd8, 0xed, 0x53, 0x16, 0x22, 0x90, 0xe7, 0x21, 0xdf, 0x9d, - 0xdb, 0x16, 0x9a, 0xbe, 0x9c, 0x5c, 0x23, 0x8f, 0xd1, 0x58, 0x31, 0xb9, 0x01, 0xc5, 0x07, 0xfa, - 0x85, 0xe1, 0xd3, 0xa9, 0x61, 0x8c, 0xf1, 0x63, 0xc4, 0x5a, 0x11, 0x86, 0xf9, 0x55, 0x59, 0xf3, - 0x19, 0x80, 0xa4, 0xea, 0xde, 0x20, 0x1b, 0xf3, 0x03, 0x18, 0x8d, 0xab, 0x24, 0x4f, 0x03, 0xec, - 0xd1, 0x7d, 0x7b, 0xd7, 0x69, 0xbb, 0xe2, 0xf5, 0xb1, 0x92, 0x35, 0xba, 0x47, 0xf7, 0x6f, 0x23, - 0x80, 0x9c, 0x85, 0x91, 0x0e, 0x1b, 0x55, 0x99, 0xdc, 0xdb, 0x1a, 0xee, 0x74, 0xb7, 0x98, 0x84, - 0xce, 0xc2, 0x08, 0x3a, 0x3f, 0xc4, 0x44, 0x1b, 0xb7, 0xe4, 0x4f, 0xf3, 0xd7, 0x72, 0x98, 0xf6, - 0x45, 0xf9, 0x4e, 0xf2, 0x1c, 0x8c, 0x37, 0x02, 0x8a, 0xcb, 0x91, 0xc3, 0xcc, 0x22, 0x51, 0x4f, - 0x29, 0x01, 0x2e, 0xb9, 0xe4, 0x12, 0x4c, 0x26, 0xd9, 0xc6, 0xed, 0xc6, 0x96, 0x48, 0x17, 0x50, - 0xb2, 0xc6, 0x3b, 0x32, 0xdd, 0xf8, 0xfc, 0x16, 0xde, 0xff, 0x29, 0xab, 0xd7, 0x64, 0x23, 0x99, - 0x39, 0x7c, 0xd4, 0x9a, 0x54, 0xe0, 0x78, 0x62, 0x73, 0x06, 0x86, 0x1d, 0x67, 0xa7, 0xeb, 0xf1, - 0xbb, 0x08, 0x25, 0x4b, 0xfc, 0x22, 0x2f, 0xc3, 0x54, 0xe8, 0xed, 0xb4, 0x9d, 0xa8, 0x1b, 0x88, - 0xbc, 0x3b, 0x34, 0x40, 0x91, 0x1a, 0xb7, 0xca, 0x71, 0xc1, 0x3c, 0x87, 0x93, 0x57, 0x81, 0xa8, - 0xf5, 0xf9, 0x5b, 0x1f, 0xd2, 0x06, 0x17, 0xb5, 0x92, 0x35, 0xa5, 0x94, 0xac, 0x62, 0x01, 0x79, - 0x16, 0x4a, 0x01, 0x0d, 0xd1, 0x24, 0xc3, 0x6e, 0xc3, 0x6c, 0x62, 0xd6, 0x98, 0x84, 0xdd, 0xa1, - 0xfb, 0x66, 0x0d, 0xa6, 0x7a, 0xe6, 0x23, 0x79, 0x95, 0x5b, 0xf7, 0x62, 0x7d, 0x2e, 0xf1, 0xcd, - 0x0c, 0xbe, 0x4e, 0xa8, 0x2d, 0xcd, 0x02, 0xc9, 0x6c, 0x43, 0x49, 0xd5, 0xaf, 0xc7, 0x24, 0x62, - 0x38, 0x83, 0x51, 0xc7, 0x5c, 0xf9, 0x0c, 0x1f, 0x1e, 0x54, 0x72, 0x9e, 0x8b, 0xb1, 0xc6, 0x97, - 0xa1, 0x28, 0xad, 0x04, 0xf5, 0xa5, 0x2c, 0x61, 0x50, 0xee, 0x5b, 0x71, 0xa9, 0xf9, 0x22, 0x8c, - 0x08, 0x15, 0x7a, 0xb4, 0x23, 0xca, 0xfc, 0x7a, 0x0e, 0x26, 0x2d, 0xca, 0x26, 0xb8, 0x78, 0x83, - 0xea, 0x13, 0x96, 0x77, 0x5d, 0x6b, 0xdb, 0x11, 0x79, 0x4f, 0x7e, 0xdb, 0x80, 0xe9, 0x0c, 0xdc, - 0x8f, 0x94, 0xa8, 0xf1, 0x26, 0x8c, 0x2e, 0x78, 0x4e, 0xb3, 0xea, 0xba, 0x71, 0xf4, 0x34, 0x5a, - 0x83, 0x2e, 0x9b, 0x4e, 0x0e, 0x83, 0xaa, 0x8b, 0x69, 0x8c, 0x4a, 0xae, 0x08, 0xa1, 0x48, 0x52, - 0xc9, 0xca, 0xcc, 0xee, 0xc0, 0xbf, 0x29, 0xc9, 0xeb, 0x8e, 0x57, 0x68, 0x39, 0x30, 0x39, 0x9c, - 0x7f, 0x62, 0x87, 0x2e, 0xfb, 0x0a, 0x6d, 0xba, 0x79, 0x03, 0x6d, 0x3b, 0xbf, 0x95, 0x83, 0x33, - 0xd9, 0x84, 0x1f, 0x35, 0xe7, 0x26, 0x26, 0x9d, 0x51, 0x92, 0xe7, 0x63, 0xce, 0x4d, 0x9e, 0xa1, - 0x06, 0xf1, 0x13, 0x04, 0xb2, 0x0d, 0xe3, 0xcb, 0x4e, 0x18, 0xdd, 0xa6, 0x4e, 0x10, 0x6d, 0x51, - 0x27, 0x1a, 0xc0, 0x82, 0x7d, 0x5e, 0x3e, 0x30, 0x84, 0x8b, 0xda, 0xae, 0xa4, 0x4c, 0x19, 0x78, - 0x3a, 0xdb, 0x58, 0x50, 0x0a, 0x03, 0x08, 0xca, 0x57, 0x61, 0xb2, 0x4e, 0x5b, 0x4e, 0x67, 0xd7, - 0x0f, 0xa8, 0xf0, 0x9d, 0x5f, 0x85, 0xf1, 0x18, 0x94, 0x29, 0x2d, 0x7a, 0xb1, 0x86, 0xaf, 0x74, - 0x44, 0xa2, 0x4a, 0xf4, 0x62, 0xf3, 0x57, 0x72, 0x70, 0xb6, 0xda, 0x10, 0x27, 0x1c, 0xa2, 0x40, - 0x1e, 0xc4, 0x7e, 0xcc, 0x75, 0x93, 0x6b, 0x30, 0x7a, 0xd7, 0x79, 0xb8, 0x4c, 0xf1, 0x05, 0x7d, - 0x9e, 0xb9, 0x8d, 0x9b, 0x5f, 0xce, 0x43, 0x3b, 0x76, 0x7b, 0x59, 0x09, 0x8e, 0xba, 0xd9, 0x2c, - 0x3c, 0xe2, 0x66, 0xd3, 0x84, 0xe1, 0xdb, 0x7e, 0xd3, 0x15, 0x8b, 0x93, 0x38, 0xb7, 0xd8, 0x45, - 0x88, 0x25, 0x4a, 0xcc, 0x1f, 0x1a, 0x30, 0x11, 0x7f, 0x31, 0x7e, 0xc2, 0xc7, 0xde, 0x25, 0x97, - 0x60, 0x04, 0x2b, 0x8a, 0x5f, 0x57, 0xc3, 0x45, 0xa3, 0xc9, 0x40, 0xb6, 0xe7, 0x5a, 0xb2, 0x50, - 0xed, 0x89, 0xa1, 0x47, 0xeb, 0x09, 0xf3, 0xef, 0xe1, 0x91, 0x88, 0xda, 0x4a, 0xb6, 0x12, 0x29, - 0x1f, 0x62, 0x0c, 0xf8, 0x21, 0xb9, 0xc7, 0x36, 0x24, 0xf9, 0xbe, 0x43, 0xf2, 0x8d, 0x1c, 0x8c, - 0xc5, 0x1f, 0xfb, 0x09, 0xcb, 0x3d, 0x11, 0xb7, 0x6b, 0xa0, 0x1b, 0x14, 0x75, 0x45, 0x57, 0x88, - 0x8b, 0x0a, 0x9f, 0x83, 0x61, 0x31, 0x99, 0x8c, 0xd4, 0x81, 0x64, 0x6a, 0x74, 0x6b, 0x13, 0x82, - 0xf5, 0x30, 0x0e, 0x68, 0x68, 0x09, 0x3a, 0xbc, 0xa2, 0xb2, 0x49, 0xb7, 0xc4, 0x09, 0xd9, 0x13, - 0xbb, 0x46, 0x65, 0x5f, 0x51, 0x49, 0x1a, 0x36, 0xd0, 0xea, 0xf4, 0xb7, 0x0b, 0x50, 0x4e, 0x93, - 0x1c, 0x9f, 0xdd, 0x63, 0xad, 0xbb, 0x25, 0xde, 0xea, 0xc1, 0xec, 0x1e, 0x9d, 0xee, 0x96, 0xc5, - 0x60, 0xe4, 0x12, 0x14, 0xd6, 0x02, 0xef, 0x3e, 0xb6, 0x5a, 0x3c, 0x55, 0xd4, 0x09, 0xbc, 0xfb, - 0x6a, 0xac, 0x36, 0x2b, 0xc7, 0x0d, 0xed, 0x72, 0x1d, 0xc3, 0x7e, 0xd1, 0xb0, 0x16, 0x1b, 0xda, - 0x66, 0x98, 0x4e, 0x23, 0x25, 0xd1, 0xd8, 0x52, 0x59, 0xa3, 0x4e, 0x20, 0x32, 0x51, 0x08, 0x75, - 0x86, 0x4b, 0xe5, 0x16, 0x82, 0x79, 0xde, 0x6f, 0x4b, 0x45, 0x22, 0x4d, 0x20, 0xca, 0x4f, 0x39, - 0x81, 0x8f, 0xdf, 0xe3, 0xc9, 0x27, 0xf6, 0x66, 0x54, 0xd6, 0xb6, 0x3a, 0x9b, 0x33, 0xf8, 0x3e, - 0x4e, 0x1f, 0xe1, 0x9a, 0xb8, 0x97, 0x88, 0x8e, 0x8c, 0xe2, 0xb1, 0xcc, 0x64, 0x5c, 0x3c, 0xf0, - 0x7b, 0x8b, 0xb1, 0x3b, 0x23, 0x61, 0x42, 0xde, 0x86, 0x31, 0x35, 0x98, 0x9b, 0x87, 0x1c, 0x5f, - 0xe0, 0xd7, 0x07, 0xfb, 0xa4, 0xd0, 0x54, 0x09, 0xcc, 0x4f, 0xa9, 0x52, 0x22, 0x16, 0xed, 0x23, - 0xa5, 0xc4, 0xfc, 0x25, 0x34, 0xe3, 0x5b, 0x7e, 0x44, 0x85, 0xf5, 0xf2, 0xc4, 0xea, 0xb1, 0xc4, - 0x85, 0x3c, 0xa4, 0x05, 0xd3, 0x68, 0xad, 0xe3, 0x18, 0x1b, 0x37, 0x12, 0xa5, 0xc3, 0x9d, 0xc9, - 0xd2, 0x85, 0xac, 0x4c, 0xb9, 0xdf, 0x34, 0xe0, 0x74, 0x26, 0x2d, 0xb9, 0x0a, 0x90, 0xd8, 0x88, - 0xa2, 0x97, 0x78, 0x42, 0xf5, 0x18, 0x6a, 0x29, 0x18, 0xe4, 0x4b, 0x69, 0xeb, 0xee, 0xf8, 0xc5, - 0x49, 0x3e, 0x3b, 0x34, 0xa1, 0x5b, 0x77, 0x19, 0x36, 0x9d, 0xf9, 0xdb, 0x79, 0x98, 0xea, 0x79, - 0x4d, 0xf7, 0x98, 0x28, 0x82, 0xbd, 0xd4, 0x63, 0x88, 0xfc, 0xb8, 0xe3, 0x4a, 0xbf, 0xb7, 0x7c, - 0x33, 0x9e, 0x46, 0x44, 0xb7, 0x98, 0xc8, 0xe5, 0x7f, 0xcc, 0x0b, 0x89, 0x61, 0xf6, 0x33, 0x9a, - 0x2f, 0xf7, 0xad, 0xed, 0x31, 0x3c, 0xa7, 0xf9, 0x97, 0xf8, 0xb5, 0xc1, 0x5f, 0xca, 0xc1, 0x74, - 0x4f, 0x9b, 0x9f, 0xd8, 0x59, 0xf7, 0x39, 0x6d, 0x75, 0x7b, 0xa6, 0xdf, 0x98, 0x0e, 0x64, 0x45, - 0xfc, 0x4f, 0x03, 0xce, 0xf6, 0xa1, 0x24, 0xfb, 0x69, 0x21, 0xe2, 0x56, 0xc5, 0xf5, 0xa3, 0x2b, - 0x7c, 0x2c, 0xa2, 0xf4, 0xb1, 0x49, 0xc2, 0xd7, 0x73, 0x00, 0x9b, 0x74, 0xeb, 0xc9, 0x4e, 0x5d, - 0xf6, 0x19, 0x4d, 0x00, 0x14, 0x07, 0xe6, 0xe0, 0x99, 0xcb, 0x56, 0xd1, 0x91, 0x38, 0x78, 0xde, - 0xb2, 0xf8, 0x69, 0xa5, 0x5c, 0xf6, 0xd3, 0x4a, 0xe6, 0x16, 0xcc, 0xbc, 0x4b, 0xa3, 0x64, 0x25, - 0x94, 0x7b, 0xc8, 0xa3, 0xd9, 0xbe, 0x02, 0xa3, 0x02, 0x5f, 0x7f, 0x26, 0x43, 0xc6, 0xe2, 0x79, - 0xae, 0x95, 0x20, 0x98, 0x14, 0xce, 0x2e, 0xd0, 0x26, 0x8d, 0xe8, 0xc7, 0x5b, 0x4d, 0x1d, 0x08, - 0x6f, 0x0a, 0x7f, 0x71, 0x67, 0xa0, 0x1a, 0x8e, 0xed, 0x9f, 0x0d, 0x38, 0x1d, 0x7f, 0xfb, 0xe3, - 0xe4, 0x7b, 0x8d, 0xd9, 0x12, 0xe2, 0x3e, 0x6c, 0xc2, 0xf1, 0x08, 0x27, 0xe2, 0x43, 0x38, 0x2f, - 0x09, 0x36, 0xbd, 0xf8, 0x24, 0x66, 0x20, 0x5a, 0xf2, 0x26, 0x8c, 0x29, 0x34, 0xe2, 0x56, 0x3f, - 0x9e, 0x76, 0x3e, 0xf0, 0xa2, 0x5d, 0x3b, 0xe4, 0x70, 0xf5, 0xb4, 0x53, 0x41, 0x37, 0xbf, 0x08, - 0x4f, 0xc5, 0x71, 0x2b, 0x19, 0x55, 0xa7, 0x98, 0x1b, 0x27, 0x63, 0xbe, 0x92, 0x34, 0x6b, 0xa9, - 0x1d, 0x87, 0xde, 0x4b, 0xde, 0x44, 0x6d, 0x96, 0x68, 0xcc, 0x05, 0x25, 0xa5, 0xa3, 0x58, 0x8b, - 0x12, 0x80, 0xf9, 0x86, 0xf2, 0xb1, 0x19, 0x0c, 0x35, 0x62, 0x23, 0x4d, 0xfc, 0xf5, 0x1c, 0x4c, - 0xae, 0x2e, 0x2d, 0xcc, 0xc7, 0x6e, 0xe4, 0x4f, 0x58, 0x5e, 0x35, 0xad, 0x6d, 0xfd, 0xf5, 0x8d, - 0x79, 0x0f, 0xa6, 0x53, 0xdd, 0x80, 0x0f, 0x8a, 0xbd, 0xcd, 0xe3, 0x4b, 0x62, 0xb0, 0x5c, 0x59, - 0xce, 0x64, 0xb1, 0xdf, 0xb8, 0x61, 0xa5, 0xb0, 0xcd, 0x7f, 0x34, 0x92, 0xe2, 0x2b, 0x54, 0xd8, - 0x2b, 0x30, 0xba, 0x14, 0x86, 0x5d, 0x1a, 0xdc, 0xb3, 0x96, 0x55, 0x1b, 0xd1, 0x43, 0xa0, 0xdd, - 0x0d, 0x9a, 0x56, 0x82, 0x40, 0x5e, 0x82, 0xa2, 0xb8, 0x83, 0x29, 0x75, 0x02, 0x1e, 0x97, 0xc7, - 0x57, 0x38, 0xad, 0xb8, 0x98, 0xbc, 0x06, 0x25, 0xfe, 0x3f, 0x97, 0x36, 0xd1, 0xe1, 0xe8, 0xab, - 0x12, 0xe8, 0x5c, 0x3a, 0x2d, 0x0d, 0x8d, 0xbc, 0x08, 0x63, 0xf2, 0xc5, 0x62, 0xf6, 0x45, 0xdc, - 0x03, 0x28, 0xae, 0x87, 0xa8, 0x25, 0xe4, 0x0a, 0xe4, 0xab, 0xf3, 0x96, 0xfa, 0x1c, 0x80, 0xd3, - 0x08, 0xf8, 0x73, 0x1a, 0xda, 0x4b, 0x80, 0xd5, 0x79, 0x8b, 0xcc, 0xe1, 0x3b, 0xf7, 0xf7, 0x3d, - 0x97, 0x06, 0x22, 0xd4, 0x15, 0x45, 0xa5, 0x23, 0x60, 0xa9, 0x67, 0xee, 0x11, 0x46, 0xae, 0xc1, - 0xc8, 0x82, 0x17, 0x76, 0x9a, 0xce, 0xbe, 0xc8, 0xa2, 0x84, 0x27, 0x20, 0x2e, 0x07, 0xa9, 0xc2, - 0x25, 0xb0, 0xc8, 0x4b, 0x30, 0x54, 0x6f, 0xf8, 0x1d, 0xb6, 0xc5, 0x8a, 0xe3, 0x59, 0x42, 0x06, - 0xd0, 0x72, 0x9d, 0x30, 0x00, 0xe6, 0x02, 0xe0, 0x57, 0x1a, 0x47, 0x95, 0x5c, 0x00, 0xe9, 0xab, - 0x8c, 0x02, 0xa7, 0x37, 0xe2, 0x10, 0x1e, 0x67, 0xc4, 0xe1, 0x16, 0x9c, 0x7d, 0x17, 0xed, 0xfb, - 0x3a, 0x0d, 0x30, 0x71, 0x2d, 0x7f, 0x35, 0xee, 0x9e, 0xb5, 0x24, 0xae, 0x71, 0xe2, 0xa5, 0x3a, - 0xbe, 0x05, 0xb0, 0x43, 0x8e, 0x23, 0x1f, 0x9c, 0x4b, 0x3d, 0x95, 0xd3, 0x8f, 0x11, 0xf9, 0x3c, - 0xcc, 0x64, 0x15, 0x89, 0x0b, 0x9d, 0x18, 0x45, 0x9f, 0x5d, 0x81, 0x1a, 0xc6, 0x9e, 0xc5, 0x81, - 0x2c, 0x43, 0x99, 0xc3, 0xab, 0x6e, 0xcb, 0x6b, 0x2f, 0xb6, 0x1c, 0xaf, 0x89, 0xd7, 0x3b, 0xc5, - 0x1d, 0x5d, 0xc1, 0xd5, 0x61, 0x85, 0x36, 0x65, 0xa5, 0x5a, 0x48, 0x52, 0x8a, 0x92, 0xfc, 0xbc, - 0x01, 0x25, 0x45, 0xc6, 0x42, 0x71, 0xdf, 0xa1, 0xdf, 0xf3, 0x43, 0xeb, 0x8f, 0xe9, 0xf9, 0xa1, - 0x92, 0x7c, 0xb7, 0x1b, 0xa7, 0x9b, 0xf6, 0x05, 0xe6, 0x1f, 0x8c, 0x70, 0xb5, 0x58, 0xed, 0x46, - 0xbb, 0x52, 0x91, 0xce, 0x65, 0x05, 0xd0, 0x70, 0x47, 0xbf, 0x12, 0x40, 0xa3, 0x87, 0xcd, 0xc8, - 0x03, 0xb9, 0x5c, 0xe6, 0x81, 0xdc, 0x2b, 0x30, 0x8a, 0x69, 0xe7, 0xe3, 0x48, 0x85, 0xa2, 0xd8, - 0x29, 0x32, 0x20, 0xbf, 0x48, 0x98, 0x20, 0x90, 0x6b, 0x00, 0x98, 0xb3, 0x87, 0xaf, 0xb2, 0xca, - 0x4d, 0x70, 0x4c, 0xed, 0x23, 0x7c, 0x27, 0x0a, 0x0a, 0xb2, 0xaf, 0x5b, 0xb7, 0x54, 0x67, 0x0b, - 0x67, 0x1f, 0x06, 0xdb, 0x02, 0x3d, 0x41, 0x60, 0xcd, 0x53, 0x55, 0xc0, 0x70, 0xd2, 0x3c, 0xad, - 0x9f, 0x34, 0x6d, 0xf0, 0x8a, 0xfa, 0x60, 0xf4, 0x08, 0x3a, 0x81, 0xf8, 0x39, 0x46, 0x7c, 0x84, - 0xab, 0x3e, 0x13, 0x3d, 0x07, 0x23, 0xf3, 0x34, 0x88, 0xd6, 0xd7, 0x97, 0xc5, 0xab, 0x48, 0x4c, - 0x7f, 0x14, 0xf1, 0x26, 0x6a, 0x14, 0xe9, 0x8f, 0xa8, 0x48, 0x44, 0x52, 0x83, 0x32, 0x0f, 0x33, - 0x49, 0x0c, 0x29, 0x9c, 0xbd, 0x45, 0xae, 0x4b, 0xc4, 0xc5, 0xcb, 0x07, 0x74, 0x2b, 0xbe, 0x82, - 0xdb, 0x83, 0x4f, 0x16, 0xe5, 0x55, 0x78, 0xb5, 0x7d, 0x80, 0xed, 0x3b, 0xab, 0x3c, 0x12, 0xa3, - 0x35, 0xb3, 0x97, 0x82, 0x54, 0x61, 0x7c, 0xde, 0x6f, 0x75, 0x9c, 0xc8, 0xc3, 0x7c, 0x43, 0xfb, - 0x62, 0xa2, 0xe2, 0x5e, 0xb7, 0xa1, 0x16, 0xe8, 0x09, 0xe4, 0x95, 0x02, 0x72, 0x0b, 0x26, 0x2c, - 0xbf, 0xcb, 0xc6, 0x47, 0x6c, 0x44, 0xc4, 0x5c, 0x8c, 0x5f, 0x0f, 0x61, 0xc3, 0x68, 0x8b, 0x73, - 0x23, 0xed, 0x7a, 0x8d, 0x46, 0x45, 0x56, 0x32, 0x36, 0xf5, 0xea, 0x04, 0x54, 0x2f, 0xe2, 0xf6, - 0x30, 0xcb, 0xf0, 0x07, 0xdc, 0x80, 0xb1, 0x7a, 0x7d, 0x75, 0x9d, 0x86, 0xd1, 0xad, 0xa6, 0xff, - 0x00, 0xe7, 0x5f, 0x51, 0x3e, 0x0c, 0xeb, 0xdb, 0x11, 0x0d, 0x23, 0x7b, 0xbb, 0xe9, 0x3f, 0xb0, - 0x54, 0x2c, 0xf2, 0x65, 0x25, 0xa3, 0x3e, 0xae, 0xbc, 0x93, 0xc7, 0xae, 0xbc, 0xa9, 0x6c, 0xfb, - 0x6c, 0xfd, 0xcd, 0xcc, 0xb6, 0xcf, 0xd0, 0xc9, 0xdb, 0xe2, 0x49, 0x91, 0xaa, 0xeb, 0x06, 0x34, - 0x0c, 0xf1, 0xe2, 0xb4, 0x88, 0x58, 0xe3, 0xe7, 0x64, 0x0e, 0x2f, 0x88, 0x39, 0x58, 0x1a, 0x3e, - 0x9a, 0x36, 0xf5, 0xea, 0xdd, 0xe5, 0x64, 0x7d, 0xfe, 0x64, 0x9d, 0x41, 0x6b, 0x6d, 0x3b, 0xe2, - 0x0c, 0xfa, 0x1e, 0x4c, 0xa7, 0xba, 0x41, 0x9a, 0x36, 0x1a, 0x38, 0x6d, 0xda, 0xa4, 0x68, 0xac, - 0x14, 0xb6, 0xf9, 0x1f, 0x86, 0x53, 0x7c, 0x85, 0xdf, 0xd9, 0x84, 0x61, 0x6e, 0xb9, 0xa8, 0xd9, - 0x5b, 0xb9, 0x5d, 0x63, 0x89, 0x12, 0x72, 0x0e, 0xf2, 0xf5, 0xfa, 0xaa, 0x9a, 0x5b, 0x3a, 0x0c, - 0x7d, 0x8b, 0xc1, 0xd8, 0x08, 0xa1, 0x4b, 0x59, 0xb9, 0x27, 0xcb, 0x34, 0x84, 0x78, 0x1e, 0xff, - 0x85, 0xc4, 0x3c, 0x28, 0x24, 0xfd, 0x2d, 0xcc, 0x83, 0xc4, 0x28, 0x98, 0x87, 0xd9, 0x6a, 0x18, - 0xd2, 0x80, 0x3f, 0xcd, 0xd2, 0x0e, 0xbb, 0x2d, 0x1a, 0x88, 0x25, 0x4c, 0x28, 0x42, 0xac, 0xd4, - 0x69, 0x84, 0x56, 0x5f, 0x44, 0x72, 0x19, 0x8a, 0xd5, 0xae, 0xeb, 0xd1, 0x76, 0x43, 0xbb, 0xa9, - 0xe3, 0x08, 0x98, 0x15, 0x97, 0x92, 0xf7, 0xe1, 0xb4, 0x20, 0x92, 0x76, 0x8c, 0xe8, 0x81, 0x91, - 0x44, 0x43, 0xc8, 0x25, 0x56, 0x5a, 0x3f, 0xb6, 0xe8, 0x92, 0x6c, 0x4a, 0x52, 0x85, 0xf2, 0x22, - 0xc6, 0x5c, 0x2c, 0xd0, 0xb0, 0x11, 0x78, 0x9d, 0xc8, 0x0f, 0xc4, 0xc3, 0x07, 0x68, 0x10, 0xf1, - 0x78, 0x0c, 0xdb, 0x8d, 0x0b, 0xad, 0x1e, 0x74, 0x72, 0x07, 0xa6, 0xd3, 0x30, 0xa6, 0xf8, 0x46, - 0x93, 0x47, 0x6c, 0x7b, 0xb8, 0xa0, 0xea, 0xcb, 0xa2, 0x22, 0x5b, 0x30, 0x55, 0x8d, 0xa2, 0xc0, - 0xdb, 0xea, 0x46, 0x34, 0x65, 0x11, 0xc9, 0x43, 0x8b, 0xb8, 0x5c, 0x5a, 0x45, 0x4f, 0x09, 0x61, - 0x9c, 0x76, 0x62, 0xca, 0xd8, 0x32, 0xb2, 0x7a, 0xd9, 0x11, 0x37, 0x7e, 0x07, 0x5b, 0xbc, 0x15, - 0x2d, 0xee, 0x75, 0xca, 0xc3, 0xa1, 0x6a, 0xb8, 0xdf, 0x6a, 0xd1, 0x28, 0xc0, 0xd5, 0x04, 0xdf, - 0x92, 0x36, 0x45, 0x3c, 0xe1, 0x79, 0xe5, 0xf9, 0x77, 0x7c, 0x2f, 0x5c, 0x0b, 0xb5, 0xd6, 0x78, - 0x6a, 0x56, 0x69, 0x69, 0x40, 0xab, 0xb4, 0x09, 0x53, 0x8b, 0xed, 0x46, 0xb0, 0x8f, 0xd7, 0xe8, - 0xe5, 0xc7, 0x8d, 0x1f, 0xf3, 0x71, 0xf2, 0xa1, 0xb8, 0x0b, 0x8e, 0x94, 0xb0, 0xac, 0xcf, 0xeb, - 0x65, 0x6c, 0xfe, 0x8f, 0x61, 0xae, 0xb8, 0x54, 0xe3, 0xe3, 0x8c, 0x92, 0x31, 0x50, 0x8d, 0xdd, - 0x49, 0x19, 0x25, 0xb9, 0x93, 0x18, 0x25, 0xf9, 0xe3, 0x8d, 0x92, 0xc2, 0x71, 0x46, 0x49, 0xca, - 0x6a, 0x18, 0x3a, 0xb1, 0xd5, 0x30, 0x7c, 0x02, 0xab, 0x61, 0x64, 0x50, 0xab, 0x41, 0xb3, 0x7c, - 0x8a, 0xc7, 0x59, 0x3e, 0xff, 0xdf, 0xc6, 0x78, 0x52, 0x6d, 0x8c, 0xac, 0x25, 0xf0, 0x24, 0x36, - 0x86, 0xf9, 0x57, 0xa0, 0x9c, 0x56, 0x5b, 0xc7, 0x5f, 0xb1, 0x7c, 0x6c, 0x37, 0xaa, 0x98, 0x52, - 0x4d, 0xab, 0x0d, 0x66, 0xe6, 0xaf, 0x05, 0xde, 0x7d, 0x27, 0xa2, 0x49, 0x5a, 0x7e, 0x34, 0xf3, - 0x3b, 0x1c, 0x8a, 0xf3, 0x43, 0x41, 0x89, 0x57, 0xcc, 0x5c, 0xd6, 0x8a, 0x69, 0x7e, 0x33, 0x07, - 0x53, 0xfc, 0x12, 0xc8, 0x93, 0xef, 0xe2, 0x79, 0x5b, 0xb3, 0x83, 0xe4, 0x11, 0x5e, 0xaa, 0x75, - 0x47, 0x38, 0x79, 0x3e, 0x80, 0xd3, 0x3d, 0x5d, 0x81, 0xb6, 0xd0, 0x82, 0xbc, 0x7e, 0xd3, 0x63, - 0x0d, 0xcd, 0x66, 0x57, 0xb2, 0x71, 0xc3, 0xea, 0xa1, 0x30, 0xff, 0x3c, 0xd7, 0xc3, 0x5f, 0xb8, - 0x7b, 0x54, 0x07, 0x8e, 0x71, 0x32, 0x07, 0x4e, 0x6e, 0x30, 0x07, 0x4e, 0x4a, 0x0f, 0xe7, 0x07, - 0xd1, 0xc3, 0xef, 0xc3, 0xf8, 0x3a, 0x75, 0x5a, 0xe1, 0xba, 0x2f, 0xae, 0xd7, 0xf3, 0x0b, 0xa9, - 0xf2, 0x76, 0x0d, 0x2b, 0x93, 0x4b, 0x79, 0x9c, 0x9a, 0x23, 0x62, 0x04, 0x4c, 0x81, 0xf0, 0xfb, - 0xf6, 0x96, 0xce, 0x41, 0xb5, 0xcf, 0x86, 0x8e, 0xb0, 0xcf, 0xea, 0x50, 0x12, 0x74, 0xc9, 0xbd, - 0x52, 0xe5, 0xe9, 0x43, 0xea, 0xe0, 0x2b, 0xf3, 0xa1, 0xac, 0x3d, 0xce, 0x19, 0x17, 0xd7, 0xce, - 0x6d, 0x08, 0x8d, 0x89, 0xf9, 0x0f, 0x46, 0xa4, 0xa4, 0x7f, 0xbc, 0xbb, 0x76, 0x7d, 0x1f, 0x9e, - 0x3f, 0xe1, 0x3e, 0xbc, 0x70, 0xdc, 0x6a, 0xa4, 0xad, 0x8e, 0x43, 0x27, 0x58, 0x1d, 0x87, 0x1f, - 0x65, 0x4f, 0x3d, 0x72, 0xc2, 0xf5, 0x2e, 0x25, 0x6f, 0xc5, 0x41, 0xe4, 0x2d, 0x73, 0x8d, 0x1c, - 0x7d, 0xf4, 0x35, 0x12, 0x4e, 0xbc, 0x46, 0x2a, 0xa9, 0xe4, 0xc7, 0x06, 0x4a, 0x25, 0x6f, 0x0c, - 0x90, 0x4a, 0xfe, 0x13, 0xb5, 0xf0, 0x7e, 0x25, 0x7b, 0xe1, 0x3d, 0x5a, 0xe7, 0x9e, 0x68, 0xe9, - 0x0d, 0xf0, 0xb3, 0x36, 0x9d, 0x80, 0x19, 0xe7, 0x21, 0xb9, 0x06, 0x23, 0xf2, 0x86, 0x97, 0x91, - 0xec, 0x73, 0x7a, 0xaf, 0x76, 0x49, 0x2c, 0x66, 0xc7, 0x4b, 0x62, 0x11, 0x0d, 0xcd, 0x2f, 0xb3, - 0x08, 0x98, 0x76, 0x99, 0x45, 0xc0, 0xcc, 0xbf, 0x53, 0x90, 0xa2, 0xcf, 0x8c, 0x57, 0x91, 0xd9, - 0xb5, 0xe7, 0x65, 0x40, 0xe3, 0xe4, 0x2f, 0x03, 0x7e, 0x84, 0xeb, 0x71, 0x4a, 0xfe, 0xa6, 0xfc, - 0x00, 0xf9, 0x9b, 0x5e, 0xd7, 0x92, 0x1f, 0x15, 0x92, 0x6c, 0x1b, 0x4c, 0x1c, 0x8e, 0x4e, 0x7b, - 0x74, 0x53, 0xcd, 0x52, 0x34, 0x94, 0x04, 0x8e, 0x23, 0xe5, 0x11, 0xf9, 0x89, 0x62, 0x4b, 0x66, - 0xf8, 0x24, 0x57, 0x45, 0x47, 0xfe, 0x9f, 0x5e, 0x15, 0x5d, 0x04, 0x50, 0xd2, 0x7d, 0x72, 0x37, - 0xe3, 0x0b, 0xac, 0x9b, 0x8e, 0x4f, 0xf5, 0xa9, 0x10, 0x9a, 0x7f, 0x3a, 0x05, 0x53, 0xf5, 0xfa, - 0xea, 0x82, 0xe7, 0xec, 0xb4, 0xfd, 0x30, 0xf2, 0x1a, 0x4b, 0xed, 0x6d, 0x9f, 0x2d, 0xe3, 0xf1, - 0x34, 0x52, 0xae, 0x2d, 0x26, 0x53, 0x28, 0x2e, 0x66, 0x66, 0xe2, 0x62, 0x10, 0xc4, 0x8f, 0x5d, - 0xa2, 0x99, 0x48, 0x19, 0xc0, 0xe2, 0x70, 0xb6, 0x52, 0xd6, 0xbb, 0x3c, 0x6f, 0x23, 0xf7, 0xfc, - 0xe2, 0x4a, 0x19, 0x72, 0x90, 0x25, 0xcb, 0x08, 0xed, 0x15, 0x58, 0x61, 0x39, 0x9d, 0xd5, 0x2e, - 0x9c, 0x26, 0xc5, 0xe2, 0x25, 0x7c, 0xae, 0xc4, 0xf1, 0xea, 0x48, 0x07, 0xe1, 0xaa, 0x0b, 0xbe, - 0x67, 0x0e, 0xec, 0xc3, 0x69, 0xdc, 0x71, 0x9e, 0x74, 0x8b, 0x7f, 0x45, 0xac, 0xcc, 0x26, 0x5e, - 0x75, 0xce, 0xd8, 0xe7, 0xab, 0x0f, 0xe2, 0x65, 0xd6, 0x40, 0xbe, 0x69, 0xc0, 0xd3, 0x99, 0x25, - 0xf1, 0xec, 0x1e, 0xd3, 0x2e, 0xfd, 0x2a, 0x4a, 0x03, 0x73, 0x5d, 0xbe, 0xdc, 0xaf, 0x6a, 0x3b, - 0x43, 0x15, 0x1c, 0x5d, 0x13, 0xf9, 0xa7, 0x06, 0x9c, 0xd5, 0x30, 0x70, 0x15, 0x6f, 0xd1, 0x76, - 0x14, 0xa2, 0x32, 0xef, 0x2b, 0xd7, 0x1f, 0x3e, 0x1e, 0xb9, 0x7e, 0x4e, 0x6f, 0x0b, 0x7f, 0x80, - 0x08, 0xab, 0x57, 0xcf, 0x7b, 0xfa, 0x7c, 0x21, 0xb9, 0x0f, 0x53, 0x58, 0x24, 0xdd, 0x0d, 0x4c, - 0x66, 0x85, 0x97, 0x62, 0x26, 0xf9, 0xec, 0xf9, 0x6e, 0x18, 0xf9, 0x2d, 0xcc, 0x6d, 0x37, 0xf7, - 0xfd, 0x83, 0xca, 0xb8, 0x86, 0x8e, 0x79, 0x42, 0xf0, 0x1b, 0x62, 0x9f, 0x85, 0xd7, 0xde, 0xf6, - 0xb5, 0x27, 0x36, 0xd2, 0x55, 0x90, 0x7f, 0x61, 0xc0, 0x2c, 0x83, 0xf2, 0x66, 0xdc, 0x0a, 0xfc, - 0x56, 0x5c, 0x2e, 0xcf, 0x72, 0xfa, 0x74, 0x5b, 0xf3, 0xf1, 0x74, 0xdb, 0x0b, 0xf8, 0xc9, 0x5c, - 0x27, 0xd8, 0xdb, 0x81, 0xdf, 0x4a, 0x3e, 0x5f, 0xcb, 0x3e, 0xd9, 0xef, 0x23, 0xc9, 0xcf, 0x18, - 0x70, 0x4e, 0xdb, 0x4b, 0xaa, 0x59, 0x36, 0x66, 0x27, 0xb5, 0x83, 0x3f, 0xb5, 0xa8, 0x76, 0x55, - 0xc8, 0xff, 0x25, 0xfc, 0x82, 0x64, 0xb5, 0xc0, 0x6f, 0xb1, 0x5b, 0x1c, 0x4b, 0xf9, 0x84, 0xfe, - 0xb5, 0x10, 0x0f, 0xa6, 0xd0, 0x65, 0xae, 0x9d, 0x39, 0xce, 0xf4, 0x3f, 0x73, 0xbc, 0x24, 0xaa, - 0x7e, 0x06, 0x33, 0x19, 0xf4, 0x3f, 0x78, 0xec, 0xe5, 0x4a, 0x7e, 0x12, 0xce, 0xf5, 0x00, 0xe3, - 0xd9, 0x76, 0xba, 0xef, 0x6c, 0x7b, 0xf9, 0xf0, 0xa0, 0xf2, 0x62, 0x56, 0x6d, 0x59, 0x33, 0xad, - 0x7f, 0x0d, 0xc4, 0x01, 0x48, 0x0a, 0x67, 0xcf, 0x1c, 0x21, 0xa0, 0x2f, 0x0b, 0xf9, 0x50, 0xf0, - 0x99, 0x2e, 0x57, 0xbe, 0x41, 0x5d, 0xf2, 0x12, 0x24, 0x42, 0xa1, 0xa4, 0x64, 0x71, 0xd8, 0x9f, - 0x3d, 0x7b, 0x54, 0x25, 0xdf, 0x3f, 0xa8, 0x68, 0xd8, 0xcc, 0x90, 0x54, 0xd3, 0x43, 0xa8, 0x86, - 0xa4, 0x86, 0x48, 0x7e, 0xcf, 0x80, 0x19, 0x06, 0x48, 0x84, 0x4a, 0x34, 0x6a, 0xf6, 0x28, 0xa9, - 0xdf, 0x7d, 0x3c, 0x52, 0xff, 0x2c, 0x7e, 0xa3, 0x2a, 0xf5, 0x3d, 0x5d, 0x92, 0xf9, 0x71, 0x28, - 0xed, 0xda, 0xe9, 0x8c, 0x26, 0xed, 0xe7, 0x06, 0x90, 0x76, 0x3e, 0x00, 0xc7, 0x4b, 0x7b, 0xdf, - 0x5a, 0xc8, 0x3a, 0x94, 0x84, 0x0d, 0xc9, 0x3b, 0xec, 0x19, 0xed, 0xd2, 0xb8, 0x5a, 0xc4, 0x0d, - 0x7b, 0x91, 0xe4, 0xa2, 0xa7, 0x85, 0x1a, 0x17, 0xd2, 0x86, 0x69, 0xfe, 0x5b, 0xdf, 0xd7, 0x56, - 0xfa, 0xee, 0x6b, 0x2f, 0x8b, 0x16, 0x5d, 0x14, 0xfc, 0x53, 0xdb, 0x5b, 0xa5, 0xa2, 0x2c, 0xc6, - 0xa4, 0x03, 0x44, 0x03, 0xf3, 0x49, 0x7b, 0xf1, 0xe8, 0xdd, 0xec, 0x8b, 0xa2, 0xce, 0x4a, 0xba, - 0xce, 0xf4, 0xcc, 0xcd, 0xe0, 0x4d, 0x1c, 0x98, 0x14, 0x50, 0xb6, 0x59, 0x44, 0x0d, 0xff, 0xac, - 0x76, 0x35, 0x23, 0x55, 0xca, 0x13, 0x64, 0xca, 0x9a, 0x30, 0x06, 0x3e, 0xa5, 0xd0, 0xd3, 0xfc, - 0xcc, 0x6f, 0x18, 0x3d, 0x75, 0xb0, 0x4d, 0x29, 0xfe, 0x50, 0x6e, 0x97, 0xe2, 0xa6, 0x94, 0x73, - 0xc4, 0xcd, 0x71, 0x82, 0xc0, 0x6c, 0x1b, 0xf5, 0xa6, 0x4d, 0x5e, 0x3c, 0x30, 0xc1, 0x41, 0xc9, - 0x86, 0xa9, 0x22, 0x43, 0x37, 0xf2, 0x89, 0x8d, 0x84, 0xa1, 0x1b, 0x22, 0x60, 0xc3, 0xfc, 0x99, - 0x9c, 0x2e, 0x25, 0xe4, 0xb2, 0x62, 0x66, 0x2b, 0x77, 0x7d, 0xa4, 0x99, 0xad, 0x18, 0xd7, 0xbf, - 0x69, 0xc0, 0xf4, 0x6a, 0xb0, 0xe3, 0xb4, 0xbd, 0x9f, 0xe0, 0x37, 0x81, 0x7d, 0xec, 0xc6, 0x38, - 0xfa, 0xf2, 0x63, 0xcd, 0x04, 0xe6, 0x2b, 0x15, 0xb3, 0x81, 0xc5, 0x11, 0xb6, 0xb2, 0xbe, 0x07, - 0xa3, 0xe6, 0xf0, 0xc3, 0x94, 0x84, 0x6c, 0x1c, 0x9d, 0xc3, 0xcd, 0x6f, 0xe5, 0x60, 0x4c, 0x91, - 0x58, 0xf2, 0x69, 0x28, 0xa9, 0x7c, 0x54, 0x87, 0x86, 0x5a, 0xad, 0xa5, 0x61, 0xa1, 0x47, 0x83, - 0x3a, 0x2d, 0xcd, 0xa3, 0xc1, 0xe4, 0x12, 0xa1, 0x27, 0xdc, 0x89, 0xbc, 0x93, 0xb1, 0x13, 0x39, - 0x51, 0x1a, 0xd6, 0x37, 0x7b, 0xf7, 0x23, 0x83, 0x67, 0x4d, 0x35, 0xbf, 0x63, 0x40, 0x39, 0x3d, - 0xa7, 0x3e, 0x96, 0x5e, 0x39, 0x81, 0x23, 0xf7, 0xe7, 0x72, 0x50, 0x5e, 0x0f, 0xd8, 0x76, 0xdb, - 0x95, 0x21, 0xdb, 0x4f, 0xea, 0x59, 0xf3, 0x5b, 0x9a, 0x8f, 0xf5, 0xa9, 0x78, 0x19, 0x50, 0x1b, - 0x77, 0xc4, 0xa5, 0xa4, 0xc2, 0x2f, 0xff, 0x7a, 0xe5, 0x94, 0xf9, 0x05, 0x98, 0x49, 0x77, 0x07, - 0xfa, 0x59, 0xab, 0x30, 0xa9, 0xc3, 0xd3, 0xf9, 0x9a, 0xd2, 0x54, 0x56, 0x1a, 0xdf, 0xfc, 0xa3, - 0x5c, 0x9a, 0xb7, 0x38, 0x77, 0x66, 0x4a, 0xa7, 0xed, 0x6c, 0x35, 0xe3, 0x94, 0x32, 0xe2, 0x55, - 0x1b, 0x04, 0x59, 0xb2, 0xec, 0x24, 0x99, 0xbb, 0xe2, 0x88, 0xd6, 0x7c, 0x76, 0x44, 0x2b, 0xb9, - 0x99, 0x8a, 0x50, 0x28, 0x24, 0x0f, 0xd8, 0x3c, 0xa0, 0x5b, 0x76, 0x12, 0xa5, 0xa0, 0x47, 0x26, - 0x90, 0x79, 0x98, 0xd1, 0x2e, 0x85, 0x4b, 0xfa, 0xa1, 0xc4, 0x97, 0x18, 0x61, 0x01, 0x27, 0xce, - 0x44, 0xc6, 0xb7, 0xdf, 0xfc, 0x26, 0xdb, 0x89, 0x09, 0xf7, 0xa9, 0xfa, 0xf8, 0x87, 0x5c, 0x6b, - 0xe4, 0x4d, 0x11, 0x82, 0x29, 0x57, 0x5b, 0x4e, 0x47, 0xcb, 0x62, 0xcc, 0x11, 0xcd, 0x3f, 0x31, - 0xd8, 0xfc, 0x6f, 0xec, 0x7d, 0xc2, 0x72, 0x8a, 0xb1, 0x26, 0x1d, 0x11, 0x16, 0xf1, 0xef, 0x0c, - 0x9e, 0x15, 0x48, 0x88, 0xcf, 0xeb, 0x30, 0xbc, 0xee, 0x04, 0x3b, 0x34, 0x12, 0xf9, 0x6b, 0x54, - 0x2e, 0xbc, 0x20, 0xb9, 0x15, 0x14, 0xe1, 0x6f, 0x4b, 0x10, 0xa8, 0xae, 0xab, 0xdc, 0x40, 0xae, - 0x2b, 0xc5, 0xfd, 0x98, 0x7f, 0x5c, 0xee, 0x47, 0xf3, 0xcf, 0x73, 0xbc, 0x3d, 0xe2, 0xa3, 0x06, - 0x7d, 0x03, 0xed, 0x12, 0x14, 0x98, 0x1c, 0xa8, 0x0f, 0xcd, 0x31, 0x59, 0xd1, 0x1e, 0xc5, 0xf7, - 0x9b, 0x78, 0xac, 0x85, 0xfa, 0x5f, 0x4d, 0x63, 0x87, 0x4b, 0x84, 0x3a, 0x6f, 0x10, 0x03, 0xdf, - 0x1f, 0xf6, 0x5d, 0xaa, 0x4e, 0x87, 0xb6, 0xfe, 0x54, 0x34, 0x96, 0x93, 0x9b, 0x4a, 0x36, 0x19, - 0x35, 0xa2, 0xb4, 0xb5, 0xed, 0xd8, 0x3c, 0x8b, 0x89, 0xba, 0x02, 0x24, 0x89, 0x67, 0x16, 0x61, - 0x42, 0x4f, 0xae, 0x2b, 0xc2, 0x33, 0x30, 0x2f, 0x65, 0x2a, 0x31, 0xaf, 0xea, 0x67, 0xd5, 0x89, - 0x48, 0x0d, 0xc6, 0xb5, 0x44, 0xa6, 0xea, 0xb3, 0x9d, 0xfc, 0xdd, 0x0c, 0xbb, 0x37, 0xf5, 0xb7, - 0x4e, 0xa2, 0x5c, 0x53, 0xf8, 0x14, 0x94, 0xc5, 0xcc, 0x8c, 0x33, 0x0a, 0xe2, 0xc9, 0xdc, 0xd2, - 0x82, 0xa5, 0xce, 0xa6, 0x86, 0xe7, 0x06, 0x16, 0x42, 0xcd, 0xef, 0x1a, 0x70, 0x6e, 0x85, 0x46, - 0x0f, 0xfc, 0x60, 0xcf, 0xa2, 0x61, 0x14, 0x78, 0x3c, 0x41, 0x21, 0xca, 0xe3, 0xa7, 0xc9, 0x9b, - 0xf2, 0x49, 0x1e, 0x5d, 0x41, 0xa6, 0xeb, 0xa8, 0x8d, 0x0b, 0xa1, 0x1c, 0xc2, 0x47, 0x79, 0xe4, - 0x53, 0x3c, 0xaf, 0x8b, 0xa7, 0x78, 0x72, 0x47, 0x13, 0xc7, 0xf3, 0xc2, 0xa5, 0x6d, 0xf9, 0x04, - 0xcf, 0x77, 0x72, 0x70, 0x3a, 0xe3, 0xb3, 0x36, 0x3e, 0xfd, 0x84, 0x2a, 0x87, 0x9a, 0xa6, 0x1c, - 0xe4, 0x5b, 0x6d, 0x7d, 0x3b, 0x3e, 0x53, 0x57, 0xfc, 0xaa, 0x01, 0x67, 0x75, 0xe9, 0x11, 0x51, - 0x3b, 0x1b, 0x37, 0xc8, 0x1b, 0x30, 0x7c, 0x9b, 0x3a, 0x2e, 0x95, 0x89, 0xaf, 0x4e, 0xa7, 0x1e, - 0xb6, 0xe4, 0x85, 0x9c, 0xed, 0x1f, 0xf1, 0xa9, 0x7c, 0xca, 0x12, 0x24, 0x64, 0x41, 0x7c, 0x1c, - 0x37, 0x4b, 0x4d, 0x79, 0x3f, 0x26, 0xab, 0xaa, 0x23, 0xce, 0x35, 0xbf, 0x6f, 0xc0, 0x53, 0x47, - 0xd0, 0xb0, 0x81, 0x63, 0x43, 0xaf, 0x0e, 0x1c, 0x2e, 0x2c, 0x08, 0x25, 0x6f, 0xc3, 0xe4, 0xba, - 0x30, 0x6b, 0xe5, 0x70, 0x28, 0xef, 0x81, 0x4b, 0x8b, 0xd7, 0x96, 0xe3, 0x92, 0x46, 0x66, 0x46, - 0xf9, 0x6d, 0x3f, 0x8c, 0xda, 0xc9, 0xeb, 0x06, 0x68, 0x94, 0xef, 0x0a, 0x98, 0x15, 0x97, 0x92, - 0x1b, 0x18, 0x7a, 0xf3, 0x70, 0x7f, 0x69, 0x41, 0xda, 0x8d, 0x78, 0xee, 0xc3, 0xd7, 0x49, 0xfd, - 0xad, 0xcf, 0x18, 0x91, 0xd9, 0x12, 0x7a, 0xdb, 0xc4, 0xcd, 0xd5, 0xe7, 0x60, 0x98, 0x31, 0x8e, - 0xcf, 0xf4, 0x50, 0x78, 0x30, 0x7d, 0xb4, 0xe7, 0x5a, 0xa2, 0x28, 0x3e, 0xcb, 0xcf, 0x65, 0x5e, - 0x30, 0xf9, 0x96, 0x01, 0x65, 0x9d, 0xf7, 0xa3, 0x8e, 0xe7, 0x5b, 0xda, 0x78, 0x3e, 0x95, 0x3d, - 0x9e, 0xfd, 0x07, 0xb2, 0x27, 0x3b, 0xf9, 0x40, 0x03, 0x68, 0xc2, 0xf0, 0x82, 0xdf, 0x72, 0xbc, - 0xb6, 0x9a, 0xd8, 0xda, 0x45, 0x88, 0x25, 0x4a, 0x94, 0xde, 0xca, 0xf7, 0xed, 0x2d, 0xf3, 0xe7, - 0x0b, 0x70, 0xce, 0xa2, 0x3b, 0x1e, 0xb3, 0xaa, 0xee, 0x85, 0x5e, 0x7b, 0x47, 0xbb, 0xfe, 0x63, - 0xa6, 0x3a, 0x5c, 0x24, 0x3d, 0x60, 0x90, 0xb8, 0xbf, 0x5f, 0x82, 0x22, 0x53, 0xed, 0x4a, 0x9f, - 0xa3, 0x87, 0x1c, 0xdf, 0x85, 0xe0, 0xc2, 0x20, 0x8b, 0xc9, 0x15, 0xb1, 0xf0, 0x28, 0x69, 0x69, - 0xd8, 0xc2, 0xf3, 0xa3, 0x83, 0x0a, 0xf0, 0x57, 0x7c, 0x59, 0xa9, 0x58, 0x7c, 0x62, 0x4b, 0xac, - 0xd0, 0xc7, 0x12, 0xbb, 0x0b, 0x33, 0x55, 0x97, 0x2b, 0x35, 0xa7, 0xb9, 0x16, 0x78, 0xed, 0x86, - 0xd7, 0x71, 0x9a, 0x72, 0x77, 0x81, 0xe7, 0x24, 0x4e, 0x5c, 0x6e, 0x77, 0x62, 0x04, 0x2b, 0x93, - 0x8c, 0x35, 0x63, 0x61, 0xa5, 0xce, 0xd3, 0xfe, 0xf3, 0xc3, 0x0f, 0x6c, 0x86, 0xdb, 0x0e, 0x79, - 0xde, 0x7f, 0x2b, 0x2e, 0x46, 0x1b, 0x10, 0x4f, 0x63, 0xd7, 0x97, 0xeb, 0x49, 0x14, 0x34, 0xbf, - 0x35, 0xcf, 0x4f, 0x6c, 0xa3, 0x66, 0x88, 0xa7, 0xb6, 0x1a, 0x5e, 0x42, 0x57, 0xaf, 0xdf, 0x66, - 0x74, 0xc5, 0x1e, 0xba, 0x30, 0xdc, 0x55, 0xe9, 0x38, 0x1e, 0xb9, 0x06, 0xc0, 0xef, 0x1d, 0xa3, - 0x40, 0x8c, 0x26, 0x16, 0x63, 0x80, 0x50, 0x6e, 0x31, 0x2a, 0x28, 0xe4, 0x4d, 0x98, 0x5e, 0x9c, - 0x9f, 0x93, 0x2e, 0xab, 0x05, 0xbf, 0xd1, 0x6d, 0xd1, 0x76, 0x84, 0x87, 0xa6, 0x25, 0x3e, 0x86, - 0xb4, 0x31, 0xc7, 0xa4, 0x20, 0x0b, 0x4d, 0x24, 0x72, 0xe2, 0x69, 0x00, 0xe7, 0x7d, 0x97, 0x86, - 0x1b, 0xd7, 0x3f, 0x61, 0x89, 0x9c, 0x94, 0xb6, 0xe1, 0x6c, 0xbb, 0x9e, 0x39, 0x33, 0xff, 0x06, - 0x26, 0x72, 0xea, 0xc1, 0x25, 0x3f, 0x06, 0x43, 0xf8, 0x53, 0x2c, 0xd3, 0xd3, 0x19, 0x6c, 0x93, - 0x25, 0xba, 0xc1, 0x13, 0xa9, 0x23, 0x01, 0x59, 0x4a, 0xde, 0x48, 0x3f, 0x41, 0x3a, 0x12, 0x91, - 0x4b, 0x54, 0x7b, 0x19, 0xdd, 0x74, 0xa1, 0xa4, 0x56, 0xc8, 0x64, 0xe4, 0xb6, 0x13, 0xee, 0x52, - 0x97, 0xfd, 0x12, 0x99, 0xc4, 0x50, 0x46, 0x76, 0x11, 0x6a, 0xb3, 0xef, 0xb0, 0x14, 0x14, 0xa6, - 0x1d, 0x96, 0xc2, 0x7b, 0xa1, 0xf8, 0x14, 0xb1, 0x75, 0xf2, 0x70, 0x1b, 0xee, 0x5a, 0xa2, 0x08, - 0xb5, 0xa5, 0x3c, 0x22, 0x0b, 0x9c, 0xc6, 0x1e, 0x0d, 0x36, 0xae, 0x7f, 0x1c, 0xda, 0x52, 0xaf, - 0xe3, 0x88, 0x31, 0xf9, 0x3a, 0xc4, 0xef, 0x00, 0x68, 0xc8, 0xcc, 0xb0, 0x4c, 0x2e, 0x51, 0x1a, - 0x89, 0x61, 0x99, 0x5c, 0xa2, 0x54, 0x0d, 0xcb, 0x18, 0x35, 0x7e, 0x88, 0x34, 0x77, 0xcc, 0x43, - 0xa4, 0x7d, 0x1e, 0x5d, 0x96, 0xf9, 0x37, 0x3e, 0x41, 0xcf, 0xe3, 0x7f, 0x16, 0x4a, 0xd5, 0x28, - 0x72, 0x1a, 0xbb, 0xd4, 0xc5, 0x07, 0x6f, 0x95, 0x6b, 0x5c, 0x8e, 0x80, 0xab, 0xce, 0x58, 0x15, - 0x97, 0xbc, 0x02, 0xc3, 0xda, 0x7b, 0xf8, 0x68, 0x4e, 0xf4, 0xbc, 0x83, 0x2f, 0x70, 0xd8, 0x26, - 0x6a, 0xa9, 0x7d, 0xdf, 0x63, 0x7d, 0x52, 0x4c, 0xf2, 0x78, 0x7b, 0x1c, 0xa4, 0x6a, 0x0d, 0x81, - 0x45, 0x5e, 0x57, 0xcc, 0x8e, 0xd1, 0xc4, 0xfe, 0xe7, 0x7b, 0x33, 0x5b, 0x5a, 0x1f, 0xaa, 0x49, - 0x11, 0xdb, 0x21, 0x37, 0x61, 0x44, 0x6e, 0xb9, 0x21, 0xb1, 0xf9, 0x05, 0x65, 0xfa, 0x56, 0xc1, - 0xbe, 0x25, 0x91, 0x31, 0x85, 0xae, 0x92, 0xea, 0x6b, 0x4c, 0x49, 0xa1, 0xab, 0xa4, 0xfa, 0xd2, - 0x52, 0xe8, 0x2a, 0x49, 0xbf, 0xe2, 0x1d, 0x54, 0xe9, 0xd8, 0x1d, 0xd4, 0x06, 0x94, 0xd6, 0x9c, - 0x20, 0xf2, 0xd8, 0x72, 0xd4, 0x8e, 0xf8, 0xe3, 0x31, 0xc9, 0x06, 0x5f, 0x29, 0x4a, 0xde, 0x4c, - 0xef, 0x28, 0xf8, 0x7a, 0x0e, 0xd2, 0x04, 0x9e, 0x1d, 0x5a, 0x32, 0xf1, 0x28, 0xa1, 0x25, 0xc5, - 0xf8, 0xc9, 0xb4, 0xc9, 0x24, 0x90, 0x27, 0x7e, 0x07, 0x2d, 0xdd, 0xfb, 0xb8, 0xe3, 0xfc, 0x12, - 0x94, 0xd8, 0xff, 0xf8, 0xa0, 0x85, 0x47, 0xf9, 0xe3, 0x30, 0x49, 0x72, 0x00, 0x7d, 0x42, 0xf3, - 0x57, 0x2f, 0xea, 0x34, 0xe2, 0x13, 0x18, 0x19, 0xa7, 0xbd, 0x35, 0x1a, 0x37, 0xf2, 0x0e, 0x94, - 0xd4, 0x97, 0x78, 0x66, 0xa7, 0x92, 0xe0, 0x20, 0x57, 0xc0, 0xd3, 0xa3, 0xa4, 0x11, 0xb0, 0xf5, - 0xab, 0xda, 0xe9, 0x20, 0x2d, 0x51, 0xa4, 0xbd, 0xd3, 0x49, 0x93, 0x49, 0x34, 0xf2, 0x39, 0x28, - 0x55, 0x3b, 0x9d, 0x44, 0xe3, 0x4c, 0x2b, 0xfb, 0xc8, 0x4e, 0xc7, 0xce, 0xd4, 0x3a, 0x1a, 0x05, - 0x13, 0x2c, 0x61, 0xf0, 0x61, 0xbd, 0x33, 0x89, 0x60, 0xc9, 0xf7, 0x65, 0xd2, 0x82, 0xa5, 0xa0, - 0x9b, 0x3f, 0x34, 0xe0, 0x6c, 0x9f, 0x6e, 0xc3, 0xbd, 0x78, 0xe2, 0x2d, 0xe7, 0x7b, 0x71, 0x9d, - 0x55, 0x41, 0x24, 0x38, 0x1b, 0xd1, 0x8d, 0x7f, 0x9c, 0x7e, 0x62, 0x0d, 0x56, 0x1b, 0x2d, 0x57, - 0xe3, 0xec, 0x97, 0x6c, 0xf2, 0x1f, 0xdb, 0x4b, 0x36, 0xe6, 0x81, 0x01, 0x63, 0x8a, 0x30, 0x3f, - 0xc6, 0x37, 0xf4, 0x2f, 0x89, 0x27, 0xdd, 0xf2, 0x09, 0x5e, 0x2b, 0xe5, 0xaf, 0xc0, 0x27, 0xdc, - 0x3e, 0x00, 0x58, 0x76, 0xc2, 0xa8, 0xda, 0x88, 0xbc, 0xfb, 0x74, 0x00, 0xcd, 0x9d, 0xa4, 0x91, - 0x76, 0xf0, 0x29, 0x4e, 0x46, 0xd6, 0x93, 0x46, 0x3a, 0x66, 0x68, 0xae, 0xc0, 0x70, 0xdd, 0x0f, - 0xa2, 0xda, 0x3e, 0x5f, 0x8e, 0x17, 0x68, 0xd8, 0x50, 0x3d, 0x99, 0x1e, 0xfa, 0x34, 0x1a, 0x96, - 0x28, 0x62, 0x36, 0xf1, 0x2d, 0x8f, 0x36, 0x5d, 0x35, 0xc2, 0x64, 0x9b, 0x01, 0x2c, 0x0e, 0xbf, - 0xf2, 0x0e, 0x4c, 0x4a, 0xc1, 0x5e, 0x5f, 0xae, 0x63, 0x0b, 0x26, 0x61, 0x6c, 0x63, 0xd1, 0x5a, - 0xba, 0xf5, 0x05, 0xfb, 0xd6, 0xbd, 0xe5, 0xe5, 0xf2, 0x29, 0x32, 0x0e, 0xa3, 0x02, 0x30, 0x5f, - 0x2d, 0x1b, 0xa4, 0x04, 0xc5, 0xa5, 0x95, 0xfa, 0xe2, 0xfc, 0x3d, 0x6b, 0xb1, 0x9c, 0xbb, 0xf2, - 0x02, 0x4c, 0x24, 0x61, 0xc6, 0x78, 0xb0, 0x33, 0x02, 0x79, 0xab, 0xba, 0x59, 0x3e, 0x45, 0x00, - 0x86, 0xd7, 0xee, 0xcc, 0xd7, 0xaf, 0x5f, 0x2f, 0x1b, 0x57, 0x3e, 0x05, 0x53, 0xb8, 0x59, 0x5b, - 0x66, 0xfb, 0x86, 0x36, 0x0d, 0xb0, 0xa6, 0x12, 0x14, 0xeb, 0xb4, 0xe3, 0x04, 0x4e, 0x44, 0x79, - 0x35, 0x77, 0xbb, 0xcd, 0xc8, 0xeb, 0x34, 0xe9, 0xc3, 0xb2, 0x71, 0xe5, 0x75, 0x98, 0xb4, 0xfc, - 0x6e, 0xe4, 0xb5, 0x77, 0xe4, 0x23, 0xa4, 0xe4, 0x34, 0x4c, 0xdd, 0x5b, 0xa9, 0xde, 0xad, 0x2d, - 0xbd, 0x7b, 0x6f, 0xf5, 0x5e, 0xdd, 0xbe, 0x5b, 0x5d, 0x9f, 0xbf, 0x5d, 0x3e, 0xc5, 0x3e, 0xf8, - 0xee, 0x6a, 0x7d, 0xdd, 0xb6, 0x16, 0xe7, 0x17, 0x57, 0xd6, 0xcb, 0xc6, 0x95, 0x9f, 0x35, 0x60, - 0x82, 0x0d, 0x1a, 0x9a, 0xfd, 0xf7, 0xd0, 0x9b, 0x76, 0x11, 0x2e, 0xdc, 0xab, 0x2f, 0x5a, 0xf6, - 0xfa, 0xea, 0x9d, 0xc5, 0x15, 0xfb, 0x5e, 0xbd, 0xfa, 0xee, 0xa2, 0x7d, 0x6f, 0xa5, 0xbe, 0xb6, - 0x38, 0xbf, 0x74, 0x6b, 0x69, 0x71, 0xa1, 0x7c, 0x8a, 0x54, 0xe0, 0x29, 0x05, 0xc3, 0x5a, 0x9c, - 0x5f, 0xdd, 0x58, 0xb4, 0xec, 0xb5, 0x6a, 0xbd, 0xbe, 0xb9, 0x6a, 0x2d, 0x94, 0x0d, 0x72, 0x1e, - 0xce, 0x64, 0x20, 0xdc, 0xbd, 0x55, 0x2d, 0xe7, 0x7a, 0xca, 0x56, 0x16, 0x37, 0xab, 0xcb, 0x76, - 0x6d, 0x75, 0xbd, 0x9c, 0xbf, 0xf2, 0x0e, 0x33, 0xbc, 0xc4, 0x6b, 0xaa, 0x6c, 0x61, 0x2f, 0x42, - 0x61, 0x65, 0x75, 0x65, 0xb1, 0x7c, 0x8a, 0x8c, 0xc1, 0xc8, 0xda, 0xe2, 0xca, 0xc2, 0xd2, 0xca, - 0xbb, 0xbc, 0x5b, 0xab, 0x6b, 0x6b, 0xd6, 0xea, 0xc6, 0xe2, 0x42, 0x39, 0xc7, 0xfa, 0x6e, 0x61, - 0x71, 0x85, 0x7d, 0x59, 0xfe, 0x8a, 0xc9, 0x1f, 0xf9, 0xd5, 0x9e, 0x0e, 0x64, 0xbd, 0xb5, 0xf8, - 0xf9, 0xf5, 0xc5, 0x95, 0xfa, 0xd2, 0xea, 0x4a, 0xf9, 0xd4, 0x95, 0x0b, 0x29, 0x1c, 0x39, 0x12, - 0xf5, 0xfa, 0xed, 0xf2, 0xa9, 0x2b, 0x5f, 0x82, 0x92, 0x6a, 0x77, 0x90, 0xb3, 0x30, 0xad, 0xfe, - 0x5e, 0xa3, 0x6d, 0xd7, 0x6b, 0xef, 0x94, 0x4f, 0xa5, 0x0b, 0xac, 0x6e, 0xbb, 0xcd, 0x0a, 0xb0, - 0xf1, 0x6a, 0xc1, 0x3a, 0x0d, 0x5a, 0x5e, 0x9b, 0x99, 0x14, 0xe5, 0x5c, 0xad, 0xfc, 0xbd, 0x3f, - 0x7e, 0xe6, 0xd4, 0xf7, 0x7e, 0xf0, 0x8c, 0xf1, 0x47, 0x3f, 0x78, 0xc6, 0xf8, 0x6f, 0x3f, 0x78, - 0xc6, 0xd8, 0x1a, 0x46, 0x41, 0xbf, 0xf1, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x71, 0x46, 0xf4, - 0x45, 0xba, 0xdc, 0x00, 0x00, + // 14074 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7f, 0x6c, 0x1c, 0x49, + 0x76, 0x18, 0xac, 0x9e, 0x19, 0x92, 0xc3, 0xc7, 0x21, 0x39, 0x2c, 0x52, 0x12, 0xa5, 0xd5, 0xee, + 0x68, 0x7b, 0x77, 0xb5, 0x5a, 0xed, 0xae, 0x74, 0xa2, 0x6e, 0x75, 0xde, 0xdb, 0x5f, 0x37, 0x43, + 0x52, 0x2b, 0xae, 0x28, 0x92, 0xdb, 0x43, 0x52, 0x77, 0xbe, 0x1f, 0x7d, 0xcd, 0xe9, 0x22, 0xd9, + 0xcb, 0x99, 0xe9, 0xb9, 0xee, 0x1e, 0x49, 0xf4, 0xd9, 0xb0, 0x8d, 0xef, 0xbb, 0xef, 0x70, 0x30, + 0x7c, 0xe7, 0x33, 0xce, 0x9f, 0xed, 0xc0, 0x81, 0x1d, 0x23, 0x0e, 0xe2, 0x04, 0x36, 0x10, 0x3b, + 0x41, 0x62, 0x04, 0x48, 0x62, 0x20, 0x30, 0x2e, 0xbf, 0x10, 0xff, 0x17, 0xe4, 0x92, 0x30, 0xf1, + 0x5d, 0xfe, 0x22, 0x60, 0x20, 0x81, 0x81, 0x00, 0x5e, 0xdb, 0x40, 0x50, 0xaf, 0xaa, 0xba, 0xab, + 0x7a, 0x7a, 0xc8, 0xe1, 0x4a, 0x8b, 0x58, 0x8b, 0xfc, 0x45, 0xce, 0xab, 0xf7, 0x5e, 0x75, 0x55, + 0xbd, 0x7a, 0xf5, 0xea, 0xd5, 0xab, 0x57, 0x30, 0x16, 0xed, 0x77, 0x68, 0x78, 0xb5, 0x13, 0xf8, + 0x91, 0x4f, 0x86, 0xf0, 0xc7, 0xf9, 0x99, 0x1d, 0x7f, 0xc7, 0x47, 0xc8, 0x35, 0xf6, 0x1f, 0x2f, + 0x3c, 0x5f, 0xd9, 0xf1, 0xfd, 0x9d, 0x26, 0xbd, 0x86, 0xbf, 0xb6, 0xba, 0xdb, 0xd7, 0x22, 0xaf, + 0x45, 0xc3, 0xc8, 0x69, 0x75, 0x04, 0xc2, 0xfc, 0x8e, 0x17, 0xed, 0x76, 0xb7, 0xae, 0x36, 0xfc, + 0xd6, 0xb5, 0x9d, 0xc0, 0xb9, 0xef, 0x45, 0x4e, 0xe4, 0xf9, 0x6d, 0xa7, 0x79, 0x2d, 0xa2, 0x4d, + 0xda, 0xf1, 0x83, 0xe8, 0x9a, 0xd3, 0xf1, 0xae, 0x61, 0x1d, 0xd7, 0x1e, 0x04, 0x4e, 0xa7, 0x43, + 0x83, 0xe4, 0x1f, 0xce, 0xc4, 0xfc, 0x5b, 0x79, 0x18, 0xbd, 0x43, 0x69, 0xa7, 0xda, 0xf4, 0xee, + 0x53, 0xf2, 0x1c, 0x14, 0x56, 0x9c, 0x16, 0x9d, 0x35, 0x2e, 0x1a, 0x97, 0x47, 0x6b, 0x93, 0x87, + 0x07, 0x95, 0xb1, 0x90, 0x06, 0xf7, 0x69, 0x60, 0xb7, 0x9d, 0x16, 0xb5, 0xb0, 0x90, 0xbc, 0x0c, + 0xa3, 0xec, 0x6f, 0xd8, 0x71, 0x1a, 0x74, 0x36, 0x87, 0x98, 0xe3, 0x87, 0x07, 0x95, 0xd1, 0xb6, + 0x04, 0x5a, 0x49, 0x39, 0xb9, 0x04, 0x23, 0xcb, 0xd4, 0x09, 0xe9, 0xd2, 0xc2, 0x6c, 0xfe, 0xa2, + 0x71, 0x39, 0x5f, 0x2b, 0x1d, 0x1e, 0x54, 0x8a, 0x4d, 0x06, 0xb2, 0x3d, 0xd7, 0x92, 0x85, 0x64, + 0x09, 0x46, 0x16, 0x1f, 0x76, 0xbc, 0x80, 0x86, 0xb3, 0x85, 0x8b, 0xc6, 0xe5, 0xb1, 0xb9, 0xf3, + 0x57, 0x79, 0xfb, 0xaf, 0xca, 0xf6, 0x5f, 0x5d, 0x97, 0xed, 0xaf, 0x4d, 0x7f, 0xff, 0xa0, 0x72, + 0xea, 0xf0, 0xa0, 0x32, 0x42, 0x39, 0xc9, 0x2f, 0xfc, 0xd7, 0x8a, 0x61, 0x49, 0x7a, 0xf2, 0x26, + 0x14, 0xd6, 0xf7, 0x3b, 0x74, 0x76, 0xf4, 0xa2, 0x71, 0x79, 0x62, 0xee, 0x99, 0xab, 0xbc, 0xc7, + 0xe3, 0x46, 0x26, 0xff, 0x31, 0xac, 0x5a, 0xf1, 0xf0, 0xa0, 0x52, 0x60, 0x28, 0x16, 0x52, 0x91, + 0x57, 0x61, 0xf8, 0xb6, 0x1f, 0x46, 0x4b, 0x0b, 0xb3, 0x80, 0x4d, 0x3b, 0x7d, 0x78, 0x50, 0x99, + 0xda, 0xf5, 0xc3, 0xc8, 0xf6, 0xdc, 0x57, 0xfc, 0x96, 0x17, 0xd1, 0x56, 0x27, 0xda, 0xb7, 0x04, + 0x92, 0xb9, 0x05, 0xe3, 0x1a, 0x3f, 0x32, 0x06, 0x23, 0x1b, 0x2b, 0x77, 0x56, 0x56, 0xef, 0xad, + 0x94, 0x4f, 0x91, 0x22, 0x14, 0x56, 0x56, 0x17, 0x16, 0xcb, 0x06, 0x19, 0x81, 0x7c, 0x75, 0x6d, + 0xad, 0x9c, 0x23, 0x25, 0x28, 0x2e, 0x54, 0xd7, 0xab, 0xb5, 0x6a, 0x7d, 0xb1, 0x9c, 0x27, 0xd3, + 0x30, 0x79, 0x6f, 0x69, 0x65, 0x61, 0xf5, 0x5e, 0xdd, 0x5e, 0x58, 0xac, 0xdf, 0x59, 0x5f, 0x5d, + 0x2b, 0x17, 0xc8, 0x04, 0xc0, 0x9d, 0x8d, 0xda, 0xa2, 0xb5, 0xb2, 0xb8, 0xbe, 0x58, 0x2f, 0x0f, + 0x99, 0xdf, 0xcc, 0x43, 0xf1, 0x2e, 0x8d, 0x1c, 0xd7, 0x89, 0x1c, 0x72, 0x41, 0x1b, 0x22, 0xfc, + 0x7a, 0x65, 0x6c, 0x9e, 0xeb, 0x1d, 0x9b, 0xa1, 0xc3, 0x83, 0x8a, 0xf1, 0xaa, 0x3a, 0x26, 0x6f, + 0xc0, 0xd8, 0x02, 0x0d, 0x1b, 0x81, 0xd7, 0x61, 0xf2, 0x82, 0xe3, 0x32, 0x5a, 0x3b, 0x77, 0x78, + 0x50, 0x39, 0xed, 0x26, 0x60, 0xa5, 0xad, 0x2a, 0x36, 0x59, 0x82, 0xe1, 0x65, 0x67, 0x8b, 0x36, + 0xc3, 0xd9, 0xa1, 0x8b, 0xf9, 0xcb, 0x63, 0x73, 0x4f, 0x89, 0xfe, 0x95, 0x1f, 0x78, 0x95, 0x97, + 0x2e, 0xb6, 0xa3, 0x60, 0xbf, 0x36, 0x73, 0x78, 0x50, 0x29, 0x37, 0x11, 0xa0, 0xf6, 0x1d, 0x47, + 0x21, 0xf5, 0x64, 0xcc, 0x87, 0x8f, 0x1d, 0xf3, 0xa7, 0xbf, 0x7f, 0x50, 0x31, 0xd8, 0x58, 0x88, + 0x31, 0x4f, 0xf8, 0xe9, 0xa3, 0x7f, 0x11, 0x72, 0x4b, 0x0b, 0xb3, 0x23, 0x28, 0x6b, 0xe5, 0xc3, + 0x83, 0x4a, 0x49, 0x1b, 0xb6, 0xdc, 0xd2, 0xc2, 0xf9, 0xd7, 0x61, 0x4c, 0xf9, 0x46, 0x52, 0x86, + 0xfc, 0x1e, 0xdd, 0xe7, 0xfd, 0x69, 0xb1, 0x7f, 0xc9, 0x0c, 0x0c, 0xdd, 0x77, 0x9a, 0x5d, 0xd1, + 0x81, 0x16, 0xff, 0xf1, 0xd9, 0xdc, 0x8f, 0x19, 0xe6, 0x2f, 0x16, 0xa0, 0x68, 0xf9, 0x7c, 0x9e, + 0x91, 0x97, 0x60, 0xa8, 0x1e, 0x39, 0x91, 0x1c, 0x8a, 0xe9, 0xc3, 0x83, 0xca, 0x64, 0xc8, 0x00, + 0x4a, 0x7d, 0x1c, 0x83, 0xa1, 0xae, 0xed, 0x3a, 0xa1, 0x1c, 0x12, 0x44, 0xed, 0x30, 0x80, 0x8a, + 0x8a, 0x18, 0xe4, 0x12, 0x14, 0xee, 0xfa, 0x2e, 0x15, 0xa3, 0x42, 0x0e, 0x0f, 0x2a, 0x13, 0x2d, + 0xdf, 0x55, 0x11, 0xb1, 0x9c, 0xbc, 0x02, 0xa3, 0xf3, 0xdd, 0x20, 0xa0, 0x6d, 0x26, 0xaa, 0x05, + 0x44, 0x9e, 0x38, 0x3c, 0xa8, 0x40, 0x83, 0x03, 0xd9, 0xe4, 0x4a, 0x10, 0x58, 0x57, 0xd7, 0x23, + 0x27, 0x88, 0xa8, 0x3b, 0x3b, 0x34, 0x50, 0x57, 0xb3, 0xe9, 0x35, 0x15, 0x72, 0x92, 0x74, 0x57, + 0x0b, 0x4e, 0xe4, 0x36, 0x8c, 0xbd, 0x1b, 0x38, 0x0d, 0xba, 0x46, 0x03, 0xcf, 0x77, 0x71, 0x0c, + 0xf3, 0xb5, 0x4b, 0x87, 0x07, 0x95, 0x33, 0x3b, 0x0c, 0x6c, 0x77, 0x10, 0x9e, 0x50, 0x7f, 0x78, + 0x50, 0x29, 0x2e, 0x74, 0x03, 0xec, 0x3d, 0x4b, 0x25, 0x25, 0x5f, 0x65, 0x43, 0x12, 0x46, 0xd8, + 0xb5, 0xd4, 0xc5, 0xd1, 0x3b, 0xfa, 0x13, 0x4d, 0xf1, 0x89, 0x67, 0x9a, 0x4e, 0x18, 0xd9, 0x01, + 0xa7, 0x4b, 0x7d, 0xa7, 0xca, 0x92, 0xac, 0x42, 0xb1, 0xde, 0xd8, 0xa5, 0x6e, 0xb7, 0x49, 0x67, + 0x8b, 0xc8, 0xfe, 0xac, 0x10, 0x5c, 0x39, 0x9e, 0xb2, 0xb8, 0x76, 0x5e, 0xf0, 0x26, 0xa1, 0x80, + 0x28, 0x7d, 0x1f, 0x33, 0xf9, 0x6c, 0xf1, 0x57, 0x7e, 0xa3, 0x72, 0xea, 0x67, 0xfe, 0xf3, 0xc5, + 0x53, 0xe6, 0x3f, 0xce, 0x41, 0x39, 0xcd, 0x84, 0x6c, 0xc3, 0xf8, 0x46, 0xc7, 0x75, 0x22, 0x3a, + 0xdf, 0xf4, 0x68, 0x3b, 0x0a, 0x51, 0x48, 0x8e, 0x6e, 0xd3, 0xf3, 0xa2, 0xde, 0xd9, 0x2e, 0x12, + 0xda, 0x0d, 0x4e, 0x99, 0x6a, 0x95, 0xce, 0x36, 0xa9, 0xa7, 0x8e, 0x7a, 0x3a, 0x44, 0x09, 0x3b, + 0x59, 0x3d, 0x5c, 0xc3, 0xf7, 0xa9, 0x47, 0xb0, 0x15, 0x02, 0xd4, 0x76, 0xb7, 0xf6, 0x51, 0x32, + 0x07, 0x17, 0x20, 0x46, 0x92, 0x21, 0x40, 0x0c, 0x6c, 0xfe, 0x77, 0x03, 0x26, 0x2c, 0x1a, 0xfa, + 0xdd, 0xa0, 0x41, 0x6f, 0x53, 0xc7, 0xa5, 0x01, 0x13, 0xff, 0x3b, 0x5e, 0xdb, 0x15, 0x73, 0x0a, + 0xc5, 0x7f, 0xcf, 0x6b, 0xab, 0x53, 0x18, 0xcb, 0xc9, 0xa7, 0x60, 0xa4, 0xde, 0xdd, 0x42, 0x54, + 0x3e, 0xa7, 0xce, 0xe0, 0x88, 0x75, 0xb7, 0xec, 0x14, 0xba, 0x44, 0x23, 0xd7, 0x60, 0x64, 0x93, + 0x06, 0x61, 0xa2, 0xf1, 0x50, 0xb3, 0xdf, 0xe7, 0x20, 0x95, 0x40, 0x60, 0x91, 0x77, 0x13, 0xad, + 0x2b, 0xd6, 0xa4, 0xc9, 0x94, 0xae, 0x4b, 0x44, 0xa5, 0x25, 0x20, 0xaa, 0xa8, 0x48, 0x2c, 0xf3, + 0xbb, 0x39, 0x28, 0x2f, 0x38, 0x91, 0xb3, 0xe5, 0x84, 0xa2, 0x3f, 0x37, 0x6f, 0x30, 0x3d, 0xae, + 0x34, 0x14, 0xf5, 0x38, 0xfb, 0xf2, 0x8f, 0xdc, 0xbc, 0x17, 0xd2, 0xcd, 0x1b, 0x63, 0x0b, 0xa4, + 0x68, 0x5e, 0xd2, 0xa8, 0xb7, 0x8e, 0x6f, 0x54, 0x59, 0x34, 0xaa, 0x28, 0x1b, 0x95, 0x34, 0x85, + 0xbc, 0x05, 0x85, 0x7a, 0x87, 0x36, 0x84, 0x12, 0x91, 0xba, 0x5f, 0x6f, 0x1c, 0x43, 0xd8, 0xbc, + 0x51, 0x2b, 0x09, 0x36, 0x85, 0xb0, 0x43, 0x1b, 0x16, 0x92, 0x29, 0x93, 0xe6, 0x5f, 0x0d, 0xc3, + 0x4c, 0x16, 0x19, 0x79, 0x4b, 0x5f, 0x9c, 0x78, 0xf7, 0x3c, 0xd5, 0x77, 0x71, 0x9a, 0x35, 0xf4, + 0xe5, 0xe9, 0x0a, 0x14, 0xd7, 0x98, 0x40, 0x36, 0xfc, 0xa6, 0xe8, 0x39, 0xa6, 0x15, 0x8b, 0x1d, + 0x09, 0x33, 0xac, 0xb8, 0x9c, 0x3c, 0x05, 0xf9, 0x0d, 0x6b, 0x49, 0x74, 0xd7, 0xe8, 0xe1, 0x41, + 0x25, 0xdf, 0x0d, 0xbc, 0x59, 0xc3, 0x62, 0x50, 0x72, 0x0d, 0x86, 0xe7, 0xab, 0xf3, 0x34, 0x88, + 0xb0, 0x9b, 0x4a, 0xb5, 0xb3, 0x4c, 0x5a, 0x1a, 0x8e, 0xdd, 0xa0, 0x41, 0xa4, 0x55, 0x2f, 0xd0, + 0xc8, 0xcb, 0x90, 0xaf, 0xde, 0xab, 0x8b, 0x9e, 0x01, 0xd1, 0x33, 0xd5, 0x7b, 0xf5, 0xda, 0xb8, + 0xe8, 0x88, 0xbc, 0xf3, 0x20, 0x64, 0xdc, 0xab, 0xf7, 0xea, 0xea, 0x68, 0x0d, 0x1f, 0x31, 0x5a, + 0x97, 0xa1, 0xc8, 0xec, 0x0c, 0xb6, 0xc0, 0xa3, 0x52, 0x1c, 0xe5, 0xe6, 0xd3, 0xae, 0x80, 0x59, + 0x71, 0x29, 0x79, 0x2e, 0x36, 0x5b, 0x8a, 0x09, 0x3f, 0x61, 0xb6, 0x48, 0x63, 0x85, 0x3c, 0x84, + 0xf1, 0x85, 0xfd, 0xb6, 0xd3, 0xf2, 0x1a, 0x62, 0x09, 0x1f, 0xc5, 0x25, 0xfc, 0xea, 0x11, 0xc3, + 0x78, 0x55, 0x23, 0xe0, 0xab, 0xba, 0x54, 0xbe, 0xb3, 0x2e, 0x2f, 0xb3, 0xd3, 0x2b, 0xfc, 0xac, + 0x61, 0xe9, 0x15, 0xb1, 0xb9, 0x24, 0x55, 0x24, 0xda, 0x55, 0x89, 0xd8, 0x49, 0x70, 0x32, 0x97, + 0x02, 0x01, 0x51, 0xe7, 0x52, 0xbc, 0xe8, 0xbe, 0x05, 0xf9, 0x77, 0xe7, 0xd7, 0x66, 0xc7, 0x90, + 0x07, 0x11, 0x3c, 0xde, 0x9d, 0x5f, 0x9b, 0x6f, 0xfa, 0x5d, 0xb7, 0xfe, 0xfe, 0x72, 0xed, 0xac, + 0x60, 0x33, 0xbe, 0xd3, 0xe8, 0x68, 0x5f, 0xc4, 0xe8, 0xc8, 0x22, 0x14, 0x65, 0x2b, 0x67, 0x4b, + 0xc8, 0x63, 0x2a, 0xd5, 0xf8, 0xcd, 0x1b, 0x7c, 0xae, 0xb9, 0xe2, 0xb7, 0xfa, 0x15, 0x12, 0x87, + 0xdc, 0x40, 0x29, 0x7b, 0xb8, 0xbf, 0xb4, 0x10, 0xce, 0x8e, 0x5f, 0xcc, 0x5f, 0x1e, 0x45, 0xf1, + 0x98, 0xee, 0x30, 0x98, 0xed, 0xb9, 0xaa, 0xb1, 0x13, 0x23, 0x9e, 0xbf, 0x07, 0xa4, 0xb7, 0x33, + 0x33, 0xcc, 0x8f, 0x97, 0x55, 0xf3, 0x63, 0x6c, 0xee, 0xb4, 0xf8, 0xc0, 0x79, 0xbf, 0xd5, 0x72, + 0xda, 0x2e, 0xd2, 0x6e, 0xce, 0xa9, 0x56, 0x49, 0x15, 0x26, 0x92, 0xaf, 0x5f, 0xf6, 0xc2, 0x88, + 0x5c, 0x83, 0x51, 0x09, 0x61, 0x2b, 0x4f, 0x3e, 0xb3, 0x9d, 0x56, 0x82, 0x63, 0xfe, 0x51, 0x0e, + 0x20, 0x29, 0x79, 0x42, 0x95, 0xd3, 0x67, 0x34, 0xe5, 0x74, 0x3a, 0x2d, 0xd5, 0x7d, 0xd5, 0x12, + 0x79, 0x07, 0x86, 0x99, 0x9d, 0xd6, 0x95, 0x76, 0xe8, 0xd9, 0x34, 0x29, 0x16, 0x6e, 0xde, 0xa8, + 0x4d, 0x08, 0xe2, 0xe1, 0x10, 0x21, 0x96, 0x20, 0x53, 0xf4, 0xda, 0xef, 0x0d, 0x25, 0x83, 0x21, + 0x34, 0xda, 0x65, 0x45, 0x25, 0x19, 0xc9, 0x24, 0x96, 0x2a, 0x49, 0x51, 0x48, 0xe7, 0xb8, 0x42, + 0xe2, 0x9d, 0x3a, 0x22, 0x14, 0x52, 0x5a, 0x1d, 0xf1, 0x0e, 0x3c, 0x56, 0x1d, 0x75, 0xd2, 0x73, + 0xbd, 0x80, 0x62, 0x70, 0x39, 0xb3, 0x57, 0xb2, 0x66, 0xf9, 0xc5, 0xe3, 0x66, 0x79, 0x7a, 0x8e, + 0xdf, 0xe8, 0xa7, 0x00, 0x4f, 0xcb, 0x29, 0xe9, 0x3c, 0x50, 0xc9, 0x51, 0x11, 0xbe, 0xc1, 0xe7, + 0xf3, 0x70, 0xdf, 0xf9, 0x7c, 0x3a, 0x73, 0x3e, 0xf3, 0xd9, 0xfc, 0x06, 0x0c, 0x55, 0x7f, 0xa2, + 0x1b, 0x50, 0x61, 0x30, 0x96, 0x64, 0x9d, 0x0c, 0x16, 0x2b, 0x82, 0x49, 0x87, 0xfd, 0x54, 0x0d, + 0x6d, 0x2c, 0x67, 0x35, 0xaf, 0x2f, 0xd7, 0x85, 0x31, 0x48, 0x52, 0xdd, 0xb2, 0xbe, 0xac, 0x7c, + 0x76, 0xa4, 0xb5, 0x9a, 0x51, 0x91, 0x6b, 0x90, 0xab, 0x2e, 0xe0, 0x0e, 0x73, 0x6c, 0x6e, 0x54, + 0x56, 0xbb, 0x50, 0x9b, 0x11, 0x24, 0x25, 0x47, 0xdb, 0x74, 0x54, 0x17, 0x48, 0x0d, 0x86, 0xee, + 0xee, 0xd7, 0xdf, 0x5f, 0x16, 0xda, 0x6f, 0x5a, 0xca, 0x35, 0x83, 0xad, 0xe2, 0xd2, 0x15, 0x26, + 0x5f, 0xdc, 0xda, 0x0f, 0xbf, 0xd6, 0x54, 0xbf, 0x18, 0xd1, 0x3e, 0x3e, 0x05, 0xf2, 0x3f, 0x0d, + 0xc5, 0x40, 0x11, 0xb2, 0xce, 0x36, 0xc2, 0x42, 0xe2, 0x8c, 0xc4, 0x5c, 0xea, 0x91, 0xb8, 0x58, + 0xde, 0x5e, 0xe2, 0xa3, 0x9f, 0xeb, 0x19, 0xfd, 0x31, 0x65, 0xf9, 0xe3, 0x63, 0x1e, 0xf7, 0x45, + 0xfe, 0x23, 0xf7, 0x05, 0x79, 0x07, 0x4a, 0x77, 0x9d, 0xb6, 0xb3, 0x43, 0xdd, 0x8d, 0x90, 0x99, + 0xbd, 0x05, 0xd4, 0xc2, 0xcc, 0x4e, 0x38, 0xdb, 0xe2, 0x70, 0xbb, 0x1b, 0x6a, 0x56, 0xad, 0xa5, + 0x11, 0x98, 0xff, 0x25, 0x8f, 0x1f, 0x4c, 0x5e, 0x81, 0x61, 0x8b, 0xee, 0x24, 0xa6, 0x06, 0x6e, + 0x59, 0x03, 0x84, 0xa8, 0xad, 0xe4, 0x38, 0xb8, 0x8e, 0x51, 0x37, 0xdc, 0xf5, 0xb6, 0x23, 0xd1, + 0xd4, 0x78, 0x1d, 0x13, 0x60, 0x65, 0x1d, 0x13, 0x10, 0x6d, 0x1d, 0x13, 0x30, 0x36, 0x59, 0xac, + 0x85, 0xba, 0xe8, 0x01, 0xd9, 0x5d, 0xd6, 0x82, 0x22, 0x75, 0x81, 0xb6, 0x8c, 0x30, 0x6c, 0x72, + 0x13, 0x46, 0xab, 0x8d, 0x86, 0xdf, 0x55, 0xf6, 0x7c, 0xb3, 0x87, 0x07, 0x95, 0x19, 0x87, 0x03, + 0x75, 0x0f, 0x45, 0x82, 0x4a, 0xea, 0x30, 0xb6, 0xc8, 0x36, 0x4a, 0xde, 0xbc, 0xd3, 0xd8, 0xa5, + 0x62, 0x86, 0x4a, 0x91, 0x57, 0x4a, 0x62, 0xc3, 0xfd, 0x34, 0x45, 0x60, 0x83, 0x01, 0x55, 0x47, + 0x80, 0x82, 0x4b, 0xd6, 0x61, 0xac, 0x4e, 0x1b, 0x01, 0x8d, 0xea, 0x91, 0x1f, 0xd0, 0xd4, 0x0c, + 0x56, 0x4a, 0x6a, 0xcf, 0xc8, 0xbd, 0x5a, 0x88, 0x40, 0x3b, 0x64, 0x50, 0x95, 0xab, 0x82, 0xcc, + 0x8d, 0xee, 0x96, 0x1f, 0xec, 0x2f, 0xd4, 0xc4, 0xac, 0x4e, 0x96, 0x00, 0x0e, 0x56, 0x8d, 0x6e, + 0x06, 0x71, 0xb7, 0x74, 0xa3, 0x9b, 0x63, 0x99, 0x5f, 0xd7, 0x3e, 0x8f, 0x75, 0xdd, 0x1d, 0xba, + 0xbf, 0x16, 0xd0, 0x6d, 0xef, 0xa1, 0x18, 0x69, 0xec, 0xba, 0x3d, 0xba, 0x6f, 0x77, 0x10, 0xaa, + 0x76, 0x5d, 0x8c, 0x4a, 0x3e, 0x0d, 0xc5, 0x3b, 0x77, 0xeb, 0x77, 0xe8, 0xfe, 0xd2, 0x82, 0xd0, + 0xcb, 0x9c, 0xac, 0x15, 0xda, 0x8c, 0x54, 0xeb, 0xf1, 0x18, 0xd3, 0xac, 0x25, 0x62, 0xc2, 0x6a, + 0x9e, 0x6f, 0x76, 0xc3, 0x88, 0x06, 0x4b, 0x0b, 0x6a, 0xcd, 0x0d, 0x0e, 0x4c, 0x0d, 0x5a, 0x8c, + 0x6a, 0xfe, 0x27, 0x03, 0x45, 0x84, 0xbc, 0x0e, 0xb0, 0xd4, 0x66, 0x1b, 0xa9, 0x06, 0x8d, 0x19, + 0xa0, 0xb3, 0xc6, 0x13, 0x50, 0x9d, 0x83, 0x82, 0xac, 0x57, 0x9d, 0x1b, 0xb8, 0x6a, 0x56, 0xa5, + 0xdc, 0x96, 0x09, 0xbf, 0x9d, 0xa8, 0x32, 0x10, 0xd0, 0x54, 0x95, 0x09, 0x32, 0xb9, 0x04, 0x23, + 0x4b, 0xd5, 0xbb, 0xd5, 0x6e, 0xb4, 0x8b, 0x02, 0x5a, 0xe4, 0x6b, 0x9d, 0xe7, 0xb4, 0x6c, 0xa7, + 0x1b, 0xed, 0x5a, 0xb2, 0xd0, 0xfc, 0xd7, 0x39, 0x4d, 0x26, 0x89, 0x05, 0xc4, 0xa2, 0x9d, 0xa6, + 0xd7, 0x40, 0x33, 0xef, 0xdd, 0xc0, 0xef, 0x76, 0xe2, 0xd6, 0x9a, 0x87, 0x07, 0x95, 0x67, 0x82, + 0xa4, 0xd4, 0xde, 0x61, 0xc5, 0xfa, 0x37, 0x64, 0x50, 0x93, 0xcf, 0x41, 0x89, 0xcd, 0x75, 0xf1, + 0x93, 0x6d, 0x8d, 0x99, 0x8e, 0xb8, 0x80, 0x5b, 0xdf, 0x90, 0x06, 0x31, 0x1b, 0x4d, 0x49, 0xa8, + 0x14, 0xc4, 0x85, 0xd9, 0xf5, 0xc0, 0x69, 0x87, 0x5e, 0xb4, 0xd8, 0x6e, 0x04, 0xfb, 0xa8, 0x9b, + 0x16, 0xdb, 0xce, 0x56, 0x93, 0xba, 0xd8, 0x2d, 0xc5, 0xda, 0xe5, 0xc3, 0x83, 0xca, 0xf3, 0x11, + 0xc7, 0xb1, 0x69, 0x8c, 0x64, 0x53, 0x8e, 0xa5, 0x70, 0xee, 0xcb, 0x89, 0xe9, 0xb2, 0xc5, 0xb6, + 0xdb, 0xf1, 0xbd, 0x76, 0x84, 0x8e, 0xcb, 0x42, 0xbc, 0xe7, 0x39, 0x4b, 0x05, 0xdc, 0x66, 0x73, + 0x40, 0xfd, 0x4c, 0x95, 0xc0, 0xfc, 0x5f, 0x46, 0x32, 0x6b, 0xc8, 0x9b, 0x30, 0x26, 0x46, 0x52, + 0xf1, 0x13, 0x9e, 0x67, 0xf3, 0x4f, 0x0e, 0x3b, 0xdb, 0x30, 0xa8, 0xf3, 0x4f, 0x41, 0x67, 0xb6, + 0x5d, 0x75, 0x7e, 0x19, 0x29, 0x15, 0xdb, 0xce, 0x69, 0x34, 0xd3, 0x54, 0x12, 0x8d, 0x09, 0xcb, + 0xfa, 0x72, 0x5d, 0xef, 0x15, 0x14, 0x96, 0xa8, 0x19, 0x66, 0x74, 0x83, 0x82, 0xfc, 0xe8, 0x0d, + 0xff, 0x19, 0x03, 0xc6, 0x14, 0x63, 0x81, 0x09, 0xfc, 0x5a, 0xe0, 0x7f, 0x40, 0x1b, 0x91, 0x3e, + 0xd7, 0x3a, 0x1c, 0x98, 0x12, 0xf8, 0x18, 0x35, 0x35, 0xc7, 0x72, 0x27, 0x98, 0x63, 0xe6, 0x35, + 0x61, 0x83, 0x90, 0x4b, 0x9a, 0x63, 0x16, 0x3d, 0x17, 0xa9, 0x2e, 0xc3, 0x72, 0xf3, 0xb7, 0x0d, + 0x66, 0x3b, 0x90, 0x6b, 0x00, 0x77, 0xe8, 0x7e, 0xe4, 0x6c, 0xdd, 0xf2, 0x9a, 0x9a, 0xc3, 0x7d, + 0x0f, 0xa1, 0xf6, 0xb6, 0xd7, 0xa4, 0x96, 0x82, 0xc2, 0xf6, 0x1c, 0x77, 0x82, 0xad, 0xd7, 0x10, + 0x3d, 0x17, 0xdb, 0x80, 0xd3, 0x7b, 0xc1, 0xd6, 0x6b, 0x88, 0xac, 0x29, 0x22, 0x81, 0x48, 0x4c, + 0x18, 0x5e, 0xf0, 0x5b, 0x8e, 0x27, 0xed, 0x6e, 0x60, 0xc6, 0xab, 0x8b, 0x10, 0x4b, 0x94, 0x30, + 0xab, 0xb3, 0xbe, 0xb6, 0x22, 0x3a, 0x1f, 0xad, 0xce, 0xb0, 0xd3, 0xb6, 0x18, 0xcc, 0xfc, 0x1d, + 0x03, 0xc6, 0x14, 0x93, 0x88, 0x7c, 0x5a, 0x38, 0x27, 0x0d, 0x74, 0xad, 0x9f, 0xe9, 0x35, 0x9a, + 0x58, 0x29, 0xdf, 0x2f, 0xb4, 0x7c, 0x97, 0x0a, 0x57, 0x65, 0x62, 0x49, 0xe4, 0x06, 0xb1, 0x24, + 0x5e, 0x07, 0xe0, 0x3b, 0x50, 0xec, 0x4e, 0x45, 0xfb, 0x28, 0x47, 0x11, 0xea, 0x60, 0x24, 0xc8, + 0xa6, 0x05, 0x25, 0xd5, 0x8a, 0x20, 0x35, 0x18, 0x17, 0x0e, 0x17, 0xb1, 0xfb, 0xe0, 0xfd, 0x8c, + 0x2a, 0x40, 0x70, 0xeb, 0x75, 0x00, 0xe9, 0x24, 0xe6, 0xcf, 0xe6, 0xa0, 0x28, 0x20, 0x73, 0x4f, + 0xe8, 0xc6, 0xe8, 0x35, 0x6d, 0x63, 0x34, 0x1d, 0xaf, 0xd1, 0xf1, 0x36, 0x7f, 0xee, 0x18, 0x6f, + 0xcd, 0xeb, 0x50, 0x92, 0x5d, 0x80, 0xfb, 0xcb, 0x97, 0x60, 0x44, 0xfa, 0x1b, 0xf9, 0xee, 0x72, + 0x52, 0xe3, 0xb9, 0x39, 0x67, 0xc9, 0x72, 0xf3, 0x2f, 0x86, 0x24, 0x2d, 0xaf, 0x89, 0x75, 0x61, + 0xd5, 0x75, 0x03, 0xb5, 0x0b, 0x1d, 0xd7, 0x0d, 0x2c, 0x84, 0xb2, 0xc1, 0x5f, 0xeb, 0x6e, 0x35, + 0xbd, 0x06, 0xe2, 0x28, 0x33, 0xb1, 0x83, 0x50, 0x9b, 0xa1, 0xaa, 0x83, 0x9f, 0x20, 0x6b, 0xce, + 0x92, 0xfc, 0x91, 0xce, 0x92, 0xaf, 0xc0, 0xe8, 0x7c, 0xcb, 0xd5, 0xf6, 0x45, 0x66, 0x46, 0xa7, + 0x5c, 0x8d, 0x91, 0xf8, 0x8e, 0xe8, 0x82, 0xe8, 0xa3, 0x99, 0x46, 0xcb, 0xed, 0xdd, 0x0d, 0x25, + 0x2c, 0x35, 0x6f, 0xc7, 0xd0, 0xa3, 0x78, 0x3b, 0x6e, 0xc2, 0xe8, 0x46, 0x48, 0xd7, 0xbb, 0xed, + 0x36, 0x6d, 0xa2, 0x85, 0x55, 0xe4, 0xfa, 0xac, 0x1b, 0x52, 0x3b, 0x42, 0xa8, 0xfa, 0x01, 0x31, + 0xaa, 0x2a, 0x56, 0x23, 0x47, 0x88, 0xd5, 0xa7, 0xa1, 0x50, 0xed, 0x74, 0xa4, 0x1b, 0x28, 0x36, + 0xda, 0x3b, 0x1d, 0xb4, 0x82, 0x27, 0x9c, 0x4e, 0x47, 0x77, 0xea, 0x20, 0x36, 0xa1, 0x40, 0xee, + 0x74, 0xb7, 0x68, 0xd0, 0xa6, 0x11, 0x0d, 0xc5, 0xda, 0x11, 0xce, 0x02, 0xf2, 0x98, 0x95, 0xa7, + 0x6d, 0x69, 0x04, 0xae, 0xd5, 0xf7, 0xba, 0x5b, 0xd4, 0x16, 0xcb, 0x90, 0xda, 0x77, 0x19, 0x0c, + 0xd1, 0xc7, 0x42, 0x69, 0x80, 0x72, 0x30, 0x96, 0xe8, 0xbb, 0x0e, 0xa5, 0x41, 0x5a, 0x0a, 0x62, + 0x44, 0xcd, 0x31, 0x53, 0x1a, 0xd4, 0x31, 0x53, 0x87, 0x09, 0x7d, 0xa4, 0x1f, 0xc3, 0x9e, 0xea, + 0xbd, 0x42, 0xb1, 0x58, 0x1e, 0x35, 0xbf, 0x99, 0x83, 0xb1, 0x6a, 0xa7, 0xf3, 0x84, 0x7b, 0x7d, + 0x7f, 0x4c, 0xd3, 0x1f, 0x67, 0x12, 0x39, 0x39, 0x81, 0xc3, 0xf7, 0x77, 0x73, 0x30, 0x99, 0xa2, + 0x50, 0xbf, 0xde, 0x18, 0xd0, 0x0b, 0x9a, 0x1b, 0xd0, 0x0b, 0x9a, 0xef, 0xef, 0x05, 0x55, 0x67, + 0x67, 0xe1, 0x51, 0x66, 0xe7, 0x8b, 0x90, 0xaf, 0x76, 0x3a, 0xa2, 0x57, 0x4a, 0x49, 0xaf, 0x6c, + 0xde, 0xe0, 0xcb, 0xa8, 0xd3, 0xe9, 0x58, 0x0c, 0x43, 0x93, 0xca, 0xe1, 0x01, 0xa5, 0xd2, 0x7c, + 0x15, 0x46, 0x91, 0x17, 0x2a, 0xdc, 0x8b, 0x62, 0xa6, 0x72, 0x6d, 0xab, 0xd5, 0xc5, 0x67, 0xa5, + 0xf9, 0x17, 0x06, 0x0c, 0xe1, 0xef, 0x27, 0x54, 0xc6, 0xe6, 0x34, 0x19, 0x2b, 0x2b, 0x32, 0x36, + 0x88, 0x74, 0xfd, 0x5e, 0x1e, 0x7b, 0x4b, 0xc8, 0x95, 0xf0, 0xa3, 0x19, 0x19, 0x7e, 0xb4, 0x47, + 0x58, 0x5f, 0xf6, 0xd2, 0x1e, 0xb5, 0x3c, 0x0e, 0xc6, 0x73, 0xe9, 0x4f, 0x7d, 0x2c, 0xce, 0xb4, + 0xdb, 0x40, 0x96, 0xda, 0x21, 0x6d, 0x74, 0x03, 0x5a, 0xdf, 0xf3, 0x3a, 0x9b, 0x34, 0xf0, 0xb6, + 0xf7, 0xc5, 0x96, 0x0a, 0x97, 0x00, 0x4f, 0x94, 0xda, 0xe1, 0x9e, 0xd7, 0x61, 0x56, 0x8c, 0xb7, + 0xbd, 0x6f, 0x65, 0xd0, 0x90, 0x77, 0x60, 0xc4, 0xa2, 0x0f, 0x02, 0x2f, 0x92, 0x1b, 0xff, 0x89, + 0xd8, 0x63, 0x81, 0x50, 0x6e, 0x8e, 0x05, 0xfc, 0x87, 0x3a, 0xfe, 0xa2, 0xfc, 0xe3, 0x73, 0x3b, + 0x7d, 0x6f, 0x08, 0x27, 0xd0, 0x31, 0x21, 0x0d, 0x47, 0x38, 0x45, 0xf5, 0xc1, 0xcc, 0x9f, 0x64, + 0x30, 0x37, 0xa1, 0x54, 0x67, 0xd3, 0x58, 0xf7, 0x8e, 0x5e, 0x48, 0xc6, 0xf2, 0xaa, 0x5a, 0x7c, + 0x54, 0x34, 0x83, 0xc6, 0x87, 0xd8, 0x69, 0x21, 0xe1, 0x51, 0x12, 0x4f, 0x2b, 0x8c, 0x33, 0xc4, + 0x23, 0xd6, 0x37, 0x0d, 0xde, 0x59, 0x27, 0x16, 0x8c, 0xe1, 0x47, 0x13, 0x8c, 0x91, 0x8f, 0x22, + 0x18, 0xe9, 0x38, 0x92, 0xe2, 0x49, 0xe2, 0x48, 0xce, 0xbf, 0x03, 0x53, 0x3d, 0x3d, 0x7c, 0x92, + 0x58, 0x8c, 0x8f, 0x4f, 0x2c, 0x7f, 0x2a, 0xee, 0x17, 0x32, 0x87, 0x7e, 0x1c, 0x2f, 0xa0, 0x8d, + 0x08, 0x55, 0xaf, 0xd0, 0x96, 0x81, 0x80, 0xa5, 0x3c, 0x7b, 0x08, 0x23, 0x6f, 0xc3, 0x08, 0x3f, + 0xcb, 0xe6, 0x0e, 0x87, 0xb1, 0xb9, 0x71, 0x51, 0x23, 0x87, 0x8a, 0x80, 0x22, 0x8e, 0xa1, 0xf6, + 0xaa, 0x20, 0x32, 0xdf, 0x85, 0x61, 0x71, 0x16, 0x7e, 0xf4, 0xbc, 0xa8, 0xc0, 0xd0, 0x66, 0xd2, + 0x33, 0x78, 0x7e, 0xc9, 0x1b, 0x61, 0x71, 0xb8, 0xf9, 0x73, 0x06, 0x4c, 0xe8, 0xad, 0x24, 0x57, + 0x61, 0x58, 0x04, 0x6b, 0x18, 0x18, 0xac, 0xc1, 0x5a, 0x33, 0xcc, 0xc3, 0x34, 0xb4, 0xe0, 0x0c, + 0x81, 0xc5, 0x54, 0xbf, 0xe0, 0x20, 0x9c, 0x27, 0xa8, 0xfa, 0x85, 0x90, 0x5a, 0xb2, 0x8c, 0xed, + 0x32, 0x2d, 0x1a, 0x76, 0x9b, 0x91, 0xba, 0xcb, 0x0c, 0x10, 0x62, 0x89, 0x12, 0xf3, 0xc0, 0x00, + 0xa8, 0xd7, 0x6f, 0xdf, 0xa1, 0xfb, 0x6b, 0x8e, 0x17, 0xe0, 0x4e, 0x1d, 0x67, 0xe3, 0x1d, 0x31, + 0x5a, 0x25, 0xb1, 0x53, 0xe7, 0x33, 0x77, 0x8f, 0xee, 0x6b, 0x3b, 0x75, 0x89, 0x8a, 0x53, 0x3e, + 0xf0, 0xee, 0x3b, 0x11, 0x65, 0x84, 0x39, 0x24, 0xe4, 0x53, 0x9e, 0x43, 0x53, 0x94, 0x0a, 0x32, + 0xf9, 0x32, 0x4c, 0x24, 0xbf, 0xd0, 0xdf, 0x90, 0xc7, 0x6d, 0xac, 0x94, 0x08, 0xbd, 0xb0, 0xf6, + 0xcc, 0xe1, 0x41, 0xe5, 0xbc, 0xc2, 0x35, 0xed, 0x89, 0x48, 0x31, 0x33, 0x7f, 0xd3, 0x40, 0x47, + 0x88, 0x6c, 0xe0, 0x25, 0x28, 0xc4, 0xce, 0xf3, 0x12, 0x77, 0x07, 0xa4, 0xf6, 0xbb, 0x58, 0x4e, + 0x9e, 0x83, 0x7c, 0xd2, 0x92, 0xa9, 0xc3, 0x83, 0xca, 0xb8, 0xde, 0x02, 0x56, 0x4a, 0xde, 0x85, + 0x91, 0x81, 0xbe, 0x19, 0xa5, 0x33, 0xe3, 0x5b, 0x25, 0x35, 0x8e, 0xc2, 0x7b, 0xf7, 0xd6, 0x3f, + 0xb9, 0xa3, 0xf0, 0x9d, 0x1c, 0x4c, 0xb2, 0x7e, 0xad, 0x76, 0xa3, 0x5d, 0x3f, 0xf0, 0xa2, 0xfd, + 0x27, 0x76, 0xd3, 0xfe, 0xa6, 0x66, 0x10, 0x9d, 0x97, 0x6a, 0x4b, 0x6d, 0xdb, 0x40, 0x7b, 0xf7, + 0x3f, 0x19, 0x81, 0xe9, 0x0c, 0x2a, 0xf2, 0x8a, 0x08, 0x93, 0x4c, 0xdc, 0x64, 0x18, 0x06, 0xf9, + 0xe1, 0x41, 0xa5, 0x24, 0xd1, 0xd7, 0x93, 0xb0, 0xc8, 0x39, 0xdd, 0xab, 0xc8, 0x7b, 0x0a, 0xe3, + 0xeb, 0x54, 0xaf, 0xa2, 0xee, 0x4b, 0xac, 0x42, 0x69, 0x7e, 0x97, 0x36, 0xf6, 0xbc, 0xf6, 0xce, + 0x1d, 0xba, 0xcf, 0xed, 0xa5, 0x52, 0xed, 0x69, 0xb6, 0x11, 0x6c, 0x08, 0x38, 0x1b, 0x52, 0x7d, + 0x8f, 0xa9, 0x91, 0x90, 0xb7, 0x61, 0xac, 0xee, 0xed, 0xb4, 0x25, 0x87, 0x02, 0x72, 0xb8, 0x80, + 0x87, 0x09, 0x1c, 0xdc, 0xcb, 0x40, 0x25, 0x20, 0x2f, 0xc1, 0x90, 0xe5, 0x37, 0x29, 0x5f, 0x86, + 0x45, 0xe0, 0x5d, 0xc0, 0x00, 0xea, 0x89, 0x12, 0x62, 0x90, 0xdb, 0x30, 0xc2, 0xfe, 0xb9, 0xeb, + 0x74, 0xd0, 0x46, 0x4f, 0xce, 0x32, 0x04, 0xb4, 0xe3, 0xb5, 0x77, 0xd4, 0x8d, 0x41, 0x93, 0xda, + 0x2d, 0xa7, 0xa3, 0xad, 0x8b, 0x1c, 0x91, 0x6c, 0xc2, 0x58, 0xa2, 0x08, 0xc2, 0xd9, 0x11, 0xed, + 0xfc, 0x3d, 0x29, 0xa9, 0x3d, 0x2b, 0x98, 0x9d, 0x8d, 0x9a, 0xfc, 0x34, 0xa1, 0xc3, 0xf0, 0xf5, + 0xc6, 0x28, 0x8c, 0xb4, 0x8d, 0x4b, 0xb1, 0xff, 0xc6, 0xc5, 0x38, 0x76, 0xe3, 0xe2, 0x02, 0x88, + 0x4e, 0xaa, 0x36, 0x77, 0x44, 0x9c, 0xec, 0x4b, 0xfd, 0x05, 0xec, 0x6a, 0x82, 0x8c, 0x73, 0x92, + 0x3b, 0xe3, 0x44, 0xff, 0x3b, 0xcd, 0x1d, 0xcd, 0x19, 0x17, 0xa3, 0xb2, 0x6e, 0x48, 0x54, 0x8d, + 0x74, 0x10, 0xc8, 0x6e, 0x48, 0x4a, 0x92, 0x6e, 0xf8, 0xe0, 0x41, 0xd4, 0xaf, 0x1b, 0x14, 0x46, + 0x64, 0x05, 0xa0, 0xda, 0x88, 0xbc, 0xfb, 0x14, 0x45, 0x62, 0x4c, 0xeb, 0x88, 0xf9, 0xea, 0x1d, + 0xba, 0x5f, 0xa7, 0x51, 0x72, 0x92, 0xe5, 0x20, 0x6a, 0x4a, 0x4c, 0x2c, 0x85, 0x03, 0xe9, 0xc0, + 0xe9, 0xaa, 0xeb, 0x7a, 0x3c, 0x76, 0x7a, 0x3d, 0x60, 0xf2, 0xeb, 0x22, 0xeb, 0x52, 0x36, 0xeb, + 0x97, 0x04, 0xeb, 0x67, 0x9d, 0x98, 0xca, 0x8e, 0x38, 0x59, 0xba, 0x9a, 0x6c, 0xc6, 0xe6, 0x2a, + 0x4c, 0xe8, 0x5d, 0xaa, 0x47, 0x0d, 0x97, 0xa0, 0x68, 0xd5, 0xab, 0x76, 0xfd, 0x76, 0xf5, 0x7a, + 0xd9, 0x20, 0x65, 0x28, 0x89, 0x5f, 0x73, 0xf6, 0xdc, 0x6b, 0x37, 0xcb, 0x39, 0x0d, 0xf2, 0xda, + 0xf5, 0xb9, 0x72, 0xde, 0xfc, 0x3d, 0x03, 0x8a, 0xf2, 0xfb, 0xc8, 0x4d, 0xc8, 0xd7, 0xeb, 0xb7, + 0x53, 0x61, 0x1f, 0xc9, 0xd2, 0xcb, 0x17, 0x99, 0x30, 0xdc, 0x55, 0x17, 0x99, 0x7a, 0xfd, 0x36, + 0xa3, 0x5b, 0x5f, 0xae, 0x0b, 0xa3, 0x25, 0x43, 0x5c, 0xa7, 0xfa, 0x9c, 0x85, 0xdf, 0x84, 0xfc, + 0x7b, 0xf7, 0xd6, 0xc5, 0x6e, 0x28, 0x63, 0x7c, 0x91, 0xee, 0x83, 0x07, 0xea, 0xd2, 0xc7, 0x08, + 0x4c, 0x0b, 0xc6, 0x94, 0xa9, 0xc5, 0x8d, 0x88, 0x96, 0x1f, 0xc7, 0xd3, 0x0a, 0x23, 0x82, 0x41, + 0x2c, 0x51, 0xc2, 0x6c, 0x9e, 0x65, 0xbf, 0xe1, 0x34, 0x85, 0x35, 0x82, 0x36, 0x4f, 0x93, 0x01, + 0x2c, 0x0e, 0x37, 0xff, 0xd0, 0x80, 0xf2, 0x5a, 0xe0, 0xdf, 0xf7, 0x98, 0x06, 0x5e, 0xf7, 0xf7, + 0x68, 0x7b, 0xf3, 0x3a, 0x79, 0x55, 0x2a, 0x01, 0x23, 0xde, 0x7b, 0x0f, 0xa1, 0x12, 0xf8, 0xf0, + 0xa0, 0x02, 0xf5, 0xfd, 0x30, 0xa2, 0x2d, 0x56, 0x2e, 0x15, 0x81, 0x12, 0x96, 0x9c, 0x1b, 0x3c, + 0xd4, 0xf1, 0x98, 0xb0, 0xe4, 0x0a, 0x0c, 0xe1, 0xe7, 0x28, 0xd1, 0x66, 0x43, 0x11, 0x03, 0x58, + 0x1c, 0xae, 0x28, 0xec, 0xef, 0xe6, 0x7a, 0xda, 0x30, 0xf7, 0x89, 0x0a, 0x17, 0xd4, 0x1b, 0x37, + 0xd0, 0x22, 0xf6, 0x05, 0x98, 0x49, 0x77, 0x09, 0xfa, 0x45, 0xaa, 0x30, 0xa9, 0xc3, 0xa5, 0x8b, + 0xe4, 0x6c, 0x66, 0x5d, 0x9b, 0x73, 0x56, 0x1a, 0xdf, 0xfc, 0xa1, 0x01, 0xa3, 0xf8, 0xaf, 0xd5, + 0x6d, 0xe2, 0x69, 0x56, 0xf5, 0x5e, 0x5d, 0x1c, 0x9d, 0xab, 0xa7, 0xad, 0xce, 0x83, 0xd0, 0x16, + 0xe7, 0xec, 0x9a, 0x1e, 0x89, 0x91, 0x05, 0x29, 0x0f, 0x14, 0x90, 0x87, 0x8d, 0x31, 0x29, 0x8f, + 0x28, 0x08, 0x53, 0xa4, 0x02, 0x19, 0x4f, 0xdd, 0xee, 0xd5, 0x99, 0xf8, 0x89, 0xd1, 0xe0, 0xa7, + 0x6e, 0x8c, 0xce, 0x6f, 0xea, 0xa7, 0x6e, 0x1c, 0x8d, 0xbc, 0x0a, 0xc3, 0xac, 0x6a, 0x4b, 0x9e, + 0xdb, 0xe0, 0xae, 0x02, 0xbf, 0x31, 0xd0, 0xe2, 0x16, 0x38, 0x92, 0xf9, 0x4f, 0x72, 0xe9, 0x0e, + 0x14, 0x56, 0xc0, 0x09, 0xe7, 0xc6, 0x1b, 0x30, 0x54, 0x6d, 0x36, 0xfd, 0x07, 0x42, 0x4b, 0x48, + 0x37, 0x4d, 0xdc, 0x7f, 0x7c, 0x85, 0x75, 0x18, 0x8a, 0x16, 0x71, 0xc3, 0x00, 0x64, 0x1e, 0x46, + 0xab, 0xf7, 0xea, 0x4b, 0x4b, 0x0b, 0xeb, 0xeb, 0xcb, 0xe2, 0x36, 0xc8, 0x0b, 0xb2, 0x7f, 0x3c, + 0xcf, 0xb5, 0xa3, 0xa8, 0xd9, 0x27, 0x58, 0x3c, 0xa1, 0x23, 0x6f, 0x01, 0xbc, 0xe7, 0x7b, 0xed, + 0xbb, 0x34, 0xda, 0xf5, 0x5d, 0xd1, 0x78, 0x66, 0x52, 0x8c, 0x7d, 0xe0, 0x7b, 0x6d, 0xbb, 0x85, + 0x60, 0xf6, 0xed, 0x09, 0x92, 0xa5, 0xfc, 0xcf, 0x7a, 0xba, 0xe6, 0x47, 0x68, 0xc3, 0x0c, 0x25, + 0x3d, 0xbd, 0xe5, 0x47, 0x3d, 0xe7, 0x9b, 0x02, 0xcd, 0xfc, 0xf9, 0x1c, 0x4c, 0xf0, 0x9d, 0x2a, + 0x17, 0x98, 0x27, 0x76, 0x32, 0xbe, 0xa1, 0x4d, 0xc6, 0x73, 0x72, 0x61, 0x50, 0x9a, 0x36, 0xd0, + 0x54, 0xdc, 0x05, 0xd2, 0x4b, 0x43, 0x2c, 0xe9, 0x4f, 0x19, 0x64, 0x16, 0x5e, 0x4f, 0xa2, 0x5c, + 0x42, 0x24, 0xb2, 0x51, 0x15, 0x86, 0x96, 0xc6, 0xc3, 0xfc, 0xb9, 0x1c, 0x8c, 0x2b, 0xf6, 0xe4, + 0x13, 0xdb, 0xf1, 0x9f, 0xd5, 0x3a, 0x5e, 0x1e, 0x91, 0x28, 0x2d, 0x1b, 0xa8, 0xdf, 0xbb, 0x30, + 0xd5, 0x43, 0x92, 0x36, 0xcb, 0x8d, 0x41, 0xcc, 0xf2, 0x57, 0x7a, 0xa3, 0x42, 0xf8, 0xcd, 0x91, + 0x38, 0x2a, 0x44, 0x0d, 0x43, 0xf9, 0x4e, 0x0e, 0x66, 0xc4, 0xaf, 0x6a, 0xd7, 0xf5, 0xa2, 0x79, + 0xbf, 0xbd, 0xed, 0xed, 0x3c, 0xb1, 0x63, 0x51, 0xd5, 0xc6, 0xa2, 0xa2, 0x8f, 0x85, 0xd2, 0xc0, + 0xfe, 0x43, 0x62, 0xfe, 0xbf, 0x00, 0xb3, 0xfd, 0x08, 0xd8, 0xb6, 0x5f, 0xd9, 0x55, 0xe1, 0xb6, + 0x3f, 0xb5, 0x63, 0xe5, 0xfb, 0xa9, 0x24, 0xec, 0x2c, 0x37, 0x40, 0xd8, 0xd9, 0x32, 0x94, 0xb1, + 0xaa, 0x3a, 0x0d, 0x59, 0x27, 0x84, 0x49, 0xd8, 0xfa, 0xc5, 0xc3, 0x83, 0xca, 0x05, 0x87, 0x95, + 0xd9, 0xa1, 0x28, 0xb4, 0xbb, 0x81, 0xa7, 0xf0, 0xe8, 0xa1, 0x24, 0xbf, 0x69, 0xc0, 0x04, 0x02, + 0x17, 0xef, 0xd3, 0x76, 0x84, 0xcc, 0x0a, 0xe2, 0x64, 0x27, 0xbe, 0x1d, 0x58, 0x8f, 0x02, 0xaf, + 0xbd, 0x83, 0x8e, 0xa4, 0xb0, 0xb6, 0xc5, 0x7a, 0xe1, 0x07, 0x07, 0x95, 0x37, 0x3f, 0xca, 0x8d, + 0x43, 0xc1, 0x2a, 0x64, 0x1b, 0x79, 0xfe, 0xa1, 0x14, 0xab, 0x4d, 0x7d, 0x66, 0xea, 0x8b, 0xc8, + 0x8f, 0xc3, 0x59, 0x1e, 0x26, 0x32, 0xef, 0xb7, 0x23, 0xaf, 0xdd, 0xf5, 0xbb, 0x61, 0xcd, 0x69, + 0xec, 0x75, 0x3b, 0xa1, 0x70, 0x76, 0x62, 0xcb, 0x1b, 0x71, 0xa1, 0xbd, 0xc5, 0x4b, 0x15, 0x96, + 0xfd, 0x18, 0x90, 0xdb, 0x30, 0xc5, 0x8b, 0xaa, 0xdd, 0xc8, 0xaf, 0x37, 0x9c, 0xa6, 0xd7, 0xde, + 0x41, 0x1f, 0x68, 0x91, 0x07, 0xca, 0x38, 0xdd, 0xc8, 0xb7, 0x43, 0x0e, 0x57, 0xf8, 0xf5, 0x12, + 0x91, 0x25, 0x98, 0xb4, 0xa8, 0xe3, 0xde, 0x75, 0x1e, 0xce, 0x3b, 0x1d, 0xa7, 0xe1, 0x45, 0xfb, + 0xb8, 0x33, 0xcb, 0xd7, 0x2a, 0x87, 0x07, 0x95, 0xa7, 0x02, 0xea, 0xb8, 0x76, 0xcb, 0x79, 0x68, + 0x37, 0x44, 0xa1, 0xc2, 0x2c, 0x4d, 0x17, 0xb3, 0xf2, 0xda, 0x31, 0xab, 0xd1, 0x34, 0x2b, 0xaf, + 0xdd, 0x9f, 0x55, 0x42, 0x27, 0x59, 0xad, 0x3b, 0xc1, 0x0e, 0x8d, 0xb8, 0x93, 0x10, 0x2e, 0x1a, + 0x97, 0x0d, 0x85, 0x55, 0x84, 0x65, 0x36, 0x3a, 0x0c, 0xd3, 0xac, 0x14, 0x3a, 0x26, 0x79, 0xf7, + 0x02, 0x2f, 0xa2, 0x6a, 0x0b, 0xc7, 0xf0, 0xb3, 0xb0, 0xff, 0xd1, 0x4d, 0xda, 0xaf, 0x89, 0x3d, + 0x94, 0x09, 0x37, 0xa5, 0x91, 0xa5, 0x1e, 0x6e, 0xd9, 0xad, 0xec, 0xa1, 0x8c, 0xb9, 0xa9, 0xed, + 0x1c, 0xc7, 0x76, 0x2a, 0xdc, 0xfa, 0x34, 0xb4, 0x87, 0x92, 0xac, 0xb0, 0x4e, 0x8b, 0x68, 0x9b, + 0x49, 0xb4, 0x70, 0x92, 0x4e, 0xe0, 0xa7, 0x3d, 0x2f, 0xf6, 0xd4, 0xe5, 0x40, 0x16, 0xdb, 0x19, + 0x2e, 0xd3, 0x34, 0x31, 0xf9, 0x49, 0x98, 0xdc, 0x08, 0xe9, 0xad, 0xa5, 0xb5, 0xba, 0x0c, 0x59, + 0x9a, 0x9d, 0xc4, 0x9d, 0xf6, 0xf5, 0x63, 0x94, 0xce, 0x55, 0x95, 0x06, 0xef, 0x0f, 0xf2, 0x71, + 0xeb, 0x86, 0xd4, 0xde, 0xf6, 0x3a, 0xa1, 0x2d, 0x63, 0xa3, 0xd4, 0x71, 0x4b, 0x55, 0x65, 0xde, + 0x86, 0xa9, 0x1e, 0x36, 0x64, 0x02, 0x80, 0x01, 0xed, 0x8d, 0x95, 0xfa, 0xe2, 0x7a, 0xf9, 0x14, + 0xdb, 0x48, 0xe2, 0xef, 0xc5, 0x95, 0x6a, 0x6d, 0x79, 0x71, 0xa1, 0x6c, 0x90, 0x29, 0x18, 0x47, + 0xc8, 0xc2, 0x52, 0x9d, 0x83, 0x72, 0xef, 0x15, 0x8a, 0x43, 0xe5, 0x61, 0xab, 0xcc, 0xa7, 0x6e, + 0xc4, 0x26, 0x00, 0xae, 0x29, 0xe6, 0xaf, 0xe6, 0xe0, 0x9c, 0x5c, 0x56, 0x68, 0xf4, 0xc0, 0x0f, + 0xf6, 0xbc, 0xf6, 0xce, 0x13, 0xbe, 0x3a, 0xdc, 0xd2, 0x56, 0x87, 0xe7, 0x53, 0x2b, 0x75, 0xaa, + 0x95, 0x47, 0x2c, 0x11, 0x7f, 0x30, 0x0c, 0x4f, 0x1f, 0x49, 0x45, 0xde, 0x67, 0xab, 0xb9, 0x47, + 0xdb, 0xd1, 0x92, 0xdb, 0xa4, 0x6c, 0x3b, 0xe9, 0x77, 0x23, 0xe1, 0x94, 0x7f, 0xee, 0xf0, 0xa0, + 0x32, 0xcd, 0x2f, 0xff, 0xd9, 0x9e, 0xdb, 0xa4, 0x76, 0xc4, 0x8b, 0x35, 0x71, 0xeb, 0xa5, 0x66, + 0x2c, 0xe3, 0xab, 0xc8, 0x4b, 0xed, 0x88, 0x06, 0xf7, 0x1d, 0x7e, 0x07, 0x4a, 0xb0, 0xdc, 0xa3, + 0xb4, 0x63, 0x3b, 0xac, 0xd4, 0xf6, 0x44, 0xb1, 0xce, 0xb2, 0x87, 0x9a, 0xdc, 0x52, 0x58, 0xce, + 0xb3, 0x4d, 0xce, 0x5d, 0xe7, 0xa1, 0xb0, 0xdc, 0x45, 0xf4, 0x6c, 0xcc, 0x92, 0x47, 0x20, 0xb7, + 0x9c, 0x87, 0x56, 0x2f, 0x09, 0xf9, 0x32, 0x9c, 0x16, 0x0b, 0x10, 0x53, 0xc6, 0x81, 0xdf, 0x94, + 0x2d, 0x2e, 0x20, 0xaf, 0x17, 0x0f, 0x0f, 0x2a, 0x67, 0xc5, 0xf2, 0x65, 0x37, 0x38, 0x46, 0x66, + 0xab, 0xb3, 0xb9, 0x90, 0x75, 0xb6, 0x20, 0xa7, 0xba, 0xe3, 0x2e, 0x0d, 0x43, 0x67, 0x47, 0x5a, + 0xf9, 0xfc, 0x64, 0x4c, 0xe9, 0x4c, 0xbb, 0xc5, 0xcb, 0xad, 0xbe, 0x94, 0xe4, 0x36, 0x4c, 0xdc, + 0xa3, 0x5b, 0xea, 0xf8, 0x0c, 0xc7, 0xaa, 0xaa, 0xfc, 0x80, 0x6e, 0xf5, 0x1f, 0x9c, 0x14, 0x1d, + 0xf1, 0x60, 0x0a, 0x8f, 0xf5, 0xd9, 0x96, 0x95, 0xb6, 0x69, 0x80, 0x31, 0x74, 0x23, 0xa8, 0x0c, + 0x66, 0x13, 0x0b, 0x59, 0x2f, 0xaf, 0x3d, 0x7b, 0x78, 0x50, 0x79, 0x9a, 0x87, 0x08, 0x34, 0x05, + 0xdc, 0x4e, 0xdd, 0x04, 0xee, 0xe5, 0x4a, 0xbe, 0x0a, 0x93, 0x96, 0xdf, 0x8d, 0xbc, 0xf6, 0x4e, + 0x3d, 0x0a, 0x9c, 0x88, 0xee, 0xf0, 0x05, 0x29, 0x09, 0xd6, 0x4b, 0x95, 0x72, 0x07, 0x7b, 0xc0, + 0x81, 0x76, 0x28, 0xa0, 0xda, 0x8a, 0xa0, 0x13, 0x90, 0xaf, 0xc0, 0x04, 0x8f, 0x32, 0x8a, 0x2b, + 0x18, 0xd5, 0x2e, 0xcd, 0xe8, 0x85, 0x9b, 0xd7, 0x71, 0x77, 0x76, 0x8e, 0x47, 0x2b, 0x65, 0x55, + 0x90, 0xe2, 0x66, 0x1e, 0x18, 0x50, 0x4e, 0xf3, 0x20, 0x9f, 0x87, 0xd1, 0xea, 0x0e, 0x6d, 0xb3, + 0xb1, 0xd9, 0x15, 0x57, 0x69, 0xe5, 0xc5, 0xfe, 0x18, 0xae, 0x13, 0x89, 0xc8, 0x78, 0x56, 0xc8, + 0xc6, 0x5a, 0xf1, 0x76, 0xdd, 0x3e, 0x65, 0x25, 0xcc, 0x88, 0x0b, 0x25, 0xec, 0xc5, 0x35, 0x4a, + 0x99, 0x99, 0x22, 0x5c, 0x3e, 0xcf, 0xaa, 0xc3, 0x22, 0x8a, 0x52, 0xfc, 0x31, 0xa0, 0x89, 0x8f, + 0x4f, 0x87, 0x23, 0x68, 0x55, 0x68, 0x5c, 0x6b, 0x00, 0xc5, 0xb8, 0x81, 0xe7, 0xe0, 0x6c, 0x9f, + 0x6f, 0x36, 0xef, 0xc3, 0xf9, 0xfe, 0x35, 0x92, 0xcf, 0xc3, 0x0c, 0x12, 0xce, 0xfb, 0xed, 0x36, + 0x6d, 0x44, 0x38, 0x0f, 0xa4, 0x97, 0x22, 0x5f, 0x7b, 0xfe, 0xf0, 0xa0, 0x72, 0x91, 0xb7, 0xb7, + 0x11, 0x23, 0xd8, 0x69, 0x87, 0x45, 0x26, 0x07, 0xf3, 0x97, 0x73, 0x30, 0x2b, 0xa6, 0x96, 0x45, + 0x1b, 0x7e, 0xe0, 0x3e, 0xf9, 0xaa, 0x7c, 0x51, 0x53, 0xe5, 0xcf, 0xc5, 0xe1, 0x7d, 0x59, 0x8d, + 0x3c, 0x42, 0x93, 0xff, 0xae, 0x01, 0x17, 0x8e, 0x22, 0x62, 0xbd, 0x13, 0x87, 0xc4, 0x8e, 0xf6, + 0x84, 0xbe, 0x76, 0x60, 0x1a, 0x07, 0x14, 0x0f, 0x35, 0xc2, 0xdb, 0x7e, 0x18, 0xa1, 0x67, 0x39, + 0xa7, 0x05, 0xb9, 0xd4, 0x7c, 0xbf, 0x89, 0x36, 0x48, 0xed, 0x15, 0x66, 0x6a, 0xfc, 0xe0, 0xa0, + 0x02, 0x0c, 0xc4, 0x83, 0x58, 0x99, 0x3d, 0xca, 0xa5, 0x0c, 0xcf, 0x4c, 0x42, 0x1b, 0xc3, 0x99, + 0xf6, 0xe8, 0x7e, 0x68, 0x65, 0xb1, 0x46, 0xef, 0x61, 0xb5, 0x1b, 0xed, 0xae, 0x05, 0x74, 0x9b, + 0x06, 0xb4, 0xdd, 0xa0, 0x9f, 0x30, 0xef, 0xa1, 0xde, 0xb8, 0x81, 0xb6, 0xce, 0x7f, 0x36, 0x02, + 0x33, 0x59, 0x64, 0xac, 0x5f, 0x94, 0xdd, 0x5a, 0x3a, 0x15, 0xc8, 0xff, 0x63, 0x40, 0xa9, 0x4e, + 0x1b, 0x7e, 0xdb, 0xbd, 0xe5, 0x34, 0x22, 0x5f, 0x86, 0x0b, 0xd9, 0x7c, 0xb5, 0x62, 0x70, 0x7b, + 0x1b, 0x0b, 0x34, 0xaf, 0xd5, 0xe7, 0x06, 0xdb, 0x24, 0x35, 0x7c, 0x8c, 0x21, 0x8f, 0xf0, 0xae, + 0x4c, 0x5c, 0x05, 0x9e, 0xb8, 0x69, 0x95, 0x92, 0x1a, 0x8c, 0x8b, 0xe9, 0xea, 0xab, 0x11, 0xd1, + 0x18, 0xc3, 0xdc, 0x90, 0x05, 0x69, 0xef, 0x95, 0x4e, 0x42, 0x6e, 0x40, 0x7e, 0x63, 0xee, 0x96, + 0x18, 0x03, 0x19, 0xe7, 0xb9, 0x31, 0x77, 0x0b, 0xfd, 0x30, 0xcc, 0xb6, 0x1d, 0xef, 0xce, 0x6d, + 0xab, 0xfe, 0xf9, 0x8d, 0xb9, 0x5b, 0x64, 0x15, 0xa6, 0x2c, 0xfa, 0xb5, 0xae, 0x17, 0x50, 0x31, + 0x01, 0xee, 0xde, 0xaa, 0xe2, 0x58, 0x14, 0xf9, 0xda, 0x14, 0xf0, 0x42, 0xb9, 0xef, 0xb4, 0x5b, + 0xdb, 0xea, 0xf5, 0xf7, 0x5e, 0x5a, 0xf2, 0xd3, 0x70, 0x7a, 0xc1, 0x0b, 0xc5, 0x37, 0x73, 0xc7, + 0xb8, 0x8b, 0x67, 0xe4, 0xc3, 0x7d, 0xa6, 0xc3, 0x67, 0x32, 0xa7, 0xc3, 0xb3, 0x6e, 0xcc, 0xc4, + 0xe6, 0x5e, 0x77, 0x37, 0x1d, 0x4a, 0x9e, 0x5d, 0x0f, 0xf9, 0x00, 0x26, 0xd0, 0x13, 0x89, 0x67, + 0x05, 0x78, 0x47, 0x65, 0xa4, 0x4f, 0xcd, 0x9f, 0xca, 0xac, 0xf9, 0x3c, 0x3a, 0x36, 0x6d, 0x3c, + 0x71, 0xc0, 0xfb, 0x2c, 0xda, 0xfe, 0x55, 0xe3, 0x4c, 0xde, 0x83, 0x49, 0x61, 0x48, 0xac, 0x6e, + 0xaf, 0xef, 0xd2, 0x05, 0x67, 0x5f, 0x04, 0xc8, 0xe0, 0xde, 0x44, 0x58, 0x1f, 0xb6, 0xbf, 0x6d, + 0x47, 0xbb, 0xd4, 0x76, 0x1d, 0x6d, 0xc9, 0x4d, 0x11, 0x92, 0xaf, 0xc3, 0xd8, 0xb2, 0x8f, 0x87, + 0xa2, 0xa8, 0x6a, 0x46, 0x91, 0xcf, 0x17, 0x30, 0xfd, 0x05, 0x07, 0xa7, 0x0c, 0x83, 0x0f, 0x0f, + 0x2a, 0x6f, 0x9c, 0x54, 0x0a, 0x95, 0x0a, 0x2c, 0xb5, 0x36, 0x32, 0x0f, 0xc5, 0x7b, 0x74, 0x8b, + 0xb5, 0x36, 0x7d, 0x75, 0x5b, 0x82, 0xb9, 0xbe, 0x78, 0x20, 0x7e, 0xa9, 0x27, 0x8e, 0x12, 0x83, + 0x04, 0x30, 0x85, 0xfd, 0xb3, 0xe6, 0x84, 0xe1, 0x03, 0x3f, 0x70, 0x9b, 0x34, 0x94, 0x47, 0x77, + 0xbd, 0x9d, 0x3f, 0x97, 0xd9, 0xf9, 0x17, 0x78, 0xe7, 0x77, 0x14, 0x0e, 0xaa, 0xb8, 0xf5, 0xb0, + 0x37, 0xff, 0xc0, 0x40, 0xa9, 0x27, 0x57, 0x30, 0x30, 0x32, 0xbe, 0x10, 0x82, 0x9e, 0x16, 0xa7, + 0x93, 0xba, 0x3f, 0xc4, 0x51, 0xc8, 0x2b, 0x30, 0x7c, 0xcb, 0x69, 0xd0, 0x48, 0xfa, 0xef, 0x11, + 0x79, 0x1b, 0x21, 0xaa, 0x5b, 0x86, 0xe3, 0xb0, 0x05, 0x79, 0x81, 0xde, 0xf7, 0x1a, 0xb4, 0x1a, + 0x45, 0x34, 0xe4, 0x3d, 0x3c, 0x5f, 0xe5, 0x07, 0xdd, 0xa3, 0x7c, 0x41, 0x76, 0xb1, 0xdc, 0x76, + 0x12, 0x04, 0xbb, 0xe1, 0xa8, 0xbc, 0x32, 0x39, 0x98, 0xff, 0xc3, 0x48, 0x7a, 0x9d, 0xbc, 0x08, + 0x05, 0x6b, 0x2d, 0xfe, 0x7e, 0x7e, 0x86, 0x9d, 0xfa, 0x7c, 0x44, 0x20, 0x5f, 0x84, 0xd3, 0x0a, + 0x1f, 0xec, 0x11, 0xea, 0xb2, 0x0f, 0xe2, 0x8d, 0x79, 0x01, 0x0f, 0x2d, 0x95, 0x2f, 0x71, 0x38, + 0x46, 0xea, 0x8b, 0xb2, 0x79, 0xa0, 0xf5, 0x91, 0x14, 0x2c, 0xd0, 0xb6, 0xc7, 0x79, 0x2b, 0x8d, + 0x55, 0x79, 0xbb, 0x88, 0x90, 0x6e, 0x6c, 0x16, 0x87, 0xf7, 0x0a, 0xc5, 0x42, 0x79, 0xc8, 0xfc, + 0x73, 0x43, 0xc9, 0x5d, 0xf4, 0x84, 0xae, 0x58, 0x37, 0xb5, 0x15, 0x6b, 0x46, 0x90, 0xc6, 0xad, + 0x62, 0x65, 0x99, 0x56, 0xc6, 0x24, 0x8c, 0x6b, 0x48, 0x18, 0x37, 0xbe, 0x11, 0xd2, 0x80, 0xfb, + 0xcb, 0x3f, 0x59, 0x71, 0xe3, 0x71, 0xbb, 0x06, 0x8a, 0xec, 0xfd, 0x13, 0x03, 0xfd, 0x28, 0x2a, + 0x05, 0xeb, 0x0d, 0x06, 0x52, 0x7b, 0xa3, 0x1b, 0xd2, 0xc0, 0x42, 0x28, 0x0f, 0x18, 0x5d, 0xd6, + 0x03, 0x46, 0x9b, 0x16, 0x83, 0x91, 0xcf, 0xc1, 0xd0, 0x06, 0xee, 0x0a, 0xf5, 0x98, 0xa3, 0x98, + 0x3f, 0x16, 0xf2, 0x19, 0xd6, 0x65, 0xff, 0xaa, 0x0a, 0x02, 0xcb, 0x48, 0x1d, 0x46, 0xe6, 0x03, + 0x8a, 0x59, 0x8a, 0x0a, 0x83, 0x1f, 0x0e, 0x37, 0x38, 0x49, 0xfa, 0x70, 0x58, 0x70, 0x32, 0x7f, + 0x29, 0x07, 0x24, 0x69, 0x23, 0xde, 0x5a, 0x0d, 0x9f, 0xd8, 0x41, 0x7f, 0x47, 0x1b, 0xf4, 0xa7, + 0x7b, 0x06, 0x9d, 0x37, 0x6f, 0xa0, 0xb1, 0xff, 0x43, 0x03, 0xce, 0x64, 0x13, 0x92, 0xe7, 0x60, + 0x78, 0x75, 0x7d, 0x4d, 0x86, 0xad, 0x89, 0xa6, 0xf8, 0x1d, 0xb4, 0x8c, 0x2d, 0x51, 0x44, 0x5e, + 0x85, 0xe1, 0xf7, 0xad, 0x79, 0xb6, 0x64, 0x2a, 0x17, 0xcf, 0xbe, 0x16, 0xd8, 0x0d, 0x7d, 0x1b, + 0x2d, 0x90, 0xd4, 0xb1, 0xcd, 0x3f, 0xb6, 0xb1, 0xfd, 0x4e, 0x0e, 0x26, 0xab, 0x8d, 0x06, 0x0d, + 0x43, 0x66, 0x10, 0xd1, 0x30, 0x7a, 0x62, 0x07, 0x36, 0x3b, 0x20, 0x4d, 0x6b, 0xdb, 0x40, 0xa3, + 0xfa, 0x47, 0x06, 0x9c, 0x96, 0x54, 0xf7, 0x3d, 0xfa, 0x60, 0x7d, 0x37, 0xa0, 0xe1, 0xae, 0xdf, + 0x74, 0x07, 0xbd, 0x42, 0x89, 0xab, 0xb4, 0xd7, 0x8c, 0x68, 0xa0, 0x1e, 0x9e, 0x6c, 0x23, 0x44, + 0x5b, 0xa5, 0x11, 0x42, 0xae, 0xc1, 0x48, 0xb5, 0xd3, 0x09, 0xfc, 0xfb, 0x7c, 0xda, 0x8f, 0x8b, + 0xb3, 0x72, 0x0e, 0xd2, 0xce, 0xd6, 0x39, 0x88, 0x7d, 0xc6, 0x02, 0x6d, 0xf3, 0x68, 0xfb, 0x71, + 0xfe, 0x19, 0x2e, 0x6d, 0xab, 0x16, 0x1a, 0x96, 0x9b, 0xdf, 0x2e, 0x40, 0x49, 0x6d, 0x08, 0x31, + 0x61, 0x98, 0x87, 0x4e, 0xa9, 0x21, 0x2c, 0x0e, 0x42, 0x2c, 0x51, 0x92, 0x44, 0xa4, 0xe5, 0x8e, + 0x8d, 0x48, 0xbb, 0x07, 0xe3, 0x6b, 0x81, 0xdf, 0xf1, 0x43, 0xea, 0xf2, 0x44, 0x73, 0x5c, 0x6b, + 0x4d, 0xc7, 0x61, 0xda, 0xbc, 0xcf, 0xd1, 0x43, 0x8c, 0xdb, 0x81, 0x8e, 0xc0, 0xb6, 0xd3, 0x69, + 0xe8, 0x74, 0x3e, 0xfc, 0xf0, 0xc9, 0x09, 0xc5, 0xfd, 0x97, 0xf8, 0xf0, 0x89, 0x41, 0xf4, 0xc3, + 0x27, 0x06, 0x51, 0xa7, 0xc5, 0xd0, 0xe3, 0x9a, 0x16, 0xe4, 0x97, 0x0c, 0x18, 0xab, 0xb6, 0xdb, + 0x22, 0x22, 0x4d, 0x26, 0x5e, 0x39, 0x9d, 0x1c, 0x40, 0xf1, 0x90, 0x65, 0x7e, 0xfe, 0xf4, 0x25, + 0x71, 0xfe, 0xf4, 0xc6, 0x47, 0x3a, 0x7f, 0x5a, 0x0f, 0x1c, 0x2f, 0x0a, 0x31, 0xd0, 0x20, 0xa9, + 0x50, 0x0d, 0x4b, 0x57, 0xbe, 0x83, 0xbc, 0x01, 0xe5, 0x58, 0x1e, 0x97, 0xda, 0x2e, 0x7d, 0x48, + 0x79, 0x00, 0xdf, 0x38, 0xbf, 0x9c, 0xab, 0x1d, 0xac, 0xa5, 0x11, 0xcd, 0xef, 0x18, 0x70, 0x46, + 0x15, 0x88, 0x7a, 0x77, 0xab, 0xe5, 0xe1, 0xf6, 0x87, 0x5c, 0x85, 0x51, 0x31, 0x5e, 0xb1, 0x21, + 0xd7, 0x9b, 0x9d, 0x30, 0x41, 0x21, 0x8b, 0x6c, 0x88, 0x18, 0x0f, 0xe1, 0x2b, 0x98, 0x4e, 0x4d, + 0x37, 0x56, 0x54, 0x9b, 0x15, 0x9d, 0x5d, 0x0e, 0xf0, 0xb7, 0x3e, 0x76, 0x0c, 0x62, 0xbe, 0x0d, + 0x53, 0xfa, 0x57, 0xd6, 0x29, 0xde, 0xde, 0x94, 0x4d, 0x33, 0xb2, 0x9b, 0x26, 0xcb, 0xcd, 0x7b, + 0x40, 0x7a, 0xe8, 0x43, 0x3c, 0x44, 0xa5, 0x91, 0x3c, 0xe4, 0x97, 0x2e, 0xcc, 0x1e, 0xc4, 0x38, + 0x4f, 0xe7, 0x98, 0xda, 0xdd, 0x48, 0x6a, 0xfe, 0x9b, 0x31, 0x98, 0xce, 0x50, 0x1d, 0xc7, 0x2c, + 0xed, 0x15, 0x7d, 0xf2, 0x8c, 0xc6, 0xd1, 0x2a, 0x72, 0xca, 0xbc, 0x2d, 0x73, 0x32, 0x1e, 0x31, + 0x55, 0x8e, 0x4a, 0xd4, 0xf8, 0x71, 0x2c, 0xef, 0x6a, 0x40, 0xd9, 0xd0, 0x63, 0x0b, 0x28, 0xab, + 0xc1, 0xb8, 0x68, 0x95, 0x98, 0xca, 0xc3, 0x89, 0x5b, 0x20, 0xe0, 0x05, 0x76, 0xcf, 0x94, 0xd6, + 0x49, 0x38, 0x8f, 0xd0, 0x6f, 0xde, 0xa7, 0x82, 0xc7, 0x88, 0xca, 0x03, 0x0b, 0x32, 0x79, 0x28, + 0x24, 0xe4, 0xef, 0x1b, 0x40, 0x04, 0x44, 0x9d, 0xcf, 0xc5, 0xa3, 0xe6, 0xb3, 0xfb, 0x78, 0xe6, + 0xf3, 0xd3, 0xf2, 0x1b, 0xb3, 0xe7, 0x75, 0xc6, 0x67, 0x91, 0xbf, 0x6b, 0xc0, 0x14, 0x8f, 0x6a, + 0x52, 0x3f, 0x76, 0xf4, 0xa8, 0x8f, 0x6d, 0x3c, 0x9e, 0x8f, 0xbd, 0x10, 0x62, 0xb5, 0x7d, 0xbe, + 0xb5, 0xf7, 0xa3, 0xc8, 0x8f, 0x03, 0xc4, 0x33, 0x4a, 0x46, 0xcf, 0x5e, 0xc8, 0xd0, 0x02, 0x31, + 0x52, 0x72, 0x3f, 0x39, 0x8a, 0xe9, 0xb4, 0xc4, 0x0b, 0x31, 0x94, 0xfc, 0x34, 0xcc, 0xb0, 0xf9, + 0x12, 0x43, 0x44, 0x0c, 0xe6, 0xec, 0x18, 0xd6, 0xf2, 0xe9, 0xfe, 0x4b, 0xfb, 0xd5, 0x2c, 0x32, + 0x7e, 0x87, 0x29, 0x49, 0x5c, 0x13, 0xb5, 0xd4, 0x2d, 0x5f, 0x16, 0x05, 0x06, 0x5b, 0xe3, 0xd7, + 0xf3, 0x6b, 0xba, 0x7d, 0xf4, 0xdb, 0x39, 0x39, 0x17, 0xb8, 0x7e, 0x0b, 0xf5, 0x4b, 0x48, 0x08, + 0x22, 0xef, 0x03, 0xa9, 0x77, 0x77, 0x76, 0x68, 0x18, 0x51, 0x97, 0xc3, 0x68, 0x20, 0x93, 0xb2, + 0xa1, 0x9b, 0x2a, 0x94, 0xa5, 0x76, 0x20, 0x8b, 0x55, 0x21, 0xe9, 0x25, 0x26, 0x14, 0x66, 0x44, + 0xa3, 0x19, 0x54, 0xa6, 0x36, 0x09, 0x67, 0x27, 0xb4, 0x08, 0xd7, 0xa4, 0x24, 0xc9, 0x70, 0xa3, + 0xe4, 0x47, 0xd1, 0xb6, 0xbd, 0x59, 0xec, 0xc8, 0x4d, 0x18, 0x5d, 0xf6, 0x77, 0xbc, 0xf6, 0x6d, + 0x79, 0x34, 0x2c, 0x8e, 0xa9, 0x9a, 0x0c, 0x68, 0xef, 0xea, 0x07, 0xbc, 0x09, 0x2a, 0xb3, 0x6a, + 0x17, 0x82, 0x7d, 0xab, 0xdb, 0x9e, 0x2d, 0xa3, 0x33, 0x0e, 0xcd, 0x19, 0x37, 0xd8, 0xb7, 0x83, + 0xae, 0xb6, 0x7c, 0x73, 0xa4, 0xf3, 0x5b, 0x70, 0xae, 0xef, 0xa0, 0x65, 0x5c, 0x97, 0xba, 0xa6, + 0x5f, 0x97, 0x3a, 0xd7, 0x4f, 0xb9, 0x87, 0xea, 0x95, 0xa9, 0x5f, 0x37, 0x52, 0xda, 0x5c, 0x98, + 0x5e, 0x3c, 0x19, 0x6f, 0xbf, 0xe5, 0x2e, 0x87, 0xf9, 0x62, 0xb8, 0xbe, 0xcf, 0x25, 0x26, 0x1f, + 0xd3, 0xf7, 0xea, 0x7a, 0x81, 0x9a, 0xff, 0x11, 0x15, 0xbb, 0xf9, 0x0f, 0x0d, 0x20, 0xfc, 0x0b, + 0xe7, 0x9d, 0x8e, 0xb3, 0xe5, 0x35, 0xbd, 0xc8, 0xa3, 0x21, 0xb9, 0x03, 0x65, 0xc1, 0xc2, 0xd9, + 0x6a, 0x52, 0x35, 0x12, 0x52, 0x84, 0x4a, 0xc4, 0x65, 0x76, 0xda, 0x48, 0xeb, 0x21, 0xec, 0x23, + 0x8a, 0xb9, 0x47, 0x10, 0x45, 0xf3, 0x47, 0x06, 0x9c, 0xeb, 0xfd, 0x6c, 0x51, 0x73, 0xdc, 0x79, + 0xc6, 0x31, 0x9d, 0x97, 0xd5, 0xca, 0x1c, 0xca, 0xce, 0x63, 0x6b, 0x65, 0x3e, 0xf1, 0x0b, 0x9f, + 0xbc, 0x95, 0x0f, 0xd4, 0x7c, 0x43, 0xe4, 0xd5, 0xac, 0x98, 0x36, 0x7e, 0xf1, 0x8c, 0x83, 0xf5, + 0x70, 0x36, 0xb9, 0x99, 0xca, 0x65, 0x6e, 0xa6, 0xe4, 0x1d, 0xba, 0x7c, 0xd6, 0x1d, 0x3a, 0xf3, + 0x5b, 0x39, 0x28, 0xad, 0x35, 0xbb, 0x3b, 0x5e, 0x7b, 0xc1, 0x89, 0x9c, 0x27, 0x76, 0x67, 0xf6, + 0xba, 0xb6, 0x33, 0x8b, 0x83, 0x2e, 0xe3, 0x86, 0x0d, 0xb4, 0x2d, 0xfb, 0x9e, 0x01, 0x93, 0x09, + 0x09, 0x57, 0x0f, 0xb7, 0xa1, 0xc0, 0x7e, 0x08, 0x43, 0xef, 0x62, 0x0f, 0x63, 0xc4, 0xba, 0x1a, + 0xff, 0x27, 0xf6, 0x4a, 0x7a, 0x1e, 0x5c, 0xe4, 0x70, 0xfe, 0x33, 0x3c, 0x23, 0xe5, 0xc9, 0x53, + 0x6e, 0xff, 0xbe, 0x01, 0xe5, 0x74, 0x4b, 0xc8, 0x1d, 0x18, 0x61, 0x9c, 0xbc, 0x38, 0xbb, 0xe5, + 0xf3, 0x7d, 0xda, 0x7c, 0x55, 0xa0, 0xf1, 0xcf, 0xc3, 0xce, 0xa7, 0x1c, 0x62, 0x49, 0x0e, 0xe7, + 0x2d, 0x28, 0xa9, 0x58, 0x19, 0x5f, 0xf7, 0x8a, 0xae, 0x13, 0xcf, 0x64, 0xf7, 0x83, 0xfa, 0xd5, + 0xbf, 0xa6, 0x7d, 0xb5, 0xd0, 0x86, 0x83, 0xe6, 0x36, 0xc6, 0x5b, 0xa7, 0x7c, 0x3a, 0xa8, 0x72, + 0x26, 0x17, 0x17, 0xfd, 0xd6, 0x29, 0x87, 0xb1, 0x2d, 0x1d, 0xaf, 0x4f, 0xc8, 0x19, 0x6e, 0xe9, + 0x3a, 0x08, 0x51, 0xd7, 0x04, 0x8e, 0x63, 0xfe, 0xcd, 0x3c, 0x9c, 0x49, 0x3e, 0x8f, 0x67, 0x7a, + 0x5e, 0x73, 0x02, 0xa7, 0x15, 0x1e, 0x33, 0x03, 0x2e, 0xf7, 0x7c, 0x1a, 0xa6, 0x62, 0x90, 0x9f, + 0xa6, 0x7c, 0x90, 0x99, 0xfa, 0x20, 0xdc, 0x0b, 0xf3, 0x0f, 0x92, 0x9f, 0x41, 0xee, 0x40, 0xbe, + 0x4e, 0x23, 0x71, 0xf7, 0xfa, 0x52, 0x4f, 0xaf, 0xaa, 0xdf, 0x75, 0xb5, 0x4e, 0x23, 0x3e, 0x88, + 0xfc, 0xfa, 0x0a, 0xd5, 0xae, 0x93, 0xb0, 0x5d, 0xcd, 0x3d, 0x18, 0x5e, 0x7c, 0xd8, 0xa1, 0x8d, + 0x48, 0x5c, 0xb9, 0x7e, 0xe9, 0x68, 0x7e, 0x1c, 0x57, 0xb9, 0xd8, 0x4d, 0x11, 0xa0, 0x76, 0x16, + 0x47, 0x39, 0x7f, 0x13, 0x8a, 0xb2, 0xf2, 0x13, 0x5d, 0x50, 0x7e, 0x1d, 0xc6, 0x94, 0x4a, 0x4e, + 0x24, 0xf4, 0x7f, 0x65, 0xc0, 0x30, 0xd3, 0xb6, 0x9b, 0xaf, 0x3d, 0xa1, 0x1a, 0xe9, 0x86, 0xa6, + 0x91, 0xa6, 0x94, 0x9b, 0x74, 0x38, 0x2f, 0x5f, 0x3b, 0x46, 0x17, 0x1d, 0x18, 0x00, 0x09, 0x32, + 0x79, 0x17, 0x46, 0x44, 0x46, 0x27, 0x11, 0xfb, 0xa1, 0x5e, 0xcd, 0x93, 0x19, 0x23, 0x63, 0x63, + 0xd1, 0xef, 0xa4, 0xad, 0x6b, 0x49, 0x4d, 0x16, 0x92, 0xeb, 0x0b, 0xea, 0x5d, 0x70, 0xc6, 0x66, + 0xde, 0x6f, 0xf3, 0xab, 0x5a, 0x4a, 0xee, 0xc9, 0x3e, 0xf7, 0x18, 0xaa, 0xc2, 0x3f, 0x94, 0x3f, + 0x8a, 0xc9, 0x19, 0xc1, 0x24, 0xdb, 0x75, 0xf4, 0x8b, 0x13, 0xfc, 0xf2, 0x93, 0xfc, 0xb0, 0xb7, + 0xa0, 0x74, 0xcb, 0x0f, 0x1e, 0x38, 0x81, 0x8b, 0xf1, 0x19, 0xd8, 0x4c, 0x9e, 0x46, 0x6d, 0x7c, + 0x9b, 0xc3, 0x6d, 0x0c, 0xed, 0xf8, 0xf0, 0xa0, 0x52, 0xa8, 0xf9, 0x7e, 0xd3, 0xd2, 0xd0, 0xc9, + 0x2a, 0x8c, 0xdf, 0x75, 0x1e, 0x8a, 0xa3, 0xd6, 0xf5, 0xf5, 0x65, 0x11, 0xf6, 0xf5, 0xd2, 0xe1, + 0x41, 0xe5, 0x5c, 0xcb, 0x79, 0x18, 0x1f, 0xd1, 0xf6, 0xbf, 0x61, 0xa1, 0xd3, 0x13, 0x0f, 0x26, + 0xd6, 0xfc, 0x20, 0x12, 0x95, 0xb0, 0xad, 0x41, 0xbe, 0xcf, 0x61, 0xdd, 0xb5, 0xcc, 0xc3, 0xba, + 0x73, 0x6c, 0x3f, 0x64, 0x6f, 0xc7, 0xe4, 0xda, 0x8d, 0x5d, 0x8d, 0x31, 0x79, 0x0b, 0xa6, 0xe6, + 0x69, 0x10, 0x79, 0xdb, 0x5e, 0xc3, 0x89, 0xe8, 0x2d, 0x3f, 0x68, 0x39, 0x91, 0xf0, 0x4b, 0xa1, + 0x5f, 0xa2, 0x41, 0x39, 0xa7, 0x96, 0x13, 0x59, 0xbd, 0x98, 0xe4, 0x8b, 0x59, 0x81, 0x74, 0x43, + 0xd8, 0xfc, 0x57, 0x99, 0x35, 0x92, 0x11, 0x48, 0xd7, 0xa7, 0x0b, 0x32, 0x42, 0xea, 0x76, 0x8e, + 0x3a, 0xb1, 0x2e, 0xd6, 0xae, 0x8b, 0xd3, 0xf3, 0xe3, 0x4f, 0xa4, 0xe3, 0x71, 0xeb, 0x73, 0x32, + 0x3d, 0x07, 0xf9, 0xda, 0xda, 0x2d, 0xf4, 0x34, 0x89, 0x13, 0x62, 0xda, 0xde, 0x75, 0xda, 0x0d, + 0x34, 0xa2, 0x44, 0xd8, 0x89, 0xaa, 0xf0, 0x6a, 0x6b, 0xb7, 0x88, 0x03, 0xd3, 0x6b, 0x34, 0x68, + 0x79, 0xd1, 0xe7, 0xaf, 0x5f, 0x57, 0x06, 0xaa, 0x88, 0x9f, 0x76, 0x4d, 0x7c, 0x5a, 0xa5, 0x83, + 0x28, 0xf6, 0xc3, 0xeb, 0xd7, 0x33, 0x87, 0x23, 0xfe, 0xb0, 0x2c, 0x5e, 0x64, 0x11, 0x26, 0xee, + 0x3a, 0x0f, 0x93, 0x68, 0xa1, 0x50, 0x84, 0x24, 0x3f, 0x2d, 0x05, 0x2b, 0x89, 0x34, 0x52, 0xe7, + 0x5b, 0x8a, 0x88, 0xbc, 0x09, 0x63, 0x89, 0x78, 0x85, 0x78, 0x8a, 0x9c, 0xe7, 0x91, 0xd6, 0x8a, + 0x70, 0x6a, 0x2e, 0x39, 0x05, 0x9d, 0x6c, 0xc4, 0x9e, 0x0e, 0x6e, 0x09, 0x8b, 0x6c, 0x50, 0xd7, + 0x54, 0x4f, 0x87, 0x83, 0x25, 0x5a, 0xb3, 0x26, 0xe3, 0xbd, 0x01, 0x0f, 0x9f, 0xb2, 0x74, 0x2e, + 0x8a, 0x03, 0x65, 0x2d, 0xf0, 0x5b, 0x9d, 0x08, 0x03, 0x91, 0x53, 0x0e, 0x94, 0x0e, 0x96, 0x64, + 0x38, 0x50, 0x38, 0x49, 0x76, 0x88, 0xc4, 0xf8, 0x23, 0x84, 0x48, 0x50, 0x28, 0x2c, 0xfb, 0x8d, + 0x3d, 0x8c, 0x3c, 0x1e, 0xad, 0xbd, 0xcf, 0xf4, 0x47, 0xd3, 0x6f, 0xec, 0x3d, 0xbe, 0xa3, 0x7d, + 0x64, 0x4f, 0x56, 0x58, 0xdb, 0x99, 0x58, 0x89, 0xaa, 0x71, 0xfb, 0x99, 0x1c, 0x58, 0x6a, 0x65, + 0xdc, 0x50, 0xe1, 0x52, 0x28, 0x1b, 0x62, 0xe9, 0xe4, 0x84, 0x42, 0x79, 0x81, 0x86, 0x7b, 0x91, + 0xdf, 0x99, 0x6f, 0x7a, 0x9d, 0x2d, 0xdf, 0x09, 0x5c, 0xdc, 0x9c, 0x66, 0x29, 0x8c, 0x17, 0x33, + 0x15, 0xc6, 0x94, 0xcb, 0xe9, 0xed, 0x86, 0x64, 0x60, 0xf5, 0xb0, 0x24, 0x5f, 0x84, 0x09, 0x36, + 0x5b, 0x16, 0x1f, 0x46, 0xb4, 0xcd, 0x45, 0x69, 0x0a, 0x97, 0xfa, 0x19, 0xe5, 0xee, 0x72, 0x5c, + 0xc8, 0x85, 0x14, 0xb5, 0x07, 0x8d, 0x09, 0x54, 0x21, 0xd5, 0x59, 0x11, 0x17, 0x66, 0xef, 0x3a, + 0x0f, 0x95, 0x44, 0x64, 0x8a, 0xd4, 0x13, 0x94, 0x58, 0xcc, 0xf5, 0xc9, 0x24, 0x76, 0x2f, 0x46, + 0xea, 0x33, 0x01, 0xfa, 0x72, 0x22, 0x5f, 0x87, 0xb3, 0xa2, 0x59, 0x0b, 0x98, 0x2e, 0xc4, 0x0f, + 0xf6, 0xeb, 0xbb, 0x0e, 0x46, 0x1e, 0x4e, 0x9f, 0x4c, 0xc3, 0xca, 0x0e, 0x73, 0x25, 0x1f, 0x3b, + 0xe4, 0x8c, 0xac, 0x7e, 0x35, 0x90, 0xaf, 0xc2, 0x04, 0xf7, 0x49, 0xde, 0xf6, 0xc3, 0x08, 0x77, + 0x8e, 0x33, 0x7d, 0xea, 0xbc, 0x94, 0x59, 0x67, 0x99, 0x3b, 0x3a, 0x79, 0x08, 0x1a, 0xba, 0x65, + 0x53, 0xfc, 0xc8, 0x1b, 0x30, 0xb6, 0xe6, 0xb5, 0xeb, 0x7c, 0x2b, 0xb7, 0x36, 0x7b, 0x3a, 0x59, + 0xc6, 0x3a, 0x5e, 0xdb, 0x96, 0xce, 0x91, 0x4e, 0xac, 0x75, 0x54, 0x6c, 0xf3, 0x5f, 0xe4, 0x52, + 0x62, 0x49, 0x96, 0x60, 0x44, 0xb4, 0x45, 0x2c, 0xfc, 0xbd, 0x5f, 0xfa, 0x74, 0xe6, 0x97, 0x8e, + 0x88, 0xde, 0xb1, 0x24, 0x3d, 0x79, 0xc0, 0x58, 0x6d, 0x3b, 0xdd, 0xa6, 0xcc, 0x42, 0xf9, 0x65, + 0x2e, 0x75, 0x08, 0xd2, 0xe6, 0xd7, 0xc2, 0xc9, 0x03, 0xb8, 0xf4, 0xf8, 0x40, 0x9c, 0x68, 0xb2, + 0x36, 0xb2, 0xc7, 0xaf, 0x63, 0xe7, 0xe3, 0xa0, 0x1d, 0xfd, 0xee, 0xf5, 0x63, 0xab, 0x90, 0xd5, + 0x62, 0xfe, 0x33, 0x03, 0xc6, 0x35, 0xb9, 0x26, 0x37, 0x95, 0x10, 0xb7, 0x24, 0xdc, 0x58, 0xc3, + 0xc9, 0x7c, 0x07, 0xeb, 0xa6, 0x88, 0x6b, 0xcc, 0xf5, 0xa7, 0xcb, 0x4c, 0xf6, 0x79, 0xe4, 0x86, + 0x3b, 0x49, 0x5a, 0x53, 0xe8, 0x93, 0xb4, 0xe6, 0x5b, 0x13, 0x30, 0xa1, 0x5b, 0x52, 0x6c, 0x6b, + 0x83, 0xce, 0x2f, 0xe9, 0x99, 0xe1, 0x69, 0x98, 0x10, 0xa2, 0x3d, 0x2a, 0x85, 0x10, 0xf2, 0x02, + 0x40, 0x1c, 0x4a, 0x21, 0x9d, 0x2f, 0xe2, 0x09, 0x2c, 0xa5, 0x80, 0x7c, 0x05, 0x60, 0xc5, 0x77, + 0x69, 0x9c, 0xc9, 0xeb, 0x08, 0x07, 0xf0, 0x8b, 0xc2, 0x01, 0x2c, 0x9e, 0xad, 0x3a, 0x3c, 0xa8, + 0x9c, 0x6e, 0xfb, 0x2e, 0xed, 0x4d, 0xe1, 0xa5, 0x70, 0x24, 0x9f, 0x85, 0x21, 0xab, 0xdb, 0xa4, + 0x32, 0xb1, 0xd4, 0x98, 0xd4, 0xac, 0xdd, 0xa6, 0x92, 0x99, 0x3e, 0xe8, 0xa6, 0xcf, 0xfd, 0x18, + 0x80, 0xbc, 0x03, 0xc0, 0x94, 0x07, 0x66, 0x21, 0x96, 0x99, 0x2b, 0xd0, 0x51, 0xa3, 0xe8, 0x1d, + 0xcc, 0x5d, 0xac, 0x55, 0x9e, 0x90, 0x90, 0x55, 0x18, 0x11, 0xeb, 0x94, 0x38, 0x57, 0x7b, 0x26, + 0xcb, 0xa3, 0xab, 0x18, 0xab, 0x22, 0xd3, 0x13, 0x82, 0x75, 0x27, 0x2b, 0x77, 0x34, 0xbd, 0x09, + 0xa3, 0x8c, 0x3d, 0x4f, 0xb5, 0xce, 0x8d, 0x14, 0x8c, 0x1b, 0x57, 0x3e, 0x28, 0x9d, 0x6d, 0x3d, + 0x21, 0x20, 0x5f, 0xc4, 0xdc, 0x6c, 0xa2, 0xab, 0x8f, 0x3c, 0x18, 0xb8, 0xd4, 0xd3, 0xd5, 0x33, + 0x4e, 0xa7, 0x93, 0x91, 0x6b, 0x33, 0xe6, 0x47, 0x76, 0xe2, 0x3b, 0xa2, 0xf1, 0x9b, 0x26, 0x47, + 0x54, 0x70, 0xa5, 0xa7, 0x82, 0x59, 0x79, 0xed, 0xb1, 0x37, 0x23, 0x9b, 0xc6, 0x97, 0x74, 0xa0, + 0x9c, 0xa8, 0x74, 0x51, 0x17, 0x1c, 0x55, 0xd7, 0xab, 0x3d, 0x75, 0xa9, 0x03, 0xd8, 0x53, 0x5d, + 0x0f, 0x77, 0xe2, 0x26, 0x4f, 0x49, 0x88, 0xfa, 0xc6, 0x8e, 0xaa, 0xef, 0x85, 0x9e, 0xfa, 0xa6, + 0xdd, 0xad, 0xde, 0x7a, 0x52, 0x3c, 0xc9, 0x9b, 0x30, 0x2e, 0x21, 0x38, 0x3f, 0x44, 0xde, 0x4c, + 0xfe, 0x08, 0xca, 0x16, 0x06, 0x96, 0xea, 0xe9, 0xc8, 0x54, 0x64, 0x95, 0x9a, 0x4b, 0xc7, 0xb8, + 0x46, 0x9d, 0x96, 0x0a, 0x1d, 0x99, 0x7c, 0x01, 0xc6, 0x96, 0x5a, 0xac, 0x21, 0x7e, 0xdb, 0x89, + 0x28, 0x5a, 0x3d, 0xc9, 0x21, 0x87, 0x52, 0xa2, 0x88, 0x2a, 0x4f, 0xcb, 0x9c, 0x14, 0xa9, 0x56, + 0xa3, 0x42, 0xc1, 0x3a, 0x8f, 0x3b, 0x18, 0x85, 0x0c, 0x87, 0xc2, 0xc6, 0x79, 0x3a, 0xe3, 0xa0, + 0x41, 0x61, 0x8f, 0x46, 0x03, 0xf7, 0x5b, 0xda, 0x62, 0x42, 0x68, 0x9d, 0xa7, 0xf3, 0x24, 0x6f, + 0xc1, 0x98, 0xb8, 0x91, 0x5f, 0xb5, 0x56, 0xc2, 0xd9, 0x72, 0xf2, 0x0a, 0x81, 0xbc, 0xbc, 0x6f, + 0x3b, 0x41, 0xea, 0xb4, 0x39, 0xc1, 0x27, 0x9f, 0x87, 0x99, 0x7b, 0x5e, 0xdb, 0xf5, 0x1f, 0x84, + 0x62, 0x99, 0x12, 0x8a, 0x6e, 0x2a, 0x89, 0xa9, 0x7b, 0xc0, 0xcb, 0x6d, 0xb9, 0xdc, 0xf7, 0x28, + 0xbe, 0x4c, 0x0e, 0xe4, 0xa7, 0x7a, 0x38, 0x73, 0x09, 0x22, 0x47, 0x49, 0xd0, 0x5c, 0x8f, 0x04, + 0xf5, 0x56, 0x9f, 0x16, 0xa7, 0xcc, 0x6a, 0x88, 0x0f, 0x44, 0x37, 0x6e, 0xdf, 0xf3, 0xbd, 0xf6, + 0xec, 0xb4, 0xf6, 0x62, 0x60, 0xbc, 0x8a, 0x21, 0xde, 0x9a, 0xdf, 0xf4, 0x1a, 0xfb, 0x32, 0xd7, + 0xbb, 0x6e, 0x36, 0x7f, 0xe0, 0x6b, 0x5e, 0xac, 0x0c, 0xd6, 0xe4, 0x0b, 0x50, 0x62, 0x7f, 0xe3, + 0x3d, 0xc6, 0x8c, 0x76, 0x34, 0xad, 0x60, 0x8a, 0x7a, 0x70, 0x8c, 0x30, 0x65, 0x40, 0xc6, 0xf6, + 0x43, 0x63, 0x45, 0x5e, 0x07, 0x60, 0xf6, 0x8d, 0x50, 0xc7, 0xa7, 0x93, 0xbc, 0x0e, 0x68, 0x06, + 0xf5, 0x2a, 0xe2, 0x04, 0x99, 0x6d, 0x7c, 0xd8, 0xaf, 0x7a, 0xd7, 0xf5, 0xd9, 0xdc, 0x38, 0x83, + 0xb4, 0xb8, 0xf1, 0x41, 0xda, 0x90, 0xc3, 0x55, 0xe9, 0x50, 0xd0, 0xcd, 0x1f, 0x19, 0x30, 0x93, + 0xd5, 0x49, 0xc7, 0x24, 0x86, 0x33, 0x53, 0xd1, 0x31, 0xe8, 0x79, 0xe3, 0xd1, 0x31, 0x71, 0x4c, + 0x4c, 0x05, 0x86, 0xee, 0x78, 0x6d, 0x57, 0x46, 0x6f, 0xe2, 0x3a, 0xbc, 0xc7, 0x00, 0x16, 0x87, + 0x33, 0x04, 0x7e, 0xb9, 0x84, 0x2d, 0xd4, 0x43, 0x1c, 0x01, 0xef, 0x92, 0x58, 0x1c, 0xce, 0x10, + 0xd8, 0x7a, 0x2f, 0xd7, 0x27, 0x44, 0x60, 0x66, 0x40, 0x68, 0x71, 0x38, 0xb9, 0x04, 0x23, 0xab, + 0xed, 0x65, 0xea, 0xdc, 0xa7, 0xe2, 0x68, 0x1a, 0x3d, 0x85, 0x7e, 0xdb, 0x6e, 0x32, 0x98, 0x25, + 0x0b, 0xcd, 0xef, 0x19, 0x30, 0xd5, 0x33, 0x3e, 0xc7, 0xe7, 0xbe, 0x3b, 0x3a, 0x0e, 0x60, 0x90, + 0xf6, 0xf1, 0xcf, 0x2f, 0x64, 0x7f, 0xbe, 0xf9, 0xbb, 0x05, 0x38, 0xdb, 0x67, 0xb9, 0x4c, 0x62, + 0x78, 0x8c, 0x63, 0x63, 0x78, 0xbe, 0xc4, 0x96, 0x27, 0xc7, 0x6b, 0x85, 0xeb, 0x7e, 0xf2, 0xc5, + 0xc9, 0x71, 0x27, 0x96, 0xc9, 0xe4, 0x52, 0x32, 0x11, 0xd2, 0xb9, 0x06, 0x52, 0xd8, 0x91, 0xdf, + 0x73, 0x1c, 0xa3, 0x33, 0xeb, 0x89, 0xa2, 0xc9, 0xff, 0x35, 0x89, 0xa2, 0xd1, 0xcf, 0xae, 0x0b, + 0x8f, 0xf5, 0xec, 0x3a, 0xfb, 0xfc, 0x69, 0xe8, 0x51, 0x0e, 0x7c, 0xe7, 0x61, 0xbc, 0x4e, 0x9d, + 0xa0, 0xb1, 0x5b, 0x0d, 0xf9, 0x20, 0xf1, 0x24, 0xbd, 0xb8, 0x16, 0x84, 0x58, 0x60, 0x3b, 0x61, + 0xef, 0x58, 0x68, 0x34, 0xe6, 0xbf, 0x4d, 0x05, 0xff, 0xfc, 0x75, 0x94, 0x97, 0x97, 0x60, 0xe8, + 0xde, 0x2e, 0x0d, 0xa4, 0x75, 0x8e, 0x1f, 0xf2, 0x80, 0x01, 0xd4, 0x0f, 0x41, 0x0c, 0xf3, 0xeb, + 0x50, 0x52, 0x2b, 0x43, 0x85, 0xc0, 0x7e, 0x8b, 0x19, 0xc9, 0x15, 0x02, 0x03, 0x58, 0x1c, 0x7e, + 0x6c, 0x3e, 0xca, 0xa4, 0x17, 0xf2, 0xc7, 0xf5, 0x02, 0xab, 0x1c, 0xe5, 0x4d, 0xa9, 0x1c, 0x7f, + 0xab, 0x95, 0x47, 0x0c, 0x60, 0x71, 0xf8, 0x63, 0xad, 0xfc, 0x5f, 0x1a, 0x50, 0xc0, 0x5c, 0x40, + 0xaf, 0xc1, 0xa8, 0x3c, 0xce, 0x50, 0xf3, 0xe3, 0x4c, 0xcb, 0xd3, 0x8e, 0x50, 0x0f, 0xdd, 0x12, + 0x40, 0x56, 0xd5, 0x26, 0x0d, 0xb6, 0xb4, 0x08, 0xbf, 0xfb, 0x0c, 0xa0, 0x56, 0x85, 0x18, 0x27, + 0x18, 0x0f, 0x8c, 0x62, 0x14, 0xde, 0x08, 0xae, 0xb2, 0x78, 0x14, 0x63, 0x8f, 0xeb, 0x41, 0x62, + 0x99, 0xbf, 0x62, 0xc0, 0xe9, 0x4c, 0x13, 0x8a, 0xd5, 0xca, 0x6d, 0x35, 0x45, 0x1c, 0xd3, 0x86, + 0x1a, 0xc7, 0x38, 0x49, 0xb4, 0xe2, 0x09, 0x64, 0xeb, 0x59, 0x18, 0x8d, 0x37, 0xf0, 0x64, 0x46, + 0x0e, 0x1d, 0xfa, 0xbc, 0xe5, 0x3e, 0xf0, 0xaf, 0x0c, 0x18, 0x66, 0x9f, 0xf0, 0xc4, 0x5e, 0x5e, + 0xcb, 0x3e, 0x01, 0x61, 0x4d, 0x1a, 0xe8, 0xca, 0xda, 0x6f, 0x0e, 0x03, 0x24, 0xc8, 0x64, 0x0b, + 0x26, 0x56, 0x97, 0x16, 0xe6, 0x97, 0x5c, 0xda, 0x8e, 0x30, 0x04, 0x20, 0x95, 0x60, 0x87, 0xed, + 0xc9, 0x83, 0xb6, 0xd3, 0x14, 0x08, 0xfb, 0x89, 0x6e, 0xf0, 0x3d, 0xb7, 0x61, 0x7b, 0x31, 0x9d, + 0x6a, 0xcb, 0xea, 0x1c, 0x59, 0x1d, 0xf5, 0xea, 0xdd, 0x65, 0xa5, 0x8e, 0xdc, 0x80, 0x75, 0x84, + 0x4e, 0xab, 0xd9, 0xa7, 0x0e, 0x9d, 0x23, 0xd9, 0x85, 0xf2, 0xbb, 0xb8, 0xfa, 0x28, 0xb5, 0xe4, + 0x8f, 0xae, 0xe5, 0x39, 0x51, 0xcb, 0x53, 0x7c, 0xd9, 0xca, 0xae, 0xa7, 0x87, 0x6b, 0x22, 0xb9, + 0x85, 0x63, 0x25, 0xf7, 0xff, 0x33, 0x60, 0x98, 0x2f, 0x6f, 0xf1, 0xd3, 0x81, 0x99, 0x0b, 0xe8, + 0xbd, 0xc7, 0xb3, 0x80, 0x96, 0x51, 0x73, 0x69, 0xbe, 0x0b, 0x5e, 0x46, 0x16, 0x52, 0xef, 0x10, + 0xca, 0x63, 0x2e, 0xb4, 0xe9, 0x79, 0x49, 0x12, 0xf3, 0xc9, 0x9f, 0x20, 0x54, 0xb9, 0x70, 0x0c, + 0xf5, 0x29, 0xf5, 0x91, 0x47, 0x7c, 0x4a, 0x7d, 0x19, 0x46, 0x45, 0x10, 0x63, 0x6d, 0x5f, 0xec, + 0xdc, 0xa5, 0x07, 0x2e, 0x86, 0x2b, 0xcf, 0x62, 0x70, 0x90, 0xbd, 0xa5, 0x65, 0x8d, 0x8d, 0x11, + 0xc9, 0x2a, 0x8c, 0x26, 0x37, 0xef, 0xf4, 0x4b, 0xe3, 0x31, 0x5c, 0x44, 0xf9, 0xcb, 0x48, 0xa8, + 0x8c, 0x8b, 0x76, 0x09, 0x0f, 0xf3, 0xdb, 0x06, 0x94, 0xd3, 0xf2, 0x82, 0xef, 0x1f, 0xc9, 0xcb, + 0x8f, 0x71, 0xf0, 0x11, 0x7f, 0xff, 0x28, 0xbe, 0x2d, 0xa9, 0x85, 0x21, 0xa9, 0xe8, 0x64, 0x0e, + 0x8a, 0x6c, 0xda, 0xb5, 0x53, 0x0f, 0x20, 0x75, 0x05, 0x4c, 0x3d, 0x7b, 0x97, 0x78, 0xca, 0xac, + 0xfd, 0xf7, 0x79, 0x18, 0x53, 0x06, 0x8b, 0xbc, 0x04, 0xc5, 0xa5, 0x70, 0xd9, 0x6f, 0xec, 0x51, + 0x57, 0x1c, 0xe9, 0xe1, 0x4b, 0xf9, 0x5e, 0x68, 0x37, 0x11, 0x68, 0xc5, 0xc5, 0xa4, 0x06, 0xe3, + 0xfc, 0x3f, 0x99, 0xb8, 0x20, 0x97, 0x1c, 0x47, 0x70, 0x64, 0x99, 0xb2, 0x40, 0x5d, 0xde, 0x35, + 0x12, 0xf2, 0x65, 0x00, 0x0e, 0x60, 0xe3, 0x3b, 0xc0, 0x1d, 0x06, 0x39, 0x81, 0x4f, 0x8b, 0x0a, + 0x22, 0x4f, 0x6d, 0x21, 0x8a, 0x82, 0xc2, 0x10, 0x5f, 0xe9, 0xf6, 0x1b, 0x7b, 0x83, 0xbf, 0xd3, + 0x9f, 0xbc, 0xd2, 0xed, 0x37, 0xf6, 0xec, 0xec, 0x80, 0x56, 0x95, 0x25, 0xf9, 0x8e, 0x01, 0xe7, + 0x2d, 0xda, 0xf0, 0xef, 0xd3, 0x60, 0xbf, 0x1a, 0x21, 0x96, 0x5a, 0xe3, 0xf1, 0xd1, 0xb3, 0x37, + 0x44, 0x8d, 0x2f, 0x06, 0x82, 0x0b, 0xde, 0xbc, 0x6b, 0x75, 0x22, 0xfb, 0x88, 0x4f, 0x38, 0xa2, + 0x4a, 0xf3, 0x3f, 0x1a, 0xca, 0x14, 0x20, 0x2b, 0x30, 0x1a, 0x0b, 0x8b, 0xf0, 0x48, 0xc7, 0x96, + 0x99, 0x84, 0x5b, 0x74, 0xbb, 0xf6, 0x94, 0x38, 0x7d, 0x9b, 0x8e, 0x45, 0x4e, 0x9b, 0x11, 0x12, + 0x48, 0x3e, 0x07, 0x05, 0x1c, 0xaa, 0xe3, 0xf3, 0x4c, 0xca, 0xa5, 0xa6, 0xc0, 0xc6, 0x08, 0xbf, + 0x1a, 0x29, 0xc9, 0xa7, 0x44, 0x08, 0x58, 0x5e, 0xcb, 0xe0, 0xce, 0x40, 0xec, 0x3b, 0xe2, 0x35, + 0x26, 0x89, 0xa1, 0x56, 0xa4, 0xf5, 0xff, 0xcf, 0x41, 0x39, 0x3d, 0xf1, 0xc8, 0x3b, 0x50, 0x92, + 0xb7, 0x28, 0x6f, 0x3b, 0x22, 0xd9, 0x42, 0x49, 0x24, 0x3b, 0x10, 0x70, 0x7b, 0xd7, 0xd1, 0xb2, + 0x87, 0x6a, 0x04, 0x6c, 0x41, 0x5e, 0x17, 0x57, 0x73, 0x94, 0x09, 0x14, 0xf9, 0x51, 0x27, 0x95, + 0x15, 0x5a, 0xa2, 0x91, 0xd7, 0x20, 0xcf, 0xaf, 0x16, 0xab, 0x29, 0x05, 0xef, 0xde, 0xaa, 0xf2, + 0x9b, 0x91, 0x3c, 0xe0, 0x43, 0x3f, 0x39, 0x63, 0xf8, 0x64, 0x59, 0xb9, 0x98, 0x3a, 0xac, 0xa5, + 0x56, 0x93, 0xe0, 0xb8, 0x71, 0xc7, 0xdf, 0x50, 0x7d, 0xaf, 0x50, 0xcc, 0x97, 0x0b, 0xe2, 0x2a, + 0xe2, 0x6f, 0xe7, 0x61, 0x34, 0xae, 0x9f, 0x10, 0x40, 0x7b, 0x43, 0x44, 0x6e, 0xe0, 0xff, 0xe4, + 0x1c, 0x14, 0xa5, 0x89, 0x21, 0xa2, 0x37, 0x46, 0x42, 0x61, 0x5e, 0xcc, 0x82, 0xb4, 0x25, 0xb8, + 0x79, 0x61, 0xc9, 0x9f, 0xe4, 0x3a, 0xc4, 0x86, 0x42, 0x3f, 0x8b, 0xa2, 0xc0, 0x06, 0xcc, 0x8a, + 0xd1, 0xc8, 0x04, 0xe4, 0x3c, 0x7e, 0xed, 0x62, 0xd4, 0xca, 0x79, 0x2e, 0x79, 0x07, 0x8a, 0x8e, + 0xeb, 0x52, 0xd7, 0x76, 0xa4, 0x6b, 0xf7, 0x28, 0xa1, 0x29, 0x32, 0x6e, 0x5c, 0xa3, 0x23, 0x55, + 0x35, 0x22, 0x55, 0x18, 0xc5, 0x27, 0xf3, 0xbb, 0xe1, 0x40, 0xef, 0xec, 0x27, 0x1c, 0x8a, 0x8c, + 0x6c, 0x23, 0xa4, 0x2e, 0x79, 0x11, 0x0a, 0x6c, 0x34, 0xc5, 0x7a, 0x10, 0x27, 0x8a, 0x5d, 0x5d, + 0x5f, 0xe3, 0x1d, 0x76, 0xfb, 0x94, 0x85, 0x08, 0xe4, 0x79, 0xc8, 0x77, 0xe7, 0xb6, 0x85, 0xa6, + 0x2f, 0x27, 0xb7, 0xce, 0x63, 0x34, 0x56, 0x4c, 0x6e, 0x40, 0xf1, 0x81, 0x7e, 0xbf, 0xf8, 0x74, + 0x6a, 0x18, 0x63, 0xfc, 0x18, 0xb1, 0x56, 0x84, 0x61, 0x7e, 0xb3, 0xd6, 0x7c, 0x06, 0x20, 0xa9, + 0xba, 0x37, 0xc8, 0xc6, 0xfc, 0x32, 0x8c, 0xc6, 0x55, 0x92, 0xa7, 0x01, 0xf6, 0xe8, 0xbe, 0xbd, + 0xeb, 0xb4, 0x5d, 0xf1, 0xe8, 0x5a, 0xc9, 0x1a, 0xdd, 0xa3, 0xfb, 0xb7, 0x11, 0x40, 0xce, 0xc2, + 0x48, 0x87, 0x8d, 0xaa, 0xcc, 0x69, 0x6e, 0x0d, 0x77, 0xba, 0x5b, 0x4c, 0x42, 0x67, 0x61, 0x04, + 0x9d, 0x1f, 0x62, 0xa2, 0x8d, 0x5b, 0xf2, 0xa7, 0xf9, 0xeb, 0x39, 0xcc, 0x12, 0xa3, 0x7c, 0x27, + 0x79, 0x0e, 0xc6, 0x1b, 0x01, 0xc5, 0xe5, 0xc8, 0x61, 0x66, 0x91, 0xa8, 0xa7, 0x94, 0x00, 0x97, + 0x5c, 0x72, 0x09, 0x26, 0x93, 0x24, 0xeb, 0x76, 0x63, 0x4b, 0x64, 0x17, 0x28, 0x59, 0xe3, 0x1d, + 0x99, 0x65, 0x7d, 0x7e, 0x0b, 0xaf, 0x0b, 0x95, 0xd5, 0x5b, 0xb5, 0x91, 0x4c, 0x98, 0x3e, 0x6a, + 0x4d, 0x2a, 0x70, 0x3c, 0xb1, 0x39, 0x03, 0xc3, 0x8e, 0xb3, 0xd3, 0xf5, 0xf8, 0xd5, 0x85, 0x92, + 0x25, 0x7e, 0x91, 0x97, 0x61, 0x2a, 0xf4, 0x76, 0xda, 0x4e, 0xd4, 0x0d, 0x44, 0x9a, 0x1e, 0x1a, + 0xa0, 0x48, 0x8d, 0x5b, 0xe5, 0xb8, 0x60, 0x9e, 0xc3, 0xc9, 0xab, 0x40, 0xd4, 0xfa, 0xfc, 0xad, + 0x0f, 0x68, 0x83, 0x8b, 0x5a, 0xc9, 0x9a, 0x52, 0x4a, 0x56, 0xb1, 0x80, 0x3c, 0x0b, 0xa5, 0x80, + 0x86, 0x68, 0x92, 0x61, 0xb7, 0x61, 0x12, 0x35, 0x6b, 0x4c, 0xc2, 0xee, 0xd0, 0x7d, 0xb3, 0x06, + 0x53, 0x3d, 0xf3, 0x91, 0xbc, 0xca, 0xad, 0x7b, 0xb1, 0x3e, 0x97, 0xf8, 0x66, 0x06, 0x1f, 0x65, + 0xd4, 0x96, 0x66, 0x81, 0x64, 0xb6, 0xa1, 0xa4, 0xea, 0xd7, 0x63, 0xf2, 0x36, 0x9c, 0xc1, 0xa8, + 0x63, 0xae, 0x7c, 0x86, 0x0f, 0x0f, 0x2a, 0x39, 0xcf, 0xc5, 0x58, 0xe3, 0xcb, 0x50, 0x94, 0x56, + 0x82, 0xfa, 0x40, 0x98, 0x30, 0x28, 0xf7, 0xad, 0xb8, 0xd4, 0x7c, 0x11, 0x46, 0x84, 0x0a, 0x3d, + 0xda, 0x11, 0x65, 0x7e, 0x23, 0x07, 0x93, 0x16, 0x65, 0x13, 0x5c, 0x3c, 0xbd, 0xf5, 0x09, 0x4b, + 0x37, 0xaf, 0xb5, 0xed, 0x88, 0x34, 0x29, 0xbf, 0x63, 0xc0, 0x74, 0x06, 0xee, 0x47, 0xca, 0x4f, + 0x79, 0x13, 0x46, 0x17, 0x3c, 0xa7, 0x59, 0x75, 0xdd, 0x38, 0x7a, 0x1a, 0xad, 0x41, 0x97, 0x4d, + 0x27, 0x87, 0x41, 0xd5, 0xc5, 0x34, 0x46, 0x25, 0x57, 0x84, 0x50, 0x24, 0x19, 0x74, 0x65, 0x42, + 0x7b, 0xe0, 0xdf, 0x94, 0xa4, 0xb3, 0xc7, 0x1b, 0xb7, 0x1c, 0x98, 0x1c, 0xce, 0x3f, 0xb1, 0x43, + 0x97, 0x7d, 0xe3, 0x36, 0xdd, 0xbc, 0x81, 0xb6, 0x9d, 0xdf, 0xce, 0xc1, 0x99, 0x6c, 0xc2, 0x8f, + 0x9a, 0x6a, 0x14, 0x73, 0xd4, 0x28, 0x6f, 0x06, 0x60, 0xaa, 0x51, 0x9e, 0xd0, 0x06, 0xf1, 0x13, + 0x04, 0xb2, 0x0d, 0xe3, 0xcb, 0x4e, 0x18, 0xdd, 0xa6, 0x4e, 0x10, 0x6d, 0x51, 0x27, 0x1a, 0xc0, + 0x82, 0x7d, 0x5e, 0xbe, 0xab, 0x84, 0x8b, 0xda, 0xae, 0xa4, 0x4c, 0x19, 0x78, 0x3a, 0xdb, 0x58, + 0x50, 0x0a, 0x03, 0x08, 0xca, 0xd7, 0x60, 0xb2, 0x4e, 0x5b, 0x4e, 0x67, 0xd7, 0x0f, 0xa8, 0xf0, + 0x9d, 0x5f, 0x85, 0xf1, 0x18, 0x94, 0x29, 0x2d, 0x7a, 0xb1, 0x86, 0xaf, 0x74, 0x44, 0xa2, 0x4a, + 0xf4, 0x62, 0xf3, 0x57, 0x73, 0x70, 0xb6, 0xda, 0x10, 0x27, 0x1c, 0xa2, 0x40, 0x1e, 0xc4, 0x7e, + 0xcc, 0x75, 0x93, 0x6b, 0x30, 0x7a, 0xd7, 0x79, 0xb8, 0x4c, 0x9d, 0x90, 0x86, 0x22, 0xd1, 0x1b, + 0x37, 0xbf, 0x9c, 0x87, 0x76, 0xec, 0xf6, 0xb2, 0x12, 0x1c, 0x75, 0xb3, 0x59, 0x78, 0xc4, 0xcd, + 0xa6, 0x09, 0xc3, 0xb7, 0xfd, 0xa6, 0x2b, 0x16, 0x27, 0x71, 0x6e, 0xb1, 0x8b, 0x10, 0x4b, 0x94, + 0x98, 0x3f, 0x32, 0x60, 0x22, 0xfe, 0x62, 0xfc, 0x84, 0x8f, 0xbd, 0x4b, 0x2e, 0xc1, 0x08, 0x56, + 0x14, 0x3f, 0x2a, 0x87, 0x8b, 0x46, 0x93, 0x81, 0x6c, 0xcf, 0xb5, 0x64, 0xa1, 0xda, 0x13, 0x43, + 0x8f, 0xd6, 0x13, 0xe6, 0xdf, 0xc3, 0x23, 0x11, 0xb5, 0x95, 0x6c, 0x25, 0x52, 0x3e, 0xc4, 0x18, + 0xf0, 0x43, 0x72, 0x8f, 0x6d, 0x48, 0xf2, 0x7d, 0x87, 0xe4, 0x9b, 0x39, 0x18, 0x8b, 0x3f, 0xf6, + 0x13, 0x96, 0xaa, 0x22, 0x6e, 0xd7, 0x40, 0x37, 0x28, 0xea, 0x8a, 0xae, 0x10, 0x17, 0x15, 0x3e, + 0x07, 0xc3, 0x62, 0x32, 0x19, 0xa9, 0x03, 0xc9, 0xd4, 0xe8, 0xd6, 0x26, 0x04, 0xeb, 0x61, 0x1c, + 0xd0, 0xd0, 0x12, 0x74, 0x78, 0x45, 0xe5, 0x1e, 0xdd, 0x12, 0x27, 0x64, 0x4f, 0xec, 0x1a, 0x95, + 0x7d, 0x45, 0x25, 0x69, 0xd8, 0x40, 0xab, 0xd3, 0xdf, 0x2e, 0x40, 0x39, 0x4d, 0x72, 0x7c, 0x32, + 0x90, 0xb5, 0xee, 0x96, 0x78, 0xa2, 0x08, 0x93, 0x81, 0x74, 0xba, 0x5b, 0x16, 0x83, 0x91, 0x4b, + 0x50, 0x58, 0x0b, 0xbc, 0xfb, 0xd8, 0x6a, 0xf1, 0x42, 0x53, 0x27, 0xf0, 0xee, 0xab, 0xb1, 0xda, + 0xac, 0x1c, 0x37, 0xb4, 0xcb, 0x75, 0x0c, 0xfb, 0x45, 0xc3, 0x5a, 0x6c, 0x68, 0x9b, 0x61, 0x3a, + 0xeb, 0x94, 0x44, 0x63, 0x4b, 0x65, 0x8d, 0x3a, 0x81, 0x48, 0x5c, 0x21, 0xd4, 0x19, 0x2e, 0x95, + 0x5b, 0x08, 0xe6, 0xe9, 0xce, 0x2d, 0x15, 0x89, 0x34, 0x81, 0x28, 0x3f, 0xe5, 0x04, 0x3e, 0x7e, + 0x8f, 0x27, 0x5f, 0x16, 0x9c, 0x51, 0x59, 0xdb, 0xea, 0x6c, 0xce, 0xe0, 0xfb, 0x38, 0x7d, 0x84, + 0x6b, 0xe2, 0x1a, 0x23, 0x3a, 0x32, 0x8a, 0xc7, 0x32, 0x93, 0x71, 0xf1, 0xc0, 0xaf, 0x39, 0xc6, + 0xee, 0x8c, 0x84, 0x09, 0x79, 0x1b, 0xc6, 0xd4, 0x60, 0x6e, 0x1e, 0x72, 0x7c, 0x81, 0x5f, 0x1f, + 0xec, 0x93, 0x71, 0x53, 0x25, 0x30, 0x3f, 0xa5, 0x4a, 0x89, 0x58, 0xb4, 0x8f, 0x94, 0x12, 0xf3, + 0x97, 0xd1, 0x8c, 0x6f, 0xf9, 0x11, 0x15, 0xd6, 0xcb, 0x13, 0xab, 0xc7, 0x12, 0x17, 0xf2, 0x90, + 0x16, 0x4c, 0xa3, 0xb5, 0x8e, 0x63, 0x6c, 0xde, 0x48, 0x94, 0x0e, 0x77, 0x26, 0x4b, 0x17, 0xb2, + 0x32, 0xe5, 0x7e, 0xcb, 0x80, 0xd3, 0x99, 0xb4, 0xe4, 0x2a, 0x40, 0x62, 0x23, 0x8a, 0x5e, 0xe2, + 0x79, 0xe4, 0x63, 0xa8, 0xa5, 0x60, 0x90, 0x2f, 0xa5, 0xad, 0xbb, 0xe3, 0x17, 0x27, 0xf9, 0xda, + 0xd2, 0x84, 0x6e, 0xdd, 0x65, 0xd8, 0x74, 0xe6, 0xef, 0xe4, 0x61, 0xaa, 0xe7, 0x11, 0xe1, 0x63, + 0xa2, 0x08, 0xf6, 0x52, 0x6f, 0x40, 0xf2, 0xe3, 0x8e, 0x2b, 0xfd, 0x9e, 0x30, 0xce, 0x78, 0x11, + 0x12, 0xdd, 0x62, 0xe2, 0x09, 0x83, 0x63, 0x1e, 0x86, 0x0c, 0xb3, 0x5f, 0x0f, 0x7d, 0xb9, 0x6f, + 0x6d, 0x8f, 0xe1, 0x15, 0xd1, 0xbf, 0xc6, 0x8f, 0x2c, 0xfe, 0x72, 0x0e, 0xa6, 0x7b, 0xda, 0xfc, + 0xc4, 0xce, 0xba, 0xcf, 0x69, 0xab, 0xdb, 0x33, 0xfd, 0xc6, 0x74, 0x20, 0x2b, 0xe2, 0x4f, 0x0d, + 0x38, 0xdb, 0x87, 0x92, 0xec, 0xa7, 0x85, 0x88, 0x5b, 0x15, 0xd7, 0x8f, 0xae, 0xf0, 0xb1, 0x88, + 0xd2, 0xc7, 0x26, 0x09, 0xdf, 0xc8, 0x01, 0xdc, 0xa3, 0x5b, 0x4f, 0x76, 0xa6, 0xb3, 0xcf, 0x68, + 0x02, 0xa0, 0x38, 0x30, 0x07, 0x4f, 0x74, 0xb6, 0x8a, 0x8e, 0xc4, 0xc1, 0xd3, 0x9c, 0xc5, 0x2f, + 0x4a, 0xe5, 0xb2, 0x5f, 0x94, 0x32, 0xb7, 0x60, 0xe6, 0x5d, 0x1a, 0x25, 0x2b, 0xa1, 0xdc, 0x43, + 0x1e, 0xcd, 0xf6, 0x15, 0x18, 0x15, 0xf8, 0xfa, 0xeb, 0x20, 0x32, 0x16, 0xcf, 0x73, 0xad, 0x04, + 0xc1, 0xa4, 0x70, 0x76, 0x81, 0x36, 0x69, 0x44, 0x3f, 0xde, 0x6a, 0xea, 0x40, 0x78, 0x53, 0xf8, + 0x43, 0x43, 0x03, 0xd5, 0x70, 0x6c, 0xff, 0x6c, 0xc2, 0xe9, 0xf8, 0xdb, 0x1f, 0x27, 0xdf, 0x6b, + 0xcc, 0x96, 0x10, 0xf7, 0x61, 0x13, 0x8e, 0x47, 0x38, 0x11, 0x1f, 0xc2, 0x79, 0x49, 0x70, 0xcf, + 0x8b, 0x4f, 0x62, 0x06, 0xa2, 0x25, 0x6f, 0xc2, 0x98, 0x42, 0x23, 0x6e, 0xf5, 0xe3, 0x69, 0xe7, + 0x03, 0x2f, 0xda, 0xb5, 0x43, 0x0e, 0x57, 0x4f, 0x3b, 0x15, 0x74, 0xf3, 0x8b, 0xf0, 0x54, 0x1c, + 0xb7, 0x92, 0x51, 0x75, 0x8a, 0xb9, 0x71, 0x32, 0xe6, 0x2b, 0x49, 0xb3, 0x96, 0xda, 0x71, 0xe8, + 0xbd, 0xe4, 0x4d, 0xd4, 0x66, 0x89, 0xc6, 0x5c, 0x50, 0x32, 0x40, 0x8a, 0xb5, 0x28, 0x01, 0x98, + 0x6f, 0x28, 0x1f, 0x9b, 0xc1, 0x50, 0x23, 0x36, 0xd2, 0xc4, 0xdf, 0xc8, 0xc1, 0xe4, 0xea, 0xd2, + 0xc2, 0x7c, 0xec, 0x46, 0xfe, 0x84, 0xa5, 0x61, 0xd3, 0xda, 0xd6, 0x5f, 0xdf, 0x98, 0x1b, 0x30, + 0x9d, 0xea, 0x06, 0x7c, 0x47, 0xed, 0x6d, 0x1e, 0x5f, 0x12, 0x83, 0xe5, 0xca, 0x72, 0x26, 0x8b, + 0xfd, 0xe6, 0x0d, 0x2b, 0x85, 0x6d, 0xfe, 0xa3, 0x91, 0x14, 0x5f, 0xa1, 0xc2, 0x5e, 0x81, 0xd1, + 0xa5, 0x30, 0xec, 0xd2, 0x60, 0xc3, 0x5a, 0x56, 0x6d, 0x44, 0x0f, 0x81, 0x76, 0x37, 0x68, 0x5a, + 0x09, 0x02, 0x79, 0x09, 0x8a, 0xe2, 0x0e, 0xa6, 0xd4, 0x09, 0x78, 0x5c, 0x1e, 0x5f, 0xe1, 0xb4, + 0xe2, 0x62, 0xf2, 0x1a, 0x94, 0xf8, 0xff, 0x5c, 0xda, 0x44, 0x87, 0xa3, 0xaf, 0x4a, 0xa0, 0x73, + 0xe9, 0xb4, 0x34, 0x34, 0xf2, 0x22, 0x8c, 0xc9, 0x87, 0x9a, 0xd9, 0x17, 0x71, 0x0f, 0xa0, 0xb8, + 0x1e, 0xa2, 0x96, 0x90, 0x2b, 0x90, 0xaf, 0xce, 0x5b, 0xea, 0xeb, 0x01, 0x4e, 0x23, 0xe0, 0xaf, + 0x88, 0x68, 0x0f, 0x20, 0x56, 0xe7, 0x2d, 0x32, 0x87, 0xcf, 0xfb, 0xdf, 0xf7, 0x5c, 0x1a, 0x88, + 0x50, 0x57, 0x14, 0x95, 0x8e, 0x80, 0xa5, 0x5e, 0xf7, 0x47, 0x18, 0xb9, 0x06, 0x23, 0x0b, 0x5e, + 0xd8, 0x69, 0x3a, 0xfb, 0x22, 0xe9, 0x12, 0xcf, 0xe2, 0xc2, 0x41, 0xaa, 0x70, 0x09, 0x2c, 0xf2, + 0x12, 0x0c, 0xd5, 0x1b, 0x7e, 0x87, 0x6d, 0xb1, 0xe2, 0x78, 0x96, 0x90, 0x01, 0xb4, 0x5c, 0x27, + 0x0c, 0x80, 0xb9, 0x00, 0xf8, 0x95, 0xc6, 0x51, 0x25, 0x17, 0x40, 0xfa, 0x2a, 0xa3, 0xc0, 0xe9, + 0x8d, 0x38, 0x84, 0xc7, 0x19, 0x71, 0xb8, 0x05, 0x67, 0xdf, 0x45, 0xfb, 0xbe, 0x4e, 0x03, 0xcc, + 0x73, 0xcb, 0x1f, 0xcb, 0xdb, 0xb0, 0x96, 0xc4, 0x35, 0x4e, 0xbc, 0x54, 0xc7, 0xb7, 0x00, 0x76, + 0xc8, 0x71, 0xe4, 0x3b, 0x7b, 0xa9, 0x17, 0x82, 0xfa, 0x31, 0x22, 0x9f, 0x87, 0x99, 0xac, 0x22, + 0x71, 0xa1, 0x13, 0xa3, 0xe8, 0xb3, 0x2b, 0x50, 0xc3, 0xd8, 0xb3, 0x38, 0x90, 0x65, 0x28, 0x73, + 0x78, 0xd5, 0x6d, 0x79, 0xed, 0xc5, 0x96, 0xe3, 0x35, 0xf1, 0x7a, 0xa7, 0xb8, 0xa3, 0x2b, 0xb8, + 0x3a, 0xac, 0xd0, 0xa6, 0xac, 0x54, 0x0b, 0x49, 0x4a, 0x51, 0x92, 0x5f, 0x30, 0xa0, 0xa4, 0xc8, + 0x58, 0x28, 0xee, 0x3b, 0xf4, 0x7b, 0x75, 0x69, 0xfd, 0x31, 0xbd, 0xba, 0x54, 0x92, 0xcf, 0x95, + 0xe3, 0x74, 0xd3, 0xbe, 0xc0, 0xfc, 0xa3, 0x11, 0xae, 0x16, 0xab, 0xdd, 0x68, 0x57, 0x2a, 0xd2, + 0xb9, 0xac, 0x00, 0x1a, 0xee, 0xe8, 0x57, 0x02, 0x68, 0xf4, 0xb0, 0x19, 0x79, 0x20, 0x97, 0xcb, + 0x3c, 0x90, 0x7b, 0x05, 0x46, 0x31, 0x4b, 0x7d, 0x1c, 0xa9, 0x50, 0x14, 0x3b, 0x45, 0x06, 0xe4, + 0x17, 0x09, 0x13, 0x04, 0x72, 0x0d, 0x00, 0x73, 0xf6, 0xf0, 0x55, 0x56, 0xb9, 0x09, 0x8e, 0xa9, + 0x7d, 0x84, 0xef, 0x44, 0x41, 0x41, 0xf6, 0x75, 0xeb, 0x96, 0xea, 0x6c, 0xe1, 0xec, 0xc3, 0x60, + 0x5b, 0xa0, 0x27, 0x08, 0xac, 0x79, 0xaa, 0x0a, 0x18, 0x4e, 0x9a, 0xa7, 0xf5, 0x93, 0xa6, 0x0d, + 0x5e, 0x51, 0xdf, 0xc9, 0x1e, 0x41, 0x27, 0x10, 0x3f, 0xc7, 0x88, 0x8f, 0x70, 0xd5, 0xd7, 0xb1, + 0x3f, 0x03, 0x23, 0xf3, 0x34, 0x88, 0xd6, 0xd7, 0x97, 0xc5, 0x63, 0x50, 0x4f, 0x33, 0x55, 0x8e, + 0x37, 0x51, 0xa3, 0xa8, 0xf9, 0xe1, 0x41, 0x65, 0x3c, 0xf2, 0x5a, 0xf4, 0x6a, 0xec, 0xbc, 0x90, + 0xd8, 0xa4, 0x06, 0x65, 0x1e, 0x6b, 0x92, 0x58, 0x53, 0x38, 0x85, 0x8b, 0x5c, 0xa1, 0x88, 0xdb, + 0x97, 0x0f, 0xe8, 0x56, 0x7c, 0x0f, 0xb7, 0x07, 0x9f, 0x2c, 0xca, 0xfb, 0xf0, 0x6a, 0x23, 0x01, + 0x1b, 0x79, 0x56, 0x79, 0x58, 0x46, 0x6b, 0x6b, 0x2f, 0x05, 0xa9, 0xc2, 0xf8, 0xbc, 0xdf, 0xea, + 0x38, 0x91, 0x87, 0x49, 0x87, 0xf6, 0xc5, 0x6c, 0xc5, 0x0d, 0x6f, 0x43, 0x2d, 0xd0, 0x93, 0xce, + 0x2b, 0x05, 0xe4, 0x16, 0x4c, 0x58, 0x7e, 0x97, 0x0d, 0x92, 0xd8, 0x8d, 0x88, 0x09, 0x19, 0xbf, + 0x38, 0xc2, 0xc6, 0xd2, 0x16, 0x87, 0x47, 0xda, 0x1d, 0x1b, 0x8d, 0x8a, 0xac, 0x64, 0xec, 0xec, + 0xd5, 0x59, 0xa8, 0xde, 0xc6, 0xed, 0x61, 0x96, 0xe1, 0x14, 0xb8, 0x01, 0x63, 0xf5, 0xfa, 0xea, + 0x3a, 0x0d, 0xa3, 0x5b, 0x4d, 0xff, 0x01, 0x4e, 0xc2, 0xa2, 0x7c, 0x14, 0xd7, 0xb7, 0x23, 0x1a, + 0x46, 0xf6, 0x76, 0xd3, 0x7f, 0x60, 0xa9, 0x58, 0xe4, 0x2b, 0x4a, 0x16, 0x7e, 0x5c, 0x7e, 0x27, + 0x8f, 0x5d, 0x7e, 0x53, 0x19, 0xfa, 0xd9, 0x22, 0x9c, 0x99, 0xa1, 0x9f, 0xa1, 0x93, 0xb7, 0xc5, + 0x33, 0x24, 0x55, 0xd7, 0x0d, 0x68, 0x18, 0xe2, 0xed, 0x69, 0x11, 0xb6, 0xc6, 0x0f, 0xcb, 0x1c, + 0x5e, 0x10, 0x73, 0xb0, 0x34, 0x7c, 0xb4, 0x6f, 0xea, 0xd5, 0xbb, 0xcb, 0xc9, 0x22, 0xfd, 0xc9, + 0x3a, 0x88, 0xd6, 0xda, 0x76, 0xc4, 0x41, 0xf4, 0x06, 0x4c, 0xa7, 0xba, 0x41, 0xda, 0x37, 0x1a, + 0x38, 0x6d, 0xdf, 0xa4, 0x68, 0xac, 0x14, 0xb6, 0xf9, 0x1f, 0x86, 0x53, 0x7c, 0x85, 0xf3, 0xd9, + 0x84, 0x61, 0x6e, 0xbe, 0xa8, 0x19, 0x5f, 0xb9, 0x71, 0x63, 0x89, 0x12, 0x72, 0x0e, 0xf2, 0xf5, + 0xfa, 0xaa, 0x9a, 0x8f, 0x3a, 0x0c, 0x7d, 0x8b, 0xc1, 0xd8, 0x08, 0xa1, 0x5f, 0x59, 0xb9, 0x2c, + 0xcb, 0xd4, 0x84, 0x85, 0x50, 0xd6, 0xdf, 0xd2, 0x46, 0x28, 0x24, 0xfd, 0x2d, 0x6c, 0x84, 0xc4, + 0x32, 0x98, 0x87, 0xd9, 0x6a, 0x18, 0xd2, 0x80, 0x3f, 0xe7, 0xd2, 0x0e, 0xbb, 0x2d, 0x1a, 0x88, + 0x75, 0x4c, 0x68, 0x43, 0xac, 0xd4, 0x69, 0x84, 0x56, 0x5f, 0x44, 0x72, 0x19, 0x8a, 0xd5, 0xae, + 0xeb, 0xd1, 0x76, 0x43, 0xbb, 0xae, 0xe3, 0x08, 0x98, 0x15, 0x97, 0x92, 0xf7, 0xe1, 0xb4, 0x20, + 0x92, 0xc6, 0x8c, 0xe8, 0x81, 0x91, 0x44, 0x43, 0xc8, 0x75, 0x56, 0x9a, 0x40, 0xb6, 0xe8, 0x92, + 0x6c, 0x4a, 0x52, 0x85, 0xf2, 0x22, 0x06, 0x5e, 0x2c, 0xd0, 0xb0, 0x11, 0x78, 0x9d, 0xc8, 0x0f, + 0xc4, 0x63, 0x09, 0x68, 0x15, 0xf1, 0xa0, 0x0c, 0xdb, 0x8d, 0x0b, 0xad, 0x1e, 0x74, 0x72, 0x07, + 0xa6, 0xd3, 0x30, 0xa6, 0xf8, 0x46, 0x93, 0x07, 0x7c, 0x7b, 0xb8, 0xa0, 0xea, 0xcb, 0xa2, 0x22, + 0x5b, 0x30, 0x55, 0x8d, 0xa2, 0xc0, 0xdb, 0xea, 0x46, 0x34, 0x65, 0x16, 0xc9, 0x93, 0x8b, 0xb8, + 0x5c, 0x9a, 0x46, 0x4f, 0x09, 0x61, 0x9c, 0x76, 0x62, 0xca, 0xd8, 0x3c, 0xb2, 0x7a, 0xd9, 0x11, + 0x37, 0x7e, 0x03, 0x5c, 0xbc, 0x93, 0x2d, 0x2e, 0x77, 0xca, 0x13, 0xa2, 0x6a, 0xb8, 0xdf, 0x6a, + 0xd1, 0x28, 0xc0, 0x25, 0x05, 0xdf, 0xd1, 0x36, 0x45, 0x50, 0xe1, 0x79, 0xe5, 0xe9, 0x7b, 0x7c, + 0x2b, 0x5d, 0x8b, 0xb7, 0xd6, 0x78, 0x6a, 0xa6, 0x69, 0x69, 0x40, 0xd3, 0xb4, 0x09, 0x53, 0x8b, + 0xed, 0x46, 0xb0, 0x8f, 0x77, 0xe9, 0xe5, 0xc7, 0x8d, 0x1f, 0xf3, 0x71, 0xf2, 0x91, 0xbc, 0x0b, + 0x8e, 0x94, 0xb0, 0xac, 0xcf, 0xeb, 0x65, 0x6c, 0xfe, 0xe9, 0x30, 0x57, 0x5c, 0xaa, 0x05, 0x72, + 0x46, 0x49, 0x1b, 0xa8, 0x06, 0xf0, 0xa4, 0x2c, 0x93, 0xdc, 0x49, 0x2c, 0x93, 0xfc, 0xf1, 0x96, + 0x49, 0xe1, 0x38, 0xcb, 0x24, 0x65, 0x3a, 0x0c, 0x9d, 0xd8, 0x74, 0x18, 0x3e, 0x81, 0xe9, 0x30, + 0x72, 0x22, 0xd3, 0x41, 0xb3, 0x81, 0x8a, 0xc7, 0xd9, 0x40, 0xff, 0xd7, 0xd0, 0x78, 0x52, 0x0d, + 0x8d, 0xac, 0x75, 0xf0, 0x24, 0x86, 0x86, 0xf9, 0x93, 0x50, 0x4e, 0xeb, 0xae, 0xe3, 0x2f, 0x5b, + 0x3e, 0xb6, 0xbb, 0x55, 0x4c, 0xb3, 0xa6, 0x75, 0x07, 0x33, 0xf8, 0xd7, 0x02, 0xef, 0xbe, 0x13, + 0xd1, 0x24, 0x9f, 0x3f, 0x1a, 0xfc, 0x1d, 0x0e, 0xc5, 0x49, 0xa2, 0xa0, 0xc4, 0xcb, 0x66, 0x2e, + 0x6b, 0xd9, 0x34, 0xbf, 0x95, 0x83, 0x29, 0x7e, 0x1d, 0xe4, 0xc9, 0x77, 0xf6, 0xbc, 0xad, 0x19, + 0x43, 0xf2, 0x30, 0x2f, 0xd5, 0xba, 0x23, 0xdc, 0x3d, 0x5f, 0x86, 0xd3, 0x3d, 0x5d, 0x81, 0x06, + 0xd1, 0x82, 0xbc, 0x88, 0xd3, 0x63, 0x12, 0xcd, 0x66, 0x57, 0xb2, 0x79, 0xc3, 0xea, 0xa1, 0x30, + 0xff, 0x32, 0xd7, 0xc3, 0x5f, 0x38, 0x7e, 0x54, 0x57, 0x8e, 0x71, 0x32, 0x57, 0x4e, 0x6e, 0x30, + 0x57, 0x4e, 0x4a, 0x19, 0xe7, 0x07, 0x51, 0xc6, 0xef, 0xc3, 0xf8, 0x3a, 0x75, 0x5a, 0xe1, 0xba, + 0x2f, 0x2e, 0xda, 0xf3, 0xab, 0xa9, 0xf2, 0x9e, 0x0d, 0x2b, 0x93, 0xeb, 0x79, 0x9c, 0xa4, 0x23, + 0x62, 0x04, 0x4c, 0x81, 0xf0, 0x9b, 0xf7, 0x96, 0xce, 0x41, 0x35, 0xd2, 0x86, 0x8e, 0x30, 0xd2, + 0xea, 0x50, 0x12, 0x74, 0xc9, 0x0d, 0x53, 0xe5, 0xcd, 0x44, 0xea, 0xe0, 0x33, 0xfb, 0xa1, 0xac, + 0x3d, 0xce, 0x1e, 0x17, 0xd7, 0xce, 0x0d, 0x09, 0x8d, 0x89, 0xf9, 0x0f, 0x46, 0xa4, 0xa4, 0x7f, + 0xbc, 0xfb, 0x77, 0x7d, 0x47, 0x9e, 0x3f, 0xe1, 0x8e, 0xbc, 0x70, 0xdc, 0x6a, 0xa4, 0x2d, 0x91, + 0x43, 0x27, 0x58, 0x22, 0x87, 0x1f, 0x79, 0x77, 0x3d, 0x72, 0xc2, 0x45, 0x2f, 0x25, 0x74, 0xc5, + 0x41, 0x84, 0x2e, 0x73, 0xa1, 0x1c, 0x7d, 0xf4, 0x85, 0x12, 0x4e, 0xbc, 0x50, 0x2a, 0x89, 0xe8, + 0xc7, 0x06, 0x4a, 0x44, 0x6f, 0x0c, 0x90, 0x88, 0xfe, 0x13, 0xb5, 0xfa, 0x7e, 0x35, 0x7b, 0xf5, + 0x3d, 0x5a, 0xf1, 0x9e, 0x68, 0xfd, 0x0d, 0xf0, 0xb3, 0xee, 0x39, 0x01, 0x33, 0xd3, 0x43, 0x72, + 0x0d, 0x46, 0xe4, 0x85, 0x2f, 0x23, 0xd9, 0xf1, 0xf4, 0xde, 0xf4, 0x92, 0x58, 0xcc, 0xa2, 0x97, + 0xc4, 0x22, 0x38, 0x9a, 0xdf, 0x6d, 0x11, 0x30, 0xed, 0x6e, 0x8b, 0x80, 0x99, 0x7f, 0xa7, 0x20, + 0x45, 0x9f, 0x99, 0xb1, 0x22, 0xd1, 0x6b, 0xcf, 0xbb, 0x82, 0xc6, 0xc9, 0xdf, 0x15, 0xfc, 0x08, + 0xb7, 0xe5, 0x94, 0x74, 0x4e, 0xf9, 0x01, 0xd2, 0x39, 0xbd, 0xae, 0xe5, 0x42, 0x2a, 0x24, 0xc9, + 0x37, 0x98, 0x38, 0x1c, 0x9d, 0x05, 0xe9, 0xa6, 0x9a, 0xb4, 0x68, 0x28, 0x89, 0x23, 0x47, 0xca, + 0x23, 0xd2, 0x15, 0xc5, 0xe6, 0xcc, 0xf0, 0x49, 0x6e, 0x8e, 0x8e, 0xfc, 0x1f, 0xbd, 0x39, 0xba, + 0x08, 0xa0, 0x64, 0xff, 0xe4, 0x5e, 0xc7, 0x17, 0x58, 0x37, 0x1d, 0x9f, 0xf9, 0x53, 0x21, 0x34, + 0xff, 0x7c, 0x0a, 0xa6, 0xea, 0xf5, 0xd5, 0x05, 0xcf, 0xd9, 0x69, 0xfb, 0x61, 0xe4, 0x35, 0x96, + 0xda, 0xdb, 0x3e, 0x5b, 0xcb, 0xe3, 0x69, 0xa4, 0xdc, 0x62, 0x4c, 0xa6, 0x50, 0x5c, 0xcc, 0x6c, + 0xc5, 0xc5, 0x20, 0x88, 0x9f, 0xca, 0x44, 0x5b, 0x91, 0x32, 0x80, 0xc5, 0xe1, 0x6c, 0xb9, 0xac, + 0x77, 0x79, 0x1a, 0x47, 0xee, 0x08, 0xc6, 0xe5, 0x32, 0xe4, 0x20, 0x4b, 0x96, 0x11, 0xda, 0x2b, + 0xb0, 0xc2, 0x7c, 0x3a, 0xab, 0xdd, 0x3f, 0x4d, 0x8a, 0xb9, 0x92, 0x10, 0x4a, 0x1c, 0x6f, 0x92, + 0x74, 0x10, 0xae, 0x7a, 0xe4, 0x7b, 0xe6, 0xc0, 0x3e, 0x9c, 0xc6, 0xbd, 0xe7, 0x49, 0x37, 0xfb, + 0x57, 0xc4, 0xf2, 0x6c, 0xe2, 0xcd, 0xe7, 0x8c, 0x1d, 0xbf, 0xfa, 0x9c, 0x5e, 0x66, 0x0d, 0xe4, + 0x5b, 0x06, 0x3c, 0x9d, 0x59, 0x12, 0xcf, 0xee, 0x31, 0xed, 0x0e, 0xb0, 0xa2, 0x34, 0x30, 0xf5, + 0xe5, 0xcb, 0xfd, 0xaa, 0xb6, 0x33, 0x54, 0xc1, 0xd1, 0x35, 0x91, 0x7f, 0x6a, 0xc0, 0x59, 0x0d, + 0x03, 0x97, 0xf2, 0x16, 0x6d, 0x47, 0x21, 0x2a, 0xf3, 0xbe, 0x72, 0xfd, 0xc1, 0xe3, 0x91, 0xeb, + 0xe7, 0xf4, 0xb6, 0xf0, 0xe7, 0x8b, 0xb0, 0x7a, 0xf5, 0xf8, 0xa7, 0xcf, 0x17, 0x92, 0xfb, 0x30, + 0x85, 0x45, 0xd2, 0xf1, 0xc0, 0x64, 0x56, 0xf8, 0x2b, 0x66, 0x92, 0xcf, 0x9e, 0xef, 0x86, 0x91, + 0xdf, 0xc2, 0x54, 0x77, 0x73, 0x3f, 0x38, 0xa8, 0x8c, 0x6b, 0xe8, 0x98, 0x36, 0x04, 0xbf, 0x21, + 0xf6, 0x5e, 0x78, 0xed, 0x6d, 0x5f, 0x7b, 0xa0, 0x23, 0x5d, 0x05, 0xf9, 0xe7, 0x06, 0xcc, 0x32, + 0x28, 0x6f, 0xc6, 0xad, 0xc0, 0x6f, 0xc5, 0xe5, 0xf2, 0x68, 0xa7, 0x4f, 0xb7, 0x35, 0x1f, 0x4f, + 0xb7, 0xbd, 0x80, 0x9f, 0xcc, 0x75, 0x82, 0xbd, 0x1d, 0xf8, 0xad, 0xe4, 0xf3, 0xb5, 0x64, 0x94, + 0xfd, 0x3e, 0x92, 0xfc, 0xac, 0x01, 0xe7, 0xb4, 0x0d, 0xa5, 0x9a, 0x74, 0x63, 0x76, 0x52, 0x3b, + 0x07, 0x54, 0x8b, 0x6a, 0x57, 0x85, 0xfc, 0x5f, 0xc2, 0x2f, 0x48, 0x56, 0x0b, 0xfc, 0x16, 0xbb, + 0xc5, 0xb1, 0x94, 0x4f, 0xe8, 0x5f, 0x0b, 0xf1, 0x60, 0x0a, 0x9d, 0xe7, 0xda, 0x11, 0xe4, 0x4c, + 0xff, 0x23, 0xc8, 0x4b, 0xa2, 0xea, 0x67, 0x30, 0xb1, 0x41, 0xff, 0x73, 0xc8, 0x5e, 0xae, 0xe4, + 0xa7, 0xe0, 0x5c, 0x0f, 0x30, 0x9e, 0x6d, 0xa7, 0xfb, 0xce, 0xb6, 0x97, 0x0f, 0x0f, 0x2a, 0x2f, + 0x66, 0xd5, 0x96, 0x35, 0xd3, 0xfa, 0xd7, 0x40, 0x1c, 0x80, 0xa4, 0x70, 0xf6, 0xcc, 0x11, 0x02, + 0xfa, 0xb2, 0x90, 0x0f, 0x05, 0x9f, 0xe9, 0x72, 0xe5, 0x1b, 0xd4, 0x25, 0x2f, 0x41, 0x22, 0x14, + 0x4a, 0x4a, 0x52, 0x87, 0xfd, 0xd9, 0xb3, 0x47, 0x55, 0xf2, 0x83, 0x83, 0x8a, 0x86, 0xcd, 0x0c, + 0x49, 0x35, 0x5b, 0x84, 0x6a, 0x48, 0x6a, 0x88, 0xe4, 0xf7, 0x0d, 0x98, 0x61, 0x80, 0x44, 0xa8, + 0x44, 0xa3, 0x66, 0x8f, 0x92, 0xfa, 0xdd, 0xc7, 0x23, 0xf5, 0xcf, 0xe2, 0x37, 0xaa, 0x52, 0xdf, + 0xd3, 0x25, 0x99, 0x1f, 0x87, 0xd2, 0xae, 0x9d, 0xd3, 0x68, 0xd2, 0x7e, 0x6e, 0x00, 0x69, 0xe7, + 0x03, 0x70, 0xbc, 0xb4, 0xf7, 0xad, 0x85, 0xac, 0x43, 0x49, 0xd8, 0x90, 0xbc, 0xc3, 0x9e, 0xd1, + 0xee, 0x90, 0xab, 0x45, 0xdc, 0xb0, 0x17, 0x39, 0x2f, 0x7a, 0x5a, 0xa8, 0x71, 0x21, 0x6d, 0x98, + 0xe6, 0xbf, 0xf5, 0xcd, 0x6d, 0xa5, 0xef, 0xe6, 0xf6, 0xb2, 0x68, 0xd1, 0x45, 0xc1, 0x3f, 0xb5, + 0xc7, 0x55, 0x2a, 0xca, 0x62, 0x4c, 0x3a, 0x40, 0x34, 0x30, 0x9f, 0xb4, 0x17, 0x8f, 0xde, 0xd2, + 0xbe, 0x28, 0xea, 0xac, 0xa4, 0xeb, 0x4c, 0xcf, 0xdc, 0x0c, 0xde, 0xc4, 0x81, 0x49, 0x01, 0x65, + 0x3b, 0x46, 0xd4, 0xf0, 0xcf, 0x6a, 0x37, 0x35, 0x52, 0xa5, 0x3c, 0x5f, 0xa6, 0xac, 0x09, 0x43, + 0xe2, 0x53, 0x0a, 0x3d, 0xcd, 0xcf, 0xfc, 0xa6, 0xd1, 0x53, 0x07, 0xdb, 0x99, 0xe2, 0x0f, 0xe5, + 0xb2, 0x29, 0xee, 0x4c, 0x39, 0x47, 0xdc, 0x21, 0x27, 0x08, 0xcc, 0xb6, 0x51, 0x2f, 0xde, 0xe4, + 0xc5, 0x7b, 0x13, 0x1c, 0x94, 0x6c, 0x98, 0x2a, 0x32, 0x92, 0x23, 0x9f, 0xd8, 0x48, 0x18, 0xc9, + 0x21, 0xe2, 0x37, 0xcc, 0x9f, 0xcd, 0xe9, 0x52, 0x42, 0x2e, 0x2b, 0x66, 0xb6, 0x72, 0xf5, 0x47, + 0x9a, 0xd9, 0x8a, 0x71, 0xfd, 0x5b, 0x06, 0x4c, 0xaf, 0x06, 0x3b, 0x4e, 0xdb, 0xfb, 0x09, 0x7e, + 0x31, 0xd8, 0xc7, 0x6e, 0x8c, 0x83, 0x31, 0x3f, 0xd6, 0xc4, 0x60, 0xbe, 0x52, 0x31, 0x1b, 0x58, + 0x1c, 0x61, 0x2b, 0xeb, 0x7b, 0x30, 0x88, 0x0e, 0x3f, 0x4c, 0xc9, 0xcf, 0xc6, 0xd1, 0x39, 0xdc, + 0xfc, 0x76, 0x0e, 0xc6, 0x14, 0x89, 0x25, 0x9f, 0x86, 0x92, 0xca, 0x47, 0xf5, 0x6a, 0xa8, 0xd5, + 0x5a, 0x1a, 0x16, 0xba, 0x35, 0xa8, 0xd3, 0xd2, 0xdc, 0x1a, 0x4c, 0x2e, 0x11, 0x7a, 0xc2, 0x9d, + 0xc8, 0x3b, 0x19, 0x3b, 0x91, 0x13, 0x65, 0x65, 0x7d, 0xb3, 0x77, 0x3f, 0x32, 0x78, 0x12, 0x55, + 0xf3, 0xbb, 0x06, 0x94, 0xd3, 0x73, 0xea, 0x63, 0xe9, 0x95, 0x13, 0x78, 0x73, 0x7f, 0x3e, 0x07, + 0xe5, 0xf5, 0x80, 0x6d, 0xb7, 0x5d, 0x19, 0xc1, 0xfd, 0xa4, 0x9e, 0x3a, 0xbf, 0xa5, 0x39, 0x5a, + 0x9f, 0x8a, 0x97, 0x01, 0xb5, 0x71, 0x47, 0xdc, 0x51, 0x2a, 0xfc, 0xca, 0x6f, 0x54, 0x4e, 0x99, + 0x5f, 0x80, 0x99, 0x74, 0x77, 0xa0, 0xb3, 0xb5, 0x0a, 0x93, 0x3a, 0x3c, 0x9d, 0xbe, 0x29, 0x4d, + 0x65, 0xa5, 0xf1, 0xcd, 0x3f, 0xce, 0xa5, 0x79, 0x8b, 0x13, 0x68, 0xa6, 0x74, 0xda, 0xce, 0x56, + 0x33, 0xce, 0x30, 0x23, 0x1e, 0xb9, 0x41, 0x90, 0x25, 0xcb, 0x4e, 0x92, 0xc8, 0x2b, 0x0e, 0x70, + 0xcd, 0x67, 0x07, 0xb8, 0x92, 0x9b, 0xa9, 0x58, 0x85, 0x42, 0xf2, 0x9e, 0xcd, 0x03, 0xba, 0x65, + 0x27, 0xf1, 0x0a, 0x7a, 0x8c, 0x02, 0x99, 0x87, 0x19, 0xed, 0x8e, 0xb8, 0xa4, 0x1f, 0x4a, 0x1c, + 0x8a, 0x11, 0x16, 0x70, 0xe2, 0x4c, 0x64, 0x7c, 0x39, 0xce, 0x6f, 0xb2, 0x9d, 0x98, 0xf0, 0xa1, + 0xaa, 0x6f, 0x81, 0xc8, 0xb5, 0x46, 0x5e, 0x1c, 0x21, 0x98, 0x81, 0xb5, 0xe5, 0x74, 0xb4, 0xa4, + 0xc6, 0x1c, 0xd1, 0xfc, 0x33, 0x83, 0xcd, 0xff, 0xc6, 0xde, 0x27, 0x2c, 0xc5, 0x18, 0x6b, 0xd2, + 0x11, 0x01, 0x12, 0xff, 0xce, 0xe0, 0x49, 0x82, 0x84, 0xf8, 0xbc, 0x0e, 0xc3, 0xeb, 0x4e, 0xb0, + 0x43, 0x23, 0x91, 0xce, 0x46, 0xe5, 0xc2, 0x0b, 0x92, 0x4b, 0x42, 0x11, 0xfe, 0xb6, 0x04, 0x81, + 0xea, 0xba, 0xca, 0x0d, 0xe4, 0xba, 0x52, 0xdc, 0x8f, 0xf9, 0xc7, 0xe5, 0x7e, 0x34, 0xff, 0x32, + 0xc7, 0xdb, 0x23, 0x3e, 0x6a, 0xd0, 0x27, 0xd1, 0x2e, 0x41, 0x81, 0xc9, 0x81, 0xfa, 0xee, 0x1c, + 0x93, 0x15, 0xed, 0x49, 0x7d, 0xbf, 0x89, 0x67, 0x5b, 0xa8, 0xff, 0xd5, 0xac, 0x76, 0xb8, 0x44, + 0xa8, 0xf3, 0x06, 0x31, 0xf0, 0xf5, 0x62, 0xdf, 0xa5, 0xea, 0x74, 0x68, 0xeb, 0x0f, 0x4d, 0x63, + 0x39, 0xb9, 0xa9, 0x24, 0x97, 0x51, 0x03, 0x4c, 0x5b, 0xdb, 0x8e, 0xcd, 0x93, 0x9a, 0xa8, 0x2b, + 0x40, 0x92, 0x87, 0x66, 0x11, 0x26, 0xf4, 0x5c, 0xbb, 0x22, 0x50, 0x03, 0xd3, 0x54, 0xa6, 0xf2, + 0xf4, 0xaa, 0x7e, 0x56, 0x9d, 0x88, 0xd4, 0x60, 0x5c, 0xcb, 0x6b, 0xaa, 0x3e, 0xfa, 0xc9, 0x9f, + 0xd1, 0xb0, 0x7b, 0x33, 0x81, 0xeb, 0x24, 0xca, 0xad, 0x85, 0x4f, 0x41, 0x59, 0xcc, 0xcc, 0x38, + 0xc1, 0x20, 0x1e, 0xcf, 0x2d, 0x2d, 0x58, 0xea, 0x6c, 0x6a, 0x78, 0x6e, 0x60, 0x21, 0xd4, 0xfc, + 0x9e, 0x01, 0xe7, 0x56, 0x68, 0xf4, 0xc0, 0x0f, 0xf6, 0x2c, 0x1a, 0x46, 0x81, 0xc7, 0xf3, 0x15, + 0xa2, 0x3c, 0x7e, 0x9a, 0xbc, 0x29, 0x5f, 0xe8, 0xd1, 0x15, 0x64, 0xba, 0x8e, 0xda, 0xb8, 0x10, + 0xca, 0x21, 0x7c, 0xa3, 0x47, 0xbe, 0xcc, 0xf3, 0xba, 0x78, 0x99, 0x27, 0x77, 0x34, 0x71, 0x3c, + 0x2f, 0x5c, 0xda, 0x96, 0x2f, 0xf2, 0x7c, 0x37, 0x07, 0xa7, 0x33, 0x3e, 0x6b, 0xf3, 0xd3, 0x4f, + 0xa8, 0x72, 0xa8, 0x69, 0xca, 0x41, 0x3e, 0xdd, 0xd6, 0xb7, 0xe3, 0x33, 0x75, 0xc5, 0xaf, 0x19, + 0x70, 0x56, 0x97, 0x1e, 0x11, 0xbf, 0xb3, 0x79, 0x83, 0xbc, 0x01, 0xc3, 0xb7, 0xa9, 0xe3, 0x52, + 0x99, 0x07, 0xeb, 0x74, 0xea, 0x59, 0x4c, 0x5e, 0xc8, 0xd9, 0xfe, 0x31, 0x9f, 0xca, 0xa7, 0x2c, + 0x41, 0x42, 0x16, 0xc4, 0xc7, 0x71, 0xb3, 0xd4, 0x94, 0xd7, 0x65, 0xb2, 0xaa, 0x3a, 0xe2, 0x70, + 0xf3, 0x07, 0x06, 0x3c, 0x75, 0x04, 0x0d, 0x1b, 0x38, 0x36, 0xf4, 0xea, 0xc0, 0xe1, 0xc2, 0x82, + 0x50, 0xf2, 0x36, 0x4c, 0xae, 0x0b, 0xb3, 0x56, 0x0e, 0x87, 0xf2, 0x9a, 0xb8, 0xb4, 0x78, 0x6d, + 0x39, 0x2e, 0x69, 0x64, 0x66, 0x94, 0xdf, 0xf6, 0xc3, 0xa8, 0x9d, 0x3c, 0x76, 0x80, 0x46, 0xf9, + 0xae, 0x80, 0x59, 0x71, 0x29, 0xb9, 0x81, 0x41, 0x38, 0x0f, 0xf7, 0x97, 0x16, 0xa4, 0xdd, 0x88, + 0xe7, 0x3e, 0x7c, 0x9d, 0xd4, 0x5f, 0x0a, 0x8d, 0x11, 0x99, 0x2d, 0xa1, 0xb7, 0x4d, 0x5c, 0x64, + 0x7d, 0x0e, 0x86, 0x19, 0xe3, 0xf8, 0x60, 0x0f, 0x85, 0x07, 0xb3, 0x49, 0x7b, 0xae, 0x25, 0x8a, + 0xe2, 0x03, 0xfd, 0x5c, 0xe6, 0x7d, 0x93, 0x6f, 0x1b, 0x50, 0xd6, 0x79, 0x3f, 0xea, 0x78, 0xbe, + 0xa5, 0x8d, 0xe7, 0x53, 0xd9, 0xe3, 0xd9, 0x7f, 0x20, 0x7b, 0x92, 0x95, 0x0f, 0x34, 0x80, 0x26, + 0x0c, 0x2f, 0xf8, 0x2d, 0xc7, 0x6b, 0xab, 0x79, 0xae, 0x5d, 0x84, 0x58, 0xa2, 0x44, 0xe9, 0xad, + 0x7c, 0xdf, 0xde, 0x32, 0x7f, 0xa1, 0x00, 0xe7, 0x2c, 0xba, 0xe3, 0x31, 0xab, 0x6a, 0x23, 0xf4, + 0xda, 0x3b, 0xda, 0x6d, 0x20, 0x33, 0xd5, 0xe1, 0x22, 0x07, 0x02, 0x83, 0xc4, 0xfd, 0xfd, 0x12, + 0x14, 0x99, 0x6a, 0x57, 0xfa, 0x1c, 0x3d, 0xe4, 0xf8, 0x4c, 0x04, 0x17, 0x06, 0x59, 0x4c, 0xae, + 0x88, 0x85, 0x47, 0xc9, 0x52, 0xc3, 0x16, 0x9e, 0x0f, 0x0f, 0x2a, 0xc0, 0xdf, 0x00, 0x66, 0xa5, + 0x62, 0xf1, 0x89, 0x2d, 0xb1, 0x42, 0x1f, 0x4b, 0xec, 0x2e, 0xcc, 0x54, 0x5d, 0xae, 0xd4, 0x9c, + 0xe6, 0x5a, 0xe0, 0xb5, 0x1b, 0x5e, 0xc7, 0x69, 0xca, 0xdd, 0x05, 0x9e, 0x93, 0x38, 0x71, 0xb9, + 0xdd, 0x89, 0x11, 0xac, 0x4c, 0x32, 0xd6, 0x8c, 0x85, 0x95, 0x3a, 0x7f, 0x05, 0x80, 0x1f, 0x7e, + 0x60, 0x33, 0xdc, 0x76, 0xc8, 0x9f, 0x01, 0xb0, 0xe2, 0x62, 0xb4, 0x01, 0xf1, 0x48, 0x76, 0x7d, + 0xb9, 0x9e, 0x04, 0x45, 0xf3, 0x4b, 0xf4, 0xfc, 0xd8, 0x36, 0x6a, 0x86, 0x78, 0x74, 0xab, 0xe1, + 0x25, 0x74, 0xf5, 0xfa, 0x6d, 0x46, 0x57, 0xec, 0xa1, 0x0b, 0xc3, 0x5d, 0x95, 0x8e, 0xe3, 0x91, + 0x6b, 0x00, 0xfc, 0x1a, 0x32, 0x0a, 0xc4, 0x68, 0x62, 0x31, 0x06, 0x08, 0xe5, 0x16, 0xa3, 0x82, + 0x42, 0xde, 0x84, 0xe9, 0xc5, 0xf9, 0x39, 0xe9, 0xb2, 0x5a, 0xf0, 0x1b, 0xdd, 0x16, 0x6d, 0x47, + 0x78, 0x68, 0x5a, 0xe2, 0x63, 0x48, 0x1b, 0x73, 0x4c, 0x0a, 0xb2, 0xd0, 0x44, 0x5e, 0x27, 0x9e, + 0x15, 0x70, 0xde, 0x77, 0x69, 0xb8, 0x79, 0xfd, 0x13, 0x96, 0xd7, 0x49, 0x69, 0x1b, 0xce, 0xb6, + 0xeb, 0x99, 0x33, 0xf3, 0x6f, 0x60, 0x5e, 0xa7, 0x1e, 0x5c, 0xf2, 0x63, 0x30, 0x84, 0x3f, 0xc5, + 0x32, 0x3d, 0x9d, 0xc1, 0x36, 0x59, 0xa2, 0x1b, 0x3c, 0xaf, 0x3a, 0x12, 0x90, 0xa5, 0xe4, 0x85, + 0xf5, 0x13, 0x64, 0x27, 0x11, 0xa9, 0x45, 0xb5, 0x77, 0xd5, 0x4d, 0x17, 0x4a, 0x6a, 0x85, 0x4c, + 0x46, 0x6e, 0x3b, 0xe1, 0x2e, 0x75, 0xd9, 0x2f, 0x91, 0x58, 0x0c, 0x65, 0x64, 0x17, 0xa1, 0x36, + 0xfb, 0x0e, 0x4b, 0x41, 0x61, 0xda, 0x61, 0x29, 0xdc, 0x08, 0xc5, 0xa7, 0x88, 0xad, 0x93, 0x87, + 0xdb, 0x70, 0xd7, 0x12, 0x45, 0xa8, 0x2d, 0xe5, 0x11, 0x59, 0xe0, 0x34, 0xf6, 0x68, 0xb0, 0x79, + 0xfd, 0xe3, 0xd0, 0x96, 0x7a, 0x1d, 0x47, 0x8c, 0xc9, 0x37, 0x20, 0x7e, 0x16, 0x40, 0x43, 0x66, + 0x86, 0x65, 0x72, 0xa7, 0xd2, 0x48, 0x0c, 0xcb, 0xe4, 0x4e, 0xa5, 0x6a, 0x58, 0xc6, 0xa8, 0xf1, + 0xbb, 0xa4, 0xb9, 0x63, 0xde, 0x25, 0xed, 0xf3, 0x06, 0xb3, 0x4c, 0xc7, 0xf1, 0x09, 0x7a, 0x5c, + 0xff, 0xb3, 0x50, 0xaa, 0x46, 0x91, 0xd3, 0xd8, 0xa5, 0x2e, 0xbe, 0x7f, 0xab, 0xdc, 0xea, 0x72, + 0x04, 0x5c, 0x75, 0xc6, 0xaa, 0xb8, 0xe4, 0x15, 0x18, 0xd6, 0x5e, 0xd3, 0x47, 0x73, 0xa2, 0xe7, + 0x15, 0x7d, 0x81, 0xc3, 0x36, 0x51, 0x4b, 0xed, 0xfb, 0x1e, 0xeb, 0x93, 0x62, 0x92, 0xd6, 0xdb, + 0xe3, 0x20, 0x55, 0x6b, 0x08, 0x2c, 0xf2, 0xba, 0x62, 0x76, 0x8c, 0x26, 0xf6, 0x3f, 0xdf, 0x9b, + 0xd9, 0xd2, 0xfa, 0x50, 0x4d, 0x8a, 0xd8, 0x0e, 0xb9, 0x09, 0x23, 0x72, 0xcb, 0x0d, 0x89, 0xcd, + 0x2f, 0x28, 0xd3, 0xf7, 0x0b, 0xf6, 0x2d, 0x89, 0x8c, 0x19, 0x75, 0x95, 0xcc, 0x5f, 0x63, 0x4a, + 0x46, 0x5d, 0x25, 0xf3, 0x97, 0x96, 0x51, 0x57, 0xc9, 0x01, 0x16, 0xef, 0xa0, 0x4a, 0xc7, 0xee, + 0xa0, 0x36, 0xa1, 0xb4, 0xe6, 0x04, 0x91, 0xc7, 0x96, 0xa3, 0x76, 0xc4, 0xdf, 0x92, 0x49, 0x36, + 0xf8, 0x4a, 0x51, 0xf2, 0xe2, 0x7a, 0x47, 0xc1, 0xd7, 0x53, 0x92, 0x26, 0xf0, 0xec, 0xd0, 0x92, + 0x89, 0x47, 0x09, 0x2d, 0x29, 0xc6, 0x2f, 0xa8, 0x4d, 0x26, 0x81, 0x3c, 0xf1, 0xb3, 0x68, 0xe9, + 0xde, 0xc7, 0x1d, 0xe7, 0x97, 0xa0, 0xc4, 0xfe, 0xc7, 0xf7, 0x2d, 0x3c, 0xca, 0xdf, 0x8a, 0x49, + 0x72, 0x05, 0xe8, 0x13, 0x9a, 0x3f, 0x82, 0x51, 0xa7, 0x11, 0x9f, 0xc0, 0xc8, 0x38, 0xed, 0xad, + 0xd1, 0xb8, 0x91, 0x77, 0xa0, 0xa4, 0x3e, 0xcc, 0x33, 0x3b, 0x95, 0x04, 0x07, 0xb9, 0x02, 0x9e, + 0x1e, 0x25, 0x8d, 0x80, 0xad, 0x5f, 0xd5, 0x4e, 0x07, 0x69, 0x89, 0x22, 0xed, 0x9d, 0x4e, 0x9a, + 0x4c, 0xa2, 0x91, 0xcf, 0x41, 0xa9, 0xda, 0xe9, 0x24, 0x1a, 0x67, 0x5a, 0xd9, 0x47, 0x76, 0x3a, + 0x76, 0xa6, 0xd6, 0xd1, 0x28, 0x98, 0x60, 0x09, 0x83, 0x0f, 0xeb, 0x9d, 0x49, 0x04, 0x4b, 0x3e, + 0x37, 0x93, 0x16, 0x2c, 0x05, 0xdd, 0xfc, 0x91, 0x01, 0x67, 0xfb, 0x74, 0x1b, 0xee, 0xc5, 0x13, + 0x6f, 0x39, 0xdf, 0x8b, 0xeb, 0xac, 0x0a, 0x22, 0xdf, 0xd9, 0x88, 0x6e, 0xfc, 0xe3, 0xf4, 0x13, + 0x6b, 0xb0, 0xda, 0x68, 0xb9, 0x1a, 0x67, 0x3f, 0x6c, 0x93, 0xff, 0xd8, 0x1e, 0xb6, 0x31, 0x0f, + 0x0c, 0x18, 0x53, 0x84, 0xf9, 0x31, 0x3e, 0xa9, 0x7f, 0x49, 0xbc, 0xf0, 0x96, 0x4f, 0xf0, 0x5a, + 0x29, 0x7f, 0x05, 0xbe, 0xe8, 0xf6, 0x65, 0x80, 0x65, 0x27, 0x8c, 0xaa, 0x8d, 0xc8, 0xbb, 0x4f, + 0x07, 0xd0, 0xdc, 0x49, 0x56, 0x69, 0x07, 0x5f, 0xe6, 0x64, 0x64, 0x3d, 0x59, 0xa5, 0x63, 0x86, + 0xe6, 0x0a, 0x0c, 0xd7, 0xfd, 0x20, 0xaa, 0xed, 0xf3, 0xe5, 0x78, 0x81, 0x86, 0x0d, 0xd5, 0x93, + 0xe9, 0xa1, 0x4f, 0xa3, 0x61, 0x89, 0x22, 0x66, 0x13, 0xdf, 0xf2, 0x68, 0xd3, 0x55, 0x23, 0x4c, + 0xb6, 0x19, 0xc0, 0xe2, 0xf0, 0x2b, 0xef, 0xc0, 0xa4, 0x14, 0xec, 0xf5, 0xe5, 0x3a, 0xb6, 0x60, + 0x12, 0xc6, 0x36, 0x17, 0xad, 0xa5, 0x5b, 0x5f, 0xb0, 0x6f, 0x6d, 0x2c, 0x2f, 0x97, 0x4f, 0x91, + 0x71, 0x18, 0x15, 0x80, 0xf9, 0x6a, 0xd9, 0x20, 0x25, 0x28, 0x2e, 0xad, 0xd4, 0x17, 0xe7, 0x37, + 0xac, 0xc5, 0x72, 0xee, 0xca, 0x0b, 0x30, 0x91, 0xc4, 0x1a, 0xe3, 0xc1, 0xce, 0x08, 0xe4, 0xad, + 0xea, 0xbd, 0xf2, 0x29, 0x02, 0x30, 0xbc, 0x76, 0x67, 0xbe, 0x7e, 0xfd, 0x7a, 0xd9, 0xb8, 0xf2, + 0x29, 0x98, 0xc2, 0xcd, 0xda, 0x32, 0xdb, 0x37, 0xb4, 0x69, 0x80, 0x35, 0x95, 0xa0, 0x58, 0xa7, + 0x1d, 0x27, 0x70, 0x22, 0xca, 0xab, 0xb9, 0xdb, 0x6d, 0x46, 0x5e, 0xa7, 0x49, 0x1f, 0x96, 0x8d, + 0x2b, 0xaf, 0xc3, 0xa4, 0xe5, 0x77, 0x23, 0xaf, 0xbd, 0x23, 0xdf, 0x24, 0x25, 0xa7, 0x61, 0x6a, + 0x63, 0xa5, 0x7a, 0xb7, 0xb6, 0xf4, 0xee, 0xc6, 0xea, 0x46, 0xdd, 0xbe, 0x5b, 0x5d, 0x9f, 0xbf, + 0x5d, 0x3e, 0xc5, 0x3e, 0xf8, 0xee, 0x6a, 0x7d, 0xdd, 0xb6, 0x16, 0xe7, 0x17, 0x57, 0xd6, 0xcb, + 0xc6, 0x95, 0x9f, 0x33, 0x60, 0x82, 0x0d, 0x1a, 0x9a, 0xfd, 0x1b, 0xe8, 0x4d, 0xbb, 0x08, 0x17, + 0x36, 0xea, 0x8b, 0x96, 0xbd, 0xbe, 0x7a, 0x67, 0x71, 0xc5, 0xde, 0xa8, 0x57, 0xdf, 0x5d, 0xb4, + 0x37, 0x56, 0xea, 0x6b, 0x8b, 0xf3, 0x4b, 0xb7, 0x96, 0x16, 0x17, 0xca, 0xa7, 0x48, 0x05, 0x9e, + 0x52, 0x30, 0xac, 0xc5, 0xf9, 0xd5, 0xcd, 0x45, 0xcb, 0x5e, 0xab, 0xd6, 0xeb, 0xf7, 0x56, 0xad, + 0x85, 0xb2, 0x41, 0xce, 0xc3, 0x99, 0x0c, 0x84, 0xbb, 0xb7, 0xaa, 0xe5, 0x5c, 0x4f, 0xd9, 0xca, + 0xe2, 0xbd, 0xea, 0xb2, 0x5d, 0x5b, 0x5d, 0x2f, 0xe7, 0xaf, 0xbc, 0xc3, 0x0c, 0x2f, 0xf1, 0xb8, + 0x2a, 0x5b, 0xd8, 0x8b, 0x50, 0x58, 0x59, 0x5d, 0x59, 0x2c, 0x9f, 0x22, 0x63, 0x30, 0xb2, 0xb6, + 0xb8, 0xb2, 0xb0, 0xb4, 0xf2, 0x2e, 0xef, 0xd6, 0xea, 0xda, 0x9a, 0xb5, 0xba, 0xb9, 0xb8, 0x50, + 0xce, 0xb1, 0xbe, 0x5b, 0x58, 0x5c, 0x61, 0x5f, 0x96, 0xbf, 0x62, 0xf2, 0x37, 0x7f, 0xb5, 0x97, + 0x04, 0x59, 0x6f, 0x2d, 0x7e, 0x7e, 0x7d, 0x71, 0xa5, 0xbe, 0xb4, 0xba, 0x52, 0x3e, 0x75, 0xe5, + 0x42, 0x0a, 0x47, 0x8e, 0x44, 0xbd, 0x7e, 0xbb, 0x7c, 0xea, 0xca, 0x97, 0xa0, 0xa4, 0xda, 0x1d, + 0xe4, 0x2c, 0x4c, 0xab, 0xbf, 0xd7, 0x68, 0xdb, 0xf5, 0xda, 0x3b, 0xe5, 0x53, 0xe9, 0x02, 0xab, + 0xdb, 0x6e, 0xb3, 0x02, 0x6c, 0xbc, 0x5a, 0xb0, 0x4e, 0x83, 0x96, 0xd7, 0x66, 0x26, 0x45, 0x39, + 0x57, 0x2b, 0x7f, 0xff, 0x4f, 0x9e, 0x39, 0xf5, 0xfd, 0x1f, 0x3e, 0x63, 0xfc, 0xf1, 0x0f, 0x9f, + 0x31, 0xfe, 0xdb, 0x0f, 0x9f, 0x31, 0xb6, 0x86, 0x51, 0xd0, 0x6f, 0xfc, 0xef, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x86, 0x3d, 0x04, 0x6c, 0xc0, 0xdd, 0x00, 0x00, } func (m *KeepAlive) Marshal() (dAtA []byte, err error) { @@ -14316,6 +14362,11 @@ func (m *ClusterAuditConfigSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.UseFIPSEndpoint != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.UseFIPSEndpoint)) + i-- + dAtA[i] = 0x78 + } if m.RetentionPeriod != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.RetentionPeriod)) i-- @@ -15809,6 +15860,18 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DryRun { + i-- + if m.DryRun { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } if len(m.LoginHint) > 0 { i -= len(m.LoginHint) copy(dAtA[i:], m.LoginHint) @@ -24902,6 +24965,9 @@ func (m *ClusterAuditConfigSpecV2) Size() (n int) { if m.RetentionPeriod != 0 { n += 1 + sovTypes(uint64(m.RetentionPeriod)) } + if m.UseFIPSEndpoint != 0 { + n += 1 + sovTypes(uint64(m.UseFIPSEndpoint)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -25594,6 +25660,9 @@ func (m *AccessRequestSpecV3) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + if m.DryRun { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -39496,6 +39565,25 @@ func (m *ClusterAuditConfigSpecV2) Unmarshal(dAtA []byte) error { break } } + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UseFIPSEndpoint", wireType) + } + m.UseFIPSEndpoint = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UseFIPSEndpoint |= ClusterAuditConfigSpecV2_FIPSEndpointState(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -44085,6 +44173,26 @@ func (m *AccessRequestSpecV3) Unmarshal(dAtA []byte) error { } m.LoginHint = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DryRun", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DryRun = bool(v != 0) default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -57393,7 +57501,7 @@ func (m *OIDCAuthRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.CertTTL |= Duration(b&0x7F) << shift + m.CertTTL |= time.Duration(b&0x7F) << shift if b < 0x80 { break } @@ -58656,7 +58764,7 @@ func (m *SAMLAuthRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.CertTTL |= Duration(b&0x7F) << shift + m.CertTTL |= time.Duration(b&0x7F) << shift if b < 0x80 { break } @@ -59931,7 +60039,7 @@ func (m *GithubAuthRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.CertTTL |= Duration(b&0x7F) << shift + m.CertTTL |= time.Duration(b&0x7F) << shift if b < 0x80 { break } diff --git a/api/types/types.proto b/api/types/types.proto index 00a7c3c0485b8..7e8409f457a93 100644 --- a/api/types/types.proto +++ b/api/types/types.proto @@ -931,6 +931,19 @@ message ClusterAuditConfigSpecV2 { (gogoproto.casttype) = "Duration", (gogoproto.nullable) = true ]; + + // FIPSEndpointState represents an AWS FIPS endpoint state. + enum FIPSEndpointState { + // FIPS_UNSET allows setting FIPS state for AWS S3/Dynamo using configuration files or + // environment variables + FIPS_UNSET = 0; + // FIPS_ENABLED explicitly enables FIPS support for AWS S3/Dynamo + FIPS_ENABLED = 1; + // FIPS_DISABLED explicitly disables FIPS support for AWS S3/Dynamo + FIPS_DISABLED = 2; + } + // UseFIPSEndpoint configures AWS endpoints to use FIPS. + FIPSEndpointState UseFIPSEndpoint = 15 [ (gogoproto.jsontag) = "use_fips_endpoint,omitempty" ]; } // ClusterNetworkingConfigV2 contains cluster-wide networking configuration. @@ -1460,6 +1473,10 @@ message AccessRequestSpecV3 { // LoginHint is used as a hint for search-based access requests to select // roles based on the login the user is attempting. string LoginHint = 15 [ (gogoproto.jsontag) = "login_hint,omitempty" ]; + + // DryRun indicates that the request should not actually be created, the + // auth server should only validate the access request. + bool DryRun = 16 [ (gogoproto.jsontag) = "dry_run,omitempty" ]; } // AccessRequestFilter encodes filter params for access requests. @@ -2712,7 +2729,7 @@ message OIDCAuthRequest { bytes PublicKey = 7 [ (gogoproto.jsontag) = "public_key" ]; // CertTTL is the TTL of the certificate user wants to get - int64 CertTTL = 8 [ (gogoproto.jsontag) = "cert_ttl", (gogoproto.casttype) = "Duration" ]; + int64 CertTTL = 8 [ (gogoproto.jsontag) = "cert_ttl", (gogoproto.casttype) = "time.Duration" ]; // CreateWebSession indicates if user wants to generate a web // session after successful authentication @@ -2824,7 +2841,7 @@ message SAMLAuthRequest { bytes PublicKey = 6 [ (gogoproto.jsontag) = "public_key" ]; // CertTTL is the TTL of the certificate user wants to get. - int64 CertTTL = 7 [ (gogoproto.jsontag) = "cert_ttl", (gogoproto.casttype) = "Duration" ]; + int64 CertTTL = 7 [ (gogoproto.jsontag) = "cert_ttl", (gogoproto.casttype) = "time.Duration" ]; // CSRFToken is associated with user web session token. string CSRFToken = 8 [ (gogoproto.jsontag) = "csrf_token" ]; @@ -2926,7 +2943,7 @@ message GithubAuthRequest { // PublicKey is an optional public key to sign in case of successful auth. bytes PublicKey = 5 [ (gogoproto.jsontag) = "public_key" ]; // CertTTL is TTL of the cert that's generated in case of successful auth. - int64 CertTTL = 6 [ (gogoproto.jsontag) = "cert_ttl", (gogoproto.casttype) = "Duration" ]; + int64 CertTTL = 6 [ (gogoproto.jsontag) = "cert_ttl", (gogoproto.casttype) = "time.Duration" ]; // CreateWebSession indicates that a user wants to generate a web session // after successful authentication. bool CreateWebSession = 7 [ (gogoproto.jsontag) = "create_web_session" ]; diff --git a/api/utils/keypaths/keypaths.go b/api/utils/keypaths/keypaths.go index 7fe657653ee04..3f8ccb4118a04 100644 --- a/api/utils/keypaths/keypaths.go +++ b/api/utils/keypaths/keypaths.go @@ -38,6 +38,8 @@ const ( fileNameTLSCerts = "certs.pem" // fileExtCert is the suffix/extension of a file where an SSH Cert is stored. fileExtSSHCert = "-cert.pub" + // fileExtPPK is the suffix/extension of a file where an SSH keypair is stored in PuTTY PPK format. + fileExtPPK = ".ppk" // fileExtPub is the extension of a file where a public key is stored. fileExtPub = ".pub" // fileExtLocalCA is the extension of a file where a self-signed localhost CA cert is stored. @@ -64,6 +66,7 @@ const ( // │ ├── certs.pem --> TLS CA certs for the Teleport CA // │ ├── foo --> RSA Private Key for user "foo" // │ ├── foo.pub --> Public Key +// │ ├── foo.ppk --> PuTTY PPK-formatted keypair for user "foo" // │ ├── foo-x509.pem --> TLS client certificate for Auth Server // │ ├── foo-ssh --> SSH certs for user "foo" // │ │ ├── root-cert.pub --> SSH cert for Teleport cluster "root" @@ -171,6 +174,14 @@ func SSHDir(baseDir, proxy, username string) string { return filepath.Join(ProxyKeyDir(baseDir, proxy), username+sshDirSuffix) } +// PPKFilePath returns the path to the user's PuTTY PPK-formatted keypair +// for the given proxy and cluster. +// +// /keys//.ppk +func PPKFilePath(baseDir, proxy, username string) string { + return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtPPK) +} + // SSHCertPath returns the path to the users's SSH certificate // for the given proxy and cluster. // diff --git a/api/utils/sshutils/ppk/ppk.go b/api/utils/sshutils/ppk/ppk.go new file mode 100644 index 0000000000000..6c69e6c071bec --- /dev/null +++ b/api/utils/sshutils/ppk/ppk.go @@ -0,0 +1,213 @@ +/* +Copyright 2021 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package ppk provides functions implementing conversion between Teleport's native RSA +// keypairs and PuTTY's PPK format. It also provides functions for working with RFC4251-formatted +// mpints and strings. +package ppk + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/binary" + "encoding/hex" + "encoding/pem" + "fmt" + "math/big" + + "github.com/gravitational/teleport/api/constants" + "github.com/gravitational/trace" +) + +// ConvertToPPK takes a regular RSA-formatted keypair and converts it into the PPK file format used by the PuTTY SSH client. +// The file format is described here: https://the.earth.li/~sgtatham/putty/0.76/htmldoc/AppendixC.html#ppk +func ConvertToPPK(priv []byte, pub []byte) ([]byte, error) { + // decode the private key from PEM format and extract the exponents + privateKeyPemBlock, rest := pem.Decode(priv) + if len(rest) > 0 { + return nil, trace.Errorf("failed to decode private key, %v bytes left over", len(rest)) + } + privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes) + if err != nil { + return nil, trace.Errorf("failed to parse private key: %v", err) + } + + // https://the.earth.li/~sgtatham/putty/0.76/htmldoc/AppendixC.html#ppk + // RSA keys are stored using an algorithm-name of 'ssh-rsa'. (Keys stored like this are also used by the updated RSA signature schemes that use + // hashes other than SHA-1. The public key data has already provided the key modulus and the public encoding exponent. The private data stores: + // mpint: the private decoding exponent of the key. + // mpint: one prime factor p of the key. + // mpint: the other prime factor q of the key. (RSA keys stored in this format are expected to have exactly two prime factors.) + // mpint: the multiplicative inverse of q modulo p. + ppkPrivateKey := new(bytes.Buffer) + + // mpint: the private decoding exponent of the key. + // this is known as 'D' + binary.Write(ppkPrivateKey, binary.BigEndian, getRFC4251Mpint(privateKey.D)) + + // mpint: one prime factor p of the key. + // this is known as 'P' + // the RSA standard dictates that P > Q + // for some reason what PuTTY names 'P' is Primes[1] to Go, and what PuTTY names 'Q' is Primes[0] to Go + P, Q := privateKey.Primes[1], privateKey.Primes[0] + binary.Write(ppkPrivateKey, binary.BigEndian, getRFC4251Mpint(P)) + + // mpint: the other prime factor q of the key. (RSA keys stored in this format are expected to have exactly two prime factors.) + // this is known as 'Q' + binary.Write(ppkPrivateKey, binary.BigEndian, getRFC4251Mpint(Q)) + + // mpint: the multiplicative inverse of q modulo p. + // this is known as 'iqmp' + iqmp := new(big.Int).ModInverse(Q, P) + binary.Write(ppkPrivateKey, binary.BigEndian, getRFC4251Mpint(iqmp)) + + // now we need to base64-encode the PPK-formatted private key which is made up of the above values + ppkPrivateKeyBase64 := make([]byte, base64.StdEncoding.EncodedLen(ppkPrivateKey.Len())) + base64.StdEncoding.Encode(ppkPrivateKeyBase64, ppkPrivateKey.Bytes()) + + // read Teleport public key + // fortunately, this is the one thing that's in exactly the same format that the PPK file uses, so we can just copy it verbatim + // remove ssh-rsa plus additional space from beginning of string if present + if !bytes.HasPrefix(pub, []byte(constants.SSHRSAType+" ")) { + return nil, trace.BadParameter("pub does not appear to be an ssh-rsa public key") + } + pub = bytes.TrimSuffix(bytes.TrimPrefix(pub, []byte(constants.SSHRSAType+" ")), []byte("\n")) + + // the PPK file contains an anti-tampering MAC which is made up of various values which appear in the file. + // copied from Section C.3 of https://the.earth.li/~sgtatham/putty/0.76/htmldoc/AppendixC.html#ppk: + // hex-mac-data is a hexadecimal-encoded value, 64 digits long (i.e. 32 bytes), generated using the HMAC-SHA-256 algorithm with the following binary data as input: + // string: the algorithm-name header field. + // string: the encryption-type header field. + // string: the key-comment-string header field. + // string: the binary public key data, as decoded from the base64 lines after the 'Public-Lines' header. + // string: the plaintext of the binary private key data, as decoded from the base64 lines after the 'Private-Lines' header. + + // these values are also used in the MAC generation, so we declare them as variables + keyType := constants.SSHRSAType + encryptionType := "none" + // as work for the future, it'd be nice to get the proxy/user pair name in here to make the name more + // of a unique identifier. this has to be done at generation time because the comment is part of the MAC + fileComment := "teleport-generated-ppk" + + // string: the algorithm-name header field. + macKeyType := getRFC4251String([]byte(keyType)) + // create a buffer to hold the elements needed to generate the MAC + macInput := new(bytes.Buffer) + binary.Write(macInput, binary.LittleEndian, macKeyType) + + // string: the encryption-type header field. + macEncryptionType := getRFC4251String([]byte(encryptionType)) + binary.Write(macInput, binary.BigEndian, macEncryptionType) + + // string: the key-comment-string header field. + macComment := getRFC4251String([]byte(fileComment)) + binary.Write(macInput, binary.BigEndian, macComment) + + // base64-decode the Teleport public key, as we need its binary representation to generate the MAC + decoded := make([]byte, base64.StdEncoding.EncodedLen(len(pub))) + n, err := base64.StdEncoding.Decode(decoded, pub) + if err != nil { + return nil, trace.Errorf("could not base64-decode public key: %v, got %v bytes successfully", err, n) + } + decoded = decoded[:n] + // append the decoded public key bytes to the MAC buffer + macPublicKeyData := getRFC4251String(decoded) + binary.Write(macInput, binary.BigEndian, macPublicKeyData) + + // append our PPK-formatted private key bytes to the MAC buffer + macPrivateKeyData := getRFC4251String(ppkPrivateKey.Bytes()) + binary.Write(macInput, binary.BigEndian, macPrivateKeyData) + + // as per the PPK spec, the key for the MAC is blank when the PPK file is unencrypted. + // therefore, the key is a zero-length byte slice. + hmacHash := hmac.New(sha256.New, []byte{}) + // generate the MAC using HMAC-SHA-256 + hmacHash.Write(macInput.Bytes()) + macString := hex.EncodeToString(hmacHash.Sum(nil)) + + // build the string-formatted output PPK file + ppk := new(bytes.Buffer) + fmt.Fprintf(ppk, "PuTTY-User-Key-File-3: %v\n", keyType) + fmt.Fprintf(ppk, "Encryption: %v\n", encryptionType) + fmt.Fprintf(ppk, "Comment: %v\n", fileComment) + // chunk the Teleport-formatted public key into 64-character length lines + chunkedPublicKey := chunk(string(pub), 64) + fmt.Fprintf(ppk, "Public-Lines: %v\n", len(chunkedPublicKey)) + for _, r := range chunkedPublicKey { + fmt.Fprintf(ppk, "%s\n", r) + } + // chunk the PPK-formatted private key into 64-character length lines + chunkedPrivateKey := chunk(string(ppkPrivateKeyBase64), 64) + fmt.Fprintf(ppk, "Private-Lines: %v\n", len(chunkedPrivateKey)) + for _, r := range chunkedPrivateKey { + fmt.Fprintf(ppk, "%s\n", r) + } + fmt.Fprintf(ppk, "Private-MAC: %v\n", macString) + + return ppk.Bytes(), nil +} + +// chunk converts a string into a []string with chunks of size chunkSize; +// used to split base64-encoded strings across multiple lines with an even width. +// note: this function operates on Unicode code points rather than bytes, therefore +// using it with multi-byte characters will result in unevenly chunked strings. +// it's intended usage is only for chunking base64-encoded strings. +func chunk(s string, size int) []string { + var chunks []string + for b := []byte(s); len(b) > 0; { + n := size + if n > len(b) { + n = len(b) + } + chunks = append(chunks, string(b[:n])) + b = b[n:] + } + return chunks +} + +// getRFC4251Mpint returns a stream of bytes representing a mixed-precision integer (a big.Int in Go) +// prepended with a big-endian uint32 expressing the length of the data following. +// This is the 'mpint' format in RFC4251 Section 5 (https://datatracker.ietf.org/doc/html/rfc4251#section-5) +func getRFC4251Mpint(n *big.Int) []byte { + buf := new(bytes.Buffer) + b := n.Bytes() + // RFC4251: If the most significant bit would be set for a positive number, the number MUST be preceded by a zero byte. + if b[0]&0x80 > 0 { + b = append([]byte{0}, b...) + } + // write a uint32 with the length of the byte stream to the buffer + binary.Write(buf, binary.BigEndian, uint32(len(b))) + // write the byte stream representing of the rest of the integer to the buffer + binary.Write(buf, binary.BigEndian, b) + return buf.Bytes() +} + +// getRFC4251String returns a stream of bytes representing a string prepended with a big-endian unit32 +// expressing the length of the data following. +// This is the 'string' format in RFC4251 Section 5 (https://datatracker.ietf.org/doc/html/rfc4251#section-5) +func getRFC4251String(data []byte) []byte { + buf := new(bytes.Buffer) + // write a uint32 with the length of the byte stream to the buffer + binary.Write(buf, binary.BigEndian, uint32(len(data))) + // write the byte stream representing of the rest of the data to the buffer + for _, v := range data { + binary.Write(buf, binary.BigEndian, v) + } + return buf.Bytes() +} diff --git a/api/utils/sshutils/ppk/ppk_test.go b/api/utils/sshutils/ppk/ppk_test.go new file mode 100644 index 0000000000000..a9cb7d1d212ee --- /dev/null +++ b/api/utils/sshutils/ppk/ppk_test.go @@ -0,0 +1,358 @@ +/* +Copyright 2022 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package ppk_test provides tests for the ppk package +package ppk_test + +import ( + "testing" + + "github.com/gravitational/teleport/api/utils/sshutils/ppk" + "github.com/stretchr/testify/require" +) + +func TestConvertToPPK(t *testing.T) { + tests := []struct { + desc string + priv []byte + pub []byte + output []byte + wantErr bool + }{ + { + desc: "valid private and public keys 1", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA3U4OOAi+F1Ct1n8HZIs1P39CWB0mKLvshouuklenZug27SuI +14rjE+hOTNHYz/Pkvk5mmKuIdegMCe8FHAF6chygcEC9BDkowLO+2+f3sazGsu4A +9H4pDuUkuIM9MwmZV7A4TJ19rRAgha+6JKKR5KeEosfiLvAtOu2Pjqz8ZrOrUUqQ +1AJ71SkWMPTJFksTNmgaH7a0SgJ4vVYMlYIAeyoAgqn6Qvu5Kez5ROfeKD4zys/+ +iFenrgbJrC38GNe2rxtb8/gfy03023FlPAQjGd1VLjxm8jhcJFqgM+uHTGRckgjv +d+VIkCbvTwpPWvvZxQcRtk073P9G8xpiNz2qbwIDAQABAoIBAQCFv37obqA0BxaI +5AzbvyZXUdoO1s8RH0I7rn+7Ai6yCvXnMMBrRA0pIuTvmIOoaoZ8XXW0HzdByxQ7 +jLFR07Lk9Fgif328566xh/B5hyAzyW/tA9qf6P93eRVQTkDWb561WFMuOqCRz4VY +RnQBYB88SeHnX1Zbd9xeGOUCHZoNlrilVpgjscGcFNxyDP72qvI79z1vV+R6dhaf +YI2v1D6aqx9qM988ytOokNi79wYvSUxqitz3IOD5nBd9ZNBC0fDeVmHqqbHSvLrr +LouF7PiUuVA2LaWfVCy5dVtLkS16qbsfqzUA4B8Eg/oF0vPpJ7QMVxKI5j2//ScL +lQ9h6gUBAoGBAOQ0t9gGuHKOMcp3H9C2fzNVbbWTubJoUyzFGyx+U2aJ4byRbxS3 +5d9cVu1GpS2ZgW6izCmxTG61Q0qQd4iT8e5cnFRU1Q3aK29TTK5hptthknXwKkVN +vUtlYKRM3TPYeTJ3WMQCY/Lzm2uVhT2ZGkpu0NaA5qiWllyPm7HlyQA/AoGBAPhC +KzioaPlqzwNKtHCsDSyeXsxU1aJCuMCIcgOB1yzmaaeL95CwMouMgouFyQ/CtLtO +pQEjymGzVynwC15s1vh1nCOWlQCx6Cjs9ko9bmecqziyyWg94gn82yLU7gClQH6v ++ezQ1n7/pb1DO/8dytO3+BZKSQH9lobzravGTcnRAoGAL8nKZfaiUXrtelSP2Qke +ggV1v/x7epzWLh3ontylYmelWfOqq1AHV0ri+TU+CdqHfD+jOWfjdZuHx+mQ3oz8 +sMm8Avzw0MHLLrjm6e2RH4fDP+dXMsQgy9Ui88UU3XKLjsHnWMSXYZ0aAuGA0XFq +TAQAv6qmos9GFYQNOqe/+8kCgYEAv88H69eae5J9bTKr5R3Zc+7MmZy2Do70hbUm +OfV4lbVUTmJDHWQ1OUKPnlL4fJfX4Zwquo23kPLqVnmjnwoCsabUw15Vs1rBX9Vt +mQCLq7wNQlpIaKTfXw4hFXFkjdUf1oIKXGEiSK8mk+s9kKepDRlnsXklnUcbpRri +xQQLF/ECgYAmKBSQtPuyA9d3dAZj96HhYZzDjD2EtAhSUyx31vgqr8C7mmShQXLh +kFap4eAldBxySXp/5af7H1Xf4BIfbbc1prMM1vIRFTN6l6rbircak7bb9a/dgWmX +iukFsFq0G0Y2zt9oHOB7pKV/Kff4o1WQ0hcCBD6pZGhbsVxXBi4Oaw== +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdTg44CL4XUK3WfwdkizU/f0JYHSYou+yGi66SV6dm6DbtK4jXiuMT6E5M0djP8+S+TmaYq4h16AwJ7wUcAXpyHKBwQL0EOSjAs77b5/exrMay7gD0fikO5SS4gz0zCZlXsDhMnX2tECCFr7okopHkp4Six+Iu8C067Y+OrPxms6tRSpDUAnvVKRYw9MkWSxM2aBoftrRKAni9VgyVggB7KgCCqfpC+7kp7PlE594oPjPKz/6IV6euBsmsLfwY17avG1vz+B/LTfTbcWU8BCMZ3VUuPGbyOFwkWqAz64dMZFySCO935UiQJu9PCk9a+9nFBxG2TTvc/0bzGmI3Papv`), + output: []byte(`PuTTY-User-Key-File-3: ssh-rsa +Encryption: none +Comment: teleport-generated-ppk +Public-Lines: 6 +AAAAB3NzaC1yc2EAAAADAQABAAABAQDdTg44CL4XUK3WfwdkizU/f0JYHSYou+yG +i66SV6dm6DbtK4jXiuMT6E5M0djP8+S+TmaYq4h16AwJ7wUcAXpyHKBwQL0EOSjA +s77b5/exrMay7gD0fikO5SS4gz0zCZlXsDhMnX2tECCFr7okopHkp4Six+Iu8C06 +7Y+OrPxms6tRSpDUAnvVKRYw9MkWSxM2aBoftrRKAni9VgyVggB7KgCCqfpC+7kp +7PlE594oPjPKz/6IV6euBsmsLfwY17avG1vz+B/LTfTbcWU8BCMZ3VUuPGbyOFwk +WqAz64dMZFySCO935UiQJu9PCk9a+9nFBxG2TTvc/0bzGmI3Papv +Private-Lines: 14 +AAABAQCFv37obqA0BxaI5AzbvyZXUdoO1s8RH0I7rn+7Ai6yCvXnMMBrRA0pIuTv +mIOoaoZ8XXW0HzdByxQ7jLFR07Lk9Fgif328566xh/B5hyAzyW/tA9qf6P93eRVQ +TkDWb561WFMuOqCRz4VYRnQBYB88SeHnX1Zbd9xeGOUCHZoNlrilVpgjscGcFNxy +DP72qvI79z1vV+R6dhafYI2v1D6aqx9qM988ytOokNi79wYvSUxqitz3IOD5nBd9 +ZNBC0fDeVmHqqbHSvLrrLouF7PiUuVA2LaWfVCy5dVtLkS16qbsfqzUA4B8Eg/oF +0vPpJ7QMVxKI5j2//ScLlQ9h6gUBAAAAgQD4Qis4qGj5as8DSrRwrA0snl7MVNWi +QrjAiHIDgdcs5mmni/eQsDKLjIKLhckPwrS7TqUBI8phs1cp8AtebNb4dZwjlpUA +sego7PZKPW5nnKs4ssloPeIJ/Nsi1O4ApUB+r/ns0NZ+/6W9Qzv/HcrTt/gWSkkB +/ZaG862rxk3J0QAAAIEA5DS32Aa4co4xyncf0LZ/M1VttZO5smhTLMUbLH5TZonh +vJFvFLfl31xW7UalLZmBbqLMKbFMbrVDSpB3iJPx7lycVFTVDdorb1NMrmGm22GS +dfAqRU29S2VgpEzdM9h5MndYxAJj8vOba5WFPZkaSm7Q1oDmqJaWXI+bseXJAD8A +AACBAM6/w3llPMNA/ZRm8wIXXssPgAZCN79zYtVu6n4KMqBzi7qj1er4gzsLZpKS +hpfdO/mDPhA3eFwU3XjYCKlHiJJYk53mc5sWwvbsfibAZSZAII/V4xWvRUUPE9EX +INDa/8cd4YSy3PiZnUTNLVb2SmRFhnlB8ZBk3CyGEvcHskir +Private-MAC: 2697903ac84b70273afc7adaa4e3ebb14536cdaf69654d40e3d46a5ba997ffb0 +`), + wantErr: false, + }, + { + desc: "valid private and public keys 2", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAve2um90K1SkpJD1vcjm2zUYUh5ZU7q1cmO7F0J/6MCEcq3vH +fDPpPZ4uGLB9jPKzs6FYWhwFNW2oAsDvWSrwwxy5gl1dAdqp1wIm86gafShR0se5 +rSdhWKP40H2lHOysRC5Jr8cvVLgflvZ4PDMqr/63BKwwkT1vN2PuenYRAAIT77X9 +O0fumGQPKIxRGn5OPKEt1LzQ0+e/QlWrqZwzWDx5jqG3jbxibdcR/mHS60XdvusL +UqxxWPjhVlDsKfvh2lt5sqsjulWW/GyNtlCfaTn2uu0nV8nbT2OvEO+oM/uyHos5 +7aIyePcOzCVM4dug6xJinqYTaVUsskKjPGUV6QIDAQABAoIBAQCBfis9k6DOIukt +D0IL5DOxk2Vt6F5x+PsYPjva+SfwZrMQbC1fjlkpLM8LAFIpplRFVe1SSqZ2fhQ+ +BGNsLS3IKa6FprhCCl8f/BSoreWZjcLz7j63QxFJCUscg33u0aLGPbT5xtmLbpoD +KHpjuRMSuZz475mRfQx1/IldL2B52sIAD6XRTgFoRG+mLu2iNVvuE0RVbASiyOUs +lVwrGRI+5GuH8G6fDCJqpYzcm/S8VXmQc2jrbo/gQ76MkFxULqEMzadjN+XMXms7 +pGZLX6Hatubn1kmhl8l6+1GYLf1HVmWXoL+hgWwbfIn6WV9y/xpnoeoJfWcFLJli +yABDx/mBAoGBAPhw3thyEP+5jdH2n1vz4X76yUbNJXaJGXozdoNfFKNOrYjFCLnD +CzHJEQmDJoFCtF6TwgvFb90HNvtNLkbC81yotQ8rfDzNTlixUhycaSsCJBqw0loU +wXoYQZiXpbfqT9Y7x7pwMxzRtkQYvyaowc7qF1xwJHhyCjDx38jAGnZxAoGBAMO1 +DXUpca09h+FujJkziyJStYq0YKqsuKXW7CuAq2iY70lzhv+SIPErqcYIWwi8JNv9 +EwBlEmSltFyGtxpeIVl6MJTil3vQ6eOSBCwt/E1YKvZoLv6mDf52Lc/wKtlecRPG +Q7G2C1ioTD9lDiYysUDmkpfitiatFwEj+y606wL5AoGBAMlQJLM9Ets1D19QuWb4 +YwPS0aBGgZHgnD1yUBk5xW5jRajrCBwGmR6Zb+3GUUAyvhdZIccKEJAI1Zuiudnr +BOpTZovJT92w+0hRP1khwPJxxLHAEGOgJ/r4hsbQMx+phVHylPBVFIXIxSm+5726 +x3kUJSPpVxQmTG3GwPBaAddxAoGALq+4QCTc22j8S0jl/X4QSOXWLPqOvOhrPBSj +TlVpjpA9NRZ8M+eWODIkU/uWS+UmHdyndcamtp/ZAOGaOI4QApplkH7liEH0Kbeh +izCFKaZIyXNdEp5mZDepAhvW/PfMnd0ENRaqakHrvovK7k3VfxgCDH2m2l8cR8df +mmrKTXECgYEA300gTnT46pMU1Wr1Zq4vGauWzk3U4J9HUu3vNy+sg4EEZ9CoiNTw +0a3f8u8gNQjB30koGW/5jYex3fUcnjTPqEGaiiGjI4oxMhquzqkVQ8FwnBAXJgT8 +nQVO8MZw8iFeSap0ILum8t60sp1/u9aCWJbjPtb/fhx0q7SLdjFEw8s= +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC97a6b3QrVKSkkPW9yObbNRhSHllTurVyY7sXQn/owIRyre8d8M+k9ni4YsH2M8rOzoVhaHAU1bagCwO9ZKvDDHLmCXV0B2qnXAibzqBp9KFHSx7mtJ2FYo/jQfaUc7KxELkmvxy9UuB+W9ng8Myqv/rcErDCRPW83Y+56dhEAAhPvtf07R+6YZA8ojFEafk48oS3UvNDT579CVaupnDNYPHmOobeNvGJt1xH+YdLrRd2+6wtSrHFY+OFWUOwp++HaW3myqyO6VZb8bI22UJ9pOfa67SdXydtPY68Q76gz+7IeizntojJ49w7MJUzh26DrEmKephNpVSyyQqM8ZRXp`), + output: []byte(`PuTTY-User-Key-File-3: ssh-rsa +Encryption: none +Comment: teleport-generated-ppk +Public-Lines: 6 +AAAAB3NzaC1yc2EAAAADAQABAAABAQC97a6b3QrVKSkkPW9yObbNRhSHllTurVyY +7sXQn/owIRyre8d8M+k9ni4YsH2M8rOzoVhaHAU1bagCwO9ZKvDDHLmCXV0B2qnX +AibzqBp9KFHSx7mtJ2FYo/jQfaUc7KxELkmvxy9UuB+W9ng8Myqv/rcErDCRPW83 +Y+56dhEAAhPvtf07R+6YZA8ojFEafk48oS3UvNDT579CVaupnDNYPHmOobeNvGJt +1xH+YdLrRd2+6wtSrHFY+OFWUOwp++HaW3myqyO6VZb8bI22UJ9pOfa67SdXydtP +Y68Q76gz+7IeizntojJ49w7MJUzh26DrEmKephNpVSyyQqM8ZRXp +Private-Lines: 14 +AAABAQCBfis9k6DOIuktD0IL5DOxk2Vt6F5x+PsYPjva+SfwZrMQbC1fjlkpLM8L +AFIpplRFVe1SSqZ2fhQ+BGNsLS3IKa6FprhCCl8f/BSoreWZjcLz7j63QxFJCUsc +g33u0aLGPbT5xtmLbpoDKHpjuRMSuZz475mRfQx1/IldL2B52sIAD6XRTgFoRG+m +Lu2iNVvuE0RVbASiyOUslVwrGRI+5GuH8G6fDCJqpYzcm/S8VXmQc2jrbo/gQ76M +kFxULqEMzadjN+XMXms7pGZLX6Hatubn1kmhl8l6+1GYLf1HVmWXoL+hgWwbfIn6 +WV9y/xpnoeoJfWcFLJliyABDx/mBAAAAgQDDtQ11KXGtPYfhboyZM4siUrWKtGCq +rLil1uwrgKtomO9Jc4b/kiDxK6nGCFsIvCTb/RMAZRJkpbRchrcaXiFZejCU4pd7 +0OnjkgQsLfxNWCr2aC7+pg3+di3P8CrZXnETxkOxtgtYqEw/ZQ4mMrFA5pKX4rYm +rRcBI/sutOsC+QAAAIEA+HDe2HIQ/7mN0fafW/PhfvrJRs0ldokZejN2g18Uo06t +iMUIucMLMckRCYMmgUK0XpPCC8Vv3Qc2+00uRsLzXKi1Dyt8PM1OWLFSHJxpKwIk +GrDSWhTBehhBmJelt+pP1jvHunAzHNG2RBi/JqjBzuoXXHAkeHIKMPHfyMAadnEA +AACAE820IDiCymxsVqgmBSNJttApBaSl3ljTzWWeJQR7ksIm9kBvy30j1682v0yq +RyPuY1EmQ3DJ3LqXbFq4qK12R/tALasyYyDYsJTt1xh+peFv23OSF8kDlG4MOdUp +3WPivAMSPR0QR192Emb0caXEkyAhvQLHKGoi8/TgbfMG6Gc= +Private-MAC: b5ede95d052e23815c8e8d816c758fb16370fc3178e1613fee61ec158900fd64 +`), + wantErr: false, + }, + { + desc: "valid public and private keys 3", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAz5J/f572H95c9DDZLrXT0kmjytznkvntSOjxmJM44fL8DQz2 +NINFi4awTNYD1eIIzaO4LLw+uXFWKD2P9LgtJ/Cxdb9LRi1OZ5Qrw/jj173zf/g+ +wpItjoakgAzerHxKAPj3DB8iHFfPq+3MfdY36SZHT0GOU7QIhnYULKWWuVfexx25 +VtgdGsmL9jwfAftzh00aCIej9zi2eSfGYfcIeRlSh9wvoYldrZbRvLTeMbW+YznW +kH4W9taCGofrq/t8tN0beh9B7z2hMGxOLLnsxu3gQc2KIUqU5l1myL0rVncvSwZw +ppQudZYtRyzmLOOm9PEvJHWvgu6KQBj5F24xrwIDAQABAoIBAQC0BgOMJMqjkxAd +POxvhYUjoXhr7bDuGNKB5H38bNrto/aUPwSdQKilPPhUe1yyOCqYZwDJ06222aP2 +nIXooX+QX0EZtQHM6GhSjwByI78/kl/IQf30dCEMtpue7wqEn/ry4vooSiwkVsgm +/cPX811kWS2JgHq2/7JRI8GVgzu4m/wLtOVUIUiSG/zNZWx/ThEvvE/528z5MZG5 +zGuQobHH+zfGYqk9IABcpNMH+4S353oPXAej2bCsQU6x+alM5z0fi+PuWIWtaDIb +e/Va9WN2fghXF5lxu/+sCv8QkoPotbRfh0nLO0nTt4MUIFR0X/mVXbVWn+5SBhWC +YUgcjychAoGBAOtLKKqkYzuOIyB2E3b7dPJ1XuzHOXj0Co5DoVNNs8TyEggoQPuj +cTLUQaIN+M+MyNmtLi4GaF1dXRrJg7qZoJ681Vz0P+w+pso1UTQcja5G8iOwiKAD +MIkyH9t9iW8yDN+J0dEzTqAgOPIDxkwDWuvwvsBleJ2EAV6qdecjLpIRAoGBAOHW +0NGHYe4GCbt/gA5UVUYXehx9mckcLwyZJJThjTZXYr1kglRYa4de5YRMk9oPCHUu +ODKqxL8CTcKyIijj1fJGDVcqTPFXlS4UZ31RLMvVnDaMID7V2zx+wxJ9onwhj798 +1k3fVahH2vXOFH9AogeHKDNyD1RdwDNOhBy95Me/AoGALV+bAf0dXbi1MWdTrZgk +HzVfDs4EWTzGZFTKYWQUjKAZthT9IwmLpL+lwHhtSKjfeoqY4ys9KPP+JlJB4tQJ +U1Ma2ggH46jZRRkvBZuT/s2TmCpMzn6O94YA+rSkshq2vMy491yrhtlv4cu0i6gB ++om8XyGyNr3j/btlbSMtseECgYB66UL1Bk2SEc8yMI4tPlC6uQRIhUMxZRlmLeLu +9GK6dIzUruMPrJ+5KTiY7GR7hTsBK4qCaNZzbnmLwQ8+WeGS3fVcvzTpFNWoIorA +dXF/7l36ggD6scGEByl74syP6mQlv3eTIj2oPJM6vFIDf9WvayvB9A3LyMpWIiFc +0yy0WQKBgQDCPCUvQhiOJyQ63n3pjFl5/YOtadl9KUD/CmdyUkCt69QoFgG0wTAV +qalC9sysLQ1QI8A8GHNoNPjqMi7SWvzSgYN9TDRjS5GRlH13EALzP7AhWJWDoLYU +9DXNAEQrPMtX4Lzre7FmrYqEYqwdcac+vyXVgDA7ti1LhDhj8mm3Sg== +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkn9/nvYf3lz0MNkutdPSSaPK3OeS+e1I6PGYkzjh8vwNDPY0g0WLhrBM1gPV4gjNo7gsvD65cVYoPY/0uC0n8LF1v0tGLU5nlCvD+OPXvfN/+D7Cki2OhqSADN6sfEoA+PcMHyIcV8+r7cx91jfpJkdPQY5TtAiGdhQspZa5V97HHblW2B0ayYv2PB8B+3OHTRoIh6P3OLZ5J8Zh9wh5GVKH3C+hiV2tltG8tN4xtb5jOdaQfhb21oIah+ur+3y03Rt6H0HvPaEwbE4suezG7eBBzYohSpTmXWbIvStWdy9LBnCmlC51li1HLOYs46b08S8kda+C7opAGPkXbjGv`), + output: []byte(`PuTTY-User-Key-File-3: ssh-rsa +Encryption: none +Comment: teleport-generated-ppk +Public-Lines: 6 +AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkn9/nvYf3lz0MNkutdPSSaPK3OeS+e1I +6PGYkzjh8vwNDPY0g0WLhrBM1gPV4gjNo7gsvD65cVYoPY/0uC0n8LF1v0tGLU5n +lCvD+OPXvfN/+D7Cki2OhqSADN6sfEoA+PcMHyIcV8+r7cx91jfpJkdPQY5TtAiG +dhQspZa5V97HHblW2B0ayYv2PB8B+3OHTRoIh6P3OLZ5J8Zh9wh5GVKH3C+hiV2t +ltG8tN4xtb5jOdaQfhb21oIah+ur+3y03Rt6H0HvPaEwbE4suezG7eBBzYohSpTm +XWbIvStWdy9LBnCmlC51li1HLOYs46b08S8kda+C7opAGPkXbjGv +Private-Lines: 14 +AAABAQC0BgOMJMqjkxAdPOxvhYUjoXhr7bDuGNKB5H38bNrto/aUPwSdQKilPPhU +e1yyOCqYZwDJ06222aP2nIXooX+QX0EZtQHM6GhSjwByI78/kl/IQf30dCEMtpue +7wqEn/ry4vooSiwkVsgm/cPX811kWS2JgHq2/7JRI8GVgzu4m/wLtOVUIUiSG/zN +ZWx/ThEvvE/528z5MZG5zGuQobHH+zfGYqk9IABcpNMH+4S353oPXAej2bCsQU6x ++alM5z0fi+PuWIWtaDIbe/Va9WN2fghXF5lxu/+sCv8QkoPotbRfh0nLO0nTt4MU +IFR0X/mVXbVWn+5SBhWCYUgcjychAAAAgQDh1tDRh2HuBgm7f4AOVFVGF3ocfZnJ +HC8MmSSU4Y02V2K9ZIJUWGuHXuWETJPaDwh1LjgyqsS/Ak3CsiIo49XyRg1XKkzx +V5UuFGd9USzL1Zw2jCA+1ds8fsMSfaJ8IY+/fNZN31WoR9r1zhR/QKIHhygzcg9U +XcAzToQcveTHvwAAAIEA60soqqRjO44jIHYTdvt08nVe7Mc5ePQKjkOhU02zxPIS +CChA+6NxMtRBog34z4zI2a0uLgZoXV1dGsmDupmgnrzVXPQ/7D6myjVRNByNrkby +I7CIoAMwiTIf232JbzIM34nR0TNOoCA48gPGTANa6/C+wGV4nYQBXqp15yMukhEA +AACAJ2iqIoXMYc0w3sXBQJ2BJyRYFBlZ0Czrz7xZEaBXrK5BcZjCARnmAp2Hfuvx +i0lz0PHAz9f6hpjZuLEGLO7f3kGMcyEquYd89FHvP1yLxggYiXGKNDYSDZRK8Yy7 +MipqcnT4j5zDuFi744aO5fIchKp02z+ttGVt/i5zuGNh+do= +Private-MAC: a9b12c6450e46fd7abbaaff5841f8a64f9597c7b2b59bd69d6fd3ceee0ca61ea +`), + }, + { + desc: "invalid private key", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA3U4OOAi+F1Ct1n8HZIs1P39CWB0mKLvshouuklenZug27SuI +14rjE+hOTNHYz/Pkvk5mmKuIdegMCe8FHAF6chygcEC9BDkowLO+2+f3sazGsu4A +9H4pDuUkuIM9MwmZV7A4TJ19rRAgha+6JKKR5KeEosfiLvAtOu2Pjqz8ZrOrUUqQ +1AJ71SkWMPTJFksTNmgaH7a0SgJ4vVYMlYIAeyoAgqn6Qvu5Kez5ROfeKD4zys/+ +iFenrgbJrC38GNe2rxtb8/gfy03023FlPAQjGd1VLjxm8jhcJFqgM+uHTGRckgjv +d+VIkCbvTwpPWvvZxQcRtk073P9G8xpiNz2qbwIDAQABAoIBAQCFv37obqA0BxaI +5AzbvyZXUdoO1s8RH0I7rn+7Ai6yCvXnMMBrRA0pIuTvmIOoaoZ8XXW0HzdByxQ7 +jLFR07Lk9Fgif328566xh/B5hyAzyW/tA9qf6P93eRVQTkDWb561WFMuOqCRz4VY +RnQBYB88SeHnX1Zbd9xeGOUCHZoNlrilVpgjscGcFNxyDP72qvI79z1vV+R6dhaf +YI2v1D6aqx9qM988ytOokNi79wYvSUxqitz3IOD5nBd9ZNBC0fDeVmHqqbHSvLrr +LouF7PiUuVA2LaWfVCy5dVtLkS16qbsfqzUA4B8Eg/oF0vPpJ7QMVxKI5j2//ScL +lQ9h6gUBAoGBAOQ0t9gGuHKOMcp3H9C2fzNVbbWTubJoUyzFGyx+U2aJ4byRbxS3 +5d9cVu1GpS2ZgW6izCmxTG61Q0qQd4iT8e5cnFRU1Q3aK29TTK5hptthknXwKkVN +aUtlYKRM3TPYeTJ3WMQCY/Lzm2uVhT2ZGkpu0NaA5qiWllyPm7HlyQA/AoGBAPhC +bzioaPlqzwNKtHCsDSyeXsxU1aJCuMCIcgOB1yzmaaeL95CwMouMgouFyQ/CtLtO +cQEjymGzVynwC15s1vh1nCOWlQCx6Cjs9ko9bmecqziyyWg94gn82yLU7gClQH6v +ezQ1n7/pb1DO/8dytO3+BZKSQH9lobzravGTcnRAoGAL8nKZfaiUXrtelSP2Qke; +ggV1v/x7epzWLh3ontylYmelWfOqq1AHV0ri+TU+CdqHfD+jOWfjdZuHx+mQ3oz8 +sMm8Avzw0MHLLrjm6e2RH4fDP+dXMsQgy9Ui88UU3XKLjsHnWMSXYZ0aAuGA0XFq +TAQAv6qmos9GFYQNOqe/+8kCgYEAv88H69eae5J9bTKr5R3Zc+7MmZy2Do70hbUm +OfV4lbVUTmJDHWQ1OUKPnlL4fJfX4Zwquo23kPLqVnmjnwoCsabUw15Vs1rBX9Vt +mQCLq7wNQlpIaKTfXw4hFXFkjdUf1oIKXGEiSK8mk+s9kKepDRlnsXklnUcbpRri +xQQLF/ECgYAmKBSQtPuyA9d3dAZj96HhYZzDjD2EtAhSUyx31vgqr8C7mmShQXLh +kFap4eAldBxySXp/5af7H1Xf4BIfbbc1prMM1vIRFTN6l6rbircak7bb9a/dgWmX +iukFsFq0G0Y2zt9oHOB7pKV/Kff4o1WQ0hcCBD6pZGhbsVxXBi4Oaw== +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdTg44CL4XUK3WfwdkizU/f0JYHSYou+yGi66SV6dm6DbtK4jXiuMT6E5M0djP8+S+TmaYq4h16AwJ7wUcAXpyHKBwQL0EOSjAs77b5/exrMay7gD0fikO5SS4gz0zCZlXsDhMnX2tECCFr7okopHkp4Six+Iu8C067Y+OrPxms6tRSpDUAnvVKRYw9MkWSxM2aBoftrRKAni9VgyVggB7KgCCqfpC+7kp7PlE594oPjPKz/6IV6euBsmsLfwY17avG1vz+B/LTfTbcWU8BCMZ3VUuPGbyOFwkWqAz64dMZFySCO935UiQJu9PCk9a+9nFBxG2TTvc/0bzGmI3Papv`), + wantErr: true, + }, + { + desc: "invalid public key", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAve2um90K1SkpJD1vcjm2zUYUh5ZU7q1cmO7F0J/6MCEcq3vH +fDPpPZ4uGLB9jPKzs6FYWhwFNW2oAsDvWSrwwxy5gl1dAdqp1wIm86gafShR0se5 +rSdhWKP40H2lHOysRC5Jr8cvVLgflvZ4PDMqr/63BKwwkT1vN2PuenYRAAIT77X9 +O0fumGQPKIxRGn5OPKEt1LzQ0+e/QlWrqZwzWDx5jqG3jbxibdcR/mHS60XdvusL +UqxxWPjhVlDsKfvh2lt5sqsjulWW/GyNtlCfaTn2uu0nV8nbT2OvEO+oM/uyHos5 +7aIyePcOzCVM4dug6xJinqYTaVUsskKjPGUV6QIDAQABAoIBAQCBfis9k6DOIukt +D0IL5DOxk2Vt6F5x+PsYPjva+SfwZrMQbC1fjlkpLM8LAFIpplRFVe1SSqZ2fhQ+ +BGNsLS3IKa6FprhCCl8f/BSoreWZjcLz7j63QxFJCUscg33u0aLGPbT5xtmLbpoD +KHpjuRMSuZz475mRfQx1/IldL2B52sIAD6XRTgFoRG+mLu2iNVvuE0RVbASiyOUs +lVwrGRI+5GuH8G6fDCJqpYzcm/S8VXmQc2jrbo/gQ76MkFxULqEMzadjN+XMXms7 +pGZLX6Hatubn1kmhl8l6+1GYLf1HVmWXoL+hgWwbfIn6WV9y/xpnoeoJfWcFLJli +yABDx/mBAoGBAPhw3thyEP+5jdH2n1vz4X76yUbNJXaJGXozdoNfFKNOrYjFCLnD +CzHJEQmDJoFCtF6TwgvFb90HNvtNLkbC81yotQ8rfDzNTlixUhycaSsCJBqw0loU +wXoYQZiXpbfqT9Y7x7pwMxzRtkQYvyaowc7qF1xwJHhyCjDx38jAGnZxAoGBAMO1 +DXUpca09h+FujJkziyJStYq0YKqsuKXW7CuAq2iY70lzhv+SIPErqcYIWwi8JNv9 +EwBlEmSltFyGtxpeIVl6MJTil3vQ6eOSBCwt/E1YKvZoLv6mDf52Lc/wKtlecRPG +Q7G2C1ioTD9lDiYysUDmkpfitiatFwEj+y606wL5AoGBAMlQJLM9Ets1D19QuWb4 +YwPS0aBGgZHgnD1yUBk5xW5jRajrCBwGmR6Zb+3GUUAyvhdZIccKEJAI1Zuiudnr +BOpTZovJT92w+0hRP1khwPJxxLHAEGOgJ/r4hsbQMx+phVHylPBVFIXIxSm+5726 +x3kUJSPpVxQmTG3GwPBaAddxAoGALq+4QCTc22j8S0jl/X4QSOXWLPqOvOhrPBSj +TlVpjpA9NRZ8M+eWODIkU/uWS+UmHdyndcamtp/ZAOGaOI4QApplkH7liEH0Kbeh +izCFKaZIyXNdEp5mZDepAhvW/PfMnd0ENRaqakHrvovK7k3VfxgCDH2m2l8cR8df +mmrKTXECgYEA300gTnT46pMU1Wr1Zq4vGauWzk3U4J9HUu3vNy+sg4EEZ9CoiNTw +0a3f8u8gNQjB30koGW/5jYex3fUcnjTPqEGaiiGjI4oxMhquzqkVQ8FwnBAXJgT8 +nQVO8MZw8iFeSap0ILum8t60sp1/u9aCWJbjPtb/fhx0q7SLdjFEw8s= +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`AAAAB3NzaC1yc2EAAAADAQABAAABAQC9806b3QrVKSkkPW9yObbNRhSHllTurVyY7sXQn/owIRyre8d8M+k9ni4YsH2M8rOzoVhaHAU1bagCwO9ZKvDDHLmCXV0B2qnXAibzqBp9KFHSx7mtJ2FYo/jQfaUc7KxELkmvxy9UuB+W9ng8Myqv/rcErDCRPW83Y+56dhEAAhPvtf07R+6YZA8ojFEafk48oS3UvNDT579CVaupnDNYPHmOobeNvGJt1xH+YdLrRd2+6wtSrHFY+OFWUOwp++HaW3myqyO6VZb8bI22UJ9pOfa67SdXydtPY68Q76gz+7IeizntojJ49w7MJUzh26DrEmKephNpVSyyQqM8ZRXp`), + wantErr: true, + }, + { + desc: "private and public keys too short", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAve2um90K1SkpJD1vcjm2zUYUh5ZU7q1cmO7F0J/6MCEcq3vH +fDPpPZ4uGLB9jPKzs6FYWhwFNW2oAsDvWSrwwxy5gl1dAdqp1wIm86gafShR0se5 +rSdhWKP40H2lHOysRC5Jr8cvVLgflvZ4PDMqr/63BKwwkT1vN2PuenYRAAIT77X9 +O0fumGQPKIxRGn5OPKEt1LzQ0+e/QlWrqZwzWDx5jqG3jbxibdcR/mHS60XdvusL +UqxxWPjhVlDsKfvh2lt5sqsjulWW/GyNtlCfaTn2uu0nV8nbT2OvEO+oM/uyHos5 +7aIyePcOzCVM4dug6xJinqYTaVUsskKjPGUV6QIDAQABAoIBAQCBfis9k6DOIukt +D0IL5DOxk2Vt6F5x+PsYPjva+SfwZrMQbC1fjlkpLM8LAFIpplRFVe1SSqZ2fhQ+ +BGNsLS3IKa6FprhCCl8f/BSoreWZjcLz7j63QxFJCUscg33u0aLGPbT5xtmLbpoD +KHpjuRMSuZz475mRfQx1/IldL2B52sIAD6XRTgFoRG+mLu2iNVvuE0RVbASiyOUs +lVwrGRI+5GuH8G6fDCJqpYzcm/S8VXmQc2jrbo/gQ76MkFxULqEMzadjN+XMXms7 +pGZLX6Hatubn1kmhl8l6+1GYLf1HVmWXoL+hgWwbfIn6WV9y/xpnoeoJfWcFLJli +yABDx/mBAoGBAPhw3thyEP+5jdH2n1vz4X76yUbNJXaJGXozdoNfFKNOrYjFCLnD +CzHJEQmDJoFCtF6TwgvFb90HNvtNLkbC81yotQ8rfDzNTlixUhycaSsCJBqw0loU +wXoYQZiXpbfqT9Y7x7pwMxzRtkQYvyaowc7qF1xwJHhyCjDx38jAGnZxAoGBAMO1 +DXUpca09h+FujJkziyJStYq0YKqsuKXW7CuAq2iY70lzhv+SIPErqcYIWwi8JNv9 +EwBlEmSltFyGtxpeIVl6MJTil3vQ6eOSBCwt/E1YKvZoLv6mDf52Lc/wKtlecRPG +Q7G2C1ioTD9lDiYysUDmkpfitiatFwEj+y606wL5AoGBAMlQJLM9Ets1D19QuWb4 +YwPS0aBGgZHgnD1yUBk5xW5jRajrCBwGmR6Zb+3GUUAyvhdZIccKEJAI1Zuiudnr +BOpTZovJT92w+0hRP1khwPJxxLHAEGOgJ/r4hsbQMx+phVHylPBVFIXIxSm+5726 +x3kUJSPpVxQmTG3GwPBaAddxAoGALq+4QCTc22j8S0jl/X4QSOXWLPqOvOhrPBSj +TlVpjpA9NRZ8M+eWODIkU/uWS+UmHdyndcamtp/ZAOGaOI4QApplkH7liEH0Kbeh +izCFKaZIyXNdEp5mZDepAhvW/PfMnd0ENRaqakHrvovK7k3VfxgCDH2m2l8cR8df +mmrKTXECgYEA300gTnT46pMU1Wr1Zq4vGauWzk3U4J9HUu3vNy+sg4EEZ9CoiNTw +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`AAAAB3NzaC1yc2EAAAADAQABAAABAQC9806b3QrVKSkkPW9yObbNRhSHllTurVyY7sXQn/owIRyre8d8M+k9ni4YsH2M8rOzoVhaHAU1bagCwO9ZKvDDHLmCXV0B2qnXAibzqBp9KFHSx7mtJ2FYo/jQfaUc7KxELkmvxy9UuB+W9ng8Myqv/rcErDCRPW83Y+56dhEAAhPvtf07R+6YZA8ojFEafk48oS3UvNDT579CVaupnDNYPHmOobeNvGJt1xH+YdLrRd2+6wtSrHFY+OFWUOwp++HaW3myqyO6VZb8bI22UJ9pOfa67SdXydtPY68Q76gz+7IeizntojJ49w7MJUzh26DrEmKephNpVSyyQqM8`), + wantErr: true, + }, + { + desc: "private and public keys too long", + priv: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAz5J/f572H95c9DDZLrXT0kmjytznkvntSOjxmJM44fL8DQz2 +NINFi4awTNYD1eIIzaO4LLw+uXFWKD2P9LgtJ/Cxdb9LRi1OZ5Qrw/jj173zf/g+ +wpItjoakgAzerHxKAPj3DB8iHFfPq+3MfdY36SZHT0GOU7QIhnYULKWWuVfexx25 +VtgdGsmL9jwfAftzh00aCIej9zi2eSfGYfcIeRlSh9wvoYldrZbRvLTeMbW+YznW +kH4W9taCGofrq/t8tN0beh9B7z2hMGxOLLnsxu3gQc2KIUqU5l1myL0rVncvSwZw +ppQudZYtRyzmLOOm9PEvJHWvgu6KQBj5F24xrwIDAQABAoIBAQC0BgOMJMqjkxAd +POxvhYUjoXhr7bDuGNKB5H38bNrto/aUPwSdQKilPPhUe1yyOCqYZwDJ06222aP2 +nIXooX+QX0EZtQHM6GhSjwByI78/kl/IQf30dCEMtpue7wqEn/ry4vooSiwkVsgm +/cPX811kWS2JgHq2/7JRI8GVgzu4m/wLtOVUIUiSG/zNZWx/ThEvvE/528z5MZG5 +zGuQobHH+zfGYqk9IABcpNMH+4S353oPXAej2bCsQU6x+alM5z0fi+PuWIWtaDIb +e/Va9WN2fghXF5lxu/+sCv8QkoPotbRfh0nLO0nTt4MUIFR0X/mVXbVWn+5SBhWC +YUgcjychAoGBAOtLKKqkYzuOIyB2E3b7dPJ1XuzHOXj0Co5DoVNNs8TyEggoQPuj +cTLUQaIN+M+MyNmtLi4GaF1dXRrJg7qZoJ681Vz0P+w+pso1UTQcja5G8iOwiKAD +MIkyH9t9iW8yDN+J0dEzTqAgOPIDxkwDWuvwvsBleJ2EAV6qdecjLpIRAoGBAOHW +0NGHYe4GCbt/gA5UVUYXehx9mckcLwyZJJThjTZXYr1kglRYa4de5YRMk9oPCHUu +ODKqxL8CTcKyIijj1fJGDVcqTPFXlS4UZ31RLMvVnDaMID7V2zx+wxJ9onwhj798 +1k3fVahH2vXOFH9AogeHKDNyD1RdwDNOhBy95Me/AoGALV+bAf0dXbi1MWdTrZgk +HzVfDs4EWTzGZFTKYWQUjKAZthT9IwmLpL+lwHhtSKjfeoqY4ys9KPP+JlJB4tQJ +U1Ma2ggH46jZRRkvBZuT/s2TmCpMzn6O94YA+rSkshq2vMy491yrhtlv4cu0i6gB ++om8XyGyNr3j/btlbSMtseECgYB66UL1Bk2SEc8yMI4tPlC6uQRIhUMxZRlmLeLu +9GK6dIzUruMPrJ+5KTiY7GR7hTsBK4qCaNZzbnmLwQ8+WeGS3fVcvzTpFNWoIorA +dXF/7l36ggD6scGEByl74syP6mQlv3eTIj2oPJM6vFIDf9WvayvB9A3LyMpWIiFc +0yy0WQKBgQDCPCUvQhiOJyQ63n3pjFl5/YOtadl9KUD/CmdyUkCt69QoFgG0wTAV +qalC9sysLQ1QI8A8GHNoNPjqMi7SWvzSgYN9TDRjS5GRlH13EALzP7AhWJWDoLYU +9DXNAEQrPMtX4Lzre7FmrYqEYqwdcac+vyXVgDA7ti1LhDhj8mm3Sg12371237== +-----END RSA PRIVATE KEY----- +`), + pub: []byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkn9/nvYf3lz0MNkutdPSSaPK3OeS+e1I6PGYkzjh8vwNDPY0g0WLhrBM1gPV4gjNo7gsvD65cVYoPY/0uC0n8LF1v0tGLU5nlCvD+OPXvfN/+D7Cki2OhqSADN6sfEoA+PcMHyIcV8+r7cx91jfpJkdPQY5TtAiGdhQspZa5V97HHblW2B0ayYv2PB8B+3OHTRoIh6P3OLZ5J8Zh9wh5GVKH3C+hiV2tltG8tN4xtb5jOdaQfhb21oIah+ur+3y03Rt6H0HvPaEwbE4suezG7eBBzYohSpTmXWbIvStWdy9LBnCmlC51li1HLOYs46b08S8kda+C7opAGPkXbjGvkj121`), + wantErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + if tc.wantErr { + _, err := ppk.ConvertToPPK(tc.priv, tc.pub) + require.Error(t, err) + } else { + output, err := ppk.ConvertToPPK(tc.priv, tc.pub) + require.NoError(t, err) + require.Equal(t, output, tc.output) + } + }) + } +} diff --git a/api/version.go b/api/version.go index 6757e1e81c6b7..6ebb00dc2cfc8 100644 --- a/api/version.go +++ b/api/version.go @@ -3,7 +3,7 @@ package api const ( - Version = "10.0.0-dev" + Version = "10.0.0" ) // Gitref variable is automatically set to the output of git-describe diff --git a/assets/aws/files/bin/teleport-generate-config b/assets/aws/files/bin/teleport-generate-config index a7a096876a2d6..20a6101a2d9ab 100755 --- a/assets/aws/files/bin/teleport-generate-config +++ b/assets/aws/files/bin/teleport-generate-config @@ -64,8 +64,8 @@ aws_metadata_get() { if ! is_test; then IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300") - IMDS_TOKEN_HEADER="-H \"X-aws-ec2-metadata-token: ${IMDS_TOKEN}\"" - curl -m5 -sS "${IMDS_TOKEN_HEADER}" ${CURL_EXTRA_ARGS} http://169.254.169.254/latest/${REQUEST_PATH} + IMDS_TOKEN_HEADER="X-aws-ec2-metadata-token: ${IMDS_TOKEN}" + curl -m5 -sS -H "${IMDS_TOKEN_HEADER}" ${CURL_EXTRA_ARGS} http://169.254.169.254/latest/${REQUEST_PATH} else # return a pre-calculated value VARIABLE="TELEPORT_TESTVAR_${REQUEST}" diff --git a/build.assets/Dockerfile b/build.assets/Dockerfile index c5eb42e9f8fc3..fbb78488bda35 100644 --- a/build.assets/Dockerfile +++ b/build.assets/Dockerfile @@ -166,8 +166,6 @@ RUN (curl -L https://github.com/bats-core/bats-core/archive/v1.2.1.tar.gz | tar ARG PROTOC_VER ARG GOGO_PROTO_TAG ENV GOGOPROTO_ROOT ${GOPATH}/src/github.com/gogo/protobuf -ENV PROTOC_NO_VENDOR true -ENV PROTOC /usr/local/bin/protoc RUN (export PROTOC_TARBALL=protoc-${PROTOC_VER}-linux-$(if [ "$BUILDARCH" = "amd64" ]; then echo "x86_64"; else echo "aarch_64"; fi).zip && \ curl -L -o /tmp/${PROTOC_TARBALL} https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VER}/${PROTOC_TARBALL} && \ diff --git a/build.assets/Dockerfile-centos7 b/build.assets/Dockerfile-centos7 index a187ad11e28b4..a0bc960eabf74 100644 --- a/build.assets/Dockerfile-centos7 +++ b/build.assets/Dockerfile-centos7 @@ -19,11 +19,12 @@ RUN git clone --depth=1 https://github.com/illiliti/libudev-zero.git -b 1.0.1 && # Instal openssl. # Pulled from source because repository versions are too old. +# install_sw install only binaries, skips docs. RUN git clone --depth=1 git://git.openssl.org/openssl.git -b OpenSSL_1_1_1o && \ cd openssl && \ ./config --release && \ make && \ - make install + make install_sw # Install libcbor. RUN git clone --depth=1 https://github.com/PJK/libcbor.git -b v0.9.0 && \ @@ -52,6 +53,35 @@ RUN git clone --depth=1 https://github.com/Yubico/libfido2.git -b 1.11.0 && \ echo /usr/local/lib64 > /etc/ld.so.conf.d/libfido2.conf && \ ldconfig +FROM centos:7 AS libbpf + +# Install required dependencies. +RUN yum groupinstall -y 'Development Tools' && \ + yum install -y epel-release && \ + yum update -y && \ + yum -y install centos-release-scl-rh && \ + yum install -y \ + # required by libbpf + centos-release-scl \ + # required by libbpf + devtoolset-11-gcc* \ + # required by libbpf + devtoolset-11-make \ + # required by libbpf + elfutils-libelf-devel-static \ + git \ + # required by libbpf + scl-utils \ + yum clean all + +# Install libbpf - compile with a newer GCC. The one installed by default is not able to compile it. +# BUILD_STATIC_ONLY disables libbpf.so build as we don't need it. +ARG LIBBPF_VERSION +RUN mkdir -p /opt && cd /opt && \ + curl -L https://github.com/gravitational/libbpf/archive/refs/tags/v${LIBBPF_VERSION}.tar.gz | tar xz && \ + cd /opt/libbpf-${LIBBPF_VERSION}/src && \ + scl enable devtoolset-11 "make && BUILD_STATIC_ONLY=y DESTDIR=/opt/libbpf make install" + FROM centos:7 AS buildbox ENV LANGUAGE=en_US.UTF-8 \ @@ -68,14 +98,27 @@ RUN (groupadd ci --gid=$GID -o && useradd ci --uid=$UID --gid=$GID --create-home mkdir -p -m0700 /var/lib/teleport && chown -R ci /var/lib/teleport) RUN yum groupinstall -y 'Development Tools' && \ + yum install -y epel-release && \ + yum update -y && \ + yum -y install centos-release-scl-rh && \ yum install -y \ - git \ - libatomic \ - net-tools \ - pam-devel \ - perl-IPC-Cmd \ - tree \ - zip \ + #required by libbpf + centos-release-scl \ + # required by libbpf + devtoolset-11-* \ + # required by libbpf + elfutils-libelf-devel-static \ + git \ + net-tools \ + # required by Teleport PAM support + pam-devel \ + perl-IPC-Cmd \ + tree \ + # used by our Makefile + which \ + zip \ + # required by libbpf + zlib-static && \ yum clean all # Install etcd. @@ -90,7 +133,11 @@ RUN mkdir -p /opt && cd /opt && curl https://storage.googleapis.com/golang/$GOLA /opt/go/bin/go version ENV GOPATH="/go" \ GOROOT="/opt/go" \ - PATH="/opt/bin:$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" + PATH="/opt/llvm/bin:$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" + +# BUILDARCH is automatically set by DOCKER when building the image with Build Kit (MacOS by deafult). +# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope +ARG BUILDARCH # Install PAM module and policies for testing. COPY pam/ /opt/pam_teleport/ @@ -142,6 +189,12 @@ RUN cd /usr/local/lib64 && \ COPY pkgconfig/centos7/ / ENV PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig" +# Download pre-built CentOS 7 assets with clang needed to build BPF tools. +RUN cd / && curl -L https://s3.amazonaws.com/clientbuilds.gravitational.io/go/centos7-assets.tar.gz | tar -xz + +# Copy libbpf into the final image. +COPY --from=libbpf /opt/libbpf/usr /usr + USER ci VOLUME ["/go/src/github.com/gravitational/teleport"] EXPOSE 6600 2379 2380 diff --git a/build.assets/Dockerfile-centos7-fips b/build.assets/Dockerfile-centos7-fips index 9c44974b6631c..a6440ef88eb0e 100644 --- a/build.assets/Dockerfile-centos7-fips +++ b/build.assets/Dockerfile-centos7-fips @@ -1,3 +1,32 @@ +FROM centos:7 AS libbpf + +# Install required dependencies. +RUN yum groupinstall -y 'Development Tools' && \ + yum install -y epel-release && \ + yum update -y && \ + yum -y install centos-release-scl-rh && \ + yum install -y \ + # required by libbpf + centos-release-scl \ + # required by libbpf + devtoolset-11-gcc* \ + # required by libbpf + devtoolset-11-make \ + # required by libbpf + elfutils-libelf-devel-static \ + git \ + # required by libbpf + scl-utils \ + yum clean all + +# Install libbpf - compile with a newer GCC. The one installed by default is not able to compile it. +# BUILD_STATIC_ONLY disables libbpf.so build as we don't need it. +ARG LIBBPF_VERSION +RUN mkdir -p /opt && cd /opt && \ + curl -L https://github.com/gravitational/libbpf/archive/refs/tags/v${LIBBPF_VERSION}.tar.gz | tar xz && \ + cd /opt/libbpf-${LIBBPF_VERSION}/src && \ + scl enable devtoolset-11 "make && BUILD_STATIC_ONLY=y DESTDIR=/opt/libbpf make install" + FROM centos:7 ENV LANGUAGE=en_US.UTF-8 \ @@ -5,7 +34,6 @@ ENV LANGUAGE=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \ LC_CTYPE=en_US.UTF-8 -ARG RUST_VERSION ARG BORINGCRYPTO_RUNTIME ARG GO_BOOTSTRAP_RUNTIME=go1.9.7 @@ -14,9 +42,28 @@ ARG GID RUN (groupadd ci --gid=$GID -o && useradd ci --uid=$UID --gid=$GID --create-home --shell=/bin/sh && \ mkdir -p -m0700 /var/lib/teleport && chown -R ci /var/lib/teleport) -# Install dev tools (make, etc) and a Perl package needed to build OpenSSL. -RUN yum groupinstall -y "Development Tools" -RUN yum install -y pam-devel net-tools tree git zip libatomic perl-IPC-Cmd && \ +RUN yum groupinstall -y 'Development Tools' && \ + yum install -y epel-release && \ + yum update -y && \ + yum -y install centos-release-scl-rh && \ + yum install -y \ + #required by libbpf + centos-release-scl \ + # required by libbpf + devtoolset-11-* \ + # required by libbpf + elfutils-libelf-devel-static \ + git \ + net-tools \ + # required by Teleport PAM support + pam-devel \ + perl-IPC-Cmd \ + tree \ + # used by our Makefile + which \ + zip \ + # required by libbpf + zlib-static && \ yum clean all # Install etcd. @@ -38,32 +85,22 @@ RUN mkdir -p /go-bootstrap && cd /go-bootstrap && curl https://dl.google.com/go/ chmod a-w / && \ /opt/go/bin/go version +ENV GOPATH="/go" \ + GOROOT="/opt/go" \ + PATH="/opt/llvm/bin:$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" + # Install PAM module and policies for testing. COPY pam/ /opt/pam_teleport/ RUN make -C /opt/pam_teleport install -# Install Rust. -ENV RUSTUP_HOME=/usr/local/rustup \ - CARGO_HOME=/usr/local/cargo \ - PATH=/usr/local/cargo/bin:$PATH \ - RUST_VERSION=$RUST_VERSION - -RUN mkdir -p $RUSTUP_HOME && chmod a+w $RUSTUP_HOME && \ - mkdir -p $CARGO_HOME/registry && chmod -R a+w $CARGO_HOME - RUN chmod a-w / -USER ci -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain $RUST_VERSION && \ - rustup --version && \ - cargo --version && \ - rustc --version && \ - rustup component add --toolchain $RUST_VERSION-x86_64-unknown-linux-gnu rustfmt clippy && \ - cargo install cbindgen +# Download pre-built CentOS 7 assets with clang needed to build BPF tools. +RUN cd / && curl -L https://s3.amazonaws.com/clientbuilds.gravitational.io/go/centos7-assets.tar.gz | tar -xz -ENV GOPATH="/go" \ - GOROOT="/opt/go" \ - PATH="/opt/bin:$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" +# Copy libbpf into the final image. +COPY --from=libbpf /opt/libbpf/usr /usr +USER ci VOLUME ["/go/src/github.com/gravitational/teleport"] EXPOSE 6600 2379 2380 diff --git a/build.assets/Dockerfile-fips b/build.assets/Dockerfile-fips index 67a6b68c30efe..fdd4f00639b8d 100644 --- a/build.assets/Dockerfile-fips +++ b/build.assets/Dockerfile-fips @@ -62,6 +62,9 @@ RUN mkdir -p /opt && cd /opt && curl https://go-boringcrypto.storage.googleapis. chmod a+w /go && \ chmod a+w /var/lib && \ chmod a-w / +ENV GOPATH="/go" \ + GOROOT="/opt/go" \ + PATH="$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" # Install libbpf ARG LIBBPF_VERSION @@ -70,10 +73,6 @@ RUN mkdir -p /opt && cd /opt && curl -L https://github.com/gravitational/libbpf/ make && \ make install -ENV GOPATH="/go" \ - GOROOT="/opt/go" \ - PATH="$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" - # Install PAM module and policies for testing. COPY pam/ /opt/pam_teleport/ RUN make -C /opt/pam_teleport install diff --git a/build.assets/Makefile b/build.assets/Makefile index 0dea5197420f6..270a3081c9ca7 100644 --- a/build.assets/Makefile +++ b/build.assets/Makefile @@ -18,7 +18,7 @@ OS ?= linux ARCH ?= amd64 BUILDBOX_VERSION ?= teleport10 GOLANG_VERSION ?= go1.18.3 -RUST_VERSION ?= 1.61.0 +RUST_VERSION ?= 1.58.1 # don't bump this without checking GLIBC compatibility NODE_VERSION ?= 16.13.2 BORINGCRYPTO_RUNTIME=$(GOLANG_VERSION)b7 LIBBPF_VERSION ?= 0.7.0-teleport @@ -158,8 +158,11 @@ buildbox-centos7: docker build \ --build-arg UID=$(UID) \ --build-arg GID=$(GID) \ + --build-arg BUILDARCH=$(RUNTIME_ARCH) \ --build-arg GOLANG_VERSION=$(GOLANG_VERSION) \ --build-arg RUST_VERSION=$(RUST_VERSION) \ + --build-arg PROTOC_VER=$(PROTOC_VER) \ + --build-arg LIBBPF_VERSION=$(LIBBPF_VERSION) \ --cache-from $(BUILDBOX_CENTOS7) \ --tag $(BUILDBOX_CENTOS7) -f Dockerfile-centos7 . @@ -174,6 +177,7 @@ buildbox-centos7-fips: --build-arg GID=$(GID) \ --build-arg BORINGCRYPTO_RUNTIME=$(BORINGCRYPTO_RUNTIME) \ --build-arg RUST_VERSION=$(RUST_VERSION) \ + --build-arg LIBBPF_VERSION=$(LIBBPF_VERSION) \ --cache-from $(BUILDBOX_CENTOS7_FIPS) \ --tag $(BUILDBOX_CENTOS7_FIPS) -f Dockerfile-centos7-fips . @@ -393,7 +397,7 @@ release-fips: buildbox-fips .PHONY:release-centos7 release-centos7: buildbox-centos7 docker run $(DOCKERFLAGS) -i $(NOROOT) $(BUILDBOX_CENTOS7) \ - /usr/bin/make release -e ADDFLAGS="$(ADDFLAGS)" OS=$(OS) ARCH=$(ARCH) RUNTIME=$(GOLANG_VERSION) FIDO2=$(FIDO2) REPRODUCIBLE=no + /usr/bin/scl enable devtoolset-11 'make release -e ADDFLAGS="$(ADDFLAGS)" OS=$(OS) ARCH=$(ARCH) RUNTIME=$(GOLANG_VERSION) FIDO2=$(FIDO2) REPRODUCIBLE=no' # # Create a Teleport FIPS package for CentOS 7 using the build container. @@ -402,7 +406,7 @@ release-centos7: buildbox-centos7 .PHONY:release-centos7-fips release-centos7-fips: docker run $(DOCKERFLAGS) -i $(NOROOT) $(BUILDBOX_CENTOS7_FIPS) \ - /usr/bin/make -C e release -e ADDFLAGS="$(ADDFLAGS)" OS=$(OS) ARCH=$(ARCH) RUNTIME=$(GOLANG_VERSION) FIPS=yes VERSION=$(VERSION) GITTAG=v$(VERSION) REPRODUCIBLE=no + /usr/bin/scl enable devtoolset-11 '/usr/bin/make -C e release -e ADDFLAGS="$(ADDFLAGS)" OS=$(OS) ARCH=$(ARCH) RUNTIME=$(GOLANG_VERSION) FIPS=yes VERSION=$(VERSION) GITTAG=v$(VERSION) REPRODUCIBLE=no' # # Create a Windows Teleport package using the build container. @@ -410,15 +414,15 @@ release-centos7-fips: .PHONY:release-windows release-windows: buildbox docker run $(DOCKERFLAGS) -i $(NOROOT) $(BUILDBOX) \ - /usr/bin/make release -e ADDFLAGS="$(ADDFLAGS)" OS=windows + /usr/bin/make release -e ADDFLAGS="$(ADDFLAGS)" OS=windows RUNTIME=$(GOLANG_VERSION) REPRODUCIBLE=yes # -# Create a Windows Teleport package using the build container. +# Create an unsigned Windows Teleport package using the build container. # .PHONY:release-windows-unsigned release-windows-unsigned: buildbox docker run $(DOCKERFLAGS) -i $(NOROOT) $(BUILDBOX) \ - /usr/bin/make release-windows-unsigned -e ADDFLAGS="$(ADDFLAGS)" OS=windows + /usr/bin/make release-windows-unsigned -e ADDFLAGS="$(ADDFLAGS)" OS=windows RUNTIME=$(GOLANG_VERSION) REPRODUCIBLE=yes # # Run docs tester to detect problems. @@ -459,3 +463,11 @@ print-node-version: .PHONY:print-buildbox-version print-buildbox-version: @echo $(BUILDBOX_VERSION) + +# +# Build CentOS 7 assets such as clang. +# +.PHONY:build-centos7-assets +build-centos7-assets: + docker build --build-arg LIBBPF_VERSION=$(LIBBPF_VERSION) -t buildbox-centos7-assets -f Dockerfile-centos7-assets . + docker run -v $$(pwd):/centos7.assets -it buildbox-centos7-assets cp /centos7-assets.tar.gz /centos7.assets diff --git a/build.assets/build-common.sh b/build.assets/build-common.sh index 0593d132ba47a..841e2bffb8659 100644 --- a/build.assets/build-common.sh +++ b/build.assets/build-common.sh @@ -101,11 +101,14 @@ notarize() { fi # XCode 12. - local goncfg='' - goncfg="$(mktemp)" + local gondir='' + gondir="$(mktemp -d)" # Early expansion on purpose. #shellcheck disable=SC2064 - trap "rm -f '$goncfg'" EXIT + trap "rm -fr '$gondir'" EXIT + + # Gon configuration file needs a proper extension. + local goncfg="$gondir/gon.json" cat >"$goncfg" <"$toydir/toy.c" < + +int main() { + fido_init(0 /* flags */); + return 0; +} +EOF + + export PKG_CONFIG_PATH="$PKGFILE_DIR" + # Word splitting desired for pkg-config. + #shellcheck disable=SC2046 + gcc \ + $(pkg-config --cflags --libs libfido2-static) \ + -o "$toydir/toy.bin" \ + "$toydir/toy.c" +} + usage() { echo "Usage: $0 build|pkg_config_path" >&2 } build() { - local cbor_path="$LIB_CACHE/cbor-$CBOR_VERSION" - local crypto_path="$LIB_CACHE/crypto-$CRYPTO_VERSION" - local fido2_path="$LIB_CACHE/fido2-$FIDO2_VERSION" - - if [[ ! -d "$cbor_path" ]]; then + if [[ ! -d "$CBOR_PATH" ]]; then cbor_fetch_and_build fi - if [[ ! -d "$crypto_path" ]]; then + if [[ ! -d "$CRYPTO_PATH" ]]; then crypto_fetch_and_build fi - if [[ ! -d "$fido2_path" ]]; then + if [[ ! -d "$FIDO2_PATH" ]]; then fido2_fetch_and_build fi @@ -163,11 +189,8 @@ build() { trap "rm -f '$tmp'" EXIT # Write libfido2-static.pc to tmp. - local cbor="$LIB_CACHE/cbor-$CBOR_VERSION" - local crypto="$LIB_CACHE/crypto-$CRYPTO_VERSION" - local fido2="$LIB_CACHE/fido2-$FIDO2_VERSION" cat >"$tmp" <&2 + rm -fr "$CBOR_PATH" "$CRYPTO_PATH" "$FIDO2_PATH" + build + fi ;; pkg_config_path) echo "$PKGFILE_DIR" diff --git a/build.assets/build-pkg-tsh.sh b/build.assets/build-pkg-tsh.sh index d01bfa791913e..4aa29114461e6 100755 --- a/build.assets/build-pkg-tsh.sh +++ b/build.assets/build-pkg-tsh.sh @@ -130,7 +130,8 @@ password created by APPLE_USERNAME" "$target" # Prepare and sign the installer package. - target="$tmp/tsh-v$TELEPORT_VERSION.pkg" # switches from app to pkg + # Note that the installer does __NOT__ have a `v` in the version number. + target="$tmp/tsh-$TELEPORT_VERSION.pkg" # switches from app to pkg pkgbuild \ --root "$tmp/root/" \ --identifier "$TSH_BUNDLEID" \ @@ -155,7 +156,7 @@ password created by APPLE_USERNAME" mv "$target" . local bn='' bn="$(basename "$target")" - sha256sum "$bn" > "$bn.sha256" + shasum -a 256 "$bn" > "$bn.sha256" } main "$@" diff --git a/constants.go b/constants.go index 750794a6fabe9..b20a891b28c1b 100644 --- a/constants.go +++ b/constants.go @@ -246,6 +246,9 @@ const ( // ComponentTracing is a tracing exporter ComponentTracing = "tracing" + // ComponentInstance is an abstract component common to all services. + ComponentInstance = "instance" + // DebugEnvVar tells tests to use verbose debug output DebugEnvVar = "DEBUG" diff --git a/docker/teleport-ent-quickstart.yml b/docker/teleport-ent-quickstart.yml index f6b25dde811d7..7772cb6137366 100644 --- a/docker/teleport-ent-quickstart.yml +++ b/docker/teleport-ent-quickstart.yml @@ -3,7 +3,7 @@ services: # The configure container starts, generates a config, writes it to # /etc/teleport/teleport.yaml and then immediately exits. configure: - image: quay.io/gravitational/teleport-ent:9 + image: quay.io/gravitational/teleport-ent:10 container_name: teleport-configure entrypoint: /bin/sh hostname: localhost @@ -14,7 +14,7 @@ services: # This container depends on the config written by the configure container above, so it # sleeps for a second on startup to allow the configure container to run first. teleport: - image: quay.io/gravitational/teleport-ent:9 + image: quay.io/gravitational/teleport-ent:10 container_name: teleport entrypoint: /bin/sh hostname: localhost diff --git a/docker/teleport-lab.yml b/docker/teleport-lab.yml index 3298d11034d5e..4aaaf76db5e9e 100644 --- a/docker/teleport-lab.yml +++ b/docker/teleport-lab.yml @@ -3,7 +3,7 @@ services: # This container depends on the config written by the configure container above, so it # sleeps for a second on startup to allow the configure container to run first. teleport: - image: quay.io/gravitational/teleport-lab:9 + image: quay.io/gravitational/teleport-lab:10 container_name: teleport entrypoint: /bin/sh hostname: luna.teleport @@ -24,7 +24,7 @@ services: # The bootstrap container generates certificates and then immediately exits. bootstrap: - image: quay.io/gravitational/teleport-lab:9 + image: quay.io/gravitational/teleport-lab:10 container_name: teleport-bootstrap entrypoint: /bin/sh command: -c "/etc/teleport.d/scripts/generate-certs.sh" @@ -41,7 +41,7 @@ services: # openssh is a demo of openssh node # openssh: - image: quay.io/gravitational/teleport-lab:9 + image: quay.io/gravitational/teleport-lab:10 container_name: openssh hostname: mars.openssh.teleport entrypoint: /bin/sh @@ -60,7 +60,7 @@ services: # term is a container with a terminal to try things out # term: - image: quay.io/gravitational/teleport-lab:9 + image: quay.io/gravitational/teleport-lab:10 hostname: term container_name: term entrypoint: /bin/sh diff --git a/docker/teleport-quickstart.yml b/docker/teleport-quickstart.yml index a8e1a7a7075d7..d8367789e8b54 100644 --- a/docker/teleport-quickstart.yml +++ b/docker/teleport-quickstart.yml @@ -3,7 +3,7 @@ services: # The configure container starts, generates a config, writes it to # /etc/teleport/teleport.yaml and then immediately exits. configure: - image: quay.io/gravitational/teleport:9 + image: quay.io/gravitational/teleport:10 container_name: teleport-configure entrypoint: /bin/sh hostname: localhost @@ -14,7 +14,7 @@ services: # This container depends on the config written by the configure container above, so it # sleeps for a second on startup to allow the configure container to run first. teleport: - image: quay.io/gravitational/teleport:9 + image: quay.io/gravitational/teleport:10 container_name: teleport entrypoint: /bin/sh hostname: localhost diff --git a/docs/config.json b/docs/config.json index 524fd0ae970f5..c31ec82335b46 100644 --- a/docs/config.json +++ b/docs/config.json @@ -18,23 +18,19 @@ "entries": [ { "title": "Linux Server", - "slug": "/getting-started/linux-server/", - "hideInScopes": [ - "enterprise", - "cloud" - ] + "slug": "/getting-started/linux-server/" }, { "title": "Docker Compose", "slug": "/getting-started/docker-compose/" }, { - "title": "DigitalOcean", - "slug": "/getting-started/digitalocean/", - "hideInScopes": [ - "enterprise", - "cloud" - ] + "title": "Local Kubernetes Lab", + "slug": "/getting-started/local-kubernetes/" + }, + { + "title": "Kubernetes Cluster", + "slug": "/getting-started/kubernetes-cluster/" } ] }, @@ -97,22 +93,48 @@ { "title": "Deployments", "slug": "/setup/deployments/", - "hideInScopes": "cloud", "entries": [ { "title": "AWS Terraform", - "slug": "/setup/deployments/aws-terraform/", - "hideInScopes": "cloud" + "slug": "/setup/deployments/aws-terraform/" }, { "title": "GCP", - "slug": "/setup/deployments/gcp/", - "hideInScopes": "cloud" + "slug": "/setup/deployments/gcp/" }, { "title": "IBM", - "slug": "/setup/deployments/ibm/", - "hideInScopes": "cloud" + "slug": "/setup/deployments/ibm/" + }, + { + "title": "Digital Ocean", + "slug": "/setup/deployments/digitalocean/" + } + ] + }, + { + "title": "Helm Deployments", + "slug": "/setup/helm-deployments/", + "entries": [ + { + "title": "AWS EKS Cluster", + "slug": "/setup/helm-deployments/aws/" + }, + { + "title": "Google Cloud GKE Cluster", + "slug": "/setup/helm-deployments/gcp/" + }, + { + "title": "DigitalOcean Kubernetes Cluster", + "slug": "/setup/helm-deployments/digitalocean/" + }, + { + "title": "Customize Deployment Config", + "slug": "/setup/helm-deployments/custom/" + }, + { + "title": "Migrating From Older Charts", + "slug": "/setup/helm-deployments/migration/" } ] }, @@ -122,8 +144,7 @@ "entries": [ { "title": "Scaling", - "slug": "/setup/operations/scaling/", - "hideInScopes": "cloud" + "slug": "/setup/operations/scaling/" }, { "title": "Upgrading a Cluster", @@ -179,8 +200,7 @@ }, { "title": "Joining Nodes via AWS EC2", - "slug": "/setup/guides/joining-nodes-aws-ec2/", - "hideInScopes": "cloud" + "slug": "/setup/guides/joining-nodes-aws-ec2/" }, { "title": "Using Teleport's CA with GitHub", @@ -222,8 +242,7 @@ }, { "title": "Storage Backends", - "slug": "/setup/reference/backends/", - "hideInScopes": "cloud" + "slug": "/setup/reference/backends/" }, { "title": "Networking", @@ -329,8 +348,7 @@ }, { "title": "Recording Proxy Mode", - "slug": "/server-access/guides/recording-proxy-mode/", - "hideInScopes": "cloud" + "slug": "/server-access/guides/recording-proxy-mode/" }, { "title": "BPF Session Recording", @@ -343,6 +361,10 @@ { "title": "Visual Studio Code", "slug": "/server-access/guides/vscode/" + }, + { + "title": "Host User Creation", + "slug": "/server-access/guides/host-user-creation/" } ] } @@ -358,22 +380,7 @@ }, { "title": "Getting Started", - "slug": "/kubernetes-access/getting-started/", - "entries": [ - { - "title": "Local Demo Cluster", - "slug": "/kubernetes-access/getting-started/local/" - }, - { - "title": "Cluster", - "slug": "/kubernetes-access/getting-started/cluster/", - "hideInScopes": "cloud" - }, - { - "title": "Agent", - "slug": "/kubernetes-access/getting-started/agent/" - } - ] + "slug": "/kubernetes-access/getting-started/" }, { "title": "Guides", @@ -397,38 +404,6 @@ } ] }, - { - "title": "Helm Guides", - "slug": "/kubernetes-access/helm/guides/", - "hideInScopes": "cloud", - "entries": [ - { - "title": "AWS EKS Cluster", - "slug": "/kubernetes-access/helm/guides/aws/", - "hideInScopes": "cloud" - }, - { - "title": "Google Cloud GKE Cluster", - "slug": "/kubernetes-access/helm/guides/gcp/", - "hideInScopes": "cloud" - }, - { - "title": "DigitalOcean Kubernetes Cluster", - "slug": "/kubernetes-access/helm/guides/digitalocean/", - "hideInScopes": "cloud" - }, - { - "title": "Customize Deployment Config", - "slug": "/kubernetes-access/helm/guides/custom/", - "hideInScopes": "cloud" - }, - { - "title": "Migrating From Older Charts", - "slug": "/kubernetes-access/helm/guides/migration/", - "hideInScopes": "cloud" - } - ] - }, { "title": "Helm Chart Reference", "slug": "/kubernetes-access/helm/reference/", @@ -473,6 +448,10 @@ "title": "AWS Redshift", "slug": "/database-access/guides/postgres-redshift/" }, + { + "title": "AWS ElastiCache & MemoryDB", + "slug": "/database-access/guides/redis-aws/" + }, { "title": "GCP Cloud SQL PostgreSQL", "slug": "/database-access/guides/postgres-cloudsql/" @@ -517,6 +496,10 @@ "title": "SQL Server (Preview)", "slug": "/database-access/guides/sql-server-ad/" }, + { + "title": "Snowflake (Preview)", + "slug": "/database-access/guides/snowflake/" + }, { "title": "Database GUI Clients", "slug": "/database-access/guides/gui-clients/" @@ -681,6 +664,10 @@ "title": "Session Locking", "slug": "/access-controls/guides/locking/" }, + { + "title": "Passwordless (Preview)", + "slug": "/access-controls/guides/passwordless/" + }, { "title": "Second Factor - WebAuthn", "slug": "/access-controls/guides/webauthn/" @@ -691,8 +678,7 @@ }, { "title": "Dual Authorization", - "slug": "/access-controls/guides/dual-authz/", - "hideInScopes": "oss" + "slug": "/access-controls/guides/dual-authz/" }, { "title": "Impersonation", @@ -700,8 +686,7 @@ }, { "title": "Moderated Sessions", - "slug": "/access-controls/guides/moderated-sessions/", - "hideInScopes": "oss" + "slug": "/access-controls/guides/moderated-sessions/" } ] }, @@ -753,107 +738,71 @@ }, { "title": "Getting Started", - "slug": "/enterprise/getting-started/", - "hideInScopes": [ - "oss", - "cloud" - ] + "slug": "/enterprise/getting-started/" }, { "title": "Single Sign-On (SSO)", "slug": "/enterprise/sso/", - "hideInScopes": [ - "oss" - ], "entries": [ { "title": "Azure Active Directory (AD)", - "slug": "/enterprise/sso/azuread/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/azuread/" }, { "title": "Active Directory (ADFS)", - "slug": "/enterprise/sso/adfs/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/adfs/" }, { "title": "Google Workspace", - "slug": "/enterprise/sso/google-workspace/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/google-workspace/" }, { "title": "GitLab", - "slug": "/enterprise/sso/gitlab/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/gitlab/" }, { "title": "OneLogin", - "slug": "/enterprise/sso/one-login/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/one-login/" }, { "title": "OIDC", - "slug": "/enterprise/sso/oidc/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/oidc/" }, { "title": "Okta", - "slug": "/enterprise/sso/okta/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/sso/okta/" } ] }, { "title": "Access Requests", "slug": "/enterprise/workflow/", - "hideInScopes": [ - "oss" + "entries": [ + { + "title": "Resource Access Requests", + "slug": "/enterprise/workflow/resource-requests/" + }, + { + "title": "Role Access Requests", + "slug": "/enterprise/workflow/role-requests/" + } ] }, { "title": "FedRAMP", - "slug": "/enterprise/fedramp/", - "hideInScopes": [ - "cloud", - "oss" - ] + "slug": "/enterprise/fedramp/" }, { "title": "SOC2", - "slug": "/enterprise/soc2/", - "hideInScopes": [ - "oss" - ] + "slug": "/enterprise/soc2/" }, { "title": "HSM", - "slug": "/enterprise/hsm/", - "hideInScopes": [ - "cloud", - "oss" - ] + "slug": "/enterprise/hsm/" }, { "title": "Enterprise License File", - "slug": "/enterprise/license/", - "hideInScopes": [ - "cloud", - "oss" - ] + "slug": "/enterprise/license/" } ] }, @@ -867,11 +816,7 @@ }, { "title": "Getting Started", - "slug": "/cloud/getting-started/", - "hideInScopes": [ - "oss", - "enterprise" - ] + "slug": "/cloud/getting-started/" }, { "title": "Architecture", @@ -879,11 +824,7 @@ }, { "title": "Downloads", - "slug": "/cloud/downloads/", - "hideInScopes": [ - "oss", - "enterprise" - ] + "slug": "/cloud/downloads/" }, { "title": "FAQ", @@ -896,20 +837,16 @@ "title": "Architecture", "entries": [ { - "title": "Architecture Overview", + "title": "Overview", "slug": "/architecture/overview/" }, { - "title": "Teleport Users", - "slug": "/architecture/users/" - }, - { - "title": "Teleport Nodes", - "slug": "/architecture/nodes/" + "title": "Authentication", + "slug": "/architecture/authentication/" }, { - "title": "Teleport Auth", - "slug": "/architecture/authentication/" + "title": "Authorization", + "slug": "/architecture/authorization/" }, { "title": "Teleport Proxy", @@ -917,7 +854,11 @@ }, { "title": "Trusted Clusters", - "slug": "/trustedclusters/" + "slug": "/architecture/trustedclusters/" + }, + { + "title": "Teleport Nodes", + "slug": "/architecture/nodes/" }, { "title": "TLS Routing", @@ -955,7 +896,7 @@ } ], "variables": { - "version": "7.0", + "version": "10.0", "terraform": { "version": "1.0.0" }, @@ -974,7 +915,7 @@ "last_report": "April 12th, 2021" }, "cloud": { - "version": "8.3.4", + "version": "9.3.8", "sla": { "monthly_percentage": "99.5%", "monthly_downtime": "3 hours 40 minutes" @@ -1003,17 +944,22 @@ "min_version": "3.6" }, "teleport": { - "version": "9.0.4", - "golang": "1.17", + "version": "10.0.0", + "golang": "1.18", "plugin": { - "version": "9.0.4" + "version": "10.0.0" }, "helm_repo_url": "https://charts.releases.teleport.dev", - "latest_oss_docker_image": "quay.io/gravitational/teleport:9.1.2", - "latest_ent_docker_image": "quay.io/gravitational/teleport-ent:9.1.2" + "latest_oss_docker_image": "quay.io/gravitational/teleport:10.0.0", + "latest_ent_docker_image": "quay.io/gravitational/teleport-ent:10.0.0" } }, "redirects": [ + { + "source": "/architecture/users/", + "destination": "/architecture/authorization/", + "permanent": true + }, { "source": "/user-manual/", "destination": "/server-access/guides/tsh/", @@ -1263,6 +1209,61 @@ "source": "/application-access/guides/jwt/", "destination": "/application-access/jwt/", "permanent": true + }, + { + "source": "/docs/kubernetes-access/getting-started/agent/", + "destination": "/docs/kubernetes-access/getting-started/", + "permanent": true + }, + { + "source": "/docs/kubernetes-access/getting-started/cluster/", + "destination": "/docs/getting-started/kubernetes-cluster/", + "permanent": true + }, + { + "source": "/docs/kubernetes-access/getting-started/local/", + "destination": "/docs/getting-started/local-kubernetes/", + "permanent": true + }, + { + "source": "/access-controls/guides/u2f/", + "destination": "/access-controls/guides/webauthn/", + "permanent": true + }, + { + "source": "/getting-started/digitalocean/", + "destination": "/setup/deployments/digitalocean/", + "permanent": true + }, + { + "source": "/kubernetes-access/helm/guides/", + "destination": "/setup/helm-deployments/", + "permanent": true + }, + { + "source": "/kubernetes-access/helm/guides/aws/", + "destination": "/setup/helm-deployments/aws/", + "permanent": true + }, + { + "source": "/kubernetes-access/helm/guides/custom/", + "destination": "/setup/helm-deployments/custom/", + "permanent": true + }, + { + "source": "/kubernetes-access/helm/guides/digitalocean/", + "destination": "/setup/helm-deployments/digitalocean/", + "permanent": true + }, + { + "source": "/kubernetes-access/helm/guides/gcp/", + "destination": "/setup/helm-deployments/gcp/", + "permanent": true + }, + { + "source": "/kubernetes-access/helm/guides/migration/", + "destination": "/setup/helm-deployments/migration/", + "permanent": true } ] -} \ No newline at end of file +} diff --git a/docs/img/architecture/auth.png b/docs/img/architecture/auth.png new file mode 100644 index 0000000000000..dcc1dd90746d1 Binary files /dev/null and b/docs/img/architecture/auth.png differ diff --git a/docs/img/architecture/certs-machine-id@1.8x.svg b/docs/img/architecture/certs-machine-id@1.8x.svg new file mode 100644 index 0000000000000..adaa8e158ac45 --- /dev/null +++ b/docs/img/architecture/certs-machine-id@1.8x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/idp-sso-traits@1.5x.svg b/docs/img/architecture/idp-sso-traits@1.5x.svg new file mode 100644 index 0000000000000..0cb9efd7fb6ae --- /dev/null +++ b/docs/img/architecture/idp-sso-traits@1.5x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/node-registration@1.2x.svg b/docs/img/architecture/node-registration@1.2x.svg new file mode 100644 index 0000000000000..0251c72ac055b --- /dev/null +++ b/docs/img/architecture/node-registration@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/proxy-iap-to-resource@1.2x.svg b/docs/img/architecture/proxy-iap-to-resource@1.2x.svg new file mode 100644 index 0000000000000..764fe310c81f8 --- /dev/null +++ b/docs/img/architecture/proxy-iap-to-resource@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/proxy-tunnel@1.2x.svg b/docs/img/architecture/proxy-tunnel@1.2x.svg new file mode 100644 index 0000000000000..d19fa89e9ccf6 --- /dev/null +++ b/docs/img/architecture/proxy-tunnel@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/proxy-web-to-resource@1.2x.svg b/docs/img/architecture/proxy-web-to-resource@1.2x.svg new file mode 100644 index 0000000000000..97c962315601f --- /dev/null +++ b/docs/img/architecture/proxy-web-to-resource@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/proxy.png b/docs/img/architecture/proxy.png new file mode 100644 index 0000000000000..835cd8d19e8d3 Binary files /dev/null and b/docs/img/architecture/proxy.png differ diff --git a/docs/img/architecture/role-mapping@1.5x.svg b/docs/img/architecture/role-mapping@1.5x.svg new file mode 100644 index 0000000000000..54d1dc40f4d60 --- /dev/null +++ b/docs/img/architecture/role-mapping@1.5x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/ssh-cert-short-lived@1.5x.svg b/docs/img/architecture/ssh-cert-short-lived@1.5x.svg new file mode 100644 index 0000000000000..5c5c796ae5b01 --- /dev/null +++ b/docs/img/architecture/ssh-cert-short-lived@1.5x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/ssh-cert@2x.svg b/docs/img/architecture/ssh-cert@2x.svg new file mode 100644 index 0000000000000..bc38fe0347dae --- /dev/null +++ b/docs/img/architecture/ssh-cert@2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/ssh-certs-short-lived.png b/docs/img/architecture/ssh-certs-short-lived.png new file mode 100644 index 0000000000000..d9eeb429fc27c Binary files /dev/null and b/docs/img/architecture/ssh-certs-short-lived.png differ diff --git a/docs/img/architecture/ssh-certs-sso.png b/docs/img/architecture/ssh-certs-sso.png new file mode 100644 index 0000000000000..555fa5e120638 Binary files /dev/null and b/docs/img/architecture/ssh-certs-sso.png differ diff --git a/docs/img/architecture/ssh-direct-mode@1.2x.svg b/docs/img/architecture/ssh-direct-mode@1.2x.svg new file mode 100644 index 0000000000000..0220ed61a488e --- /dev/null +++ b/docs/img/architecture/ssh-direct-mode@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/ssh-host-cert@1.2x.svg b/docs/img/architecture/ssh-host-cert@1.2x.svg new file mode 100644 index 0000000000000..045f39095056f --- /dev/null +++ b/docs/img/architecture/ssh-host-cert@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/ssh-tunnel-mode@1.2x.svg b/docs/img/architecture/ssh-tunnel-mode@1.2x.svg new file mode 100644 index 0000000000000..7eb802c1c10e8 --- /dev/null +++ b/docs/img/architecture/ssh-tunnel-mode@1.2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/tc-role-mapping.svg b/docs/img/architecture/tc-role-mapping.svg new file mode 100644 index 0000000000000..ccef7a20e5405 --- /dev/null +++ b/docs/img/architecture/tc-role-mapping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/trusted-clusters@1.5x.svg b/docs/img/architecture/trusted-clusters@1.5x.svg new file mode 100644 index 0000000000000..5b0c9549ae6a9 --- /dev/null +++ b/docs/img/architecture/trusted-clusters@1.5x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/architecture/x509-cert@2x.svg b/docs/img/architecture/x509-cert@2x.svg new file mode 100644 index 0000000000000..20c53330e7716 --- /dev/null +++ b/docs/img/architecture/x509-cert@2x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/authn_authz.svg b/docs/img/authn_authz.svg deleted file mode 100644 index c2fbd647b0ea6..0000000000000 --- a/docs/img/authn_authz.svg +++ /dev/null @@ -1 +0,0 @@ -grav-00 10.X.X.1 arch=debianTeleportAuth APITeleport User : loginjoe : root, joe tara : taraWeb client> sshOpenSSHclientjoe:password 2FA: 265176Authentication : joe proves that he isjoe since he has thepassword and 2FAtokenAuthorization : joe is allowed to accessgrav-00 \ No newline at end of file diff --git a/docs/img/cert_invalid.svg b/docs/img/cert_invalid.svg deleted file mode 100644 index 519a762e0beae..0000000000000 --- a/docs/img/cert_invalid.svg +++ /dev/null @@ -1 +0,0 @@ -xCertificate has expired ornot signed, please log in1Auth returnsvalid certificateto client viaproxyjoe:password 2FA: 265176Web clientUser sends credentials Proxy forwards to auth> sshOpenSSHclient2joe:password 2FA: 2651763 \ No newline at end of file diff --git a/docs/img/cert_ok.svg b/docs/img/cert_ok.svg deleted file mode 100644 index 7087778ef2e24..0000000000000 --- a/docs/img/cert_ok.svg +++ /dev/null @@ -1 +0,0 @@ -Certificate has beensigned and is not expiredWeb client> sshOpenSSHclient \ No newline at end of file diff --git a/docs/img/cluster_state.svg b/docs/img/cluster_state.svg deleted file mode 100644 index 9a751de82a999..0000000000000 --- a/docs/img/cluster_state.svg +++ /dev/null @@ -1 +0,0 @@ -Teleport User: login joe : root, joe tara : taraNode : IP : Labels grav-00 : 10.X.X.1 : arch=ubuntu grav-01 : 10.X.X.2 : arch=debian grav-02 : 10.X.X.3 : arch=rhel Tokens: Expiry: Type fuzzywuzzywasabear : 2019-10-19 : Node BBBCDDDDBBBBBBBB : 2019-10-16 : UserCluster State is storedin a location configuredby the auth service,locally by defaultIP: 10.X.X.1 Labels: arch=ubuntuIP: 10.X.X.3 Labels: arch=rhelIP: 10.X.X.2 Labels: arch=debian \ No newline at end of file diff --git a/docs/img/database-access/guides/redis/redis-aws-managed-user-tag.png b/docs/img/database-access/guides/redis/redis-aws-managed-user-tag.png new file mode 100644 index 0000000000000..ff684ba29985c Binary files /dev/null and b/docs/img/database-access/guides/redis/redis-aws-managed-user-tag.png differ diff --git a/docs/img/database-access/guides/redis_elasticache_cloud.png b/docs/img/database-access/guides/redis_elasticache_cloud.png new file mode 100644 index 0000000000000..c962bad2051a1 Binary files /dev/null and b/docs/img/database-access/guides/redis_elasticache_cloud.png differ diff --git a/docs/img/database-access/guides/redis_elasticache_selfhosted.png b/docs/img/database-access/guides/redis_elasticache_selfhosted.png new file mode 100644 index 0000000000000..15ad6a9147ed2 Binary files /dev/null and b/docs/img/database-access/guides/redis_elasticache_selfhosted.png differ diff --git a/docs/img/database-access/guides/snowflake/dbeaver-driver.png b/docs/img/database-access/guides/snowflake/dbeaver-driver.png new file mode 100644 index 0000000000000..aad3f911c3e50 Binary files /dev/null and b/docs/img/database-access/guides/snowflake/dbeaver-driver.png differ diff --git a/docs/img/database-access/guides/snowflake/dbeaver-main-screen.png b/docs/img/database-access/guides/snowflake/dbeaver-main-screen.png new file mode 100644 index 0000000000000..2a2a19ed334a9 Binary files /dev/null and b/docs/img/database-access/guides/snowflake/dbeaver-main-screen.png differ diff --git a/docs/img/database-access/guides/snowflake/dbeaver-main.png b/docs/img/database-access/guides/snowflake/dbeaver-main.png new file mode 100644 index 0000000000000..226244f6d2173 Binary files /dev/null and b/docs/img/database-access/guides/snowflake/dbeaver-main.png differ diff --git a/docs/img/database-access/guides/snowflake/dbeaver-select-database.png b/docs/img/database-access/guides/snowflake/dbeaver-select-database.png new file mode 100644 index 0000000000000..f741275f2e78e Binary files /dev/null and b/docs/img/database-access/guides/snowflake/dbeaver-select-database.png differ diff --git a/docs/img/database-access/guides/snowflake/dbeaver-success.png b/docs/img/database-access/guides/snowflake/dbeaver-success.png new file mode 100644 index 0000000000000..3fbeb3b6cc48b Binary files /dev/null and b/docs/img/database-access/guides/snowflake/dbeaver-success.png differ diff --git a/docs/img/database-access/guides/snowflake/jetbrains-add-database.png b/docs/img/database-access/guides/snowflake/jetbrains-add-database.png new file mode 100644 index 0000000000000..266c7e159f758 Binary files /dev/null and b/docs/img/database-access/guides/snowflake/jetbrains-add-database.png differ diff --git a/docs/img/database-access/guides/snowflake/jetbrains-advanced.png b/docs/img/database-access/guides/snowflake/jetbrains-advanced.png new file mode 100644 index 0000000000000..8074dd7de8295 Binary files /dev/null and b/docs/img/database-access/guides/snowflake/jetbrains-advanced.png differ diff --git a/docs/img/database-access/guides/snowflake/jetbrains-general.png b/docs/img/database-access/guides/snowflake/jetbrains-general.png new file mode 100644 index 0000000000000..348a96ab7264a Binary files /dev/null and b/docs/img/database-access/guides/snowflake/jetbrains-general.png differ diff --git a/docs/img/database-access/guides/snowflake/jetbrains-success.png b/docs/img/database-access/guides/snowflake/jetbrains-success.png new file mode 100644 index 0000000000000..246b0da46ea8c Binary files /dev/null and b/docs/img/database-access/guides/snowflake/jetbrains-success.png differ diff --git a/docs/img/database-access/guides/snowflake_cloud.png b/docs/img/database-access/guides/snowflake_cloud.png new file mode 100644 index 0000000000000..3f96e9a4d717b Binary files /dev/null and b/docs/img/database-access/guides/snowflake_cloud.png differ diff --git a/docs/img/database-access/guides/snowflake_selfhosted.png b/docs/img/database-access/guides/snowflake_selfhosted.png new file mode 100644 index 0000000000000..b2c9b4d3b994f Binary files /dev/null and b/docs/img/database-access/guides/snowflake_selfhosted.png differ diff --git a/docs/img/everything.svg b/docs/img/everything.svg deleted file mode 100644 index e3d72c4131e3f..0000000000000 --- a/docs/img/everything.svg +++ /dev/null @@ -1 +0,0 @@ -Web client> sshOpenSSHclient> tctlCLI admin132Nodes authenticate nodekeys signed by auth service45Generate and signauto-expiring keyAuthenticateusers via 2FACheck client’s auto-expiringkey for CA signature \ No newline at end of file diff --git a/docs/img/node_cluster_auth.svg b/docs/img/node_cluster_auth.svg deleted file mode 100644 index 86a24a9744faa..0000000000000 --- a/docs/img/node_cluster_auth.svg +++ /dev/null @@ -1 +0,0 @@ -Please prove that youare a member of thecluster2Node sends certificateto Auth Service forvalidation1TeleportAuth APIgrav-00 10.X.X.1 arch=debian \ No newline at end of file diff --git a/docs/img/node_join.svg b/docs/img/node_join.svg deleted file mode 100644 index 1a2a7edfec79b..0000000000000 --- a/docs/img/node_join.svg +++ /dev/null @@ -1 +0,0 @@ -1Node presents jointoken2Auth Servervalidates tokenand generatesnode certificateToken:fuzzywuzzywasabearToken:fuzzywuzzywasabearTokens: Expiry: Type fuzzywuzzywasabear : 2019-10-19 : Node BBBCDDDDBBBBBBBB : 2019-10-16 : User \ No newline at end of file diff --git a/docs/img/node_lookup.svg b/docs/img/node_lookup.svg deleted file mode 100644 index 28464d6bb2892..0000000000000 --- a/docs/img/node_lookup.svg +++ /dev/null @@ -1 +0,0 @@ -DNS ResolverNodename | IP | Labels grav-00 10.X.X.0 arch=ubuntu grav-01 10.X.X.1 arch=debianNodename | IP | Labels grav-00 10.X.X.0 arch=ubuntu grav-01 10.X.X.1 arch=debian1Please resolve “grav-00”to a node IP23Please lookfor “grav-00”in your list ofnodesPlease look for“arch=debian” inyour list of nodes \ No newline at end of file diff --git a/docs/img/overview.svg b/docs/img/overview.svg deleted file mode 100644 index f6713cb868340..0000000000000 --- a/docs/img/overview.svg +++ /dev/null @@ -1 +0,0 @@ -3Web Client124 \ No newline at end of file diff --git a/docs/img/proxy-ssh-1.svg b/docs/img/proxy-ssh-1.svg deleted file mode 100644 index deb1111d1d95a..0000000000000 --- a/docs/img/proxy-ssh-1.svg +++ /dev/null @@ -1 +0,0 @@ -1243 \ No newline at end of file diff --git a/docs/img/proxy-ssh-2.svg b/docs/img/proxy-ssh-2.svg deleted file mode 100644 index 3a05dc9548235..0000000000000 --- a/docs/img/proxy-ssh-2.svg +++ /dev/null @@ -1 +0,0 @@ -> sshOpenSSHclient123 \ No newline at end of file diff --git a/docs/img/proxy-web.svg b/docs/img/proxy-web.svg deleted file mode 100644 index 552b43e0dd0e5..0000000000000 --- a/docs/img/proxy-web.svg +++ /dev/null @@ -1 +0,0 @@ -Web client1423 \ No newline at end of file diff --git a/docs/img/proxy_client_connect.svg b/docs/img/proxy_client_connect.svg deleted file mode 100644 index 037d40746353b..0000000000000 --- a/docs/img/proxy_client_connect.svg +++ /dev/null @@ -1 +0,0 @@ -joe wants toaccessgrav-00234joe can accessgrav-00as“root” or “joe”Proxy opens SSH tunnel tograv-00Client uses existingSSH tunnel toconnect tograv-00 via the proxygrav-00 10.X.X.1 arch=debianTeleportAuth APITeleport User : loginjoe : root, joe tara :tara1Web client> sshOpenSSHclientjoe:password 2FA: 265176 \ No newline at end of file diff --git a/docs/img/quickstart/welcome.png b/docs/img/quickstart/welcome.png new file mode 100644 index 0000000000000..cd9aa1ba90ba1 Binary files /dev/null and b/docs/img/quickstart/welcome.png differ diff --git a/docs/img/trusted-clusters/TrustedClusters-MSP.svg b/docs/img/trusted-clusters/TrustedClusters-MSP.svg deleted file mode 100644 index 7697553c89a93..0000000000000 --- a/docs/img/trusted-clusters/TrustedClusters-MSP.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/img/trusted-clusters/trusted-clusters@1.5x.svg b/docs/img/trusted-clusters/trusted-clusters@1.5x.svg new file mode 100644 index 0000000000000..526fb303ea510 --- /dev/null +++ b/docs/img/trusted-clusters/trusted-clusters@1.5x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/tunnel.svg b/docs/img/tunnel.svg deleted file mode 100644 index 2110e68ca0922..0000000000000 --- a/docs/img/tunnel.svg +++ /dev/null @@ -1 +0,0 @@ -FirewallTunnel \ No newline at end of file diff --git a/docs/img/user_auth.svg b/docs/img/user_auth.svg deleted file mode 100644 index 3c9354b6d6930..0000000000000 --- a/docs/img/user_auth.svg +++ /dev/null @@ -1 +0,0 @@ -Client offers certificate1Auth CAvalidatessignature ofcertificateWeb client> sshOpenSSHclient2 \ No newline at end of file diff --git a/docs/img/user_mappings.svg b/docs/img/user_mappings.svg deleted file mode 100644 index e19167696e762..0000000000000 --- a/docs/img/user_mappings.svg +++ /dev/null @@ -1 +0,0 @@ -root,teleport,opsroot,tara,joe,opsroot,tara,teleportTeleport User: loginjoe : root, joe tara : tara teleport : teleport sandra : opsgrav-00grav-01grav-02 \ No newline at end of file diff --git a/docs/img/user_node_access.svg b/docs/img/user_node_access.svg deleted file mode 100644 index b454182f35439..0000000000000 --- a/docs/img/user_node_access.svg +++ /dev/null @@ -1 +0,0 @@ -2Node requests list ofauthorized users andloginsjoe wants toaccessgrav-003Auth API sends list of UsersTeleportAuth API1Teleport User : loginjoe : root, joe tara :taragrav-00 10.X.X.1 arch=debian \ No newline at end of file diff --git a/docs/pages/access-controls/guides.mdx b/docs/pages/access-controls/guides.mdx index 1c9bf2a0b1263..294df91c17f13 100644 --- a/docs/pages/access-controls/guides.mdx +++ b/docs/pages/access-controls/guides.mdx @@ -16,6 +16,9 @@ layout: tocless-doc
  • [Impersonating Teleport Users](./guides/impersonation.mdx). Create certs for CI/CD using impersonation.
  • +
  • + [Passwordless](./guides/passwordless.mdx). Use passwordless authentication (Preview). +
  • [Second Factor - WebAuthn](./guides/webauthn.mdx). Add Two-Factor Authentication through WebAuthn.
  • diff --git a/docs/pages/access-controls/guides/dual-authz.mdx b/docs/pages/access-controls/guides/dual-authz.mdx index 283bab9c03a1d..debc76baf44cf 100644 --- a/docs/pages/access-controls/guides/dual-authz.mdx +++ b/docs/pages/access-controls/guides/dual-authz.mdx @@ -19,19 +19,8 @@ of two team members for a privileged role `dbadmin`. edition of Teleport only supports [GitHub](../../setup/admin/github-sso.mdx) as an SSO provider. - View this guide as a user of another Teleport edition: - - - - - - - - - - The steps below describe how to use Teleport with Mattermost. You can also [integrate with many other providers](../../enterprise/workflow/index.mdx). @@ -257,5 +246,3 @@ auth_service: ``` - - \ No newline at end of file diff --git a/docs/pages/access-controls/guides/moderated-sessions.mdx b/docs/pages/access-controls/guides/moderated-sessions.mdx index c1f2ed01859f7..4acca63d91ea2 100644 --- a/docs/pages/access-controls/guides/moderated-sessions.mdx +++ b/docs/pages/access-controls/guides/moderated-sessions.mdx @@ -16,19 +16,8 @@ in the session, and terminate the session at will. Moderated Sessions requires Teleport Enterprise or Teleport Cloud. - View this guide as a user of another Teleport edition: - - - - - - - - - - ### Use cases Moderated Sessions are useful in the following scenarios: @@ -227,4 +216,3 @@ example be used to enable notifications over some external communication system. - [Moderated Sessions](https://github.com/gravitational/teleport/blob/master/rfd/0043-kubeaccess-multiparty.md) - \ No newline at end of file diff --git a/docs/pages/access-controls/guides/passwordless.mdx b/docs/pages/access-controls/guides/passwordless.mdx new file mode 100644 index 0000000000000..fab927b4ff9c7 --- /dev/null +++ b/docs/pages/access-controls/guides/passwordless.mdx @@ -0,0 +1,292 @@ +--- +title: "Passwordless (Preview)" +description: Learn how to use passwordless authentication with Teleport. +--- + + + Passwordless is currently in Preview. + + +Passwordless takes advantage of WebAuthn to provide passwordless and +usernameless authentication for Teleport. + +## Prerequisites + +- A Teleport cluster with WebAuthn configured. + See the [Second Factor: WebAuthn](./webauthn.mdx) guide. +- A hardware device with support for WebAuthn and resident keys. + As an alternative, you can use a Mac with biometrics / Touch ID. +- A web browser with WebAuthn support. To see if your browser supports + WebAuthn, check the [WebAuthn Compatibility]( + https://developers.yubico.com/WebAuthn/WebAuthn_Browser_Support/) page. +- A signed and notarized `tsh` for Touch ID. + [Download the macOS tsh installer](../../installation.mdx#macos). + +A Teleport cluster capable of WebAuthn is automatically capable of passwordless. + +## Step 1/2. Register + +Register your passwordless device using `tsh`: + +```code +$ tsh mfa add +# Choose device type [TOTP, WEBAUTHN, TOUCHID]: WEBAUTHN +# Enter device name: bio +# Allow passwordless logins [YES, NO]: YES +# Tap any *registered* security key +# Tap your *new* security key +# MFA device "bio" added. +``` + +You may pick either `WEBAUTHN` or `TOUCHID` as the device type. Make sure to +answer `YES` to "Allow passwordless logins". + +If you are using a hardware device, a passwordless registration will occupy a +resident key slot. Resident keys, also called discoverable credentials, are +stored in persistent memory in the authenticator (i.e., the device that is used +to authenticate). In contrast, MFA keys are encrypted by the authenticator and +stored in the Teleport Auth Server. Regardless of your device type, passwordless +registrations may also be used for regular MFA. + + +If you plan on relying exclusively on passwordless, it's recommended to register +more than one device. A portable hardware device is ideal, as it can be shared +between `tsh`, the Teleport Web UI, and different computers. + + +
    + Touch ID registrations are isolated by application. A Touch ID registration + for `tsh` is different from a registration made from Chrome or Safari. You may + register the same Touch ID device from multiple applications to get + passwordless access in all of them. +
    + +## Step 2/2. Authenticate + +Authenticate using your passwordless credential: + +```code +$ tsh login --proxy=example.com --auth=passwordless +# Tap your security key +# > Profile URL: https://example.com +# Logged in as: codingllama +# Cluster: example.com +# Roles: access, editor +# Logins: codingllama +# Kubernetes: enabled +# Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] +# Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + +A fully passwordless cluster defaults to passwordless logins, making +`--auth=passwordless` unnecessary. See the next section to learn how to enable +passwordless by default. + + +You can also execute passwordless logins in the Teleport Web UI. To do so, look +for the passwordless link in the Web UI. + + +## Optional: Enable passwordless by default + +Passwordless enthusiasts may enable passwordless by default in their clusters. +Note that this configuration changes Teleport's behavior even for users without +a passwordless device registered, so existing users may need to authenticate +using `tsh login --proxy=example.com --auth=local` in order to get their first +passwordless registration. + +To enable passwordless by default, add `connector_name: passwordless` to your +cluster configuration: + + + + + Auth Server `teleport.yaml` file: + + ```yaml + auth_service: + authentication: + type: local + second_factor: on + webauthn: + rp_id: example.com + connector_name: passwordless # passwordless by default + ``` + + + Create a `cap.yaml` file or get the existing configuration using + `tctl get cluster_auth_preference`: + + ```yaml + kind: cluster_auth_preference + version: v2 + metadata: + name: cluster-auth-preference + spec: + type: local + second_factor: on + webauthn: + rp_id: example.com + connector_name: passwordless # passwordless by default + ``` + + Update the configuration: + + ```code + $ tctl create -f cap.yaml + # cluster auth preference has been updated + ``` + + + + + +Create a `cap.yaml` file or get the existing configuration using +`tctl get cluster_auth_preference`: + +```yaml +kind: cluster_auth_preference +version: v2 +metadata: + name: cluster-auth-preference +spec: + type: local + second_factor: on + webauthn: + rp_id: example.com + connector_name: passwordless # passwordless by default +``` + +Update the configuration: + +```code +$ tctl create -f cap.yaml +# cluster auth preference has been updated +``` + + +## Troubleshooting + +### "Allow passwordless logins" doesn't appear + +If you don't see the "Allow passwordless logins" prompt during `tsh mfa add`, +you may be using an older version of `tsh`. Download the latest `tsh` from our +[installation page](../../installation.mdx). + +### Hardware device not usable + +`tsh` only prompts for hardware devices with certain capabilities for +passwordless registrations. If your device isn't blinking it may not be capable +of passwordless logins. + +Below is a non-comprehensive list of requirements: + +- Device must support WebAuthn (sometimes also called FIDO2 or CTAP2). +- Device must be capable of user verification (biometrics or PIN). +- Device must have a PIN set. +- Device must have fingerprints enrolled (if biometric). This typically means + both a PIN *and* fingerprints. + +`tsh` relies in an embedded libfido2 to access hardware devices. If you are +running on Linux, you may be missing the necessary udev rules to access your +device. Try following the [installation instructions for libfido2]( +https://github.com/Yubico/libfido2#installation), which may provide you the +necessary udev rules. + +### Touch ID not usable + +If you are having trouble with Touch ID, make sure that you are using the latest +standalone version of `tsh`. [Download the macOS tsh installer]( +../../installation.mdx#macos). + +Touch ID support requires Macs with the Touch Bar and Secure Enclave. It also +requires macOS >= 10.13 (macOS High Sierra). + +You can run the `tsh touchid diag` command to verify requirements. A capable +device and `tsh` binary should show an output similar to the one below: + +```code +$ tsh touchid diag +# Has compile support? true +# Has signature? true +# Has entitlements? true +# Passed LAPolicy test? true +# Passed Secure Enclave test? true +# Touch ID enabled? true +``` + +### Disable passwordless + +If you want to forbid passwordless access to your cluster, add `passwordless: +false` to your configuration: + + + + + Auth Server `teleport.yaml` file: + + ```yaml + # snippet from /etc/teleport.yaml: + auth_service: + authentication: + type: local + second_factor: on + webauthn: + rp_id: example.com + passwordless: false # disable passwordless + ``` + + + Create a `cap.yaml` file or get the existing configuration using + `tctl get cluster_auth_preference`: + + ```yaml + kind: cluster_auth_preference + version: v2 + metadata: + name: cluster-auth-preference + spec: + type: local + second_factor: on + webauthn: + rp_id: example.com + passwordless: false # disable passwordless + ``` + + Update the configuration: + + ```code + $ tctl create -f cap.yaml + # cluster auth preference has been updated + ``` + + + + + +Create a `cap.yaml` file or get the existing configuration using +`tctl get cluster_auth_preference`: + +```yaml +kind: cluster_auth_preference +version: v2 +metadata: + name: cluster-auth-preference +spec: + type: local + second_factor: on + webauthn: + rp_id: example.com + passwordless: false # disable passwordless +``` + +Update the configuration: + +```code +$ tctl create -f cap.yaml +# cluster auth preference has been updated +``` + diff --git a/docs/pages/access-controls/guides/per-session-mfa.mdx b/docs/pages/access-controls/guides/per-session-mfa.mdx index 5594c7be08d3b..c15ecbeffcbab 100644 --- a/docs/pages/access-controls/guides/per-session-mfa.mdx +++ b/docs/pages/access-controls/guides/per-session-mfa.mdx @@ -246,6 +246,11 @@ $ tsh ssh prod3.example.com # jerry@prod3.example.com > ``` + +If you are using `tsh` in a constrained environment, you can tell it to use +OTP by doing `tsh --mfa-mode=otp ssh prod3.example.com`. + + If per-session MFA was enabled cluster-wide, Jerry would be prompted for MFA even when logging into `dev1.example.com`. @@ -283,11 +288,10 @@ Current limitations for this feature are: - WebAuthn hardware devices aren't currently supported in `tsh` on Windows. - Only `tsh ssh` supports per-session MFA authentication for SSH (OpenSSH `ssh` does not). -- Only `kubectl` supports per-session U2F authentication for Kubernetes. +- Only `kubectl` supports per-session WebAuthn authentication for Kubernetes. - Application access clients don't support per-session MFA authentication yet, although cluster and role configuration applies to them. If you enable per-session MFA checks cluster-wide, you will not be able to use Application access. We're working on integrating per-session MFA checks for these clients. -- For Desktop Access, only WebAuthn devices are supported. Teleport does not - support U2F devices for Desktop Access MFA. +- For Desktop Access, only WebAuthn devices are supported. diff --git a/docs/pages/access-controls/guides/u2f.mdx b/docs/pages/access-controls/guides/u2f.mdx deleted file mode 100644 index 0dd3515630510..0000000000000 --- a/docs/pages/access-controls/guides/u2f.mdx +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: Second Factor - U2F -description: Configuring U2F support in Teleport clusters. ---- - -# U2F (Hardware Tokens) - - - Consider updating your cluster to use [WebAuthn](./webauthn.mdx) as the second - factor protocol. WebAuthn is a modern U2F replacement that allows for a wider - range of devices to be used as second factor authenticators. - - -Teleport supports [FIDO U2F](https://www.yubico.com/about/background/fido/) -hardware keys as a second authentication factor. U2F can be used for logging -into Teleport (`tsh login` or the login page on the Web UI) and for logging -into individual SSH nodes or Kubernetes clusters (`tsh ssh` and `kubectl`). - -## Prerequisites - -(!docs/pages/includes/edition-prereqs-tabs.mdx!) - -- U2F hardware device, such as Yubikey or Solokey -- Web browser that [supports U2F](https://caniuse.com/u2f) - -(!docs/pages/includes/tctl.mdx!) - -## Enable U2F support - -By default U2F is disabled. To enable U2F support, edit the Teleport -configuration file `/etc/teleport.yaml` like so: - -```yaml -# snippet from /etc/teleport.yaml to show an example configuration of U2F: -auth_service: - authentication: - type: local - # to enable U2F support, set this field to 'u2f', 'on' or 'optional' - second_factor: u2f - u2f: - app_id: https://example.com - facets: - - "https://example.com" # app_id should always also be listed as a facet - - "https://example.com:443" - device_attestation_cas: - - "/path/to/u2f_attestation_ca.pem" -``` - -The fields in the above snippet are: - -- `app_id` - public address of the Teleport proxy, *including* the `https://` - prefix. If you use a port number other than 443, include it as well. - - Examples: - - - `https://example.com` (uses default port 443) - - `https://example.com:3080` (uses non-default port 3080) - - - The `app_id` must never change in the lifetime of the cluster, because it's - recorded in the registration data on the U2F device. If the App ID changes, - all existing U2F key registrations will become invalid and all users who use - U2F as the second factor will need to re-register. When using multiple proxy - servers, make sure they are reachable at the same public address (usually - behind a load balancer). - - -- `facets` - list of allowed addresses of the Teleport proxy, checked during - authentication attempts. This list is used to prevent malicious websites and - proxies from requesting U2F challenges on behalf of the legitimate proxy. - - For compatibility with multiple browsers, it's recommended to write down the - proxy address in several formats. For example, if your `app_id` is - `https://example.com`, your `facets` should include `https://example.com` - (same as the app_id) and `https://example.com:443`. - -- `device_attestation_cas` - optional list of certificate authorities (as local - file paths or in-line PEM certificate string) for U2F [device - attestation](https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-overview.html#verifying-that-a-u2f-device-is-genuine) - verification. This field allows you to restrict which U2F device vendors you - trust. Devices from other vendors will be rejected during registration. By - default, any vendor is allowed. - -Once the configuration file was edited, restart `teleport` to pick up the -changes. - -## Register U2F devices as a user - -A user can register multiple U2F devices [using `tsh`](../../setup/reference/cli.mdx#tsh-mfa-add): - -```code -$ tsh mfa add - -# Choose device type [TOTP, U2F]: u2f -# Enter device name: desktop yubikey -# Tap any *registered* security key -# Tap your *new* security key -# MFA device "desktop yubikey" added. -``` - -{/* Convert to new UI component https://github.com/gravitational/next/issues/275 */} - - - U2F devices are currently not supported in `tsh` on Windows. - - -## Login using U2F - -Once a U2F device is registered, the user will be prompted for it on login: - -```code -$ tsh login --proxy=example.com - -# Enter password for Teleport user awly: -# Tap any security key -# > Profile URL: https://example.com -# Logged in as: awly -# Cluster: example.com -# Roles: admin* -# Logins: awly -# Kubernetes: enabled -# Valid until: 2021-04-01 23:32:29 -0700 PDT [valid for 12h0m0s] -# Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty -``` - - -U2F for logging into Teleport is only required for [local -users](../../setup/reference/authentication.mdx#local-no-authentication-connector). SSO users should configure -multi-factor authentication in their SSO provider. - - -## Next steps - -- [Setup per-session U2F checks](per-session-mfa.mdx) diff --git a/docs/pages/access-controls/guides/webauthn.mdx b/docs/pages/access-controls/guides/webauthn.mdx index 8fee14df8cf98..8c055bbc035ee 100644 --- a/docs/pages/access-controls/guides/webauthn.mdx +++ b/docs/pages/access-controls/guides/webauthn.mdx @@ -4,9 +4,9 @@ description: Configuring WebAuthn support in Teleport clusters. --- Teleport supports [WebAuthn](https://webauthn.guide/) as a second authentication -factor. WebAuthn can be used for logging in to Teleport (`tsh login` or the login -page on the Web UI) and for logging in to individual SSH nodes or Kubernetes -clusters (`tsh ssh` and `kubectl`). +factor. WebAuthn can be used for logging in to Teleport (`tsh login` or the +login page on the Web UI) and for logging in to individual SSH nodes or +Kubernetes clusters (`tsh ssh` and `kubectl`). WebAuthn support includes hardware devices, such as YubiKeys or SoloKeys (`tsh` and Web UI), as well as biometric authenticators like Touch ID and Windows Hello @@ -24,11 +24,10 @@ and Web UI), as well as biometric authenticators like Touch ID and Windows Hello ## Step 1/3. Enable WebAuthn support -WebAuthn is disabled by default. To enable WebAuthn support, update your Teleport -configuration as below: +WebAuthn is disabled by default. To enable WebAuthn support, update your +Teleport configuration as below: - Auth Server `teleport.yaml` file: @@ -83,11 +82,11 @@ configuration as below: $ tctl create -f cap.yaml # cluster auth preference has been updated ``` - + - + Obtain your existing `cluster_auth_preference` resource: @@ -129,10 +128,14 @@ Update the configuration: $ tctl create -f cap.yaml # cluster auth preference has been updated ``` - -You will need to include the following configuration fields. +
    + Starting on Teleport v10, WebAuthn replaces U2F. See the [U2F](#u2f) section. +
    `rp_id` is the public domain of the Teleport Proxy Service, *excluding* protocol (`https://`) and port number. @@ -178,7 +181,6 @@ $ tsh mfa add Once a WebAuthn device is registered, the user will be prompted for it on login: - ```code $ tsh login --proxy=example.com # Enter password for Teleport user codingllama: @@ -192,10 +194,9 @@ $ tsh login --proxy=example.com # Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] # Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty ``` - - + ```code $ tsh login --proxy=mytenant.teleport.sh # Enter password for Teleport user codingllama: @@ -209,15 +210,112 @@ $ tsh login --proxy=mytenant.teleport.sh # Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] # Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty ``` - WebAuthn for logging in to Teleport is only required for [local users]( - ../../setup/reference/authentication.mdx#local-no-authentication-connector). SSO users should configure - multi-factor authentication in their SSO provider. + ../../setup/reference/authentication.mdx#local-no-authentication-connector). + SSO users should configure multi-factor authentication in their SSO provider. +## U2F + +Starting with Teleport v10, WebAuthn replaces U2F. If you haven't configured U2F +before, no further action is necessary—any U2F devices are automatically +supported. + +If you have an existing U2F configuration, but haven't explicitly configured +WebAuthn yet, Teleport will automatically derive your WebAuthn configuration +from your existing U2F configuration. + +You may write the WebAuthn configuration yourself, but keep the U2F `app_id` +field. Doing so ensures that any already-registered U2F devices won't need to be +re-registered. + +For example, consider the U2F configuration below: + +```yaml +# snippet from /etc/teleport.yaml showing a U2F configuration: +auth_service: + authentication: + type: local + second_factor: u2f + u2f: + app_id: https://example.com + facets: + - "https://example.com" + - "https://example.com:443" + device_attestation_cas: + - "/path/to/u2f_attestation_ca.pem" +``` + +The migrated WebAuthn configuration is: + + + + + ```yaml + # snippet from /etc/teleport.yaml: + auth_service: + authentication: + type: local + second_factor: on # changed from "u2f" + u2f: + # Keep the app_id to avoid re-registering U2F devices. + app_id: https://example.com + webauthn: + # rp_id is the public domain of the Teleport Proxy Service. + # It's similar to the U2F app_id, but without "https://" or port number. + rp_id: example.com + attestation_allowed_cas: + - "/path/to/u2f_attestation_ca.pem" + ``` + + + ```yaml + kind: cluster_auth_preference + version: v2 + metadata: + name: cluster-auth-preference + spec: + type: local + second_factor: on # changed from "u2f" + u2f: + # Keep the app_id to avoid re-registering U2F devices. + app_id: https://example.com + webauthn: + # rp_id is the public domain of the Teleport Proxy Service. + # It's similar to the U2F app_id, but without "https://" or port number. + rp_id: example.com + attestation_allowed_cas: + - "/path/to/u2f_attestation_ca.pem" + ``` + + + + + +```yaml +kind: cluster_auth_preference +version: v2 +metadata: + name: cluster-auth-preference +spec: + type: local + second_factor: on # changed from "u2f" + u2f: + # Keep the app_id to avoid re-registering U2F devices. + app_id: https://example.com + webauthn: + # rp_id is the public domain of the Teleport Proxy Service. + # It's similar to the U2F app_id, but without "https://" or port number. + rp_id: example.com + attestation_allowed_cas: + - "/path/to/u2f_attestation_ca.pem" +``` + + ## Next steps -- [Setup per-session MFA checks](per-session-mfa.mdx) +- [Passwordless](./passwordless.mdx) +- [Setup per-session MFA checks](./per-session-mfa.mdx) diff --git a/docs/pages/access-controls/introduction.mdx b/docs/pages/access-controls/introduction.mdx index 2682056936f34..56833db802749 100644 --- a/docs/pages/access-controls/introduction.mdx +++ b/docs/pages/access-controls/introduction.mdx @@ -34,6 +34,9 @@ guide. Create certs for CI/CD using impersonation. + + Use passwordless authentication (Preview). + Add Two-Factor Authentication through WebAuthn. diff --git a/docs/pages/access-controls/reference.mdx b/docs/pages/access-controls/reference.mdx index 6da65d0f8f45e..251d11d1c1604 100644 --- a/docs/pages/access-controls/reference.mdx +++ b/docs/pages/access-controls/reference.mdx @@ -37,8 +37,9 @@ To see the list of roles in a Teleport cluster, an administrator can execute: ```code -# Log in to your cluster with tsh so you can use tctl. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --user=myuser --proxy=teleport.example.com $ tctl get roles ``` @@ -56,151 +57,9 @@ $ tctl get roles (!docs/pages/includes/backup-warning.mdx!) -A role definition looks like this: - -```yaml -kind: role -version: v5 -metadata: - name: example -spec: - # Options used for user sessions with default values: - options: - # max_session_ttl defines the TTL (time to live) of SSH certificates - # issued to the users with this role. - max_session_ttl: 8h - # forward_agent controls whether SSH agent forwarding is allowed - forward_agent: true - # port_forwarding controls whether TCP port forwarding is allowed - port_forwarding: true - # client_idle_timeout determines if SSH sessions to cluster nodes are forcefully - # terminated after no activity from a client (idle client). it overrides the - # global cluster setting. examples: "30m", "1h" or "1h30m" - client_idle_timeout: never - # Determines if the clients will be forcefully disconnected when their - # certificates expire in the middle of an active SSH session. - # It overrides the global cluster setting. - disconnect_expired_cert: no - # Optional: max_connections Per-user limit of concurrent sessions within a - # cluster. - max_connections: 2 - # Optional: max_sessions total number of session channels that can be established - # across a single connection. 10 will match OpenSSH default behavior. - max_sessions: 10 - # permit_x11_forwarding allows users to use X11 forwarding with openssh clients and servers through the proxy - permit_x11_forwarding: true - # Specify whether or not to record the user's desktop sessions. - # Desktop session recording is enabled if one or more of the user's - # roles has enabled recording. Defaults to true if unspecified. - # Desktop sessions will never be recorded if auth_service.session_recording - # is set to 'off' in teleport.yaml or if the cluster's session_recording_config - # resource has set 'mode: off'. - record_sessions: - desktop: true - # Specify whether clipboard sharing should be allowed with the - # remote desktop (requires a supported browser). Defaults to true - # if unspecified. If one or more of the user's roles has disabled - # the clipboard, then it will be disabled. - desktop_clipboard: true - # Specify a list of names and associated values to be included in user SSH keys. - # The key type can only be "ssh" and the mode can only be "extension". - # The name and value fields can be arbitrary strings and the value field - # supports variable interpolation. - cert_extensions: - - type: ssh - mode: extension - name: login@github.com - value: "{{ external.github_login }}" - # The allow section declares a list of resource/verb combinations that are - # allowed for the users of this role. By default, nothing is allowed. - allow: - # The logins array defines the OS/UNIX logins a user is allowed to use. - # a few special variables are supported here (see below) - logins: [root, '{{internal.logins}}'] - # Windows logins a user is allowed to use for desktop sessions. - windows_desktop_logins: [Administrator, '{{internal.logins}}'] - # If the Kubernetes integration is enabled, this setting configures which - # kubernetes groups the users of this role will be assigned to. - # Note that you can refer to a SAML/OIDC trait via the "external" property bag. - # This allows you to specify Kubernetes group membership in an identity manager: - kubernetes_groups: ["system:masters", "{{external.trait_name}}"]] - - # List of node labels a user will be allowed to connect to: - node_labels: - # A user can only connect to a node marked with 'test' label: - 'environment': 'test' - # The wildcard ('*') means "any node" - '*': '*' - # Labels can be specified as a list: - 'environment': ['test', 'staging'] - # Regular expressions are also supported, for example, the equivalent - # of the list example above can be expressed as: - 'environment': '^test|staging$' +Here is a full role specification: - kubernetes_labels: - # A user can only access prod environments - 'env': 'prod' - # User can access any region in us-west, e.g us-west-1, us-west-2 - 'region': 'us-west-*' - 'cluster_name': '^us.*\.example\.com$' - - # Defines roles that this user can request. - # Needed for teleport's access request workflow - # https://goteleport.com/teleport/docs/enterprise/workflow/ - request: - roles: - - dba - - # List of allow-rules. See below for more information. - rules: - - resources: [role] - verbs: [list, create, read, update, delete] - - resources: [auth_connector] - verbs: [list, create, read, update, delete] - - resources: [session] - verbs: [list, read] - - resources: [trusted_cluster] - verbs: [list, create, read, update, delete] - - resources: [event] - verbs: [list, read] - - resources: [user] - verbs: [list,create,read,update,delete] - - resources: [token] - verbs: [list,create,read,update,delete] - - # Moderated Sessions policy that dictates requirements for starting a session. - require_session_join: - # Defines the name of the policy. The name serves only as an - # identifier in logs and for organisation/categorisation. - - name: Auditor oversight - # Specifies an RBAC predicate that is used to define - # which users count against the required user count of the policy. - filter: 'contains(user.roles, "auditor")' - # The different session kinds this policy applies to. - kinds: ['k8s', 'ssh'] - # A list of session participant modes that a participant must have - # one of in order to count against the policy. - modes: ['moderator'] - # The minimum amount of users that need to match the filter expression - # in order to satisfy the policy. - count: 1 - - # Moderated Sessions policy that dictates the ability to join sessions - join_sessions: - # Defines the name of the policy. The name serves only as an - # identifier in logs and for organisation/categorisation. - - name: Auditor oversight - # Allows one to join sessions created by other users with these roles - roles : ['prod-access'] - # The different session kinds this policy applies to. - kinds: ['k8s', 'ssh'] - # The list of session participant modes the role may join the session as. - modes: ['moderator', 'observer'] - - # The deny section uses the identical format as the 'allow' section. - # The deny rules always override allow rules. - deny: {} -``` +(!docs/pages/includes/role-spec.mdx!) The following variables can be used with `logins` and `windows_desktop_logins` fields: @@ -232,7 +91,7 @@ logins: ### Role options -As shown above, a role can define certain restrictions on SSH sessions initiated by users. +As shown above, a role can define certain restrictions on sessions initiated by users. The table below documents the behavior of each option if multiple roles are assigned to a user. | Option | Description | Multi-role behavior | @@ -242,8 +101,20 @@ The table below documents the behavior of each option if multiple roles are assi | `port_forwarding` | Allow TCP port forwarding | Logical "OR" i.e. if any role allows port forwarding, it's allowed | | `client_idle_timeout` | Forcefully terminate active SSH sessions after an idle interval | The shortest timeout value wins, i.e. the most restrictive value is selected | | `disconnect_expired_cert` | Forcefully terminate active SSH sessions when a client certificate expires | Logical "OR" i.e. evaluates to "yes" if at least one role requires session termination | -| `max_connections` | Limit on how many active SSH sessions can be started via Teleport | | | `max_sessions` | Total number of session channels which can be established across a single SSH connection via Teleport | | +| `enhanced_recording` | Indicates which events should be recorded by the BFP-based session recorder | | +| `permit_x11_forwarding` | Allow users to enable X11 forwarding with OpenSSH clients and servers | | +| `require_session_mfa` | Require additional MFA tap before initiating a session | Logical "OR" i.e. evaluates to "yes" if at least one role requires session MFA | +| `lock` | Locking mode (`strict` or `best_effort`) | `strict` wins in case of conflict | +| `request_access` | Enterprise-only access request strategy (`optional`, `always` or `reason`) | | +| `request_prompt` | Prompt for the access request "reason" field | | +| `max_connections` | Enterprise-only limit on how many concurrent sessions can be started via Teleport | | +| `max_kubernetes_connections` | Defines the maximum number of concurrent Kubernetes sessions per user | | +| `record_session` | Configures session recording behavior | | +| `desktop_clipboard` | Allow clipboard sharing for desktop sessions | Logical "AND" i.e. evaluates to "yes" if all roles enable clipboard sharing | +| `pin_source_ip` | Enable source IP pinning for SSH certificates | Logical "OR" i.e. evaluates to "yes" if at least one role requires session termination | +| `cert_extensions` | Specifies extensions to be included in SSH certificates | | +| `create_host_user` | Allow users to be automatically created on a host | | ## Preset roles @@ -355,8 +226,8 @@ RBAC lets teams limit what resources are available to Teleport users. This can b you don't want regular users editing SSO (`auth_connector`) or creating and editing new roles (`role`). -Below is an example `allow` section that illustrates commonly used `rules`. -Each rule includes a list of Teleport resources and the CRUD +Below is an example `allow` section that illustrates commonly used `rules`. +Each rule includes a list of Teleport resources and the CRUD operations that a user is allowed to execute on them: ```yaml @@ -413,7 +284,7 @@ allow: It is possible to further limit access to [shared sessions](../server-access/guides/tsh.mdx#sharing-sessions) and -[session recordings](../architecture/nodes.mdx#session-recording). +[session recordings](../architecture/nodes.mdx#ssh-session-recording). The examples below illustrate how to restrict session access only for the user who created the session. @@ -475,8 +346,8 @@ spec: ## Second Factor - U2F -Refer to the [Second Factor - U2F guide](./guides/u2f.mdx) if you have a cluster -using the legacy U2F support. +Refer to the [Second Factor - WebAuthn](./guides/webauthn.mdx#u2f) guide if you +have a cluster using the legacy U2F support. ## Filter fields @@ -489,5 +360,5 @@ Here is an explanation of the fields used in the `where` and `filter` conditions | `ssh_session.participants` | The list of participants from an SSH session | | `user.metadata.name` | The user's name | -Check out our [predicate language](../setup/reference/predicate-language.mdx#scoping-allowdeny-rules-in-role-resources) +Check out our [predicate language](../setup/reference/predicate-language.mdx#scoping-allowdeny-rules-in-role-resources) guide for a more in depth explanation of the language. diff --git a/docs/pages/application-access/guides/connecting-apps.mdx b/docs/pages/application-access/guides/connecting-apps.mdx index 83e2050a5ce91..3849dd7650afe 100644 --- a/docs/pages/application-access/guides/connecting-apps.mdx +++ b/docs/pages/application-access/guides/connecting-apps.mdx @@ -41,6 +41,10 @@ join the cluster. Generate a short-lived join token and save it for example in `/tmp/token`: ```code +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. +$ tsh login --user=myuser --proxy=teleport.example.com $ tctl tokens add \ --type=app \ --app-name=grafana \ diff --git a/docs/pages/application-access/guides/dynamic-registration.mdx b/docs/pages/application-access/guides/dynamic-registration.mdx index fb9252734298e..af751776d0766 100644 --- a/docs/pages/application-access/guides/dynamic-registration.mdx +++ b/docs/pages/application-access/guides/dynamic-registration.mdx @@ -85,8 +85,9 @@ To create an application resource, run: ```code -# Log in to your Teleport cluster so you can use tctl remotely. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser $ tctl create app.yaml ``` diff --git a/docs/pages/application-access/reference.mdx b/docs/pages/application-access/reference.mdx index 0eee16d52d4c5..fcdde3c29f714 100644 --- a/docs/pages/application-access/reference.mdx +++ b/docs/pages/application-access/reference.mdx @@ -100,8 +100,9 @@ assume that you have created a YAML file called `app.yaml` with your configurati ```code -# Log in to your Teleport cluster. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser # Create the resource $ tctl create -f app.yaml @@ -111,7 +112,7 @@ $ tctl create -f app.yaml ```code -# Log in to your Teleport cluster. +# Log in to your cluster with tsh so you can use tctl from your local machine. $ tsh login --proxy=mytenant.teleport.sh --user=myuser # Create the resource. $ tctl create -f app.yaml diff --git a/docs/pages/architecture/authentication.mdx b/docs/pages/architecture/authentication.mdx index 61d9e6a7a0e31..3a691327d22bf 100644 --- a/docs/pages/architecture/authentication.mdx +++ b/docs/pages/architecture/authentication.mdx @@ -1,230 +1,167 @@ --- -title: Teleport Authentication Service, SSH, and Kubernetes certificates -description: This chapter explains the concept of a Teleport Auth Service and Certificate Authority (CA) to issue SSH and Kubernetes certificates. -h1: Teleport Authentication Service +title: Teleport Authentication +description: This chapter explains how Teleport uses certificate authorities to authenticate users and services. +h1: Teleport Authentication with Certificates --- -This document outlines the Teleport Authentication Service and Certificate -Management. It explains how Users and Nodes are identified and granted access to -Nodes and Services. +## Authentication -## Authentication vs. Authorization +Teleport handles both authentication and authorization. -Teleport Auth handles both authentication and authorization. These topics are -related but different, and they are often discussed jointly as "Auth". +- Authentication is about proving an identity of a user or a service. +- Authorization is proving access rights to something. -**Authentication** is proving an identity. "I say I am Bob, and I really am Bob. -See look I have Bob's purple hat." The job of an Authentication system is to -define the criteria by which users must prove their identity. Is having a purple -hat enough to show that a person is Bob? Maybe, maybe not. To identify users and -nodes to Teleport Auth, we require them to present a cryptographically-signed -certificate issued by the Teleport Auth Certificate Authority. +This article covers authentication with short-lived certificates. -**Authorization** is proving access to something: "Bob has a purple hat, but -also a debit card and the correct PIN code. Bob can access a bank account with -the number 814000001344. Can Bob get $20 out of the ATM?" The ATM's Authentication system would validate Bob's PIN Code, while the Authorization system would use a stored mapping from Bob to account #814000001344 to decide -whether Bob could withdraw cash. Authorization defines and determines -permissions that users have within a system, such as access to cash within a -banking system, or data in a filesystem. Before users are granted access to -nodes, the Auth Service checks their identity against a stored mapping in a -database. +## Short-Lived Certificates -![Authentication and Authorization](../../img/authn_authz.svg) +Certificate Authorities and short-lived certificates are the core of Teleport authentication. +In Teleport at the start of every connection, a user or a service has to present a valid certificate issued by +a trusted certificate authority. Clients always initiate mutual TLS or mutual SSH connections. -## SSH certificates +Teleport Certificate Authority issues short-lived x.509 certificates for web services, databases, kubernetes clusters, +desktops and SSH certificates for OpenSSH-compatible servers. -One can think of an SSH certificate as a "permit" issued and time-stamped by a -trusted authority. In this case, the authority is the Auth Server's Certificate -Authority. A certificate contains four important pieces of data: +### Why certificates? -1. List of principals (identities) this certificate belongs to. -2. Signature of the certificate authority who issued it. -3. The expiration date, also known as "time-to-live" or simply TTL. -4. Additional data, such as the node role, is stored as a certificate extension. - -## Authentication in Teleport - -Teleport uses SSH certificates to authenticate nodes and users within a cluster. - -Two CAs are used inside the Auth Server because nodes and users each need their own certificates. {/* TODO: Why? */} +- Certificates are tied to user or service identity. Any connection and action can be traced back to a user +or a service. +- Short-lived certificates automatically expire, there is no need to revoke them. +- Certificates solve trust on first use (TOFU) problems. In a Teleport cluster, all servers have +identities and certificates of their own. They will not allow a connection if a client certificate is signed by an +untrusted certificate authority. +- Certificates enable mutually authenticated channel - mTLS, mTLS mitigates a wide range of attacks - spoofing, on-path attacks, credential stuffing and others. +- Certificates work better for large-scale deployments. Each server or service just needs to validate +if the certificate has been signed with a valid certificate authority, and does not need to copy user +credentials over to every service. -- The **Node CA** issues certificates which identify a node (i.e. host, server, - computer). These certificates are used to add new nodes to a cluster and identify connections coming from the node. -- The **User CA** issues certificates which identify a User. These certificates are used to authenticate users when they try to connect to a cluster node. + +Teleport issues certificates that are good from a few hours to minutes before they auto-expire without any action. +The shorter the duration for these certificates, the better. +Ideally, certs should be issued only for the duration of a session. +In practice, several hours or the duration of the workday are OK too. +The expiry date in certificates can not be forged +without invalidating the certificates, so any system can validate the certificate. + -### Issuing Node certificates +### X.509 certificates -Node Certificates identify a node within a cluster and establish the permissions -of the node to access other Teleport services. The presence of a signed -certificate on a node makes it a cluster member. +X.509 certificates are the same certificates you use when accessing websites with a browser. They bind +identity to the public key with a certificate authority's signature. -![Node Joins Cluster](../../img/node_join.svg) - -1. To join a cluster for the first time, a node must present a "join token" to the auth server. The token can be static (configured via config file) or a dynamic, single-use token generated by [`tctl nodes add`](../setup/reference/cli.mdx#tctl-nodes-add). - - - When using dynamic tokens, their default time to live (TTL) is 30 - minutes, but it can be reduced (not increased) via - [`tctl nodes add --ttl`](../setup/reference/cli.mdx#tctl-nodes-add) flag. - - -2. When a new node joins the cluster, the auth server generates a new public/private keypair for the node and signs its certificate. This node certificate contains the node's role(s) (`proxy`, `auth` or `node`) as a certificate extension (opaque signed string). -### Using Node certificates +![x.509 certs](../../img/architecture/x509-cert@2x.svg) -![Node Authorization](../../img/node_cluster_auth.svg) + -All nodes in a cluster can connect to the [Auth Server's API](#auth-api) {/* Docs about this */} -implemented as an HTTP REST service running over the SSH -tunnel. This API connection is authenticated with the node certificate and the -encoded role is checked to enforce access control. For example, a client -connection using a certificate with only the `node` role won't be able to add -and delete users. This client connection would only be authorized to get auth -servers registered in the cluster. +Teleport uses x.509 certificates for Kubernetes, databases, web services and its own internal +components - proxies, auth services to establish mutually authenticated TLS connections - mTLS. -### Issuing user certificates +### OpenSSH certificates -![Client obtains new certificate](../../img/cert_invalid.svg) +OpenSSH certificates are similar to X.509 (web) certificates and also bind identity of the user or a server +to the public key with a certificate authority's signature. -The Auth Server uses its User CA to issue user certificates. User certificates -are stored on a user's machine in the `~/.tsh/keys/example.com` directory or also -by the system's SSH agent if it is running. - -1. To get permission to join a cluster for the first time a user must provide their username, password, and 2nd-factor token. Users can log in with [`tsh login`](../setup/reference/cli.mdx#tsh-login) or via the Web UI. The Auth server checks the username and password against its identity storage and checks the 2nd-factor token. -2. If the correct credentials were offered, the Auth Server will generate a signed certificate and return it to the client. For users, certificates are stored in `~/.tsh` by default. If the client uses the Web UI the signed certificate is associated with a secure WebSocket session. - -In addition to a user's identity, user certificates also contain user roles and -SSH options, like "permit-agent-forwarding" {/* TODO: link to config/set options here */}. -This additional data is stored as a certificate extension and is protected by -the CA signature. +
    -### Using user certificates +![SSH certs](../../img/architecture/ssh-cert@2x.svg) -![Client offers valid certificate](../../img/user_auth.svg) +
    -When a client requests access to a node cluster, the Auth Server first checks -that a certificate exists and hasn't expired. If it has expired, the client must -re-authenticate with their username, password, and 2nd factor. If the -certificate is still valid, the Auth Server validates the certificate's -signature. The client is then granted access to the cluster. From here, the -[Proxy Server](proxy.mdx) establishes a connection between client and node. +OpenSSH certificate contain metadata used to authenticate users and hosts: -## Certificate rotation +1. List of principals (identities) this certificate belongs to. +2. Signature of the certificate authority who issued it. +3. The expiration date, also known as "time-to-live" or simply TTL. +4. Additional data, such as the node role, is stored as a certificate extension. -By default, all user certificates have an expiration date, also known as the *time to live *(TTL). This TTL can be configured by a Teleport administrator. However, the node certificates issued by an Auth Server are valid indefinitely by default. +### Making Time Work For You -Teleport supports certificate rotation, i.e. the process of invalidating all -previously-issued certificates for nodes *and* users regardless of their TTL. -Certificate rotation is triggered by [`tctl auth -rotate`](../setup/reference/cli.mdx#tctl-auth-rotate). When this command is invoked by a Teleport -administrator on one of a cluster's Auth Servers, the following happens: +Expiry is a feature of certificates that makes time work in favor of security. +SSH and X.509 certificates include an optional expiry date that is verified by +servers in addition to a signature. -1. A new certificate authority (CA) key is generated. -2. The old CA will be considered valid *alongside* the new CA for a while. This period is called a *grace period*. {/* TODO: Link to config/defaults. */} -3. During the grace period, all previously issued certificates will be considered valid, assuming their TTL isn't expired. -4. After the grace period is over, the certificates issued by the old CA are no longer accepted. +
    -This process is repeated twice, once for the node CA and once for the user CA. +![Short lived certs](../../img/architecture/ssh-cert-short-lived@1.5x.svg) -Take a look at the [Certificate Rotation Guide](../setup/operations/ca-rotation.mdx) to -learn how to do certificate rotation in practice. +
    -## Auth API +In the diagram above, Alice gets a short lived SSH certificate, but the same rules apply to +X.509 certificates issued by Teleport and used for Kubernetes, Databases, Web Apps and Desktops. -{ - /* TODO: Can we say more about this, abstract of routes provided */ -} +Teleport issues certificates that are good from a few hours to minutes before they auto-expire without any action. +Instead of distributing revocation lists, Teleport relies on time to do the job for us. -Clients can also connect to the auth API through the Teleport proxy to use a limited subset of the API to discover the member nodes of the cluster. + +In some cases, certificate expiration is not fast enough, and all sessions have to be terminated immediately, +for example during active security incident. +For those cases, Teleport Proxy can terminate live connections using [session and identity locking](../access-controls/guides/locking.mdx). + -## Auth state +### Short-lived Certs For Users -The Auth service maintains state using a database of users, credentials, -certificates, and audit logs. The default storage location is -`/var/lib/teleport` or an [admin-configured storage destination](../setup/reference/backends.mdx). +To issue a certificate to a user, Teleport opens login screen, issues a cert and delivers it back to a user's computer: -There are three types of data stored by the auth server: +We recommend using SSO with GitHub, Okta or any other identity provider and get a cert. -- - **Cluster State** The auth server stores its own keys in a cluster state storage. All of cluster dynamic configuration is stored there as well, including: - - Node membership information and online/offline status for each node. - - List of active sessions. - - List of locally stored users - - RBAC configuration (roles and permissions). - - Other dynamic configuration. -- **Audit Log** When users log into a Teleport cluster, execute remote commands, and log out, that activity is recorded in the audit log. See Audit Log for more details. More on this in the [Audit Log section](../setup/reference/audit.mdx). -- **Recorded Sessions** When Teleport users launch remote shells via `tsh ssh` command, their interactive sessions are recorded and stored by the auth server. Each recorded session is a file that is saved in /var/lib/teleport by default but can also be saved in external storage, like an AWS S3 bucket. +
    + +![SSO exchange for short-lived certs](../../img/architecture/idp-sso-traits@1.5x.svg) +
    -## Audit log +### Short-lived Certs for Services -The Teleport auth server keeps the audit log of SSH-related events that take -place on any node within a Teleport cluster. Each node in a cluster emits audit -events and submits them to the auth server. The events recorded include: +Deployment automation services, such as Jenkins, can use Teleport's Machine ID +service to receive and renew certificates. Teleport Machine ID's bot runs alongside +services and rotates SSH and X.509 certificates. -- Successful user logins -- Node IP addresses, Application, Database and Kubernetes FQDN -- Session time -- Session IDs +
    + +![Certificates for services](../../img/architecture/certs-machine-id@1.8x.svg) +
    - - Because all SSH events like `exec` or `session_start` are by default reported by the Teleport node service, they will not be logged if you are using OpenSSH `sshd` daemon on your nodes. [Recording proxy mode](proxy.mdx#recording-proxy-mode) - +### Internal certificates -Only an SSH server can report what's happening to the Teleport auth server. -The audit log is a JSON file that is by default stored on the auth server's -filesystem under `/var/lib/teleport/log`. The format of the file is documented -in the [Admin Manual](../setup/reference/audit.mdx). +Teleport internal services - Auth, Proxy and Nodes use certificates to identify themselves +within a cluster. To join proxies and nodes to the cluster and receive certificates, admins should use +[short-lived tokens or cloud identity services](../setup/admin/adding-nodes.mdx). -Teleport users are encouraged to export the events into external, long term -storage. +Unlike users and services, internal services receive long-lived certificates. - - If multiple Teleport auth servers are used - to service the same cluster (High Availability mode) a network file system must be used for - `/var/lib/teleport/log` to allow them to combine all audit events into the - same audit log. [Learn how to deploy Teleport in High Availability Mode.](../setup/reference/backends.mdx). - - -## Storage back-ends - -Different types of cluster data can be configured with different storage -back-ends as shown in the table below: - -| Data Type | Supported Back-ends | Notes | -| - | - | - | -| Cluster state | `dir`, `etcd`, `dynamodb`,`firestore` | Multi-server (High Availability) configuration is only supported using `etcd`, `dynamodb`, and `firestore` back-ends. | -| Audit Log Events | `dir`, `dynamodb`, `firestore` | If `dynamodb` is used for the audit log events, `s3` back-end **must** be used for the recorded sessions. | -| Recorded Sessions | `dir`, `s3` | `s3` is mandatory if `dynamodb` is used for the audit log. For Google Cloud storage use `audit_sessions_uri: 'gs://` | - - - The reason Teleport designers split the audit log events and the recorded sessions into different back-ends is because of the nature of the data. A recorded session is a compressed binary stream (blob) while the event is a well-defined JSON structure. `dir` works well enough for both in small deployments, but large clusters require specialized data stores: S3 is perfect for uploading session blobs, while DynamoDB or `etcd` are better suited to store the cluster state. - +To renew these certificates, admins should use certificate authority rotation, the process of invalidating all +previously-issued certificates for nodes or users regardless of expiry and issuing a new ones, +using a new certificate authority. -The combination of DynamoDB + S3 is especially popular among AWS users because -it allows them to run Teleport clusters completely devoid of local state. +Take a look at the [Certificate Rotation Guide](../setup/operations/ca-rotation.mdx) to +learn how to do certificate rotation in practice. - - For High Availability in production, a Teleport cluster can be - serviced by multiple auth servers running in sync. Check [High Availability configuration](../setup/reference/backends.mdx) in the Admin Guide. - + +To quickly lock out the node, proxy or auth service that may be compromised without rotating the entire +cluster certificates, use node [session and identity locking](../access-controls/guides/locking.mdx). + ## More concepts - [Architecture Overview](overview.mdx) -- [Teleport Users](users.mdx) +- [Authorization](authorization.mdx) - [Teleport Nodes](nodes.mdx) - [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/authorization.mdx b/docs/pages/architecture/authorization.mdx new file mode 100644 index 0000000000000..5d96f24c02bf5 --- /dev/null +++ b/docs/pages/architecture/authorization.mdx @@ -0,0 +1,381 @@ +--- +title: Teleport Authorization +description: This chapter explains how Teleport authorizes users and roles. +h1: Teleport Authorization +--- + +## Authorization + +Teleport handles both authentication and authorization. + +- Authentication is about proving an identity of a user or a service. +- Authorization is proving access rights to something. + +This article covers authorization of users and services with RBAC. + +## Users and Roles + +Teleport supports several types of user accounts: + +- Interactive and non-interactive. +- Local and external. + +Each user is associated with one or several roles after successful authentication. + +### Interactive users + +Interactive users can be local or external. +Local user accounts store login credentials - password hash and MFA device data in Teleport's backend. +External user accounts authenticate with a third-party identity provider using SSO protocols - OAuth 2.0, OIDC or SAML. + +#### External users from SSO providers + +Let's review the example Alice who is authenticating using SSO provider of her organization +with Teleport: + +![Role mapping](../../img/architecture/role-mapping@1.5x.svg) + + +Every time SSO user logs in, Teleport creates a temporary user account record +that automatically expires with SSO session and logs audit log entries. + +Teleport creates this record to avoid name collisions with local users. + + +#### External users from other clusters + +A user could be external to the Teleport cluster, if another cluster or certificate authority issues a certificate +that this cluster trusts. In this case, Teleport activates [trusted cluster mapping logic](./trustedclusters.mdx#role-mapping). + +#### Local interactive users + +Local interactive users have a record in Teleport's backend with credentials. + +A cluster administrator have to create account entries for every Teleport user with +[`tctl users add`](../setup/reference/cli.mdx) or API call. + +Every local Teleport User must be associated with a list of one or more roles. +This list is called "role mappings". + +### Non-interactive users + +Teleport supports non-interactive users for automation services, e.g. Jenkins or micro-services +running in your organization. + +### Local non-interactive users + +Local non-interactive users also have a user entry that maps their name to roles, +but they do not have credentials stored in the database. +Non-interactive users have to use Teleport's machine ID product to receive and renew certificates. +Teleport Machine ID's bot runs alongside services and rotates SSH and X.509 certificates on behalf +of non-interactive users: + +
    + +![Certificates for services](../../img/architecture/certs-machine-id@1.8x.svg) +
    + +### External non-interactive users + +External non-interactive users behave just like local ones, but it is another +cluster or certificate authority that issues certificates for them. + +They do not have local user records in Teleport backend. Teleport activates +[trusted cluster mapping logic](./trustedclusters.mdx#role-mapping) to support this use case. + +## Role Based Access Control + +Every Teleport user is assigned one or several roles that govern access to resources and Teleport's API. + +### Allow and Deny Rules + +Each Teleport role works by having two lists of rules: `allow` rules and `deny` rules: + +- Everything is denied by default. +- Deny rules get evaluated first and take priority. +- A rule consists of two parts: the resources and verbs. + +Here's an example of an allow rule describing a list verb applied to the sessions resource. +It means "allow users of this role to see a list of recorded SSH or Kubernetes sessions". + +```yaml +allow: + - resources: [session] + verbs: [list] +``` + +### Principals + +Roles define what principals (e.g. Linux OS users or Kubernetes group) users assigned +to the role are allowed to assume: + +```yaml +spec: + allow: + # The logins array defines the OS/UNIX logins a user is allowed to use. + logins: [ubuntu] + # Kubernetes groups defines what kubernetes groups a user is allowed to assume. + kubernetes_groups: [viewer] +``` + +In case if a user has many roles, the list of principals is merged in one set. + +### Labels + +Role labels define what resources rules in the role apply to. For example, let's +review a role that specifies access for SSH nodes and kubernetes clusters: + +```yaml +spec: + allow: + # List of node labels a user will be allowed to connect to: + node_labels: + # Regular expressions are also supported, for example, the equivalent + # of the list example above can be expressed as: + 'environment': '^test|staging$' + + kubernetes_labels: + # User can access any region in us-west, e.g us-west-1, us-west-2 + 'region': 'us-west-*' + 'cluster_name': '^us.*\.example\.com$' +``` + +Here is how labels, allow rules and principals are applied: + +- For `allow` rule to match, all labels in the rule should match, +for example, in the Kubernetes rule above, both `region` and `cluster_name` should match. +- For `deny` rule to match, any label in the rule could match. + +**Principals and labels** + +Let's assume Alice is assigned two roles: `dev` and `prod`: + +Dev role allows SSH access as `root` and unrestricted access to kubernetes as `system:masters` for +any kubernetes cluster or node with labels matching 'test' or 'stage'. + +```yaml +metadata: + name: dev +spec: + allow: + logins: [root] + kubernetes_groups: ['system:masters'] + # List of node labels a user will be allowed to connect to: + node_labels: + 'environment': ['test', 'stage'] + kubernetes_labels: + 'environment': ['test', 'stage'] +``` + +Prod role allows SSH access as `ubuntu` and `view` access to kubernetes for +any kubernetes cluster or node with labels matching 'prod' + +```yaml +metadata: + name: prod +spec: + allow: + logins: [ubuntu] + kubernetes_groups: ['view'] + node_labels: + 'environment': ['prod'] + kubernetes_labels: + 'environment': ['prod'] +``` + +Here is how Teleport will evaluate Alice's access: + +- Alice can SSH as root to server labeled as `test` or `stage` +- Alice can not SSH as root to server labeled as `prod`, because prod role +only allows access as `ubuntu` to `prod`-labeled servers. + +The same applies to Kubernetes: + +- Alice can access kubernetes cluster as `system:masters` if it's labeled as `test` or `stage`. +- Alice can access kubernetes clusters only as a `view` role if it's labeled as `prod`. + + +### Role templates + +Roles support template variables. Here is a role snippet that explains +how variables are interpolated. + +```yaml +spec: + # The allow section declares a list of resource/verb combinations that are + # allowed for the users of this role. By default, nothing is allowed. + allow: + # internal.logins - will be interpolated from local user's traits - + # properties you can assign when creating a user. + logins: ['{{internal.logins}}'] + + # kubernetes_groups specifies Kubernetes groups a user with this role will assume. + # You can refer to a SAML/OIDC trait via the "external" property bag. + # This allows you to specify Kubernetes group membership in an identity manager: + kubernetes_groups: ['{{external.groups}}'] +``` + + +Any role that uses variable interpolation is treated as a role template. +You can add interpolation to any role spec. + + +**Variable interpolation rules* + +- If `external.groups` is a list that contains `["dev", "prod"]` the expression `["{{external.groups}}"]` +will interpolate to list `["dev", "prod"]`. +- If `external.groups` is a variable that equals `"dev"` the expression `["{{external.groups}}"]` +will interpolate to `["dev"]`. +- If `external.groups` is missing, the expression `"{{external.groups}}"` will evaluate into empty string `""`. +You can use predicate language function calls in templates, e.g. `{{email.local(external.foo)}}`. +- You can combine string prefixes and values, for example: `"IAM#{{regexp.replace(external.foo, "^bar-(.*)$", "$1")}};"`. +- Invalid expressions will be ignored, e.g. `external.foo}}` will be skipped, just as invalid function calls. +- Invalid values will be omitted, for example `-foo` is not a valid Unix login, so if variable `external.foo` equals +`"-foo"`, it will be omitted in `logins: ["{{external.foo}}"]`. + +**How role templates are evaluated** + +Role templates are evaluated at the time of access to any resource either by proxy or node. +Every Teleport component - proxy, auth server or node has up to date copy of all roles. + +Let's review a case with the following role template: + +```yaml +metadata: + name: devs +spec: + allow: + kubernetes_groups: ["{{external.k8s_groups}}"] + kubernetes_labels: + "env": ["{{external.env}}"] +``` + +User Alice authenticates with Teleport and receives the following variables from +the identity provider: + +``` +k8s_groups: ["view", "edit"] +env: ["stage"] +``` + +These variables get encoded in the X.509 certificate as extensions. + +When proxy authorizes the attempt to connect to the Kubernetes cluster it interpolates +the role template and the variables, and gets: + +```yaml +metadata: + name: devs +spec: + allow: + kubernetes_groups: ["view", "edit"] + kubernetes_labels: + "env": ["stage"] +``` + +Finally, the proxy applies the resulting role to the kubernetes cluster Alice tries to +access and checks it against cluster. If the cluster has labels `"env": "stage"` +the attempt succeeds, otherwise it fails. + +### Role conditions + +The example below illustrate how to restrict session access only for the user who created the session +using role conditions: + +```yaml +kind: role +metadata: + name: only-own-sessions +spec: + allow: + rules: + # Users can only view session recordings for sessions in which they + # participated. + - resources: [session] + verbs: [list, read] + where: contains(session.participants, user.metadata.name) +``` + + +You can use `where` fields in all resource rules. Check out [the full role reference](../access-controls/reference.mdx) contains full role spec for details. + + +### Role options + +Alongside `allow` and `deny` rules, roles control a variety of options, for example: + +``` +kind: role +version: v5 +metadata: + name: relaxed +spec: + # options specify connection, in case if user has multiple non-default + # conflicting options, teleport chooses the least permissive value. + options: + # max_session_ttl defines the TTL (time to live) of certificates + # issued to the users with this role. + max_session_ttl: 8h + # lock sets locking mode for user of this role, + # valid values are "strict" or "best_effort" + lock: strict +``` + +In case if user has multiple roles that specify conflicting options, for example, +role `relaxed` sets the `max_session_ttl` to `8h` and `restricted` that sets `max_session_ttl` +to `4h`, most secure value will be used, in this case Teleport will choose to limit sessions to 4 hours. + +Teleport applies the same logic to other values, for example if two roles specify both `strict` and `best_effort` +options, Teleport will choose `strict` option. + +### Just in Time Access Requests + + + + + The full version of Just In Time Access Requests is available only in Teleport Cloud or Enterprise. + + + + +Roles allow requesting elevated privileges - other roles or individual resources. + +Roles control who can review requests for privileges and define how many approvals +or rejections are required: + +```yaml +spec: + allow: + # review_requests allows a user holding this role + # to approve or deny access requests + review_requests: + roles: ['dbadmin'] + + # request allows a user user request roles matching + # expressions below + request: + # the `roles` list can be a mixture of literals and wildcard matchers + roles: ['common', 'dev-*'] + # thresholds specifies minimum amount of approvers and deniers, + # defaults to 1 for both + thresholds: + # requires at least two qualifying approvers and at least one denier. + - approve: 2 + deny: 1 +``` + +## Next steps + +- [Access Control Reference](../access-controls/reference.mdx). +- [Teleport Predicate Language](../setup/reference/predicate-language.mdx). +- [Access Requests Guides](../enterprise/workflow/index.mdx) +- [Architecture Overview](overview.mdx) +- [Teleport Auth](authentication.mdx) +- [Teleport Nodes](nodes.mdx) +- [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/nodes.mdx b/docs/pages/architecture/nodes.mdx index 9fea6fb78e766..849ba94993b03 100644 --- a/docs/pages/architecture/nodes.mdx +++ b/docs/pages/architecture/nodes.mdx @@ -1,43 +1,50 @@ --- -title: Teleport Nodes -description: This chapter explains the concept of a Teleport Node and Teleport manages SSH and Kubernetes nodes. -h1: Teleport Nodes +title: Teleport SSH Nodes +description: This chapter explains the concept of a Teleport Node and how Teleport manages SSH. +h1: Teleport SSH Nodes --- -Teleport calls any computing device (server, VM, AWS instance, etc) a "node". +## The SSH Node service -## The Node service +The Teleport Node service is optional. You can use it to replace OpenSSH on your infrastructure. +Here is why we recommend Teleport Node service instead of OpenSSH: -A node becomes a Teleport Node when the node joins a cluster with a "join" token. Read about how nodes are issued certificates in the [Auth Guide](authentication.mdx#issuing-node-certificates). +- The node service supports BPF recording of all syscalls, network calls and files accessed during SSH session. +- It can record terminal sessions. +- It provides automatic registration, certificate and certificate authority rotation, +- It can provision OS user and update sudoers files according to teleport roles. +- You can connect nodes to proxies with outbound persistent tunnels, for your IoT lab or remote infrastructure. -![Node joins a cluster](../../img/node_join.svg) +Just like with OpenSSH, the `node` service provides SSH access to every node with any clients supporting client SSH certificates: -A Teleport Node runs the [`teleport`](../setup/reference/cli.mdx#teleport) daemon with the `node` role. This process handles incoming connection requests, authentication, and remote command execution on the node, similar to the function of OpenSSH's `sshd`. +- [OpenSSH: `ssh`](../server-access/guides/openssh.mdx) +- [Teleport CLI client: `tsh ssh`](../setup/reference/cli.mdx#tsh-ssh) +- [Teleport Proxy UI](./proxy.mdx) accessed via a web browser. +- Ansible and other SSH compatible clients. + +## Joining Nodes -![Node Service ping API](../../img/node_service_api.svg) +A node candidate becomes a Teleport Node it joins a cluster - authenticates itself to receive cluster certificate. -All cluster Nodes keep the Auth Server updated on their status with periodic ping messages. They report their IP addresses and the values of their assigned labels. Nodes can access the list of all Nodes in their cluster via the [Auth Server API](authentication.mdx#auth-api). +![Node joins a cluster](../../img/architecture/node-registration@1.2x.svg) + +All cluster Nodes keep the Auth Server updated on their status with periodic ping messages. +They report their IP addresses and the values of their assigned labels. +Clients can access the list of all Nodes in their cluster via the Auth Server API or CLI. - In most environments, we advise replacing the OpenSSH daemon `sshd` with the Teleport Node Service unless there are existing workflows relying on `ssh` or in special cases such as embedded devices that can't run custom binaries. +Nodes can register with Auth servers directly, or use proxies to establish the connection to auth servers. +The latter is helpful if you have multiple proxies and nodes all over the world. -The `node` service provides SSH access to every node with all of the following clients: +## SSH Host certificate -- [OpenSSH: `ssh`](../server-access/guides/openssh.mdx) -- [Teleport CLI client: `tsh ssh`](../setup/reference/cli.mdx#tsh-ssh) -- [Teleport Proxy UI](proxy.mdx#web-to-ssh-proxy) accessed via a web browser. +Node's identity is represented by SSH host certificate it receives after registering withing the cluster: -Each client is authenticated via the [Auth Service](authentication.mdx#authentication-in-teleport) before being granted access to a Node. - -## Node identity on a cluster - -Node Identity is defined on the Cluster level by the certificate a node possesses. - -![Node Identity](../../img/node_identity.svg) +![Host certificate](../../img/architecture/ssh-host-cert@1.2x.svg) This certificate contains information about the node including: @@ -45,9 +52,9 @@ This certificate contains information about the node including: - A **nodename**, which defaults to `hostname` of the node, but can be configured. - The **cluster_name**, which defaults to the `hostname` of the auth server, but can be configured - The node **role** (i.e. `node,proxy`) encoded as a certificate extension -- The cert **TTL** (time-to-live) +- The cert **Expiry time** -A Teleport Cluster is a set of one or more machines whose certificates are signed by the same certificate authority (CA) operating in the Auth Server. A certificate is issued to a node when it joins the cluster for the first time. Learn more about this process in the [Auth Guide](authentication.mdx#authentication-in-teleport). +A Teleport Cluster is a set of one or more machines whose certificates are signed by the same certificate authority (CA) operating in the Auth Server. A certificate is issued to a node when it joins the cluster for the first time. +You can mix both modes in the same cluster, depending on your use case. +For example, you can have several IOT devices joining the cluster via reverse tunnel +and a large fleet of servers in the internal network using standard mode. + ## Cluster state Cluster state is stored in a central storage location configured by the Auth -Server. This means that each node is completely stateless and holds no secrets +Server. Each node (or proxy) is stateless and holds no secrets such as keys or passwords. -![Cluster State](../../img/cluster_state.svg) - -The cluster state information stored includes: +The cluster state includes: - Node membership information and online/offline status for each node. - List of active sessions. @@ -85,14 +99,14 @@ The cluster state information stored includes: - RBAC configuration (roles and permissions). - Dynamic configuration. -Read more about what is stored in the [Auth Guide](authentication.mdx#auth-state) - -## Session recording +## SSH Session recording By default, nodes submit SSH session traffic to the Auth server for storage. These recorded sessions can be replayed later via `tsh play` command or in a web browser. +### SSH node recording + Some Teleport users assume that audit and session recording happen by default on the Teleport proxy server. This is not the case in default configuration because a proxy cannot see the encrypted traffic, it is encrypted end-to-end, @@ -100,22 +114,44 @@ i.e. from an SSH client to an SSH server/node, see the diagram below: ![session-recording-diagram](../../img/session-recording.svg) -However, starting from Teleport 2.4, it is possible to configure the -Teleport proxy to enable "recording proxy mode". +### Proxy recording mode + +In this mode, the proxy terminates (decrypts) the SSH connection using the +certificate supplied by the client via SSH agent forwarding and then establishes +its own SSH connection to the final destination server, effectively becoming an +authorized "man in the middle". This allows the proxy server to forward SSH +session data to the auth server to be recorded, as shown below: + +![recording-proxy](../../img/recording-proxy.svg) + +The recording proxy mode, although *less secure*, was added to allow Teleport +users to enable session recording for OpenSSH's servers running `sshd`, which is +helpful when gradually transitioning large server fleets to Teleport. + +We consider the "recording proxy mode" to be less secure for two reasons: + +1. It grants additional privileges to the Teleport proxy. In the default mode, + the proxy stores no secrets and cannot "see" the decrypted data. This makes a + proxy less critical to the security of the overall cluster. But if an + attacker gains physical access to a proxy Node running in the "recording" + mode, they will be able to see the decrypted traffic and client keys stored in the proxy's process memory. +2. Recording proxy mode requires SSH Agent Forwarding. Agent Forwarding is required because without it, a proxy will not be able to establish the 2nd connection to the destination Node. + +However, there are advantages of proxy-based session recording too. When +sessions are recorded at the Nodes, a root user can add iptables rules to +prevent sessions logs from reaching the Auth Service. With sessions recorded at +the proxy, users with root privileges on Nodes have no way of disabling the +audit. -## Trusted Clusters +See the [reference](../setup/reference/audit.mdx#recorded-sessions) to learn how to turn +on the recording proxy mode. Note that the recording mode is configured on the +Auth Service. -Teleport Auth Service can allow 3rd party users or nodes to connect to cluster -nodes if their certificates are signed by a trusted CA. A *trusted cluster* is -a public key of the trusted CA. It can be configured via `teleport.yaml` file. -{ - /* TODO: incomplete, write more on this */ -} ## More concepts - [Architecture Overview](overview.mdx) -- [Teleport Users](users.mdx) -- [Teleport Auth](authentication.mdx) +- [Teleport Authentication](authentication.mdx) +- [Teleport Authorization](authorization.mdx) - [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/overview.mdx b/docs/pages/architecture/overview.mdx index 704dfc46dbc85..c32ff8f2fa75a 100644 --- a/docs/pages/architecture/overview.mdx +++ b/docs/pages/architecture/overview.mdx @@ -1,254 +1,133 @@ --- title: Teleport Architecture Overview -description: Basic concepts and architecture of Teleport. What is an SSH cluster? How certificate-based SSH authentication works? How does SSH auditing work? -h1: Architecture Introduction +description: High level overview of concepts and architecture of Teleport. +h1: Architecture Overview --- + This guide is for those looking for a deeper understanding of Teleport. If you are looking for hands-on instructions on how to set up Teleport for your team, check out the [Admin Guide](../setup/admin.mdx) + ## What makes Teleport different -- Teleport replaces legacy keys and shared secrets with short-lived X.509 and SSH certificates - for services and users. -- It proxies and inspects SSH, Kubernetes, Web, and Database protocols. - For example for SSH, it controls the session from the start - and captures a session recording and in-kernel system calls using BPF. -- It removes a need for VPN and can connect multiple regions and organizations - in a decentralized network using mutual TLS and SSH tunnels. +- Teleport replaces legacy keys, passwords and shared secrets with short-lived X.509 and SSH certificates + for services and users accessing your infrastructure. +- It proxies and inspects SSH, Kubernetes, Web, Database and Desktop access protocols. +- It removes a need for VPN and connects multiple regions and organizations +in a decentralized network using mutual TLS and SSH tunnels. -## Design principles +## Core Components -Teleport was designed under the following principles: +The key concept of Teleport's architecture is a cluster. +A Teleport cluster consists of the Teleport Auth Service, Teleport Proxy Service and optional Teleport Agents. -- **Off the Shelf Security**: Teleport does not re-implement any security primitives and uses well-established, popular implementations of the encryption and network protocols. -- **Open Standards**: There is no security through obscurity. Teleport is fully - compatible with existing and open standards and other software, including - [OpenSSH](../server-access/guides/openssh.mdx). -- **Cluster-Oriented Design**: Teleport is built for managing clusters, not individual servers. In practice this means that hosts and users - have cluster memberships. Identity management and authorization happen on a - cluster level. -- **Built for Teams**: Teleport was created under the assumption of multiple teams operating on several disconnected clusters. Example use cases might be production-vs-staging environment, or a cluster-per-customer or cluster-per-application basis. +Cluster controls access to resources - Linux or Windows servers, databases, Kubernetes clusters, +Windows desktops, cloud services and consoles, internal web applications and services. -This doc introduces the basic concepts of Teleport so you can get started -managing access! + +To create a minimal Teleport cluster, you have to run two services: +Teleport Auth Service and Teleport Proxy Service. For your home lab, +you can run both services as a one binary and process. + -## Definitions - -Here are definitions of the key concepts you will use in Teleport. - -| Concept | Description | -| - | - | -| Node | A node is a "server", "host" or "computer". Users can create shell sessions to access nodes remotely. | -| User | A user represents someone (a person) or something (a machine) who can perform a set of operations on a node. | -| Cluster | A cluster is a group of nodes that work together and can be considered a single system. Cluster nodes can create connections to each other, often over a private network. Cluster nodes often require TLS authentication to ensure that communication between nodes remains secure and comes from a trusted source. | -| Certificate Authority (CA) | A Certificate Authority issues SSL certificates in the form of public/private keypairs. | -| [Teleport Node](nodes.mdx) | A Teleport Node is a regular node that is running the Teleport Node service. Teleport Nodes can be accessed by authorized Teleport Users. A Teleport Node is always considered a member of a Teleport Cluster, even if it's a single-node cluster. | -| [Teleport User](users.mdx) | A Teleport User represents someone who needs access to a Teleport Cluster. Users have stored usernames and passwords, and are mapped to OS users on each node. User data is stored locally or in an external store. | -| Teleport Cluster | A Teleport Cluster is comprised of one or more nodes, each of which holds certificates signed by the same [Auth Server CA](authentication.mdx). The CA cryptographically signs the certificate of a node, establishing cluster membership. | -| [Teleport CA](authentication.mdx) | Teleport operates two internal CAs as a function of the Auth service. One is used to sign User certificates and the other signs Node certificates. Each certificate is used to prove identity, cluster membership, and manage access. | - -## Teleport services - -Teleport uses three services which work together: [Nodes](nodes.mdx), -[Auth](authentication.mdx), and [Proxy](proxy.mdx). - -[**Teleport Nodes**](nodes.mdx) are servers that can be accessed remotely with -SSH. The Teleport Node service runs on a machine and is similar to the `sshd` -daemon you may be familiar with. Users can log in to a Teleport Node with all -of the following clients: - -- [OpenSSH: `ssh`](../server-access/guides/openssh.mdx) (works on Linux, macOS and Windows) -- [Teleport CLI client: `tsh ssh`](../setup/reference/cli.mdx#tsh-ssh) (works on Linux, macOS and Windows) -- [Teleport Proxy UI](proxy.mdx#web-to-ssh-proxy) accessed via any modern web browser (including Safari on iOS and Chrome on Android) - -[**Teleport Auth**](authentication.mdx) authenticates Users and Nodes, authorizes User -access to Nodes, and acts as a CA by signing certificates issued to Users and -Nodes. - -[**Teleport Proxy**](proxy.mdx) forwards User credentials to the [Auth -Service](authentication.mdx), creates connections to a requested Node after successful -authentication, and serves a [Web UI](proxy.mdx#web-to-ssh-proxy). - -## Basic architecture overview - -The numbers correspond to the steps needed to connect a client to a node. These -steps are explained below the diagram. +### Teleport Auth Service - - The teleport daemon calls services "roles" in the CLI - client. The `--roles` flag has no relationship to concept of [User Roles](users.mdx#user-roles) or - permissions. - - -![Teleport Overview](../../img/overview.svg) +The auth service controls certificate authority of the cluster. +It uses managed back-ends and HSM to store the certificate authority private keys. +The auth service issues certificates to clients and maintains the audit log. -1. Initiate Client Connection -2. Authenticate Client -3. Connect to Node -4. Authorize Client Access to Node - - - In the diagram above we show each Teleport service separately for clarity, but Teleport services do not have to run on separate nodes. - Teleport can be run as a binary on a single-node cluster with no external storage backend. We demonstrate this minimal setup in the [Getting Started Guide](../getting-started.mdx). - - -## Detailed architecture overview - -Here is a detailed diagram of a Teleport Cluster. - -The numbers correspond to the steps needed to connect a client to a node. These -steps are explained in detail below the diagram. - -![Teleport Everything](../../img/everything.svg) - -### 1: Initiate client connection - -![Client offers certificate](../../img/client_initiate.svg) - -The client tries to establish an SSH connection to a proxy using the CLI -interface or a web browser. When establishing a connection, the client offers -its certificate. Clients must always connect through a proxy for two reasons: - -1. Individual nodes may not always be reachable from outside a secure network. - -2. Proxies always record SSH sessions and keep track of active user sessions. - - This makes it possible for an SSH user to see if someone else is connected to - a node she is about to work on. -### 2: Authenticate client certificate +![Auth service](../../img/architecture/auth.png) -![Client offers valid certificate](../../img/cert_ok.svg) + -The proxy checks if the submitted certificate has been previously signed by the -auth server. + +The auth service uses HTTPS and accepts client certificates for authentication. +You don't have to deploy it on a private network, but it's a good practice to restrict network access to its port +for defense in depth. + -![Client obtains new certificate](../../img/cert_invalid.svg) +Here are some key facts about the auth service: -If there was no certificate previously offered (first time log in) or if the certificate has expired, the proxy denies the connection and asks the client to -login interactively using a password and a 2nd factor if enabled. +- It is the only service that has to be connected to the backend for audit and state storage. +All other services are stateless and always interact with auth service GRPC API, never +directly with the backend. +- This is why you can safely limit access to the backend to the auth service only. +- You can run multiple auth services in the cluster for high availability. -Teleport supports -[Google Authenticator](https://support.google.com/accounts/answer/1066447?hl=en), -[Authy](https://www.authy.com/), or another -[TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm) -generator. The password + 2nd factor are submitted to a proxy via HTTPS, -therefore it is critical for a secure configuration of Teleport to install a -proper HTTPS certificate on a proxy. +### Teleport Proxy Service - - Do not use self-signed SSL/HTTPS certificates in production! - - -If the credentials are correct, the auth server generates and signs a new -certificate and returns it to the client via the proxy. The client stores this certificate -and will use it for subsequent logins. The certificate will automatically expire after -12 hours by default. This [TTL](https://en.wikipedia.org/wiki/Time_to_live) can be [configured](../setup/reference/cli.mdx#tctl-users-add) -to another value by the cluster administrator. - -### 3: Lookup Node - -![Node lookup](../../img/node_lookup.svg) - -At this step, the proxy tries to locate the requested node in a cluster. There -are three lookup mechanisms a proxy uses to find the node's IP address: - -1. Uses DNS to resolve the name requested by the client. -2. Asks the Auth Server if there is a Node registered with this `nodename`. -3. Asks the Auth Server to find a node (or nodes) with a label that matches the requested name. - -If the node is located, the proxy establishes the connection between the client -and the requested node. The destination node then begins recording the session, -sending the session history to the auth server to be stored. +The proxy service allows access to cluster resources from the outside. +It is the only service that has to be available from any user-facing network. +All public users and external services most of the time connect to the proxy. - - Teleport may also be configured to have the session recording - occur on the proxy, see [Audit Reference](../setup/reference/audit.mdx) for more - information. - - -### 4: Authenticate Node certificate - -![Node Membership Authentication](../../img/node_cluster_auth.svg) - -When the node receives a connection request, it checks with the Auth Server to -validate the node's certificate and validate the Node's cluster membership. - -If the node certificate is valid, the node is allowed to access the Auth Server -API which provides access to information about nodes and users in the cluster. - -### 5: Grant user Node access - -![User Granted Node Access](../../img/user_node_access.svg) -The node requests the Auth Server to provide a list of [OS users (user -mappings)](../setup/admin/users.mdx) for the connecting client, to make sure the client is -authorized to use the requested OS login. +![Proxy service](../../img/architecture/proxy.png) -Finally, the client is authorized to create an SSH connection to a node. + -![Proxy Connection Established](../../img/proxy_client_connect.svg) + +In its minimal configuration, the proxy service can multiplex all connections on one port and protocol, HTTPS. + -## Teleport CLI tools + +In some cases, e.g. break-glass recovery scenarios, and if allowed by configuration, clients can bypass proxies and +connect to resources with client certificates directly. Proxies add benefits, such as connection control, +routing and tunneling but are not a required component for connections! + -Teleport offers two command-line tools. `tsh` is a client tool used by the end -users, while `tctl` is used for cluster administration. +### Teleport Node Service -### `tsh` +The Teleport Node service is optional. You can use it to replace OpenSSH on your infrastructure. +Here is why we recommend Teleport Node service instead of OpenSSH: -`tsh` is similar in nature to OpenSSH `ssh` or `scp`. It has -subcommands named after them so you can call: +- The node service supports BPF recording of all syscalls, network calls and files accessed during SSH session. +- It can record terminal sessions. +- It provides automatic registration, certificate and certificate authority rotation. +- It can provision OS user and update sudoers files according to teleport roles. +- You connect nodes to the proxy using outbound persistent tunnels, for your IoT lab or +remote infrastructure. -```code -$ tsh --proxy=p ssh -p 1522 user@host -$ tsh --proxy=p scp -P example.txt user@host/destination/dir -``` - -Unlike `ssh`, `tsh` is very opinionated about authentication: it always uses -auto-expiring certificates and it always connects to Teleport nodes via a proxy. - -When `tsh` logs in, the auto-expiring certificate is stored in `~/.tsh` and is -valid for 12 hours by default, unless you specify another interval via the -`--ttl` flag (capped by the server-side configuration). +## Definitions -You can learn more about `tsh` in the [User Manual](../server-access/guides/tsh.mdx). +Here are some of the key concepts we use in Teleport. -### `tctl` +| Concept | Description | +| - | - | +| Certificate Authority (CA) | A Certificate Authority issues x.509 and SSH certificates in the form of public/private key pairs. | +| Teleport Cluster | A Teleport Cluster manages access to resources - databases, kubernetes clusters, servers, desktops, web apps and clouds.| +| Teleport Proxy Service | A proxy service allows access to cluster resources from the public network. It is the only service that has to be available from the public network.| +| Teleport Auth Service | The auth service manages certificate authorities of the cluster. It issues certificates to clients and maintains the audit log.| +| [Teleport CA](./authentication.mdx) | Teleport's Auth service operates multiple internal certificate authorities. One is used to sign User certificates and the other signs Node certificates. Each certificate is used to prove identity, cluster membership, and manage access.| +| [Teleport Users](./authorization.mdx) | A Teleport User represents a user or a service that needs access to resources behind Teleport Cluster. Users can be local or external, interactive for users and non-interactive for services. | +| [Teleport Node](./nodes.mdx) | A Teleport Node is an optional service to replace OpenSSH. | -`tctl` is used to administer a Teleport cluster. It connects to the Teleport -Auth Service and allows an administrator to manage Nodes, users, and other -resources in the cluster. +## Next steps -You can run `tctl` commands either remotely or on the Teleport Auth Service -host. When run remotely, `tctl` requires that the user authenticate to the -cluster. When run on the Auth Service host, `tctl` uses the identity of the Auth -Service itself, and does not require additional authentication. +Read the rest of the Architecture Guides: -You can learn more about `tctl` in the [CLI Reference](../setup/reference/cli.mdx#tctl). +- See how Teleport uses [Certificates](authentication.mdx) for authentication. +- [Teleport Authorization](authorization.mdx) +- [Teleport Nodes](nodes.mdx) +- [Teleport Proxy](proxy.mdx) +- Reduce your surface of attack using [TLS routing](./tls-routing.mdx). -## Next steps +Get started with Teleport: -- If you haven't already, read the [Getting Started Guide](../getting-started.mdx) to run a - minimal setup of Teleport yourself. +- Read the [Getting Started Guide](../getting-started.mdx) to run a Teleport yourself or +sign up for [Teleport cloud](https://goteleport.com/signup/). - Set up Teleport for your team with the [Admin Guide](../setup/admin.mdx). -Read the rest of the Architecture Guides: -- [Teleport Users](users.mdx) -- [Teleport Nodes](nodes.mdx) -- [Teleport Auth](authentication.mdx) -- [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/proxy.mdx b/docs/pages/architecture/proxy.mdx index 144338df5e26f..43688cc00cff5 100644 --- a/docs/pages/architecture/proxy.mdx +++ b/docs/pages/architecture/proxy.mdx @@ -1,125 +1,73 @@ --- title: Teleport Proxy Service -description: How Teleport implements SSH and Kubernetes access via a Proxy -h1: The Proxy Service +description: Architecture of Teleport's identity-aware proxy service +h1: Teleport Identity-Aware Proxy Service --- -The proxy is a stateless service that performs three main functions in a -Teleport cluster: +Teleport Proxy is a identity aware proxy, with a web UI. Here are Proxy's key features: -1. It serves as an authentication gateway. It asks for credentials from - connecting clients and forwards them to the Auth server via [Auth - API](authentication.mdx#auth-api). -2. It looks up the IP address for a requested Node and then proxies a connection - from client to Node. -3. It serves a Web UI that is used by cluster users to sign up and configure - their accounts, explore Nodes in a cluster, log into remote Nodes, join - existing SSH sessions or replay recorded sessions. +- Users can authenticate with a Single-Sign-On or local credentials to access SSH and Windows Desktops via Proxy's web UI. +- Proxy is identity aware - it makes sure that only authenticated clients can connect to target resources. +It intercepts traffic for multiple protocols - SSH, Kubernetes, HTTPS, databases. +It records commands, API calls and queries and streams them to the audit log. +- Proxy provides networking and connectivity features. Nodes and proxies behind firewalls can connect +to proxies using reverse tunnels. System administrators can use TLS routing feature to compress all ports for all protocols to one TLS port using TLS routing feature. -## Connecting to a Node +![Proxy service](../../img/architecture/proxy.png) -### Web to SSH Proxy + +To create a minimal Teleport cluster, you have run two services: +Teleport Auth Service and Teleport Proxy Service. For your home lab, +you can run both services as a one binary and process. + -In this mode, Teleport Proxy implements WSS - secure web sockets - to proxy a -client SSH connection: +## Web UI -![Teleport Proxy Web](../../img/proxy-web.svg) +In Web UI, Teleport Proxy implements WSS - secure web sockets - to proxy a +target resource, for example SSH server or Desktop: -1. User logs in to Web UI using username and password, and 2nd-factor token if configured (2FA Tokens are not used with SSO providers). -2. Proxy passes credentials to the Auth Server's API -3. If Auth Server accepts credentials, it generates a new web session and generates a special ssh keypair associated with this web session. Auth server - starts serving [OpenSSH ssh-agent protocol](https://tools.ietf.org/html/draft-miller-ssh-agent-04) to the proxy. -4. The User obtains an SSH session in the Web UI and can interact with the Node on a web-based terminal. From the Node's perspective, it's a regular SSH - client connection that is authenticated using an OpenSSH certificate, so no special logic is needed. +![Teleport Proxy Web](../../img/architecture/proxy-web-to-resource@1.2x.svg) - When using the web UI, the Teleport Proxy terminates SSL traffic and re-encodes data for the SSH client connection. + When using the web UI, the Teleport Proxy terminates traffic and re-encodes data for the client connection. -### CLI to SSH Proxy +## Identity-Aware-Proxy -**Getting Client Certificates** +In IAP mode, users initiate the SSO or login flow to sign public keys on their client machines: -Teleport Proxy implements a special method to let clients get short-lived -authentication certificates signed by the Certificate Authority (CA) provided by -the [Auth Service](authentication.mdx#authentication-in-teleport). - -![Teleport Proxy SSH](../../img/proxy-ssh-1.svg) - -1. A [`tsh` client](../setup/reference/cli.mdx#tsh) generates an OpenSSH key pair. It forwards the generated public key, username, password, and second-factor token to the proxy. -2. The Proxy Service forwards the request to the Auth Service. -3. If Auth Service accepts credentials, it generates a new certificate signed by its user CA and sends it back to the Proxy Server. The certificate has a TTL - that defaults to 12 hours but can be configured in [`tctl`](../setup/reference/cli.mdx#tctl). -4. The Proxy Server returns the user certificate to the client and the client stores it in `~/.tsh/keys/example.com`. The certificate is also added to the local SSH agent if one is running. - -**Using Client Certificates** - -Once the client has obtained a certificate, it can use it to authenticate with -any Node in the cluster. Users can use the certificate using a standard OpenSSH -client `ssh` or using `tsh`: - -![Teleport Proxy Web](../../img/proxy-ssh-2.svg) - -1. A client connects to the Proxy Server and provides target Node's host and port location. There are three lookup mechanisms a proxy uses to find the - Node's IP address: - - - Use DNS to resolve the name requested by the client. - - Asks the Auth Service if there is a Node registered with this `nodename`. - - Asks the Auth Service to find a Node (or Nodes) with a label that matches the requested name. - -2. If the Node is located, the Proxy establishes an SSH tunnel to the - requested Node and starts forwarding traffic from Node to client. - -3. The client uses the established SSH tunnel from Proxy to Node to open a new - SSH connection. The client authenticates with the target Node using its - client certificate. +![Teleport Proxy IAP](../../img/architecture/proxy-iap-to-resource@1.2x.svg) - Teleport's proxy command makes it compatible with [SSH jump hosts](https://wiki.gentoo.org/wiki/SSH_jump_host) implemented using OpenSSH's `ProxyCommand`. It also supports OpenSSH's ProxyJump/ssh -J implementation. +We consider IAP mode more secure than Web UI access, because private keys never leave user's client. +Client's connection to resource is mutually authenticated. This mode is also less vulnerable +for web-related attacks, like CSRF or cookie hijacking, because browser is used less. -## Recording Proxy mode - -In this mode, the proxy terminates (decrypts) the SSH connection using the -certificate supplied by the client via SSH agent forwarding and then establishes -its own SSH connection to the final destination server, effectively becoming an -authorized "man in the middle". This allows the proxy server to forward SSH -session data to the auth server to be recorded, as shown below: - -![recording-proxy](../../img/recording-proxy.svg) - -The recording proxy mode, although *less secure*, was added to allow Teleport -users to enable session recording for OpenSSH's servers running `sshd`, which is -helpful when gradually transitioning large server fleets to Teleport. +## Tunnels -We consider the "recording proxy mode" to be less secure for two reasons: +In this mode, resources behind firewall can establish reverse tunnels back to proxies. +Proxies will forward client's connections to target resources via those tunnels. -1. It grants additional privileges to the Teleport proxy. In the default mode, - the proxy stores no secrets and cannot "see" the decrypted data. This makes a - proxy less critical to the security of the overall cluster. But if an - attacker gains physical access to a proxy Node running in the "recording" - mode, they will be able to see the decrypted traffic and client keys stored in the proxy's process memory. -2. Recording proxy mode requires SSH Agent Forwarding. Agent Forwarding is required because without it, a proxy will not be able to establish the 2nd connection to the destination Node. +In the example below, Alice connects to kubernetes cluster behind firewall via two tunnels: -However, there are advantages of proxy-based session recording too. When -sessions are recorded at the Nodes, a root user can add iptables rules to -prevent sessions logs from reaching the Auth Service. With sessions recorded at -the proxy, users with root privileges on Nodes have no way of disabling the -audit. +![Teleport Proxy Tunnel](../../img/architecture/proxy-tunnel@1.2x.svg) -See the [reference](../setup/reference/audit.mdx#recorded-sessions) to learn how to turn -on the recording proxy mode. Note that the recording mode is configured on the -Auth Service. + +All modes above are turned on by default in Proxies. No special configuration is necessary, unless you +want to turn some of those modes off. + ## More concepts +- [TLS Routing](tls-routing.mdx) - [Architecture Overview](overview.mdx) -- [Teleport Users](users.mdx) -- [Teleport Auth](authentication.mdx) +- [Teleport Authentication](authentication.mdx) +- [Teleport Authorization](authorization.mdx) - [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/trustedclusters.mdx b/docs/pages/architecture/trustedclusters.mdx new file mode 100644 index 0000000000000..75bce9d5afbce --- /dev/null +++ b/docs/pages/architecture/trustedclusters.mdx @@ -0,0 +1,65 @@ +--- +title: Teleport Trusted Clusters Architecture +description: Deep dive into design of Teleport Trusted Clusters. +h1: Trusted Clusters Architecture +--- + +## Overview + +Teleport can partition compute infrastructure into multiple clusters. A cluster +is a group of Teleport connected resources. Each cluster +manages a set of certificate authorities (CAs) for its users and resources. + +Trusted Clusters allow the users of one cluster, the **root cluster**, to +seamlessly SSH into the Nodes of another cluster, the **leaf cluster**, while +remaining authenticated with only a single Auth Service. The leaf cluster can +be running behind a firewall without any ingress ports open. + +Uses for Trusted Clusters include: + +- Managed service providers (MSP) remotely managing the infrastructure of their clients. +- Device manufacturers remotely maintaining computing appliances deployed on premises. +- Large cloud software vendors managing multiple data centers. + + +Individual nodes and proxies can create reverse tunnels to proxy services without creating a new cluster. +You don't need to set up a trusted cluster just to connect a couple of servers, kubernetes clusters or +databases behind a firewall. + + +## Multi-Data-center Clusters + +In the example below, there are three independent clusters: + +- Cluster `sso.example.com` is a root cluster. This cluster can be used as a single-sign-on entry point +for your organization. It can have it's own independent resources connected to it, or be used just for audit +logs collection and single-sign-on. +- Clusters `us-east-1a` and `us-east-1b` are two independent clusters in different availability zones. + +![Trusted clusters](../../img/architecture/trusted-clusters@1.5x.svg) + +## Role Mapping + +In Teleport, leaf clusters are autonomous - they have their own state, roles and even local users. +Leaf clusters have autonomy to decide how to map identity of the external users to their local roles. +We call this process role mapping. Take a look at the flow below to understand how it works: + +![Role mapping](../../img/architecture/tc-role-mapping.svg) + + +If this all sounds complicated, but don't worry, you do not need to use trusted clusters unless you have +large, distributed infrastructure or your organization works with external agencies or contractors who +need separate access. + +In many cases, a single cluster is enough. A single teleport cluster can scale to hundreds of thousands +of connected resources! + + +## Next steps + +Read the rest of the Architecture Guides: + +- See how Teleport uses [Certificates](authentication.mdx) for authentication. +- Reduce your surface of attack using [TLS routing](./tls-routing.mdx). +- Follow our [guide](../setup/admin/trustedclusters.mdx) to set up trusted clusters. + diff --git a/docs/pages/architecture/users.mdx b/docs/pages/architecture/users.mdx deleted file mode 100644 index 30caeec4ee053..0000000000000 --- a/docs/pages/architecture/users.mdx +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: Teleport Users -description: This chapter explains the concept of a Teleport User and how it's different from operating system (OS) users or Kubernetes users. -h1: Teleport Users ---- - -## Types of users - -Unlike traditional SSH, Teleport introduces the concept of a User Account. A -User Account is not the same as SSH login. Instead, each Teleport User is -associated with another account which is used to authenticate the user. - -For Open Source edition users, these will be OS users who are administered -outside of Teleport on each cluster node. For example, there can be a Teleport -user `joe` who can be permitted to log in as "root" to a specific subset of -nodes. Another user `juliet` could be permitted to OS users `root` and to -`nginx`. Teleport does not know the OS Users so it expects both `root` and -`nginx` to exist on the node. - -For Enterprise edition users, these can be stored in an external identity source -such as Okta, Active Directory, OneLogin, G Suite, or OIDC. Read the -[Enterprise Guide](../enterprise/introduction.mdx) to learn more. - -Teleport supports two types of user accounts: **Local Users** and -**External Users**. - -### Local users - -Local users are created and stored in Teleport's own identity storage in the -Auth Server. - -Let's look at this table: - -| Teleport User | Allowed OS Logins | Description | -| - | - | - | -| joe | joe, root | Teleport user `joe` can log in into member nodes as OS user `joe` or `root`. | -| juliet | juliet | Teleport user `juliet` can log in into member nodes only as OS user `juliet`. | -| ross | | If no OS login is specified, it defaults to the same name as the Teleport user, here this is `ross`. | - -A cluster administrator must create account entries for every Teleport user with -[`tctl users add`](../setup/reference/cli.mdx). Every Teleport User must be -associated with a list of one or more machine-level OS usernames it can -authenticate as during a login. This list is called "user mappings". - -![User Mappings](../../img/user_mappings.svg) - -The diagram shows the following mappings. A couple of noteworthy things -from this example: - -- Teleport User `sandra` does **not** have access to `grav-02` - through Teleport because `ops` is not an OS username on that node. -- Teleport User `joe` has access to all nodes because the OS user `root` - is present on all nodes. - -| Teleport User | logins | has access to nodes | -| - | - | - | -| joe | root, joe | grav-00, grav-01, grav-02 | -| tara | tara | grav-01, grav-02 | -| teleport | teleport | grav-00, grav-02 | -| sandra | ops | grav-00, grav-01 | - -Teleport supports second-factor authentication (2FA) when using a local auth -connector and it is enforced by default. - - - 2FA is not supported with SSO providers such as GitHub or Okta. To learn - more about SSO configuration check out the [SSO section of the Enterprise - Guide](../enterprise/introduction.mdx#sso) - - -There are two types of 2FA supported: - -- [TOTP - e.g. Google Authenticator](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) -- [WebAuthn - e.g. YubiKey](https://webauthn.guide) - -`TOTP` is the default. You can use [Google -Authenticator](https://en.wikipedia.org/wiki/Google_Authenticator) or -[Authy](https://www.authy.com/) or any other TOTP client. - -### External users - -{ - /* TODO: Production topic */ -} - -External users are users stored elsewhere within an organization. Examples -include GitHub, Active Directory (AD), OIDC, or any identity store with an -OpenID/OAuth2 or SAML endpoint. - - - External user storage is only supported in Teleport - Enterprise. Please take a look at the [Teleport - Enterprise](../enterprise/introduction.mdx) chapter for more information. - - -#### Multiple identity sources - -It is possible to have multiple identity sources configured for a Teleport -cluster. In this case, an identity source (called a "connector") will have to be -passed to -[`tsh --auth=connector_name login`](../setup/reference/cli.mdx#tsh-login). - -{ - /* TODO: Production Configuration */ -} - -The local users connector can be specified via [`tsh --auth=local -login`](../setup/reference/cli.mdx#tsh-login). - -## User roles - -Unlike traditional SSH, each Teleport user account is assigned a `role`. Having -roles allows Teleport to implement role-based access control (RBAC), i.e. assign -users to groups (roles) and restrict each role to a subset of actions on a -subset of nodes in a cluster. - -{ - /* TODO: Enterprise Topic */ -} - -## More concepts - -- [Architecture Overview](overview.mdx) -- [Teleport Auth](authentication.mdx) -- [Teleport Nodes](nodes.mdx) -- [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/cloud/architecture.mdx b/docs/pages/cloud/architecture.mdx index d2d2b3e40a756..3bc8ebb4b4512 100644 --- a/docs/pages/cloud/architecture.mdx +++ b/docs/pages/cloud/architecture.mdx @@ -16,7 +16,7 @@ whether the Teleport Cloud is ready for strict compliance use-cases. ## Managed Teleport Settings -SSH sessions are recorded [on nodes](../architecture/nodes.mdx#session-recording). +SSH sessions are recorded [on nodes](../architecture/nodes.mdx). Teleport Cloud Proxy does not terminate SSH sessions when using OpenSSH and `tsh` sessions. The Cloud Proxy terminates TLS for Application, Database and Kubernetes sessions. diff --git a/docs/pages/cloud/getting-started.mdx b/docs/pages/cloud/getting-started.mdx index ee3621ef045ec..86c7d8db5e9c9 100644 --- a/docs/pages/cloud/getting-started.mdx +++ b/docs/pages/cloud/getting-started.mdx @@ -60,6 +60,12 @@ $ tsh ls $ tsh ssh root@myserver ``` +
    + +(!docs/pages/includes/node-logins.mdx!) + +
    + Type exit to end this session. Happy Teleporting! ## Next Steps diff --git a/docs/pages/cloud/introduction.mdx b/docs/pages/cloud/introduction.mdx index 737cd3767ed7a..265534b50fcc3 100644 --- a/docs/pages/cloud/introduction.mdx +++ b/docs/pages/cloud/introduction.mdx @@ -33,7 +33,7 @@ desktops, and service accounts. Sign up for a free trial of Teleport Cloud - + Start using your Teleport Cloud account diff --git a/docs/pages/database-access/architecture.mdx b/docs/pages/database-access/architecture.mdx index 73cf58425a388..f502bf75b1e65 100644 --- a/docs/pages/database-access/architecture.mdx +++ b/docs/pages/database-access/architecture.mdx @@ -52,7 +52,7 @@ Let's take a look at the typical flow Database Access users go through to connect to a database. 1. A user logs into the cluster with `tsh login` command and retrieves - a client certificate. See [Issuing User Certificates](../architecture/authentication.mdx#issuing-user-certificates) + a client certificate. See [Issuing User Certificates](../architecture/authentication.mdx) for more details on how it works. 2. The user picks the database they want to connect to from the list of available databases shown in `tsh db ls` command and retrieves a short-lived X.509 diff --git a/docs/pages/database-access/faq.mdx b/docs/pages/database-access/faq.mdx index a579246b8c7ed..feaba17969556 100644 --- a/docs/pages/database-access/faq.mdx +++ b/docs/pages/database-access/faq.mdx @@ -13,6 +13,7 @@ Teleport Database Access currently supports the following protocols: - MySQL - PostgreSQL - Redis +- Snowflake For PostgreSQL and MySQL, the following Cloud-hosted versions are supported in addition to self-hosted deployments: @@ -112,4 +113,4 @@ If none of the above options work for you and you still want to disable the CA check, you can use `mode` under the `tls` option in the Teleport configuration file. For more details please refer to the reference -[configuration file](./reference/configuration.mdx#database-service-configuration). \ No newline at end of file +[configuration file](./reference/configuration.mdx#database-service-configuration). diff --git a/docs/pages/database-access/guides/gui-clients.mdx b/docs/pages/database-access/guides/gui-clients.mdx index 44b91bb32176e..1cfa530368cf9 100644 --- a/docs/pages/database-access/guides/gui-clients.mdx +++ b/docs/pages/database-access/guides/gui-clients.mdx @@ -16,7 +16,7 @@ Ensure that your environment includes the following: - A running Teleport cluster. For details on how to set this up, see one of our - [Getting Started](/docs/getting-started) guides. + [Getting Started](/docs/getting-started) guides. - The `tsh` client tool version >= (=teleport.version=). @@ -338,3 +338,72 @@ Click `Add Redis Database`. Congratulations! You have just connected to your Redis instance. ![Redis Insight Connected](../../../img/database-access/guides/redis/redisinsight-connected.png) + + +## Snowflake: JetBrains (IntelliJ, Goland, DataGrip, PyCharm, etc.) + + +The Snowflake integration works only in the authenticated proxy mode. Start a local proxy for connections to your Snowflake database by using the command below: +``` +tsh proxy db --tunnel --port 2000 snowflake +``` + +In "Database Explorer" click the "add" button, pick "Data Source", and then pick "Snowflake": + +![JetBrains Add Database](../../../img/database-access/guides/snowflake/jetbrains-add-database.png) + +Next, set "Host" to `localhost` and "Port" to the port returned by the `tsh proxy db` command you ran earlier (`2000` in the example above). +Set the "Username" to match the one that you are assuming when you connect to Snowflake + via Teleport and enter any value (e.g., "teleport") in the "Password" field (the value of + "Password" will be ignored but is required to create a data source in your IDE): + +![JetBrains General](../../../img/database-access/guides/snowflake/jetbrains-general.png) + +Switch to the "Advanced" tab, set any value (e.g., "teleport") for "account", and add a new record named `ssl` with value `off` (as with "Password", "account" is ignored while establishing the connection but required by your IDE): + +![JetBrains Advanced](../../../img/database-access/guides/snowflake/jetbrains-advanced.png) + +Teleport ignores the provided password and the account name as internally it uses values from the Database Agent configuration. +Setting "SSL" to `off` only disables encryption on your local machine. The connection to Snowflake is encrypted by Teleport. + +Now you can click "Test Connection" to check your configuration. + +![JetBrains Success](../../../img/database-access/guides/snowflake/jetbrains-success.png) + +Congratulations! You have just connected to your Snowflake instance. + +## Snowflake: DBeaver + +The Snowflake integration works only in the authenticated proxy mode. Start a local proxy for connections to your Snowflake database by using the command below: +``` +tsh proxy db --tunnel --port 2000 snowflake +``` + +Add a new database by clicking the "add" icon in the top-left corner: + +![DBeaver Main Screen](../../../img/database-access/guides/snowflake/dbeaver-main-screen.png) + +In the search bar of the "Connect to a database" window that opens up, type "snowflake", select the Snowflake driver, and click "Next": + +![DBeaver Select Database](../../../img/database-access/guides/snowflake/dbeaver-select-database.png) + +Set "Host" to `localhost` and "Port" to the port returned by the `tsh proxy db` command you ran earlier (`2000` in the example above). +In the "Authentication" section set the "Username" to match the database username passed to Teleport with `--db-user` +and enter any value (e.g., "teleport") in the "Password" field (the value of + "Password" will be ignored when establishing a connection but is required by DBeaver to register your database): + +![DBeaver Main](../../../img/database-access/guides/snowflake/dbeaver-main.png) + +Next, click the "Driver properties" tab and set "account" to any value (e.g., "teleport"; as with "Password", the value of + "account" will be ignored when establishing a connection but is required by DBeaver to register your database). In "User properties", set "ssl" to `off`: + +![DBeaver Driver](../../../img/database-access/guides/snowflake/dbeaver-driver.png) + +Teleport ignores the provided password and the account name as internally it uses values from the Database Agent configuration. +SSL set to `off` disables only encryption on local machine. Connection to Snowflake is encrypted by Teleport. + +Now you can click on "Test Connection..." in the bottom-left corner: + +![DBeaver Success](../../../img/database-access/guides/snowflake/dbeaver-success.png) + +Congratulations! You have just connected to your Snowflake instance. diff --git a/docs/pages/database-access/guides/redis-aws.mdx b/docs/pages/database-access/guides/redis-aws.mdx new file mode 100644 index 0000000000000..b3faf494fd122 --- /dev/null +++ b/docs/pages/database-access/guides/redis-aws.mdx @@ -0,0 +1,243 @@ +--- +title: Database Access with AWS ElastiCache and AWS MemoryDB for Redis +description: How to configure Teleport Database Access with AWS ElastiCache and AWS MemoryDB for Redis. +--- + +This guide will help you to: + +- Install Teleport `(=teleport.version=)`. +- Set up Teleport to access your ElastiCache and MemoryDB for Redis clusters. +- Connect to your clusters through Teleport. + + +![Teleport Database Access RDS Self-Hosted](../../../img/database-access/guides/redis_elasticache_selfhosted.png) + + + +![Teleport Database Access RDS Cloud](../../../img/database-access/guides/redis_elasticache_cloud.png) + + +## Prerequisites + +- AWS account with at least one ElastiCache or MemoryDB for Redis clusters + **In-transit encryption via (TLS) must be enabled**. +- Permissions to create and attach IAM policies. +- A host, e.g., an EC2 instance, where you will run the Teleport Database + Service. + +## Step 1/7. Install Teleport + +(!docs/pages/includes/database-access/start-auth-proxy.mdx!) + +## Step 2/7. Create a Teleport user + +(!docs/pages/includes/database-access/create-user.mdx!) + +## Step 3/7. Create a Database Service configuration + +(!docs/pages/includes/database-access/token.mdx!) + +Install Teleport on the host where you will run the Teleport Database Service: + +(!docs/pages/includes/install-linux.mdx!) + +Create the Database Service configuration: + + + + + + ```code + $ teleport db configure create \ + -o file \ + --proxy=teleport.example.com:3080 \ + --token=/tmp/token \ + --elasticache-discovery=us-west-1 + ``` + + + ```code + $ teleport db configure create \ + -o file \ + --proxy=teleport.example.com:3080 \ + --token=/tmp/token \ + --memorydb-discovery=us-west-1 + ``` + + + + + + + + + ```code + $ teleport db configure create \ + -o file \ + --proxy=mytenant.teleport.sh \ + --token=/tmp/token \ + --elasticache-discovery=us-west-1 + ``` + + + ``` + $ teleport db configure create \ + -o file \ + --proxy=mytenant.teleport.sh \ + --token=/tmp/token \ + --memorydb-discovery=us-west-1 + ``` + + + + + +The command will generate a Database Service configuration with ElastiCache or +MemoryDB database auto-discovery enabled on the `us-west-1` region and place it +at the `/etc/teleport.yaml` location. + +## Step 4/7. Create an IAM policy for Teleport + +Teleport needs AWS IAM permissions to be able to: + +- Discover and register ElastiCache and MemoryDB for Redis clusters. +- Modify ElastiCache and MemoryDB user passwords for Teleport-managed users. +- Save user passwords in AWS Secrets Manager for Teleport-managed users. + +(!docs/pages/includes/database-access/aws-bootstrap.mdx!) + +## Step 5/7. Start the Database Service + +Start the Database Service: + +```code +$ teleport start --config=/etc/teleport.yaml +``` + +The Database Service will discover and register all ElastiCache and MemoryDB +for Redis clusters according to the configuration. + +## Step 6/7. Create a Teleport-managed ElastiCache or MemoryDB user (optional) + +To provide better security, it is recommended to use [Redis +ACL](https://redis.io/docs/manual/security/acl/) for authentication with Redis +and let Teleport manage the users. The Teleport Database Service constantly +rotates any passwords managed by Teleport, saves these passwords in AWS Secrets +Manager, and automatically sends an `AUTH` command with the saved password when +connecting the client to the Redis server. + +To enable Redis ACL, please see [Authenticating users with Role-Based Access +Control for +ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/Clusters.RBAC.html) +and [Authenticating users with Access Control Lists for +MemoryDB](https://docs.aws.amazon.com/memorydb/latest/devguide/clusters.acls.html). + +Once an ElastiCache or MemoryDB user is created with the desired access, add an +AWS resource tag `teleport.dev/managed` with the value `true` to this user: + +![Managed User Tag](../../../img/database-access/guides/redis/redis-aws-managed-user-tag.png) + +The Database Service will automatically discover this user if it is associated +with a registered database. Keep in mind that it may take the Database Service +some time (up to 20 minutes) to discover this user once the tag is added. + +## Step 7/7. Connect + +Once the Database Service has started and joined the cluster, log in to see the +registered databases: + + +```code +$ tsh login --proxy=teleport.example.com --user=alice +$ tsh db ls +# Name Description Labels +# --------------------------- --------------------------------------------------------- -------- +# my-cluster-mode-elasticache ElastiCache cluster in us-west-1 (configuration endpoint) ... +# my-elasticache ElastiCache cluster in us-west-1 (primary endpoint) ... +# my-elasticache-reader ElastiCache cluster in us-west-1 (reader endpoint) ... +# my-memorydb MemoryDB cluster in us-west-1 ... +``` + + + + +```code +$ tsh login --proxy=mytenant.teleport.sh --user=alice +$ tsh db ls +# Name Description Labels +# --------------------------- --------------------------------------------------------- -------- +# my-cluster-mode-elasticache ElastiCache cluster in us-west-1 (configuration endpoint) ... +# my-elasticache ElastiCache cluster in us-west-1 (primary endpoint) ... +# my-elasticache-reader ElastiCache cluster in us-west-1 (reader endpoint) ... +# my-memorydb MemoryDB cluster in us-west-1 ... +``` + + + +To connect to a particular database, first retrieve its certificate using the +`tsh db login` command: + +```code +$ tsh db login --db-user=my-database-user my-elasticache +``` + +If flag `--db-user` is not provided, Teleport logs in as the `default` user. + + + You can be logged in to multiple databases simultaneously. + + +Once logged in, connect to the database: + +```code +$ tsh db connect my-elasticache +``` + +The `redis-cli` command-line client should be available in the system `PATH` in order to be +able to connect. + +Now, depending on the authentication configurations, you may need to send an +`AUTH` command to authenticate with the Redis server: + + + + The Database Service automatically authenticates Teleport-managed users + with the Redis server. No `AUTH` command is required after successful + connection. + + If you are connecting as a non-Teleport-mangaed user, the connection + normally starts as the `default` user. Now you can authenticate the + database user with its password: + + ``` + AUTH my-database-user + ``` + + + + Now you can authenticate with the shared AUTH token: + + ``` + AUTH + ``` + + + + For Redis deployments without the ACL system or legacy `requirepass` + directive enabled, no `AUTH` command is required. + + + + +To log out of the database and remove credentials: + +```code +# Remove credentials for a particular database instance. +$ tsh db logout my-elasticache +# Remove credentials for all database instances. +$ tsh db logout +``` + +## Next steps + +(!docs/pages/includes/database-access/guides-next-steps.mdx!) diff --git a/docs/pages/database-access/guides/snowflake.mdx b/docs/pages/database-access/guides/snowflake.mdx new file mode 100644 index 0000000000000..9ea6ee88695ef --- /dev/null +++ b/docs/pages/database-access/guides/snowflake.mdx @@ -0,0 +1,208 @@ +--- +title: Database Access with Snowflake +description: How to configure Teleport Database Access with Snowflake. +--- + +
    + Database access for Snowflake is available starting from Teleport `10.0`. +
    + +This guide will help you to: + +- Install and configure Teleport. +- Assign Teleport's public key to a Snowflake user. +- Connect to Snowflake through Teleport. + + + ![Teleport Database Access Snowflake Self-Hosted](../../../img/database-access/guides/snowflake_selfhosted.png) + + + + ![Teleport Database Access Snowflake Cloud](../../../img/database-access/guides/snowflake_cloud.png) + + +## Prerequisites + +- Snowflake account with `SECURITYADMIN` role or higher. + +- `snowsql` installed and added to your system's `PATH` environment variable. + +- A host where you will run the Teleport Database Service. Teleport version 10.0 or newer must be installed. + + See [Installation](../../installation.mdx) for details. + +(!docs/pages/includes/user-client-prereqs.mdx!) + +(!docs/pages/includes/tctl.mdx!) + +## Step 1/5. Install and configure Teleport + +### Set up the Teleport Auth and Proxy Services + +(!docs/pages/includes/database-access/start-auth-proxy.mdx!) + +### Set up the Teleport Database Service + +(!docs/pages/includes/database-access/token.mdx!) + +Install Teleport on the host where you will run the Teleport Database Service: + +(!docs/pages/includes/install-linux.mdx!) + + + + Start the Teleport Database Service, pointing the `--auth-server` flag to the + address of your Teleport Proxy Service: + + ```code + $ teleport db start \ + --token=/tmp/token \ + --auth-server=teleport.example.com:3080 \ + --name=example-snowflake \ + --protocol=Snowflake \ + --uri=https://abc123.us-east-2.aws.snowflakecomputing.com \ + --labels=env=dev + ``` + + + + The `--auth-server` flag must point to the Teleport cluster's Proxy Service + endpoint because the Database Service always connects back to the cluster over a + reverse tunnel. + + + + + + + Start the Teleport Database Service, pointing the `--auth-server` flag to the + address of your Teleport Cloud tenant: + + ```code + $ teleport db start \ + --token=/tmp/token \ + --auth-server=mytenant.teleport.sh:443 \ + --name=example-snowflake \ + --protocol=Snowflake \ + --uri=Snowflakes://Snowflake.example.com:6379 \ + --labels=env=dev + ``` + + + + + You can start the Database Service using a configuration file instead of CLI flags. + See the [YAML reference](../reference/configuration.mdx) for details. + + +## Step 2/5. Create a Teleport user + +(!docs/pages/includes/database-access/create-user.mdx!) + +## Step 3/5. Export a public key + +Use the `tctl auth sign` command below to export a public key for your Snowflake user: + +```code +$ tctl auth sign --format=snowflake --out=server +``` + +The command will create a `server.pub` file with Teleport's public key. Teleport will use the corresponding private key to +generate a JWT (JSON Web Token) that will be used to authenticate to Snowflake. + +(!docs/pages/includes/database-access/rotation-note.mdx!) + +## Step 4/5. Add the public key to your Snowflake user + +Use the public key you generated earlier to enable key pair authentication. + +Log in to your Snowflake instance and execute the SQL statement below: + +```sql +alter user alice set rsa_public_key='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3dHYw4LJCcZzdbhb3hV +... +LwIDAQAB'; +``` + +In this statement, `alice` is the name of the Snowflake user and the `rsa_public_key` is the key generated earlier without +the PEM header/footer (first and the last line). + +You can use the `describe user` command to verify the user's public key: + +```sql +desc user alice; +``` + +See the [Snowflake documentation](https://docs.snowflake.com/en/user-guide/key-pair-auth.html#step-4-assign-the-public-key-to-a-snowflake-user) +for more details. + +## Step 5/5. Connect + +Log in to your Teleport cluster and see the available databases: + + + + ```code + $ tsh login --proxy=teleport.example.com --user=alice + $ tsh db ls + # Name Description Labels + # ----------------- ------------------- -------- + # example-snowflake Example Snowflake ❄ env=dev + ``` + + + ```code + $ tsh login --proxy=mytenant.teleport.sh --user=alice + $ tsh db ls + # Name Description Labels + # ----------------- ------------------- -------- + # example-snowflake Example Snowflake ❄ env=dev + ``` + + + +To connect to a particular database instance, first retrieve its certificate +using the `tsh db login` command: + +```code +$ tsh db login example-snowflake +``` + + + You can be logged into multiple databases simultaneously. + + +You can optionally specify the user to use by default +when connecting to the database instance: + +```code +$ tsh db login --db-user=alice example-snowflake +``` + +Once logged in, connect to the database: + +```code +$ tsh db connect example-snowflake +``` + +The `snowsql` command-line client should be available in the system `PATH` in order to be +able to connect. + +To log out of the database and remove credentials: + +```code +# Remove credentials for a particular database instance. +$ tsh db logout example-snowflake +# Remove credentials for all database instances. +$ tsh db logout +``` + +## Next steps + +(!docs/pages/includes/database-access/guides-next-steps.mdx!) diff --git a/docs/pages/database-access/reference/aws.mdx b/docs/pages/database-access/reference/aws.mdx index 9bf906be356eb..7f116096f0b6f 100644 --- a/docs/pages/database-access/reference/aws.mdx +++ b/docs/pages/database-access/reference/aws.mdx @@ -5,10 +5,14 @@ description: AWS IAM policies for Teleport database access. ## Auto-discovery With the appropriate IAM permissions, Teleport automatically discovers and -configures IAM policies for Amazon RDS and Redshift. +configures IAM policies for Amazon RDS and Redshift. Teleport also requires +permission to update database configurations, for example, to enable IAM +authentication on RDS databases. -Teleport also requires permission to update database configurations, for example, to -enable IAM authentication on RDS databases. +For Amazon ElastiCache and MemoryDB, Teleport requires permission to +automatically discover the Redis clusters. Teleport also requires permission to +automatically discover and modify any Teleport-managed ElastiCache or MemoryDB +users and permission to manage the passwords in AWS Secrets Manager. You can generate and manage the permissions with the [`teleport db configure bootstrap`](../../database-access/reference/cli.mdx#teleport-db-configure-bootstrap) @@ -19,8 +23,8 @@ IAM policies: $ teleport db configure bootstrap --manual ``` -Or if you prefer, you manage the IAM permissions yourself. Examples of policies -for each discovery type are shown below. +Or if you prefer, you can manage the IAM permissions yourself. Examples of +policies for each discovery type are shown below. ### Aurora/RDS @@ -29,7 +33,7 @@ for each discovery type are shown below. Use this policy if you're connecting to RDS instances and your Teleport database agent runs as an IAM user (for example, uses an AWS credentials file). - Replace `{account-id}` with your AWS Account ID. + Replace `{account-id}` with your AWS Account ID: ```json { "Version": "2012-10-17", @@ -60,7 +64,7 @@ for each discovery type are shown below. database agent runs as an IAM role (for example, on an EC2 instance with an attached IAM role). - Replace `{account-id}` with your AWS Account ID. + Replace `{account-id}` with your AWS Account ID: ```json { "Version": "2012-10-17", @@ -90,7 +94,7 @@ for each discovery type are shown below. Use this policy if you're connecting to Aurora clusters and your Teleport database agent runs as an IAM user (for example, uses an AWS credentials file). - Replace `{account-id}` with your AWS Account ID. + Replace `{account-id}` with your AWS Account ID: ```json { "Version": "2012-10-17", @@ -121,7 +125,7 @@ for each discovery type are shown below. database agent runs as an IAM role (for example, on an EC2 instance with an attached IAM role). - Replace `{account-id}` with your AWS Account ID. + Replace `{account-id}` with your AWS Account ID: ```json { "Version": "2012-10-17", @@ -156,7 +160,7 @@ for each discovery type are shown below. Use this permission boundary if your Teleport database agent runs as an IAM user (for example, it uses an AWS credentials file). - Replace `{account-id}` with your AWS Account ID. + Replace `{account-id}` with your AWS Account ID: ```json { "Version": "2012-10-17", @@ -186,7 +190,7 @@ for each discovery type are shown below. Use this permission boundary if your Teleport database agent runs as an IAM role (for example, on an EC2 instance with an attached IAM role). - Replace `{account-id}` with your AWS Account ID. + Replace `{account-id}` with your AWS Account ID: ```json { "Version": "2012-10-17", @@ -214,9 +218,99 @@ for each discovery type are shown below.
    +### ElastiCache/MemoryDB + +In addition to database discovery, Teleport requires permissions to modify user +passwords, and save passwords in AWS Secrets Manager, if any ElastiCache or +MemoryDB users are tagged to be managed by Teleport. + + + + Use this policy if you are connecting to ElastiCache clusters. + + Replace `{account-id}` with your AWS Account ID: + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "elasticache:ListTagsForResource", + "elasticache:DescribeReplicationGroups", + "elasticache:DescribeCacheClusters", + "elasticache:DescribeCacheSubnetGroups", + "elasticache:DescribeUsers", + "elasticache:ModifyUser" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:CreateSecret", + "secretsmanager:UpdateSecret", + "secretsmanager:DeleteSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:TagResource" + ], + "Resource": [ + "arn:aws:secretsmanager:*:{account-id}:secret:teleport/*" + ] + } + ] + } + ``` + + + Use this policy if you are connecting to MemoryDB clusters. + + Replace `{account-id}` with your AWS Account ID: + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "memorydb:ListTags", + "memorydb:DescribeClusters", + "memorydb:DescribeSubnetGroups", + "memorydb:DescribeUsers", + "memorydb:UpdateUser" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:CreateSecret", + "secretsmanager:UpdateSecret", + "secretsmanager:DeleteSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:TagResource" + ], + "Resource": [ + "arn:aws:secretsmanager:*:{account-id}:secret:teleport/*" + ] + } + ] + } + ``` + + + ## Manual registration -If you prefer to register RDS or Redshift databases manually using a [static -configuration](./configuration.mdx) or +If you prefer to register RDS, Redshift, ElastiCache or MemoryDB databases +manually using a [static configuration](./configuration.mdx) or [`tctl`](../guides/dynamic-registration.mdx) and manage IAM yourself, example IAM policies with the required permissions are shown below. @@ -308,3 +402,128 @@ See [Create an IAM role or user with permissions to call GetClusterCredentials](https://docs.aws.amazon.com/redshift/latest/mgmt/generating-iam-credentials-role-permissions.html) for more information. +### ElastiCache/MemoryDB policy + +If any ElastiCache or MemoryDB users are tagged to be managed by Teleport, +below are the IAM permissions required for managing the ElastiCache or MemoryDB +users. Otherwise, no additional IAM permissions are required. + + + + Use this policy for managing ElastiCache users. + + Replace `{account-id}` with your AWS Account ID: + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "elasticache:ListTagsForResource", + "elasticache:DescribeReplicationGroups", + "elasticache:DescribeUsers", + "elasticache:ModifyUser" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:CreateSecret", + "secretsmanager:UpdateSecret", + "secretsmanager:DeleteSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:TagResource" + ], + "Resource": [ + "arn:aws:secretsmanager:*:{account-id}:secret:teleport/*" + ] + } + ] + } + ``` + + + Use this policy for managing MemoryDB users. + + Replace `{account-id}` with your AWS Account ID: + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "memorydb:ListTags", + "memorydb:DescribeClusters", + "memorydb:DescribeUsers", + "memorydb:UpdateUser" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:CreateSecret", + "secretsmanager:UpdateSecret", + "secretsmanager:DeleteSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:TagResource" + ], + "Resource": [ + "arn:aws:secretsmanager:*:{account-id}:secret:teleport/*" + ] + } + ] + } + ``` + + + +If any custom key prefix or KMS key ID is used in the static configuration, add +the following to the IAM policy. + +Replace `{account-id}`, `{my-prefix}` and `{my-kms-id}` accordingly: + +``` +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:CreateSecret", + "secretsmanager:UpdateSecret", + "secretsmanager:DeleteSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:TagResource" + ], + "Resource": [ + "arn:aws:secretsmanager:*:{account-id}:secret:{my-prefix}/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "kms:GenerateDataKey", + "kms:Decrypt" + ], + "Resource": [ + "arn:aws:kms:*:{account-id}:key/{my-kms-id}", + ] + } + ] +} +``` + diff --git a/docs/pages/database-access/reference/cli.mdx b/docs/pages/database-access/reference/cli.mdx index 1dd0f9ddb0e84..7503cb67576e9 100644 --- a/docs/pages/database-access/reference/cli.mdx +++ b/docs/pages/database-access/reference/cli.mdx @@ -103,11 +103,13 @@ $ teleport db configure create \ | - | - | | `--proxy` | Teleport Proxy Service address to connect to. Default: `0.0.0.0:3080`. | | `--token` | Invitation token to register with the Auth Service. Default: none. | -| `--rds-discovery` | List of AWS regions the agent will discover for RDS/Aurora instances. | -| `--redshift-discovery` | List of AWS regions the agent will discover for Redshift instances. | +| `--rds-discovery` | List of AWS regions in which the agent will discover RDS/Aurora instances. | +| `--redshift-discovery` | List of AWS regions in which the agent will discover Redshift instances. | +| `--elasticache-discovery` | List of AWS regions in which the agent will discover ElastiCache Redis clusters. | +| `--memorydb-discovery` | List of AWS regions in which the agent will discover MemoryDB clusters. | | `--ca-pin` | CA pin to validate the Auth Service (can be repeated for multiple pins). | | `--name` | Name of the proxied database. | -| `--protocol` | Proxied database protocol. Supported are: `[postgres mysql mongodb cockroachdb redis sqlserver]`. | +| `--protocol` | Proxied database protocol. Supported are: `[postgres mysql mongodb cockroachdb redis sqlserver snowflake]`. | | `--uri` | Address the proxied database is reachable at. | | `--labels` | Comma-separated list of labels for the database, for example env=dev,dept=it | | `-o/--output` | Write to stdout with `-o=stdout`, the default config file with `-o=file`, or a custom path with `-o=file:///path` | diff --git a/docs/pages/database-access/reference/configuration.mdx b/docs/pages/database-access/reference/configuration.mdx index 3cdf32e3a035c..0378cf2ef4b2a 100644 --- a/docs/pages/database-access/reference/configuration.mdx +++ b/docs/pages/database-access/reference/configuration.mdx @@ -171,8 +171,9 @@ assume that you have created a YAML file called `db.yaml` with your configuratio ```code -# Log in to your Teleport cluster. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser # Create the resource $ tctl create -f db.yaml @@ -182,7 +183,7 @@ $ tctl create -f db.yaml ```code -# Log in to your Teleport cluster +# Log in to your Teleport cluster so you can use tctl from your local machine. $ tsh login --proxy=mytenant.teleport.sh --user=myuser # Create the resource $ tctl create -f db.yaml diff --git a/docs/pages/desktop-access/rbac.mdx b/docs/pages/desktop-access/rbac.mdx index 2290ce89ee716..655116b843315 100644 --- a/docs/pages/desktop-access/rbac.mdx +++ b/docs/pages/desktop-access/rbac.mdx @@ -24,7 +24,7 @@ spec: # Desktop sessions will never be recorded if auth_service.session_recording # is set to 'off' in teleport.yaml or if the cluster's session_recording_config # resource has set 'mode: off'. - record_sessions: + record_session: desktop: true # Specify whether clipboard sharing should be allowed with the @@ -152,7 +152,7 @@ By default, desktop session recording is considered enabled in Teleport roles unless it is explicitly disabled: ```yaml -record_sessions: +record_session: desktop: false ``` diff --git a/docs/pages/desktop-access/troubleshooting.mdx b/docs/pages/desktop-access/troubleshooting.mdx index 5be26057a0fbc..131b4835c7633 100644 --- a/docs/pages/desktop-access/troubleshooting.mdx +++ b/docs/pages/desktop-access/troubleshooting.mdx @@ -50,8 +50,9 @@ new CA using the following command: ```code -# Log in to your Teleport cluster so you can use tctl remotely. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser $ tctl auth export --type=windows >user-ca.cer ``` @@ -112,23 +113,6 @@ instance(s) running Teleport's Windows Desktop Service to the LDAP server ## Teleport fails to start -### Invalid LDAP Credentials - -Teleport fails to start with an error similar to: - -```text -LDAP Result Code 49 "Invalid Credentials": 80090308: LdapErr: DSID-0C0903C5, comment: AcceptSecurityContext error, data 52e, v2580\x00 -``` - -**Solution:** Fix Credentials - -This means that your LDAP username and password were not correct. Double-check -them in the `ldap` section of `windows_desktop_service`. - -Note that the LDAP username must be formatted as `DOMAIN\User`, where `DOMAIN` -is the NetBIOS name for the domain. For example, user `Administrator` in domain -`example.com` should be formatted as `EXAMPLE\Administrator`. - ### Incorrect Domain Teleport fails to start with an error similar to: @@ -186,3 +170,70 @@ issue, you can your own third party certificate. Note that Active Directory is [extremely picky](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/enable-ldap-over-ssl-3rd-certification-authority#requirements-for-an-ldaps-certificate) so take care to generate your certificates correctly. + +## Desktops are not discovered via LDAP + +### LDAP not yet initialized + +Teleport is running, but desktops do not show up in the Web UI. The logs contain +errors similar to: + +``` +skipping desktop discovery: LDAP not yet initialized +``` + +**Solution:** Confirm Teleport certificate is installed + +The Teleport Desktop Service uses a Teleport-issued certificate to authenticate +with the LDAP server. This error occurs when Teleport is unable to authenticate, +which is often due to its certificate authority not being trusted by Active +Directory. + +First, verify that the Teleport CA is present in the LDAP NTAuth store. Run the +following command, modifying the DN for your domain (in this command we use a +domain of example.com) + +``` +$ certutil -viewstore "ldap:///CN=NTAuthCertificates,CN=Public Key Services,CN=Configuration,DC=example,DC=com?caCertificate" +``` + +You should see a popup window that shows the Teleport CA certificate. If the +Teleport certificate is not present, import it with: + +``` +$ certutil -dspublish -f NTAuthCA +``` + +Once you've verified that the Teleport certificate is present in LDAP, you +should check whether it has propagated to all desktops. From a desktop that you +would like to connect to, run the following: + +``` +$ certutil -viewstore -enterprise NTAuth +``` + +If the popup window does not show the Teleport certificate, and it was present +in LDAP, you can force the desktop to sync with the following command: + +``` +$ certutil -pulse +``` + +## Connection attempts fail + +### Enhanced RDP security with CredSSP required + +Attempts to connect to a desktop fail, and the logs show an error similar to: + +``` +Error during negotiation step: the server requires that the client support enhanced RDP security with CredSSP +``` + +**Solution:** Disable NLA + +This means that the RDP server is requiring Network Level Authentication (NLA). +Teleport currently requires that NLA is disabled in order to perform its +certificate-based passwordless login. + +To disable NLA, follow the instructions in our +[Getting Started Guide](./getting-started.mdx#allow-remote-rdp-connections). \ No newline at end of file diff --git a/docs/pages/enterprise/fedramp.mdx b/docs/pages/enterprise/fedramp.mdx index c02395654ff3e..73ce2de558562 100644 --- a/docs/pages/enterprise/fedramp.mdx +++ b/docs/pages/enterprise/fedramp.mdx @@ -6,20 +6,6 @@ description: How to configure SSH, Kubernetes, database, and web app access to b Teleport provides the foundation to meet FedRAMP requirements for the purposes of accessing infrastructure. This includes support for [FIPS 140-2](https://en.wikipedia.org/wiki/FIPS\_140-2), also known as the Federal Information Processing Standard, which is the US government approved standard for cryptographic modules. This document outlines a high level overview of how Teleport FIPS mode works and how it can help your company to become FedRAMP certified. - - -This guide is intended for Teleport Enterprise users. - - - - - - - - - - - ### Obtain FedRAMP certification with Teleport Teleport includes new FedRAMP and FIPS 140-2 features to support companies that sell into @@ -31,7 +17,7 @@ government agencies. | [AC-10 Concurrent Session Control]((=fedramp.control_url=)AC-10) | Teleport administrators can define concurrent session limits using Teleport’s RBAC. | | [AC-17 Remote Access]((=fedramp.control_url=)AC-17) | Teleport administrators create users with configurable roles that can be used to allow or deny access to system resources. | | [AC-20 Use of External Information Systems]((=fedramp.control_url=)AC-20) | Teleport supports connecting multiple independent clusters using a feature called [Trusted Clusters](../setup/admin/trustedclusters.mdx). When allowing access from one cluster to another, roles are mapped according to a pre-defined relationship of the scope of access. | -| [AU-03 Audit and Accountability]((=fedramp.control_url=)AU-3) – Content of Audit Records and [AU-12 Audit Generation]((=fedramp.control_url=)AU-12) | Teleport contains an [Audit Log](../architecture/authentication.mdx#audit-log) that records cluster-wide events such as:
    • Failed login attempts.
    • Commands that were executed (SSH “exec” commands).
    • Ports that were forwarded.
    • File transfers that were initiated. | +| [AU-03 Audit and Accountability]((=fedramp.control_url=)AU-3) – Content of Audit Records and [AU-12 Audit Generation]((=fedramp.control_url=)AU-12) | Teleport contains an [Audit Log](../setup/reference/audit.mdx) that records cluster-wide events such as:
    • Failed login attempts.
    • Commands that were executed (SSH “exec” commands).
    • Ports that were forwarded.
    • File transfers that were initiated. | | [AU-10 Non-Repudiation]((=fedramp.control_url=)AU-10) | Teleport audit logging supports both events as well as audit of an entire SSH session. For non-repudiation purposes a full session can be replayed back and viewed. | | [CM-08 Information System Component Inventory]((=fedramp.control_url=)CM-8) | Teleport maintains a live list of all nodes within a cluster. This node list can be queried by users (who see a subset they have access to) and administrators any time. | | [IA-03 Device Identification and Authentication]((=fedramp.control_url=)IA-3) | Teleport requires valid x509 or SSH certificates issued by a Teleport Certificate Authority (CA) to establish a network connection for device-to-device network connection between Teleport components. | @@ -158,5 +144,3 @@ is emitted to the Audit Log. - Removes all uses of non-compliant algorithms like NaCl and replace with compliant algorithms like AES-GCM. - Teleport is compiled with [BoringCrypto](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3678) - User, host and CA certificates (and host keys for recording proxy mode) should only use 2048-bit RSA private keys. - -
    \ No newline at end of file diff --git a/docs/pages/enterprise/getting-started.mdx b/docs/pages/enterprise/getting-started.mdx index 4794b0a1d0c28..fbc3ac23c6ba0 100644 --- a/docs/pages/enterprise/getting-started.mdx +++ b/docs/pages/enterprise/getting-started.mdx @@ -6,20 +6,6 @@ h1: Teleport Enterprise Quick Start This guide shows you how to get up and running with Teleport Enterprise. - - -This guide is intended for Teleport Enterprise users. - - - - - - - - - - - There are three types of services Teleport can run: - **Auth Service** stores user accounts and provides authentication and @@ -91,7 +77,7 @@ and save it as `/var/lib/teleport/license.pem` on the auth server. ### Systemd Unit File -Next, download the systemd service unit file from [examples directory](https://github.com/gravitational/teleport/tree/master/examples/systemd) +Download the systemd unit file for Teleport from the [examples directory](https://github.com/gravitational/teleport/tree/v(=teleport.version=)/examples/systemd) on GitHub and save it as `/etc/systemd/system/teleport.service` on both servers. ```code @@ -325,16 +311,22 @@ store it in `~/.tsh/keys/` directory. With a certificate in place, Joe can now interact with the Teleport cluster: ```code -# SSH into any host behind the proxy (Unix user 'joe' should already exist on the node): -$ tsh ssh joe@node.example.com - # See what hosts are available behind the proxy: $ tsh ls +# SSH into any host behind the proxy (Unix user 'joe' should already exist on the node): +$ tsh ssh joe@node.example.com + # Log out (this will remove the user certificate from ~/.tsh) $ tsh logout ``` +
    + +(!docs/pages/includes/node-logins.mdx!) + +
    + ## Configuring SSO The local account is good for administrative purposes but regular users of @@ -379,11 +371,15 @@ We currently only offer Docker images for `x86_64` architectures. You will need a recent version of [`docker-compose`](https://docs.docker.com/compose/install/) installed to follow this section of the quick start guide.
    -The easiest way to start Teleport Enterprise quickly is to use `docker-compose` with our [`teleport-ent-quickstart.yml`](https://github.com/gravitational/teleport/blob/master/docker/teleport-ent-quickstart.yml) file: +The easiest way to start Teleport Enterprise quickly is to use `docker-compose` with our [`teleport-ent-quickstart.yml`](https://github.com/gravitational/teleport/blob/v(=teleport.version=)/docker/teleport-ent-quickstart.yml) file: ```code -# download the quickstart file from our GitHub repo -$ curl -Lso teleport-ent-quickstart.yml https://raw.githubusercontent.com/gravitational/teleport/master/docker/teleport-ent-quickstart.yml +# Download your license file from the Gravitational dashboard and put it in the correct directory. +# The file needs to be named "license.pem". +$ cp ~/downloads/license.pem . + +# Download the quickstart file from our GitHub repo +$ curl -Lso teleport-ent-quickstart.yml https://raw.githubusercontent.com/gravitational/teleport/v(=teleport.version=)/docker/teleport-ent-quickstart.yml # start teleport quickstart using docker-compose $ docker-compose -f teleport-ent-quickstart.yml up @@ -407,7 +403,7 @@ $ mkdir -p ~/teleport/config ~/teleport/data # download your license file from the Gravitational dashboard and put it in the correct directory # the file needs to be named license.pem -$ cp ~/downloads/downloaded-license.pem ~/teleport/data/license.pem +$ cp ~/downloads/license.pem ~/teleport/data/license.pem # generate a sample teleport config and write it to the local config directory # this container will write the config and immediately exit - this is expected @@ -470,4 +466,3 @@ If something is not working, please reach out to us by creating a ticket in your Customers who have purchased the premium support package can also ping us through your Slack channel. -
    \ No newline at end of file diff --git a/docs/pages/enterprise/hsm.mdx b/docs/pages/enterprise/hsm.mdx index b14bbe9a72c11..2925b93d28cc2 100644 --- a/docs/pages/enterprise/hsm.mdx +++ b/docs/pages/enterprise/hsm.mdx @@ -11,16 +11,8 @@ hardware security module (HSM) to store and handle private keys. This guide is intended for Teleport Enterprise users. - - - - - -
    - - ## Prerequisites - Teleport v(=teleport.version=) Enterprise (self-hosted). @@ -36,7 +28,6 @@ This guide is intended for Teleport Enterprise users. Teleport Cloud and Teleport Open Source do not currently support HSM. -You can view this guide as a [Teleport Enterprise user](./hsm.mdx/?scope=enterprise). While most PKCS#11 HSMs should be supported, the Teleport team tests with AWS @@ -227,4 +218,3 @@ You are all set! Check the teleport logs for `Creating new HSM key pair` to confirm that the feature is working. You can also check that keys were created in your HSM using your HSM's admin tool. - \ No newline at end of file diff --git a/docs/pages/enterprise/introduction.mdx b/docs/pages/enterprise/introduction.mdx index 95020edf9c453..fc770c4f14da7 100644 --- a/docs/pages/enterprise/introduction.mdx +++ b/docs/pages/enterprise/introduction.mdx @@ -8,7 +8,7 @@ Teleport Enterprise is a commercial product built around Teleport's open source core. For those that want to jump right in, you can play with the -[Getting Started Guide for Teleport Enterprise](getting-started.mdx/?scope=enterprise). +[Getting Started Guide for Teleport Enterprise](getting-started.mdx). The table below gives a quick overview of the benefits of Teleport Enterprise. @@ -17,6 +17,8 @@ The table below gives a quick overview of the benefits of Teleport Enterprise. | [Single Sign-On (SSO)](#sso) | Allows Teleport to integrate with existing enterprise identity systems. Examples include Active Directory, GitHub, Google Apps and numerous identity middleware solutions like Auth0, Okta, and so on. Teleport supports SAML and OAuth/OpenID Connect protocols to interact with them. | | [Access Requests](workflow/index.mdx) | User interface for teams to create and review requests to access infrastructure with escalated privileges. | | [FedRAMP/FIPS](#fedrampfips) | Access controls to meet the requirements in a FedRAMP System Security Plan (SSP). This includes a FIPS 140-2 friendly build of Teleport Enterprise as well as a variety of improvements to aid in complying with security controls even in FedRAMP High environments. | +| [Hardware Security Module support](./hsm.mdx)|The Teleport Auth Service can use your organization's HSM to generate TLS credentials, ensuring a highly reliable and secure public key infrastructure.| +| [Moderated Sessions](../access-controls/guides/moderated-sessions.mdx)|Allow or require moderators to be present in SSH or Kubernetes sessions.| | Commercial Support | Support SLA with guaranteed response times. | - -This guide is intended for Teleport Enterprise users. - - - -Teleport Cloud manages licensing for customers, and there is no need to manage -license files yourself. - - - - - - - - - -
    - - - Commercial self-hosted Teleport subscriptions require a valid license. The license file can be downloaded from the [Teleport Customer Portal](https://dashboard.gravitational.com/web/login). When downloading the @@ -51,5 +30,3 @@ Attempts to use unlicensed products will result in an error message and users wi ```code this Teleport cluster is not licensed for database access, please contact the cluster administrator ``` - - \ No newline at end of file diff --git a/docs/pages/enterprise/soc2.mdx b/docs/pages/enterprise/soc2.mdx index 1c23eebc2b2d3..ced5ca3ad4c15 100644 --- a/docs/pages/enterprise/soc2.mdx +++ b/docs/pages/enterprise/soc2.mdx @@ -13,19 +13,8 @@ level overview of how Teleport can be used to help your company to become SOC2 c This guide requires Teleport Cloud or Teleport Enterprise. - View this guide as the user of another Teleport edition: - - - - - - - -
    - - ## Achieving SOC2 Compliance with Teleport SOC2 or Service Organization Controls were developed by the American Institute of CPAs (AICPA). They are based on five trust service areas: security, availability, processing integrity, confidentiality and privacy. @@ -65,7 +54,7 @@ Each principle has many “Points of Focus” which will apply differently to di | CC6.1 - Identifies and Authenticates Users | Persons, infrastructure, and software are identified and authenticated prior to accessing information assets, whether locally or remotely. | Provide role-based access controls (RBAC) using short-lived certificates and your existing identity management service. Connecting locally or remotely is just as easy. | | CC6.1 - Considers Network Segmentation | Network segmentation permits unrelated portions of the entity's information system to be isolated from each other. | [Teleport enables beyond corp network segmentation](../setup/admin/trustedclusters.mdx) | [Connect to nodes behind Firewalls or create reverse tunnels to a proxy server](../faq.mdx#can-i-connect-to-nodes-behind-a-firewall) | | | | | CC6.1 - Manages Points of Access | Points of access by outside entities and the types of data that flow through the points of access are identified, inventoried, and managed. The types of individuals and systems using each point of access are identified, documented, and managed. | [Label Nodes to inventory and create rules](../setup/admin/labels.mdx) | [Create Labels from AWS Tags](../setup/guides/ec2-tags.mdx) | Teleport maintains a live list of all nodes within a cluster. This node list can be queried by users (who see a subset they have access to) and administrators any time. | | | -| CC6.1 - Restricts Access to Information Assets | Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access-control rules for information assets. | [Teleport uses Certificates to grant access and create access control rules](../architecture/overview.mdx#4-authenticate-node-certificate) | +| CC6.1 - Restricts Access to Information Assets | Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access-control rules for information assets. | [Teleport uses Certificates to grant access and create access control rules](../architecture/overview.mdx) | | CC6.1 - Manages Identification and Authentication | Identification and authentication requirements are established, documented, and managed for individuals and systems accessing entity information, infrastructure, and software. | Teleport makes setting policies for SSH requirements easy since it works in the cloud and on premise with the same authentication security standards. | | CC6.1 - Manages Credentials for Infrastructure and Software | New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use. | [Invite nodes to your cluster with short lived tokens](../setup/admin/adding-nodes.mdx) | | CC6.1 - Uses Encryption to Protect Data | The entity uses encryption to supplement other measures used to protect data at rest, when such protections are deemed appropriate based on assessed risk. | Teleport Audit logs can use DynamoDB encryption at rest. | @@ -84,7 +73,7 @@ Each principle has many “Points of Focus” which will apply differently to di | CC6.7 - Uses Encryption Technologies or Secure Communication Channels to Protect Data | Encryption technologies or secured communication channels are used to protect transmission of data and other communications beyond connectivity access points. | [Teleport has strong encryption including a FedRAMP compliant FIPS mode](./fedramp.mdx#starting-teleport-in-fips-mode) | | CC7.2 - Implements Detection Policies, Procedures, and Tools | Processes are in place to detect changes to software and configuration parameters that may be indicative of unauthorized or malicious software. | [Teleport creates detailed SSH Audit Logs with Metadata](../setup/reference/audit.mdx) | [Use BPF Session Recording to catch malicious program execution](../server-access/guides/bpf-session-recording.mdx) | | | | | CC7.2 - Designs Detection Measures | Detection measures are designed to identify anomalies that could result from actual or attempted (1) compromise of physical barriers; (2) unauthorized actions of authorized personnel; (3) use of compromised identification and authentication credentials; (4) unauthorized access from outside the system boundaries; (5) compromise of authorized external parties; and (6) implementation or connection of unauthorized hardware and software. | [Use Enhanced Session Recording to catch malicious program execution, capture TCP connections and log programs accessing files on the system the should not be accessing.](../server-access/guides/bpf-session-recording.mdx) | -| CC7.3 - Communicates and Reviews Detected Security Events | Detected security events are communicated to and reviewed by the individuals responsible for the management of the security program and actions are taken, if necessary. | [Use Session recording to replay and review suspicious sessions](../architecture/nodes.mdx#session-recording). | +| CC7.3 - Communicates and Reviews Detected Security Events | Detected security events are communicated to and reviewed by the individuals responsible for the management of the security program and actions are taken, if necessary. | [Use Session recording to replay and review suspicious sessions](../architecture/nodes.mdx#ssh-session-recording). | | CC7.3 - Develops and Implements Procedures to Analyze Security Incidents | Procedures are in place to analyze security incidents and determine system impact. | [Analyze detailed logs and replay recorded sessions to determine impact. See exactly what files were accessed during an incident.](../server-access/guides/bpf-session-recording.mdx) | | CC7.4 - Contains Security Incidents | Procedures are in place to contain security incidents that actively threaten entity objectives. | [Use Teleport to quickly revoke access and contain an active incident](../access-controls/guides/locking.mdx) | [Use Shared Sessions so Multiple On-Call Engineers can collaborate and fight fires together.](../server-access/guides/tsh.mdx#sharing-sessions) | | | | | CC7.4 - Ends Threats Posed by Security Incidents | Procedures are in place to mitigate the effects of ongoing security incidents. | [Use Teleport to quickly revoke access and contain an active incident](../access-controls/guides/locking.mdx) | @@ -93,5 +82,3 @@ Each principle has many “Points of Focus” which will apply differently to di | CC7.4 - Periodically Evaluates Incidents | Periodically, management reviews incidents related to security, availability, processing integrity, confidentiality, and privacy and identifies the need for system changes based on incident patterns and root causes. | [Use Session recording and audit logs to find patterns that lead to incidents.](../server-access/guides/bpf-session-recording.mdx) | | CC7.5 - Determines Root Cause of the Event | The root cause of the event is determined. | [Use Session recording and audit logs to find root cause.](../server-access/guides/bpf-session-recording.mdx) | | CC7.5 - Improves Response and Recovery Procedures | Lessons learned are analyzed and the incident-response plan and recovery procedures are improved. | [Replay Session recordings at your 'after action review' or postmortem meetings](../server-access/guides/bpf-session-recording.mdx) | - - \ No newline at end of file diff --git a/docs/pages/enterprise/sso.mdx b/docs/pages/enterprise/sso.mdx index bd36dd414ddf5..5141af741a7ad 100644 --- a/docs/pages/enterprise/sso.mdx +++ b/docs/pages/enterprise/sso.mdx @@ -8,27 +8,6 @@ Users of the Enterprise edition of Teleport can log in to servers, Kubernetes clusters, databases, web applications, and Windows desktops through their organization's Single Sign-On (SSO) provider. - - - - Learn how to use Teleport's SSO integrations in Teleport Cloud. - - - Learn how to use Teleport's SSO integrations in Teleport Enterprise. - - - - - - Configure Azure Active Directory SSO for SSH, Kubernetes, databases, desktops and web apps. @@ -382,22 +361,13 @@ Example of a user being denied because the role `clusteradmin` wasn't set up: ### Teleport does not show the expected Nodes -When Teleport's Auth Service receives a request to list Teleport Nodes, -it only returns the Nodes that a user is authorized to access. - -A user's Teleport roles must grant the user explicit access to Nodes with a particular label - before the user can view those Nodes. The Auth Service compares the user's -`traits.logins` with the `allow` and `deny` rules defined in each of the user's roles. -If the user's logins match a role's `allow` and `deny` rules, and a Node's labels match -the keys and values listed within a role's `node_labels` field, then the Auth Service will -list the Node in response to the user's request. +(!docs/pages/includes/node-logins.mdx!) When configuring SSO, ensure that the identity provider is populating each user's traits correctly. For a user to see a Node in Teleport, the result of populating a template variable in a role's `allow.logins` must match at least one of a user's `traits.logins`. - In this example a user will have usernames `ubuntu`, `debian` and usernames from the SSO trait `logins` for Nodes that have a `env: dev` label. If the SSO trait username is `bob` then the usernames would include `ubuntu`, `debian`, and `bob`. ```yaml @@ -411,4 +381,3 @@ spec: 'env': 'dev' version: v5 ``` - diff --git a/docs/pages/enterprise/sso/adfs.mdx b/docs/pages/enterprise/sso/adfs.mdx index cf941b28de241..44bfd21d7012b 100644 --- a/docs/pages/enterprise/sso/adfs.mdx +++ b/docs/pages/enterprise/sso/adfs.mdx @@ -13,26 +13,6 @@ like: - Only members of "DBA" group can SSH into machines running PostgreSQL. - Developers must never SSH into production servers. -- ... and many others. - - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - ## Prerequisites @@ -207,5 +187,3 @@ automatically in a browser. ## Troubleshooting (!docs/pages/includes/sso/loginerrortroubleshooting.mdx!) - - diff --git a/docs/pages/enterprise/sso/azuread.mdx b/docs/pages/enterprise/sso/azuread.mdx index 62c4871a9735b..9624d9c4d34e1 100644 --- a/docs/pages/enterprise/sso/azuread.mdx +++ b/docs/pages/enterprise/sso/azuread.mdx @@ -12,25 +12,6 @@ SSH credentials to specific groups of users with a SAML Authentication Connector The following steps configure an example SAML authentication connector matching Azure AD groups with security roles. You can choose to configure other options. - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - - ## Prerequisites Before you get started you’ll need: @@ -404,4 +385,3 @@ Change the Name ID format to use email instead: ## Further reading - [Teleport Configuration Resources Reference](../../setup/reference/resources.mdx) - \ No newline at end of file diff --git a/docs/pages/enterprise/sso/gitlab.mdx b/docs/pages/enterprise/sso/gitlab.mdx index d0eb57efb2b1b..1140a2cf481e9 100644 --- a/docs/pages/enterprise/sso/gitlab.mdx +++ b/docs/pages/enterprise/sso/gitlab.mdx @@ -15,25 +15,6 @@ like: - Only members of "ProductionKubernetes" can access production Kubernetes clusters - Developers must never SSH into production servers. - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - - ## Prerequisites - At least two groups in GitLab with users assigned. @@ -201,4 +182,3 @@ automatically in a browser). (!docs/pages/includes/sso/loginerrortroubleshooting.mdx!) - \ No newline at end of file diff --git a/docs/pages/enterprise/sso/google-workspace.mdx b/docs/pages/enterprise/sso/google-workspace.mdx index 19b9410aa0c3b..be579c1dab2ff 100644 --- a/docs/pages/enterprise/sso/google-workspace.mdx +++ b/docs/pages/enterprise/sso/google-workspace.mdx @@ -12,26 +12,6 @@ to define policies like: - Only members of "DBA" Google group can SSH into machines running PostgreSQL. - Developers must never SSH into production servers. -- ... and many others. - - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - ## Prerequisites @@ -321,4 +301,3 @@ automatically in a browser). - [Google Workspace Directory API](https://developers.google.com/admin-sdk/directory) - [How nested Google Workspace groups work](https://support.google.com/a/answer/167100?hl=en) - \ No newline at end of file diff --git a/docs/pages/enterprise/sso/oidc.mdx b/docs/pages/enterprise/sso/oidc.mdx index ea29a46334946..0a20773cd305d 100644 --- a/docs/pages/enterprise/sso/oidc.mdx +++ b/docs/pages/enterprise/sso/oidc.mdx @@ -11,26 +11,6 @@ administrators to define policies like: - Only members of "DBA" group can SSH into machines running PostgreSQL. - Developers must never SSH into production servers. -- ... and many others. - - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - ## Prerequisites @@ -90,8 +70,9 @@ Create the connector: ```code -# Log in to your Teleport cluster so you can use tctl remotely. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser $ tctl create oidc-connector.yaml ``` @@ -100,7 +81,7 @@ $ tctl create oidc-connector.yaml ```code -# Log in to your Teleport cluster so you can use tctl remotely +# Log in to your Teleport cluster so you can use tctl remotely. $ tsh login --proxy=mytenant.teleport.sh --user=myuser $ tctl create oidc-connector.yaml ``` @@ -259,4 +240,3 @@ identity provider if you are not automatically redirected. (!docs/pages/includes/sso/loginerrortroubleshooting.mdx!) - \ No newline at end of file diff --git a/docs/pages/enterprise/sso/okta.mdx b/docs/pages/enterprise/sso/okta.mdx index d748bab651589..3dcde77bbad49 100644 --- a/docs/pages/enterprise/sso/okta.mdx +++ b/docs/pages/enterprise/sso/okta.mdx @@ -15,25 +15,6 @@ like: - Only members of "DBA" group can SSH into machines running PostgreSQL. - Developers must never SSH into production servers. - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - - ## Prerequisites - Okta account with admin access. Your account must include users and at least two groups. @@ -191,4 +172,3 @@ automatically in a browser). (!docs/pages/includes/sso/loginerrortroubleshooting.mdx!) - \ No newline at end of file diff --git a/docs/pages/enterprise/sso/one-login.mdx b/docs/pages/enterprise/sso/one-login.mdx index d5deb6fc282a2..6892c427b5088 100644 --- a/docs/pages/enterprise/sso/one-login.mdx +++ b/docs/pages/enterprise/sso/one-login.mdx @@ -13,25 +13,6 @@ like: - Developers must never SSH into production servers. - ... and many others. - - - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - - - - - - ## Prerequisites - One Login account with admin access and users assigned to at least two groups. @@ -195,4 +176,3 @@ automatically in a browser). (!docs/pages/includes/sso/loginerrortroubleshooting.mdx!) - \ No newline at end of file diff --git a/docs/pages/enterprise/workflow/index.mdx b/docs/pages/enterprise/workflow/index.mdx index cbacd4dbfc456..6ad0cff893138 100644 --- a/docs/pages/enterprise/workflow/index.mdx +++ b/docs/pages/enterprise/workflow/index.mdx @@ -1,281 +1,40 @@ --- -title: Access Requests for Infrastructure Access -description: Teleport allows users to request new roles with elevated privileges from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API. -h1: Teleport Access Requests +title: Just-in-time Access Requests +description: Teleport allows users to request new access capabilities from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API. +h1: Teleport Just-in-time Access Requests --- -With Teleport, users can request additional roles via a third-party -communication service. The Access Request API makes it easy to dynamically -approve or deny these requests. +Teleport Just-in-time Access Requests allow any developer to request access to +a resource or role depending on need. The request can then be approved or +denied based on a configurable number of approvers. - + - This guide requires Teleport Cloud or Teleport Enterprise. - - View this guide as the user of another Teleport edition: - - - - - - - +Just-in-time Access Requests are a feature of Teleport Enterprise. +Open-source Teleport users can get a preview of how Access Requests work by +requesting a role via the Teleport CLI. Full access request functionality, +including Resource Access Requests and an intuitive and searchable UI are +available in Teleport Enterprise. - - -- [Integrating Teleport with Slack](ssh-approval-slack.mdx) -- [Integrating Teleport with Mattermost](ssh-approval-mattermost.mdx) -- [Integrating Teleport with Jira Cloud](ssh-approval-jira-cloud.mdx) -- [Integrating Teleport with Jira Server](ssh-approval-jira-server.mdx) -- [Integrating Teleport with PagerDuty](ssh-approval-pagerduty.mdx) - -## Access Requests Setup - -**Contractor Role** -This role allows the contractor to request the role DBA. - -```yaml -kind: role -version: v5 -metadata: - name: contractor -spec: - allow: - request: - roles: ['dba'] - # ... - deny: - # ... - options: - # ... -``` - -**DBA Role** -This role allows the contractor to request the role DBA. - -```yaml -kind: role -version: v5 -metadata: - name: dba -spec: - allow: - # ... - deny: - # ... - options: - # ... - # Only allows the contractor to use this role for 1 hour from time of request. - max_session_ttl: 1h -``` - -**Admin Role** -This role allows the admin to approve the contractor's request. - -```yaml -kind: role -version: v5 -metadata: - name: admin -spec: - allow: - # `review_requests` permits the listed roles to be approved - review_requests: - roles: - - 'dba' - rules: - # `access_request` is part of Access Workflows introduced in 4.2 - # `access_request` should only be given to Teleport Admins. - # For a full list of allow-rules, see - # https://goteleport.com/docs/access-controls/reference/ - - resources: - - access_request - verbs: - - list - - read - - update - - delete - deny: - # ... - options: - # ... -``` - -```code -$ tsh login teleport-cluster --request-roles=dba -# Seeking request approval... (id: bc8ca931-fec9-4b15-9a6f-20c13c5641a9) -``` - - - Users can finish the request without waiting for approval with the `--request-nowait` flag. - Once the request is approved, the user can see it with `tsh request ls` and login with it - using `tsh login --request-id`. - - -As a Teleport Administrator: - -```code -$ tctl request ls -# Token Requestor Metadata Created At (UTC) Status -# ------------------------------------ --------- -------------- ------------------- ------- -# bc8ca931-fec9-4b15-9a6f-20c13c5641a9 alice roles=dba 07 Nov 19 19:38 UTC PENDING -``` - -```code -$ tctl request approve bc8ca931-fec9-4b15-9a6f-20c13c5641a9 -``` - -Assuming access, `tsh` will automatically manage a certificate re-issued with -the newly requested roles applied. In this case `contractor` will now have have -the permission of the `dba`. - - - Granting a role with administrative abilities could allow a user to **permanently** - upgrade their privileges (e.g. if contractor was granted admin for some reason). - We recommend only escalating to the next role of least privilege vs jumping directly - to "Super Admin" role. - - The `deny.request` block can help mitigate the risk of doing this by accident. See - Example Below. - +## Resource Access Requests -```yaml -# Example role that explicitly denies a contractor from requesting the admin -# role. -kind: role -version: v5 -metadata: -name: contractor -spec: -options: - # ... -allow: - # ... -deny: - request: - roles: ['admin'] -``` +Resource Access Requests follow the principle of least privilege. On teams +leveraging Teleport, engineers can easily get access to only the individual +resources they need, when they need it. -## Adding a Reason to Access Requests +[Get started with Resource Access Requests](./resource-requests.mdx). -When requesting a new role users can add provide a reason along with their request -`tsh login --request-roles="db" --request-reason="Need access to db"`. +## Role Access Requests -By requiring a reason along with an access request, you can provide users with a default -unprivileged state where they must always go through the Access Requests API in order to -gain meaningful privilege. +Role Access Requests balance security and flexibility. Engineers can request +temporary credentials with elevated roles in order to perform critical +system-wide tasks. -Teams can leverage claims (traits) provided by external identity providers both when -determining which roles a user is allowed to request, and if a specific request -should be approved/denied. +[Get started with Role Access Requests](./role-requests.mdx). -### Example Setup - -**Unprivileged User**
    -In this example we have an employee who isn't able to access any systems. When they -log in, they'll always need to provide a reason for access. - -```yaml -kind: role -metadata: - name: employee -spec: - allow: - request: - # the `roles` list can now be a mixture of literals and wildcard matchers - roles: ['common', 'dev-*'] - # the `claims_to_roles` mapping works the same as it does in - # the OIDC connector, with the added benefit that the roles being mapped to - # can also be matchers. the below mapping says that users with - # the claims `groups: admins` can request any role in the system. - claims_to_roles: - - claim: groups - value: admins - roles: ['*'] - # Teleport can attach annotations to pending access requests. these - # annotations may be literals, or be variable interpolation expressions, - # effectively creating a means for propagating selected claims from an - # external identity provider to the plugin system. - annotations: - foo: ['bar'] - groups: ['{{external.groups}}'] - options: - # the `request_access` field can be set to 'always' or 'reason' to tell - # tsh or the web UI to always create an access request on login. If it is - # set to 'reason', the user will be required to indicate *why* they are - # generating the access request. - request_access: reason - # the `request_prompt` field can be used to tell the user what should - # be supplied in the request reason field. - request_prompt: Please provide your ticket ID -version: v5 -``` - - - Teleport RBAC offers powerful wildcard and RegEx helpers. Below are a few examples. - - `dev-*` - Can request all dev clusters. e.g. dev-prod,dev-stg - - `^prod.*$` - Can request all `prod.*` clusters. e.g. prod.us-east - - `dev-{{regexp.match("us-*")}}` - Can request any dev cluster in the US. e.g. dev-us-east-a, dev-us-west-b - - `dev-{{regexp.not_match("beta")}}-prod` - Can request any cluster, apart from beta cluster. e.g. Can access dev-alpha-prod, cannot access dev-beta-prod. - - -**Unprivileged User Login**
    - -```code -# Login: This will prompt the user to provide a reason in the UI. -$ tsh login -# Login: The user can provide a reason using tsh. -$ tsh login --request-reason="..." -``` - - - Notice that the above role does not specify any logins. If a users's roles specify no logins, Teleport will now generate the user's initial SSH certificates with an invalid dummy login of the form `-teleport-nologin-` (e.g. `-teleport-nologin-1e02dbfd`). - - -**Admin Flow: Approve/Deny**
    - -A number of new parameters are now available that grant the plugin or administrator greater insight into approvals/denials: - -```code -$ tctl request deny --reason='Please be more specific' --annotations=method=cli,unix-user=${USER} 28a3fb86-0230-439d-ad88-11cfcb213193 -``` - -Because automatically generated requests always include all roles that the user is allowed to request, approvers can now specify a smaller subset of the requested roles that should actually be applied, allowing for sub-selection in cases where full escalation is not a desirable default: - -```code -$ tctl request approve --roles=role-1,role-3 --reason='Approved, but not role-2 right now' 28a3fb86-0230-439d-ad88-11cfcb213193 -``` - -### Other features of Access Requests - -- Users can request multiple roles at one time. e.g `roles: ['dba','netsec','cluster-x']` -- Approved requests have no effect on Teleport's behavior outside of allowing additional - roles on re-issue. This has the nice effect of making requests "compatible" with - older versions of Teleport, since only the issuing Auth Server needs any particular - knowledge of the feature. ## Integrating with an External Tool +(!docs/pages/includes/access-request-integrations.mdx!) -| Integration | Feature | Type | Setup Instructions | -| - | - | - | - | -| Slack | | Chatbot | [Setup Slack](ssh-approval-slack.mdx) | -| Mattermost | | Chatbot | [Setup Mattermost](ssh-approval-mattermost.mdx) | -| Jira Server | | Project Board | [Setup Jira Server](ssh-approval-jira-server.mdx) | -| Jira Cloud | | Project Board | [Setup Jira Cloud](ssh-approval-jira-cloud.mdx) | -| PagerDuty | | Schedule | [Setup PagerDuty](ssh-approval-pagerduty.mdx) | - -
    \ No newline at end of file diff --git a/docs/pages/enterprise/workflow/resource-requests.mdx b/docs/pages/enterprise/workflow/resource-requests.mdx new file mode 100644 index 0000000000000..b94d7ebe30118 --- /dev/null +++ b/docs/pages/enterprise/workflow/resource-requests.mdx @@ -0,0 +1,353 @@ +--- +title: Resource Access Requests +description: Teleport allows users to request access to specific resources from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API. +h1: Teleport Resource Access Requests +--- + +With Teleport Resource Access Requests, users can request access to specific +resources without needing to know anything about the roles or RBAC controls used +under the hood. +The Access Request API makes it easy to dynamically approve or deny these +requests. + + + +Just-in-time Access Requests are a feature of Teleport Enterprise. +Open-source Teleport users can get a preview of how Access Requests work by +requesting a role via the Teleport CLI. Full access request functionality, +including Resource Access Requests and an intuitive and searchable UI are +available in Teleport Enterprise. + + + +## Prerequisites + +(!docs/pages/includes/commercial-prereqs-tabs.mdx!) + +(!docs/pages/includes/tctl.mdx!) + +## Step 1/8. Create the requester role + +This role allows the requester to search for resources accessible by the +`access` role (all resources by default) and request access to them. + +```yaml +# requester.yaml +kind: role +version: v5 +metadata: + name: requester +spec: + allow: + request: + search_as_roles: + - access +``` + +```code +$ tctl create requester.yaml +``` + +## Step 2/8. Create the reviewer role + +This role allows the reviewer to approve all requests for the `access` role. + +```yaml +# reviewer.yaml +kind: role +version: v5 +metadata: + name: reviewer +spec: + allow: + review_requests: + roles: + - access +``` + +```code +$ tctl create reviewer.yaml +``` + +## Step 3/8. Grant the roles to users + +Grant the `requester` and `reviewer` roles to existing users, or create new +users to test this feature. +Make sure the requester has a valid `login` so that they can view and access SSH +nodes. + +```code +$ tctl users add alice --roles requester --logins alice +$ tctl users add bob --roles reviewer +``` + +For the rest of the guide we will assume that the `requester` role has been +granted to a user named `alice` and the `reviewer` role has been granted to a +user named `bob`. + +## Step 4/8. Search for resources + +First, log in as `alice`. + +```code +$ tsh login --proxy teleport.example.com --user alice +``` + +Notice that `tsh ls` returns an empty list, because `alice` does not have access to any resources by default. +```code +$ tsh ls +Node Name Address Labels +--------- ------- ------ +``` + +Then try searching for all available ssh nodes. + +```code +$ tsh request search --kind node +Name Hostname Labels Resource ID +------------------------------------ ----------- ------------ ------------------------------------------------------ +b1168402-9340-421a-a344-af66a6675738 iot test=test /teleport.example.com/node/b1168402-9340-421a-a344-af66a6675738 +bbb56211-7b54-4f9e-bee9-b68ea156be5f node test=test /teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f + +To request access to these resources, run +> tsh request create --resource /teleport.example.com/node/b1168402-9340-421a-a344-af66a6675738 --resource /teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f \ + --reason +``` + +You can search for resources of kind `node`, `kube_cluster`, `db`, `app`, and `windows_desktop`. +Advanced filters and queries are supported, see our +[filtering reference](../../setup/reference/cli.mdx#resource-filtering). + +Try narrowing your search to a specific resource you want to access. + +```code +$ tsh request search --kind node --search iot +Name Hostname Labels Resource ID +------------------------------------ ----------- ------------ ------------------------------------------------------ +b1168402-9340-421a-a344-af66a6675738 iot test=test /teleport.example.com/node/b1168402-9340-421a-a344-af66a6675738 + +To request access to these resources, run +> tsh request create --resource /teleport.example.com/node/b1168402-9340-421a-a344-af66a6675738 \ + --reason +``` + +## Step 5/8. Request access to a resource + +Copy the command output by `tsh request search` in the previous step, optionally filling in a request reason. + +```code +$ tsh request create --resource /teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f \ + --reason "responding to incident 123" +Creating request... +Request ID: f406f5d8-3c2a-428f-8547-a1d091a4ddab +Username: alice +Roles: access +Resources: ["/teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f"] +Reason: "responding to incident 123" +Reviewers: [none] (suggested) +Status: PENDING + +hint: use 'tsh login --request-id=' to login with an approved request + +Waiting for request approval... + +``` + +The command will automatically wait until the request is approved. + +## Step 6/8. Approve the access request + +First, log in as `bob`. + +```code +$ tsh login --proxy teleport.example.com --user bob +``` + +Then list, review, and approve the access request. + +```code +$ tsh request ls +ID User Roles Resources Created At (UTC) Status +------------------------------------ ----- ------ --------------------------- ------------------- ------- +f406f5d8-3c2a-428f-8547-a1d091a4ddab alice access ["/teleport.example.... [+] 23 Jun 22 18:25 UTC PENDING + +[+] Requested resources truncated, use `tsh request show ` to view the full list + +hint: use 'tsh request show ' for additional details + use 'tsh login --request-id=' to login with an approved request +$ tsh request show f406f5d8-3c2a-428f-8547-a1d091a4ddab +Request ID: f406f5d8-3c2a-428f-8547-a1d091a4ddab +Username: alice +Roles: access +Resources: ["/teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f"] +Reason: "responding to incident 123" +Reviewers: [none] (suggested) +Status: PENDING + +hint: use 'tsh login --request-id=' to login with an approved request +$ tsh request review --approve f406f5d8-3c2a-428f-8547-a1d091a4ddab +Successfully submitted review. Request state: APPROVED +``` + + +Check out our +[Access Request Integrations](#integrating-with-an-external-tool) +to notify the right people about new access requests. + + +## Step 7/8. Access the requested resource + +`alice`'s `tsh request create` command should resolve now that the request has been approved. + +```code +$ tsh request create --resource /teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f \ + --reason "responding to incident 123" +Creating request... +Request ID: f406f5d8-3c2a-428f-8547-a1d091a4ddab +Username: alice +Roles: access +Resources: ["/teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f"] +Reason: "responding to incident 123" +Reviewers: [none] (suggested) +Status: PENDING + +hint: use 'tsh login --request-id=' to login with an approved request + +Waiting for request approval... + +Approval received, getting updated certificates... + +> Profile URL: https://teleport.example.com + Logged in as: alice + Active requests: f406f5d8-3c2a-428f-8547-a1d091a4ddab + Cluster: teleport.example.com + Roles: access, requester + Logins: alice + Kubernetes: disabled + Allowed Resources: ["/teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f"] + Valid until: 2022-06-23 22:46:22 -0700 PDT [valid for 11h16m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + +`alice` can now view and access the node. + +```code +$ tsh ls +Node Name Address Labels +--------- --------- --------- +iot [::]:3022 test=test + +$ tsh ssh alice@iot +iot:~ alice$ +``` + + +While logged in with a resource access request, users will be blocked from access to any other resources. +This is necessary because their certicate now contains an elevated role. +Their certificate is restricted to only allow access to the resources they were specifically approved for. +They will need to `tsh logout` and log back in to resume their regular access. + + +## Next Steps + +### Automatically request access for SSH + +Once you have configured resource access requests, +`tsh ssh` is able to automatically create a resource access request for you when access is denied, +allowing you to skip the `tsh request search` and `tsh request create` steps. + +```code +$ tsh ssh alice@iot +ERROR: access denied to alice connecting to iot on cluster teleport.example.com + +You do not currently have access to alice@iot, attempting to request access. + +Enter request reason: please +Creating request... +Request ID: ab43fc70-e893-471b-872e-ae65eb24fd76 +Username: alice +Roles: access +Resources: ["/teleport.example.com/node/bbb56211-7b54-4f9e-bee9-b68ea156be5f"] +Reason: "please" +Reviewers: [none] (suggested) +Status: PENDING + +hint: use 'tsh login --request-id=' to login with an approved request + +Waiting for request approval... + +Approval received, reason="okay" +Getting updated certificates... + +iot:~ alice$ +``` + +### Restrict the resources a user can request access to + +Create a role which can only access SSH nodes labeled `env:staging`. + +```yaml +# staging-access.yaml +kind: role +version: v5 +metadata: + name: staging-access +spec: + allow: + node_labels: + env: staging + logins: + - "{{internal.logins}}" + options: + # Only allows the requester to use this role for 1 hour from time of request. + max_session_ttl: 1h +``` + +```code +$ tctl create staging-access.yaml +``` + +Update the `requester` and `reviewer` roles to reference `staging-access` +instead of the default `access` role. + +```yaml +# requester.yaml +kind: role +version: v5 +metadata: + name: requester +spec: + allow: + request: + search_as_roles: + - staging-access + # Requires 2 approvals for the request. + thresholds: + - approve: 2 + deny: 1 +``` + +```yaml +# reviewer.yaml +kind: role +version: v5 +metadata: + name: reviewer +spec: + allow: + review_requests: + roles: + - staging-access +``` + +```code +$ tctl create -f requester.yaml +$ tctl create -f reviewer.yaml +``` + +The `requester` will now only be able to search for or request access to +resources accessible by the `staging-access` role. + +### Integrating with an External Tool +(!docs/pages/includes/access-request-integrations.mdx!) + diff --git a/docs/pages/enterprise/workflow/role-requests.mdx b/docs/pages/enterprise/workflow/role-requests.mdx new file mode 100644 index 0000000000000..b88a3da1df0e9 --- /dev/null +++ b/docs/pages/enterprise/workflow/role-requests.mdx @@ -0,0 +1,266 @@ +--- +title: Role Access Requests +description: Teleport allows users to request new roles with elevated privileges from the CLI or UI. Requests can be escalated via ChatOps or anywhere else via our flexible Authorization Workflow API. +h1: Teleport Role Access Requests +--- + +With Teleport, users can request additional roles via a third-party +communication service. The Access Request API makes it easy to dynamically +approve or deny these requests. + + + +Just-in-time Access Requests are a feature of Teleport Enterprise. +Open-source Teleport users can get a preview of how Access Requests work by +requesting a role via the Teleport CLI. Full access request functionality, +including Resource Access Requests and an intuitive and searchable UI are +available in Teleport Enterprise. + + + +## Prerequisites + +(!docs/pages/includes/commercial-prereqs-tabs.mdx!) + +(!docs/pages/includes/tctl.mdx!) + + +## Role Access Requests Setup + +**Contractor Role** +This role allows the contractor to request the role DBA. + +```yaml +kind: role +version: v5 +metadata: + name: contractor +spec: + allow: + request: + roles: ['dba'] + # ... + deny: + # ... + options: + # ... +``` + +**DBA Role** +This role can be requested by the contractor. + +```yaml +kind: role +version: v5 +metadata: + name: dba +spec: + allow: + # ... + deny: + # ... + options: + # ... + # Only allows the contractor to use this role for 1 hour from time of request. + max_session_ttl: 1h +``` + +**Admin Role** +This role allows the admin to approve the contractor's request. + +```yaml +kind: role +version: v5 +metadata: + name: admin +spec: + allow: + # `review_requests` permits the listed roles to be approved + review_requests: + roles: + - 'dba' + rules: + # `access_request` is part of Access Workflows introduced in 4.2 + # `access_request` should only be given to Teleport Admins. + # For a full list of allow-rules, see + # https://goteleport.com/docs/access-controls/reference/ + - resources: + - access_request + verbs: + - list + - read + - update + - delete + deny: + # ... + options: + # ... +``` + +```code +$ tsh login teleport-cluster --request-roles=dba +# Seeking request approval... (id: bc8ca931-fec9-4b15-9a6f-20c13c5641a9) +``` + + + Users can finish the request without waiting for approval with the `--request-nowait` flag. + Once the request is approved, the user can see it with `tsh request ls` and login with it + using `tsh login --request-id`. + + +As a Teleport Administrator: + +```code +$ tctl request ls +# Token Requestor Metadata Created At (UTC) Status +# ------------------------------------ --------- -------------- ------------------- ------- +# bc8ca931-fec9-4b15-9a6f-20c13c5641a9 alice roles=dba 07 Nov 19 19:38 UTC PENDING +``` + +```code +$ tctl request approve bc8ca931-fec9-4b15-9a6f-20c13c5641a9 +``` + +Assuming access, `tsh` will automatically manage a certificate re-issued with +the newly requested roles applied. In this case `contractor` will now have have +the permission of the `dba`. + + + Granting a role with administrative abilities could allow a user to **permanently** + upgrade their privileges (e.g. if contractor was granted admin for some reason). + We recommend only escalating to the next role of least privilege vs jumping directly + to "Super Admin" role. + + The `deny.request` block can help mitigate the risk of doing this by accident. See + Example Below. + + +```yaml +# Example role that explicitly denies a contractor from requesting the admin +# role. +kind: role +version: v5 +metadata: +name: contractor +spec: +options: + # ... +allow: + # ... +deny: + request: + roles: ['admin'] +``` + +## Adding a Reason to Access Requests + +When requesting a new role users can add provide a reason along with their request +`tsh login --request-roles="db" --request-reason="Need access to db"`. + +By requiring a reason along with an access request, you can provide users with a default +unprivileged state where they must always go through the Access Requests API in order to +gain meaningful privilege. + +Teams can leverage claims (traits) provided by external identity providers both when +determining which roles a user is allowed to request, and if a specific request +should be approved/denied. + +### Example Setup + +**Unprivileged User**
    +In this example we have an employee who isn't able to access any systems. When they +log in, they'll always need to provide a reason for access. + +```yaml +kind: role +metadata: + name: employee +spec: + allow: + request: + # the `roles` list can now be a mixture of literals and wildcard matchers + roles: ['common', 'dev-*'] + # the `claims_to_roles` mapping works the same as it does in + # the OIDC connector, with the added benefit that the roles being mapped to + # can also be matchers. the below mapping says that users with + # the claims `groups: admins` can request any role in the system. + claims_to_roles: + - claim: groups + value: admins + roles: ['*'] + # Teleport can attach annotations to pending access requests. these + # annotations may be literals, or be variable interpolation expressions, + # effectively creating a means for propagating selected claims from an + # external identity provider to the plugin system. + annotations: + foo: ['bar'] + groups: ['{{external.groups}}'] + options: + # the `request_access` field can be set to 'always' or 'reason' to tell + # tsh or the web UI to always create an access request on login. If it is + # set to 'reason', the user will be required to indicate *why* they are + # generating the access request. + request_access: reason + # the `request_prompt` field can be used to tell the user what should + # be supplied in the request reason field. + request_prompt: Please provide your ticket ID +version: v5 +``` + + + Teleport RBAC offers powerful wildcard and RegEx helpers. Below are a few examples. + + `dev-*` - Can request all dev clusters. e.g. dev-prod,dev-stg + + `^prod.*$` - Can request all `prod.*` clusters. e.g. prod.us-east + + `dev-{{regexp.match("us-*")}}` - Can request any dev cluster in the US. e.g. dev-us-east-a, dev-us-west-b + + `dev-{{regexp.not_match("beta")}}-prod` - Can request any cluster, apart from beta cluster. e.g. Can access dev-alpha-prod, cannot access dev-beta-prod. + + +**Unprivileged User Login**
    + +```code +# Login: This will prompt the user to provide a reason in the UI. +$ tsh login +# Login: The user can provide a reason using tsh. +$ tsh login --request-reason="..." +``` + + + Notice that the above role does not specify any logins. If a users's roles specify no logins, Teleport will now generate the user's initial SSH certificates with an invalid dummy login of the form `-teleport-nologin-` (e.g. `-teleport-nologin-1e02dbfd`). + + +**Admin Flow: Approve/Deny**
    + +A number of new parameters are now available that grant the plugin or administrator greater insight into approvals/denials: + +```code +$ tctl request deny --reason='Please be more specific' --annotations=method=cli,unix-user=${USER} 28a3fb86-0230-439d-ad88-11cfcb213193 +``` + +Because automatically generated requests always include all roles that the user is allowed to request, approvers can now specify a smaller subset of the requested roles that should actually be applied, allowing for sub-selection in cases where full escalation is not a desirable default: + +```code +$ tctl request approve --roles=role-1,role-3 --reason='Approved, but not role-2 right now' 28a3fb86-0230-439d-ad88-11cfcb213193 +``` + +### Other features of Role Access Requests + +- Users can request multiple roles at one time. e.g `roles: ['dba','netsec','cluster-x']` +- Approved requests have no effect on Teleport's behavior outside of allowing additional + roles on re-issue. This has the nice effect of making requests "compatible" with + older versions of Teleport, since only the issuing Auth Server needs any particular + knowledge of the feature. + + +## Integrating with an External Tool +(!docs/pages/includes/access-request-integrations.mdx!) + diff --git a/docs/pages/enterprise/workflow/ssh-approval-slack.mdx b/docs/pages/enterprise/workflow/ssh-approval-slack.mdx index 14a1f0906c323..ec1710b16a8c6 100644 --- a/docs/pages/enterprise/workflow/ssh-approval-slack.mdx +++ b/docs/pages/enterprise/workflow/ssh-approval-slack.mdx @@ -40,6 +40,8 @@ Here is an example of sending an access request via Teleport's Slack plugin: (!/docs/pages/includes/commercial-prereqs-tabs.mdx!) +(!/docs/pages/includes/tctl.mdx!) + ## Step 1/7. Install the Teleport Slack plugin We currently only provide `linux-amd64` binaries. You can also compile these plugins diff --git a/docs/pages/faq.mdx b/docs/pages/faq.mdx index 15eee00f51f30..911536e828015 100644 --- a/docs/pages/faq.mdx +++ b/docs/pages/faq.mdx @@ -1,47 +1,42 @@ --- title: Teleport FAQ -description: Frequently asked questions about using Teleport -h1: FAQ +description: Frequently Asked Questions About Using Teleport +h1: Teleport FAQ --- -## Community FAQ +## Can I use Teleport in production today? -### Can I use Teleport in production today? - -Teleport has been deployed on server clusters with thousands of nodes at +Teleport has been deployed on server clusters with thousands of hosts at Fortune 500 companies. It has been through several security audits from nationally recognized technology security companies, so we are comfortable with the stability of Teleport from a security perspective. -### Can Teleport be deployed in agentless mode? +## Can Teleport be deployed in agentless mode? Yes. Teleport can be deployed with a tiny footprint as an authentication -gateway/proxy and you can keep your existing SSH servers on the nodes. But some -innovating Teleport features, such as cluster introspection, will not be -available unless the Teleport SSH daemon is present on all cluster nodes. +gateway/proxy and you can keep your existing SSH servers on Teleport Nodes. But +some innovating Teleport features, such as cluster introspection, will not be +available unless the Teleport SSH daemon is present on all cluster Nodes. -### Can I use OpenSSH with a Teleport cluster? +## Can I use OpenSSH with a Teleport cluster? Yes, this question comes up often and is related to the previous one. Take a look at [Using OpenSSH Guide](./server-access/guides/openssh.mdx). -### Can I connect to nodes behind a firewall? +## Can I connect to Nodes behind a firewall? Yes, Teleport supports reverse SSH tunnels out of the box. To configure -behind-firewall clusters refer to [Trusted Clusters](./setup/admin/trustedclusters.mdx) -section of the Admin Manual. +behind-firewall clusters refer to our +[Trusted Clusters](./setup/admin/trustedclusters.mdx) guide. -### Can individual nodes create reverse tunnels to a proxy server without creating a new cluster? +## Can individual agents create reverse tunnels to the Proxy Service without creating a new cluster? -This was a popular customer -[request](https://github.com/gravitational/teleport/issues/803) that was added -in Teleport version 4.0. Change the node config option `--auth-server` flag when -running the `teleport` daemon on an agent to point to the Proxy Service address -(this would be `public_addr` and `web_listen_addr` in file configuration). For -more information, see +Yes. When running a Teleport agent, use the `--auth-server` flag to point to the +Proxy Service address (this would be `public_addr` and `web_listen_addr` in your +file configuration). For more information, see [Adding Nodes to the Cluster](./setup/admin/adding-nodes.mdx). -### Can nodes use a single port for reverse tunnels? +## Can Nodes use a single port for reverse tunnels? Yes, Teleport supports tunnel multiplexing on a single port. Set the `tunnel_listen_addr` to use the same port as the `web_listen_addr` address @@ -50,99 +45,35 @@ multiplexing with that configuration. ## How is Open Source different from Enterprise? -Open Source Teleport is licensed under the Apache 2 License, and must be -self-hosted. Enterprise Teleport is commercially licensed and is available in -both self-hosted and cloud deployments. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Capability/OfferingOpen SourceEnterprise
    LicenseApache 2Commercial
    Role-Based Access Control
    Cloud-hosted
    Self-hosted
    Single Sign-OnGitHub onlyGitHub, Google, OIDC, SAML
    Access RequestsLimited✔ [Dual authorization, mandatory requests](./access-controls/guides/dual-authz.mdx)
    FedRAMP Control[Compiled with FIPS-certified crypto libraries, FedRAMP control features](./enterprise/fedramp.mdx)
    PCI DSS FeaturesLimited
    SOC2 FeaturesLimited
    Annual or Multi-Year contracts, Volume Discounts
    SupportBest-effort, community24x7 support with premium SLAs & account managers
    +Teleport provides three offerings: + +- Open Source +- Enterprise +- Cloud + +||Open Source|Enterprise|Cloud| +|---|---|---|---| +|Auth and Proxy Service management|Self-hosted|Self-hosted|Fully managed| +|License|Apache 2|Commercial|Commercial| +|Role-Based Access Control|✔|✔|✔| +|Single Sign-On|GitHub|GitHub, Google Workspace, OIDC, SAML|GitHub, Google Workspace, OIDC, SAML| +|[Access Requests](./access-controls/guides/dual-authz.mdx)|Limited|✔|✔| +|[FedRAMP Control](./enterprise/fedramp.mdx)|✖|✔|✖| +|PCI DSS Features|Limited|✔|✔|✔| +|SOC2 Features|Limited|✔|✔| +|Annual or multi-year contracts, volume discounts|✖|✔|✔| +|Support|Best-effort, community|24x7 support with premium SLAs and account managers|24x7 support with premium SLAs and account managers| +|[Hardware Security Module support](./enterprise/hsm.mdx)|✖|✔|✖| +|[Moderated Sessions](./access-controls/guides/moderated-sessions.mdx)|✖|✔|✔| ## Which version of Teleport is supported? Teleport provides security-critical support for the current and two previous releases. With our typical release cadence, this means a release is usually supported for 9 months. -| Release | Long Term Support | Release Date | Min tsh version | -| - | - | - | - | -| 6.2 | No | May 21th, 2021 | 3.0.0 | -| 6.1 | No | April 9th, 2021 | 3.0.0| -| 6 | Yes | March 4th, 2021 | 3.0.0 | -| 5.0 | Yes | November 24th, 2020 | 3.0.0 | -| 4.4 | Yes | October 20th, 2020 | 3.0.0 | -| 4.3 (EOL) | Yes | July 8th, 2020 | 3.0.0 | -| 4.2 (EOL) | Yes | December 19th, 2019 | 3.0.0 | - - -**How should I upgrade my cluster?** +See our [Upgrading](./setup/operations/upgrading.mdx) guide for more +information. -Please follow our guidelines for [upgrading](./setup/admin/graceful-restarts.mdx). -We recommend that the Auth Server should be upgraded first, and the proxy bumped thereafter. - -### Does Web UI support copy and paste? +## Does the Web UI support copy and paste? Yes. You can copy and paste using a mouse. If you prefer a keyboard, Teleport employs `tmux`-like "prefix" mode. To enter prefix mode, use the `Ctrl`+`A` keyboard shortcut. @@ -154,26 +85,29 @@ mode by pressing `[`. When in text selection mode: - Select text by toggling `space`. - And, copy it via `Ctrl`+`C`. -### What TCP ports does Teleport use? +## What TCP ports does Teleport use? -Please refer to the [Ports](./setup/reference/networking.mdx) section of the Admin Manual. +Please refer to our [Networking](./setup/reference/networking.mdx) guide. -### Does Teleport support authentication via OAuth, SAML, or Active Directory? +## Does Teleport support authentication via OAuth, SAML, or Active Directory? Teleport offers this feature for the [Enterprise versions of Teleport](enterprise/introduction.mdx). -### Does Teleport send any data back to the cloud? +## Does Teleport send any data back to the cloud? + +The open source and Enterprise editions of Teleport do not send any information +to our company, and can be used on servers without internet access. -The Open-Source Edition of Teleport does not send any information to -Gravitational and can be used on servers without internet access. The -commercial versions of Teleport may or may not be configured to send anonymized information to Gravitational, depending on the license purchased. This information contains the following: +The commercial editions of Teleport can optionally be configured to send +anonymized information, depending on the license purchased. This information +contains the following: - Anonymized user ID: SHA256 hash of a username with a randomly generated prefix. - Anonymized server ID: SHA256 hash of a server IP with a randomly generated prefix. -This allows Teleport to print a warning if users are exceeding the usage limits -of their license. The reporting library code is +This allows Teleport Cloud and Teleport Enterprise to print a warning if users +are exceeding the usage limits of their license. The reporting library code is [on GitHub](https://github.com/gravitational/reporting). Reach out to `sales@goteleport.com` if you have questions about the commercial -edition of Teleport. +editions of Teleport. diff --git a/docs/pages/getting-started.mdx b/docs/pages/getting-started.mdx index 92338a4b26d61..cd4d382bf73ca 100644 --- a/docs/pages/getting-started.mdx +++ b/docs/pages/getting-started.mdx @@ -9,55 +9,93 @@ Follow these guides to get started using Teleport. ## Try a lab on your local machine - + Try Teleport using our guided interactive labs. - + Try Teleport locally using Docker Compose. - + See how Teleport runs on Kubernetes with this local lab. ## Deploy to production +Not sure which edition of Teleport is right for you? View our [comparison chart](./faq.mdx#how-is-open-source-different-from-enterprise). + + + + +Host your own Teleport deployment. + Learn how to host your own open source Teleport deployment on a standalone Linux server. - - Use our DigitalOcean 1-Click App to quickly spin up Teleport on a droplet. - + Learn how to host your own open source Teleport deployment on Kubernetes. + - + + + + +Teleport Cloud is a deployment of the Auth Service and Proxy Service, +managed by a dedicated team at Teleport. + + + + + Learn how to start using Teleport Cloud. + + + + + Try Teleport hosted by us in the cloud for free. + + + + + Get started with a self-hosted Teleport Enterprise deployment, which gives you more advanced features and full customization. - + + + - + Learn how to deploy Teleport Enterprise. - Try Teleport hosted by us in the cloud for free. + + + + Learn how to host your Teleport Enterprise deployment on Kubernetes. - + + + diff --git a/docs/pages/getting-started/docker-compose.mdx b/docs/pages/getting-started/docker-compose.mdx index 8869d6065ce9a..b432b1ba136f3 100644 --- a/docs/pages/getting-started/docker-compose.mdx +++ b/docs/pages/getting-started/docker-compose.mdx @@ -146,7 +146,7 @@ Port `443` on the Teleport container is published to the local host, so you can - Learn about [Teleport Access Controls](../access-controls/getting-started.mdx). - Get started with [Teleport Session Recording](../server-access/guides/bpf-session-recording.mdx). - Try out one of our [Database Access Guides](../database-access/guides.mdx). -- For Kubernetes environments, try out one of our [Helm Guides](../kubernetes-access/helm/guides.mdx). +- For Kubernetes environments, try out one of our [Helm Guides](../setup/helm-deployments.mdx). ## Under the hood diff --git a/docs/pages/kubernetes-access/getting-started/cluster.mdx b/docs/pages/getting-started/kubernetes-cluster.mdx similarity index 91% rename from docs/pages/kubernetes-access/getting-started/cluster.mdx rename to docs/pages/getting-started/kubernetes-cluster.mdx index adda48dc127e2..e78cb7eb8c658 100644 --- a/docs/pages/kubernetes-access/getting-started/cluster.mdx +++ b/docs/pages/getting-started/kubernetes-cluster.mdx @@ -8,35 +8,8 @@ This guide shows you how to deploy the Teleport Auth Service and Proxy Service o Instead, Teleport Cloud users should consult the following guide, which shows you how to connect a Teleport Kubernetes Service agent to an existing Teleport cluster: - - - - - -You can also view this guide as a user of another Teleport edition: - - - - - - -
    - - Teleport can provide secure, unified access to your Kubernetes clusters. This guide will show you how to: - Deploy Teleport in a Kubernetes cluster. @@ -45,7 +18,7 @@ Teleport can provide secure, unified access to your Kubernetes clusters. This gu While completing this guide, you will deploy a single Teleport pod running the Auth Service and Proxy Service in your Kubernetes cluster, and a load balancer that allows outside traffic to your Teleport cluster. Users can then access your Kubernetes cluster via the Teleport cluster running within it. -If you are already running Teleport on another platform, you can use your existing Teleport deployment to access your Kubernetes cluster. [Follow our guide](./agent.mdx) to connect your Kubernetes cluster to Teleport. +If you are already running Teleport on another platform, you can use your existing Teleport deployment to access your Kubernetes cluster. [Follow our guide](../kubernetes-access/getting-started.mdx) to connect your Kubernetes cluster to Teleport. ## Follow along with our video guide @@ -64,7 +37,7 @@ If you are already running Teleport on another platform, you can use your existi - A Kubernetes cluster hosted by a cloud provider, which is required for the load balancer we deploy in this guide. -Teleport also supports Kubernetes in on-premise and air-gapped environments. If you would like to try out Teleport on your local machine, we recommend following our [Docker Compose guide](../../getting-started/docker-compose.mdx). +Teleport also supports Kubernetes in on-premise and air-gapped environments. If you would like to try out Teleport on your local machine, we recommend following our [Docker Compose guide](./docker-compose.mdx). (!docs/pages/includes/kubernetes-access/helm-k8s.mdx!) @@ -213,7 +186,7 @@ $ kubectl exec -ti ${POD?} -- tctl users add alice --roles=member ``` Let's install `tsh` and `tctl` on Linux. -For other install options, check out [install guide](../../installation.mdx) +For other install options, check out the [installation guide](../installation.mdx) @@ -295,8 +268,8 @@ In this step, we will set up the GitHub Single Sign-On connector for the OSS ver - Follow the [SAML Okta Guide](../../enterprise/sso/okta.mdx#configure-okta) to create a SAML app. - Check out [OIDC guides](../../enterprise/sso/oidc.mdx#identity-providers) for OpenID Connect apps. + Follow the [SAML Okta Guide](../enterprise/sso/okta.mdx#configure-okta) to create a SAML app. + Check out [OIDC guides](../enterprise/sso/oidc.mdx#identity-providers) for OpenID Connect apps. Save the file below as `okta.yaml` and update the `acs` field. Any member in Okta group `okta-admin` will assume a builtin role `access`. @@ -372,9 +345,8 @@ the default one in case there is a problem. ## Next steps -- [Connect Multiple Kubernetes Clusters](../guides/multiple-clusters.mdx) -- [Setup CI/CD Access with Teleport](../guides/cicd.mdx) -- [Federated Access using Trusted Clusters](../guides/federation.mdx) -- [Single-Sign On and Kubernetes Access Control](../controls.mdx) +- [Connect Multiple Kubernetes Clusters](../kubernetes-access/guides/multiple-clusters.mdx) +- [Setup CI/CD Access with Teleport](../kubernetes-access/guides/cicd.mdx) +- [Federated Access using Trusted Clusters](../kubernetes-access/guides/federation.mdx) +- [Single-Sign On and Kubernetes Access Control](../kubernetes-access/controls.mdx) - diff --git a/docs/pages/getting-started/linux-server.mdx b/docs/pages/getting-started/linux-server.mdx index 6d21ee3a9a8aa..75a001f04cbc1 100644 --- a/docs/pages/getting-started/linux-server.mdx +++ b/docs/pages/getting-started/linux-server.mdx @@ -8,52 +8,6 @@ This tutorial will guide you through the steps needed to install and run Teleport (=teleport.version=) on a Linux machine, then show you how to use Teleport to configure access to resources. - - -This guide is intended for users of the self-hosted, Open Source edition of -Teleport. - - - - - - - - - - - - -This guide is intended for users of the self-hosted, Open Source edition of -Teleport. - - - - - - - - - - - - We will run the following Teleport services: - **Teleport Auth Service:** The certificate authority for your cluster. It @@ -196,7 +150,7 @@ app_service: public_addr: "demo.teleport.example.com" ``` -## Start Teleport +### Start Teleport On your Linux machine, run the following command to start the `teleport` daemon (this depends on how you installed Telport earlier). @@ -220,7 +174,7 @@ You can access Teleport's Web UI via HTTPS at the domain you created earlier (e.g., `https://teleport.example.com`). You should see a welcome screen similar to the following: -![Teleport User Registration](../../img/quickstart/login.png) +![Teleport Welcome Screen](../../img/quickstart/welcome.png) ## Step 4/6. Create a Teleport user and set up two-factor authentication @@ -412,4 +366,3 @@ Teleport tasks, such as: - How Let's Encrypt uses the [ACME protocol](https://letsencrypt.org/how-it-works/) to issue certificates - \ No newline at end of file diff --git a/docs/pages/kubernetes-access/getting-started/local.mdx b/docs/pages/getting-started/local-kubernetes.mdx similarity index 97% rename from docs/pages/kubernetes-access/getting-started/local.mdx rename to docs/pages/getting-started/local-kubernetes.mdx index 684060ec2904b..e489eb0a5fb99 100644 --- a/docs/pages/kubernetes-access/getting-started/local.mdx +++ b/docs/pages/getting-started/local-kubernetes.mdx @@ -256,7 +256,7 @@ reverse tunnel will allow you to access the Teleport Proxy Service at (!docs/pages/includes/insecure-certificate.mdx!) -![Teleport User Registration](../../../img/quickstart/login.png) +![Teleport User Registration](../../img/quickstart/login.png) In the Teleport Web UI, enter a password and scan the QR code with your OTP application to create your user. @@ -355,7 +355,7 @@ of readers who have launched a local Application Service. */} You will now see Kubernetes Dashboard as connected to your cluster. -![An application connected to your Teleport cluster](../../../img/connected-app.png) +![An application connected to your Teleport cluster](../../img/connected-app.png) To access Kubernetes Dashboard, click "LAUNCH." If you see an authentication form with the title, "Kubernetes Dashboard," you have successfully gained access @@ -380,12 +380,12 @@ Kubernetes cluster, read our guides to setting up Teleport for Kubernetes in production. - Get started with Teleport on AWS EKS: [Running an HA Teleport cluster using - AWS, EKS, and Helm](../helm/guides/aws.mdx) + AWS, EKS, and Helm](../setup/helm-deployments/aws.mdx) - Manage access to your Kubernetes cluster with the Teleport Kubernetes Service: - [Connect Kubernetes Cluster to Teleport](./agent.mdx) + [Connect Kubernetes Cluster to Teleport](../kubernetes-access/getting-started.mdx) - Integrate Teleport with your SSO provider: - [Single Sign-On and Kubernetes RBAC](../controls.mdx) + [Single Sign-On and Kubernetes RBAC](../kubernetes-access/controls.mdx) - Have a Kubernetes cluster but don't want to run Teleport there? - [Kubernetes Access from Standalone Teleport](../guides/standalone-teleport.mdx) + [Kubernetes Access from Standalone Teleport](../kubernetes-access/guides/standalone-teleport.mdx) diff --git a/docs/pages/includes/access-request-integrations.mdx b/docs/pages/includes/access-request-integrations.mdx new file mode 100644 index 0000000000000..a2740c48cfb0a --- /dev/null +++ b/docs/pages/includes/access-request-integrations.mdx @@ -0,0 +1,11 @@ +Admins can review Just-in-time Access Requests via a third-party communication +service. The Access Request API makes it easy to dynamically approve or deny +these requests. + +| Integration | Feature | Type | Setup Instructions | +| - | - | - | - | +| Slack | | Chatbot | [Setup Slack](/docs/enterprise/workflow/ssh-approval-slack.mdx) | +| Mattermost | | Chatbot | [Setup Mattermost](/docs/enterprise/workflow/ssh-approval-mattermost.mdx) | +| Jira Server | | Project Board | [Setup Jira Server](/docs/enterprise/workflow/ssh-approval-jira-server.mdx) | +| Jira Cloud | | Project Board | [Setup Jira Cloud](/docs/enterprise/workflow/ssh-approval-jira-cloud.mdx) | +| PagerDuty | | Schedule | [Setup PagerDuty](/docs/enterprise/workflow/ssh-approval-pagerduty.mdx) | diff --git a/docs/pages/includes/database-access/create-user.mdx b/docs/pages/includes/database-access/create-user.mdx index 5aea083c01bc5..3016aff737f4c 100644 --- a/docs/pages/includes/database-access/create-user.mdx +++ b/docs/pages/includes/database-access/create-user.mdx @@ -8,11 +8,11 @@ $ tctl users add \ alice ``` -| Flag | Description | -| ---- | ----------- | -| `--roles` | List of roles to assign to the user. The builtin `access` role allows them to connect to any database server registered with Teleport. | -| `--db-users` | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user. | -| `--db-names` | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. | +| Flag | Description | +|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------| +| `--roles` | List of roles to assign to the user. The builtin `access` role allows them to connect to any database server registered with Teleport. | +| `--db-users` | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user. | +| `--db-names` | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. | Database names are only enforced for PostgreSQL and MongoDB databases. diff --git a/docs/pages/includes/database-access/database-config.yaml b/docs/pages/includes/database-access/database-config.yaml index 4de80a464317f..4f79b39c76303 100644 --- a/docs/pages/includes/database-access/database-config.yaml +++ b/docs/pages/includes/database-access/database-config.yaml @@ -12,7 +12,9 @@ db_service: # Database types. Valid options are: # 'rds' - discovers and registers AWS RDS and Aurora databases. # 'redshift' - discovers and registers AWS Redshift databases. - - types: ["rds", "redshift"] + # 'elasticache' - discovers and registers AWS ElastiCache Redis databases. + # 'memorydb' - discovers and registers AWS MemoryDB Redis databases. + - types: ["rds", "redshift", "elasticache", "memorydb"] # AWS regions to register databases from. regions: ["us-west-1", "us-east-2"] # AWS resource tags to match when registering databases. @@ -53,14 +55,45 @@ db_service: # When this option is set the Database Agent doesn't try to check the MySQL server version. server_version: 8.0.28 - # AWS specific configuration, only required for RDS/Aurora/Redshift. + # Optional AWS configuration for AWS hosted databases. AWS region- and + # service-specific configurations can usually be auto-detected from the + # endpoint. aws: # Region the database is deployed in. region: "us-east-1" - # Redshift specific configuration. + # Redshift-specific configuration. redshift: # Redshift cluster identifier. cluster_id: "redshift-cluster-1" + # RDS-specific configuration. + rds: + # RDS instance identifier. + instance_id: "rds-instance-1" + # RDS Aurora cluster identifier. + cluster_id: "aurora-cluster-1" + # ElastiCache-specific configuration. + elasticache: + # ElastiCache replication group identifier. + replication_group_id: "elasticache-replication-group-1" + # MemoryDB-specific configuration. + memorydb: + # MemoryDB cluster name. + cluster_name: "memorydb-cluster-1" + + # Optional AWS Secrets Manager configuration for managing ElastiCache + # or MemoryDB users. + # + # IMPORTANT: please make sure databases sharing the same Teleport-managed + # users have the same secret_store configuration. The configuration + # should also be consistent across all Database Services in High + # Availability (HA) mode. + secret_store: + # Prefix to all secrets created by the service. Defaults to 'teleport/'. + key_prefix: "teleport/" + # KMS Key ID used for secret encryption and description. If not + # specified, Secrets Manager uses AWS managed key 'aws/secretsmanager' + # by default. + kms_key_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # GCP specific configuration for Cloud SQL databases. gcp: diff --git a/docs/pages/includes/database-access/guides.mdx b/docs/pages/includes/database-access/guides.mdx index 05325a9eba3c3..96dc69af109e0 100644 --- a/docs/pages/includes/database-access/guides.mdx +++ b/docs/pages/includes/database-access/guides.mdx @@ -7,6 +7,9 @@ Connect AWS Redshift database. + + Connect AWS ElastiCache or AWS MemoryDB for Redis database. + Connect GCP Cloud SQL PostgreSQL database. @@ -40,6 +43,9 @@ Connect Microsoft SQL Server with Active Directory authentication. + + Connect Snowflake. + ## Other guides diff --git a/docs/pages/includes/database-access/rotation-note.mdx b/docs/pages/includes/database-access/rotation-note.mdx index e95abbb111ccb..7b57d167f0808 100644 --- a/docs/pages/includes/database-access/rotation-note.mdx +++ b/docs/pages/includes/database-access/rotation-note.mdx @@ -1,8 +1,10 @@ - Teleport 9.1 introduced new database certificate authority that is only used by Database Access. - Older Teleport versions uses host certificate to sign Database Access certificates. - After upgrading to Teleport 9.1 the host certificate authority will be still used by Database Access to maintain compatibility. + Teleport 10.0 introduced a new certificate authority that is only used by Database Access. + Older Teleport versions use a host certificate to sign Database Access certificates. + +After upgrading to Teleport 10.0, the host certificate authority will still be used by Database Access to maintain compatibility. The first [certificate rotation](../../setup/operations/ca-rotation.mdx) will rotate host and database certificates. - New Teleport 9.1+ installations generate database certificate authority on the first start and they are not affected + +New Teleport 10.0+ installations generate the database certificate authority when they first start, and are not affected by the rotation procedure described above. diff --git a/docs/pages/includes/install-linux.mdx b/docs/pages/includes/install-linux.mdx index 2c0b6651e9608..0a1b537a9bfd1 100644 --- a/docs/pages/includes/install-linux.mdx +++ b/docs/pages/includes/install-linux.mdx @@ -1,3 +1,4 @@ + ```code @@ -63,3 +64,41 @@ + + + +Visit the [Downloads Page](https://dashboard.gravitational.com/web/downloads) in +the customer portal and select the URL for your package of choice. + +Next, use the appropriate commands for your environment to install your package. + +For example, use the following commands to install Teleport on a machine with an +x86-64 chip via tarball: + + +```code +$ curl https://get.gravitational.com/teleport-ent-v(=teleport.version=)-linux-amd64-bin.tar.gz.sha256 +# +$ curl -O https://get.gravitational.com/teleport-ent-v(=teleport.version=)-linux-amd64-bin.tar.gz +$ shasum -a 256 teleport-ent-v(=teleport.version=)-linux-amd64-bin.tar.gz +# Verify that the checksums match +$ tar -xzf teleport-ent-v(=teleport.version=)-linux-amd64-bin.tar.gz +$ cd teleport +$ sudo ./install +``` + +For FedRAMP/FIPS-compliant installations of Teleport Enterprise, package URLs +will be slightly different: + +```code +$ curl https://get.gravitational.com/teleport-ent-v(=teleport.version=)-linux-amd64-fips-bin.tar.gz.sha256 +# +$ curl -O https://get.gravitational.com/teleport-ent-v(=teleport.version=)-linux-amd64-fips-bin.tar.gz +$ shasum -a 256 teleport-ent-v(=teleport.version=)-linux-amd64-fips-bin.tar.gz +# Verify that the checksums match +$ tar -xzf teleport-ent-v(=teleport.version=)-linux-amd64-fips-bin.tar.gz +$ cd teleport +$ sudo ./install +``` + + \ No newline at end of file diff --git a/docs/pages/includes/node-logins.mdx b/docs/pages/includes/node-logins.mdx new file mode 100644 index 0000000000000..b46e29eb54eae --- /dev/null +++ b/docs/pages/includes/node-logins.mdx @@ -0,0 +1,17 @@ +When Teleport's Auth Service receives a request to list Teleport Nodes (e.g., to +display Nodes in the Web UI or via `tsh ls`), it only returns the Nodes that the +current user is authorized to view. + +For each Node in the user's Teleport cluster, the Auth Service applies the +following checks in order and, if one check fails, hides the Node from the user: + +- None of the user's roles contain a `deny` rule that matches the Node's labels. +- None of the user's roles contain a `deny` rule that matches the user's login. +- At least one of the user's roles contains an `allow` rule that matches the + Node's labels. +- At least one of the user's roles contains an `allow` rule that matches the + user's login. + +If you are not seeing Nodes when expected, make sure that your user's roles +include the appropriate `allow` and `deny` rules as documented in the +[Teleport Access Controls Reference](../access-controls/reference.mdx). \ No newline at end of file diff --git a/docs/pages/includes/role-spec.mdx b/docs/pages/includes/role-spec.mdx new file mode 100644 index 0000000000000..e2127ece78932 --- /dev/null +++ b/docs/pages/includes/role-spec.mdx @@ -0,0 +1,295 @@ +```yaml +kind: role +version: v5 +metadata: + name: example +spec: + # options specify connection, in case if user has multiple non-default + # conflicting options, teleport chooses the least permissive value. + options: + # max_session_ttl defines the TTL (time to live) of certificates + # issued to the users with this role. + max_session_ttl: 8h + # forward_agent controls whether SSH agent forwarding is allowed + forward_agent: true + # port_forwarding controls whether TCP port forwarding is allowed for SSH + port_forwarding: true + # client_idle_timeout determines if SSH sessions to cluster nodes are + # forcefully terminated after no activity from a client (idle client). + # it overrides the global cluster setting. examples: "30m", "1h" or "1h30m" + client_idle_timeout: never + # Determines if the clients will be forcefully disconnected when their + # certificates expire in the middle of an active session. + # It overrides the global cluster setting. + disconnect_expired_cert: no + # max_sessions is total number of session channels that can be established + # across a single connection. Setting it to 10 matches OpenSSH default behavior. + max_sessions: 10 + # Defines which events are recorded by the BPF-based session recorder. + enhanced_recording: + - command + - disk + - network + # permit_x11_forwarding allows users to use X11 forwarding with openssh + # clients and servers through the proxy + permit_x11_forwarding: true + # require_session_mfa require per-session MFA for any owner of this role + require_session_mfa: true + # lock sets locking mode for user of this role, + # valid values are "strict" or "best_effort" + lock: strict + # enterprise-only request_access field is either 'always' or 'reason'. If set to always, it instructs + # tsh or the web UI clients to always create an access request on login. If it is + # set to 'reason', the user will be required to indicate why they are + # generating the access request. + request_access: reason + # the `request_prompt` field can be used to tell the user what should + # be supplied in the request reason field. + request_prompt: Please provide your ticket ID + # enterprise-only max_connections field sets a limit of concurrent sessions within a + # cluster. This setting slows down Teleport performance because it has to track + # connections cluster-wide. + max_connections: 2 + # limit number of concurrent Kubernetes sessions per user + max_kubernetes_connections: 1 + # Specify whether or not to record the user's desktop sessions. + # Desktop session recording is enabled if one or more of the user's + # roles has enabled recording. Defaults to true if unspecified. + # Desktop sessions will never be recorded if auth_service.session_recording + # is set to 'off' in teleport.yaml or if the cluster's session_recording_config + # resource has set 'mode: off'. + record_session: + desktop: true + # Specify whether clipboard sharing should be allowed with the + # remote desktop (requires a supported browser). Defaults to true + # if unspecified. If one or more of the user's roles has disabled + # the clipboard, then it will be disabled. + desktop_clipboard: true + # enterprise-only: when enabled, the source IP that was used to log in is embedded in the SSH + # certificate, preventing a compromised certificate from being used on other + # devices. The default is false. + pin_source_ip: true + # Specify a list of names and associated values to be included in user SSH keys. + # The key type can only be "ssh" and the mode can only be "extension". + # The name and value fields can be arbitrary strings and the value field + # supports variable interpolation. + cert_extensions: + - type: ssh + mode: extension + name: login@github.com + value: "{{ external.github_login }}" + # Controls whether this role supports auto provisioning of users. + create_host_user: true + + # The allow section declares a list of resource/verb combinations that are + # allowed for the users of this role. By default, nothing is allowed. + allow: + # The logins array defines the OS/UNIX logins a user is allowed to use. + # both strings and template variables are supported in this field + logins: [root, '{{internal.logins}}'] + + # Windows logins a user is allowed to use for desktop sessions. + windows_desktop_logins: [Administrator, '{{internal.logins}}'] + + # node_labels: a user with this role will be allowed to connect to + # SSH nodes, which labels match expressions below. + node_labels: + # literal strings: + 'env': 'test' + # the wildcard ('*') means "any node" + '*': '*' + # a list of alternative options: + 'region': ['us-west-1', 'eu-central-1'] + # regular expressions start with ^ and end with $ + # Teleport uses golang regexp syntax. + # of the list example above can be expressed as: + 'reg': '^us-west-1|eu-central-1$' + + # kubernetes_groups specifies Kubernetes groups a user with this role will assume. + # You can refer to a SAML/OIDC trait via the "external" property bag. + # This allows you to specify Kubernetes group membership in an identity manager: + kubernetes_groups: ["system:masters", "{{external.trait_name}}"] + + # kubernetes_users is an optional field that specifies kubernetes users + # this role can assume. + kubernetes_users: ['IAM#{{external.foo}};'] + + # kubernetes_labels: a user with this role will be allowed to connect to + # k8s clusters, which labels match expressions below. + kubernetes_labels: + # A user can only access prod environments + 'env': 'prod' + # User can access any region in us-west, e.g us-west-1, us-west-2 + 'region': 'us-west-*' + # regular expressions start with ^ and ending with $ + # Teleport uses golang regexp syntax. + 'cluster_name': '^us.*\.example\.com$' + + # Functions transform variables. + db_users: ['{{email.local(external.email)}}'] + db_names: ['{{external.db_names}}'] + db_labels: + 'env': '{{regexp.replace(external.access["env"], "^(staging)$", "$1")}}' + + # app_labels: a user with this role will be allowed to connect to + # applications, which labels match expressions below. + app_labels: + # A user can only access prod environments + 'env': 'prod' + # User can access any region in us-west, e.g us-west-1, us-west-2 + 'region': 'us-west-*' + # Regular expressions start with ^ and end with $. + # Teleport uses Go's regular expression syntax: + # https://github.com/google/re2/wiki/Syntax + # The list example above can be expressed as: + # 'region': '^us-west-1|eu-central-1$' + 'cluster_name': '^us.*\.example\.com$' + + # aws_role_arns allows a user with this role to assume AWS roles when + # accessing AWS console using UI or AWS API using CLI + aws_role_arns: + - 'arn:aws:iam::1234567890:role/ec2-read-only' + - 'arn:aws:iam::1234567890:role/ec2-full-access' + - 'arn:aws:iam::0987654321:role/example-role' + + # impersonate allows a user with this role to issue certificates on behalf + # of other users and roles matching expressions below + impersonate: + users: ['*'] + roles: ['jenkins'] + # where is an optional where condition + # further limiting the scope for matching users and roles + where: > + contains(user.spec.traits["group"], impersonate_role.metadata.labels["group"]) && + contains(user.spec.traits["group"], impersonate_user.metadata.labels["group"]) + + # review_requests allows a user holding this role + # to approve or deny access requests + review_requests: + roles: ['dbadmin'] + + # request allows a user user request roles matching + # expressions below + request: + # the `roles` list can be a mixture of literals and wildcard matchers + roles: ['common', 'dev-*'] + + # `search_as_roles` allows users to search for and request access to + # resources accessible by the listed roles + search_as_roles: ['access'] + + # thresholds specifies minimum amount of approvers and deniers, + # defaults to 1 for both + thresholds: + # requires at least two qualifying approvers and at least one denier. + - approve: 2 + deny: 1 + + # the `claims_to_roles` mapping works the same as it does in + # the OIDC connector, with the added benefit that the roles being mapped to + # can also be matchers. the below mapping says that users with + # the claims `groups: admins` can request any role in the system. + claims_to_roles: + - claim: 'projects' + # matches all group names with a leading 'product-' + value: '^product-(.*)$' + # generates a role name from the value capture + roles: ['$1-admin'] + + # Teleport can attach annotations to pending access requests. these + # annotations may be literals, or be variable interpolation expressions, + # effectively creating a means for propagating selected claims from an + # external identity provider to the plugin system. + annotations: + foo: ['bar'] + groups: ['{{external.groups}}'] + + # Moderated Sessions policy that dictates requirements for starting a session. + require_session_join: + # Defines the name of the policy. The name serves only as an + # identifier in logs and for organisation/categorisation. + - name: Auditor oversight + # Specifies an RBAC predicate that is used to define + # which users count against the required user count of the policy. + filter: 'contains(user.roles, "auditor")' + # The different session kinds this policy applies to. + kinds: ['k8s', 'ssh'] + # A list of session participant modes that a participant must have + # one of in order to count against the policy. + modes: ['moderator'] + # The minimum amount of users that need to match the filter expression + # in order to satisfy the policy. + count: 1 + + # Moderated Sessions policy that dictates the ability to join sessions + join_sessions: + # Defines the name of the policy. The name serves only as an + # identifier in logs and for organisation/categorisation. + - name: Auditor oversight + # Allows one to join sessions created by other users with these roles + roles : ['prod-access'] + # The different session kinds this policy applies to. + kinds: ['k8s', 'ssh'] + # The list of session participant modes the role may join the session as. + modes: ['moderator', 'observer'] + + # rules allow a user holding this role to modify other resources + # matching expressions below + # supported resources: + # role - role resource + # user - user resource + # + # auth_connector - any auth connector resource + # oidc - OIDC connector resource + # saml - connector resource + # github - GitHub connector resource + # + # trusted_cluster - trusted cluster resource + # remote_cluster - remote cluster resource + # + # access_request - access request resource + # access_plugin_data - allows modifying access request plugin data + # + # session - session playback records + # ssh_session - an active SSH session + # event - structured audit logging event + # + # + # lock - lock resource. + # network_restrictions - restrictions for SSH sessions + # + # auth_server - auth server resource + # proxy - proxy resource + # node - SSH node resource + # app_server - application server resource + # db_server - database proxy server resource + # token - provisioning token resource + # cert_authority - certificate authority resource + # + # cluster_name - resource that contains the cluster name. + # cluster_config - resource that holds cluster level config + # cluster_auth_preference - type of authentication for this cluster + # session_recording_config - resource for session recording config + # cluster_audit_config - resource that holds cluster audit config + # cluster_networking_config - resource that holds cluster networking config + + rules: + - resources: [role] + verbs: [list, create, read, update, delete] + - resources: [auth_connector] + verbs: [list, create, read, update, delete] + - resources: [session] + verbs: [list, read] + - resources: [trusted_cluster] + verbs: [list, create, read, update, delete] + - resources: [event] + verbs: [list, read] + - resources: [user] + verbs: [list, create, read, update, delete] + - resources: [token] + verbs: [list, create, read, update, delete] + + # The deny section uses the identical format as the 'allow' section. + # The deny rules always override allow rules. + deny: {} +``` diff --git a/docs/pages/includes/sso/loginerrortroubleshooting.mdx b/docs/pages/includes/sso/loginerrortroubleshooting.mdx index c7744f79347a2..6aa4aef8f656f 100644 --- a/docs/pages/includes/sso/loginerrortroubleshooting.mdx +++ b/docs/pages/includes/sso/loginerrortroubleshooting.mdx @@ -37,15 +37,7 @@ Example of a user being denied because the role `clusteradmin` wasn't set up: ### Teleport does not show the expected Nodes -When Teleport's Auth Service receives a request to list Teleport Nodes, -it only returns the Nodes that a user is authorized to access. - -A user's Teleport roles must grant the user explicit access to Nodes with a particular label - before the user can view those Nodes. The Auth Service compares the user's -`traits.logins` with the `allow` and `deny` rules defined in each of the user's roles. -If the user's logins match a role's `allow` and `deny` rules, and a Node's labels match -the keys and values listed within a role's `node_labels` field, then the Auth Service will -list the Node in response to the user's request. +(!docs/pages/includes/node-logins.mdx!) When configuring SSO, ensure that the identity provider is populating each user's traits correctly. For a user to see a Node in Teleport, the result of populating a diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 3b9082dc40737..ac4c799027263 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -3,7 +3,7 @@ title: Introduction to Teleport description: How to install and quickly get up and running with Teleport. h1: Introduction layout: tocless-doc -videoBanner: ErhTeypZ2gw +videoBanner: bA4bkkaCd1w --- Teleport is a certificate authority and access plane for your infrastructure. @@ -20,7 +20,7 @@ With Teleport you can: Quickly see how Teleport works in one of our demo environments. - + Try Teleport using our guided interactive labs. @@ -42,7 +42,7 @@ You can also [compare Teleport editions](faq.mdx#how-is-open-source-different-fr Learn how to host your own open source Teleport deployment on a standalone @@ -52,7 +52,7 @@ You can also [compare Teleport editions](faq.mdx#how-is-open-source-different-fr Get started with a self-hosted Teleport Enterprise deployment, which gives you @@ -60,7 +60,7 @@ You can also [compare Teleport editions](faq.mdx#how-is-open-source-different-fr - + Try Teleport hosted by us in the cloud for free. diff --git a/docs/pages/installation.mdx b/docs/pages/installation.mdx index f8b56118612de..d00921f6403cb 100644 --- a/docs/pages/installation.mdx +++ b/docs/pages/installation.mdx @@ -40,9 +40,19 @@ All installations include `teleport`, `tsh`, `tctl`, and `tbot`. (!docs/pages/includes/install-linux.mdx!) + + Check the [Downloads](https://goteleport.com/download/) page for the most up-to-date information. + + + +Check the [Downloads](./cloud/downloads.mdx) page for the most +up-to-date information. + + + ## Docker @@ -102,6 +112,7 @@ chart. ## macOS + @@ -215,6 +226,30 @@ chart. + + + You can download one of the following .pkg installers for macOS: + + |Link|Binaries| + |-|-| + |[`teleport-ent-(=teleport.version=).pkg`](https://get.gravitational.com/teleport-ent-(=teleport.version=).pkg)|`teleport`
    `tctl`
    `tsh`
    `tbot`| + |[`tsh-(=teleport.version=).pkg`](https://get.gravitational.com/tsh-(=teleport.version=).pkg)|`tsh`| + + You can also fetch an installer via the command line: + + ```code + $ curl -O https://get.gravitational.com/teleport-ent-(=teleport.version=).pkg + # Installs on Macintosh HD + $ sudo installer -pkg teleport-ent-(=teleport.version=).pkg -target / + # Password: + # installer: Package name is teleport-ent-(=teleport.version=) + # installer: Upgrading at base path / + # installer: The upgrade was successful. + $ which teleport + # /usr/local/bin/teleport + ``` + +
    ## Windows (tsh client only) diff --git a/docs/pages/kubernetes-access/controls.mdx b/docs/pages/kubernetes-access/controls.mdx index bb4f6b43c0798..955763e2d2a11 100644 --- a/docs/pages/kubernetes-access/controls.mdx +++ b/docs/pages/kubernetes-access/controls.mdx @@ -123,8 +123,9 @@ Create or update this role using `tctl`: ```code -# Log in to your Teleport cluster so you can use tctl remotely. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser $ tctl create -f member.yaml ``` diff --git a/docs/pages/kubernetes-access/getting-started.mdx b/docs/pages/kubernetes-access/getting-started.mdx index 2aa84e6bf20af..3a21d33690e3d 100644 --- a/docs/pages/kubernetes-access/getting-started.mdx +++ b/docs/pages/kubernetes-access/getting-started.mdx @@ -1,40 +1,176 @@ --- -title: Getting Started with Kubernetes Access -description: Getting started with Teleport Kubernetes Access. -videoBanner: VPGYLEMTdJ8 -layout: tocless-doc +title: Connect a Kubernetes Cluster to Teleport +description: Connecting a Kubernetes cluster to Teleport --- - +## Prerequisites -## Deploy Teleport on Kubernetes +(!docs/pages/includes/edition-prereqs-tabs.mdx!) -See how you can deploy the Teleport Auth Service and Proxy Service on a -Kubernetes cluster. +- The `jq` tool to process `JSON` output. This is available via common package managers. - - - ![Teleport ](../../img/k8s/mini-diagrams/teleport-in-k8s-mono.svg) - Quickly see how Teleport works with Kubernetes on your laptop. - - - ![Teleport ](../../img/k8s/mini-diagrams/teleport-in-k8s-mono.svg) - Deploy a standalone Teleport cluster in a Kubernetes cluster. - - +(!docs/pages/includes/kubernetes-access/helm-k8s.mdx!) - +(!docs/pages/includes/tctl.mdx!) -## Use Teleport to access a Kubernetes cluster +## Deployment overview -Register your Kubernetes clusters with Teleport for secure `kubectl` -connections, fine-grained RBAC, and more. +In this guide, we deploy the Teleport Kubernetes Service, which connects +Kubernetes cluster `cookie` to Teleport cluster `tele.example.com`: - - - ![Kubernetes agent](../../img/k8s/mini-diagrams/k8s-to-teleport-mono.svg) + - Get started with Teleport Kubernetes Access. +In your Teleport Cloud account, the name of your cluster will be your tenant +domain name, e.g., `mytenant.teleport.sh`, rather than `teleport.example.com`. - - + + +
    + ![Kubernetes agent](../../img/k8s/agent.svg) +
    + +## Step 1/3. Get a join token + +In order to start the Teleport Kubernetes Service, we will need to request a +join token from the Teleport Auth Service: + +```code +# Create a join token for the Teleport Kubernetes Service to authenticate +$ TOKEN=$(tctl nodes add --roles=kube --ttl=10000h --format=json | jq -r '.[0]') +$ echo $TOKEN +``` + +## Step 2/3. Deploy teleport-kube-agent + + + +The Teleport agent version should be the same as the Teleport Cluster version +or up to one major version back. You can set the version override with the override variable, ex: `--set teleportVersionOverride=(=teleport.version=)`. + + + + + + +Switch `kubectl` to the Kubernetes cluster `cookie` and run the following +commands, assigning `PROXY_ADDR` to the address of your Auth Service or Proxy +Service. + +```code +# Add teleport-agent chart to charts repository +$ PROXY_ADDR=tele.example.com:443 +$ helm repo add teleport https://charts.releases.teleport.dev +$ helm repo update + +# Install Kubernetes agent. It dials back to the Teleport cluster at $PROXY_ADDR +$ CLUSTER='cookie' +$ helm install teleport-agent teleport/teleport-kube-agent --set kubeClusterName=${CLUSTER?} \ + --set proxyAddr=${PROXY_ADDR?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent +``` + + + + +Switch `kubectl` to the Kubernetes cluster `cookie` and run the following +commands, assigning `PROXY_ADDR` to the address of your Teleport Cloud tenant. + +```code +# Add teleport-agent chart to charts repository +$ PROXY_ADDR=mytenant.teleport.sh:443 +$ helm repo add teleport https://charts.releases.teleport.dev +$ helm repo update + +# Install Kubernetes agent. It dials back to the Teleport cluster at $PROXY_ADDR +$ CLUSTER='cookie' +# Run the helm install specifying to match to the Teleport Cloud version of Teleport +$ helm install teleport-agent teleport/teleport-kube-agent --set kubeClusterName=${CLUSTER?} \ + --set proxyAddr=${PROXY_ADDR?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent \ + --set teleportVersionOverride=(=cloud.version=) +``` + + + + +## Step 3/3 Access your Kubernetes cluster + +### Grant access to your Teleport user + +To use Teleport to interact with a Kubernetes cluster, your Teleport roles must +allow access from your Kubernetes user and groups. Ensure that you have a +Teleport role that grants access to the cluster you plan to interact with. + +Run the following command to get the Kubernetes user for your current context: + +```code +$ kubectl config view \ +-o jsonpath="{.contexts[?(@.context.cluster==\"$(kubectl config current-context)\")].context.user}" +cookie +``` + +Create a file called `kube-user.yaml` with the following content, replacing +`USER` with the output of the command above. + +```yaml +kind: role +metadata: + name: kube-user +version: v5 +spec: + allow: + kubernetes_labels: + '*': '*' + kubernetes_groups: + - view + kubernetes_users: + - USER + deny: {} +``` + +Retrieve your user: + +```code +$ TELEPORT_USER=myuser +$ tctl get user/${TELEPORT_USER?} > user.yaml +``` + +Add `kube-user` to your Teleport user's list of roles: + +```diff + roles: + - access + - auditor ++ - kube-user +``` + +Apply your changes: + +```code +$ tctl create -f kube-user.yaml +$ tctl create -f user.yaml +``` + +Log out of Teleport and log in again. + +### View pods in your cluster + +List connected clusters using `tsh kube ls` and switch between +them using `tsh kube login`: + +```code +$ tsh kube ls + +# Kube Cluster Name Selected +# ----------------- -------- +# cookie + +# kubeconfig now points to the cookie cluster +$ tsh kube login cookie +# Logged into kubernetes cluster "cookie" + +# kubectl command executed on `cookie` but is routed through the Teleport cluster. +$ kubectl get pods +``` + +## Next Steps + +- Take a look at a [kube-agent helm chart reference](./helm/reference/teleport-kube-agent.mdx) for a full list of parameters. diff --git a/docs/pages/kubernetes-access/getting-started/agent.mdx b/docs/pages/kubernetes-access/getting-started/agent.mdx deleted file mode 100644 index 54feb7d9fa7c2..0000000000000 --- a/docs/pages/kubernetes-access/getting-started/agent.mdx +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: Connect a Kubernetes Cluster to Teleport -description: Connecting a Kubernetes cluster to Teleport ---- - -## Prerequisites - -(!docs/pages/includes/edition-prereqs-tabs.mdx!) - -- The `jq` tool to process `JSON` output. This is available via common package managers. - -(!docs/pages/includes/kubernetes-access/helm-k8s.mdx!) - -(!docs/pages/includes/tctl.mdx!) - -## Deployment overview - -In this guide, we deploy the Teleport Kubernetes Service, which connects -Kubernetes cluster `cookie` to Teleport cluster `tele.example.com`: - - - -In your Teleport Cloud account, the name of your cluster will be your tenant -domain name, e.g., `mytenant.teleport.sh`, rather than `teleport.example.com`. - - - -
    - ![Kubernetes agent](../../../img/k8s/agent.svg) -
    - -## Step 1/3. Get a join token - -In order to start the Teleport Kubernetes Service, we will need to request a -join token from the Teleport Auth Service: - -```code -# Create a join token for the Teleport Kubernetes Service to authenticate -$ TOKEN=$(tctl nodes add --roles=kube --ttl=10000h --format=json | jq -r '.[0]') -$ echo $TOKEN -``` - -## Step 2/3. Deploy teleport-kube-agent - - - -The Teleport agent version should be the same as the Teleport Cluster version -or up to one major version back. You can set the version override with the override variable, ex: `--set teleportVersionOverride=(=teleport.version=)`. - - - - - - -Switch `kubectl` to the Kubernetes cluster `cookie` and run the following -commands, assigning `PROXY_ADDR` to the address of your Auth Service or Proxy -Service. - -```code -# Add teleport-agent chart to charts repository -$ PROXY_ADDR=tele.example.com:443 -$ helm repo add teleport https://charts.releases.teleport.dev -$ helm repo update - -# Install Kubernetes agent. It dials back to the Teleport cluster at $PROXY_ADDR -$ CLUSTER='cookie' -$ helm install teleport-agent teleport/teleport-kube-agent --set kubeClusterName=${CLUSTER?} \ - --set proxyAddr=${PROXY_ADDR?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent -``` - - - - -Switch `kubectl` to the Kubernetes cluster `cookie` and run the following -commands, assigning `PROXY_ADDR` to the address of your Teleport Cloud tenant. - -```code -# Add teleport-agent chart to charts repository -$ PROXY_ADDR=mytenant.teleport.sh:443 -$ helm repo add teleport https://charts.releases.teleport.dev -$ helm repo update - -# Install Kubernetes agent. It dials back to the Teleport cluster at $PROXY_ADDR -$ CLUSTER='cookie' -# Run the helm install specifying to match to the Teleport Cloud version of Teleport -$ helm install teleport-agent teleport/teleport-kube-agent --set kubeClusterName=${CLUSTER?} \ - --set proxyAddr=${PROXY_ADDR?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent \ - --set teleportVersionOverride=(=cloud.version=) -``` - - - - -## Step 3/3 Access your Kubernetes cluster - -### Grant access to your Teleport user - -To use Teleport to interact with a Kubernetes cluster, your Teleport roles must -allow access from your Kubernetes user and groups. Ensure that you have a -Teleport role that grants access to the cluster you plan to interact with. - -Run the following command to get the Kubernetes user for your current context: - -```code -$ kubectl config view \ --o jsonpath="{.contexts[?(@.context.cluster==\"$(kubectl config current-context)\")].context.user}" -cookie -``` - -Create a file called `kube-user.yaml` with the following content, replacing -`USER` with the output of the command above. - -```yaml -kind: role -metadata: - name: kube-user -version: v5 -spec: - allow: - kubernetes_labels: - '*': '*' - kubernetes_groups: - - view - kubernetes_users: - - USER - deny: {} -``` - -Retrieve your user: - -```code -$ TELEPORT_USER=myuser -$ tctl get user/${TELEPORT_USER?} > user.yaml -``` - -Add `kube-user` to your Teleport user's list of roles: - -```diff - roles: - - access - - auditor -+ - kube-user -``` - -Apply your changes: - -```code -$ tctl create -f kube-user.yaml -$ tctl create -f user.yaml -``` - -Log out of Teleport and log in again. - -### View pods in your cluster - -List connected clusters using `tsh kube ls` and switch between -them using `tsh kube login`: - -```code -$ tsh kube ls - -# Kube Cluster Name Selected -# ----------------- -------- -# cookie - -# kubeconfig now points to the cookie cluster -$ tsh kube login cookie -# Logged into kubernetes cluster "cookie" - -# kubectl command executed on `cookie` but is routed through the Teleport cluster. -$ kubectl get pods -``` - -## Next Steps - -- Take a look at a [kube-agent helm chart reference](../helm/reference/teleport-kube-agent.mdx) for a full list of parameters. diff --git a/docs/pages/kubernetes-access/guides/cicd.mdx b/docs/pages/kubernetes-access/guides/cicd.mdx index c8a231ede8c4c..657ece4aa943b 100644 --- a/docs/pages/kubernetes-access/guides/cicd.mdx +++ b/docs/pages/kubernetes-access/guides/cicd.mdx @@ -43,8 +43,9 @@ Generate a `kubeconfig` using the `jenkins` user and its roles using [`tctl auth ```code -# Log in to your Teleport cluster so you can use tctl remotely. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser # Create a new local user for Jenkins $ tctl users add jenkins --roles=robot diff --git a/docs/pages/kubernetes-access/guides/multiple-clusters.mdx b/docs/pages/kubernetes-access/guides/multiple-clusters.mdx index 3ed5e0540c866..3a50f81044f2f 100644 --- a/docs/pages/kubernetes-access/guides/multiple-clusters.mdx +++ b/docs/pages/kubernetes-access/guides/multiple-clusters.mdx @@ -12,7 +12,7 @@ This guide will show you how to use Teleport as an access plane for multiple Kub - The Teleport Kubernetes Service running in a Kubernetes cluster, version >= v(=kubernetes.major_version=).(=kubernetes.minor_version=).0. We will assume that you have already followed - [Connect a Kubernetes Cluster to Teleport](../getting-started/agent.mdx) + [Connect a Kubernetes Cluster to Teleport](../getting-started.mdx) - The `jq` tool to process `JSON` output. This is available via common package managers - An additional Kubernetes cluster version >= diff --git a/docs/pages/kubernetes-access/helm/guides.mdx b/docs/pages/kubernetes-access/helm/guides.mdx deleted file mode 100644 index 031b27a2af797..0000000000000 --- a/docs/pages/kubernetes-access/helm/guides.mdx +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Guides for running Teleport using Helm -description: How to install and configure Teleport in Kubernetes using Helm -layout: tocless-doc ---- - -## Helm guides - -These guides show you how to set up a full self-hosted Teleport deployment using -our `teleport-cluster` Helm chart. - - - - - Getting started with Kubernetes Access - - - Running an HA Teleport cluster in Kubernetes using an AWS EKS Cluster - - - Running an HA Teleport cluster in Kubernetes using a Google Cloud GKE cluster - - - Running a Teleport cluster in Kubernetes with a custom Teleport config - - - - - - - Learn how to deploy an open source Teleport cluster using Helm. - - - Learn how to deploy a Teleport Enterprise cluster using Helm. - - - - -## Detailed Helm chart references - - - - -Deploy the `teleport` daemon on Kubernetes with preset configurations for the -Auth and Proxy Services and support for any Teleport service configuration. - - - - -Deploy the Teleport Kubernetes Service, Application Service, or Database Service on Kubernetes. - - - - - -## Migration Guides - - - - - - - \ No newline at end of file diff --git a/docs/pages/kubernetes-access/helm/reference/teleport-cluster.mdx b/docs/pages/kubernetes-access/helm/reference/teleport-cluster.mdx index e947635b88370..1e03381817002 100644 --- a/docs/pages/kubernetes-access/helm/reference/teleport-cluster.mdx +++ b/docs/pages/kubernetes-access/helm/reference/teleport-cluster.mdx @@ -23,9 +23,9 @@ The `teleport-cluster` chart can be deployed in four different modes. Get starte | `chartMode` | Guide | | - | - | | `standalone` | [Getting started with Kubernetes Access](../../../getting-started.mdx) | -| `aws` | [Running an HA Teleport cluster using an AWS EKS Cluster](../guides/aws.mdx) | -| `gcp` | [Running an HA Teleport cluster using a Google Cloud GKE cluster](../guides/gcp.mdx) | -| `custom` | [Running a Teleport cluster with a custom config](../guides/custom.mdx) | +| `aws` | [Running an HA Teleport cluster using an AWS EKS Cluster](../../../setup/helm-deployments/aws.mdx) | +| `gcp` | [Running an HA Teleport cluster using a Google Cloud GKE cluster](../../../setup/helm-deployments/gcp.mdx) | +| `custom` | [Running a Teleport cluster with a custom config](../../../setup/helm-deployments/custom.mdx) | This reference details available values for the `teleport-cluster` chart. @@ -395,9 +395,9 @@ Teleport's RBAC policies to define access rules for the cluster. | `chartMode` | Guide | | - | - | | `standalone` | [Getting started with Kubernetes Access](../../../getting-started.mdx) | -| `aws` | [Running an HA Teleport cluster using an AWS EKS Cluster](../guides/aws.mdx) | -| `gcp` | [Running an HA Teleport cluster using a Google Cloud GKE cluster](../guides/gcp.mdx) | -| `custom` | [Running a Teleport cluster with a custom config](../guides/custom.mdx) | +| `aws` | [Running an HA Teleport cluster using an AWS EKS Cluster](../../../setup/helm-deployments/aws.mdx) | +| `gcp` | [Running an HA Teleport cluster using a Google Cloud GKE cluster](../../../setup/helm-deployments/gcp.mdx) | +| `custom` | [Running a Teleport cluster with a custom config](../../../setup/helm-deployments/custom.mdx) | ## `persistence` @@ -479,7 +479,7 @@ You can set `volumeSize` to request a different size of persistent volume when i | - | - | | ❌ | See [Using DynamoDB](../../../setup/reference/backends.mdx#dynamodb) and [Using Amazon S3](../../../setup/reference/backends.mdx#s3) for details | -`aws` settings are described in the AWS guide: [Running an HA Teleport cluster using an AWS EKS Cluster](../guides/aws.mdx) +`aws` settings are described in the AWS guide: [Running an HA Teleport cluster using an AWS EKS Cluster](../../../setup/helm-deployments) ## `gcp` @@ -487,7 +487,7 @@ You can set `volumeSize` to request a different size of persistent volume when i | - | - | | ❌ | See [Using Firestore](../../../setup/reference/backends.mdx#dynamodb) and [Using GCS](../../../setup/reference/backends.mdx#gcs) for details | -`gcp` settings are described in the GCP guide: [Running an HA Teleport cluster using a Google Cloud GKE cluster](../guides/gcp.mdx) +`gcp` settings are described in the GCP guide: [Running an HA Teleport cluster using a Google Cloud GKE cluster](../../../setup/helm-deployments/gcp.mdx) ### `highAvailability` @@ -515,7 +515,7 @@ Set to a number higher than `1` for a high availability mode where multiple Tele When using `custom` mode, you **must** use highly-available storage (e.g. etcd, DynamoDB or Firestore) for multiple replicas to be supported. - [Information on supported Teleport storage backends](../../../architecture/authentication.mdx#storage-back-ends) + [Information on supported Teleport storage backends](../../../setup/reference/backends.mdx) Manually configuring NFS-based storage or `ReadWriteMany` volume claims is **NOT** supported for an HA deployment and will result in errors. @@ -639,7 +639,7 @@ cluster deployed in HA mode. You must install and configure `cert-manager` in your Kubernetes cluster yourself. See the [cert-manager Helm install instructions](https://cert-manager.io/docs/installation/kubernetes/#option-2-install-crds-as-part-of-the-helm-release) - and the relevant sections of the [AWS](../guides/aws.mdx#step-47-configure-tls-certificates-for-teleport) and [GCP](../guides/gcp.mdx#step-47-install-and-configure-cert-manager) guides for more information. + and the relevant sections of the [AWS](../../../setup/helm-deployments/aws.mdx#step-47-configure-tls-certificates-for-teleport) and [GCP](../../../setup/helm-deployments/gcp.mdx#step-47-install-and-configure-cert-manager) guides for more information.
    ### `highAvailability.certManager.addCommonName` @@ -654,7 +654,7 @@ Setting `highAvailability.certManager.addCommonName` to `true` will instruct `ce You must install and configure `cert-manager` in your Kubernetes cluster yourself. See the [cert-manager Helm install instructions](https://cert-manager.io/docs/installation/kubernetes/#option-2-install-crds-as-part-of-the-helm-release) - and the relevant sections of the [AWS](../guides/aws.mdx#step-47-configure-tls-certificates-for-teleport) and [GCP](../guides/gcp.mdx#step-47-install-and-configure-cert-manager) guides for more information. + and the relevant sections of the [AWS](../../../setup/helm-deployments/aws.mdx#step-47-configure-tls-certificates-for-teleport) and [GCP](../../../setup/helm-deployments/gcp.mdx#step-47-install-and-configure-cert-manager) guides for more information. @@ -688,7 +688,7 @@ Sets the name of the `cert-manager` `Issuer` or `ClusterIssuer` to use for issui You must install configure an appropriate `Issuer` supporting a DNS01 challenge yourself. Please see the [cert-manager DNS01 docs](https://cert-manager.io/docs/configuration/acme/dns01/#supported-dns01-providers) and the relevant sections - of the [AWS](../guides/aws.mdx#step-47-configure-tls-certificates-for-teleport) and [GCP](../guides/gcp.mdx#step-47-install-and-configure-cert-manager) guides for more information. + of the [AWS](../../../setup/helm-deployments/aws.mdx#step-47-configure-tls-certificates-for-teleport) and [GCP](../../../setup/helm-deployments/gcp.mdx#step-47-install-and-configure-cert-manager) guides for more information. diff --git a/docs/pages/kubernetes-access/introduction.mdx b/docs/pages/kubernetes-access/introduction.mdx index f1a98dd8674c9..2a2a14e49e436 100644 --- a/docs/pages/kubernetes-access/introduction.mdx +++ b/docs/pages/kubernetes-access/introduction.mdx @@ -3,12 +3,11 @@ title: Kubernetes Access description: Teleport Kubernetes Access introduction, demo, and resources. --- -Teleport provides secure access for Kubernetes clusters. +Teleport provides secure access to Kubernetes clusters. - Users can receive short-lived kubeconfig files (and certificates) using Single Sign-On (SSO) and switch between clusters without logging in twice. - Admins can use roles to implement policies, such as the best practice that developers must not access production. - Organizations can achieve compliance by capturing `kubectl` events and session recordings for `kubectl`. -- Admins can host the Teleport Auth Service and Proxy Service within a Kubernetes Cluster. ## SSO and Audit for Kubernetes Clusters @@ -32,27 +31,10 @@ Set up SSO, capture audit events, and sessions with Teleport running in a Kubern Your browser does not support the video tag. -## Getting started - - - -### Deploy Teleport on Kubernetes - - - - Quickly see how Teleport works with Kubernetes on your laptop. - - - Deploy a standalone Teleport cluster in a Kubernetes cluster. - - - - -### Use Teleport to access a Kubernetes cluster - +## Get started - + Get started with Teleport Kubernetes Access. diff --git a/docs/pages/machine-id/getting-started.mdx b/docs/pages/machine-id/getting-started.mdx index 02ca07c09f4ad..b50dfec040c33 100644 --- a/docs/pages/machine-id/getting-started.mdx +++ b/docs/pages/machine-id/getting-started.mdx @@ -3,15 +3,16 @@ title: Machine ID Getting Started Guide description: Getting started with Teleport Machine ID --- -In this getting started guide, you will use Machine ID to create a bot user for -a machine and use that identity to connect to said machine. +In this getting started guide, you will configure Machine ID to issue +certificates that enable a bot user to connect to a remote host. Here's an overview of what you will do: -1. Download and install Teleport (=teleport.version=) -2. Create a bot user -3. Start Machine ID -4. Use certificates issued by Machine ID to connect to a remote machine +1. Download and install `tbot` (=teleport.version=) on the host that will run + Machine ID. +2. Create a bot user. +3. Start Machine ID. +4. Use certificates issued by Machine ID to connect to a remote machine. ## Prerequisites @@ -21,10 +22,15 @@ Here's an overview of what you will do: (!/docs/pages/includes/tctl.mdx!) - -TLS Routing support will be added to Machine ID in [Teleport -9.3](https://goteleport.com/docs/preview/upcoming-releases/#teleport-93). Until -that time, the Teleport Proxy Server will need to be configured with a + + +TLS Routing support was added to Machine ID in [Teleport +9.3](https://goteleport.com/docs/preview/upcoming-releases/#teleport-93). For +earlier versions, the Teleport Proxy Server will need to be configured with a dedicated SSH listener. ```yaml @@ -148,44 +154,89 @@ the foreground to better understand how it works. + + + ```code $ tbot start \ --data-dir=/var/lib/teleport/bot \ --destination-dir=/opt/machine-id \ - --token=00000000000000000000000000000000 \ + --token=(=presets.tokens.first=) \ --join-method=token \ - --ca-pin=sha256:1111111111111111111111111111111111111111111111111111111111111111 \ + --ca-pin=(=presets.ca_pin=) \ --auth-server=auth.example.com:3025 ``` + + + + + ```code + $ tbot start \ + --data-dir=/var/lib/teleport/bot \ + --destination-dir=/opt/machine-id \ + --token=(=presets.tokens.first=) \ + --join-method=token \ + --ca-pin=(=presets.ca_pin=) \ + --auth-server=example.teleport.sh:443 + ``` + + + + + + ```code $ tbot start \ --data-dir=/var/lib/teleport/bot \ --destination-dir=/opt/machine-id \ --token=iam-token \ --join-method=iam \ - --ca-pin=sha256:1111111111111111111111111111111111111111111111111111111111111111 \ + --ca-pin=(=presets.ca_pin=) \ --auth-server=auth.example.com:3025 ``` + + + + + ```code + $ tbot start \ + --data-dir=/var/lib/teleport/bot \ + --destination-dir=/opt/machine-id \ + --token=iam-token \ + --join-method=iam \ + --ca-pin=(=presets.ca_pin=) \ + --auth-server=example.teleport.sh:443 + ``` + + + Replace the following fields with values from your own cluster. -- `token` is the token output by the `tctl bots add` command or the name of your IAM method token -- `ca-pin` is the CA Pin for your Teleport cluster, and is output by the `tctl bots add` command -- `destination-dir` is where Machine ID writes renewable certificates, which are only used by Machine ID and should not be used by applications and tools -- `data-dir` is where Machine ID writes the short-lived certificate. This certificate should be used by applications and tools -- `auth-server` is the address of your Teleport Cloud Proxy Server, for example `example.teleport.sh:443` + +- `token` is the token output by the `tctl bots add` command or the name of your IAM method token. +- `ca-pin` is the CA Pin for your Teleport cluster, and is output by the `tctl bots add` command. +- `destination-dir` is where Machine ID writes renewable certificates, which are only used by Machine ID and should not be used by applications and tools. +- `data-dir` is where Machine ID writes the short-lived certificate. This certificate should be used by applications and tools. +- `auth-server` is the address of your Teleport Cloud Proxy Server, for example `example.teleport.sh:443`. + -- `token` is the token output by the `tctl bots add` command or the name of your IAM method token -- `ca-pin` is the CA Pin for your Teleport cluster, and is output by the `tctl bots add` command -- `destination-dir` is where Machine ID writes renewable certificates, which are only used by Machine ID and should not be used by applications and tools -- `data-dir` is where Machine ID writes the short-lived certificate. This certificate should be used by applications and tools -- `auth-server` is the address of your Teleport Auth Server, for example `auth.example.com:3025` + +- `token` is the token output by the `tctl bots add` command or the name of your IAM method token. +- `ca-pin` is the CA Pin for your Teleport cluster, and is output by the `tctl bots add` command. +- `destination-dir` is where Machine ID writes renewable certificates, which are only used by Machine ID and should not be used by applications and tools. +- `data-dir` is where Machine ID writes the short-lived certificate. This certificate should be used by applications and tools. +- `auth-server` is the address of your Teleport Auth Server, for example + `auth.example.com:3025`. If your Machine ID host is in a different network + than your Auth Server, use the public web address of your Proxy Service + instead (e.g., `auth.example.com:443`). + Now that Machine ID has successfully started, let's investigate the @@ -223,6 +274,12 @@ Node Name Address Labels node-name 127.0.0.1:3022 arch=x86_64,group=api-servers ``` +
    + +(!docs/pages/includes/node-logins.mdx!) + +
    + To use Machine ID with the OpenSSH integration, run the following command to connect to `node-name` within cluster `example.com`. diff --git a/docs/pages/machine-id/guides/ansible.mdx b/docs/pages/machine-id/guides/ansible.mdx index 98173c582972a..dfdcfbe2795c3 100644 --- a/docs/pages/machine-id/guides/ansible.mdx +++ b/docs/pages/machine-id/guides/ansible.mdx @@ -76,6 +76,12 @@ $ # Replace ".example.com" below with the name of your cluster. $ tsh ls --format=json | jq -r '.[].spec.hostname + ".example.com"' > hosts ``` +
    + +(!docs/pages/includes/node-logins.mdx!) + +
    + ## Step 2/2. Run a playbook Finally, let's create a simple Ansible playbook, `playbook.yaml`. diff --git a/docs/pages/older-versions.mdx b/docs/pages/older-versions.mdx index eb214abd53d0b..6ae6ad6776c6a 100644 --- a/docs/pages/older-versions.mdx +++ b/docs/pages/older-versions.mdx @@ -7,10 +7,11 @@ layout: tocless-doc Deprecated versions of the Teleport docs can be found at the GitHub links below: +[Teleport 7.0](https://github.com/gravitational/teleport/tree/branch/v7)
    [Teleport 6.2](https://github.com/gravitational/teleport/tree/branch/v6.2)
    [Teleport 6.1](https://github.com/gravitational/teleport/tree/branch/v6.1)
    [Teleport 6.0](https://github.com/gravitational/teleport/tree/branch/v6.0)
    [Teleport 5](https://github.com/gravitational/teleport/tree/branch/5.0)
    [Teleport 4](https://github.com/gravitational/teleport/tree/branch/4.4)
    -You can also [return to the main documentation site](../). \ No newline at end of file +You can also [return to the main documentation site](../). diff --git a/docs/pages/preview/upcoming-releases.mdx b/docs/pages/preview/upcoming-releases.mdx index 122950ca0301e..7a33a3cb3d355 100644 --- a/docs/pages/preview/upcoming-releases.mdx +++ b/docs/pages/preview/upcoming-releases.mdx @@ -8,76 +8,80 @@ The teleport team delivers a new major release roughly every 3 months. ## Teleport -### Teleport 8.3 +### Teleport 10.1 -Teleport 8.3 will add support for IAM based joining on AWS and Session Moderation. +Teleport 10.1 will bring file upload/download support to Desktop Access, +Kubernetes Access and CA rotation support to Machine ID, and a Kubernetes +Operator. -https://github.com/gravitational/teleport/milestone/69 +| Version | Date | Description | +|-------------|-----------------|----------------------------| +| Release | Late-July 2022 | Good to go for production. | -| Version | Date | Description | -| ----------- | ------------------ | -------------------------------- | -| Release | February 14th, 2022 | Good to go for production. | +### Teleport 10.2 -You can find the full list of fixes and features in the [GitHub milestone](https://github.com/gravitational/teleport/milestone/69). +Teleport 10.2 will bring host certificate support to Machine ID, Elasticsearch +support to Database Access, automatic configuration of AD to Desktop Access, TCP +endpoint support to Application Access, and remove the need for a PVC to securely +deploy Teleport within a Kubernetes cluster. -### Teleport 9 +In addition, support for a notification-only automatic upgrade system will be +added to Teleport. -Teleport 9.0 will focus on bringing Desktop Access to GA with support for -session recording, per-session MFA, and clipboard support. Database Access -will add self-hosted Redis, auto-discovery for Redshift clusers, and -auto-IAM configuration improvements. +| Version | Date | Description | +|-------------|--------------|----------------------------| +| Release | August 2022 | Good to go for production. | -In addition, Teleport 9 will include preview releases of Microsoft SQL -Server with AD authentication for Database Access and Teleport Certificate Bot. +### Teleport 10.3 -| Version | Date | Description | -| ----------- | ------------------ | -------------------------------- | -| Alpha | Febuary 14th, 2022 | Good for some testing and demos. | -| Beta | Febuary 21st, 2022 | Deploy on staging. | -| Release | March 11th, 2022 | Good to go for production. | +Teleport 10 will bring Cassandra support to Database Access. -You can find the full list of fixes and features in the [GitHub milestone](https://github.com/gravitational/teleport/milestone/64). +| Version | Date | Description | +|-------------|-------------------|----------------------------| +| Release | September 2022 | Good to go for production. | ## Teleport Cloud -The key areas of focus for Teleport cloud in early 2022 are: +The key areas of focus for Teleport Cloud in Summer 2022 are: + - Ensuring the best routing and latency experience - Stronger outbound communications on cloud health and infrastructure changes - UX where the cloud offering differs from the on-prem offering +- Scheduled upgrades will limit downtime to non-peak hours ### Release Schedule -| Date | Description | -| - | - | -| March 2022 | Complete rollout of our [worldwide access design](https://goteleport.com/blog/access-proxy-latency/), allowing low-latency access from around the world. | -| April 2022 | Update security audit from independent auditors. [2021 Audit](https://goteleport.com/resources/audits/teleport-cloud-security-audit-2021/) | -| Q1 2022 | Roll out a technical communications framework, notifying technical contacts of planned maintenance, infrastructure changes and outages | -| Q1 2022 | Provide a public listing of IP addresses used by Teleport infrastructure for firewall configuration | -| Q2 2022 | Offer more data retention options | -| Q3 2022 | Option to store data in alternate regions around the world | - +| Date | Description | +|----------------|-------------| +| September 2022 | Complete rollout of our [worldwide access design](https://goteleport.com/blog/access-proxy-latency/), allowing low-latency access from around the world. | +| Q2 2022 | Update security audit from independent auditors. [2021 Audit](https://goteleport.com/resources/audits/teleport-cloud-security-audit-2021/) | +| Q2 2022 | Provide a public listing of IP addresses used by Teleport infrastructure for firewall configuration | ## Semantic Versioning -Teleport follows [semantic versioning](https://semver.org/) for pre-releases and releases. +Teleport follows [semantic versioning](https://semver.org/) for pre-releases +and releases. -**Pre-releases** +### Pre-releases -Pre-releases have suffixes `-alpha`, `-beta` and `-rc`. -They are not ready for production: +Pre-releases have suffixes `-alpha`, `-beta` and `-rc`. They are not ready for +production: - You can use alpha releases such as `5.0.1-alpha.1` for trying new features. Things can break and new changes may not be backwards-compatible. -- Teleport `beta` releases, such as `5.0.1-beta.2` are suitable for staging environments. - We are unlikely to change the APIs while we are ironing out bugs and UX glitches. +- Teleport `beta` releases, such as `5.0.1-beta.2` are suitable for staging + environments. We are unlikely to change the APIs while we are ironing out + bugs and UX glitches. - We mark release candidates as `5.0.1-rc.1` coding and bug fixes are finished. The team is going through the manual test plan to find any regressions. -**Releases** +### Releases Releases are ready for production use. -- Releases `5.0.0` and `6.0.0` are major releases. We publish 4 major releases each year. - Read more about upgrades and compatibility [here](../setup/operations/upgrading.mdx). -- Releases `5.1.0` are minor releases. They contain minor backwards-compatible improvements and backports. -- Versions like `5.0.1` are quick patches. They contain backwards-compatible fixes. +- Releases `5.0.0` and `6.0.0` are major releases. We publish 4 major releases + each year. Read more about upgrades and compatibility in [Upgrading a Teleport Cluster](../setup/operations/upgrading.mdx). +- Releases `5.1.0` are minor releases. They contain minor backwards-compatible + improvements and backports. +- Versions like `5.0.1` are quick patches. They contain backwards-compatible + fixes. diff --git a/docs/pages/server-access/getting-started.mdx b/docs/pages/server-access/getting-started.mdx index 27129c705c34c..31f9796a01db1 100644 --- a/docs/pages/server-access/getting-started.mdx +++ b/docs/pages/server-access/getting-started.mdx @@ -1,7 +1,7 @@ --- title: Server Access Getting Started Guide description: Getting started with Teleport Server Access. -videoBanner: EsEvO5ndNDI +videoBanner: KCk7wYgUn3A --- Server Access involves managing your resources, configuring new clusters, and issuing commands through a CLI or programmatically to an API. diff --git a/docs/pages/server-access/guides.mdx b/docs/pages/server-access/guides.mdx index 9f374eb83b8d9..fc5bc2da3fe71 100644 --- a/docs/pages/server-access/guides.mdx +++ b/docs/pages/server-access/guides.mdx @@ -8,9 +8,6 @@ layout: tocless-doc How to configure Teleport SSH with PAM (Pluggable Authentication Modules). - - How to configure Teleport SSH with Ansible. - How to use Teleport on legacy systems with OpenSSH and sshd. @@ -28,4 +25,7 @@ layout: tocless-doc How to remotely develop with Visual Studio Code and Teleport. + + How to configure Teleport to automatically create transient host users. +
    diff --git a/docs/pages/server-access/guides/bpf-session-recording.mdx b/docs/pages/server-access/guides/bpf-session-recording.mdx index 2edc835440b16..b951b5c064c83 100644 --- a/docs/pages/server-access/guides/bpf-session-recording.mdx +++ b/docs/pages/server-access/guides/bpf-session-recording.mdx @@ -8,7 +8,7 @@ videoBanner: 8uO5H-iYw5A This guide explains Enhanced Session Recording for SSH with BPF and how to set it up in your Teleport cluster. -Teleport's default [SSH and Kubernetes session recording](../../architecture/nodes.mdx#session-recording) +Teleport's default [SSH and Kubernetes session recording](../../architecture/nodes.mdx#ssh-session-recording) feature captures what is echoed to a terminal. This has inherent advantages. For example, because no input is captured, Teleport @@ -49,7 +49,7 @@ Teleport Enhanced Session Recording mitigates all three concerns by providing ad Our Standard Session Recording works with older Linux kernels. View - [Teleport Nodes](../../architecture/nodes.mdx#session-recording) for more + [Teleport Nodes](../../architecture/nodes.mdx#ssh-session-recording) for more details. @@ -255,6 +255,6 @@ Sessions with Enhanced Session Recording will include the ## Next steps - Read more about - [session recording](../../architecture/nodes.mdx#session-recording). + [session recording](../../architecture/nodes.mdx#ssh-session-recording). - See all configuration options for Enhanced Session Recording in our - [Configuration Reference](../../setup/reference/config.mdx). \ No newline at end of file + [Configuration Reference](../../setup/reference/config.mdx). diff --git a/docs/pages/server-access/guides/host-user-creation.mdx b/docs/pages/server-access/guides/host-user-creation.mdx new file mode 100644 index 0000000000000..e6efc88b45662 --- /dev/null +++ b/docs/pages/server-access/guides/host-user-creation.mdx @@ -0,0 +1,155 @@ +--- +title: Configure Teleport to Create Host Users +description: How to configure Teleport to automatically create transient host users. +--- + +Teleport's SSH Service can be configured to automatically create local Unix users +upon login. + +Host users created by Teleport are transient and will be deleted at the end of an SSH +session. This feature has overlap with the [PAM](./ssh-pam.mdx) integration, however +it provides some additional convenience of not having to manually configure a PAM +script to create and delete users. + +It also has benefits over manually creating users as it allows for separate host +users for each member of an organization. This provides more fine-grained control +of permissions on a given host. + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + +- A running Teleport Node. See the [Server Access Getting Started Guide](../getting-started.mdx) for how to add a Node to your Teleport cluster. +- The following utilities should be available in the PATH for the Teleport SSH Service, +since it must execute these commands in order to create transient users: + - `useradd` + - `userdel` + - `usermod` + - `groupadd` + - `getent` + - `visudo` + +(!docs/pages/includes/tctl.mdx!) + +## Step 1/2. Configure a role + +First, create a role with `create_host_user` set to `true`. This will allow users +with this role to have transient host users created at login time. + +The following role specification will allow users to log in as `nginxrestarter` on +any matching Node. The host user will be created and added to the groups listed in +`host_groups`. They will also be given permission to restart the Nginx service as +root. + +Save the file below as `auto-users.yaml` + +```yaml +kind: role +version: v5 +metadata: + name: auto-users +spec: + options: + # Allow automatic creation of users. + create_host_user: true + allow: + logins: [ "nginxrestarter" ] + # List of host groups the created user will be added to. Any that don't already exist are created. + host_groups: [ubuntu, nginx, other] + # List of entries to include in a temporary sudoers file created in /etc/sudoers.d + host_sudoers: [ + # This line will allow the `nginxrestarter` user to run + # `systemctl restart nginx.service` as + # root without requiring a password. + # The sudoers entries will be prefixed with `nginxrestarter` in this case. + # sudoers file reference documentation: https://www.sudo.ws/docs/man/1.8.17/sudoers.man/ + "ALL = (root) NOPASSWD: /usr/bin/systemctl restart nginx.service" + ] + node_labels: + 'env': 'devel' +``` +Create the role: +```code +$ tctl create -f auto-users.yaml +# role 'auto-users' has been created +``` + +Each value of the `logins` field must conform to the username requirements +of the Linux distribution being used. See [User/Group Name Syntax](https://systemd.io/USER_NAMES/) for requirements in common distributions. + + + +When a Teleport user accesses a Node, Teleport Server Access checks each of the +user's roles that match the Node. If at least one role matches the Node but does not +include `create_host_user: true`, automatic user creation will be disabled. Roles that +do not match the Node will not be checked. + + + +If a role includes a `deny` rule that sets `host_sudoers` to `'*'`, the user will +have all sudoers entries removed when accessing matching Nodes, otherwise `deny` +rules are matched literally when filtering: + +```yaml +kind: role +version: v5 +metadata: + name: auto-users +spec: + options: + create_host_user: true + deny: + host_sudoers: [ + "*" # ensure that users in this role never have sudoers files created on matching Nodes + "ALL=(ALL) NOPASSWD: ALL" # host_sudoers entries matching this are filtered out + ] + node_labels: + 'env': 'devel' +``` + +If an SSH Node must never allow the automatic creation of transient Unix users +you can set `disable_create_host_users` to `true` in the Node's configuration: + +```yaml +# teleport.yml +teleport: + nodename: node +ssh_service: + enabled: true + # Disable automatic host user creation on this Node, regardless of role permissions. + disable_create_host_users: true +``` + +## Step 2/2 Test host user creation + +When you connect to a remote Node via `tsh`, and host user creation is enabled, the +Teleport SSH Service will automatically create a user on the host: +```code +$ tsh login +$ tsh ssh nginxrestarter@develnode +$ grep "nginxrestarter" /etc/passwd +# nginxrestarter:x:1001:1003::/home/nginxrestarter:/bin/bash +$ grep "other" /etc/group +# other:x:1002:nginxrestarter +$ exit +$ tsh ssh admin@develnode # checking the user was deleted after logout +$ grep "teleportuser" /etc/passwd +$ echo $? +# 1 +``` + +When logging in, the `nginxrestarter` user and any groups that do not already exist +will be created on the host. The `nginxrestarter` user will be added to the `ubuntu`, +`nginx` and `other` groups as specified in the `host_groups` field. + +A file will also be created in `/etc/sudoers.d` with the contents of the +`host_sudoers` file written with one entry per line, each prefixed with the username +of the user that has logged in. + +The session can then proceed as usual, however once the SSH session ends, the user +will be automatically removed and their home directory will be deleted. Files owned +by the deleted user, created outside the home directory, will remain in place. Groups +that were created will remain on the system after the session ends. + +Should a Teleport SSH instance be restarted while a session is in progress, the user +will be cleaned up at the next Teleport restart. diff --git a/docs/pages/server-access/guides/openssh.mdx b/docs/pages/server-access/guides/openssh.mdx index e5d8e7752b969..1c31cea677e56 100644 --- a/docs/pages/server-access/guides/openssh.mdx +++ b/docs/pages/server-access/guides/openssh.mdx @@ -275,9 +275,6 @@ This command creates an SSH configuration file at a nonstandard location in order to make it easier to clean up, but you can append the output of `tsh config` to the default SSH config file (`~/.ssh/config`) if you wish. -If you are using Trusted Clusters, this will print an OpenSSH client -configuration block for the root cluster and all currently known leaf clusters. -
    Teleport implements an SSH server that includes several **subsystems**, or @@ -340,6 +337,98 @@ authenticate the host via the certificate we generated earlier.
    +
    + +### Proxy Jump + +In the generated OpenSSH client configuration, the `ProxyCommand` for each leaf +cluster connects through the root cluster's Proxy Service. In scenarios where +leaf cluster Proxy Services are reachable by SSH client, you might prefer to +connect directly through the leaf proxies for lower latency. + +To enable direct connections to a Proxy Service in a leaf cluster, open the +SSH configuration file you generated earlier and update the `ProxyCommand` +of the leaf cluster's configuration block to use the leaf Proxy Service as +a jumphost, using the `-J` flag. + +```txt +Host *.{{ .NodeName }}.leaf1.example.com + Port 3022 + ProxyCommand tsh proxy ssh -J proxy.leaf1.example.com:443 %r@%h:%p +``` + +### Proxy Templates + +With Proxy Templates, `tsh` will dynamically determine the address of the +Proxy Service to connect to based on the address of the destination +host in your `ssh` command. + +To use Proxy Templates, add `-J {{proxy}}` to the `ProxyCommand` line in +your `~/.ssh/config`. + +```txt +Host *.example.com + Port 3022 + ProxyCommand tsh proxy ssh -J {{proxy}} %r@%h:%p +``` + +Then, add `proxy_templates` to your `tsh` configuration file (`~/.tsh/config/config.yaml` +or a global `/etc/tsh.yaml`). + +```yaml +proxy_templates: +- template: '^(\w+)\.(leaf1\.example\.com):([0-9]+)$' + proxy: "$2:443" +``` + +`tsh proxy ssh -J {{proxy}}` will attempt to match the host server address `%h:%p` with the +configured templates. If there is a match, then the jump proxy address `{{proxy}}` will +be replaced using the template's `proxy` field and the host server address `%h:%p` will be +replaced using the template's `host` field if set. + +| Field | Description | +| ---------- | ----------- | +| `template` | (Required) Regular expression that the host server address `%h:%p` is matched against. | +| `proxy` | (Required) Proxy Service address to use for proxy jump. Can reference capturing groups from the regular expression in `template` (e.g., `$1` or `$2`). | +| `host` | (Optional) Host Server address to connect to. Can reference capturing groups from the regular expression in `template` (e.g., `$1` or `$2`). Defaults to full host spec `%h:%p`. | + +### Example configuration + +```yaml +proxy_templates: +- template: '^(\w+)\.(leaf1\.example\.com):([0-9]+)$' + proxy: "$2:443" +- template: '^(\w+)\.(leaf2\.example\.com):([0-9]+)$' + proxy: "$2:3080" + host: "$1:$3" +- template: '(\w+(\.\w+)*)\.(example\.com):([0-9]+)$' + proxy: "leaf1.example.com:443" + host: "$1:22" + +Given the configuration above, the following command will connect to the Node +`node-1.leaf1.example.com:3022` through the Proxy Service `leaf1.example.com:443`: + +```code +$ ssh root@node-1.leaf1.example.com +``` + +The following command will connect to the Node `node-1:3022` through the Proxy Service +`leaf2.example.com:3080`: + +```code +$ ssh root@node-1.leaf2.example.com +``` + +The last template can be used to connect to openssh hosts with their own FQDN. +For example, you can connect to the host `openssh.external.com:22` through the +Proxy Service `leaf1.example.com:443` with the following command: + +```code +$ ssh root@openssh.external.com.example.com +``` + +
    + - - - - - -
    - - We consider Recording Proxy Mode to be less secure than recording at the Node level for two reasons: @@ -271,4 +252,3 @@ dropped. To increase the concurrency level, increase the value to something like `MaxStartups 50:30:100`. This allows 50 concurrent connections and a max of 100. - \ No newline at end of file diff --git a/docs/pages/server-access/guides/restricted-session.mdx b/docs/pages/server-access/guides/restricted-session.mdx index 2756fea3d95ca..f1ca2319cc1ca 100644 --- a/docs/pages/server-access/guides/restricted-session.mdx +++ b/docs/pages/server-access/guides/restricted-session.mdx @@ -93,7 +93,7 @@ Create a file called `netpolicy.yaml`: ```yaml kind: network_restrictions -version: v5 +version: v4 metadata: name: network-restrictions spec: diff --git a/docs/pages/server-access/guides/tsh.mdx b/docs/pages/server-access/guides/tsh.mdx index dfe0bed4943ec..a1d4b7c4acc51 100644 --- a/docs/pages/server-access/guides/tsh.mdx +++ b/docs/pages/server-access/guides/tsh.mdx @@ -352,7 +352,10 @@ In this example, we're creating a certificate with a TTL of one hour for the ```code -# To be executed on a Teleport Auth Server +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. +$ tsh login --proxy=teleport.example.com --user=myuser $ tctl auth sign --ttl=1h --user=jenkins --out=jenkins.pem ``` @@ -411,6 +414,12 @@ $ tsh ls os=osx [CLI Docs -tsh ls](../../setup/reference/cli.mdx#tsh-ls) +
    + +(!docs/pages/includes/node-logins.mdx!) + +
    + ## Interactive shell To launch an interactive shell on a remote Node or to execute a command, use @@ -718,5 +727,37 @@ Service, and this tunnel is used to establish inbound SSH connections.
    +## X11 forwarding + +In order to run graphical programs within an SSH session, such as an IDE like +Virtual Studio Code, you'll need to request X11 forwarding for the session with +the `-X` flag. + +```code +$ tsh ssh -X node01 +``` + +X11 forwarding provides the server with secure access to your local X Server +so that it can communicate directly with your local display and I/O devices. + + + The `-Y` flag can be used to start Trusted X11 forwarding. This is needed + in order to enable more "unsafe" features, such as running clipboard or + screenshot utilities like `xclip`. However, it provides the server with + unmitigated access to your local X Server and puts your local machine at + risk of X11 attacks, so it should only be used with extreme caution. + + +In order to use X11 forwarding, you'll need to enable it on the Teleport Node. +You'll also need to ensure that your user has the `permit_x11_forwarding` role option: + +```code +$ tsh status +> Profile URL: https://proxy.example.com:3080 + Logged in as: dev + ... + Extensions: permit-X11-forwarding +``` + ## Further reading - [CLI Reference](../../setup/reference/cli.mdx). \ No newline at end of file diff --git a/docs/pages/setup/admin/trustedclusters.mdx b/docs/pages/setup/admin/trustedclusters.mdx index 60308292efda9..5db46e8cded26 100644 --- a/docs/pages/setup/admin/trustedclusters.mdx +++ b/docs/pages/setup/admin/trustedclusters.mdx @@ -5,13 +5,13 @@ h1: Trusted Clusters --- Teleport can partition compute infrastructure into multiple clusters. A cluster -is a group of Teleport resources connected to the cluster's Auth Service, which -acts as a certificate authority (CA) for all users and Nodes in the cluster. +is a group of Teleport resources connected. Each clustes +manages a separate certificate authority (CA) for all users and resources. Trusted Clusters allow the users of one cluster, the **root cluster**, to seamlessly SSH into the Nodes of another cluster, the **leaf cluster**, while remaining authenticated with only a single Auth Service. The leaf cluster can -be running behind a firewall with no TCP ports open to the root cluster. +be running behind a firewall without any ingress ports open. Uses for Trusted Clusters include: @@ -20,14 +20,18 @@ Uses for Trusted Clusters include: - Large cloud software vendors managing multiple data centers using a common proxy. Here is an example of an MSP using Trusted Clusters to obtain access to client clusters: -![MSP Example](../../../img/trusted-clusters/TrustedClusters-MSP.svg) +![MSP Example](../../../img/trusted-clusters/trusted-clusters@1.5x.svg) -This setup works as follows: a leaf cluster creates an outbound reverse SSH -tunnel to the root cluster and keeps the tunnel open. When a user tries to -connect to a Node inside the leaf cluster using the root's Proxy Service, the -reverse tunnel is used to establish this connection. +A leaf cluster always creates an outbound reverse SSH tunnel to the root cluster and keeps the tunnel open. -![Tunnels](../../../img/tunnel.svg) + +Individual nodes and proxies can create reverse tunnels to proxy serivices without creating a new cluster. +You don't need to set up a trusted cluster just to connect a couple of servers, kubernetes clusters or +databases behind a firewall. For more information, see [Adding Nodes to the Cluster](./adding-nodes.mdx). + + +When a user tries to connect to any resource inside the leaf cluster using the root's proxy, the +the connection goes through the reverse tunnel. This guide will explain how to: diff --git a/docs/pages/setup/deployments.mdx b/docs/pages/setup/deployments.mdx index d23e6a49228f7..95d6425fbd9ee 100644 --- a/docs/pages/setup/deployments.mdx +++ b/docs/pages/setup/deployments.mdx @@ -7,35 +7,28 @@ layout: tocless-doc These guides show you how to set up a full self-hosted Teleport deployment on the platform of your choice. - - - View our deployment guides as an Open Source Teleport user. - - - View our deployment guides as a Teleport Enterprise user. - - - - - -
      -
    • - [AWS Terraform](./deployments/aws-terraform.mdx). Deploy HA Teleport with Terraform Provider on AWS. -
    • -
    • - [GCP](./deployments/gcp.mdx). Deploy HA Teleport on GCP. -
    • -
    • - [IBM Cloud](./deployments/ibm.mdx). Deploy HA Teleport on IBM cloud. -
    • -
    -
    + + Use our DigitalOcean 1-Click App to quickly spin up Teleport on a droplet. + + + + + Deploy HA Teleport with Terraform Provider on AWS. + + + + + Deploy HA Teleport on GCP. + + + + + Deploy HA Teleport on IBM cloud. + + + diff --git a/docs/pages/setup/deployments/aws-terraform.mdx b/docs/pages/setup/deployments/aws-terraform.mdx index bf8f51655a4b2..147be3dec01a4 100644 --- a/docs/pages/setup/deployments/aws-terraform.mdx +++ b/docs/pages/setup/deployments/aws-terraform.mdx @@ -7,55 +7,6 @@ h1: Running Teleport Enterprise in High Availability mode on AWS This guide is designed to accompany our [reference Terraform code](https://github.com/gravitational/teleport/tree/master/examples/aws/terraform/ha-autoscale-cluster#terraform-based-provisioning-example-amazon-single-ami) and describe how to manage the resulting Teleport deployment. - - -Our reference Terraform code deploys self-hosted instances of the Teleport Auth -Service and Proxy Service. Since Teleport Cloud manages these services for you, -users interested in Terraform should consult the following guides instead of -this one: - - - - -Read our guide to using Teleport and Terraform - - - - -Read our Terraform provider reference - - - - -You can also view this guide as a user of another Teleport edition: - - - - - - - - - - - - ## Prerequisites Our code requires Terraform 0.12+. You can [download Terraform here](https://www.terraform.io/downloads.html). We will assume that you have @@ -883,5 +834,3 @@ $ ./connect.sh proxy 1 # connect to the node $ ./connect.sh node ``` - - \ No newline at end of file diff --git a/docs/pages/getting-started/digitalocean.mdx b/docs/pages/setup/deployments/digitalocean.mdx similarity index 85% rename from docs/pages/getting-started/digitalocean.mdx rename to docs/pages/setup/deployments/digitalocean.mdx index d2eb4314c5270..89a521c080651 100644 --- a/docs/pages/getting-started/digitalocean.mdx +++ b/docs/pages/setup/deployments/digitalocean.mdx @@ -7,26 +7,9 @@ videoBanner: voHQlSX_czE This tutorial will guide you through quickly getting started with Teleport on DigitalOcean with the Teleport 1-Click Droplet app. - - -This guide is intended for users of Teleport Open Source. - - - - - - - - - - -If you are looking for a manual installation, refer to our [Linux installation guide](./linux-server.mdx). +If you are looking for a manual installation, refer to our [Linux installation guide](../../getting-started/linux-server.mdx). @@ -40,19 +23,19 @@ If you are looking for a manual installation, refer to our [Linux installation g Head over to the Teleport page on [DigitalOcean Marketplace](https://marketplace.digitalocean.com/apps/teleport) and click the “Create a Droplet” button:
    - ![Teleport 1-Click droplet page](../../img/quickstart/digitalocean/1click-droplet-page.png) + ![Teleport 1-Click droplet page](../../../img/quickstart/digitalocean/1click-droplet-page.png)
    Once you click the button, DigitalOcean redirects you to the control panel to configure resources for the Teleport droplet. This step is similar to how you create a regular [droplet in DigitalOcean](https://docs.digitalocean.com/products/droplets/how-to/create/). Teleport is very lightweight, and if you are just trying out Teleport, you can select the $5 droplet. Make sure you select "SSH keys" as the SSH authentication method as it is more secure than a password.
    - ![Create a droplet](../../img/quickstart/digitalocean/create-droplet.png) + ![Create a droplet](../../../img/quickstart/digitalocean/create-droplet.png)
    It will take a few minutes before our newly created Teleport droplet is ready. Once the droplet is ready, configure your FQDN with the public IP address of the droplet as an IP address for the `A` record of your domain name. For example, refer to the image below; we use the domain name `example.com`. The resulting domain we are using as an FQDN is `tele.example.com`, pointing to our Teleport droplet's public IP `192.168.200.200`.
    - ![Configure DNS](../../img/quickstart/digitalocean/fqdn.png) + ![Configure DNS](../../../img/quickstart/digitalocean/fqdn.png)
    ## Step 2/3. Configure Teleport @@ -99,14 +82,14 @@ Open the link copied in the previous step in the browser to complete the setup p 1. Scan the QR code with your two-factor authentication app (e.g., Google Authenticator) 2. Set a password and enter the TOTP code generated from the two-factor authentication app.
    - ![Set up user](../../img/quickstart/digitalocean/setup-user.png) + ![Set up user](../../../img/quickstart/digitalocean/setup-user.png)
    Once you set up a password and provide a valid TOTP code, the user setup process will be complete, and you will be redirected to Teleport Web UI:
    - ![Teleport Web UI](../../img/quickstart/digitalocean/webui.png) + ![Teleport Web UI](../../../img/quickstart/digitalocean/webui.png)
    @@ -114,7 +97,7 @@ Congrats! You've completed setting up Teleport. ## Next steps Finally, you are a step closer to managing secure access to your infrastructure hosted in DigitalOcean. -Teleport lets you enable [certificate-based authentication for SSH](../server-access/getting-started.mdx) access. If you want to protect public access to internal applications such as GitLab or Grafana, check out our getting started guide on [Application Access](../application-access/getting-started.mdx). +Teleport lets you enable [certificate-based authentication for SSH](../../server-access/getting-started.mdx) access. If you want to protect public access to internal applications such as GitLab or Grafana, check out our getting started guide on [Application Access](../../application-access/getting-started.mdx). You can also secure access to databases, DigitalOcean Marketplace apps, and Kubernetes clusters using Teleport. Below are the links to get started further: @@ -134,5 +117,3 @@ You can also secure access to databases, DigitalOcean Marketplace apps, and Kube Secure access to Windows Server. - -
    \ No newline at end of file diff --git a/docs/pages/setup/deployments/gcp.mdx b/docs/pages/setup/deployments/gcp.mdx index 57942adf4ccd0..47b46938b37d8 100644 --- a/docs/pages/setup/deployments/gcp.mdx +++ b/docs/pages/setup/deployments/gcp.mdx @@ -12,27 +12,8 @@ high-level introduction to setting up and running Teleport in production. This guide shows you how to deploy the Auth Service and Proxy Service, which Teleport Cloud manages for you. -You can view this guide as a user of another Teleport edition: - - - - - - - -
    - - We have split this guide into: - [Teleport on GCP FAQ](#teleport-on-gcp-faq) @@ -248,5 +229,3 @@ proxy_service: **4. Add Users** Follow [adding users](../../enterprise/getting-started.mdx#adding-users) or integrate with [Google Workspace](../../enterprise/sso/google-workspace.mdx) to provide SSO access. - - \ No newline at end of file diff --git a/docs/pages/setup/deployments/ibm.mdx b/docs/pages/setup/deployments/ibm.mdx index d6a4e81d93252..22eeb815fc5ac 100644 --- a/docs/pages/setup/deployments/ibm.mdx +++ b/docs/pages/setup/deployments/ibm.mdx @@ -12,27 +12,8 @@ introduction to setting up and running Teleport in production. This guide shows you how to deploy the Auth Service and Proxy Service, which Teleport Cloud manages for you. -You can view this guide as a user of another Teleport edition: - - - - - - - -
    - - We have split this guide into: - [Teleport on IBM FAQ](#teleport-on-ibm-cloud-faq) @@ -168,8 +149,8 @@ Save these settings to `~/.aws/credentials` ```yaml # Example keys from example service account to be saved into ~/.aws/credentials [default] -access_key_id="e668d66374e141668e3432443bc879e" -secret_access_key="d8762b57f61d5dd524ccd49c7d44861ceafdsfds37d05836" +aws_access_key_id="e668d66374e141668e3432443bc879e" +aws_secret_access_key="d8762b57f61d5dd524ccd49c7d44861ceafdsfds37d05836" ``` Example `/etc/teleport.yaml` @@ -217,4 +198,3 @@ the Teleport Proxy public address. public_addr: proxy.example.com:3080 ``` - \ No newline at end of file diff --git a/docs/pages/setup/guides/docker.mdx b/docs/pages/setup/guides/docker.mdx index e5e73a792d341..53c16bfd61313 100644 --- a/docs/pages/setup/guides/docker.mdx +++ b/docs/pages/setup/guides/docker.mdx @@ -215,6 +215,6 @@ root@localhost:~# ## Next steps -- Try out one of our [Helm Guides](../../kubernetes-access/helm/guides.mdx). +- Try out one of our [Helm Guides](../../setup/helm-deployments.mdx). - Try out one of our [Database Access Guides](../../database-access/guides.mdx). - Learn about [Teleport Server Access](../../server-access/introduction.mdx). diff --git a/docs/pages/setup/guides/joining-nodes-aws-ec2.mdx b/docs/pages/setup/guides/joining-nodes-aws-ec2.mdx index ea657e6c63340..e829ef2cf950e 100644 --- a/docs/pages/setup/guides/joining-nodes-aws-ec2.mdx +++ b/docs/pages/setup/guides/joining-nodes-aws-ec2.mdx @@ -13,27 +13,8 @@ The EC2 join method is not available in Teleport Cloud. Teleport Cloud customers can use the [IAM join method](./joining-nodes-aws-iam.mdx) or [secret tokens](../admin/adding-nodes.mdx). -You can view this guide as a user of another Teleport edition: - - - - - - - - - - The EC2 join method is available in self-hosted versions of Teleport 7.3+. It is available to any Teleport node or Proxy running on an EC2 instance. Only one Teleport node or Proxy per EC2 instance may use the EC2 join method. @@ -302,4 +283,3 @@ spec: aws_role: "arn:aws:iam::333333333333:role/teleport-DescribeInstances-role" ``` - \ No newline at end of file diff --git a/docs/pages/setup/guides/ssh-key-extensions.mdx b/docs/pages/setup/guides/ssh-key-extensions.mdx index 435cbe470f80a..65f86681a068d 100644 --- a/docs/pages/setup/guides/ssh-key-extensions.mdx +++ b/docs/pages/setup/guides/ssh-key-extensions.mdx @@ -18,8 +18,9 @@ In order to export the Teleport CA, execute the following command: ```code -# Log in to your Teleport cluster so you can use tctl remotely. -# You can also run tctl on your Auth Service host. +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. $ tsh login --proxy=teleport.example.com --user=myuser $ tctl auth export --type=user | sed 's/^cert-authority //g' ``` diff --git a/docs/pages/setup/helm-deployments.mdx b/docs/pages/setup/helm-deployments.mdx new file mode 100644 index 0000000000000..cec6edad405e0 --- /dev/null +++ b/docs/pages/setup/helm-deployments.mdx @@ -0,0 +1,34 @@ +--- +title: Guides for running Teleport using Helm +description: How to install and configure Teleport in Kubernetes using Helm +layout: tocless-doc +--- + +## Helm deployment guides + +These guides show you how to set up a full self-hosted Teleport deployment using +our `teleport-cluster` Helm chart. + + + + Running an HA Teleport cluster in Kubernetes using an AWS EKS Cluster + + + Running an HA Teleport cluster in Kubernetes using a Google Cloud GKE cluster + + + Running a Teleport cluster in Kubernetes with a custom Teleport config + + + +## Migration Guides + + + + + + diff --git a/docs/pages/kubernetes-access/helm/guides/aws.mdx b/docs/pages/setup/helm-deployments/aws.mdx similarity index 95% rename from docs/pages/kubernetes-access/helm/guides/aws.mdx rename to docs/pages/setup/helm-deployments/aws.mdx index a36a073dfe5e8..832b9e60f4f5e 100644 --- a/docs/pages/kubernetes-access/helm/guides/aws.mdx +++ b/docs/pages/setup/helm-deployments/aws.mdx @@ -10,27 +10,8 @@ using Teleport Helm charts and AWS products (DynamoDB and S3). (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-cloud-warning.mdx!) -You can also view this guide as a user of another Teleport edition: - - - - - - - - - - ## Prerequisites (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) @@ -134,27 +115,31 @@ You'll need to replace these values in the policy example below: "Version": "2012-10-17", "Statement": [ { - "Sid": "ClusterSessionsStorage", + "Sid": "BucketActions", "Effect": "Allow", "Action": [ "s3:PutEncryptionConfiguration", - "s3:PutObject", - "s3:GetObject", - "s3:GetEncryptionConfiguration", - "s3:GetObjectRetention", + "s3:PutBucketVersioning", "s3:ListBucketVersions", "s3:ListBucketMultipartUploads", - "s3:AbortMultipartUpload", - "s3:CreateBucket", "s3:ListBucket", + "s3:GetEncryptionConfiguration", "s3:GetBucketVersioning", - "s3:PutBucketVersioning", - "s3:GetObjectVersion" + "s3:CreateBucket" ], - "Resource": [ - "arn:aws:s3:::teleport-helm-sessions/*", - "arn:aws:s3:::teleport-helm-sessions" - ] + "Resource": "arn:aws:s3:::teleport-helm-sessions" + }, + { + "Sid": "ObjectActions", + "Effect": "Allow", + "Action": [ + "s3:GetObjectVersion", + "s3:GetObjectRetention", + "s3:*Object", + "s3:ListMultipartUploadParts", + "s3:AbortMultipartUpload" + ], + "Resource": "arn:aws:s3:::teleport-helm-sessions/*" } ] } @@ -550,11 +535,10 @@ $ helm --namespace cert-manager uninstall cert-manager ## Next steps -You can follow our [Getting Started with Teleport guide](../../../setup/guides/docker.mdx#step-34-creating-a-teleport-user) to finish setting up your +You can follow our [Getting Started with Teleport guide](../guides/docker.mdx#step-34-creating-a-teleport-user) to finish setting up your Teleport cluster. -See the [high availability section of our Helm chart reference](../reference/teleport-cluster.mdx#highavailability) for more details on high availability. +See the [high availability section of our Helm chart reference](../../kubernetes-access/helm/reference/teleport-cluster.mdx#highavailability) for more details on high availability. Read the [`cert-manager` documentation](https://cert-manager.io/docs/). - \ No newline at end of file diff --git a/docs/pages/kubernetes-access/helm/guides/custom.mdx b/docs/pages/setup/helm-deployments/custom.mdx similarity index 89% rename from docs/pages/kubernetes-access/helm/guides/custom.mdx rename to docs/pages/setup/helm-deployments/custom.mdx index 62920201e1f21..f0a7c63e3df69 100644 --- a/docs/pages/kubernetes-access/helm/guides/custom.mdx +++ b/docs/pages/setup/helm-deployments/custom.mdx @@ -3,47 +3,12 @@ title: Running Teleport with a Custom Configuration using Helm description: Install and configure a Teleport cluster with a custom configuration using Helm --- -In this guide, we'll go through how to set up a Teleport cluster in Kubernetes using a custom [`teleport.yaml`](../../../setup/reference/config.mdx) +In this guide, we'll go through how to set up a Teleport cluster in Kubernetes using a custom [`teleport.yaml`](../reference/config.mdx) config file using Teleport Helm charts. This setup can be useful when you already have an existing Teleport cluster and would like to start running it in Kubernetes, or when migrating your setup from a legacy version of the Helm charts. - - -Teleport Cloud users should consult the following guide, which shows -you how to connect a Teleport Kubernetes Service agent to an existing Teleport -cluster: - - - - - - -You can also view this guide as a user of another Teleport edition: - - - - - - - - - - - ## Prerequisites (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) @@ -61,7 +26,7 @@ icon="building" In `custom` mode, the `teleport-cluster` Helm chart does not create a `ConfigMap` containing a `teleport.yaml` file for you, but expects that you will provide this yourself. -For this example, we'll be using this `teleport.yaml` configuration file with a static join token (for more information on join tokens, see [Adding Nodes to the Cluster](../../../setup/admin/adding-nodes.mdx)): +For this example, we'll be using this `teleport.yaml` configuration file with a static join token (for more information on join tokens, see [Adding Nodes to the Cluster](../admin/adding-nodes.mdx)): ```code $ cat << EOF > teleport.yaml @@ -252,7 +217,7 @@ $ helm upgrade teleport teleport/teleport-cluster \ When using `custom` mode, you **must** use highly-available storage (e.g. etcd, DynamoDB, or Firestore) for multiple replicas to be supported. - [Information on supported Teleport storage backends](../../../architecture/authentication.mdx#storage-back-ends) + [Information on supported Teleport storage backends](../reference/backends.mdx) Manually configuring NFS-based storage or `ReadWriteMany` volume claims is **NOT** supported for an HA deployment and will result in errors. @@ -271,7 +236,5 @@ $ helm --namespace teleport uninstall teleport ## Next steps -You can follow our [Getting Started with Teleport guide](../../../setup/guides/docker.mdx#step-34-creating-a-teleport-user) to finish setting up your +You can follow our [Getting Started with Teleport guide](../guides/docker.mdx#step-34-creating-a-teleport-user) to finish setting up your Teleport cluster. - - \ No newline at end of file diff --git a/docs/pages/kubernetes-access/helm/guides/digitalocean.mdx b/docs/pages/setup/helm-deployments/digitalocean.mdx similarity index 86% rename from docs/pages/kubernetes-access/helm/guides/digitalocean.mdx rename to docs/pages/setup/helm-deployments/digitalocean.mdx index ee0da75a4958f..309d163b1df7a 100644 --- a/docs/pages/kubernetes-access/helm/guides/digitalocean.mdx +++ b/docs/pages/setup/helm-deployments/digitalocean.mdx @@ -22,25 +22,8 @@ icon="kubernetes" -You can also view this guide as a user of another Teleport edition: - - - - - - - - This guide will show you how to get started with Teleport on DigitalOcean Kubernetes. @@ -53,13 +36,13 @@ Kubernetes. ## Step 1/4. Create a DigitalOcean Kubernetes cluster Create a new [DigitalOcean Kubernetes Cluster](https://cloud.digitalocean.com/kubernetes/clusters/)
    - ![Create DigitalOcean Kubernetes cluster](../../../../img/helm/digitalocean/create-k8s.png) + ![Create DigitalOcean Kubernetes cluster](../../../img/helm/digitalocean/create-k8s.png)

    While the Kubernetes cluster is being provisioned, follow the "Getting Started" guide as shown below:
    - ![Set up DigitalOcean Kubernetes client](../../../../img/helm/digitalocean/setup-k8s.png) + ![Set up DigitalOcean Kubernetes client](../../../img/helm/digitalocean/setup-k8s.png)
    @@ -98,7 +81,7 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) ``` Once you get the value for the external IP (it may take a few minutes for this field to be populated), update your DNS record such that the clusterName's A record points to this IP address. For example `192.168.200.200` is the external IP in the above case.
    - ![Configure DNS](../../../../img/helm/digitalocean/fqdn.png) + ![Configure DNS](../../../img/helm/digitalocean/fqdn.png)
    ## Step 3/4. Create and set up Teleport user @@ -114,7 +97,7 @@ $ kubectl --namespace teleport-cluster exec deploy/teleport-cluster -- tctl user Copy the link shown after executing the above command and open the link in a web browser to complete the user registration process (the link is `https://tele.teleporters.dev:443/web/invite/` in the above case).
    - ![Setup user](../../../../img/helm/digitalocean/setup-user.png) + ![Setup user](../../../img/helm/digitalocean/setup-user.png)
    @@ -154,12 +137,12 @@ $ kubectl --namespace=teleport-cluster exec -i ${POD?} -- tctl create -f < membe Now we will assign Teleport user **tadmin** with this role. The example below shows a process using Teleport Web UI: First, lets select user edit menu:
    - ![Edit user](../../../../img/helm/digitalocean/edit-user.png) + ![Edit user](../../../img/helm/digitalocean/edit-user.png)
    Second, update the **tadmin** user role to assign the **member** role:
    - ![Update role](../../../../img/helm/digitalocean/update-role.png) + ![Update role](../../../img/helm/digitalocean/update-role.png)
    We've updated the user **tadmin** to have the **member** role, which is allowed to access a Kubernetes cluster with privilege `system:master`. @@ -219,14 +202,13 @@ Voila! User **tadmin** was able to list the pods in their DigitalOcean Kubernete Teleport keeps an audit log of access to a Kubernetes cluster. In the screenshot below, the Teleport audit log shows that the user **tadmin** has logged into the cluster.
    - ![View audit log](../../../../img/helm/digitalocean/view-activity.png) + ![View audit log](../../../img/helm/digitalocean/view-activity.png)
    ## Next steps -- [Connect Multiple Kubernetes Clusters](../../guides/multiple-clusters.mdx) -- [Setup CI/CD Access with Teleport](../../guides/cicd.mdx) -- [Federated Access using Trusted Clusters](../../guides/federation.mdx) -- [Single-Sign On and Kubernetes Access Control](../../controls.mdx) +- [Connect Multiple Kubernetes Clusters](../../kubernetes-access/guides/multiple-clusters.mdx) +- [Setup CI/CD Access with Teleport](../../kubernetes-access/guides/cicd.mdx) +- [Federated Access using Trusted Clusters](../../kubernetes-access/guides/federation.mdx) +- [Single-Sign On and Kubernetes Access Control](../../kubernetes-access/controls.mdx) -
    \ No newline at end of file diff --git a/docs/pages/kubernetes-access/helm/guides/gcp.mdx b/docs/pages/setup/helm-deployments/gcp.mdx similarity index 90% rename from docs/pages/kubernetes-access/helm/guides/gcp.mdx rename to docs/pages/setup/helm-deployments/gcp.mdx index d00808545e609..b88ded6e85425 100644 --- a/docs/pages/kubernetes-access/helm/guides/gcp.mdx +++ b/docs/pages/setup/helm-deployments/gcp.mdx @@ -10,27 +10,8 @@ using Teleport Helm charts and Google Cloud Platform products (Firestore and Goo (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-cloud-warning.mdx!) -You can also view this guide as a user of another Teleport edition: - - - - - - - - - - ## Prerequisites (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) @@ -62,37 +43,37 @@ Go to the "Roles" section of Google Cloud IAM & Admin. 1. Click the "Create Role" button at the top.
    - ![Roles section](../../../../img/helm/gcp/1-roles@1.5x.png) + ![Roles section](../../../img/helm/gcp/1-roles@1.5x.png)
    2. Fill in the details of a "Storage Bucket Creator" role (we suggest using the name `storage-bucket-creator-role`)
    - ![Create role](../../../../img/helm/gcp/2-createrole@1.5x.png) + ![Create role](../../../img/helm/gcp/2-createrole@1.5x.png)
    3. Click the "Add Permissions" button.
    - ![Storage bucket creator role](../../../../img/helm/gcp/3-addpermissions@1.5x.png) + ![Storage bucket creator role](../../../img/helm/gcp/3-addpermissions@1.5x.png)
    4. Use the "Filter" box to enter `storage.buckets.create` and select it in the list.
    - ![Filter the list](../../../../img/helm/gcp/4-storagebucketscreate@1.5x.png) + ![Filter the list](../../../img/helm/gcp/4-storagebucketscreate@1.5x.png)
    5. Check the `storage.buckets.create` permission in the list and click the "Add" button to add it to the role.
    - ![Select storage.buckets.create](../../../../img/helm/gcp/5-select@1.5x.png) + ![Select storage.buckets.create](../../../img/helm/gcp/5-select@1.5x.png)
    6. Once all these settings are entered successfully, click the "Create" button.
    - ![Create role](../../../../img/helm/gcp/6-createrole@1.5x.png) + ![Create role](../../../img/helm/gcp/6-createrole@1.5x.png)
    ### Create an IAM role granting Cloud DNS permissions @@ -102,19 +83,19 @@ Go to the "Roles" section of Google Cloud IAM & Admin. 1. Click the "Create Role" button at the top.
    - ![Roles section](../../../../img/helm/gcp/1-roles@1.5x.png) + ![Roles section](../../../img/helm/gcp/1-roles@1.5x.png)
    2. Fill in the details of a "DNS Updater" role (we suggest using the name `dns-updater-role`)
    - ![Create role](../../../../img/helm/gcp/13-dns-createrole@1.5x.png) + ![Create role](../../../img/helm/gcp/13-dns-createrole@1.5x.png)
    3. Click the "Add Permissions" button.
    - ![DNS updater role](../../../../img/helm/gcp/3-addpermissions@1.5x.png) + ![DNS updater role](../../../img/helm/gcp/3-addpermissions@1.5x.png)
    4. Use the "Filter" box to find each of the following permissions in the list and add it. @@ -134,7 +115,7 @@ dns.managedZones.list 5. Once all these settings are entered successfully, click the "Create" button.
    - ![Add DNS permissions](../../../../img/helm/gcp/14-dns-permissions-create@1.5x.png) + ![Add DNS permissions](../../../img/helm/gcp/14-dns-permissions-create@1.5x.png)
    ### Create a service account for the Teleport Helm chart @@ -150,13 +131,13 @@ Go to the "Service Accounts" section of Google Cloud IAM & Admin. 1. Click the "Create Service Account" button at the top.
    - ![Create service account](../../../../img/helm/gcp/7-serviceaccounts@1.5x.png) + ![Create service account](../../../img/helm/gcp/7-serviceaccounts@1.5x.png)
    2. Enter details for the service account (we recommend using the name `teleport-helm`) and click the "Create" button.
    - ![Enter service account details](../../../../img/helm/gcp/8-createserviceaccount@1.5x.png) + ![Enter service account details](../../../img/helm/gcp/8-createserviceaccount@1.5x.png)
    3. In the "Grant this service account access to project" section, add these four roles: @@ -170,7 +151,7 @@ Go to the "Service Accounts" section of Google Cloud IAM & Admin. | Storage Object Viewer | Allows reading of Google Cloud storage objects |
    - ![Add roles](../../../../img/helm/gcp/9-addroles@1.5x.png) + ![Add roles](../../../img/helm/gcp/9-addroles@1.5x.png)
    4. Click the "continue" button to save these settings, then click the "create" button to create the service account. @@ -182,20 +163,20 @@ Go back to the "Service Accounts" view in Google Cloud IAM & Admin. 1. Click on the `teleport-helm` service account that you just created.
    - ![Click on the service account](../../../../img/helm/gcp/10-serviceaccountdetails@1.5x.png) + ![Click on the service account](../../../img/helm/gcp/10-serviceaccountdetails@1.5x.png)
    2. Click the "Keys" tab at the top and click "Add Key". Choose "JSON" and click "Create".
    - ![Create JSON key](../../../../img/helm/gcp/11-createkey.png) + ![Create JSON key](../../../img/helm/gcp/11-createkey.png)
    3. The JSON private key will be downloaded to your computer. Take note of the filename (`bens-demos-24150b1a0a7f.json` in this example) as you will need it shortly.
    - ![Private key saved](../../../../img/helm/gcp/12-privatekey@1.5x.png) + ![Private key saved](../../../img/helm/gcp/12-privatekey@1.5x.png)
    @@ -432,7 +413,7 @@ To make changes to your Teleport cluster after deployment, you can use `helm upg Helm defaults to using the latest version of the chart available in the repo, which will also correspond to the latest version of Teleport. You can make sure that the repo is up to date by running `helm repo update`. -If you want to use a different version of Teleport, set the [`teleportVersionOverride`](../reference/teleport-cluster.mdx#teleportversionoverride) value. +If you want to use a different version of Teleport, set the [`teleportVersionOverride`](../../kubernetes-access/helm/reference/teleport-cluster.mdx#teleportversionoverride) value. Here's an example where we set the chart to use 3 replicas: @@ -483,9 +464,8 @@ $ helm --namespace cert-manager uninstall cert-manager ## Next steps -You can follow our [Getting Started with Teleport guide](../../../setup/guides/docker.mdx#step-34-creating-a-teleport-user) to finish setting up your +You can follow our [Getting Started with Teleport guide](../guides/docker.mdx#step-34-creating-a-teleport-user) to finish setting up your Teleport cluster. -See the [high availability section of our Helm chart reference](../reference/teleport-cluster.mdx#highavailability) for more details on high availability. +See the [high availability section of our Helm chart reference](../../kubernetes-access/helm/reference/teleport-cluster.mdx#highavailability) for more details on high availability. -
    \ No newline at end of file diff --git a/docs/pages/kubernetes-access/helm/guides/migration.mdx b/docs/pages/setup/helm-deployments/migration.mdx similarity index 97% rename from docs/pages/kubernetes-access/helm/guides/migration.mdx rename to docs/pages/setup/helm-deployments/migration.mdx index 53c9c934daa20..790dbcaa7a52e 100644 --- a/docs/pages/kubernetes-access/helm/guides/migration.mdx +++ b/docs/pages/setup/helm-deployments/migration.mdx @@ -19,25 +19,8 @@ to use the newer `teleport-cluster` Helm chart instead. You can also view this guide as a user of another Teleport edition: - - - - - - - - - ## Prerequisites (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) @@ -270,5 +253,3 @@ To uninstall the `teleport-cluster` chart, use `helm uninstall `. ```code $ helm --namespace teleport-cluster uninstall teleport ``` - - \ No newline at end of file diff --git a/docs/pages/setup/operations/backup-restore.mdx b/docs/pages/setup/operations/backup-restore.mdx index 84fe4d3f15432..832e22815dd34 100644 --- a/docs/pages/setup/operations/backup-restore.mdx +++ b/docs/pages/setup/operations/backup-restore.mdx @@ -114,6 +114,10 @@ When migrating backends, you should back up your Auth Service's ### Example of backing up and restoring a cluster ```code +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. +$ tsh login --proxy=teleport.example.com --user=myuser # Export dynamic configuration state from old cluster $ tctl get all --with-secrets > state.yaml @@ -146,9 +150,9 @@ also apply to a new cluster being bootstrapped from the state of an old cluster: - Changing the cluster name will break your CAs. This will be caught and Teleport will refuse to start. - - Some user authentication mechanisms (e.g. WebAuthn and U2F) require that the - public endpoint of the Web UI remains the same. This cannot be caught by - Teleport, so be careful! + - Some user authentication mechanisms (e.g. WebAuthn) require that the public + endpoint of the Web UI remains the same. This cannot be caught by Teleport, + so be careful! - Any Node whose invite token is defined in the Auth Service's configuration file will be able to join automatically, but Nodes that were added dynamically will need to be re-invited. @@ -174,6 +178,10 @@ When migrating backends, you should back up your Auth Service's ### Example of backing up and restoring a cluster ```code +# Log in to your cluster with tsh so you can use tctl from your local machine. +# You can also run tctl on your Auth Service host without running "tsh login" +# first. +$ tsh login --user=myuser --proxy=teleport.example.com # Export dynamic configuration state from old cluster $ tctl get all --with-secrets > state.yaml @@ -206,9 +214,9 @@ also apply to a new cluster being bootstrapped from the state of an old cluster: - Changing the cluster name will break your CAs. This will be caught and Teleport will refuse to start. - - Some user authentication mechanisms (e.g. WebAuthn and U2F) require that the - public endpoint of the Web UI remains the same. This cannot be caught by - Teleport, so be careful! + - Some user authentication mechanisms (e.g. WebAuthn) require that the public + endpoint of the Web UI remains the same. This cannot be caught by Teleport, + so be careful! - Any Node whose invite token is defined in the Auth Service's configuration file will be able to join automatically, but Nodes that were added dynamically will need to be re-invited. @@ -216,12 +224,15 @@ also apply to a new cluster being bootstrapped from the state of an old cluster: -In Teleport Cloud, backend data is managed for you automatically. If you would -like to migrate configuration resources to a self-hosted Teleport cluster, -follow our recommended backup practice of storing configuration resources in a -git repository and running `tctl create -f` regularly for each resource. This -will enable you to keep your configuration resources up to date regardless of -storage backend. +In Teleport Cloud, backend data is managed for you automatically. + +If you would like to migrate configuration resources to a self-hosted Teleport +cluster, follow our recommended backup practice of storing configuration +resources in a git repository and running `tctl create -f` regularly for each +resource. + +This will enable you to keep your configuration resources up to date regardless +of storage backend. diff --git a/docs/pages/setup/operations/ca-rotation.mdx b/docs/pages/setup/operations/ca-rotation.mdx index 8eeed3bdbdcd2..0bfdb62ceb69c 100644 --- a/docs/pages/setup/operations/ca-rotation.mdx +++ b/docs/pages/setup/operations/ca-rotation.mdx @@ -334,4 +334,4 @@ authority is made active. ## Further reading -How the [Teleport Certificate Authority](../../architecture/authentication.mdx#authentication-in-teleport) works. +How the [Teleport Certificate Authority](../../architecture/authentication.mdx) works. diff --git a/docs/pages/setup/operations/scaling.mdx b/docs/pages/setup/operations/scaling.mdx index e2ccc7b022378..216cbfc8a99c8 100644 --- a/docs/pages/setup/operations/scaling.mdx +++ b/docs/pages/setup/operations/scaling.mdx @@ -11,27 +11,8 @@ deployments of Teleport. For Teleport Cloud customers, the settings in this guide are configured automatically. -You can view this guide as a user of another Teleport edition: - - - - - - - - - - ## Prerequisites - Teleport v(=teleport.version=) Open Source or Enterprise. @@ -76,4 +57,3 @@ $ cat /proc/$(pidof teleport)/limits # Max open files 65536 65536 files ``` - \ No newline at end of file diff --git a/docs/pages/setup/reference/audit.mdx b/docs/pages/setup/reference/audit.mdx index 82a541865be24..c390032125ba5 100644 --- a/docs/pages/setup/reference/audit.mdx +++ b/docs/pages/setup/reference/audit.mdx @@ -37,11 +37,6 @@ to get even more comprehensive audit logs with advanced security. -Refer to the -["Audit Log" section](../../architecture/authentication.mdx#audit-log) in the -Teleport architecture guide to learn more about how the audit log and Session -Recording are designed. - ## Events @@ -191,4 +186,4 @@ $ tsh --proxy=proxy play 4c146ec8-eab6-11e6-b1b3-40167e68e931 --format=json ``` - \ No newline at end of file + diff --git a/docs/pages/setup/reference/backends.mdx b/docs/pages/setup/reference/backends.mdx index a96820f4fb201..7561066ab8765 100644 --- a/docs/pages/setup/reference/backends.mdx +++ b/docs/pages/setup/reference/backends.mdx @@ -12,28 +12,8 @@ stored data (size, read/write ratio, mutability, etc.). Teleport Cloud manages Auth Service and Proxy Service data for you, so there is no need to configure a backend. - -You can view this guide as a user of another Teleport edition: - - - - - - - - - - | Data type | Description | Supported storage backends | | - | - | - | | core cluster state | Cluster configuration (e.g. users, roles, auth connectors) and identity (e.g. certificate authorities, registered nodes, trusted clusters). | Local directory (SQLite), etcd, AWS DynamoDB, GCP Firestore, self-hosted PostgreSQL/CockroachDB (Preview) | @@ -233,7 +213,8 @@ teleport: The AWS authentication settings above can be omitted if the machine itself is running on an EC2 instance with an IAM role. -The optional `GET` parameters shown below control how Teleport interacts with an S3 endpoint, including S3-compatible endpoints. +You can add optional query parameters to the S3 URL. The Teleport Auth +Service reads these parameters to configure its interactions with S3: `s3://bucket/path?region=us-east-1&endpoint=mys3.example.com&insecure=false&disablesse=false&acl=private` @@ -703,5 +684,3 @@ $ psql -d postgres postgres=# CREATE DATABASE teleport; postgres=# GRANT ALL PRIVILEGES ON DATABASE teleport TO dbuser; ``` - - \ No newline at end of file diff --git a/docs/pages/setup/reference/cli.mdx b/docs/pages/setup/reference/cli.mdx index a72f874f6e13a..0adb311019f86 100644 --- a/docs/pages/setup/reference/cli.mdx +++ b/docs/pages/setup/reference/cli.mdx @@ -154,7 +154,8 @@ information about the cluster. | `-i, --identity` | none | **string** filepath | Identity file | | `--cert-format` | `file` | `file` or `openssh` | SSH certificate format | | `--insecure` | none | none | Do not verify the server's certificate and host name. Use only in test environments. | -| `--auth` | `local` | Any defined [authentication connector](./authentication.mdx) | Specify the type of authentication connector to use. | +| `--auth` | `local` | any defined [authentication connector](./authentication.mdx), including `local` and `passwordless` | Specify the type of authentication connector to use. | +| `--mfa-mode` | auto | `auto`, `cross-platform`, `platform` or `otp` | Preferred mode for MFA and Passwordless assertions. | | `--skip-version-check` | none | none | Skip version checking between server and client. | | `-d, --debug` | none | none | Verbose logging to stdout | | `-J, --jumphost` | none | A jump host | SSH jumphost | @@ -402,6 +403,12 @@ List cluster nodes: $ tsh ls [] [