From e00ff42cb82448838854377fb0e0fc7b4bedef77 Mon Sep 17 00:00:00 2001 From: Nic Klaassen Date: Tue, 8 Feb 2022 10:48:13 -0800 Subject: [PATCH] IAM Join Method (backend implementation) (#10085) --- api/types/provisioning.go | 74 +- api/types/provisioning_test.go | 272 +++ api/types/types.pb.go | 1519 +++++++++-------- api/types/types.proto | 27 +- integration/ec2_test.go | 2 +- lib/auth/apiserver.go | 4 +- lib/auth/auth.go | 75 +- lib/auth/auth_test.go | 108 +- lib/auth/auth_with_roles.go | 20 +- lib/auth/clt.go | 8 +- lib/auth/join.go | 131 ++ lib/auth/{ec2_join.go => join_ec2.go} | 37 +- .../{ec2_join_test.go => join_ec2_test.go} | 114 +- lib/auth/join_iam.go | 350 ++++ lib/auth/join_iam_test.go | 422 +++++ lib/auth/join_test.go | 251 +++ lib/auth/register.go | 23 +- lib/auth/trustedcluster.go | 8 +- lib/config/configuration.go | 4 +- lib/service/cfg.go | 13 +- lib/service/connect.go | 2 +- lib/service/service.go | 4 +- lib/srv/alpnproxy/local_proxy.go | 4 +- lib/srv/app/aws/handler.go | 5 +- lib/srv/app/aws/handler_test.go | 3 +- lib/srv/app/server.go | 3 +- lib/utils/aws.go | 61 - lib/{srv/app => utils}/aws/aws.go | 43 +- lib/{srv/app => utils}/aws/aws_test.go | 50 + lib/utils/aws_test.go | 73 - lib/web/apiserver.go | 4 +- lib/web/sessions.go | 4 +- lib/web/ui/app.go | 6 +- 33 files changed, 2603 insertions(+), 1121 deletions(-) create mode 100644 api/types/provisioning_test.go create mode 100644 lib/auth/join.go rename lib/auth/{ec2_join.go => join_ec2.go} (88%) rename lib/auth/{ec2_join_test.go => join_ec2_test.go} (91%) create mode 100644 lib/auth/join_iam.go create mode 100644 lib/auth/join_iam_test.go create mode 100644 lib/auth/join_test.go delete mode 100644 lib/utils/aws.go rename lib/{srv/app => utils}/aws/aws.go (84%) rename lib/{srv/app => utils}/aws/aws_test.go (68%) delete mode 100644 lib/utils/aws_test.go diff --git a/api/types/provisioning.go b/api/types/provisioning.go index c1e113ac1f735..c03ccb4a1e925 100644 --- a/api/types/provisioning.go +++ b/api/types/provisioning.go @@ -1,5 +1,5 @@ /* -Copyright 2020 Gravitational, Inc. +Copyright 2020-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. @@ -25,6 +25,20 @@ import ( "github.com/gravitational/trace" ) +// JoinMethod is the method used for new nodes to join the cluster. +type JoinMethod string + +const ( + JoinMethodUnspecified JoinMethod = "" + // JoinMethodToken is the default join method, nodes join the cluster by + // presenting a secret token. + JoinMethodToken JoinMethod = "token" + // JoinMethodEC2 indicates that the node will join with the EC2 join method. + JoinMethodEC2 JoinMethod = "ec2" + // JoinMethodIAM indicates that the node will join with the IAM join method. + JoinMethodIAM JoinMethod = "iam" +) + // ProvisionToken is a provisioning token type ProvisionToken interface { Resource @@ -40,6 +54,8 @@ type ProvisionToken interface { GetAllowRules() []*TokenRule // GetAWSIIDTTL returns the TTL of EC2 IIDs GetAWSIIDTTL() Duration + // GetJoinMethod returns joining method that must be used with this token. + GetJoinMethod() JoinMethod // V1 returns V1 version of the resource V1() *ProvisionTokenV1 // String returns user friendly representation of the resource @@ -98,8 +114,55 @@ func (p *ProvisionTokenV2) CheckAndSetDefaults() error { return trace.Wrap(err) } - if p.Spec.AWSIIDTTL == 0 { - p.Spec.AWSIIDTTL = Duration(5 * time.Minute) + hasAllowRules := len(p.Spec.Allow) > 0 + if p.Spec.JoinMethod == JoinMethodUnspecified { + // Default to the ec2 join method if any allow rules were specified, + // else default to the token method. These defaults are necessary for + // backwards compatibility. + if hasAllowRules { + p.Spec.JoinMethod = JoinMethodEC2 + } else { + p.Spec.JoinMethod = JoinMethodToken + } + } + switch p.Spec.JoinMethod { + case JoinMethodToken: + if hasAllowRules { + return trace.BadParameter("allow rules are not compatible with the %q join method", JoinMethodToken) + } + case JoinMethodEC2: + if !hasAllowRules { + return trace.BadParameter("the %q join method requires defined token allow rules", JoinMethodEC2) + } + for _, allowRule := range p.Spec.Allow { + if allowRule.AWSARN != "" { + return trace.BadParameter(`the %q join method does not support the "aws_arn" parameter`, JoinMethodEC2) + } + if allowRule.AWSAccount == "" && allowRule.AWSRole == "" { + return trace.BadParameter(`allow rule for %q join method must set "aws_account" or "aws_role"`, JoinMethodEC2) + } + } + if p.Spec.AWSIIDTTL == 0 { + // default to 5 minute ttl if unspecified + p.Spec.AWSIIDTTL = Duration(5 * time.Minute) + } + case JoinMethodIAM: + if !hasAllowRules { + return trace.BadParameter("the %q join method requires defined token allow rules", JoinMethodIAM) + } + for _, allowRule := range p.Spec.Allow { + if allowRule.AWSRole != "" { + return trace.BadParameter(`the %q join method does not support the "aws_role" parameter`, JoinMethodIAM) + } + if len(allowRule.AWSRegions) != 0 { + return trace.BadParameter(`the %q join method does not support the "aws_regions" parameter`, JoinMethodIAM) + } + if allowRule.AWSAccount == "" && allowRule.AWSARN == "" { + return trace.BadParameter(`allow rule for %q join method must set "aws_account" or "aws_arn"`, JoinMethodEC2) + } + } + default: + return trace.BadParameter("unknown join method %q", p.Spec.JoinMethod) } return nil @@ -132,6 +195,11 @@ func (p *ProvisionTokenV2) GetAWSIIDTTL() Duration { return p.Spec.AWSIIDTTL } +// GetJoinMethod returns joining method that must be used with this token. +func (p *ProvisionTokenV2) GetJoinMethod() JoinMethod { + return p.Spec.JoinMethod +} + // GetKind returns resource kind func (p *ProvisionTokenV2) GetKind() string { return p.Kind diff --git a/api/types/provisioning_test.go b/api/types/provisioning_test.go new file mode 100644 index 0000000000000..d87d81d65093a --- /dev/null +++ b/api/types/provisioning_test.go @@ -0,0 +1,272 @@ +/* +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 types + +import ( + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" +) + +func TestProvisionTokenV2_CheckAndSetDefaults(t *testing.T) { + testcases := []struct { + desc string + token *ProvisionTokenV2 + expected *ProvisionTokenV2 + expectedErr error + }{ + { + desc: "empty", + token: &ProvisionTokenV2{}, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "missing roles", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "invalid role", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode, "not a role"}, + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "simple token", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + }, + }, + expected: &ProvisionTokenV2{ + Kind: "token", + Version: "v2", + Metadata: Metadata{ + Name: "test", + Namespace: "default", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "token", + }, + }, + }, + { + desc: "implicit ec2 method", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + Allow: []*TokenRule{ + &TokenRule{ + AWSAccount: "1234", + AWSRole: "1234/role", + AWSRegions: []string{"us-west-2"}, + }, + }, + }, + }, + expected: &ProvisionTokenV2{ + Kind: "token", + Version: "v2", + Metadata: Metadata{ + Name: "test", + Namespace: "default", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{ + &TokenRule{ + AWSAccount: "1234", + AWSRole: "1234/role", + AWSRegions: []string{"us-west-2"}, + }, + }, + AWSIIDTTL: Duration(5 * time.Minute), + }, + }, + }, + { + desc: "explicit ec2 method", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{&TokenRule{AWSAccount: "1234"}}, + }, + }, + expected: &ProvisionTokenV2{ + Kind: "token", + Version: "v2", + Metadata: Metadata{ + Name: "test", + Namespace: "default", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{&TokenRule{AWSAccount: "1234"}}, + AWSIIDTTL: Duration(5 * time.Minute), + }, + }, + }, + { + desc: "ec2 method no allow rules", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "ec2 method with aws_arn", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{ + &TokenRule{ + AWSAccount: "1234", + AWSARN: "1234", + }, + }, + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "ec2 method empty rule", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{&TokenRule{}}, + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "iam method", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{&TokenRule{AWSAccount: "1234"}}, + }, + }, + expected: &ProvisionTokenV2{ + Kind: "token", + Version: "v2", + Metadata: Metadata{ + Name: "test", + Namespace: "default", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "ec2", + Allow: []*TokenRule{&TokenRule{AWSAccount: "1234"}}, + AWSIIDTTL: Duration(5 * time.Minute), + }, + }, + }, + { + desc: "iam method with aws_role", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "iam", + Allow: []*TokenRule{ + &TokenRule{ + AWSAccount: "1234", + AWSRole: "1234/role", + }, + }, + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + { + desc: "iam method with aws_regions", + token: &ProvisionTokenV2{ + Metadata: Metadata{ + Name: "test", + }, + Spec: ProvisionTokenSpecV2{ + Roles: []SystemRole{RoleNode}, + JoinMethod: "iam", + Allow: []*TokenRule{ + &TokenRule{ + AWSAccount: "1234", + AWSRegions: []string{"us-west-2"}, + }, + }, + }, + }, + expectedErr: &trace.BadParameterError{}, + }, + } + + for _, tc := range testcases { + t.Run(tc.desc, func(t *testing.T) { + err := tc.token.CheckAndSetDefaults() + if tc.expectedErr != nil { + require.ErrorAs(t, err, &tc.expectedErr) + return + } + require.NoError(t, err) + require.Equal(t, tc.token, tc.expected) + }) + } +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 6e929eadebdd8..93419b19bbe0c 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -2236,10 +2236,20 @@ func (m *ProvisionTokenV2List) XXX_DiscardUnknown() { var xxx_messageInfo_ProvisionTokenV2List proto.InternalMessageInfo +// TokenRule is a rule that a joining node must match in order to use the +// associated token. type TokenRule struct { - AWSAccount string `protobuf:"bytes,1,opt,name=AWSAccount,proto3" json:"aws_account,omitempty"` - AWSRegions []string `protobuf:"bytes,2,rep,name=AWSRegions,proto3" json:"aws_regions,omitempty"` - AWSRole string `protobuf:"bytes,3,opt,name=AWSRole,proto3" json:"aws_role,omitempty"` + // AWSAccount is the AWS account ID. + AWSAccount string `protobuf:"bytes,1,opt,name=AWSAccount,proto3" json:"aws_account,omitempty"` + // AWSRegions is used for the EC2 join method and is a list of AWS regions a + // node is allowed to join from. + AWSRegions []string `protobuf:"bytes,2,rep,name=AWSRegions,proto3" json:"aws_regions,omitempty"` + // AWSRole is used for the EC2 join method and is the the ARN of the AWS + // role that the auth server will assume in order to call the ec2 API. + AWSRole string `protobuf:"bytes,3,opt,name=AWSRole,proto3" json:"aws_role,omitempty"` + // AWSARN is used for the IAM join method, the AWS identity of joining nodes + // must match this ARN. Supports wildcards "*" and "?". + AWSARN string `protobuf:"bytes,4,opt,name=AWSARN,proto3" json:"aws_arn,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2283,12 +2293,19 @@ type ProvisionTokenSpecV2 struct { // Roles is a list of roles associated with the token, // that will be converted to metadata in the SSH and X509 // certificates issued to the user of the token - Roles []SystemRole `protobuf:"bytes,1,rep,name=Roles,proto3,casttype=SystemRole" json:"roles"` - Allow []*TokenRule `protobuf:"bytes,2,rep,name=allow,proto3" json:"allow,omitempty"` - AWSIIDTTL Duration `protobuf:"varint,3,opt,name=AWSIIDTTL,proto3,casttype=Duration" json:"aws_iid_ttl,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Roles []SystemRole `protobuf:"bytes,1,rep,name=Roles,proto3,casttype=SystemRole" json:"roles"` + // Allow is a list of TokenRules, nodes using this token must match one + // allow rule to use this token. + Allow []*TokenRule `protobuf:"bytes,2,rep,name=Allow,proto3" json:"allow,omitempty"` + // AWSIIDTTL is the TTL to use for AWS EC2 Instance Identity Documents used + // to join the cluster with this token. + AWSIIDTTL Duration `protobuf:"varint,3,opt,name=AWSIIDTTL,proto3,casttype=Duration" json:"aws_iid_ttl,omitempty"` + // JoinMethod is the joining method required in order to use this token. + // Supported joining methods include "token", "ec2", and "iam". + JoinMethod JoinMethod `protobuf:"bytes,4,opt,name=JoinMethod,proto3,casttype=JoinMethod" json:"join_method"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ProvisionTokenSpecV2) Reset() { *m = ProvisionTokenSpecV2{} } @@ -8034,9 +8051,12 @@ type RegisterUsingTokenRequest struct { // RemoteAddr is the remote address of the host requesting a host certificate. // It is used to replace 0.0.0.0 in the list of additional principals. RemoteAddr string `protobuf:"bytes,9,opt,name=RemoteAddr,proto3" json:"remote_addr"` - // EC2IdentityDocument is used for Simplified Node Joining to prove the - // identity of a joining EC2 instance. - EC2IdentityDocument []byte `protobuf:"bytes,10,opt,name=EC2IdentityDocument,proto3" json:"ec2_id"` + // EC2IdentityDocument is used for the EC2 join method to prove the identity + // of a joining EC2 instance. + EC2IdentityDocument []byte `protobuf:"bytes,10,opt,name=EC2IdentityDocument,proto3" json:"ec2_id"` + // STSIdentityRequest is used for the IAM join method to prove the AWS + // identity of a joining node. + STSIdentityRequest []byte `protobuf:"bytes,11,opt,name=STSIdentityRequest,proto3" json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -8406,676 +8426,680 @@ func init() { func init() { proto.RegisterFile("types.proto", fileDescriptor_d938547f84707355) } var fileDescriptor_d938547f84707355 = []byte{ - // 10704 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x7d, 0x5b, 0x6c, 0x24, 0xd9, - 0x75, 0xd8, 0x54, 0x77, 0x93, 0xec, 0x3e, 0x7c, 0x35, 0xef, 0x0c, 0x67, 0x38, 0xb3, 0xb3, 0xdb, - 0xa3, 0xda, 0xd7, 0xcc, 0x68, 0x77, 0x66, 0x87, 0xb3, 0xbb, 0xd2, 0x6a, 0x5f, 0xea, 0x26, 0x39, - 0x33, 0xd4, 0x70, 0x48, 0x6e, 0x35, 0x1f, 0x7a, 0xba, 0x5c, 0xec, 0xba, 0x43, 0x96, 0xd8, 0xdd, - 0xd5, 0xaa, 0xaa, 0x1e, 0x0e, 0xad, 0x18, 0x76, 0x12, 0x28, 0x82, 0x61, 0x58, 0xb2, 0x02, 0x19, - 0x92, 0x03, 0x27, 0x31, 0x84, 0x04, 0x79, 0x18, 0xca, 0x87, 0x15, 0x20, 0x08, 0x90, 0x7c, 0x18, - 0x30, 0x1c, 0x7d, 0xc4, 0x88, 0xfe, 0x02, 0x3b, 0x01, 0x13, 0xc9, 0xf9, 0x31, 0x81, 0x7c, 0xe5, - 0xcb, 0x4a, 0x84, 0x18, 0xf7, 0xdc, 0x7b, 0xab, 0xee, 0xad, 0xae, 0x26, 0x9b, 0x3b, 0xb3, 0x80, - 0xb8, 0x5f, 0x64, 0x9f, 0x7b, 0xce, 0xb9, 0xef, 0x73, 0xcf, 0xb9, 0xf7, 0x9c, 0x53, 0x30, 0x1a, - 0xed, 0x77, 0x68, 0x78, 0xa3, 0x13, 0xf8, 0x91, 0x4f, 0x86, 0xf0, 0xc7, 0xa5, 0x73, 0xdb, 0xfe, - 0xb6, 0x8f, 0x90, 0x9b, 0xec, 0x3f, 0x5e, 0x78, 0xa9, 0xb2, 0xed, 0xfb, 0xdb, 0x4d, 0x7a, 0x13, - 0x7f, 0x6d, 0x75, 0x1f, 0xde, 0x8c, 0xbc, 0x16, 0x0d, 0x23, 0xa7, 0xd5, 0x11, 0x08, 0x73, 0xdb, - 0x5e, 0xb4, 0xd3, 0xdd, 0xba, 0xd1, 0xf0, 0x5b, 0x37, 0xb7, 0x03, 0xe7, 0x91, 0x17, 0x39, 0x91, - 0xe7, 0xb7, 0x9d, 0xe6, 0xcd, 0x88, 0x36, 0x69, 0xc7, 0x0f, 0xa2, 0x9b, 0x4e, 0xc7, 0xbb, 0x89, - 0x75, 0xdc, 0xdc, 0x0b, 0x9c, 0x4e, 0x87, 0x06, 0xc9, 0x3f, 0x9c, 0x89, 0xf9, 0x9d, 0x3c, 0x94, - 0xee, 0x53, 0xda, 0xa9, 0x36, 0xbd, 0x47, 0x94, 0x3c, 0x0f, 0x85, 0x65, 0xa7, 0x45, 0x67, 0x8c, - 0x2b, 0xc6, 0xd5, 0x52, 0x6d, 0xf2, 0xf0, 0xa0, 0x32, 0x1a, 0xd2, 0xe0, 0x11, 0x0d, 0xec, 0xb6, - 0xd3, 0xa2, 0x16, 0x16, 0x92, 0x4f, 0x42, 0x89, 0xfd, 0x0d, 0x3b, 0x4e, 0x83, 0xce, 0xe4, 0x10, - 0x73, 0xfc, 0xf0, 0xa0, 0x52, 0x6a, 0x4b, 0xa0, 0x95, 0x94, 0x93, 0x97, 0x60, 0x64, 0x89, 0x3a, - 0x21, 0x5d, 0x9c, 0x9f, 0xc9, 0x5f, 0x31, 0xae, 0xe6, 0x6b, 0x63, 0x87, 0x07, 0x95, 0x62, 0x93, - 0x81, 0x6c, 0xcf, 0xb5, 0x64, 0x21, 0x59, 0x84, 0x91, 0x85, 0xc7, 0x1d, 0x2f, 0xa0, 0xe1, 0x4c, - 0xe1, 0x8a, 0x71, 0x75, 0x74, 0xf6, 0xd2, 0x0d, 0xde, 0xff, 0x1b, 0xb2, 0xff, 0x37, 0xd6, 0x64, - 0xff, 0x6b, 0x67, 0x7f, 0x7c, 0x50, 0x39, 0x73, 0x78, 0x50, 0x19, 0xa1, 0x9c, 0xe4, 0x77, 0xff, - 0x47, 0xc5, 0xb0, 0x24, 0x3d, 0x79, 0x07, 0x0a, 0x6b, 0xfb, 0x1d, 0x3a, 0x53, 0xba, 0x62, 0x5c, - 0x9d, 0x98, 0x7d, 0xee, 0x06, 0x1f, 0xf1, 0xb8, 0x93, 0xc9, 0x7f, 0x0c, 0xab, 0x56, 0x3c, 0x3c, - 0xa8, 0x14, 0x18, 0x8a, 0x85, 0x54, 0xe4, 0x55, 0x18, 0xbe, 0xe7, 0x87, 0xd1, 0xe2, 0xfc, 0x0c, - 0x60, 0xd7, 0xa6, 0x0f, 0x0f, 0x2a, 0x53, 0x3b, 0x7e, 0x18, 0xd9, 0x9e, 0xfb, 0x8a, 0xdf, 0xf2, - 0x22, 0xda, 0xea, 0x44, 0xfb, 0x96, 0x40, 0x32, 0x2d, 0x18, 0xd7, 0xf8, 0x91, 0x51, 0x18, 0x59, - 0x5f, 0xbe, 0xbf, 0xbc, 0xb2, 0xb9, 0x5c, 0x3e, 0x43, 0x8a, 0x50, 0x58, 0x5e, 0x99, 0x5f, 0x28, - 0x1b, 0x64, 0x04, 0xf2, 0xd5, 0xd5, 0xd5, 0x72, 0x8e, 0x8c, 0x41, 0x71, 0xbe, 0xba, 0x56, 0xad, - 0x55, 0xeb, 0x0b, 0xe5, 0x3c, 0x39, 0x0b, 0x93, 0x9b, 0x8b, 0xcb, 0xf3, 0x2b, 0x9b, 0x75, 0x7b, - 0x7e, 0xa1, 0x7e, 0x7f, 0x6d, 0x65, 0xb5, 0x5c, 0x30, 0xbf, 0x99, 0x87, 0xe2, 0x03, 0x1a, 0x39, - 0xae, 0x13, 0x39, 0xe4, 0xb2, 0x36, 0x25, 0xd8, 0x5a, 0x65, 0x2e, 0x9e, 0xef, 0x9d, 0x8b, 0xa1, - 0xc3, 0x83, 0x8a, 0xf1, 0xaa, 0x3a, 0x07, 0x6f, 0xc3, 0xe8, 0x3c, 0x0d, 0x1b, 0x81, 0xd7, 0x61, - 0xeb, 0x03, 0xe7, 0xa1, 0x54, 0xbb, 0x78, 0x78, 0x50, 0x99, 0x76, 0x13, 0xb0, 0xd2, 0x37, 0x15, - 0x9b, 0x2c, 0xc2, 0xf0, 0x92, 0xb3, 0x45, 0x9b, 0xe1, 0xcc, 0xd0, 0x95, 0xfc, 0xd5, 0xd1, 0xd9, - 0x67, 0xc4, 0x78, 0xca, 0x06, 0xde, 0xe0, 0xa5, 0x0b, 0xed, 0x28, 0xd8, 0xaf, 0x9d, 0x3b, 0x3c, - 0xa8, 0x94, 0x9b, 0x08, 0x50, 0xc7, 0x8a, 0xa3, 0x90, 0x7a, 0x32, 0xc7, 0xc3, 0xc7, 0xce, 0xf1, - 0xb3, 0x3f, 0x3e, 0xa8, 0x18, 0x6c, 0xec, 0xc5, 0x1c, 0x27, 0xfc, 0xf4, 0xd9, 0xbe, 0x02, 0xb9, - 0xc5, 0xf9, 0x99, 0x11, 0x5c, 0x5b, 0xe5, 0xc3, 0x83, 0xca, 0x98, 0x36, 0x4d, 0xb9, 0xc5, 0xf9, - 0x4b, 0x6f, 0xc1, 0xa8, 0xd2, 0x46, 0x52, 0x86, 0xfc, 0x2e, 0xdd, 0xe7, 0xe3, 0x69, 0xb1, 0x7f, - 0xc9, 0x39, 0x18, 0x7a, 0xe4, 0x34, 0xbb, 0x62, 0x00, 0x2d, 0xfe, 0xe3, 0x33, 0xb9, 0x4f, 0x1b, - 0xe6, 0x3f, 0x2c, 0x40, 0xd1, 0xf2, 0xf9, 0xbe, 0x22, 0xd7, 0x60, 0xa8, 0x1e, 0x39, 0x91, 0x9c, - 0x8a, 0xb3, 0x87, 0x07, 0x95, 0xc9, 0x90, 0x01, 0x94, 0xfa, 0x38, 0x06, 0x43, 0x5d, 0xdd, 0x71, - 0x42, 0x39, 0x25, 0x88, 0xda, 0x61, 0x00, 0x15, 0x15, 0x31, 0xc8, 0x4b, 0x50, 0x78, 0xe0, 0xbb, - 0x54, 0xcc, 0x0a, 0x39, 0x3c, 0xa8, 0x4c, 0xb4, 0x7c, 0x57, 0x45, 0xc4, 0x72, 0xf2, 0x0a, 0x94, - 0xe6, 0xba, 0x41, 0x40, 0xdb, 0x6c, 0x69, 0x16, 0x10, 0x79, 0xe2, 0xf0, 0xa0, 0x02, 0x0d, 0x0e, - 0x64, 0x9b, 0x29, 0x41, 0x60, 0x43, 0x5d, 0x8f, 0x9c, 0x20, 0xa2, 0xee, 0xcc, 0xd0, 0x40, 0x43, - 0xcd, 0xb6, 0xd3, 0x54, 0xc8, 0x49, 0xd2, 0x43, 0x2d, 0x38, 0x91, 0x7b, 0x30, 0x7a, 0x37, 0x70, - 0x1a, 0x74, 0x95, 0x06, 0x9e, 0xef, 0xe2, 0x1c, 0xe6, 0x6b, 0x2f, 0x1d, 0x1e, 0x54, 0xce, 0x6f, - 0x33, 0xb0, 0xdd, 0x41, 0x78, 0x42, 0xfd, 0xf3, 0x83, 0x4a, 0x71, 0xbe, 0x1b, 0xe0, 0xe8, 0x59, - 0x2a, 0x29, 0xf9, 0x55, 0x36, 0x25, 0x61, 0x84, 0x43, 0x4b, 0x5d, 0x9c, 0xbd, 0xa3, 0x9b, 0x68, - 0x8a, 0x26, 0x9e, 0x6f, 0x3a, 0x61, 0x64, 0x07, 0x9c, 0x2e, 0xd5, 0x4e, 0x95, 0x25, 0x59, 0x81, - 0x62, 0xbd, 0xb1, 0x43, 0xdd, 0x6e, 0x93, 0xce, 0x14, 0x91, 0xfd, 0x05, 0xb1, 0x70, 0xe5, 0x7c, - 0xca, 0xe2, 0xda, 0x25, 0xc1, 0x9b, 0x84, 0x02, 0xa2, 0x8c, 0x7d, 0xcc, 0xe4, 0x33, 0xc5, 0xef, - 0xff, 0x61, 0xe5, 0xcc, 0x6f, 0xfe, 0xf7, 0x2b, 0x67, 0xcc, 0x7f, 0x97, 0x83, 0x72, 0x9a, 0x09, - 0x79, 0x08, 0xe3, 0xeb, 0x1d, 0xd7, 0x89, 0xe8, 0x5c, 0xd3, 0xa3, 0xed, 0x28, 0xc4, 0x45, 0x72, - 0x74, 0x9f, 0x5e, 0x10, 0xf5, 0xce, 0x74, 0x91, 0xd0, 0x6e, 0x70, 0xca, 0x54, 0xaf, 0x74, 0xb6, - 0x49, 0x3d, 0x75, 0x94, 0xcb, 0x21, 0xae, 0xb0, 0x93, 0xd5, 0xc3, 0x25, 0x7a, 0x9f, 0x7a, 0x04, - 0x5b, 0xb1, 0x80, 0xda, 0xee, 0xd6, 0x3e, 0xae, 0xcc, 0xc1, 0x17, 0x10, 0x23, 0xc9, 0x58, 0x40, - 0x0c, 0x6c, 0xfe, 0x2f, 0x03, 0x26, 0x2c, 0x1a, 0xfa, 0xdd, 0xa0, 0x41, 0xef, 0x51, 0xc7, 0xa5, - 0x01, 0x5b, 0xfe, 0xf7, 0xbd, 0xb6, 0x2b, 0xf6, 0x14, 0x2e, 0xff, 0x5d, 0xaf, 0xad, 0x6e, 0x61, - 0x2c, 0x27, 0xaf, 0xc1, 0x48, 0xbd, 0xbb, 0x85, 0xa8, 0x7c, 0x4f, 0x9d, 0xc7, 0x19, 0xeb, 0x6e, - 0xd9, 0x29, 0x74, 0x89, 0x46, 0x6e, 0xc2, 0xc8, 0x06, 0x0d, 0xc2, 0x44, 0xe2, 0xa1, 0x24, 0x7f, - 0xc4, 0x41, 0x2a, 0x81, 0xc0, 0x22, 0x77, 0x13, 0xa9, 0x2b, 0xce, 0xa0, 0xc9, 0x94, 0xac, 0x4b, - 0x96, 0x4a, 0x4b, 0x40, 0xd4, 0xa5, 0x22, 0xb1, 0xcc, 0xef, 0xe4, 0xa0, 0x3c, 0xef, 0x44, 0xce, - 0x96, 0x13, 0x8a, 0xf1, 0xdc, 0xb8, 0xcd, 0xe4, 0xb8, 0xd2, 0x51, 0x94, 0xe3, 0xac, 0xe5, 0x1f, - 0xba, 0x7b, 0x2f, 0xa6, 0xbb, 0x37, 0xca, 0x0e, 0x44, 0xd1, 0xbd, 0xa4, 0x53, 0xef, 0x1e, 0xdf, - 0xa9, 0xb2, 0xe8, 0x54, 0x51, 0x76, 0x2a, 0xe9, 0x0a, 0x79, 0x17, 0x0a, 0xf5, 0x0e, 0x6d, 0x08, - 0x21, 0x22, 0x65, 0xbf, 0xde, 0x39, 0x86, 0xb0, 0x71, 0xbb, 0x36, 0x26, 0xd8, 0x14, 0xc2, 0x0e, - 0x6d, 0x58, 0x48, 0xa6, 0x6c, 0x9a, 0xef, 0x0e, 0xc3, 0xb9, 0x2c, 0x32, 0xf2, 0xae, 0x7e, 0x38, - 0xf1, 0xe1, 0x79, 0xa6, 0xef, 0xe1, 0x34, 0x63, 0xe8, 0xc7, 0xd3, 0x75, 0x28, 0xae, 0xb2, 0x05, - 0xd9, 0xf0, 0x9b, 0x62, 0xe4, 0x98, 0x54, 0x2c, 0x76, 0x24, 0xcc, 0xb0, 0xe2, 0x72, 0xf2, 0x0c, - 0xe4, 0xd7, 0xad, 0x45, 0x31, 0x5c, 0xa5, 0xc3, 0x83, 0x4a, 0xbe, 0x1b, 0x78, 0x33, 0x86, 0xc5, - 0xa0, 0xe4, 0x26, 0x0c, 0xcf, 0x55, 0xe7, 0x68, 0x10, 0xe1, 0x30, 0x8d, 0xd5, 0x2e, 0xb0, 0xd5, - 0xd2, 0x70, 0xec, 0x06, 0x0d, 0x22, 0xad, 0x7a, 0x81, 0x46, 0x3e, 0x09, 0xf9, 0xea, 0x66, 0x5d, - 0x8c, 0x0c, 0x88, 0x91, 0xa9, 0x6e, 0xd6, 0x6b, 0xe3, 0x62, 0x20, 0xf2, 0xce, 0x5e, 0xc8, 0xb8, - 0x57, 0x37, 0xeb, 0xea, 0x6c, 0x0d, 0x1f, 0x31, 0x5b, 0x57, 0xa1, 0xc8, 0xf4, 0x0a, 0x76, 0xc0, - 0xa3, 0x50, 0x2c, 0x71, 0x75, 0x69, 0x47, 0xc0, 0xac, 0xb8, 0x94, 0x3c, 0x1f, 0xab, 0x29, 0xc5, - 0x84, 0x9f, 0x50, 0x53, 0xa4, 0x72, 0x42, 0x1e, 0xc3, 0xf8, 0xfc, 0x7e, 0xdb, 0x69, 0x79, 0x0d, - 0x71, 0x84, 0x97, 0xf0, 0x08, 0xbf, 0x71, 0xc4, 0x34, 0xde, 0xd0, 0x08, 0xf8, 0xa9, 0x2e, 0x85, - 0xef, 0x8c, 0xcb, 0xcb, 0xec, 0xf4, 0x09, 0x3f, 0x63, 0x58, 0x7a, 0x45, 0x6c, 0x2f, 0x49, 0x11, - 0x89, 0x7a, 0x54, 0xb2, 0xec, 0x24, 0x38, 0xd9, 0x4b, 0x81, 0x80, 0xa8, 0x7b, 0x29, 0x3e, 0x74, - 0xdf, 0x85, 0xfc, 0xdd, 0xb9, 0xd5, 0x99, 0x51, 0xe4, 0x41, 0x04, 0x8f, 0xbb, 0x73, 0xab, 0x73, - 0x4d, 0xbf, 0xeb, 0xd6, 0x3f, 0x58, 0xaa, 0x5d, 0x10, 0x6c, 0xc6, 0xb7, 0x1b, 0x1d, 0xad, 0x45, - 0x8c, 0x8e, 0x2c, 0x40, 0x51, 0xf6, 0x72, 0x66, 0x0c, 0x79, 0x4c, 0xa5, 0x3a, 0xbf, 0x71, 0x9b, - 0xef, 0x35, 0x57, 0xfc, 0x56, 0x5b, 0x21, 0x71, 0x2e, 0x6d, 0x02, 0xe9, 0x1d, 0x97, 0x0c, 0x4d, - 0xe2, 0x93, 0xaa, 0x26, 0x31, 0x3a, 0x3b, 0x2d, 0xea, 0x9a, 0xf3, 0x5b, 0x2d, 0xa7, 0xed, 0x22, - 0xed, 0xc6, 0xac, 0xaa, 0x60, 0x54, 0x61, 0x22, 0x69, 0xc8, 0x92, 0x17, 0x46, 0xe4, 0x26, 0x94, - 0x24, 0x84, 0x1d, 0x22, 0xf9, 0xcc, 0x26, 0x5b, 0x09, 0x8e, 0xf9, 0x67, 0x39, 0x80, 0xa4, 0xe4, - 0x94, 0xca, 0x99, 0x4f, 0x69, 0x72, 0x66, 0x3a, 0xbd, 0x40, 0xfb, 0x4a, 0x18, 0xf2, 0x3e, 0x0c, - 0x33, 0x95, 0xab, 0x2b, 0x55, 0xca, 0x0b, 0x69, 0x52, 0x2c, 0xdc, 0xb8, 0x5d, 0x9b, 0x10, 0xc4, - 0xc3, 0x21, 0x42, 0x2c, 0x41, 0xa6, 0x88, 0xa8, 0xff, 0x58, 0x48, 0x26, 0x43, 0x08, 0xa7, 0xab, - 0x8a, 0x74, 0x31, 0x92, 0xfd, 0x28, 0xa5, 0x8b, 0x22, 0x5b, 0x2e, 0x72, 0xd9, 0xc2, 0x07, 0x75, - 0x44, 0xc8, 0x96, 0xb4, 0x64, 0xe1, 0x03, 0x78, 0xac, 0x64, 0xe9, 0xa4, 0xb7, 0x6d, 0x01, 0x97, - 0xc1, 0xd5, 0xcc, 0x51, 0xc9, 0xda, 0xb0, 0x57, 0x8e, 0xdb, 0xb0, 0xe9, 0xed, 0x7a, 0xbb, 0x9f, - 0x2c, 0x9b, 0x96, 0xbb, 0xcb, 0xd9, 0x53, 0xc9, 0x51, 0xa6, 0xbd, 0xcd, 0xb7, 0xe6, 0x70, 0xdf, - 0xad, 0x39, 0x9d, 0xb9, 0x35, 0xf9, 0xc6, 0x7c, 0x1b, 0x86, 0xaa, 0xbf, 0xd6, 0x0d, 0xa8, 0xd0, - 0xfd, 0xc6, 0x64, 0x9d, 0x0c, 0x16, 0xef, 0xe9, 0x49, 0x87, 0xfd, 0x54, 0x75, 0x66, 0x2c, 0x67, - 0x35, 0xaf, 0x2d, 0xd5, 0x85, 0x5e, 0x47, 0x52, 0xc3, 0xb2, 0xb6, 0xa4, 0x34, 0x3b, 0xd2, 0x7a, - 0xcd, 0xa8, 0x3e, 0xba, 0xbd, 0xdc, 0x54, 0x4e, 0x7d, 0xb1, 0xea, 0x98, 0x35, 0x29, 0xe6, 0xde, - 0x48, 0x74, 0x90, 0x9e, 0xb9, 0x8f, 0x67, 0xfe, 0x1a, 0x9f, 0x87, 0x5c, 0xcf, 0x3c, 0x8c, 0x2a, - 0x67, 0x0a, 0x8e, 0xbe, 0xf9, 0xd7, 0x06, 0xe2, 0x92, 0x57, 0x60, 0xd8, 0xa2, 0xdb, 0xc9, 0xd1, - 0x89, 0x26, 0x58, 0x80, 0x10, 0xb5, 0x02, 0x8e, 0x83, 0x72, 0x99, 0xba, 0xe1, 0x8e, 0xf7, 0x30, - 0x12, 0xb5, 0xc4, 0x72, 0x59, 0x80, 0x15, 0xb9, 0x2c, 0x20, 0x9a, 0x5c, 0x16, 0x30, 0xb6, 0x62, - 0xac, 0xf9, 0xba, 0xd0, 0x0d, 0x65, 0x4b, 0xad, 0x79, 0x65, 0xe8, 0x03, 0x57, 0x1b, 0x7a, 0x6b, - 0xbe, 0x4e, 0xde, 0x84, 0x52, 0xb5, 0xd1, 0xf0, 0xbb, 0x8a, 0x0d, 0x33, 0x73, 0x78, 0x50, 0x39, - 0xe7, 0x70, 0xa0, 0x6e, 0x61, 0x27, 0xa8, 0x66, 0x2d, 0x69, 0x35, 0xe3, 0x31, 0xd7, 0xec, 0x86, - 0x11, 0x0d, 0x16, 0xe7, 0x45, 0x97, 0x91, 0x47, 0x83, 0x03, 0x53, 0x3c, 0x62, 0x54, 0xf3, 0xbf, - 0x19, 0xd8, 0x62, 0xf2, 0x16, 0xc0, 0x62, 0x9b, 0xe9, 0xa9, 0x0d, 0x1a, 0x33, 0x40, 0x5b, 0xd8, - 0x13, 0x50, 0x9d, 0x83, 0x82, 0xac, 0x57, 0x9d, 0x1b, 0xb8, 0x6a, 0x56, 0xa5, 0xd4, 0x7a, 0xc5, - 0x35, 0x88, 0xa8, 0x32, 0x10, 0xd0, 0x54, 0x95, 0x09, 0x32, 0x79, 0x09, 0x46, 0x16, 0xab, 0x0f, - 0xaa, 0xdd, 0x68, 0x07, 0xc7, 0xab, 0xc8, 0xe5, 0x8f, 0xe7, 0xb4, 0x6c, 0xa7, 0x1b, 0xed, 0x58, - 0xb2, 0xd0, 0xfc, 0x4d, 0x03, 0x46, 0x95, 0xad, 0xc7, 0x9a, 0xba, 0x1a, 0xf8, 0x5f, 0xa5, 0x8d, - 0x48, 0x1f, 0xa5, 0x0e, 0x07, 0xa6, 0x9a, 0x1a, 0xa3, 0xa6, 0x46, 0x27, 0x77, 0x82, 0xd1, 0x31, - 0x6f, 0x8a, 0x1d, 0xcd, 0x54, 0x7a, 0xe5, 0xc6, 0x02, 0x55, 0x7a, 0xa6, 0xb2, 0xa8, 0x2a, 0x3d, - 0x2b, 0x37, 0x7f, 0x68, 0xc0, 0xa8, 0xb2, 0x69, 0xc9, 0xeb, 0xc2, 0x12, 0x36, 0xf0, 0xde, 0xe6, - 0x7c, 0xef, 0xb6, 0x66, 0xa5, 0xfc, 0x44, 0x63, 0x16, 0xb2, 0xb0, 0x8b, 0x93, 0x1d, 0x96, 0x1b, - 0x64, 0x87, 0xbd, 0x05, 0xc0, 0xd5, 0x1d, 0x6c, 0xa2, 0x32, 0x17, 0xca, 0x3d, 0x97, 0xda, 0xc1, - 0x04, 0xd9, 0xfc, 0xbb, 0x39, 0x28, 0x0a, 0x75, 0x7e, 0xf6, 0x94, 0x1e, 0xb3, 0x6f, 0x68, 0xc7, - 0xec, 0x59, 0x41, 0xaa, 0xe8, 0x7f, 0xb3, 0xc7, 0xa8, 0xf1, 0x6f, 0xc1, 0x98, 0x1c, 0x02, 0xd4, - 0x56, 0xae, 0xc1, 0x88, 0x34, 0x44, 0xb9, 0xae, 0x32, 0xa9, 0xf1, 0xdc, 0x98, 0xb5, 0x64, 0xb9, - 0xf9, 0x9d, 0x21, 0x49, 0xcb, 0x6b, 0x62, 0x43, 0x58, 0x75, 0xdd, 0x40, 0x1d, 0x42, 0xc7, 0x75, - 0x03, 0x0b, 0xa1, 0x6c, 0xa2, 0x56, 0xbb, 0x5b, 0x4d, 0xaf, 0x81, 0x38, 0xca, 0x4a, 0xec, 0x20, - 0xd4, 0x66, 0xa8, 0xea, 0x44, 0x25, 0xc8, 0x9a, 0x16, 0x9d, 0x3f, 0x52, 0x8b, 0xfe, 0x15, 0x28, - 0xcd, 0xb5, 0x5c, 0xed, 0x94, 0x35, 0x33, 0x06, 0xe5, 0x46, 0x8c, 0xc4, 0xcf, 0xd7, 0xcb, 0x62, - 0x8c, 0xce, 0x35, 0x5a, 0x6e, 0xef, 0xd9, 0x9a, 0xb0, 0xd4, 0xd4, 0xe0, 0xa1, 0x27, 0x51, 0x83, - 0xdf, 0x84, 0xd2, 0x7a, 0x48, 0xd7, 0xba, 0xed, 0x36, 0x6d, 0xe2, 0x89, 0x5b, 0xe4, 0xfb, 0xb9, - 0x1b, 0x52, 0x3b, 0x42, 0xa8, 0xda, 0x80, 0x18, 0x55, 0x5d, 0x56, 0x23, 0x47, 0x2c, 0xab, 0xd7, - 0xa1, 0x50, 0xed, 0x74, 0xa4, 0x7d, 0x10, 0x1f, 0x3c, 0x9d, 0x0e, 0x1e, 0x27, 0x13, 0x4e, 0xa7, - 0xa3, 0x6b, 0xfb, 0x88, 0x4d, 0x28, 0x90, 0xfb, 0xdd, 0x2d, 0x1a, 0xb4, 0x69, 0x44, 0x43, 0x21, - 0xee, 0xc2, 0x19, 0x40, 0x1e, 0x33, 0xf2, 0xda, 0x35, 0x8d, 0x80, 0xb6, 0xdd, 0x85, 0xdd, 0xee, - 0x16, 0xb5, 0x85, 0xdc, 0x54, 0xc7, 0x2e, 0x83, 0xe1, 0xa5, 0x3a, 0x4c, 0xe8, 0xe3, 0xff, 0x14, - 0x0e, 0xeb, 0xcf, 0x15, 0x8a, 0xc5, 0x72, 0xc9, 0xfc, 0x66, 0x0e, 0x46, 0xab, 0x9d, 0xce, 0x29, - 0x37, 0xd2, 0x3f, 0xad, 0xed, 0xea, 0xf3, 0xc9, 0xec, 0x9d, 0xc0, 0x3e, 0xff, 0x1b, 0x03, 0x26, - 0x53, 0x14, 0x6a, 0xeb, 0x8d, 0x01, 0x8d, 0xd6, 0xdc, 0x80, 0x46, 0x6b, 0xbe, 0xbf, 0xd1, 0xaa, - 0xee, 0x99, 0xc2, 0x93, 0xec, 0x99, 0x97, 0x21, 0x5f, 0xed, 0x74, 0xc4, 0xa8, 0x8c, 0x25, 0xa3, - 0xb2, 0x71, 0x9b, 0x2b, 0xe8, 0x4e, 0xa7, 0x63, 0x31, 0x0c, 0xf3, 0x55, 0x28, 0x21, 0x18, 0x25, - 0xda, 0x15, 0xb1, 0x15, 0xb8, 0x38, 0xd3, 0xc8, 0xf8, 0xb2, 0x37, 0xff, 0xaf, 0x01, 0x43, 0xf8, - 0xfb, 0x94, 0x2e, 0x97, 0x59, 0x6d, 0xb9, 0x94, 0x95, 0xe5, 0x32, 0xc8, 0x42, 0xf9, 0xe3, 0x3c, - 0x8e, 0x96, 0x58, 0x22, 0xc2, 0xec, 0x31, 0x32, 0xcc, 0x9e, 0x27, 0x10, 0xe0, 0xbb, 0x69, 0x03, - 0x28, 0x8f, 0x93, 0xf1, 0x7c, 0xba, 0xa9, 0x4f, 0xc5, 0xf6, 0xb9, 0x07, 0x64, 0xb1, 0x1d, 0xd2, - 0x46, 0x37, 0xa0, 0xf5, 0x5d, 0xaf, 0xb3, 0x41, 0x03, 0xef, 0xe1, 0xbe, 0xd0, 0xb6, 0x50, 0xc6, - 0x7a, 0xa2, 0xd4, 0x0e, 0x77, 0xbd, 0x8e, 0xfd, 0x08, 0xcb, 0xad, 0x0c, 0x1a, 0xf2, 0x3e, 0x8c, - 0x58, 0x74, 0x2f, 0xf0, 0x22, 0x2a, 0xc6, 0x76, 0x22, 0xd6, 0xad, 0x11, 0xca, 0x75, 0x93, 0x80, - 0xff, 0x50, 0xe7, 0x5f, 0x94, 0x7f, 0x74, 0xa6, 0xc9, 0x77, 0x87, 0x70, 0x2f, 0x1c, 0xf3, 0x98, - 0x74, 0x84, 0x0d, 0xab, 0x4f, 0x66, 0xfe, 0x24, 0x93, 0xb9, 0x01, 0x63, 0xcc, 0x1c, 0x4a, 0x19, - 0xb3, 0x97, 0x93, 0xb9, 0xbc, 0xa1, 0x16, 0x1f, 0xf5, 0x8e, 0xa4, 0xf1, 0x21, 0x76, 0x7a, 0x91, - 0xf0, 0xf7, 0xa9, 0x67, 0x15, 0xc6, 0x19, 0xcb, 0x23, 0x16, 0x1d, 0x0d, 0x3e, 0x58, 0x27, 0x5e, - 0x18, 0xc3, 0x4f, 0xb6, 0x30, 0x46, 0x3e, 0xcc, 0xc2, 0x48, 0xbf, 0xe0, 0x15, 0x4f, 0xf2, 0x82, - 0x77, 0xe9, 0x7d, 0x98, 0xea, 0x19, 0xe1, 0x93, 0xbc, 0x82, 0x7d, 0x74, 0xcb, 0xf2, 0xd7, 0xe3, - 0x71, 0x21, 0xb3, 0x68, 0xe2, 0x79, 0x01, 0x6d, 0x44, 0x28, 0x7a, 0x85, 0xb4, 0x0c, 0x04, 0x2c, - 0x65, 0x83, 0x22, 0x8c, 0xbc, 0x07, 0x23, 0xfc, 0x15, 0x21, 0x9c, 0xc9, 0xe1, 0xdc, 0x8f, 0x8b, - 0x1a, 0x39, 0x54, 0x3c, 0xdd, 0x72, 0x0c, 0x75, 0x54, 0x05, 0x91, 0x79, 0x17, 0x86, 0xc5, 0x2b, - 0xc4, 0xd1, 0xfb, 0xa2, 0x02, 0x43, 0x1b, 0xc9, 0xc8, 0xe0, 0xcd, 0x31, 0xef, 0x84, 0xc5, 0xe1, - 0xe6, 0x6f, 0x1b, 0x30, 0xa1, 0xf7, 0x92, 0xdc, 0x80, 0x61, 0xf1, 0x4c, 0x66, 0xe0, 0x33, 0x19, - 0xeb, 0xcd, 0x30, 0x7f, 0x20, 0xd3, 0x9e, 0xc5, 0x04, 0x16, 0x13, 0xfd, 0x82, 0x03, 0xf6, 0x45, - 0x88, 0x7e, 0xb1, 0x48, 0x2d, 0x59, 0x46, 0x4c, 0x66, 0xed, 0x87, 0xdd, 0xa6, 0xbc, 0x4b, 0x02, - 0xc6, 0x36, 0x40, 0x88, 0x25, 0x4a, 0xcc, 0x03, 0x03, 0xa0, 0x5e, 0xbf, 0x77, 0x9f, 0xee, 0xaf, - 0x3a, 0x5e, 0x80, 0xa6, 0x20, 0xee, 0xc6, 0xfb, 0x62, 0xb6, 0xc6, 0x84, 0x29, 0xc8, 0x77, 0xee, - 0x2e, 0xdd, 0xd7, 0x4c, 0x41, 0x89, 0x8a, 0x5b, 0x3e, 0xf0, 0x1e, 0x39, 0x11, 0x65, 0x84, 0x39, - 0x24, 0xe4, 0x5b, 0x9e, 0x43, 0x53, 0x94, 0x0a, 0x32, 0xf9, 0x0a, 0x4c, 0x24, 0xbf, 0xf0, 0x2d, - 0x3e, 0x8f, 0x36, 0x9d, 0x5c, 0x11, 0x7a, 0x61, 0xed, 0xb9, 0xc3, 0x83, 0xca, 0x25, 0x85, 0xab, - 0xcd, 0xb0, 0x14, 0xd6, 0x29, 0x66, 0xe6, 0x0f, 0x0c, 0x80, 0xb5, 0xa5, 0xba, 0xec, 0xe0, 0x4b, - 0x50, 0x88, 0x6f, 0x58, 0xc6, 0xb8, 0xbd, 0x99, 0x32, 0xfe, 0xb0, 0x9c, 0x3c, 0x0f, 0xf9, 0xa4, - 0x27, 0x53, 0x87, 0x07, 0x95, 0x71, 0xbd, 0x07, 0xac, 0x94, 0xdc, 0x85, 0x91, 0x81, 0xda, 0x8c, - 0xab, 0x33, 0xa3, 0xad, 0x92, 0x1a, 0x67, 0xe1, 0x73, 0x9b, 0x6b, 0x1f, 0xdf, 0x59, 0xf8, 0x76, - 0x0e, 0x26, 0xd9, 0xb8, 0x56, 0xbb, 0xd1, 0x8e, 0x1f, 0x78, 0xd1, 0xfe, 0xa9, 0xb5, 0x8a, 0xdf, - 0xd1, 0x14, 0xa2, 0x4b, 0x52, 0x6c, 0xa9, 0x7d, 0x1b, 0xc8, 0x38, 0xfe, 0xe9, 0x08, 0x9c, 0xcd, - 0xa0, 0x22, 0xaf, 0x08, 0x87, 0x94, 0xe4, 0x1e, 0x06, 0x1d, 0x4e, 0x7e, 0x7e, 0x50, 0x19, 0x93, - 0xe8, 0x6b, 0x89, 0x03, 0xca, 0x2c, 0x8c, 0x0a, 0xd3, 0x67, 0x39, 0xd1, 0xa8, 0xd1, 0xb3, 0x41, - 0xde, 0x33, 0xa1, 0x68, 0x52, 0x91, 0x48, 0x15, 0xc6, 0xe6, 0x76, 0x68, 0x63, 0xd7, 0x6b, 0x6f, - 0xdf, 0xa7, 0xfb, 0x5c, 0x5f, 0x1a, 0xab, 0x3d, 0xcb, 0x2c, 0xad, 0x86, 0x80, 0xb3, 0x29, 0xd5, - 0x8d, 0x38, 0x8d, 0x84, 0xbc, 0x07, 0xa3, 0x75, 0x6f, 0xbb, 0x2d, 0x39, 0x14, 0x90, 0xc3, 0xe5, - 0xc3, 0x83, 0xca, 0xf9, 0x90, 0x83, 0x7b, 0x19, 0xa8, 0x04, 0xe4, 0x1a, 0x0c, 0x59, 0x7e, 0x93, - 0xf2, 0x63, 0x58, 0xb8, 0x3c, 0x04, 0x0c, 0xa0, 0x5e, 0xdf, 0x22, 0x06, 0xb9, 0x07, 0x23, 0xec, - 0x9f, 0x07, 0x4e, 0x67, 0x66, 0x18, 0xe5, 0x36, 0x89, 0x15, 0x7c, 0x84, 0x76, 0xbc, 0xf6, 0xb6, - 0xaa, 0xe3, 0x37, 0xa9, 0xdd, 0x72, 0x3a, 0xda, 0xb9, 0xc8, 0x11, 0xc9, 0x06, 0x8c, 0x26, 0x82, - 0x20, 0x9c, 0x19, 0xd1, 0x9e, 0x4b, 0x92, 0x92, 0xda, 0x27, 0x04, 0xb3, 0x0b, 0x51, 0x33, 0xc4, - 0xb5, 0xdd, 0x61, 0xf8, 0x7a, 0x67, 0x14, 0x46, 0x9a, 0x0d, 0x52, 0xec, 0x6f, 0x83, 0x18, 0xc7, - 0xda, 0x20, 0x2e, 0x80, 0x18, 0xa4, 0x6a, 0x73, 0x5b, 0x78, 0x24, 0x5d, 0xeb, 0xbf, 0xc0, 0x6e, - 0x24, 0xc8, 0xb8, 0x27, 0xf9, 0xcd, 0x94, 0x18, 0x7f, 0xa7, 0xb9, 0xad, 0xdd, 0x4c, 0xc5, 0xa8, - 0x6c, 0x18, 0x12, 0x51, 0x23, 0x2d, 0x70, 0x39, 0x0c, 0x49, 0x49, 0x32, 0x0c, 0x5f, 0xdd, 0x8b, - 0xfa, 0x0d, 0x83, 0xc2, 0x88, 0x2c, 0x03, 0x54, 0x1b, 0x91, 0xf7, 0x88, 0xe2, 0x92, 0x18, 0xd5, - 0x06, 0x62, 0xae, 0x7a, 0x9f, 0xee, 0xd7, 0x69, 0x14, 0x3f, 0xfe, 0x4f, 0x3b, 0x88, 0x9a, 0x5a, - 0x26, 0x96, 0xc2, 0x81, 0x74, 0x60, 0xba, 0xea, 0xba, 0x1e, 0xf7, 0x52, 0x5b, 0x0b, 0xd8, 0xfa, - 0x75, 0x91, 0xf5, 0x58, 0x36, 0xeb, 0x6b, 0x82, 0xf5, 0x27, 0x9c, 0x98, 0xca, 0x8e, 0x38, 0x59, - 0xba, 0x9a, 0x6c, 0xc6, 0xe6, 0x0a, 0x4c, 0xe8, 0x43, 0xaa, 0xfb, 0x67, 0x8d, 0x41, 0xd1, 0xaa, - 0x57, 0xed, 0xfa, 0xbd, 0xea, 0xad, 0xb2, 0x41, 0xca, 0x30, 0x26, 0x7e, 0xcd, 0xda, 0xb3, 0x6f, - 0xbc, 0x59, 0xce, 0x69, 0x90, 0x37, 0x6e, 0xcd, 0x96, 0xf3, 0xe6, 0x1f, 0x1b, 0x50, 0x94, 0xed, - 0x23, 0x6f, 0x42, 0xbe, 0x5e, 0xbf, 0x97, 0x7a, 0xa5, 0x4b, 0x8e, 0x5e, 0x7e, 0xc8, 0x84, 0xe1, - 0x8e, 0x7a, 0xc8, 0xd4, 0xeb, 0xf7, 0x18, 0xdd, 0xda, 0x52, 0x5d, 0x28, 0x2d, 0x19, 0xcb, 0x75, - 0x2a, 0xfb, 0xe9, 0x82, 0xd1, 0x7d, 0x6e, 0x73, 0x4d, 0x58, 0x43, 0x19, 0xf3, 0x8b, 0x74, 0x5f, - 0xdd, 0x53, 0x8f, 0x3e, 0x46, 0x60, 0x5a, 0x30, 0xaa, 0x6c, 0x2d, 0xae, 0x44, 0xb4, 0xfc, 0xd8, - 0x93, 0x49, 0x28, 0x11, 0x0c, 0x62, 0x89, 0x12, 0xa6, 0xf3, 0x2c, 0xf9, 0x0d, 0xa7, 0x29, 0xb4, - 0x11, 0xd4, 0x79, 0x9a, 0x0c, 0x60, 0x71, 0xb8, 0xf9, 0x27, 0x06, 0x94, 0x57, 0x03, 0xff, 0x91, - 0xc7, 0x24, 0xf0, 0x9a, 0xbf, 0x4b, 0xdb, 0x1b, 0xb7, 0xc8, 0xab, 0x52, 0x08, 0x70, 0x15, 0xee, - 0x02, 0xa3, 0x42, 0x21, 0xf0, 0xf3, 0x83, 0x0a, 0xd4, 0xf7, 0xc3, 0x88, 0xb6, 0x58, 0xb9, 0x14, - 0x04, 0x8a, 0x43, 0x58, 0x6e, 0x70, 0x27, 0x93, 0x63, 0x1c, 0xc2, 0x2a, 0x30, 0x84, 0xcd, 0x51, - 0xde, 0xf9, 0x87, 0x22, 0x06, 0xb0, 0x38, 0x5c, 0x11, 0xd8, 0xdf, 0xc9, 0xf5, 0xf4, 0x61, 0xf6, - 0x63, 0xe5, 0xa8, 0xa1, 0x77, 0x6e, 0xa0, 0x43, 0xec, 0x0b, 0x70, 0x2e, 0x3d, 0x24, 0x78, 0x2f, - 0x52, 0x85, 0x49, 0x1d, 0x2e, 0xaf, 0x48, 0x2e, 0x64, 0xd6, 0xb5, 0x31, 0x6b, 0xa5, 0xf1, 0xcd, - 0x1f, 0x19, 0x50, 0xc2, 0x7f, 0xad, 0x6e, 0x93, 0x32, 0xcd, 0xa6, 0xba, 0x59, 0x17, 0x8f, 0x3c, - 0xea, 0x43, 0x8c, 0xb3, 0x17, 0xda, 0xe2, 0x45, 0x48, 0x93, 0x23, 0x31, 0xb2, 0x20, 0xe5, 0x4f, - 0x5a, 0xa1, 0x58, 0xa1, 0x31, 0x29, 0x7f, 0xfb, 0x0a, 0x53, 0xa4, 0x02, 0x99, 0xcd, 0x1f, 0xfb, - 0xe5, 0x37, 0xe5, 0xd5, 0x30, 0xce, 0x1f, 0xd2, 0xf9, 0x9a, 0xe7, 0x97, 0x44, 0x33, 0xff, 0x93, - 0x91, 0x1e, 0x11, 0x71, 0xac, 0x9f, 0x70, 0xb1, 0xbf, 0x0d, 0x43, 0x4e, 0xb3, 0xe9, 0xef, 0x89, - 0x6d, 0x2f, 0xef, 0x5d, 0xe2, 0x01, 0xe1, 0x47, 0x26, 0xa2, 0xa8, 0x47, 0x26, 0x02, 0xc8, 0x1c, - 0x94, 0xaa, 0x9b, 0xf5, 0xc5, 0xc5, 0xf9, 0xb5, 0xb5, 0x25, 0xe1, 0x48, 0xfb, 0xa2, 0xec, 0xb0, - 0xe7, 0xb9, 0x76, 0x14, 0x35, 0xfb, 0xf8, 0xdd, 0x25, 0x74, 0xe6, 0xef, 0xe4, 0x60, 0x82, 0x5b, - 0x82, 0x7c, 0x42, 0x4e, 0xed, 0x62, 0x7f, 0x5b, 0x5b, 0xec, 0x17, 0xa5, 0xe0, 0x55, 0xba, 0x36, - 0xd0, 0x52, 0xdf, 0x01, 0xd2, 0x4b, 0x43, 0x2c, 0x79, 0x5f, 0x31, 0xc8, 0x2a, 0xbf, 0x95, 0xbc, - 0x77, 0x86, 0x48, 0x64, 0xa3, 0xa8, 0x09, 0x2d, 0x8d, 0x87, 0xf9, 0xdb, 0x39, 0x18, 0x57, 0xf4, - 0xb5, 0x53, 0x3b, 0xf0, 0x9f, 0xd1, 0x06, 0x5e, 0xde, 0xf1, 0x2b, 0x3d, 0x1b, 0x68, 0xdc, 0xbb, - 0x30, 0xd5, 0x43, 0x92, 0x56, 0x7b, 0x8d, 0x41, 0xd4, 0xde, 0x57, 0x7a, 0x1f, 0x64, 0xb9, 0x4f, - 0x6c, 0xfc, 0x20, 0xab, 0xbe, 0x00, 0x7f, 0x3b, 0x07, 0xe7, 0xc4, 0xaf, 0x6a, 0xd7, 0xf5, 0xa2, - 0x39, 0xbf, 0xfd, 0xd0, 0xdb, 0x3e, 0xb5, 0x73, 0x51, 0xd5, 0xe6, 0xa2, 0xa2, 0xcf, 0x85, 0xd2, - 0xc1, 0xfe, 0x53, 0x62, 0xfe, 0x87, 0x22, 0xcc, 0xf4, 0x23, 0x60, 0x66, 0xb5, 0x62, 0xb5, 0xa0, - 0x59, 0x9d, 0xb2, 0x08, 0xb9, 0xbd, 0x92, 0x38, 0x20, 0xe4, 0x06, 0x70, 0x40, 0x58, 0x82, 0x32, - 0x56, 0x55, 0xa7, 0x21, 0x1b, 0x84, 0x30, 0x71, 0xc8, 0xbb, 0x72, 0x78, 0x50, 0xb9, 0xec, 0xb0, - 0x32, 0x3b, 0x14, 0x85, 0x76, 0x37, 0xf0, 0x14, 0x1e, 0x3d, 0x94, 0xe4, 0x07, 0x06, 0x4c, 0x20, - 0x70, 0xe1, 0x11, 0x6d, 0x47, 0xc8, 0xac, 0x20, 0x1e, 0x41, 0xe2, 0x38, 0x87, 0x7a, 0x14, 0x78, - 0xed, 0x6d, 0xbc, 0xa8, 0x09, 0x6b, 0x5b, 0x6c, 0x14, 0xfe, 0xf2, 0xa0, 0xf2, 0xce, 0x87, 0x89, - 0x9d, 0x10, 0xac, 0x42, 0x66, 0x28, 0xf3, 0x86, 0x52, 0xac, 0x36, 0xd5, 0xcc, 0x54, 0x8b, 0xc8, - 0x17, 0xe1, 0xc2, 0x42, 0xdb, 0xd9, 0x6a, 0xd2, 0x39, 0xbf, 0x1d, 0x79, 0xed, 0xae, 0xdf, 0x0d, - 0x6b, 0x4e, 0x63, 0xb7, 0xdb, 0x09, 0xc5, 0x65, 0x22, 0xf6, 0xbc, 0x11, 0x17, 0xda, 0x5b, 0xbc, - 0x54, 0x61, 0xd9, 0x8f, 0x01, 0xb9, 0x07, 0x53, 0xbc, 0xa8, 0xda, 0x8d, 0xfc, 0x7a, 0xc3, 0x69, - 0x7a, 0xed, 0x6d, 0xbc, 0x63, 0x2c, 0xd6, 0x2e, 0x31, 0xdb, 0xcd, 0xe9, 0x46, 0xbe, 0x1d, 0x72, - 0xb8, 0xc2, 0xaf, 0x97, 0x88, 0x2c, 0xc2, 0xa4, 0x45, 0x1d, 0xf7, 0x81, 0xf3, 0x78, 0xce, 0xe9, - 0x38, 0x0d, 0x2f, 0xda, 0x47, 0xcb, 0x27, 0x5f, 0xab, 0x1c, 0x1e, 0x54, 0x9e, 0x09, 0xa8, 0xe3, - 0xda, 0x2d, 0xe7, 0xb1, 0xdd, 0x10, 0x85, 0x0a, 0xb3, 0x34, 0x5d, 0xcc, 0xca, 0x6b, 0xc7, 0xac, - 0x4a, 0x69, 0x56, 0x5e, 0xbb, 0x3f, 0xab, 0x84, 0x4e, 0xb2, 0x5a, 0x73, 0x82, 0x6d, 0x1a, 0xf1, - 0x4b, 0x38, 0xb8, 0x62, 0x5c, 0x35, 0x14, 0x56, 0x11, 0x96, 0xd9, 0x78, 0x21, 0x97, 0x66, 0xa5, - 0xd0, 0xb1, 0x95, 0xb7, 0x19, 0x78, 0x11, 0x55, 0x7b, 0x38, 0x8a, 0xcd, 0xc2, 0xf1, 0xc7, 0x6b, - 0xc8, 0x7e, 0x5d, 0xec, 0xa1, 0x4c, 0xb8, 0x29, 0x9d, 0x1c, 0xeb, 0xe1, 0x96, 0xdd, 0xcb, 0x1e, - 0xca, 0x98, 0x9b, 0xda, 0xcf, 0x71, 0xec, 0xa7, 0xc2, 0xad, 0x4f, 0x47, 0x7b, 0x28, 0xc9, 0x32, - 0x1b, 0xb4, 0x88, 0xb6, 0xd9, 0x8a, 0x16, 0x97, 0x90, 0x13, 0xd8, 0xb4, 0x17, 0x84, 0xcd, 0x5a, - 0x0e, 0x64, 0xb1, 0x9d, 0x71, 0x25, 0x99, 0x26, 0xfe, 0x5c, 0xa1, 0x38, 0x54, 0x1e, 0xb6, 0xca, - 0x7c, 0xc9, 0x47, 0x6c, 0xe1, 0xa0, 0x2c, 0x36, 0x7f, 0x3f, 0x07, 0x17, 0xa5, 0x38, 0xa6, 0xd1, - 0x9e, 0x1f, 0xec, 0x7a, 0xed, 0xed, 0x53, 0x2e, 0x55, 0xef, 0x68, 0x52, 0xf5, 0x85, 0xd4, 0x09, - 0x97, 0xea, 0xe5, 0x11, 0xa2, 0xf5, 0x2f, 0x86, 0xe0, 0xd9, 0x23, 0xa9, 0xc8, 0x07, 0xec, 0x14, - 0xf4, 0x68, 0x3b, 0x5a, 0x74, 0x9b, 0x94, 0x99, 0x39, 0x7e, 0x37, 0x12, 0x97, 0xc5, 0xcf, 0x1f, - 0x1e, 0x54, 0xce, 0xf2, 0x70, 0x00, 0xdb, 0x73, 0x9b, 0xd4, 0x8e, 0x78, 0xb1, 0x36, 0x4d, 0xbd, - 0xd4, 0x8c, 0x65, 0x1c, 0x8c, 0xb4, 0xd8, 0x8e, 0x68, 0xf0, 0xc8, 0xe1, 0x5e, 0xd1, 0x82, 0xe5, - 0x2e, 0xa5, 0x1d, 0xdb, 0x61, 0xa5, 0xb6, 0x27, 0x8a, 0x75, 0x96, 0x3d, 0xd4, 0xe4, 0x8e, 0xc2, - 0x72, 0x8e, 0x29, 0xdf, 0x0f, 0x9c, 0xc7, 0x42, 0x01, 0xc5, 0xfb, 0x4b, 0x85, 0x25, 0xf7, 0xe1, - 0x6a, 0x39, 0x8f, 0xad, 0x5e, 0x12, 0xf2, 0x15, 0x98, 0x16, 0x82, 0x9b, 0x09, 0xb1, 0xc0, 0x6f, - 0xca, 0x1e, 0x17, 0x90, 0xd7, 0xcb, 0x87, 0x07, 0x95, 0x0b, 0x42, 0xec, 0xdb, 0x0d, 0x8e, 0x91, - 0xd9, 0xeb, 0x6c, 0x2e, 0x64, 0x8d, 0x1d, 0x64, 0xa9, 0xe1, 0x78, 0x40, 0xc3, 0xd0, 0xd9, 0xe6, - 0x6f, 0x71, 0xc2, 0xfd, 0x49, 0x1d, 0x4c, 0xbb, 0xc5, 0xcb, 0xad, 0xbe, 0x94, 0xe4, 0x1e, 0x4c, - 0x6c, 0xd2, 0x2d, 0x75, 0x7e, 0x86, 0xe3, 0x2d, 0x5e, 0xde, 0xa3, 0x5b, 0xfd, 0x27, 0x27, 0x45, - 0x47, 0x3c, 0x98, 0x5a, 0x0d, 0xfc, 0xc7, 0xfb, 0xcc, 0x94, 0xa2, 0x6d, 0x1a, 0xa0, 0xa3, 0xd3, - 0x08, 0x5e, 0x07, 0xcd, 0x24, 0x9a, 0xa5, 0x5e, 0x5e, 0xfb, 0xc4, 0xe1, 0x41, 0xe5, 0xd9, 0x0e, - 0x03, 0xdb, 0x4d, 0x01, 0xb7, 0x53, 0xb1, 0x41, 0xbd, 0x5c, 0xc9, 0xaf, 0xc2, 0xa4, 0xe5, 0x77, - 0x23, 0xaf, 0xbd, 0x5d, 0x8f, 0x02, 0x27, 0xa2, 0xdb, 0x5c, 0x90, 0x27, 0x1e, 0x55, 0xa9, 0x52, - 0x7e, 0xf1, 0x1b, 0x70, 0xa0, 0x1d, 0x0a, 0xa8, 0x26, 0x49, 0x75, 0x02, 0xf3, 0x7b, 0x39, 0x98, - 0x11, 0xd3, 0x60, 0xd1, 0x86, 0x1f, 0xb8, 0xa7, 0x7f, 0xdb, 0x2f, 0x68, 0xdb, 0xfe, 0xf9, 0xd8, - 0x07, 0x28, 0xab, 0x93, 0x47, 0xec, 0xfa, 0x7f, 0x63, 0xc0, 0xe5, 0xa3, 0x88, 0xd8, 0xe8, 0xc4, - 0x3e, 0x6e, 0xa5, 0x1e, 0x5f, 0xb6, 0x0e, 0x9c, 0xc5, 0xf9, 0xc4, 0x8b, 0xd9, 0xf0, 0x9e, 0x1f, - 0x46, 0x78, 0x3b, 0x96, 0xd3, 0x1e, 0xea, 0x6b, 0xbe, 0xdf, 0x44, 0x39, 0x5f, 0x7b, 0x85, 0x89, - 0xf3, 0xbf, 0x3c, 0xa8, 0x00, 0x03, 0xad, 0xe0, 0x63, 0x1f, 0x3b, 0xf3, 0xf9, 0x8a, 0xc1, 0x7b, - 0xdf, 0xd0, 0x46, 0xef, 0x8a, 0x5d, 0xba, 0x1f, 0x5a, 0x59, 0xac, 0xf1, 0x06, 0xa4, 0xda, 0x8d, - 0x76, 0x56, 0x03, 0xfa, 0x90, 0x06, 0xb4, 0xdd, 0xa0, 0x1f, 0xb3, 0x1b, 0x10, 0xbd, 0x73, 0x03, - 0x99, 0x27, 0xff, 0x7f, 0x18, 0xce, 0x65, 0x91, 0xb1, 0x71, 0x51, 0x34, 0xe2, 0x74, 0xe0, 0xe8, - 0xdf, 0x37, 0x60, 0xac, 0x4e, 0x1b, 0x7e, 0xdb, 0xbd, 0xe3, 0x34, 0x22, 0x5f, 0xba, 0x3c, 0xd8, - 0x5c, 0xb2, 0x31, 0xb8, 0xfd, 0x10, 0x0b, 0x34, 0x43, 0xfd, 0xb3, 0x83, 0x29, 0xa2, 0x0d, 0x1f, - 0x1d, 0x2d, 0x23, 0xb6, 0x26, 0x93, 0x2a, 0xf0, 0xd5, 0x40, 0xab, 0x94, 0xd4, 0x60, 0x7c, 0xce, - 0x6f, 0xb7, 0x29, 0xfb, 0xa1, 0xb8, 0x38, 0x5e, 0x3e, 0x3c, 0xa8, 0xcc, 0x34, 0x64, 0x41, 0xda, - 0xcb, 0x51, 0x27, 0x21, 0xb7, 0x21, 0xbf, 0x3e, 0x7b, 0x47, 0xcc, 0x81, 0x74, 0x06, 0x5b, 0x9f, - 0xbd, 0x83, 0xb6, 0x2e, 0xd3, 0x1f, 0xc6, 0xbb, 0xb3, 0x0f, 0xd5, 0x3b, 0xc6, 0xf5, 0xd9, 0x3b, - 0x64, 0x05, 0xa6, 0x2c, 0xfa, 0xb5, 0xae, 0x17, 0x50, 0xb1, 0x01, 0x1e, 0xdc, 0xa9, 0xe2, 0x5c, - 0x14, 0xb9, 0x1c, 0x0b, 0x78, 0xa1, 0xd4, 0xed, 0xed, 0xd6, 0x43, 0x35, 0x78, 0xaa, 0x97, 0x96, - 0xfc, 0x06, 0x4c, 0xcf, 0x7b, 0xa1, 0x68, 0x33, 0xbf, 0xdc, 0x73, 0xf1, 0x9d, 0x6f, 0xb8, 0xcf, - 0x76, 0xf8, 0x54, 0xe6, 0x76, 0xf8, 0x84, 0x1b, 0x33, 0xb1, 0xf9, 0xcd, 0xa1, 0x9b, 0xf6, 0x0d, - 0xcd, 0xae, 0x87, 0x7c, 0x15, 0x26, 0xaa, 0xcd, 0xa6, 0xbf, 0x87, 0xf7, 0x9d, 0xe8, 0x82, 0x3b, - 0xd2, 0xa7, 0xe6, 0xd7, 0x32, 0x6b, 0xbe, 0x84, 0x57, 0x37, 0x36, 0xde, 0x9a, 0xa2, 0xbb, 0xae, - 0x66, 0x23, 0x68, 0x9c, 0xc9, 0xe7, 0x60, 0x52, 0x1c, 0x3a, 0x2b, 0x0f, 0xd7, 0x76, 0xe8, 0xbc, - 0xb3, 0x2f, 0x1e, 0xf9, 0x51, 0xff, 0x13, 0x27, 0x95, 0xed, 0x3f, 0xb4, 0xa3, 0x1d, 0x6a, 0xbb, - 0x8e, 0x26, 0x9e, 0x53, 0x84, 0xe4, 0xeb, 0x30, 0xba, 0xe4, 0xe3, 0xc3, 0x0e, 0x8a, 0x9a, 0x12, - 0xf2, 0xf9, 0x02, 0x06, 0x4f, 0x72, 0x70, 0xea, 0x10, 0xf9, 0xf9, 0x41, 0xe5, 0xed, 0x93, 0xae, - 0x42, 0xa5, 0x02, 0x4b, 0xad, 0x8d, 0xcc, 0x41, 0x71, 0x93, 0x6e, 0xb1, 0xde, 0xa6, 0x03, 0x7f, - 0x24, 0x98, 0xcb, 0x8b, 0x3d, 0xf1, 0x4b, 0x7d, 0x35, 0x91, 0x18, 0xe6, 0xbf, 0x37, 0x70, 0x05, - 0x92, 0xeb, 0xe8, 0x68, 0x15, 0x7b, 0x30, 0xa3, 0x65, 0xe9, 0x74, 0x3a, 0xba, 0x0f, 0x32, 0x47, - 0x61, 0x66, 0xe8, 0x1d, 0xa7, 0x41, 0x23, 0x79, 0x1f, 0x88, 0xc8, 0x0f, 0x11, 0xa2, 0x9a, 0xa1, - 0x1c, 0x87, 0x7c, 0x1e, 0xce, 0xcd, 0xd3, 0x47, 0x5e, 0x83, 0x56, 0xa3, 0x88, 0x86, 0xbc, 0xb7, - 0x73, 0x55, 0xfe, 0x70, 0x56, 0xaa, 0xbd, 0x70, 0x78, 0x50, 0xb9, 0xe2, 0x62, 0xb9, 0xed, 0x24, - 0x08, 0x76, 0xc3, 0x51, 0x79, 0x65, 0x72, 0x30, 0xff, 0x49, 0x2e, 0x19, 0x01, 0xf2, 0x32, 0x14, - 0xac, 0xd5, 0xb8, 0xfd, 0xfc, 0x4d, 0x2c, 0xd5, 0x7c, 0x44, 0x20, 0x5f, 0x82, 0x69, 0x85, 0x0f, - 0x2e, 0x0e, 0xea, 0xb2, 0x06, 0xf1, 0xce, 0xbc, 0x88, 0x8f, 0x20, 0x4a, 0x4b, 0x1c, 0x8e, 0x91, - 0x6a, 0x51, 0x36, 0x0f, 0xd6, 0x59, 0xa5, 0x60, 0x9e, 0xb6, 0x3d, 0xce, 0x5b, 0xe9, 0xac, 0xca, - 0xdb, 0x45, 0x84, 0x74, 0x67, 0xb3, 0x38, 0x90, 0x59, 0x28, 0xce, 0x7b, 0x21, 0xb3, 0x08, 0x5c, - 0xe1, 0x31, 0xc5, 0x63, 0xa9, 0x04, 0x4c, 0x8b, 0xa5, 0x12, 0x30, 0xf3, 0x6f, 0x0c, 0x25, 0x66, - 0xfd, 0x94, 0x9e, 0x35, 0x6f, 0x6a, 0x67, 0xcd, 0x39, 0x41, 0x1a, 0xf7, 0x8a, 0x95, 0x65, 0xea, - 0x07, 0x93, 0x30, 0xae, 0x21, 0xa1, 0x03, 0xea, 0x7a, 0x48, 0x03, 0x7e, 0x9b, 0xf8, 0xf1, 0x72, - 0x40, 0x8d, 0xfb, 0x35, 0x90, 0x5f, 0xe1, 0x4f, 0x0d, 0x98, 0x4c, 0x51, 0xb0, 0xd1, 0x60, 0x20, - 0x75, 0x34, 0xba, 0x21, 0x0d, 0x2c, 0x84, 0x72, 0x77, 0xb5, 0x25, 0xdd, 0x5d, 0xad, 0x69, 0x31, - 0x18, 0xf9, 0x2c, 0x0c, 0xad, 0xa3, 0xee, 0xaf, 0x7b, 0x3c, 0xc4, 0xfc, 0xb1, 0x90, 0xef, 0xc7, - 0x2e, 0xfb, 0x57, 0x15, 0x27, 0x58, 0x46, 0xea, 0x30, 0x32, 0x17, 0x50, 0x8c, 0x4e, 0x2f, 0x0c, - 0xfe, 0x34, 0xd5, 0xe0, 0x24, 0xe9, 0xa7, 0x29, 0xc1, 0xc9, 0xfc, 0xbd, 0x1c, 0x90, 0xa4, 0x8f, - 0xb4, 0x11, 0xd0, 0x28, 0x3c, 0xb5, 0x93, 0xfe, 0xbe, 0x36, 0xe9, 0xcf, 0xf6, 0x4c, 0x3a, 0xef, - 0xde, 0x40, 0x73, 0xff, 0x27, 0x06, 0x9c, 0xcf, 0x26, 0x24, 0xcf, 0xc3, 0xf0, 0xca, 0xda, 0xaa, - 0x74, 0x9a, 0x11, 0x5d, 0xf1, 0x3b, 0xa8, 0xd3, 0x5a, 0xa2, 0x88, 0xbc, 0x0a, 0xc3, 0x1f, 0x58, - 0x73, 0xec, 0xb0, 0x53, 0x62, 0x40, 0xbe, 0x16, 0xd8, 0x0d, 0xdd, 0x58, 0x12, 0x48, 0xea, 0xdc, - 0xe6, 0x9f, 0xda, 0xdc, 0x7e, 0x3b, 0x07, 0x93, 0xd5, 0x46, 0x83, 0x86, 0x21, 0x53, 0x65, 0x68, - 0x18, 0x9d, 0xda, 0x89, 0xcd, 0x76, 0x87, 0xd1, 0xfa, 0x36, 0xd0, 0xac, 0xfe, 0x99, 0x01, 0xd3, - 0x92, 0xea, 0x91, 0x47, 0xf7, 0xd6, 0x76, 0x02, 0x1a, 0xee, 0xf8, 0x4d, 0x77, 0xd0, 0x08, 0x21, - 0x3c, 0xd3, 0xbd, 0x66, 0x44, 0x03, 0xf5, 0x6a, 0xf9, 0x21, 0x42, 0xb4, 0x33, 0x1d, 0x21, 0xe4, - 0x26, 0x8c, 0x54, 0x3b, 0x9d, 0xc0, 0x7f, 0xc4, 0xb7, 0xfd, 0x38, 0x5f, 0x06, 0x0e, 0x07, 0x69, - 0x2f, 0x7b, 0x1c, 0xc4, 0x9a, 0x31, 0x4f, 0xdb, 0xdc, 0xd7, 0x77, 0x9c, 0x37, 0xc3, 0xa5, 0x6d, - 0x55, 0xb7, 0xc2, 0x72, 0xf3, 0x5b, 0x05, 0x18, 0x53, 0x3b, 0x42, 0x4c, 0x18, 0xe6, 0x8e, 0x1b, - 0xea, 0x03, 0xba, 0x83, 0x10, 0x4b, 0x94, 0x24, 0xfe, 0x30, 0xb9, 0x63, 0xfd, 0x61, 0x36, 0x61, - 0x7c, 0x35, 0xf0, 0x3b, 0x7e, 0x48, 0x5d, 0x9e, 0x60, 0x84, 0x4b, 0xad, 0xb3, 0xb1, 0x93, 0x28, - 0x1f, 0x73, 0x56, 0xc4, 0x15, 0xf9, 0x8e, 0xc0, 0xb6, 0xd3, 0xe9, 0x47, 0x74, 0x3e, 0xfc, 0x6a, - 0xde, 0x09, 0x85, 0x23, 0x7d, 0x7c, 0x35, 0xcf, 0x20, 0xfa, 0xd5, 0x3c, 0x83, 0xa8, 0xdb, 0x62, - 0xe8, 0x69, 0x6d, 0x0b, 0xf2, 0x7b, 0x06, 0x8c, 0x56, 0xdb, 0x6d, 0xe1, 0x0f, 0x23, 0xa3, 0x74, - 0xa7, 0x93, 0xeb, 0x79, 0xee, 0x30, 0xc9, 0x6f, 0xe7, 0xbf, 0x2c, 0x6e, 0xe7, 0xdf, 0xfe, 0x50, - 0xb7, 0xf3, 0x6b, 0x81, 0xe3, 0x45, 0x21, 0xbe, 0x8a, 0x26, 0x15, 0xaa, 0x4e, 0xb1, 0x4a, 0x3b, - 0xc8, 0xdb, 0x50, 0x8e, 0xd7, 0xe3, 0x62, 0xdb, 0xa5, 0x8f, 0x29, 0x77, 0x1f, 0x1a, 0xe7, 0x59, - 0x8f, 0xb4, 0x67, 0x87, 0x34, 0xa2, 0xf9, 0x6d, 0x03, 0xce, 0xab, 0x0b, 0xa2, 0xde, 0xdd, 0x6a, - 0x79, 0x68, 0xb8, 0x90, 0x1b, 0x50, 0x12, 0xf3, 0x15, 0xab, 0x7d, 0xbd, 0x59, 0x69, 0x12, 0x14, - 0xb2, 0xc0, 0xa6, 0x88, 0xf1, 0x10, 0x56, 0xfe, 0xd9, 0xd4, 0x76, 0x63, 0x45, 0xb5, 0x19, 0x31, - 0xd8, 0xe5, 0x00, 0x7f, 0xeb, 0x73, 0xc7, 0x20, 0xe6, 0x7b, 0x30, 0xa5, 0xb7, 0xb2, 0x4e, 0x31, - 0x38, 0x4b, 0x76, 0xcd, 0xc8, 0xee, 0x9a, 0x2c, 0x37, 0x37, 0x81, 0xf4, 0xd0, 0x87, 0xf8, 0xc4, - 0x44, 0x23, 0xf9, 0x04, 0x2a, 0x2f, 0xaa, 0x7a, 0x10, 0xe3, 0x7c, 0x4c, 0xa3, 0xea, 0x70, 0x23, - 0xa9, 0xf9, 0x8b, 0x12, 0x9c, 0xcd, 0x10, 0x1d, 0xc7, 0x1c, 0xed, 0x15, 0x7d, 0xf3, 0x94, 0xe2, - 0xa7, 0x75, 0xb9, 0x65, 0xde, 0x93, 0xb9, 0x78, 0x8e, 0xd8, 0x2a, 0x47, 0x25, 0xe8, 0xf9, 0x28, - 0x8e, 0x77, 0xd5, 0x9d, 0x65, 0xe8, 0xa9, 0xb9, 0xb3, 0xd4, 0x60, 0x5c, 0xf4, 0x4a, 0x6c, 0xe5, - 0xe1, 0xc4, 0xa0, 0x0f, 0x78, 0x81, 0xdd, 0xb3, 0xa5, 0x75, 0x12, 0xce, 0x23, 0xf4, 0x9b, 0x8f, - 0xa8, 0xe0, 0x31, 0xa2, 0xf2, 0xc0, 0x82, 0x4c, 0x1e, 0x0a, 0x09, 0xf9, 0x23, 0x03, 0x88, 0x80, - 0xa8, 0xfb, 0xb9, 0x78, 0xd4, 0x7e, 0x76, 0x9f, 0xce, 0x7e, 0x7e, 0x56, 0xb6, 0x31, 0x7b, 0x5f, - 0x67, 0x34, 0x8b, 0xfc, 0x4b, 0x03, 0xa6, 0xb8, 0x0b, 0x86, 0xda, 0xd8, 0xd2, 0x51, 0x8d, 0x6d, - 0x3c, 0x9d, 0xc6, 0x5e, 0x0e, 0xb1, 0xda, 0x3e, 0x6d, 0xed, 0x6d, 0x14, 0xf9, 0x22, 0x40, 0xbc, - 0xa3, 0xa4, 0xef, 0xde, 0xe5, 0x0c, 0x29, 0x10, 0x23, 0x25, 0xe1, 0x87, 0x51, 0x4c, 0xa7, 0x7a, - 0xbb, 0x24, 0xdc, 0xc8, 0x6f, 0xc0, 0x39, 0xb6, 0x5f, 0x62, 0x88, 0xf0, 0x00, 0x9b, 0x19, 0xc5, - 0x5a, 0x5e, 0xef, 0x7f, 0xb4, 0xdf, 0xc8, 0x22, 0xe3, 0x11, 0x14, 0x49, 0x80, 0x77, 0xd4, 0x52, - 0x0d, 0xc4, 0x2c, 0x0a, 0x74, 0xf5, 0xc4, 0xd6, 0x87, 0x33, 0x63, 0x58, 0x67, 0xa6, 0x7c, 0xbb, - 0x28, 0xf7, 0x02, 0x97, 0x6f, 0xa1, 0x1e, 0x02, 0x81, 0x20, 0xf2, 0x01, 0x90, 0x7a, 0x77, 0x7b, - 0x9b, 0x86, 0x11, 0x75, 0x39, 0x8c, 0x06, 0xe1, 0xcc, 0x38, 0xca, 0x07, 0xbc, 0x60, 0x0a, 0x65, - 0xa9, 0x1d, 0xc8, 0x62, 0x75, 0x91, 0xf4, 0x12, 0x5f, 0xda, 0x82, 0x8b, 0x7d, 0xbb, 0x99, 0x11, - 0xde, 0x70, 0x53, 0x0f, 0x6f, 0xb8, 0xd8, 0x4f, 0x1c, 0x86, 0x6a, 0x88, 0xc3, 0x3f, 0x35, 0x52, - 0xf2, 0x4f, 0x28, 0x2b, 0x3c, 0x6d, 0x59, 0xbf, 0x03, 0x22, 0x87, 0xa1, 0xdf, 0x5c, 0x42, 0xe6, - 0x12, 0x25, 0x89, 0x49, 0x48, 0x55, 0xc2, 0xa2, 0xac, 0x7c, 0x42, 0x51, 0x68, 0xfe, 0x5b, 0x03, - 0x08, 0x6f, 0xe1, 0x9c, 0xd3, 0x71, 0xb6, 0xbc, 0xa6, 0x17, 0x79, 0x34, 0x24, 0xf7, 0xa1, 0x2c, - 0x58, 0x30, 0xb3, 0x5d, 0x75, 0x74, 0x12, 0x4f, 0xaf, 0x71, 0x99, 0x9d, 0x56, 0x6b, 0x7a, 0x08, - 0xfb, 0x4c, 0x5e, 0xee, 0x09, 0x26, 0xcf, 0xfc, 0x2b, 0x03, 0x2e, 0xf6, 0x36, 0x5b, 0xd4, 0x1c, - 0x0f, 0x9e, 0x71, 0xcc, 0xe0, 0x65, 0xf5, 0x32, 0x87, 0x17, 0x19, 0x4f, 0xad, 0x97, 0xf9, 0xe4, - 0x0e, 0xf4, 0xe4, 0xbd, 0xfc, 0xad, 0x1c, 0x8c, 0xad, 0x36, 0xbb, 0xdb, 0x5e, 0x7b, 0xde, 0x89, - 0x9c, 0x53, 0x6b, 0x52, 0xbc, 0xa5, 0x99, 0x14, 0xb1, 0x2f, 0x55, 0xdc, 0xb1, 0xc1, 0x52, 0x48, - 0x19, 0x30, 0x99, 0x90, 0xf0, 0x5d, 0x7a, 0x0f, 0x0a, 0xec, 0x87, 0xd0, 0x50, 0xae, 0xf4, 0x30, - 0x46, 0xac, 0x1b, 0xf1, 0x7f, 0x42, 0xc9, 0xd7, 0x13, 0x77, 0x21, 0x87, 0x4b, 0x9f, 0xe2, 0x79, - 0x77, 0x4e, 0x9e, 0x23, 0xf0, 0x47, 0x06, 0x94, 0xd3, 0x3d, 0x21, 0xf7, 0x61, 0x84, 0x71, 0xf2, - 0xe2, 0x1c, 0x3e, 0x2f, 0xf4, 0xe9, 0xf3, 0x0d, 0x81, 0xc6, 0x9b, 0x87, 0x83, 0x4f, 0x39, 0xc4, - 0x92, 0x1c, 0x2e, 0x59, 0x30, 0xa6, 0x62, 0x65, 0xb4, 0xee, 0x15, 0x5d, 0x34, 0x9d, 0xcf, 0x1e, - 0x07, 0xb5, 0xd5, 0x7f, 0xa0, 0xb5, 0x5a, 0x08, 0xa5, 0x41, 0x93, 0xb1, 0x61, 0xb0, 0x16, 0xcf, - 0x51, 0xa1, 0xae, 0x33, 0x99, 0xce, 0x42, 0x0f, 0xd6, 0xe2, 0x30, 0x66, 0x8b, 0xf0, 0xfa, 0xc4, - 0x3a, 0x43, 0x5b, 0xa4, 0x83, 0x10, 0x55, 0x9f, 0xe5, 0x38, 0xe6, 0x3f, 0xce, 0xc3, 0xf9, 0xa4, - 0x79, 0x3c, 0x35, 0xdd, 0xaa, 0x13, 0x38, 0xad, 0xf0, 0x98, 0x1d, 0x70, 0xb5, 0xa7, 0x69, 0x18, - 0x8c, 0x2c, 0x9b, 0xa6, 0x34, 0xc8, 0x4c, 0x35, 0x08, 0x8d, 0x38, 0xde, 0x20, 0xd9, 0x0c, 0x72, - 0x1f, 0xf2, 0x75, 0x1a, 0x89, 0x90, 0xc5, 0x97, 0x7a, 0x46, 0x55, 0x6d, 0xd7, 0x8d, 0x3a, 0x8d, - 0xf8, 0x24, 0x72, 0xaf, 0x6f, 0xaa, 0x79, 0x61, 0x33, 0x75, 0x7c, 0x13, 0x86, 0x17, 0x1e, 0x77, - 0x68, 0x23, 0x12, 0x91, 0x8a, 0xd7, 0x8e, 0xe6, 0xc7, 0x71, 0x95, 0x78, 0x48, 0x8a, 0x00, 0x75, - 0xb0, 0x38, 0xca, 0xa5, 0x37, 0xa1, 0x28, 0x2b, 0x3f, 0x51, 0x5c, 0xdf, 0x5b, 0x30, 0xaa, 0x54, - 0x72, 0xa2, 0x45, 0xff, 0x0b, 0x03, 0x86, 0x99, 0xd0, 0xdb, 0x78, 0xfd, 0x94, 0x4a, 0xa4, 0xdb, - 0x9a, 0x44, 0x9a, 0x52, 0x02, 0x50, 0x70, 0x5f, 0xbe, 0x7e, 0x8c, 0x2c, 0x3a, 0x30, 0x00, 0x12, - 0x64, 0x72, 0x17, 0x46, 0xf8, 0xb3, 0x8f, 0xcc, 0xfb, 0xa8, 0x46, 0xb4, 0x88, 0x92, 0x44, 0xcb, - 0xf1, 0x3b, 0x69, 0xb5, 0x50, 0x52, 0x93, 0x79, 0x18, 0xaa, 0x0a, 0x27, 0x61, 0x35, 0x84, 0x92, - 0xb1, 0x99, 0xf3, 0xdb, 0x3c, 0xc2, 0x21, 0x54, 0xf2, 0x23, 0xa5, 0xbd, 0x85, 0x91, 0x98, 0xd9, - 0x6d, 0x78, 0xb1, 0x91, 0x3f, 0x8a, 0xc9, 0x79, 0xc1, 0x24, 0xfb, 0xce, 0xe3, 0x47, 0xc0, 0x63, - 0x06, 0x64, 0xc3, 0xde, 0x85, 0xb1, 0x3b, 0x7e, 0xb0, 0xe7, 0x04, 0x6e, 0x75, 0x9b, 0x0a, 0x7f, - 0xed, 0x22, 0x3a, 0x5d, 0x8f, 0x3f, 0xe4, 0x70, 0xdb, 0x61, 0x05, 0x3f, 0x3f, 0xa8, 0x14, 0x6a, - 0xbe, 0xdf, 0xb4, 0x34, 0x74, 0xb2, 0x02, 0xe3, 0x0f, 0x9c, 0xc7, 0xe2, 0x75, 0x6f, 0x6d, 0x6d, - 0x49, 0x78, 0xa5, 0x5c, 0x3b, 0x3c, 0xa8, 0x5c, 0x6c, 0x39, 0x8f, 0xe3, 0x57, 0xc1, 0xfe, 0x7e, - 0xcc, 0x3a, 0x3d, 0xf1, 0x60, 0x62, 0xd5, 0x0f, 0x22, 0x51, 0x09, 0xd3, 0x69, 0xf3, 0x7d, 0x1e, - 0xe7, 0x6e, 0x66, 0x3e, 0xce, 0x5d, 0x64, 0x8a, 0xbc, 0xfd, 0x30, 0x26, 0xd7, 0x02, 0xdd, 0x34, - 0xc6, 0xe4, 0x5d, 0x98, 0x9a, 0xa3, 0x41, 0xe4, 0x3d, 0xf4, 0x1a, 0x4e, 0x44, 0xef, 0xf8, 0x41, - 0xcb, 0x89, 0xc4, 0x85, 0x0a, 0x1a, 0xd4, 0x0d, 0xca, 0x39, 0xb5, 0x9c, 0xc8, 0xea, 0xc5, 0x24, - 0x5f, 0xca, 0xf2, 0xf3, 0x19, 0xc2, 0xee, 0xbf, 0xca, 0x94, 0x82, 0x0c, 0x3f, 0x9f, 0x3e, 0x43, - 0x90, 0xe1, 0xf1, 0xb3, 0x7d, 0xd4, 0x23, 0x69, 0xb1, 0x76, 0x4b, 0x3c, 0xd8, 0x1e, 0xff, 0x08, - 0x1a, 0xcf, 0x5b, 0x9f, 0xc7, 0xd0, 0x59, 0xc8, 0xd7, 0x56, 0xef, 0xe0, 0x15, 0x89, 0x78, 0x94, - 0xa4, 0xed, 0x1d, 0xa7, 0xdd, 0x40, 0x5d, 0x46, 0x78, 0x3a, 0xa8, 0x02, 0xaf, 0xb6, 0x7a, 0x87, - 0x38, 0x70, 0x76, 0x95, 0x06, 0x2d, 0x2f, 0xfa, 0xfc, 0xad, 0x5b, 0xca, 0x44, 0x15, 0xb1, 0x69, - 0x37, 0x45, 0xd3, 0x2a, 0x1d, 0x44, 0xb1, 0x1f, 0xdf, 0xba, 0x95, 0x39, 0x1d, 0x71, 0xc3, 0xb2, - 0x78, 0x91, 0x05, 0x98, 0x78, 0xe0, 0x3c, 0x16, 0xcf, 0xd7, 0xb1, 0x8d, 0x97, 0xc7, 0xd0, 0x37, - 0x5c, 0x58, 0x8d, 0xa4, 0x48, 0x9d, 0x62, 0x9d, 0x88, 0xbc, 0x03, 0xa3, 0xc9, 0xf2, 0x0a, 0xf1, - 0xe1, 0x32, 0xcf, 0x1d, 0x28, 0x95, 0xc5, 0xa9, 0xdd, 0x25, 0x29, 0xe8, 0x64, 0x3d, 0x36, 0xd1, - 0xb9, 0x42, 0x8a, 0x6e, 0x85, 0xa5, 0xda, 0x4d, 0xd5, 0x44, 0x77, 0xb0, 0x44, 0xeb, 0xd6, 0x64, - 0xac, 0xa2, 0x73, 0xbf, 0x1a, 0x4b, 0xe7, 0xa2, 0x58, 0xfe, 0xab, 0x81, 0xdf, 0xea, 0x44, 0xe8, - 0x5f, 0x98, 0xb2, 0xfc, 0x3b, 0x58, 0x92, 0x61, 0xf9, 0x73, 0x92, 0xec, 0x57, 0xf9, 0xf1, 0x27, - 0x78, 0x95, 0xa7, 0x50, 0x58, 0xf2, 0x1b, 0xbb, 0xe8, 0x50, 0x58, 0xaa, 0x7d, 0xc0, 0xe4, 0x47, - 0xd3, 0x6f, 0xec, 0x3e, 0xbd, 0xd7, 0x64, 0x64, 0x4f, 0x96, 0x59, 0xdf, 0xd9, 0xb2, 0x12, 0x55, - 0xcf, 0x4c, 0x6a, 0x2f, 0x6d, 0x5a, 0x19, 0x57, 0x54, 0xf8, 0x2a, 0x94, 0x1d, 0xb1, 0x74, 0x72, - 0x42, 0xa1, 0x3c, 0x4f, 0xc3, 0xdd, 0xc8, 0xef, 0xcc, 0x35, 0xbd, 0xce, 0x96, 0xef, 0x04, 0xee, - 0x4c, 0xb9, 0x8f, 0xc0, 0x78, 0x39, 0x53, 0x60, 0x4c, 0xb9, 0x9c, 0xde, 0x6e, 0x48, 0x06, 0x56, - 0x0f, 0x4b, 0xf3, 0x8b, 0xa9, 0x66, 0x93, 0x45, 0x18, 0x11, 0x48, 0xe2, 0x60, 0xe8, 0xad, 0xee, - 0xd9, 0xcc, 0xea, 0x46, 0x44, 0x75, 0x96, 0xa4, 0x37, 0xff, 0x74, 0x14, 0x26, 0x74, 0x11, 0xce, - 0x74, 0xaa, 0x25, 0x7f, 0xdb, 0x6b, 0x4b, 0xcb, 0x8c, 0xa7, 0x4d, 0x40, 0x88, 0x96, 0x7e, 0x1b, - 0x21, 0xe4, 0x45, 0x80, 0xf8, 0xf1, 0x51, 0x1a, 0x5f, 0x22, 0x59, 0xb8, 0x52, 0x40, 0x7e, 0x05, - 0x60, 0xd9, 0x77, 0x69, 0x9c, 0x79, 0xe3, 0x88, 0x2b, 0x93, 0x97, 0xc5, 0x95, 0x89, 0x48, 0xf0, - 0x7d, 0x78, 0x50, 0x99, 0x6e, 0xfb, 0x2e, 0xed, 0x4d, 0xb9, 0xa1, 0x70, 0x24, 0x9f, 0x81, 0x21, - 0xab, 0xdb, 0xa4, 0x32, 0x11, 0xc4, 0xa8, 0x9c, 0xd2, 0x6e, 0x53, 0x49, 0xfc, 0x17, 0x74, 0xd3, - 0x37, 0xe5, 0x0c, 0x40, 0xde, 0x07, 0xb8, 0xdf, 0xdd, 0xa2, 0x77, 0x03, 0xbf, 0xdb, 0x91, 0x91, - 0xa6, 0x68, 0xa8, 0xed, 0xc6, 0x69, 0x83, 0xec, 0x6d, 0x2c, 0x54, 0x2b, 0x4f, 0x48, 0xc8, 0x0a, - 0x8c, 0x88, 0x0d, 0x22, 0x6e, 0xa2, 0x9f, 0xcb, 0xba, 0x03, 0x51, 0x4e, 0x49, 0x91, 0x99, 0x01, - 0xc1, 0xfa, 0xb5, 0x04, 0x37, 0x34, 0xdf, 0x81, 0x12, 0x63, 0xcf, 0x8c, 0xc9, 0x50, 0x48, 0x47, - 0xf4, 0xa7, 0x53, 0x1a, 0xc4, 0x0c, 0x4f, 0x2d, 0x3f, 0x54, 0x4c, 0x40, 0xbe, 0x84, 0xb9, 0x54, - 0xc4, 0x50, 0x1f, 0x79, 0x95, 0xf6, 0x52, 0xcf, 0x50, 0x9f, 0x73, 0x3a, 0x9d, 0x8c, 0xe4, 0x53, - 0x31, 0x3f, 0xb2, 0x1d, 0xc7, 0x9c, 0xc4, 0xd9, 0x5f, 0x8f, 0xa8, 0xe0, 0x7a, 0x4f, 0x05, 0x33, - 0x32, 0x8c, 0xa2, 0x37, 0x83, 0x8a, 0xc6, 0x97, 0x74, 0xa0, 0x9c, 0xa4, 0x6d, 0x12, 0x75, 0xc1, - 0x51, 0x75, 0xbd, 0xda, 0x53, 0x97, 0x3a, 0x81, 0x3d, 0xd5, 0xf5, 0x70, 0x27, 0x6e, 0x92, 0xa9, - 0x53, 0xd4, 0x37, 0x7a, 0x54, 0x7d, 0x2f, 0xf6, 0xd4, 0x77, 0xd6, 0xdd, 0xea, 0xad, 0x27, 0xc5, - 0x93, 0xbc, 0x03, 0xe3, 0x12, 0x82, 0xfb, 0x03, 0xaf, 0xb0, 0x84, 0x06, 0xeb, 0x6e, 0xa1, 0x13, - 0x95, 0x9e, 0x3e, 0x44, 0x45, 0x56, 0xa9, 0xf9, 0xea, 0x18, 0xd7, 0xa8, 0xd3, 0xab, 0x42, 0x47, - 0x26, 0x5f, 0x80, 0xd1, 0xc5, 0x16, 0xeb, 0x88, 0xdf, 0x76, 0x22, 0x8a, 0xe2, 0x36, 0xb9, 0x16, - 0x54, 0x4a, 0x94, 0xa5, 0xca, 0xf3, 0xf4, 0x25, 0x45, 0xea, 0x71, 0xa5, 0x50, 0xb0, 0xc1, 0xe3, - 0x17, 0x0c, 0x62, 0x0d, 0x87, 0x42, 0xb8, 0x3e, 0x9b, 0x71, 0x35, 0xa7, 0xb0, 0xc7, 0x23, 0x95, - 0xdf, 0x5b, 0xd8, 0x62, 0x43, 0x68, 0x83, 0xa7, 0xf3, 0x24, 0xef, 0xc2, 0xa8, 0x88, 0xa0, 0xab, - 0x5a, 0xcb, 0xe1, 0x4c, 0x19, 0x3b, 0x8f, 0xb9, 0xbf, 0x64, 0xb0, 0x9d, 0xed, 0x04, 0xa9, 0xf7, - 0x99, 0x04, 0x9f, 0x7c, 0x1e, 0xce, 0x6d, 0x7a, 0x6d, 0xd7, 0xdf, 0x0b, 0x85, 0xfc, 0x13, 0x82, - 0x6e, 0x2a, 0xf1, 0x59, 0xd9, 0xe3, 0xe5, 0xb6, 0x14, 0xcc, 0x3d, 0x82, 0x2f, 0x93, 0x03, 0xf9, - 0xf5, 0x1e, 0xce, 0x7c, 0x05, 0x91, 0xa3, 0x56, 0xd0, 0x6c, 0xcf, 0x0a, 0xea, 0xad, 0x3e, 0xbd, - 0x9c, 0x32, 0xab, 0x31, 0xff, 0x3a, 0x0f, 0x17, 0xfa, 0x08, 0x9b, 0xe4, 0xcd, 0xd0, 0x38, 0xf6, - 0xcd, 0xf0, 0xcb, 0x6c, 0x73, 0x3b, 0x5e, 0x2b, 0x5c, 0xf3, 0x93, 0x97, 0x92, 0xe4, 0x7a, 0x15, - 0xcb, 0x64, 0x28, 0xbd, 0x0c, 0xfb, 0xbe, 0xd8, 0x40, 0x0a, 0x3b, 0xf2, 0x7b, 0x2e, 0xb3, 0x74, - 0x66, 0x3d, 0xaf, 0x76, 0xf9, 0x5f, 0x92, 0x57, 0x3b, 0xfd, 0xae, 0xbc, 0xf0, 0x54, 0xef, 0xca, - 0xb3, 0x6f, 0xef, 0x86, 0x9e, 0xe4, 0x8e, 0xf2, 0x3f, 0xa7, 0xde, 0x09, 0x7f, 0x19, 0xa7, 0xfa, - 0x1a, 0x0c, 0x6d, 0xee, 0xd0, 0x40, 0x3a, 0x8a, 0x62, 0x43, 0xf6, 0x18, 0x40, 0x6d, 0x08, 0x62, - 0x98, 0x5f, 0x87, 0x31, 0xb5, 0x32, 0x52, 0x81, 0x21, 0xfc, 0x2d, 0x4c, 0x7f, 0x7c, 0xa5, 0xc3, - 0x7a, 0x2d, 0x0e, 0x3f, 0x36, 0x71, 0x4e, 0x32, 0x0a, 0xf9, 0xe3, 0x46, 0xc1, 0xfc, 0x53, 0x03, - 0x0a, 0x18, 0x37, 0xfc, 0x06, 0x94, 0xe4, 0x1d, 0x8e, 0x1a, 0x7a, 0x7b, 0x56, 0x5e, 0xf1, 0x84, - 0xfa, 0x43, 0xab, 0x00, 0xb2, 0xaa, 0x36, 0x68, 0xb0, 0xa5, 0xbd, 0xc7, 0x3f, 0x62, 0x00, 0xb5, - 0x2a, 0xc4, 0x38, 0xc1, 0x90, 0xa0, 0xcf, 0x81, 0x30, 0x3c, 0x0a, 0xc8, 0x97, 0xfb, 0x1c, 0xf4, - 0x18, 0x1c, 0x12, 0xcb, 0xfc, 0xbe, 0x01, 0xd3, 0x99, 0xe2, 0x9b, 0xd5, 0xca, 0xcf, 0x09, 0x65, - 0x45, 0xa4, 0x0f, 0x09, 0x8e, 0x71, 0x12, 0xdf, 0x82, 0x13, 0x4c, 0xef, 0x27, 0xa0, 0x14, 0x6b, - 0xa5, 0xe4, 0x9c, 0x9c, 0x3a, 0x34, 0xf4, 0x65, 0xa2, 0xa3, 0x5f, 0x18, 0x30, 0xcc, 0x9a, 0x70, - 0x6a, 0x9d, 0xc4, 0xb3, 0xaf, 0x7d, 0x58, 0x97, 0x06, 0x72, 0x0d, 0xff, 0xc1, 0x30, 0x40, 0x82, - 0x4c, 0xb6, 0x60, 0x62, 0x65, 0x71, 0x7e, 0x6e, 0xd1, 0xa5, 0xed, 0x08, 0x9f, 0x1f, 0x52, 0xc1, - 0xc2, 0x0b, 0x8f, 0x23, 0x1a, 0xb4, 0x9d, 0xa6, 0x40, 0xd8, 0x4f, 0xb6, 0xa7, 0xef, 0xb9, 0x0d, - 0xdb, 0x8b, 0xe9, 0xd4, 0x73, 0x54, 0xe7, 0xc8, 0xea, 0xa8, 0x57, 0x1f, 0x2c, 0x29, 0x75, 0xe4, - 0x06, 0xac, 0x23, 0x74, 0x5a, 0xcd, 0x3e, 0x75, 0xe8, 0x1c, 0xc9, 0x0e, 0x94, 0xef, 0xa2, 0xec, - 0x56, 0x6a, 0xc9, 0x1f, 0x5d, 0xcb, 0xf3, 0xa2, 0x96, 0x67, 0xb8, 0xd0, 0xcf, 0xae, 0xa7, 0x87, - 0x6b, 0xb2, 0x72, 0x0b, 0xc7, 0xae, 0xdc, 0x7f, 0x60, 0xc0, 0x30, 0x3f, 0x1c, 0xe2, 0xac, 0xf0, - 0x99, 0xc7, 0xcf, 0xe6, 0xd3, 0x39, 0x7e, 0xca, 0x11, 0xfe, 0xa7, 0xda, 0x4d, 0xbc, 0x8c, 0xcc, - 0xa7, 0x52, 0xcc, 0xcb, 0xbb, 0x3d, 0xd4, 0x27, 0x78, 0x49, 0xe2, 0xa1, 0xc1, 0xb3, 0xcb, 0xab, - 0x5c, 0x38, 0x86, 0xfa, 0x81, 0xab, 0x91, 0x27, 0xfc, 0xc0, 0xd5, 0x12, 0x94, 0x84, 0xcb, 0x41, - 0x6d, 0x5f, 0x58, 0x0d, 0xd2, 0xac, 0x8c, 0xe1, 0x4a, 0x8e, 0x5a, 0x0e, 0xb2, 0xb7, 0xb4, 0x0c, - 0x53, 0x31, 0x22, 0x59, 0x81, 0x52, 0xe2, 0xe1, 0x5e, 0xd2, 0x1e, 0x68, 0x62, 0xb8, 0xf0, 0xc9, - 0xe3, 0x41, 0x54, 0x99, 0x0e, 0xed, 0x09, 0x0f, 0xf3, 0x5b, 0x06, 0x94, 0xd3, 0xeb, 0x85, 0xbc, - 0x03, 0xa3, 0x71, 0x90, 0x41, 0xfc, 0xf0, 0x89, 0x37, 0x2c, 0x49, 0x54, 0x82, 0xf6, 0x04, 0xaa, - 0xa2, 0x93, 0x59, 0x28, 0xb2, 0x6d, 0xa7, 0xa4, 0x18, 0x45, 0x79, 0xd2, 0x15, 0x30, 0xf5, 0xc1, - 0x41, 0xe2, 0x29, 0xbb, 0xf6, 0xbf, 0xe4, 0x61, 0x54, 0x99, 0x2c, 0x72, 0x0d, 0x8a, 0x8b, 0xe1, - 0x92, 0xdf, 0xd8, 0xa5, 0xae, 0xb8, 0xc7, 0xc4, 0xef, 0x97, 0x79, 0xa1, 0xdd, 0x44, 0xa0, 0x15, - 0x17, 0x93, 0x1a, 0x8c, 0xf3, 0xff, 0x64, 0x30, 0x59, 0x2e, 0xb9, 0x83, 0xe1, 0xc8, 0x32, 0x8c, - 0x4c, 0x3d, 0x61, 0x35, 0x12, 0xf2, 0x15, 0x00, 0x0e, 0x60, 0xf3, 0x3b, 0x80, 0xc7, 0xa1, 0xdc, - 0xc0, 0xd3, 0xa2, 0x82, 0xc8, 0x53, 0x7b, 0x88, 0x4b, 0x41, 0x61, 0x88, 0xdf, 0x52, 0xf2, 0x1b, - 0xbb, 0x83, 0x7f, 0x3d, 0x2d, 0xf9, 0x96, 0x92, 0xdf, 0xd8, 0xb5, 0xb3, 0xdd, 0x4f, 0x54, 0x96, - 0xe4, 0xdb, 0x06, 0x5c, 0xb2, 0x68, 0xc3, 0x7f, 0x44, 0x83, 0xfd, 0x6a, 0x84, 0x58, 0x6a, 0x8d, - 0xc7, 0xfb, 0xba, 0xdc, 0x16, 0x35, 0xbe, 0x1c, 0x08, 0x2e, 0xe8, 0x55, 0xdf, 0xea, 0x44, 0xf6, - 0x11, 0x4d, 0x38, 0xa2, 0x4a, 0xf3, 0x2f, 0x0c, 0x65, 0x0b, 0x90, 0x65, 0x28, 0xc5, 0x8b, 0x45, - 0x5c, 0xb3, 0xc4, 0xca, 0x91, 0x84, 0x5b, 0xf4, 0x61, 0xed, 0x19, 0x71, 0xe5, 0x78, 0x36, 0x5e, - 0x72, 0xda, 0x8e, 0x90, 0x40, 0xf2, 0x59, 0x28, 0xe0, 0x54, 0x1d, 0x9f, 0x93, 0x46, 0x1e, 0x35, - 0x05, 0x36, 0x47, 0xd8, 0x6a, 0xa4, 0x24, 0xaf, 0x89, 0xe7, 0xe7, 0xbc, 0x96, 0xed, 0x91, 0x81, - 0x58, 0x3b, 0xe2, 0x33, 0x26, 0xf1, 0x78, 0x52, 0x56, 0xeb, 0xdf, 0x33, 0xe0, 0xec, 0xfa, 0xec, - 0x1d, 0x8b, 0x6e, 0x7b, 0x18, 0x8c, 0xe7, 0xf9, 0xf8, 0x36, 0x44, 0x2e, 0x42, 0xde, 0x72, 0xf6, - 0x44, 0xee, 0x38, 0x74, 0x77, 0x0e, 0x9c, 0x3d, 0x8b, 0xc1, 0xc8, 0x2b, 0x50, 0xba, 0x4f, 0xf7, - 0xef, 0x39, 0x6d, 0xb7, 0x49, 0x45, 0x8e, 0x38, 0xcc, 0x83, 0xb0, 0x4b, 0xf7, 0xed, 0x1d, 0x84, - 0x5a, 0x09, 0x02, 0x3e, 0x7c, 0x75, 0xb7, 0xee, 0x53, 0xfe, 0x3e, 0x30, 0x26, 0x1e, 0xbe, 0xba, - 0x5b, 0xe8, 0x51, 0xcb, 0x4b, 0xcc, 0x3f, 0xca, 0x43, 0x39, 0xbd, 0xfb, 0xc9, 0xfb, 0x30, 0xb6, - 0xea, 0x84, 0xe1, 0x9e, 0x1f, 0xb8, 0xf7, 0x9c, 0x70, 0x47, 0x34, 0x05, 0x6d, 0xba, 0x8e, 0x80, - 0xdb, 0x3b, 0x8e, 0x96, 0xee, 0x48, 0x23, 0x60, 0x5a, 0xc1, 0x9a, 0xf0, 0xe6, 0x55, 0x76, 0x71, - 0xe4, 0x47, 0x9d, 0x54, 0x1a, 0x3b, 0x89, 0x46, 0x5c, 0x98, 0x4c, 0x8d, 0x45, 0xbc, 0x81, 0xe2, - 0xb0, 0xa4, 0xf4, 0x48, 0xf1, 0x0b, 0x98, 0xee, 0xec, 0x43, 0x4c, 0x05, 0x23, 0x4b, 0xd4, 0x88, - 0x99, 0x14, 0x11, 0x79, 0x0b, 0x60, 0x7d, 0xf6, 0x0e, 0xc6, 0xaa, 0xd2, 0x40, 0xb8, 0x83, 0xa2, - 0x35, 0xcd, 0x98, 0x34, 0x38, 0x58, 0xb5, 0x1a, 0x12, 0x64, 0xf2, 0x06, 0xe4, 0x79, 0xa0, 0x93, - 0x9a, 0xd3, 0xe5, 0xc1, 0x9d, 0x2a, 0x8f, 0x0d, 0xe1, 0x6f, 0x81, 0xfa, 0xa5, 0x2a, 0xc3, 0x27, - 0x4b, 0x4a, 0x98, 0xcc, 0xb0, 0x96, 0x4c, 0x43, 0x82, 0xe3, 0xd1, 0x1f, 0x20, 0x5e, 0xe6, 0x5f, - 0xe5, 0xa1, 0x14, 0xd7, 0x49, 0x08, 0xa0, 0x26, 0x26, 0x1e, 0xf2, 0xf0, 0x7f, 0x72, 0x11, 0x8a, - 0x52, 0xf9, 0x12, 0x8f, 0x79, 0x23, 0xa1, 0x50, 0xbc, 0x66, 0x40, 0x6a, 0x59, 0x5c, 0xf1, 0xb2, - 0xe4, 0x4f, 0x72, 0x0b, 0x62, 0x15, 0xaa, 0x9f, 0xae, 0x55, 0x60, 0x4b, 0xd9, 0x8a, 0xd1, 0xc8, - 0x04, 0xe4, 0x3c, 0xee, 0x3e, 0x5a, 0xb2, 0x72, 0x9e, 0x4b, 0xde, 0x87, 0xa2, 0xe3, 0xba, 0xd4, - 0xb5, 0x9d, 0x68, 0x80, 0x6f, 0xfe, 0x15, 0x19, 0x37, 0x7e, 0xd6, 0x21, 0x55, 0x35, 0x22, 0x55, - 0x28, 0xe1, 0x27, 0xdf, 0xba, 0xe1, 0x40, 0xdf, 0x89, 0x4b, 0x38, 0x14, 0x19, 0xd9, 0x7a, 0x48, - 0x5d, 0xf2, 0x32, 0x14, 0xd8, 0x12, 0x13, 0x27, 0x65, 0x9c, 0x6e, 0x6b, 0x65, 0x6d, 0x95, 0x0f, - 0xd8, 0xbd, 0x33, 0x16, 0x22, 0x90, 0x17, 0x20, 0xdf, 0x9d, 0x7d, 0x28, 0xce, 0xc0, 0x72, 0xb2, - 0xc0, 0x62, 0x34, 0x56, 0x4c, 0x6e, 0x43, 0x71, 0x4f, 0x8f, 0x70, 0x9a, 0x4e, 0x4d, 0x5d, 0x8c, - 0x1f, 0x23, 0xd6, 0x8a, 0x30, 0xcc, 0xe3, 0x89, 0xcc, 0xe7, 0x00, 0x92, 0xaa, 0x7b, 0xdf, 0x5c, - 0xcd, 0xaf, 0x40, 0x29, 0xae, 0x92, 0x3c, 0x0b, 0xca, 0x1e, 0xe6, 0xfb, 0xcd, 0x2a, 0xed, 0xc6, - 0x3b, 0xf9, 0x02, 0x8c, 0x74, 0xd8, 0xac, 0xca, 0xcc, 0x90, 0x16, 0xdb, 0xc6, 0x6c, 0xdb, 0xcc, - 0xc0, 0x88, 0x58, 0xb6, 0xdc, 0x15, 0xda, 0x92, 0x3f, 0xcd, 0x3f, 0x37, 0x30, 0xa6, 0x59, 0x69, - 0x27, 0x79, 0x1e, 0xc6, 0x1b, 0x01, 0xc5, 0x83, 0xda, 0x61, 0x0a, 0xa3, 0xa8, 0x67, 0x2c, 0x01, - 0x2e, 0xba, 0xe4, 0x25, 0x98, 0x4c, 0x52, 0x55, 0xda, 0x8d, 0x2d, 0x11, 0xdf, 0x38, 0x66, 0x8d, - 0x77, 0x64, 0xae, 0xca, 0xb9, 0x2d, 0x74, 0x7b, 0x2e, 0xab, 0xb1, 0x44, 0x91, 0x4c, 0x3b, 0x59, - 0xb2, 0x26, 0x15, 0x38, 0x06, 0x4c, 0x9e, 0x87, 0x61, 0xc7, 0xd9, 0xee, 0x7a, 0xdc, 0x05, 0x73, - 0xcc, 0x12, 0xbf, 0xc8, 0x27, 0x61, 0x2a, 0xf4, 0xb6, 0xdb, 0x4e, 0xd4, 0x0d, 0xa8, 0xdc, 0x7d, - 0xb8, 0xa4, 0xc6, 0xad, 0x72, 0x5c, 0x20, 0xf6, 0x9f, 0x59, 0x83, 0xa9, 0x9e, 0x1d, 0x43, 0x5e, - 0xe5, 0x56, 0x8a, 0xd0, 0x33, 0xc6, 0xb8, 0x51, 0xc6, 0x84, 0x6d, 0xea, 0x1b, 0x9e, 0x1c, 0xc9, - 0x6c, 0xc3, 0x98, 0x7a, 0x4e, 0x1c, 0x13, 0xe7, 0x79, 0x1e, 0x3d, 0xb7, 0xb8, 0xfc, 0x1a, 0x3e, - 0x3c, 0xa8, 0xe4, 0x3c, 0x17, 0xfd, 0xb5, 0xae, 0x42, 0x51, 0x6a, 0x3b, 0xea, 0x57, 0x07, 0x84, - 0x62, 0xbc, 0x6f, 0xc5, 0xa5, 0xe6, 0xcb, 0x30, 0x22, 0x8e, 0x82, 0xa3, 0x13, 0xcf, 0x9a, 0xdf, - 0xc8, 0xc1, 0xa4, 0x45, 0xd9, 0x76, 0x14, 0xf9, 0xfc, 0x3f, 0x66, 0x29, 0x36, 0xb5, 0xbe, 0x1d, - 0x11, 0x56, 0xfd, 0x43, 0x03, 0xce, 0x66, 0xe0, 0x7e, 0xa8, 0x9c, 0x41, 0x6f, 0x42, 0x69, 0xde, - 0x73, 0x9a, 0x55, 0xd7, 0x8d, 0x3d, 0xd0, 0x50, 0xab, 0x75, 0xd9, 0xe2, 0x77, 0x18, 0x54, 0x55, - 0x0a, 0x62, 0x54, 0x72, 0x5d, 0x2c, 0x8a, 0x24, 0x6b, 0x98, 0x4c, 0xe2, 0x09, 0xbc, 0x4d, 0x49, - 0x0a, 0x4f, 0x8c, 0xf3, 0xe1, 0xc0, 0xe4, 0x91, 0xf1, 0xd4, 0x4e, 0x5d, 0x76, 0x9c, 0x4f, 0xba, - 0x7b, 0x03, 0x99, 0xcf, 0xdf, 0xca, 0xc1, 0xf9, 0x6c, 0xc2, 0x0f, 0x9b, 0xfe, 0x09, 0x63, 0xda, - 0x95, 0x3c, 0xa9, 0xa8, 0xf6, 0xf0, 0x00, 0x78, 0xc4, 0x4f, 0x10, 0xc8, 0x43, 0x18, 0x5f, 0x72, - 0xc2, 0xe8, 0x1e, 0x75, 0x82, 0x68, 0x8b, 0x3a, 0xd1, 0x00, 0x9a, 0x78, 0xfc, 0xe5, 0x4c, 0x3c, - 0x82, 0x76, 0x24, 0x65, 0xfa, 0xcb, 0x99, 0x1a, 0xdb, 0x78, 0xa1, 0x14, 0x06, 0x58, 0x28, 0x5f, - 0x83, 0xc9, 0x3a, 0x6d, 0x39, 0x9d, 0x1d, 0x3f, 0xa0, 0xc2, 0x07, 0xeb, 0x06, 0x8c, 0xc7, 0xa0, - 0xcc, 0xd5, 0xa2, 0x17, 0x6b, 0xf8, 0xca, 0x40, 0x24, 0xa2, 0x44, 0x2f, 0x36, 0x7f, 0x3f, 0x07, - 0x17, 0xaa, 0x0d, 0xf1, 0xac, 0x2b, 0x0a, 0xe4, 0x63, 0xd6, 0x47, 0x5c, 0x37, 0xb9, 0x09, 0xa5, - 0x07, 0xce, 0x63, 0xfc, 0xe4, 0x73, 0x28, 0x92, 0x88, 0x70, 0x05, 0xc9, 0x79, 0x6c, 0xc7, 0xd7, - 0x77, 0x56, 0x82, 0xf3, 0x34, 0xbf, 0x0a, 0x6d, 0xc2, 0xf0, 0x3d, 0xbf, 0xe9, 0x8a, 0xa3, 0x44, - 0xb8, 0x7b, 0xed, 0x20, 0xc4, 0x12, 0x25, 0xe6, 0x5f, 0x19, 0x30, 0x11, 0xb7, 0x18, 0x9b, 0xf0, - 0x91, 0x0f, 0x49, 0xea, 0xfb, 0xd8, 0xa5, 0x01, 0xbe, 0x8f, 0x3d, 0xf4, 0x64, 0x23, 0x61, 0xfe, - 0x6b, 0x03, 0xa6, 0xf4, 0x5e, 0xb2, 0x93, 0x48, 0x69, 0x88, 0x31, 0x60, 0x43, 0x72, 0x4f, 0x6d, - 0x4a, 0xf2, 0x7d, 0xa7, 0xe4, 0x9b, 0x39, 0x18, 0x8d, 0x1b, 0xfb, 0x31, 0x0b, 0x90, 0x8d, 0xfb, - 0x35, 0x90, 0xfb, 0x6b, 0x5d, 0x91, 0x15, 0xc2, 0xcb, 0xf4, 0xb3, 0x30, 0x2c, 0x36, 0x93, 0x1e, - 0xa1, 0xd3, 0x33, 0xbb, 0xc9, 0xd7, 0x0f, 0x71, 0x42, 0x43, 0x4b, 0xd0, 0xa1, 0x7f, 0xf1, 0x26, - 0xdd, 0x12, 0xee, 0x0a, 0xa7, 0xf6, 0x8c, 0xca, 0xf6, 0x2f, 0x4e, 0x3a, 0x36, 0xd0, 0xe9, 0xf4, - 0xcf, 0x0a, 0x50, 0x4e, 0x93, 0x1c, 0x1f, 0x82, 0xbc, 0xda, 0xdd, 0x12, 0x26, 0x37, 0xda, 0xe4, - 0x9d, 0xee, 0x96, 0xc5, 0x60, 0xe4, 0x25, 0x28, 0xac, 0x06, 0xde, 0x23, 0x61, 0x63, 0xa3, 0x8b, - 0x4a, 0x27, 0xf0, 0x1e, 0xa9, 0x8e, 0x76, 0xac, 0x1c, 0x6d, 0xe2, 0xa5, 0xba, 0xf2, 0xe1, 0x59, - 0x6e, 0x13, 0x37, 0xc3, 0x74, 0x96, 0x0a, 0x89, 0xc6, 0x8e, 0xca, 0x1a, 0x75, 0x02, 0x11, 0x2e, - 0x2b, 0xc4, 0x19, 0x1e, 0x95, 0x5b, 0x08, 0xe6, 0x29, 0x28, 0x2d, 0x15, 0x89, 0x34, 0x81, 0x28, - 0x3f, 0x07, 0xff, 0x0a, 0xbb, 0xfc, 0x9a, 0xca, 0x39, 0x95, 0xb5, 0xad, 0xee, 0xe6, 0x0c, 0xbe, - 0x4f, 0xf3, 0xae, 0x73, 0x15, 0x4a, 0x78, 0x75, 0x87, 0x17, 0x32, 0xc5, 0x63, 0x99, 0x49, 0xa7, - 0x46, 0xc0, 0xc7, 0x60, 0x3b, 0xbe, 0x96, 0x49, 0x98, 0x90, 0xf7, 0x60, 0x54, 0xf5, 0xc4, 0xe3, - 0xfe, 0x62, 0x97, 0x79, 0x08, 0x46, 0x9f, 0x6c, 0x4e, 0x2a, 0x81, 0xf9, 0x9a, 0xba, 0x4a, 0xc4, - 0xa1, 0x7d, 0xe4, 0x2a, 0x31, 0xbf, 0x87, 0x6a, 0x7c, 0xcb, 0x8f, 0xa8, 0xd0, 0x5e, 0x4e, 0xad, - 0x1c, 0x4b, 0xae, 0xc2, 0x87, 0x34, 0x87, 0x04, 0xad, 0x77, 0x27, 0xf8, 0xe4, 0xea, 0x3f, 0x37, - 0x60, 0x3a, 0x93, 0x96, 0xdc, 0x00, 0x48, 0x74, 0x44, 0x31, 0x4a, 0x3c, 0xb7, 0x67, 0x0c, 0xb5, - 0x14, 0x0c, 0xf2, 0xe5, 0xb4, 0x76, 0x77, 0xfc, 0xe1, 0x24, 0x33, 0xcc, 0x4f, 0xe8, 0xda, 0x5d, - 0x86, 0x4e, 0x67, 0xfe, 0x30, 0x0f, 0x53, 0x3d, 0x5f, 0x26, 0x3b, 0xe6, 0xab, 0x21, 0xbb, 0xa9, - 0xef, 0xde, 0xf0, 0x67, 0x9b, 0xeb, 0xfd, 0xbe, 0x8b, 0x96, 0xf1, 0x15, 0x1c, 0xbc, 0x59, 0x13, - 0x69, 0x65, 0x8f, 0xf9, 0x18, 0x4e, 0x98, 0xfd, 0xc5, 0xa4, 0x4f, 0xf6, 0xad, 0xed, 0x29, 0x7c, - 0x39, 0xe9, 0x97, 0xf8, 0xc3, 0x32, 0xdf, 0xcb, 0xc1, 0xd9, 0x9e, 0x3e, 0x9f, 0xda, 0x5d, 0xf7, - 0x59, 0xed, 0x74, 0x7b, 0xae, 0xdf, 0x9c, 0x0e, 0xa4, 0x45, 0xfc, 0x6f, 0x03, 0x2e, 0xf4, 0xa1, - 0x24, 0xfb, 0xe9, 0x45, 0xc4, 0xb5, 0x8a, 0x5b, 0x47, 0x57, 0xf8, 0x54, 0x96, 0xd2, 0x47, 0xb6, - 0x12, 0xbe, 0x91, 0x03, 0xd8, 0xa4, 0x5b, 0xa7, 0x3b, 0xbf, 0x4a, 0xf6, 0xd7, 0xb1, 0x65, 0xb7, - 0x06, 0x9a, 0xf7, 0x15, 0xbc, 0xf6, 0x1b, 0x3c, 0xb9, 0x4a, 0x9c, 0x45, 0x3f, 0x97, 0x9d, 0x45, - 0xdf, 0xdc, 0x82, 0x73, 0x77, 0x69, 0x94, 0x9c, 0x84, 0xd2, 0x86, 0x3c, 0x9a, 0xed, 0x2b, 0x50, - 0x12, 0xf8, 0x7a, 0xc6, 0x66, 0xe9, 0x7f, 0xec, 0xb9, 0x56, 0x82, 0x60, 0x52, 0xb8, 0x30, 0x4f, - 0x9b, 0x34, 0xa2, 0x1f, 0x6d, 0x35, 0x75, 0x20, 0xbc, 0x2b, 0x3c, 0x17, 0xfb, 0x40, 0x35, 0x1c, - 0x3b, 0x3e, 0x1b, 0x30, 0x1d, 0xb7, 0xfd, 0x69, 0xf2, 0xbd, 0xc9, 0x74, 0x09, 0x11, 0xcc, 0x94, - 0x70, 0x3c, 0xe2, 0x12, 0xf1, 0x31, 0x5c, 0x92, 0x04, 0x9b, 0x5e, 0xfc, 0x98, 0x33, 0x10, 0x2d, - 0x79, 0x07, 0x46, 0x15, 0x1a, 0x11, 0x19, 0x89, 0xaf, 0xb6, 0x7b, 0x5e, 0xb4, 0x63, 0x87, 0x1c, - 0xae, 0xbe, 0xda, 0x2a, 0xe8, 0xe6, 0x97, 0xe0, 0x99, 0xd8, 0xff, 0x26, 0xa3, 0xea, 0x14, 0x73, - 0xe3, 0x64, 0xcc, 0x97, 0x93, 0x6e, 0x2d, 0xb6, 0x63, 0xf7, 0x65, 0xc9, 0x9b, 0xa8, 0xdd, 0x12, - 0x9d, 0xb9, 0xac, 0xe4, 0x9d, 0x12, 0x67, 0x51, 0x02, 0x30, 0xdf, 0x56, 0x1a, 0x9b, 0xc1, 0x50, - 0x23, 0x36, 0xd2, 0xc4, 0xdf, 0xc8, 0xc1, 0xe4, 0xca, 0xe2, 0xfc, 0x5c, 0x7c, 0x8d, 0xfc, 0x31, - 0x4b, 0xfe, 0xa2, 0xf5, 0xad, 0xbf, 0xbc, 0x31, 0xd7, 0xe1, 0x6c, 0x6a, 0x18, 0xf0, 0xdb, 0x11, - 0xef, 0x71, 0x3f, 0x99, 0x18, 0x2c, 0x4f, 0x96, 0xf3, 0x59, 0xec, 0x37, 0x6e, 0x5b, 0x29, 0x6c, - 0xf3, 0x87, 0xc3, 0x29, 0xbe, 0x42, 0x84, 0xbd, 0x02, 0xa5, 0xc5, 0x30, 0xec, 0xd2, 0x60, 0xdd, - 0x5a, 0x52, 0x75, 0x44, 0x0f, 0x81, 0x76, 0x37, 0x68, 0x5a, 0x09, 0x02, 0xb9, 0x06, 0x45, 0x11, - 0x40, 0x23, 0x65, 0x02, 0x3e, 0xfb, 0xc7, 0xf1, 0x37, 0x56, 0x5c, 0x4c, 0xde, 0x80, 0x31, 0xfe, - 0x3f, 0x5f, 0x6d, 0x62, 0xc0, 0xf1, 0xae, 0x4a, 0xa0, 0xf3, 0xd5, 0x69, 0x69, 0x68, 0xcc, 0x32, - 0x93, 0x1f, 0xa7, 0x63, 0x2d, 0x2a, 0x24, 0x96, 0x99, 0xfc, 0x8e, 0x1d, 0xb6, 0x49, 0x45, 0x22, - 0xd7, 0x21, 0x5f, 0x9d, 0xb3, 0xd4, 0x24, 0xb5, 0x4e, 0x23, 0xe0, 0x49, 0x9e, 0xf5, 0x2f, 0xee, - 0xcf, 0x59, 0x64, 0x16, 0x8a, 0xf8, 0xfd, 0x01, 0x97, 0x06, 0x22, 0x0d, 0x04, 0xae, 0x9a, 0x8e, - 0x80, 0xa9, 0x6f, 0x83, 0x12, 0x8f, 0xdc, 0x84, 0x91, 0x79, 0x2f, 0xec, 0x34, 0x9d, 0x7d, 0x91, - 0xf5, 0x01, 0x1f, 0x43, 0x5c, 0x0e, 0x52, 0xd7, 0x99, 0xc0, 0x22, 0xd7, 0x60, 0xa8, 0xde, 0xf0, - 0x3b, 0xcc, 0xda, 0x8a, 0x5d, 0x74, 0x42, 0x06, 0xd0, 0x42, 0xc7, 0x19, 0x00, 0x63, 0x3a, 0x79, - 0x68, 0x4a, 0x49, 0x89, 0xe9, 0x4c, 0x87, 0xa4, 0x08, 0x9c, 0x5e, 0x3f, 0x46, 0x78, 0x9a, 0x7e, - 0x8c, 0x5b, 0x70, 0xe1, 0x2e, 0xaa, 0xfa, 0x75, 0x1a, 0x60, 0x5a, 0x3e, 0xfe, 0xad, 0x90, 0x75, - 0x6b, 0x51, 0x84, 0xe3, 0x5c, 0x3d, 0x3c, 0xa8, 0xbc, 0xc0, 0xad, 0x01, 0x3b, 0xe4, 0x38, 0xf2, - 0x33, 0x23, 0xa9, 0x04, 0xee, 0xfd, 0x18, 0x91, 0xcf, 0xc3, 0xb9, 0xac, 0x22, 0x11, 0x98, 0x83, - 0x4e, 0xc9, 0xd9, 0x15, 0xa8, 0x5e, 0xc1, 0x59, 0x1c, 0xc8, 0x12, 0x94, 0x39, 0xbc, 0xea, 0xb6, - 0xbc, 0xf6, 0x42, 0xcb, 0xf1, 0x9a, 0x18, 0xa6, 0x23, 0x62, 0xad, 0x04, 0x57, 0x87, 0x15, 0xda, - 0x94, 0x95, 0x6a, 0x5e, 0x56, 0x29, 0x4a, 0x14, 0x47, 0xf5, 0xea, 0x83, 0xa5, 0x64, 0x4f, 0x7d, - 0xbc, 0xde, 0x8d, 0xb4, 0xbe, 0x1d, 0xf1, 0x6e, 0xb4, 0x0e, 0x67, 0x53, 0xc3, 0x20, 0xc5, 0x91, - 0x06, 0x4e, 0x8b, 0xa3, 0x14, 0x8d, 0x95, 0xc2, 0x36, 0xff, 0xeb, 0x70, 0x8a, 0xaf, 0xb8, 0x2b, - 0x32, 0x61, 0x98, 0x4b, 0x1b, 0x35, 0x2d, 0x14, 0x97, 0x45, 0x96, 0x28, 0x21, 0x17, 0x21, 0x5f, - 0xaf, 0xaf, 0xa8, 0x49, 0xeb, 0xc2, 0xd0, 0xb7, 0x18, 0x8c, 0xcd, 0x10, 0x5e, 0x03, 0xe5, 0x93, - 0x19, 0x6a, 0xd0, 0x20, 0x12, 0x5f, 0x2f, 0x7c, 0x31, 0xd9, 0xc7, 0x85, 0x64, 0xbc, 0xc5, 0x3e, - 0x4e, 0x76, 0xef, 0x1c, 0xcc, 0x54, 0xc3, 0x90, 0x06, 0x11, 0xcf, 0x91, 0x1d, 0x76, 0x5b, 0x34, - 0x10, 0x6b, 0x4d, 0xc8, 0x18, 0xfe, 0xed, 0xe3, 0x46, 0x68, 0xf5, 0x45, 0x24, 0x57, 0xa1, 0x58, - 0xed, 0xba, 0x1e, 0x6d, 0x37, 0xa8, 0x90, 0x33, 0x78, 0x19, 0xec, 0x08, 0x98, 0x15, 0x97, 0x92, - 0x0f, 0x60, 0x5a, 0x10, 0x49, 0x81, 0x23, 0x46, 0x80, 0xcb, 0x1a, 0x6e, 0xc1, 0x8a, 0xbd, 0x20, - 0xc5, 0x94, 0x2d, 0x86, 0x24, 0x9b, 0x92, 0x54, 0xa1, 0xbc, 0x80, 0xef, 0xa4, 0xf2, 0x1b, 0xa6, - 0x7e, 0x20, 0x72, 0xa1, 0xa2, 0xe4, 0xe2, 0x6f, 0xa8, 0xb6, 0x1b, 0x17, 0x5a, 0x3d, 0xe8, 0xe4, - 0x3e, 0x9c, 0x4d, 0xc3, 0x98, 0x3c, 0x2e, 0x25, 0xdf, 0x18, 0xea, 0xe1, 0x82, 0x82, 0x39, 0x8b, - 0x8a, 0x6c, 0xc1, 0x54, 0x35, 0x8a, 0x02, 0x6f, 0xab, 0x1b, 0xd1, 0x94, 0xe8, 0x92, 0x17, 0x8d, - 0x71, 0xb9, 0x14, 0x5f, 0xcf, 0x88, 0xc5, 0x78, 0xd6, 0x89, 0x29, 0x63, 0x11, 0x66, 0xf5, 0xb2, - 0x23, 0x6e, 0xfc, 0x99, 0x32, 0xf1, 0x29, 0x2f, 0x11, 0xcf, 0x22, 0x2f, 0x74, 0xab, 0xe1, 0x7e, - 0xab, 0x45, 0xa3, 0x00, 0xdf, 0xd9, 0xf1, 0x53, 0x5f, 0xa6, 0xf0, 0x65, 0xba, 0xa4, 0x7c, 0x9d, - 0x0f, 0x3f, 0xe7, 0xa6, 0xb9, 0x79, 0x6a, 0x3c, 0xb5, 0xe3, 0x63, 0x6c, 0xc0, 0xe3, 0xa3, 0x09, - 0x53, 0x0b, 0xed, 0x46, 0xb0, 0x8f, 0x71, 0x69, 0xb2, 0x71, 0xe3, 0xc7, 0x34, 0x4e, 0x7e, 0x67, - 0xe0, 0xb2, 0x23, 0x57, 0x58, 0x56, 0xf3, 0x7a, 0x19, 0x9b, 0x7f, 0x07, 0xca, 0xe9, 0xb1, 0x7c, - 0xc2, 0x6f, 0xb3, 0x9e, 0xc4, 0xc5, 0x9c, 0xcd, 0x74, 0xba, 0x2f, 0xe4, 0xa6, 0xf6, 0x01, 0x4e, - 0x23, 0x09, 0xfb, 0x55, 0x3e, 0x95, 0xa9, 0x7d, 0x76, 0x53, 0x6e, 0xe3, 0x5c, 0xd6, 0x36, 0x36, - 0x7f, 0x2b, 0x07, 0x53, 0xdc, 0x2b, 0xf6, 0xf4, 0xeb, 0x8a, 0xef, 0x69, 0xc2, 0x59, 0xde, 0x05, - 0xa6, 0x7a, 0x77, 0x84, 0xb6, 0xf8, 0x15, 0x98, 0xee, 0x19, 0x0a, 0x14, 0xd0, 0xf3, 0xd2, 0x1f, - 0xb9, 0x47, 0x44, 0xcf, 0x64, 0x57, 0xb2, 0x71, 0xdb, 0xea, 0xa1, 0x30, 0xff, 0x45, 0xae, 0x87, - 0xbf, 0xd0, 0x1b, 0x55, 0x4d, 0xd0, 0x38, 0x99, 0x26, 0x98, 0xfb, 0x50, 0x9a, 0x60, 0x7e, 0x10, - 0x4d, 0xf0, 0x03, 0x18, 0x5f, 0xa3, 0x0e, 0xd3, 0x68, 0x44, 0xac, 0x53, 0x41, 0xfb, 0x38, 0x26, - 0x2b, 0x93, 0xf2, 0x25, 0x8e, 0x93, 0x8c, 0x18, 0x01, 0x13, 0x2d, 0x3c, 0xf8, 0xc9, 0xd2, 0x39, - 0xa8, 0x87, 0xc6, 0x50, 0xff, 0x43, 0xc3, 0xfc, 0x56, 0x0e, 0x46, 0x15, 0xf6, 0xe4, 0x75, 0x18, - 0x5b, 0x09, 0xb6, 0x9d, 0xb6, 0xf7, 0x6b, 0x8e, 0x72, 0xfd, 0x8a, 0xcd, 0xf7, 0x15, 0xb8, 0xa5, - 0x61, 0xa1, 0xdb, 0x0c, 0x75, 0x5a, 0xea, 0xc2, 0x67, 0xcd, 0xb3, 0x10, 0xaa, 0xc4, 0xaa, 0xe6, - 0x07, 0x88, 0x55, 0xd5, 0x03, 0x3d, 0x0b, 0x27, 0x0f, 0xf4, 0xd4, 0xe2, 0x32, 0x87, 0x4e, 0x18, - 0x97, 0x69, 0xfe, 0x4e, 0x0e, 0xca, 0xe2, 0x33, 0x92, 0xf2, 0xf2, 0xf0, 0xe3, 0x95, 0x16, 0x5f, - 0xef, 0xdc, 0x11, 0xcf, 0x63, 0x85, 0xef, 0xff, 0x61, 0x05, 0x3f, 0x0a, 0x98, 0x1e, 0x0e, 0xf9, - 0x51, 0x40, 0x1d, 0x9e, 0x8e, 0x80, 0x48, 0x53, 0x59, 0x69, 0x7c, 0xf3, 0x27, 0xb9, 0x34, 0x6f, - 0xa1, 0x4d, 0xbd, 0x08, 0x23, 0xfc, 0x2b, 0x45, 0xd2, 0x49, 0x5b, 0x24, 0xc7, 0x41, 0x90, 0x25, - 0xcb, 0x4e, 0x12, 0x0b, 0x73, 0xdc, 0x97, 0x21, 0xc9, 0x9b, 0x30, 0x86, 0xfe, 0x22, 0x55, 0xd7, - 0x0d, 0x68, 0x18, 0x0a, 0x45, 0x0b, 0xdf, 0xee, 0xf6, 0xe8, 0x96, 0xcd, 0xfd, 0x4a, 0x1c, 0xd7, - 0x0d, 0x2c, 0x0d, 0x8f, 0xcc, 0xc1, 0x39, 0xcd, 0x3d, 0x49, 0xd2, 0x0f, 0x25, 0xa7, 0x45, 0x84, - 0x05, 0x9c, 0x38, 0x13, 0xf9, 0xe9, 0x7d, 0x15, 0xd7, 0xfc, 0x3f, 0x06, 0xdb, 0x6b, 0x8d, 0xdd, - 0x8f, 0x59, 0x94, 0x0e, 0xeb, 0xd2, 0x11, 0xca, 0xfe, 0x9f, 0x1b, 0xdc, 0xcf, 0x5e, 0x2c, 0x9f, - 0xb7, 0x60, 0x98, 0x7f, 0x13, 0x49, 0x78, 0x84, 0xab, 0x5c, 0x78, 0x41, 0xf2, 0x3e, 0xc5, 0xbf, - 0xac, 0x64, 0x09, 0x02, 0x66, 0x32, 0xeb, 0xee, 0xfe, 0xa8, 0x78, 0xf6, 0xfa, 0xf9, 0x4b, 0x2c, - 0x35, 0xf1, 0xe3, 0x60, 0x09, 0x85, 0x8d, 0xe3, 0x13, 0x3f, 0x9a, 0xff, 0x2f, 0xc7, 0xfb, 0x23, - 0x1a, 0x35, 0x68, 0x46, 0xb3, 0x97, 0xa0, 0x80, 0x5f, 0xb7, 0x54, 0xd2, 0xc6, 0xa5, 0xbe, 0x6c, - 0x89, 0xe5, 0x6c, 0xdf, 0xa0, 0xac, 0x55, 0x03, 0xc3, 0x50, 0x1c, 0xab, 0xfb, 0x06, 0x31, 0x30, - 0x5d, 0xaf, 0xef, 0x52, 0x75, 0x3b, 0xb4, 0xf5, 0xcc, 0xca, 0x58, 0x4e, 0xde, 0x54, 0xbc, 0x90, - 0xd5, 0x0b, 0x8d, 0xd6, 0x43, 0xc7, 0xe6, 0xde, 0xaf, 0xaa, 0xb4, 0x4d, 0x1c, 0x96, 0x17, 0x60, - 0x42, 0x0f, 0x95, 0x15, 0x46, 0x07, 0x46, 0x1c, 0xa7, 0xc2, 0x6c, 0x55, 0xf5, 0x56, 0x27, 0x22, - 0x35, 0x18, 0xd7, 0x02, 0x6b, 0xd5, 0x2c, 0x97, 0x3c, 0xfd, 0x86, 0xdd, 0x1b, 0xc8, 0xaf, 0x93, - 0x28, 0x17, 0xe6, 0xaf, 0x41, 0x59, 0xec, 0xcc, 0x38, 0x46, 0x0f, 0x55, 0xbb, 0xc5, 0x79, 0x4b, - 0xdd, 0x4d, 0x0d, 0xcf, 0x0d, 0x2c, 0x84, 0x9a, 0xdf, 0x35, 0xe0, 0xa2, 0xf8, 0xd6, 0x93, 0x45, - 0x43, 0xa6, 0x43, 0x62, 0x60, 0x9f, 0x48, 0x11, 0xf4, 0x8e, 0xcc, 0xec, 0xa3, 0x0b, 0xc8, 0x74, - 0x1d, 0xb5, 0x71, 0xb1, 0x28, 0xf9, 0x87, 0x3f, 0x65, 0x46, 0x9f, 0xb7, 0x44, 0x46, 0x9f, 0xdc, - 0xd1, 0xc4, 0xf1, 0xbe, 0x70, 0x69, 0x5b, 0x66, 0xf2, 0xf9, 0x4e, 0x0e, 0xa6, 0x33, 0x9a, 0x75, - 0x6a, 0x33, 0x37, 0xd5, 0x34, 0xe1, 0x20, 0x53, 0xbe, 0xf5, 0x1d, 0xf8, 0x4c, 0x59, 0xf1, 0x07, - 0x06, 0x5c, 0xd0, 0x57, 0x8f, 0xb0, 0x45, 0x37, 0x6e, 0x93, 0xb7, 0x61, 0xf8, 0x1e, 0x75, 0x5c, - 0x2a, 0x43, 0x49, 0xe2, 0xf4, 0x49, 0xe2, 0x76, 0x98, 0x17, 0x72, 0xb6, 0x3f, 0xe1, 0x5b, 0xf9, - 0x8c, 0x25, 0x48, 0xc8, 0xbc, 0x68, 0x1c, 0x7f, 0x9e, 0x32, 0xe5, 0x4b, 0x4d, 0x56, 0x55, 0x47, - 0x28, 0xc6, 0x5f, 0x87, 0x67, 0x8e, 0x20, 0x61, 0xf3, 0xc6, 0x66, 0x5e, 0x9d, 0x37, 0x3c, 0x57, - 0x10, 0x4a, 0xde, 0x83, 0xc9, 0x35, 0x11, 0xf0, 0x26, 0x67, 0x43, 0xc9, 0x9e, 0x2d, 0x63, 0xe1, - 0x6c, 0x39, 0x2d, 0x69, 0x64, 0x0c, 0xdf, 0xd2, 0x6b, 0x7f, 0xd2, 0x41, 0x79, 0x57, 0x1b, 0x94, - 0x67, 0xb2, 0x07, 0xa5, 0xff, 0x68, 0xf4, 0xa4, 0x02, 0x18, 0x68, 0x18, 0x4c, 0x18, 0x9e, 0xf7, - 0x5b, 0x8e, 0x27, 0x7b, 0x8f, 0x97, 0x31, 0x2e, 0x42, 0x2c, 0x51, 0x62, 0xfe, 0x6e, 0x01, 0x2e, - 0xf2, 0x40, 0x10, 0x1a, 0xac, 0x87, 0x5e, 0x7b, 0x5b, 0x7b, 0xa8, 0x41, 0xf7, 0x34, 0x25, 0x8f, - 0xb3, 0x70, 0x4f, 0x63, 0x10, 0x4b, 0x94, 0x30, 0x4b, 0x82, 0x89, 0x3e, 0xc5, 0xd3, 0x0f, 0x2d, - 0x09, 0xcc, 0x82, 0x82, 0x56, 0x6a, 0x5c, 0x4c, 0xae, 0x0b, 0xc1, 0xac, 0x38, 0x10, 0x33, 0xc1, - 0x9c, 0xfa, 0x58, 0x30, 0x17, 0xce, 0xb1, 0xa6, 0x52, 0xe8, 0xa3, 0xa9, 0x3c, 0x80, 0x73, 0xc9, - 0x07, 0xcf, 0x57, 0x03, 0xaf, 0xdd, 0xf0, 0x3a, 0x4e, 0x53, 0x6a, 0xba, 0xfc, 0x5b, 0xc8, 0xc9, - 0x37, 0xd3, 0x3b, 0x31, 0x82, 0x95, 0x49, 0xc6, 0xba, 0x31, 0xbf, 0x5c, 0xe7, 0x49, 0x2e, 0x86, - 0x91, 0x05, 0x76, 0xc3, 0x6d, 0x87, 0x3c, 0xcb, 0x85, 0x15, 0x17, 0xa3, 0x8e, 0x84, 0x1e, 0xff, - 0xfc, 0x7b, 0xe5, 0x28, 0x64, 0xa5, 0x7f, 0x13, 0x0f, 0x10, 0x10, 0xdf, 0xd8, 0xb7, 0x34, 0xbc, - 0x84, 0x8e, 0x7f, 0x1f, 0x1d, 0xaf, 0x74, 0x74, 0xba, 0x30, 0xdc, 0x51, 0xe9, 0x38, 0x1e, 0xb3, - 0xbf, 0xb9, 0x87, 0x08, 0xce, 0x75, 0x29, 0xd1, 0xa8, 0xf8, 0x07, 0xcb, 0xb9, 0x46, 0xa5, 0xa0, - 0x90, 0x77, 0xe0, 0xec, 0xc2, 0xdc, 0xac, 0x74, 0xb6, 0x9f, 0xf7, 0x1b, 0xdd, 0x16, 0x6d, 0x47, - 0x18, 0xaa, 0x21, 0x62, 0x9d, 0x68, 0x63, 0x96, 0x19, 0x79, 0x59, 0x68, 0xc2, 0xe5, 0x9e, 0x07, - 0x9e, 0xcd, 0xf9, 0x2e, 0x0d, 0x37, 0x6e, 0x7d, 0xcc, 0x5c, 0xee, 0x95, 0xbe, 0xe1, 0x46, 0xba, - 0x95, 0xb9, 0xe9, 0xfe, 0x11, 0xba, 0xdc, 0xf7, 0xe0, 0x92, 0x4f, 0xc3, 0x10, 0xfe, 0x14, 0xc7, - 0xd8, 0xd9, 0x0c, 0xb6, 0xc9, 0x11, 0xd6, 0x60, 0x98, 0x16, 0x27, 0x20, 0x8b, 0x49, 0xca, 0xed, - 0x13, 0x38, 0x8e, 0x8a, 0xe8, 0x55, 0xfd, 0x5b, 0x0b, 0x2e, 0x8c, 0xa9, 0x15, 0xb2, 0x35, 0x72, - 0xcf, 0x09, 0x77, 0xa8, 0x3b, 0x27, 0xbf, 0xad, 0x36, 0xc6, 0xd7, 0xc8, 0x0e, 0x42, 0xf1, 0x3b, - 0x10, 0x96, 0x82, 0x42, 0x9e, 0x87, 0xe1, 0xc5, 0x70, 0x3d, 0x14, 0x4d, 0x11, 0xa6, 0x85, 0x87, - 0x26, 0xa1, 0x6b, 0x89, 0xa2, 0xeb, 0xef, 0xc3, 0xa4, 0xcc, 0xc9, 0xb2, 0xb6, 0x54, 0xc7, 0xaf, - 0x1b, 0x4d, 0xc2, 0xe8, 0xc6, 0x82, 0xb5, 0x78, 0xe7, 0x0b, 0xf6, 0x9d, 0xf5, 0xa5, 0xa5, 0xf2, - 0x19, 0x32, 0x0e, 0x25, 0x01, 0x98, 0xab, 0x96, 0x0d, 0x32, 0x06, 0xc5, 0xc5, 0xe5, 0xfa, 0xc2, - 0xdc, 0xba, 0xb5, 0x50, 0xce, 0x5d, 0x7f, 0x11, 0x26, 0x92, 0x7b, 0x21, 0x8c, 0x1d, 0x19, 0x81, - 0xbc, 0x55, 0xdd, 0x2c, 0x9f, 0x21, 0x00, 0xc3, 0xab, 0xf7, 0xe7, 0xea, 0xb7, 0x6e, 0x95, 0x8d, - 0xeb, 0xaf, 0x65, 0x7c, 0x1b, 0x90, 0x71, 0xaa, 0xd3, 0x8e, 0x13, 0x38, 0x11, 0xe5, 0xd5, 0x3c, - 0xe8, 0x36, 0x23, 0xaf, 0xd3, 0xa4, 0x8f, 0xcb, 0xc6, 0xf5, 0xb7, 0x7a, 0x3e, 0xf1, 0x47, 0xa6, - 0x61, 0x6a, 0x7d, 0xb9, 0xfa, 0xa0, 0xb6, 0x78, 0x77, 0x7d, 0x65, 0xbd, 0x6e, 0x3f, 0xa8, 0xae, - 0xcd, 0xdd, 0x2b, 0x9f, 0x61, 0x0d, 0x7e, 0xb0, 0x52, 0x5f, 0xb3, 0xad, 0x85, 0xb9, 0x85, 0xe5, - 0xb5, 0xb2, 0x71, 0xdd, 0x87, 0x09, 0xfd, 0x2b, 0x28, 0xe4, 0x0a, 0x5c, 0x5e, 0xaf, 0x2f, 0x58, - 0xf6, 0xda, 0xca, 0xfd, 0x85, 0x65, 0x7b, 0xbd, 0x5e, 0xbd, 0xbb, 0x60, 0xaf, 0x2f, 0xd7, 0x57, - 0x17, 0xe6, 0x16, 0xef, 0x2c, 0x2e, 0xcc, 0x97, 0xcf, 0x90, 0x0a, 0x3c, 0xa3, 0x60, 0x58, 0x0b, - 0x73, 0x2b, 0x1b, 0x0b, 0x96, 0xbd, 0x5a, 0xad, 0xd7, 0x37, 0x57, 0xac, 0xf9, 0xb2, 0x41, 0x2e, - 0xc1, 0xf9, 0x0c, 0x84, 0x07, 0x77, 0xaa, 0xe5, 0xdc, 0xf5, 0xf7, 0xd9, 0x5c, 0x25, 0xa9, 0x88, - 0x49, 0x11, 0x0a, 0xcb, 0x2b, 0xcb, 0x0b, 0xe5, 0x33, 0x64, 0x14, 0x46, 0x56, 0x17, 0x96, 0xe7, - 0x17, 0x97, 0xef, 0xf2, 0x91, 0xab, 0xae, 0xae, 0x5a, 0x2b, 0x1b, 0x0b, 0xf3, 0xe5, 0x1c, 0x1b, - 0x9e, 0xf9, 0x85, 0x65, 0x56, 0x7b, 0xbe, 0x56, 0xfe, 0xf1, 0x4f, 0x9f, 0x3b, 0xf3, 0xe3, 0x9f, - 0x3d, 0x67, 0xfc, 0xe4, 0x67, 0xcf, 0x19, 0xff, 0xf3, 0x67, 0xcf, 0x19, 0x5b, 0xc3, 0xb8, 0x60, - 0x6e, 0xff, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, 0xa3, 0x60, 0x7d, 0x4c, 0xa9, 0x00, 0x00, + // 10767 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0xbd, 0x5d, 0x6c, 0x24, 0xd9, + 0x75, 0x18, 0x3c, 0xd5, 0xdd, 0x24, 0xbb, 0x0f, 0xff, 0x9a, 0x97, 0xc3, 0x19, 0xce, 0xec, 0xec, + 0xf6, 0xa8, 0xf6, 0x6f, 0x66, 0xb4, 0x3b, 0xb3, 0xc3, 0xd9, 0x5d, 0x69, 0xb5, 0x7f, 0xea, 0x26, + 0x39, 0x33, 0xdc, 0xe1, 0x90, 0xdc, 0x6a, 0xfe, 0xe8, 0xd7, 0xe5, 0x62, 0xd7, 0x1d, 0xb2, 0xc4, + 0xee, 0xae, 0x56, 0x55, 0xf5, 0xcc, 0xd0, 0xfa, 0x0c, 0xfb, 0x4b, 0x20, 0x0b, 0x86, 0x61, 0x29, + 0x0a, 0x64, 0x48, 0x0e, 0x9c, 0xc4, 0x10, 0x12, 0xe4, 0xc7, 0x50, 0x1e, 0xec, 0x00, 0x41, 0x80, + 0xe4, 0xc1, 0x80, 0xe1, 0xe8, 0x21, 0x46, 0xf4, 0x16, 0xd8, 0x09, 0x98, 0x48, 0xce, 0x8b, 0x09, + 0xe4, 0x29, 0x4f, 0x56, 0x22, 0x24, 0xb8, 0xe7, 0xde, 0x5b, 0x75, 0x6f, 0x75, 0x35, 0xd9, 0xdc, + 0x99, 0x05, 0xc4, 0x7d, 0x22, 0xfb, 0xdc, 0x73, 0xce, 0xfd, 0x3f, 0xf7, 0x9c, 0x7b, 0xcf, 0x39, + 0x05, 0xa3, 0xd1, 0x7e, 0x87, 0x86, 0xd7, 0x3b, 0x81, 0x1f, 0xf9, 0x64, 0x08, 0x7f, 0x5c, 0x3c, + 0xbb, 0xe3, 0xef, 0xf8, 0x08, 0xb9, 0xc1, 0xfe, 0xe3, 0x85, 0x17, 0x2b, 0x3b, 0xbe, 0xbf, 0xd3, + 0xa4, 0x37, 0xf0, 0xd7, 0x76, 0xf7, 0xc1, 0x8d, 0xc8, 0x6b, 0xd1, 0x30, 0x72, 0x5a, 0x1d, 0x81, + 0x30, 0xbf, 0xe3, 0x45, 0xbb, 0xdd, 0xed, 0xeb, 0x0d, 0xbf, 0x75, 0x63, 0x27, 0x70, 0x1e, 0x7a, + 0x91, 0x13, 0x79, 0x7e, 0xdb, 0x69, 0xde, 0x88, 0x68, 0x93, 0x76, 0xfc, 0x20, 0xba, 0xe1, 0x74, + 0xbc, 0x1b, 0x58, 0xc7, 0x8d, 0x47, 0x81, 0xd3, 0xe9, 0xd0, 0x20, 0xf9, 0x87, 0x33, 0x31, 0xbf, + 0x9b, 0x87, 0xd2, 0x3d, 0x4a, 0x3b, 0xd5, 0xa6, 0xf7, 0x90, 0x92, 0xe7, 0xa1, 0xb0, 0xe2, 0xb4, + 0xe8, 0xac, 0x71, 0xd9, 0xb8, 0x52, 0xaa, 0x4d, 0x1e, 0x1e, 0x54, 0x46, 0x43, 0x1a, 0x3c, 0xa4, + 0x81, 0xdd, 0x76, 0x5a, 0xd4, 0xc2, 0x42, 0xf2, 0x69, 0x28, 0xb1, 0xbf, 0x61, 0xc7, 0x69, 0xd0, + 0xd9, 0x1c, 0x62, 0x8e, 0x1f, 0x1e, 0x54, 0x4a, 0x6d, 0x09, 0xb4, 0x92, 0x72, 0xf2, 0x12, 0x8c, + 0x2c, 0x53, 0x27, 0xa4, 0x4b, 0x0b, 0xb3, 0xf9, 0xcb, 0xc6, 0x95, 0x7c, 0x6d, 0xec, 0xf0, 0xa0, + 0x52, 0x6c, 0x32, 0x90, 0xed, 0xb9, 0x96, 0x2c, 0x24, 0x4b, 0x30, 0xb2, 0xf8, 0xb8, 0xe3, 0x05, + 0x34, 0x9c, 0x2d, 0x5c, 0x36, 0xae, 0x8c, 0xce, 0x5d, 0xbc, 0xce, 0xfb, 0x7f, 0x5d, 0xf6, 0xff, + 0xfa, 0xba, 0xec, 0x7f, 0x6d, 0xfa, 0xc7, 0x07, 0x95, 0x33, 0x87, 0x07, 0x95, 0x11, 0xca, 0x49, + 0xfe, 0xde, 0x7f, 0xab, 0x18, 0x96, 0xa4, 0x27, 0xef, 0x40, 0x61, 0x7d, 0xbf, 0x43, 0x67, 0x4b, + 0x97, 0x8d, 0x2b, 0x13, 0x73, 0xcf, 0x5d, 0xe7, 0x23, 0x1e, 0x77, 0x32, 0xf9, 0x8f, 0x61, 0xd5, + 0x8a, 0x87, 0x07, 0x95, 0x02, 0x43, 0xb1, 0x90, 0x8a, 0xbc, 0x0a, 0xc3, 0x77, 0xfd, 0x30, 0x5a, + 0x5a, 0x98, 0x05, 0xec, 0xda, 0xcc, 0xe1, 0x41, 0x65, 0x6a, 0xd7, 0x0f, 0x23, 0xdb, 0x73, 0x5f, + 0xf1, 0x5b, 0x5e, 0x44, 0x5b, 0x9d, 0x68, 0xdf, 0x12, 0x48, 0xa6, 0x05, 0xe3, 0x1a, 0x3f, 0x32, + 0x0a, 0x23, 0x1b, 0x2b, 0xf7, 0x56, 0x56, 0xb7, 0x56, 0xca, 0x67, 0x48, 0x11, 0x0a, 0x2b, 0xab, + 0x0b, 0x8b, 0x65, 0x83, 0x8c, 0x40, 0xbe, 0xba, 0xb6, 0x56, 0xce, 0x91, 0x31, 0x28, 0x2e, 0x54, + 0xd7, 0xab, 0xb5, 0x6a, 0x7d, 0xb1, 0x9c, 0x27, 0xd3, 0x30, 0xb9, 0xb5, 0xb4, 0xb2, 0xb0, 0xba, + 0x55, 0xb7, 0x17, 0x16, 0xeb, 0xf7, 0xd6, 0x57, 0xd7, 0xca, 0x05, 0xf3, 0x5b, 0x79, 0x28, 0xde, + 0xa7, 0x91, 0xe3, 0x3a, 0x91, 0x43, 0x2e, 0x69, 0x53, 0x82, 0xad, 0x55, 0xe6, 0xe2, 0xf9, 0xde, + 0xb9, 0x18, 0x3a, 0x3c, 0xa8, 0x18, 0xaf, 0xaa, 0x73, 0xf0, 0x36, 0x8c, 0x2e, 0xd0, 0xb0, 0x11, + 0x78, 0x1d, 0xb6, 0x3e, 0x70, 0x1e, 0x4a, 0xb5, 0x0b, 0x87, 0x07, 0x95, 0x19, 0x37, 0x01, 0x2b, + 0x7d, 0x53, 0xb1, 0xc9, 0x12, 0x0c, 0x2f, 0x3b, 0xdb, 0xb4, 0x19, 0xce, 0x0e, 0x5d, 0xce, 0x5f, + 0x19, 0x9d, 0x7b, 0x46, 0x8c, 0xa7, 0x6c, 0xe0, 0x75, 0x5e, 0xba, 0xd8, 0x8e, 0x82, 0xfd, 0xda, + 0xd9, 0xc3, 0x83, 0x4a, 0xb9, 0x89, 0x00, 0x75, 0xac, 0x38, 0x0a, 0xa9, 0x27, 0x73, 0x3c, 0x7c, + 0xec, 0x1c, 0x3f, 0xfb, 0xe3, 0x83, 0x8a, 0xc1, 0xc6, 0x5e, 0xcc, 0x71, 0xc2, 0x4f, 0x9f, 0xed, + 0xcb, 0x90, 0x5b, 0x5a, 0x98, 0x1d, 0xc1, 0xb5, 0x55, 0x3e, 0x3c, 0xa8, 0x8c, 0x69, 0xd3, 0x94, + 0x5b, 0x5a, 0xb8, 0xf8, 0x16, 0x8c, 0x2a, 0x6d, 0x24, 0x65, 0xc8, 0xef, 0xd1, 0x7d, 0x3e, 0x9e, + 0x16, 0xfb, 0x97, 0x9c, 0x85, 0xa1, 0x87, 0x4e, 0xb3, 0x2b, 0x06, 0xd0, 0xe2, 0x3f, 0x3e, 0x97, + 0xfb, 0xac, 0x61, 0xfe, 0xfd, 0x02, 0x14, 0x2d, 0x9f, 0xef, 0x2b, 0x72, 0x15, 0x86, 0xea, 0x91, + 0x13, 0xc9, 0xa9, 0x98, 0x3e, 0x3c, 0xa8, 0x4c, 0x86, 0x0c, 0xa0, 0xd4, 0xc7, 0x31, 0x18, 0xea, + 0xda, 0xae, 0x13, 0xca, 0x29, 0x41, 0xd4, 0x0e, 0x03, 0xa8, 0xa8, 0x88, 0x41, 0x5e, 0x82, 0xc2, + 0x7d, 0xdf, 0xa5, 0x62, 0x56, 0xc8, 0xe1, 0x41, 0x65, 0xa2, 0xe5, 0xbb, 0x2a, 0x22, 0x96, 0x93, + 0x57, 0xa0, 0x34, 0xdf, 0x0d, 0x02, 0xda, 0x66, 0x4b, 0xb3, 0x80, 0xc8, 0x13, 0x87, 0x07, 0x15, + 0x68, 0x70, 0x20, 0xdb, 0x4c, 0x09, 0x02, 0x1b, 0xea, 0x7a, 0xe4, 0x04, 0x11, 0x75, 0x67, 0x87, + 0x06, 0x1a, 0x6a, 0xb6, 0x9d, 0xa6, 0x42, 0x4e, 0x92, 0x1e, 0x6a, 0xc1, 0x89, 0xdc, 0x85, 0xd1, + 0x3b, 0x81, 0xd3, 0xa0, 0x6b, 0x34, 0xf0, 0x7c, 0x17, 0xe7, 0x30, 0x5f, 0x7b, 0xe9, 0xf0, 0xa0, + 0x72, 0x6e, 0x87, 0x81, 0xed, 0x0e, 0xc2, 0x13, 0xea, 0x9f, 0x1f, 0x54, 0x8a, 0x0b, 0xdd, 0x00, + 0x47, 0xcf, 0x52, 0x49, 0xc9, 0xaf, 0xb2, 0x29, 0x09, 0x23, 0x1c, 0x5a, 0xea, 0xe2, 0xec, 0x1d, + 0xdd, 0x44, 0x53, 0x34, 0xf1, 0x5c, 0xd3, 0x09, 0x23, 0x3b, 0xe0, 0x74, 0xa9, 0x76, 0xaa, 0x2c, + 0xc9, 0x2a, 0x14, 0xeb, 0x8d, 0x5d, 0xea, 0x76, 0x9b, 0x74, 0xb6, 0x88, 0xec, 0xcf, 0x8b, 0x85, + 0x2b, 0xe7, 0x53, 0x16, 0xd7, 0x2e, 0x0a, 0xde, 0x24, 0x14, 0x10, 0x65, 0xec, 0x63, 0x26, 0x9f, + 0x2b, 0xfe, 0xe0, 0x0f, 0x2b, 0x67, 0x7e, 0xf3, 0xbf, 0x5e, 0x3e, 0x63, 0xfe, 0x9b, 0x1c, 0x94, + 0xd3, 0x4c, 0xc8, 0x03, 0x18, 0xdf, 0xe8, 0xb8, 0x4e, 0x44, 0xe7, 0x9b, 0x1e, 0x6d, 0x47, 0x21, + 0x2e, 0x92, 0xa3, 0xfb, 0xf4, 0x82, 0xa8, 0x77, 0xb6, 0x8b, 0x84, 0x76, 0x83, 0x53, 0xa6, 0x7a, + 0xa5, 0xb3, 0x4d, 0xea, 0xa9, 0xa3, 0x5c, 0x0e, 0x71, 0x85, 0x9d, 0xac, 0x1e, 0x2e, 0xd1, 0xfb, + 0xd4, 0x23, 0xd8, 0x8a, 0x05, 0xd4, 0x76, 0xb7, 0xf7, 0x71, 0x65, 0x0e, 0xbe, 0x80, 0x18, 0x49, + 0xc6, 0x02, 0x62, 0x60, 0xf3, 0x7f, 0x18, 0x30, 0x61, 0xd1, 0xd0, 0xef, 0x06, 0x0d, 0x7a, 0x97, + 0x3a, 0x2e, 0x0d, 0xd8, 0xf2, 0xbf, 0xe7, 0xb5, 0x5d, 0xb1, 0xa7, 0x70, 0xf9, 0xef, 0x79, 0x6d, + 0x75, 0x0b, 0x63, 0x39, 0x79, 0x0d, 0x46, 0xea, 0xdd, 0x6d, 0x44, 0xe5, 0x7b, 0xea, 0x1c, 0xce, + 0x58, 0x77, 0xdb, 0x4e, 0xa1, 0x4b, 0x34, 0x72, 0x03, 0x46, 0x36, 0x69, 0x10, 0x26, 0x12, 0x0f, + 0x25, 0xf9, 0x43, 0x0e, 0x52, 0x09, 0x04, 0x16, 0xb9, 0x93, 0x48, 0x5d, 0x71, 0x06, 0x4d, 0xa6, + 0x64, 0x5d, 0xb2, 0x54, 0x5a, 0x02, 0xa2, 0x2e, 0x15, 0x89, 0x65, 0x7e, 0x37, 0x07, 0xe5, 0x05, + 0x27, 0x72, 0xb6, 0x9d, 0x50, 0x8c, 0xe7, 0xe6, 0x2d, 0x26, 0xc7, 0x95, 0x8e, 0xa2, 0x1c, 0x67, + 0x2d, 0xff, 0xc8, 0xdd, 0x7b, 0x31, 0xdd, 0xbd, 0x51, 0x76, 0x20, 0x8a, 0xee, 0x25, 0x9d, 0x7a, + 0xf7, 0xf8, 0x4e, 0x95, 0x45, 0xa7, 0x8a, 0xb2, 0x53, 0x49, 0x57, 0xc8, 0xbb, 0x50, 0xa8, 0x77, + 0x68, 0x43, 0x08, 0x11, 0x29, 0xfb, 0xf5, 0xce, 0x31, 0x84, 0xcd, 0x5b, 0xb5, 0x31, 0xc1, 0xa6, + 0x10, 0x76, 0x68, 0xc3, 0x42, 0x32, 0x65, 0xd3, 0x7c, 0x6f, 0x18, 0xce, 0x66, 0x91, 0x91, 0x77, + 0xf5, 0xc3, 0x89, 0x0f, 0xcf, 0x33, 0x7d, 0x0f, 0xa7, 0x59, 0x43, 0x3f, 0x9e, 0xae, 0x41, 0x71, + 0x8d, 0x2d, 0xc8, 0x86, 0xdf, 0x14, 0x23, 0xc7, 0xa4, 0x62, 0xb1, 0x23, 0x61, 0x86, 0x15, 0x97, + 0x93, 0x67, 0x20, 0xbf, 0x61, 0x2d, 0x89, 0xe1, 0x2a, 0x1d, 0x1e, 0x54, 0xf2, 0xdd, 0xc0, 0x9b, + 0x35, 0x2c, 0x06, 0x25, 0x37, 0x60, 0x78, 0xbe, 0x3a, 0x4f, 0x83, 0x08, 0x87, 0x69, 0xac, 0x76, + 0x9e, 0xad, 0x96, 0x86, 0x63, 0x37, 0x68, 0x10, 0x69, 0xd5, 0x0b, 0x34, 0xf2, 0x69, 0xc8, 0x57, + 0xb7, 0xea, 0x62, 0x64, 0x40, 0x8c, 0x4c, 0x75, 0xab, 0x5e, 0x1b, 0x17, 0x03, 0x91, 0x77, 0x1e, + 0x85, 0x8c, 0x7b, 0x75, 0xab, 0xae, 0xce, 0xd6, 0xf0, 0x11, 0xb3, 0x75, 0x05, 0x8a, 0x4c, 0xaf, + 0x60, 0x07, 0x3c, 0x0a, 0xc5, 0x12, 0x57, 0x97, 0x76, 0x05, 0xcc, 0x8a, 0x4b, 0xc9, 0xf3, 0xb1, + 0x9a, 0x52, 0x4c, 0xf8, 0x09, 0x35, 0x45, 0x2a, 0x27, 0xe4, 0x31, 0x8c, 0x2f, 0xec, 0xb7, 0x9d, + 0x96, 0xd7, 0x10, 0x47, 0x78, 0x09, 0x8f, 0xf0, 0xeb, 0x47, 0x4c, 0xe3, 0x75, 0x8d, 0x80, 0x9f, + 0xea, 0x52, 0xf8, 0xce, 0xba, 0xbc, 0xcc, 0x4e, 0x9f, 0xf0, 0xb3, 0x86, 0xa5, 0x57, 0xc4, 0xf6, + 0x92, 0x14, 0x91, 0xa8, 0x47, 0x25, 0xcb, 0x4e, 0x82, 0x93, 0xbd, 0x14, 0x08, 0x88, 0xba, 0x97, + 0xe2, 0x43, 0xf7, 0x5d, 0xc8, 0xdf, 0x99, 0x5f, 0x9b, 0x1d, 0x45, 0x1e, 0x44, 0xf0, 0xb8, 0x33, + 0xbf, 0x36, 0xdf, 0xf4, 0xbb, 0x6e, 0xfd, 0xc3, 0xe5, 0xda, 0x79, 0xc1, 0x66, 0x7c, 0xa7, 0xd1, + 0xd1, 0x5a, 0xc4, 0xe8, 0xc8, 0x22, 0x14, 0x65, 0x2f, 0x67, 0xc7, 0x90, 0xc7, 0x54, 0xaa, 0xf3, + 0x9b, 0xb7, 0xf8, 0x5e, 0x73, 0xc5, 0x6f, 0xb5, 0x15, 0x12, 0xe7, 0xe2, 0x16, 0x90, 0xde, 0x71, + 0xc9, 0xd0, 0x24, 0x3e, 0xad, 0x6a, 0x12, 0xa3, 0x73, 0x33, 0xa2, 0xae, 0x79, 0xbf, 0xd5, 0x72, + 0xda, 0x2e, 0xd2, 0x6e, 0xce, 0xa9, 0x0a, 0x46, 0x15, 0x26, 0x92, 0x86, 0x2c, 0x7b, 0x61, 0x44, + 0x6e, 0x40, 0x49, 0x42, 0xd8, 0x21, 0x92, 0xcf, 0x6c, 0xb2, 0x95, 0xe0, 0x98, 0x7f, 0x9e, 0x03, + 0x48, 0x4a, 0x4e, 0xa9, 0x9c, 0xf9, 0x8c, 0x26, 0x67, 0x66, 0xd2, 0x0b, 0xb4, 0xaf, 0x84, 0x21, + 0xef, 0xc3, 0x30, 0x53, 0xb9, 0xba, 0x52, 0xa5, 0x3c, 0x9f, 0x26, 0xc5, 0xc2, 0xcd, 0x5b, 0xb5, + 0x09, 0x41, 0x3c, 0x1c, 0x22, 0xc4, 0x12, 0x64, 0x8a, 0x88, 0xfa, 0xf7, 0x85, 0x64, 0x32, 0x84, + 0x70, 0xba, 0xa2, 0x48, 0x17, 0x23, 0xd9, 0x8f, 0x52, 0xba, 0x28, 0xb2, 0xe5, 0x02, 0x97, 0x2d, + 0x7c, 0x50, 0x47, 0x84, 0x6c, 0x49, 0x4b, 0x16, 0x3e, 0x80, 0xc7, 0x4a, 0x96, 0x4e, 0x7a, 0xdb, + 0x16, 0x70, 0x19, 0x5c, 0xc9, 0x1c, 0x95, 0xac, 0x0d, 0x7b, 0xf9, 0xb8, 0x0d, 0x9b, 0xde, 0xae, + 0xb7, 0xfa, 0xc9, 0xb2, 0x19, 0xb9, 0xbb, 0x9c, 0x47, 0x2a, 0x39, 0xca, 0xb4, 0xb7, 0xf9, 0xd6, + 0x1c, 0xee, 0xbb, 0x35, 0x67, 0x32, 0xb7, 0x26, 0xdf, 0x98, 0x6f, 0xc3, 0x50, 0xf5, 0xd7, 0xba, + 0x01, 0x15, 0xba, 0xdf, 0x98, 0xac, 0x93, 0xc1, 0xe2, 0x3d, 0x3d, 0xe9, 0xb0, 0x9f, 0xaa, 0xce, + 0x8c, 0xe5, 0xac, 0xe6, 0xf5, 0xe5, 0xba, 0xd0, 0xeb, 0x48, 0x6a, 0x58, 0xd6, 0x97, 0x95, 0x66, + 0x47, 0x5a, 0xaf, 0x19, 0xd5, 0xc7, 0xb7, 0x97, 0x9b, 0xca, 0xa9, 0x2f, 0x56, 0x1d, 0xb3, 0x26, + 0xc5, 0xdc, 0x1b, 0x89, 0x0e, 0xd2, 0x33, 0xf7, 0xf1, 0xcc, 0x5f, 0xe5, 0xf3, 0x90, 0xeb, 0x99, + 0x87, 0x51, 0xe5, 0x4c, 0xc1, 0xd1, 0x37, 0xff, 0xc6, 0x40, 0x5c, 0xf2, 0x0a, 0x0c, 0x5b, 0x74, + 0x27, 0x39, 0x3a, 0xd1, 0x04, 0x0b, 0x10, 0xa2, 0x56, 0xc0, 0x71, 0x50, 0x2e, 0x53, 0x37, 0xdc, + 0xf5, 0x1e, 0x44, 0xa2, 0x96, 0x58, 0x2e, 0x0b, 0xb0, 0x22, 0x97, 0x05, 0x44, 0x93, 0xcb, 0x02, + 0xc6, 0x56, 0x8c, 0xb5, 0x50, 0x17, 0xba, 0xa1, 0x6c, 0xa9, 0xb5, 0xa0, 0x0c, 0x7d, 0xe0, 0x6a, + 0x43, 0x6f, 0x2d, 0xd4, 0xc9, 0x9b, 0x50, 0xaa, 0x36, 0x1a, 0x7e, 0x57, 0xb1, 0x61, 0x66, 0x0f, + 0x0f, 0x2a, 0x67, 0x1d, 0x0e, 0xd4, 0x2d, 0xec, 0x04, 0xd5, 0xac, 0x25, 0xad, 0x66, 0x3c, 0xe6, + 0x9b, 0xdd, 0x30, 0xa2, 0xc1, 0xd2, 0x82, 0xe8, 0x32, 0xf2, 0x68, 0x70, 0x60, 0x8a, 0x47, 0x8c, + 0x6a, 0xfe, 0x17, 0x03, 0x5b, 0x4c, 0xde, 0x02, 0x58, 0x6a, 0x33, 0x3d, 0xb5, 0x41, 0x63, 0x06, + 0x68, 0x0b, 0x7b, 0x02, 0xaa, 0x73, 0x50, 0x90, 0xf5, 0xaa, 0x73, 0x03, 0x57, 0xcd, 0xaa, 0x94, + 0x5a, 0xaf, 0xb8, 0x06, 0x11, 0x55, 0x06, 0x02, 0x9a, 0xaa, 0x32, 0x41, 0x26, 0x2f, 0xc1, 0xc8, + 0x52, 0xf5, 0x7e, 0xb5, 0x1b, 0xed, 0xe2, 0x78, 0x15, 0xb9, 0xfc, 0xf1, 0x9c, 0x96, 0xed, 0x74, + 0xa3, 0x5d, 0x4b, 0x16, 0x9a, 0xbf, 0x69, 0xc0, 0xa8, 0xb2, 0xf5, 0x58, 0x53, 0xd7, 0x02, 0xff, + 0x6b, 0xb4, 0x11, 0xe9, 0xa3, 0xd4, 0xe1, 0xc0, 0x54, 0x53, 0x63, 0xd4, 0xd4, 0xe8, 0xe4, 0x4e, + 0x30, 0x3a, 0xe6, 0x0d, 0xb1, 0xa3, 0x99, 0x4a, 0xaf, 0xdc, 0x58, 0xa0, 0x4a, 0xcf, 0x54, 0x16, + 0x55, 0xa5, 0x67, 0xe5, 0xe6, 0x8f, 0x0c, 0x18, 0x55, 0x36, 0x2d, 0x79, 0x5d, 0x58, 0xc2, 0x06, + 0xde, 0xdb, 0x9c, 0xeb, 0xdd, 0xd6, 0xac, 0x94, 0x9f, 0x68, 0xcc, 0x42, 0x16, 0x76, 0x71, 0xb2, + 0xc3, 0x72, 0x83, 0xec, 0xb0, 0xb7, 0x00, 0xb8, 0xba, 0x83, 0x4d, 0x54, 0xe6, 0x42, 0xb9, 0xe7, + 0x52, 0x3b, 0x98, 0x20, 0x9b, 0xff, 0x7f, 0x0e, 0x8a, 0x42, 0x9d, 0x9f, 0x3b, 0xa5, 0xc7, 0xec, + 0x1b, 0xda, 0x31, 0x3b, 0x2d, 0x48, 0x15, 0xfd, 0x6f, 0xee, 0x18, 0x35, 0xfe, 0x2d, 0x18, 0x93, + 0x43, 0x80, 0xda, 0xca, 0x55, 0x18, 0x91, 0x86, 0x28, 0xd7, 0x55, 0x26, 0x35, 0x9e, 0x9b, 0x73, + 0x96, 0x2c, 0x37, 0xbf, 0x3b, 0x24, 0x69, 0x79, 0x4d, 0x6c, 0x08, 0xab, 0xae, 0x1b, 0xa8, 0x43, + 0xe8, 0xb8, 0x6e, 0x60, 0x21, 0x94, 0x4d, 0xd4, 0x5a, 0x77, 0xbb, 0xe9, 0x35, 0x10, 0x47, 0x59, + 0x89, 0x1d, 0x84, 0xda, 0x0c, 0x55, 0x9d, 0xa8, 0x04, 0x59, 0xd3, 0xa2, 0xf3, 0x47, 0x6a, 0xd1, + 0xbf, 0x02, 0xa5, 0xf9, 0x96, 0xab, 0x9d, 0xb2, 0x66, 0xc6, 0xa0, 0x5c, 0x8f, 0x91, 0xf8, 0xf9, + 0x7a, 0x49, 0x8c, 0xd1, 0xd9, 0x46, 0xcb, 0xed, 0x3d, 0x5b, 0x13, 0x96, 0x9a, 0x1a, 0x3c, 0xf4, + 0x24, 0x6a, 0xf0, 0x9b, 0x50, 0xda, 0x08, 0xe9, 0x7a, 0xb7, 0xdd, 0xa6, 0x4d, 0x3c, 0x71, 0x8b, + 0x7c, 0x3f, 0x77, 0x43, 0x6a, 0x47, 0x08, 0x55, 0x1b, 0x10, 0xa3, 0xaa, 0xcb, 0x6a, 0xe4, 0x88, + 0x65, 0xf5, 0x3a, 0x14, 0xaa, 0x9d, 0x8e, 0xb4, 0x0f, 0xe2, 0x83, 0xa7, 0xd3, 0xc1, 0xe3, 0x64, + 0xc2, 0xe9, 0x74, 0x74, 0x6d, 0x1f, 0xb1, 0x09, 0x05, 0x72, 0xaf, 0xbb, 0x4d, 0x83, 0x36, 0x8d, + 0x68, 0x28, 0xc4, 0x5d, 0x38, 0x0b, 0xc8, 0x63, 0x56, 0x5e, 0xbb, 0xa6, 0x11, 0xd0, 0xb6, 0x3b, + 0xbf, 0xd7, 0xdd, 0xa6, 0xb6, 0x90, 0x9b, 0xea, 0xd8, 0x65, 0x30, 0xbc, 0x58, 0x87, 0x09, 0x7d, + 0xfc, 0x9f, 0xc2, 0x61, 0xfd, 0x41, 0xa1, 0x58, 0x2c, 0x97, 0xcc, 0x6f, 0xe5, 0x60, 0xb4, 0xda, + 0xe9, 0x9c, 0x72, 0x23, 0xfd, 0xb3, 0xda, 0xae, 0x3e, 0x97, 0xcc, 0xde, 0x09, 0xec, 0xf3, 0xbf, + 0x35, 0x60, 0x32, 0x45, 0xa1, 0xb6, 0xde, 0x18, 0xd0, 0x68, 0xcd, 0x0d, 0x68, 0xb4, 0xe6, 0xfb, + 0x1b, 0xad, 0xea, 0x9e, 0x29, 0x3c, 0xc9, 0x9e, 0x79, 0x19, 0xf2, 0xd5, 0x4e, 0x47, 0x8c, 0xca, + 0x58, 0x32, 0x2a, 0x9b, 0xb7, 0xb8, 0x82, 0xee, 0x74, 0x3a, 0x16, 0xc3, 0x30, 0x5f, 0x85, 0x12, + 0x82, 0x51, 0xa2, 0x5d, 0x16, 0x5b, 0x81, 0x8b, 0x33, 0x8d, 0x8c, 0x2f, 0x7b, 0xf3, 0x7f, 0x1b, + 0x30, 0x84, 0xbf, 0x4f, 0xe9, 0x72, 0x99, 0xd3, 0x96, 0x4b, 0x59, 0x59, 0x2e, 0x83, 0x2c, 0x94, + 0x3f, 0xce, 0xe3, 0x68, 0x89, 0x25, 0x22, 0xcc, 0x1e, 0x23, 0xc3, 0xec, 0x79, 0x02, 0x01, 0xbe, + 0x97, 0x36, 0x80, 0xf2, 0x38, 0x19, 0xcf, 0xa7, 0x9b, 0xfa, 0x54, 0x6c, 0x9f, 0xbb, 0x40, 0x96, + 0xda, 0x21, 0x6d, 0x74, 0x03, 0x5a, 0xdf, 0xf3, 0x3a, 0x9b, 0x34, 0xf0, 0x1e, 0xec, 0x0b, 0x6d, + 0x0b, 0x65, 0xac, 0x27, 0x4a, 0xed, 0x70, 0xcf, 0xeb, 0xd8, 0x0f, 0xb1, 0xdc, 0xca, 0xa0, 0x21, + 0xef, 0xc3, 0x88, 0x45, 0x1f, 0x05, 0x5e, 0x44, 0xc5, 0xd8, 0x4e, 0xc4, 0xba, 0x35, 0x42, 0xb9, + 0x6e, 0x12, 0xf0, 0x1f, 0xea, 0xfc, 0x8b, 0xf2, 0x8f, 0xcf, 0x34, 0xf9, 0xde, 0x10, 0xee, 0x85, + 0x63, 0x1e, 0x93, 0x8e, 0xb0, 0x61, 0xf5, 0xc9, 0xcc, 0x9f, 0x64, 0x32, 0x37, 0x61, 0x8c, 0x99, + 0x43, 0x29, 0x63, 0xf6, 0x52, 0x32, 0x97, 0xd7, 0xd5, 0xe2, 0xa3, 0xde, 0x91, 0x34, 0x3e, 0xc4, + 0x4e, 0x2f, 0x12, 0xfe, 0x3e, 0xf5, 0xac, 0xc2, 0x38, 0x63, 0x79, 0xc4, 0xa2, 0xa3, 0xc1, 0x07, + 0xeb, 0xc4, 0x0b, 0x63, 0xf8, 0xc9, 0x16, 0xc6, 0xc8, 0x47, 0x59, 0x18, 0xe9, 0x17, 0xbc, 0xe2, + 0x49, 0x5e, 0xf0, 0x2e, 0xbe, 0x0f, 0x53, 0x3d, 0x23, 0x7c, 0x92, 0x57, 0xb0, 0x8f, 0x6f, 0x59, + 0xfe, 0x7a, 0x3c, 0x2e, 0x64, 0x0e, 0x4d, 0x3c, 0x2f, 0xa0, 0x8d, 0x08, 0x45, 0xaf, 0x90, 0x96, + 0x81, 0x80, 0xa5, 0x6c, 0x50, 0x84, 0x91, 0xf7, 0x60, 0x84, 0xbf, 0x22, 0x84, 0xb3, 0x39, 0x9c, + 0xfb, 0x71, 0x51, 0x23, 0x87, 0x8a, 0xa7, 0x5b, 0x8e, 0xa1, 0x8e, 0xaa, 0x20, 0x32, 0xef, 0xc0, + 0xb0, 0x78, 0x85, 0x38, 0x7a, 0x5f, 0x54, 0x60, 0x68, 0x33, 0x19, 0x19, 0xbc, 0x39, 0xe6, 0x9d, + 0xb0, 0x38, 0xdc, 0xfc, 0x1d, 0x03, 0x26, 0xf4, 0x5e, 0x92, 0xeb, 0x30, 0x2c, 0x9e, 0xc9, 0x0c, + 0x7c, 0x26, 0x63, 0xbd, 0x19, 0xe6, 0x0f, 0x64, 0xda, 0xb3, 0x98, 0xc0, 0x62, 0xa2, 0x5f, 0x70, + 0xc0, 0xbe, 0x08, 0xd1, 0x2f, 0x16, 0xa9, 0x25, 0xcb, 0x88, 0xc9, 0xac, 0xfd, 0xb0, 0xdb, 0x94, + 0x77, 0x49, 0xc0, 0xd8, 0x06, 0x08, 0xb1, 0x44, 0x89, 0x79, 0x60, 0x00, 0xd4, 0xeb, 0x77, 0xef, + 0xd1, 0xfd, 0x35, 0xc7, 0x0b, 0xd0, 0x14, 0xc4, 0xdd, 0x78, 0x4f, 0xcc, 0xd6, 0x98, 0x30, 0x05, + 0xf9, 0xce, 0xdd, 0xa3, 0xfb, 0x9a, 0x29, 0x28, 0x51, 0x71, 0xcb, 0x07, 0xde, 0x43, 0x27, 0xa2, + 0x8c, 0x30, 0x87, 0x84, 0x7c, 0xcb, 0x73, 0x68, 0x8a, 0x52, 0x41, 0x26, 0x5f, 0x85, 0x89, 0xe4, + 0x17, 0xbe, 0xc5, 0xe7, 0xd1, 0xa6, 0x93, 0x2b, 0x42, 0x2f, 0xac, 0x3d, 0x77, 0x78, 0x50, 0xb9, + 0xa8, 0x70, 0xb5, 0x19, 0x96, 0xc2, 0x3a, 0xc5, 0xcc, 0xfc, 0xa1, 0x01, 0xb0, 0xbe, 0x5c, 0x97, + 0x1d, 0x7c, 0x09, 0x0a, 0xf1, 0x0d, 0xcb, 0x18, 0xb7, 0x37, 0x53, 0xc6, 0x1f, 0x96, 0x93, 0xe7, + 0x21, 0x9f, 0xf4, 0x64, 0xea, 0xf0, 0xa0, 0x32, 0xae, 0xf7, 0x80, 0x95, 0x92, 0x3b, 0x30, 0x32, + 0x50, 0x9b, 0x71, 0x75, 0x66, 0xb4, 0x55, 0x52, 0xe3, 0x2c, 0x7c, 0xb0, 0xb5, 0xfe, 0xc9, 0x9d, + 0x85, 0xef, 0xe4, 0x60, 0x92, 0x8d, 0x6b, 0xb5, 0x1b, 0xed, 0xfa, 0x81, 0x17, 0xed, 0x9f, 0x5a, + 0xab, 0xf8, 0x1d, 0x4d, 0x21, 0xba, 0x28, 0xc5, 0x96, 0xda, 0xb7, 0x81, 0x8c, 0xe3, 0x9f, 0x8e, + 0xc0, 0x74, 0x06, 0x15, 0x79, 0x45, 0x38, 0xa4, 0x24, 0xf7, 0x30, 0xe8, 0x70, 0xf2, 0xf3, 0x83, + 0xca, 0x98, 0x44, 0x5f, 0x4f, 0x1c, 0x50, 0xe6, 0x60, 0x54, 0x98, 0x3e, 0x2b, 0x89, 0x46, 0x8d, + 0x9e, 0x0d, 0xf2, 0x9e, 0x09, 0x45, 0x93, 0x8a, 0x44, 0xaa, 0x30, 0x36, 0xbf, 0x4b, 0x1b, 0x7b, + 0x5e, 0x7b, 0xe7, 0x1e, 0xdd, 0xe7, 0xfa, 0xd2, 0x58, 0xed, 0x59, 0x66, 0x69, 0x35, 0x04, 0x9c, + 0x4d, 0xa9, 0x6e, 0xc4, 0x69, 0x24, 0xe4, 0x3d, 0x18, 0xad, 0x7b, 0x3b, 0x6d, 0xc9, 0xa1, 0x80, + 0x1c, 0x2e, 0x1d, 0x1e, 0x54, 0xce, 0x85, 0x1c, 0xdc, 0xcb, 0x40, 0x25, 0x20, 0x57, 0x61, 0xc8, + 0xf2, 0x9b, 0x94, 0x1f, 0xc3, 0xc2, 0xe5, 0x21, 0x60, 0x00, 0xf5, 0xfa, 0x16, 0x31, 0xc8, 0x5d, + 0x18, 0x61, 0xff, 0xdc, 0x77, 0x3a, 0xb3, 0xc3, 0x28, 0xb7, 0x49, 0xac, 0xe0, 0x23, 0xb4, 0xe3, + 0xb5, 0x77, 0x54, 0x1d, 0xbf, 0x49, 0xed, 0x96, 0xd3, 0xd1, 0xce, 0x45, 0x8e, 0x48, 0x36, 0x61, + 0x34, 0x11, 0x04, 0xe1, 0xec, 0x88, 0xf6, 0x5c, 0x92, 0x94, 0xd4, 0x3e, 0x25, 0x98, 0x9d, 0x8f, + 0x9a, 0x21, 0xae, 0xed, 0x0e, 0xc3, 0xd7, 0x3b, 0xa3, 0x30, 0xd2, 0x6c, 0x90, 0x62, 0x7f, 0x1b, + 0xc4, 0x38, 0xd6, 0x06, 0x71, 0x01, 0xc4, 0x20, 0x55, 0x9b, 0x3b, 0xc2, 0x23, 0xe9, 0x6a, 0xff, + 0x05, 0x76, 0x3d, 0x41, 0xc6, 0x3d, 0xc9, 0x6f, 0xa6, 0xc4, 0xf8, 0x3b, 0xcd, 0x1d, 0xed, 0x66, + 0x2a, 0x46, 0x65, 0xc3, 0x90, 0x88, 0x1a, 0x69, 0x81, 0xcb, 0x61, 0x48, 0x4a, 0x92, 0x61, 0xf8, + 0xda, 0xa3, 0xa8, 0xdf, 0x30, 0x28, 0x8c, 0xc8, 0x0a, 0x40, 0xb5, 0x11, 0x79, 0x0f, 0x29, 0x2e, + 0x89, 0x51, 0x6d, 0x20, 0xe6, 0xab, 0xf7, 0xe8, 0x7e, 0x9d, 0x46, 0xf1, 0xe3, 0xff, 0x8c, 0x83, + 0xa8, 0xa9, 0x65, 0x62, 0x29, 0x1c, 0x48, 0x07, 0x66, 0xaa, 0xae, 0xeb, 0x71, 0x2f, 0xb5, 0xf5, + 0x80, 0xad, 0x5f, 0x17, 0x59, 0x8f, 0x65, 0xb3, 0xbe, 0x2a, 0x58, 0x7f, 0xca, 0x89, 0xa9, 0xec, + 0x88, 0x93, 0xa5, 0xab, 0xc9, 0x66, 0x6c, 0xae, 0xc2, 0x84, 0x3e, 0xa4, 0xba, 0x7f, 0xd6, 0x18, + 0x14, 0xad, 0x7a, 0xd5, 0xae, 0xdf, 0xad, 0xde, 0x2c, 0x1b, 0xa4, 0x0c, 0x63, 0xe2, 0xd7, 0x9c, + 0x3d, 0xf7, 0xc6, 0x9b, 0xe5, 0x9c, 0x06, 0x79, 0xe3, 0xe6, 0x5c, 0x39, 0x6f, 0xfe, 0xb1, 0x01, + 0x45, 0xd9, 0x3e, 0xf2, 0x26, 0xe4, 0xeb, 0xf5, 0xbb, 0xa9, 0x57, 0xba, 0xe4, 0xe8, 0xe5, 0x87, + 0x4c, 0x18, 0xee, 0xaa, 0x87, 0x4c, 0xbd, 0x7e, 0x97, 0xd1, 0xad, 0x2f, 0xd7, 0x85, 0xd2, 0x92, + 0xb1, 0x5c, 0xa7, 0xb2, 0x9f, 0x2e, 0x18, 0xdd, 0x07, 0x5b, 0xeb, 0xc2, 0x1a, 0xca, 0x98, 0x5f, + 0xa4, 0xfb, 0xda, 0x23, 0xf5, 0xe8, 0x63, 0x04, 0xa6, 0x05, 0xa3, 0xca, 0xd6, 0xe2, 0x4a, 0x44, + 0xcb, 0x8f, 0x3d, 0x99, 0x84, 0x12, 0xc1, 0x20, 0x96, 0x28, 0x61, 0x3a, 0xcf, 0xb2, 0xdf, 0x70, + 0x9a, 0x42, 0x1b, 0x41, 0x9d, 0xa7, 0xc9, 0x00, 0x16, 0x87, 0x9b, 0x7f, 0x6a, 0x40, 0x79, 0x2d, + 0xf0, 0x1f, 0x7a, 0x4c, 0x02, 0xaf, 0xfb, 0x7b, 0xb4, 0xbd, 0x79, 0x93, 0xbc, 0x2a, 0x85, 0x00, + 0x57, 0xe1, 0xce, 0x33, 0x2a, 0x14, 0x02, 0x3f, 0x3f, 0xa8, 0x40, 0x7d, 0x3f, 0x8c, 0x68, 0x8b, + 0x95, 0x4b, 0x41, 0xa0, 0x38, 0x84, 0xe5, 0x06, 0x77, 0x32, 0x39, 0xc6, 0x21, 0xac, 0x02, 0x43, + 0xd8, 0x1c, 0xe5, 0x9d, 0x7f, 0x28, 0x62, 0x00, 0x8b, 0xc3, 0x15, 0x81, 0xfd, 0xdd, 0x5c, 0x4f, + 0x1f, 0xe6, 0x3e, 0x51, 0x8e, 0x1a, 0x7a, 0xe7, 0x06, 0x3a, 0xc4, 0xbe, 0x08, 0x67, 0xd3, 0x43, + 0x82, 0xf7, 0x22, 0x55, 0x98, 0xd4, 0xe1, 0xf2, 0x8a, 0xe4, 0x7c, 0x66, 0x5d, 0x9b, 0x73, 0x56, + 0x1a, 0xdf, 0xfc, 0x99, 0x01, 0x25, 0xfc, 0xd7, 0xea, 0x36, 0x29, 0xd3, 0x6c, 0xaa, 0x5b, 0x75, + 0xf1, 0xc8, 0xa3, 0x3e, 0xc4, 0x38, 0x8f, 0x42, 0x5b, 0xbc, 0x08, 0x69, 0x72, 0x24, 0x46, 0x16, + 0xa4, 0xfc, 0x49, 0x2b, 0x14, 0x2b, 0x34, 0x26, 0xe5, 0x6f, 0x5f, 0x61, 0x8a, 0x54, 0x20, 0xb3, + 0xf9, 0x63, 0xbf, 0xfc, 0xa6, 0xbc, 0x1a, 0xc6, 0xf9, 0x43, 0x3a, 0x5f, 0xf3, 0xfc, 0x92, 0x68, + 0xe4, 0x55, 0x18, 0x66, 0x55, 0x5b, 0x2b, 0xe2, 0xc5, 0x0a, 0xad, 0x0a, 0x6c, 0x63, 0xa0, 0xbd, + 0xb0, 0x71, 0x24, 0xf3, 0xb7, 0x72, 0xe9, 0x01, 0x14, 0x5a, 0xc0, 0x09, 0xf7, 0xc6, 0xdb, 0x30, + 0x54, 0x6d, 0x36, 0xfd, 0x47, 0x42, 0x4a, 0xc8, 0x6b, 0x9a, 0x78, 0xfc, 0xf8, 0x09, 0xeb, 0x30, + 0x14, 0xed, 0x81, 0x94, 0x01, 0xc8, 0x3c, 0x94, 0xaa, 0x5b, 0xf5, 0xa5, 0xa5, 0x85, 0xf5, 0xf5, + 0x65, 0xe1, 0x77, 0xfb, 0xa2, 0x1c, 0x1f, 0xcf, 0x73, 0xed, 0x28, 0x6a, 0xf6, 0x71, 0xd3, 0x4b, + 0xe8, 0xc8, 0xbb, 0x00, 0x1f, 0xf8, 0x5e, 0xfb, 0x3e, 0x8d, 0x76, 0x7d, 0x57, 0x74, 0x9e, 0xa9, + 0x14, 0xa3, 0x5f, 0xf3, 0xbd, 0xb6, 0xdd, 0x42, 0x30, 0x6b, 0x7b, 0x82, 0x64, 0x29, 0xff, 0x9b, + 0xbf, 0x9b, 0x83, 0x09, 0x6e, 0x77, 0xf2, 0xe9, 0x3f, 0xb5, 0x5b, 0xeb, 0x6d, 0x6d, 0x6b, 0x5d, + 0x90, 0x62, 0x5e, 0xe9, 0xda, 0x40, 0x1b, 0x6b, 0x17, 0x48, 0x2f, 0x0d, 0xb1, 0xe4, 0xed, 0xc8, + 0x20, 0x7b, 0xea, 0x66, 0xf2, 0xba, 0x1a, 0x22, 0x91, 0x8d, 0x82, 0x2d, 0xb4, 0x34, 0x1e, 0xe6, + 0xef, 0xe4, 0x60, 0x5c, 0xd1, 0x0e, 0x4f, 0xed, 0xc0, 0x7f, 0x4e, 0x1b, 0x78, 0xf9, 0xa2, 0xa0, + 0xf4, 0x6c, 0xa0, 0x71, 0xef, 0xc2, 0x54, 0x0f, 0x49, 0x5a, 0xc9, 0x36, 0x06, 0x51, 0xb2, 0x5f, + 0xe9, 0x7d, 0xfe, 0xe5, 0x1e, 0xb8, 0xf1, 0xf3, 0xaf, 0xfa, 0xde, 0xfc, 0x9d, 0x1c, 0x9c, 0x15, + 0xbf, 0xaa, 0x5d, 0xd7, 0x8b, 0xe6, 0xfd, 0xf6, 0x03, 0x6f, 0xe7, 0xd4, 0xce, 0x45, 0x55, 0x9b, + 0x8b, 0x8a, 0x3e, 0x17, 0x4a, 0x07, 0xfb, 0x4f, 0x89, 0xf9, 0xef, 0x8a, 0x30, 0xdb, 0x8f, 0x80, + 0x19, 0xf1, 0x8a, 0x8d, 0x84, 0x46, 0x7c, 0xca, 0xfe, 0xe4, 0xd6, 0x51, 0xe2, 0xee, 0x90, 0x1b, + 0xc0, 0xdd, 0x61, 0x19, 0xca, 0x58, 0x55, 0x9d, 0x86, 0x6c, 0x10, 0xc2, 0xc4, 0xfd, 0xef, 0xf2, + 0xe1, 0x41, 0xe5, 0x92, 0xc3, 0xca, 0xec, 0x50, 0x14, 0xda, 0xdd, 0xc0, 0x53, 0x78, 0xf4, 0x50, + 0x92, 0x1f, 0x1a, 0x30, 0x81, 0xc0, 0xc5, 0x87, 0xb4, 0x1d, 0x21, 0xb3, 0x82, 0x78, 0x72, 0x89, + 0xa3, 0x2a, 0xea, 0x51, 0xe0, 0xb5, 0x77, 0xf0, 0x5a, 0x28, 0xac, 0x6d, 0xb3, 0x51, 0xf8, 0xab, + 0x83, 0xca, 0x3b, 0x1f, 0x25, 0x52, 0x43, 0xb0, 0x0a, 0x99, 0x59, 0xce, 0x1b, 0x4a, 0xb1, 0xda, + 0x54, 0x33, 0x53, 0x2d, 0x22, 0x5f, 0x82, 0xf3, 0x8b, 0x6d, 0x67, 0xbb, 0x49, 0xe7, 0xfd, 0x76, + 0xe4, 0xb5, 0xbb, 0x7e, 0x37, 0xac, 0x39, 0x8d, 0xbd, 0x6e, 0x27, 0x14, 0x57, 0x97, 0xd8, 0xf3, + 0x46, 0x5c, 0x68, 0x6f, 0xf3, 0x52, 0x85, 0x65, 0x3f, 0x06, 0xe4, 0x2e, 0x4c, 0xf1, 0xa2, 0x6a, + 0x37, 0xf2, 0xeb, 0x0d, 0xa7, 0xe9, 0xb5, 0x77, 0xf0, 0x46, 0xb3, 0x58, 0xbb, 0xc8, 0x2c, 0x45, + 0xa7, 0x1b, 0xf9, 0x76, 0xc8, 0xe1, 0x0a, 0xbf, 0x5e, 0x22, 0xb2, 0x04, 0x93, 0x16, 0x75, 0xdc, + 0xfb, 0xce, 0xe3, 0x79, 0xa7, 0xe3, 0x34, 0xbc, 0x68, 0x1f, 0xed, 0xac, 0x7c, 0xad, 0x72, 0x78, + 0x50, 0x79, 0x26, 0xa0, 0x8e, 0x6b, 0xb7, 0x9c, 0xc7, 0x76, 0x43, 0x14, 0x2a, 0xcc, 0xd2, 0x74, + 0x31, 0x2b, 0xaf, 0x1d, 0xb3, 0x2a, 0xa5, 0x59, 0x79, 0xed, 0xfe, 0xac, 0x12, 0x3a, 0xc9, 0x6a, + 0xdd, 0x09, 0x76, 0x68, 0xc4, 0xaf, 0xfc, 0xe0, 0xb2, 0x71, 0xc5, 0x50, 0x58, 0x45, 0x58, 0x66, + 0xe3, 0xf5, 0x5f, 0x9a, 0x95, 0x42, 0xc7, 0x56, 0xde, 0x56, 0xe0, 0x45, 0x54, 0xed, 0xe1, 0x28, + 0x36, 0x0b, 0xc7, 0x1f, 0x2f, 0x3d, 0xfb, 0x75, 0xb1, 0x87, 0x32, 0xe1, 0xa6, 0x74, 0x72, 0xac, + 0x87, 0x5b, 0x76, 0x2f, 0x7b, 0x28, 0x63, 0x6e, 0x6a, 0x3f, 0xc7, 0xb1, 0x9f, 0x0a, 0xb7, 0x3e, + 0x1d, 0xed, 0xa1, 0x24, 0x2b, 0x6c, 0xd0, 0x22, 0xda, 0x66, 0x2b, 0x5a, 0x5c, 0x79, 0x4e, 0x60, + 0xd3, 0x5e, 0x10, 0x16, 0x72, 0x39, 0x90, 0xc5, 0x76, 0xc6, 0x05, 0x68, 0x9a, 0xf8, 0x83, 0x42, + 0x71, 0xa8, 0x3c, 0x6c, 0x95, 0xf9, 0x92, 0x8f, 0xd8, 0xc2, 0x41, 0x59, 0x6c, 0xfe, 0x7e, 0x0e, + 0x2e, 0x48, 0x71, 0x4c, 0xa3, 0x47, 0x7e, 0xb0, 0xe7, 0xb5, 0x77, 0x4e, 0xb9, 0x54, 0xbd, 0xad, + 0x49, 0xd5, 0x17, 0x52, 0x27, 0x5c, 0xaa, 0x97, 0x47, 0x88, 0xd6, 0xbf, 0x1c, 0x82, 0x67, 0x8f, + 0xa4, 0x22, 0x1f, 0xb2, 0x53, 0xd0, 0xa3, 0xed, 0x68, 0xc9, 0x6d, 0x52, 0x66, 0x54, 0xf9, 0xdd, + 0x48, 0x5c, 0x4d, 0x3f, 0x7f, 0x78, 0x50, 0x99, 0xe6, 0xc1, 0x07, 0xb6, 0xe7, 0x36, 0xa9, 0x1d, + 0xf1, 0x62, 0x6d, 0x9a, 0x7a, 0xa9, 0x19, 0xcb, 0x38, 0xf4, 0x69, 0xa9, 0x1d, 0xd1, 0xe0, 0xa1, + 0xc3, 0x7d, 0xb0, 0x05, 0xcb, 0x3d, 0x4a, 0x3b, 0xb6, 0xc3, 0x4a, 0x6d, 0x4f, 0x14, 0xeb, 0x2c, + 0x7b, 0xa8, 0xc9, 0x6d, 0x85, 0xe5, 0x3c, 0x53, 0xf5, 0xef, 0x3b, 0x8f, 0x85, 0xfe, 0x8a, 0xb7, + 0xa5, 0x0a, 0x4b, 0xee, 0x31, 0xd6, 0x72, 0x1e, 0x5b, 0xbd, 0x24, 0xe4, 0xab, 0x30, 0x23, 0x04, + 0x37, 0x13, 0x62, 0x81, 0xdf, 0x94, 0x3d, 0x2e, 0x20, 0xaf, 0x97, 0x0f, 0x0f, 0x2a, 0xe7, 0x85, + 0xd8, 0xb7, 0x1b, 0x1c, 0x23, 0xb3, 0xd7, 0xd9, 0x5c, 0xc8, 0x3a, 0x3b, 0xc8, 0x52, 0xc3, 0x71, + 0x9f, 0x86, 0xa1, 0xb3, 0xc3, 0x5f, 0xfe, 0x84, 0xb3, 0x95, 0x3a, 0x98, 0x76, 0x8b, 0x97, 0x5b, + 0x7d, 0x29, 0xc9, 0x5d, 0x98, 0xd8, 0xa2, 0xdb, 0xea, 0xfc, 0x0c, 0xc7, 0x5b, 0xbc, 0xfc, 0x88, + 0x6e, 0xf7, 0x9f, 0x9c, 0x14, 0x1d, 0xf1, 0x60, 0x6a, 0x2d, 0xf0, 0x1f, 0xef, 0x33, 0xc3, 0x8d, + 0xb6, 0x69, 0x80, 0x6e, 0x55, 0x23, 0x78, 0xf9, 0x34, 0x9b, 0x68, 0x96, 0x7a, 0x79, 0xed, 0x53, + 0x87, 0x07, 0x95, 0x67, 0x3b, 0x0c, 0x6c, 0x37, 0x05, 0xdc, 0x4e, 0x45, 0x22, 0xf5, 0x72, 0x25, + 0xbf, 0x0a, 0x93, 0x96, 0xdf, 0x8d, 0xbc, 0xf6, 0x4e, 0x3d, 0x0a, 0x9c, 0x88, 0xee, 0x70, 0x41, + 0x9e, 0xf8, 0x6f, 0xa5, 0x4a, 0xf9, 0x35, 0x73, 0xc0, 0x81, 0x76, 0x28, 0xa0, 0x9a, 0x24, 0xd5, + 0x09, 0xcc, 0xef, 0xe7, 0x60, 0x56, 0x4c, 0x83, 0x45, 0x1b, 0x7e, 0xe0, 0x9e, 0xfe, 0x6d, 0xbf, + 0xa8, 0x6d, 0xfb, 0xe7, 0x63, 0x8f, 0xa3, 0xac, 0x4e, 0x1e, 0xb1, 0xeb, 0xff, 0x95, 0x01, 0x97, + 0x8e, 0x22, 0x62, 0xa3, 0x13, 0x7b, 0xd4, 0x95, 0x7a, 0x3c, 0xe7, 0x3a, 0x30, 0x8d, 0xf3, 0x89, + 0xd7, 0xc0, 0xe1, 0x5d, 0x3f, 0x8c, 0xf0, 0x2e, 0x2e, 0xa7, 0xb9, 0x05, 0xd4, 0x7c, 0xbf, 0x89, + 0x72, 0xbe, 0xf6, 0x0a, 0x13, 0xe7, 0x7f, 0x75, 0x50, 0x01, 0x06, 0x5a, 0xc5, 0xa7, 0x45, 0x76, + 0xe6, 0xf3, 0x15, 0x83, 0xb7, 0xcc, 0xa1, 0x8d, 0xbe, 0x1c, 0x7b, 0x74, 0x3f, 0xb4, 0xb2, 0x58, + 0xe3, 0x7d, 0x4b, 0xb5, 0x1b, 0xed, 0xae, 0x05, 0xf4, 0x01, 0x0d, 0x68, 0xbb, 0x41, 0x3f, 0x61, + 0xf7, 0x2d, 0x7a, 0xe7, 0x06, 0x32, 0x4f, 0xfe, 0xef, 0x30, 0x9c, 0xcd, 0x22, 0x63, 0xe3, 0xa2, + 0x68, 0xc4, 0xe9, 0x30, 0xd5, 0xbf, 0x6b, 0xc0, 0x58, 0x9d, 0x36, 0xfc, 0xb6, 0x7b, 0xdb, 0x69, + 0x44, 0xbe, 0x74, 0xb0, 0xb0, 0xb9, 0x64, 0x63, 0x70, 0xfb, 0x01, 0x16, 0x68, 0x76, 0xfe, 0xe7, + 0x07, 0x53, 0x44, 0x1b, 0x3e, 0xba, 0x75, 0x46, 0x6c, 0x4d, 0x26, 0x55, 0xe0, 0x1b, 0x85, 0x56, + 0x29, 0xa9, 0xc1, 0xf8, 0xbc, 0xdf, 0x6e, 0x53, 0xf6, 0x43, 0x71, 0xa8, 0xbc, 0x74, 0x78, 0x50, + 0x99, 0x6d, 0xc8, 0x82, 0xb4, 0x4f, 0xa5, 0x4e, 0x42, 0x6e, 0x41, 0x7e, 0x63, 0xee, 0xb6, 0x98, + 0x03, 0xe9, 0x7a, 0xb6, 0x31, 0x77, 0x1b, 0x6d, 0x5d, 0xa6, 0x3f, 0x8c, 0x77, 0xe7, 0x1e, 0xa8, + 0x37, 0x9a, 0x1b, 0x73, 0xb7, 0xc9, 0x2a, 0x4c, 0x59, 0xf4, 0xeb, 0x5d, 0x2f, 0xa0, 0x62, 0x03, + 0xdc, 0xbf, 0x5d, 0xc5, 0xb9, 0x28, 0x72, 0x39, 0x16, 0xf0, 0x42, 0xa9, 0xdb, 0xdb, 0xad, 0x07, + 0x6a, 0xa8, 0x56, 0x2f, 0x2d, 0xf9, 0x0d, 0x98, 0x59, 0xf0, 0x42, 0xd1, 0x66, 0x7e, 0x95, 0xe8, + 0xe2, 0xab, 0xe2, 0x70, 0x9f, 0xed, 0xf0, 0x99, 0xcc, 0xed, 0xf0, 0x29, 0x37, 0x66, 0x62, 0xf3, + 0x7b, 0x4a, 0x37, 0xed, 0x89, 0x9a, 0x5d, 0x0f, 0xf9, 0x1a, 0x4c, 0xe0, 0xdd, 0x0d, 0xde, 0xae, + 0xa2, 0xc3, 0xef, 0x48, 0x9f, 0x9a, 0x5f, 0xcb, 0xac, 0xf9, 0x22, 0x5e, 0x05, 0xd9, 0x78, 0x47, + 0x8b, 0xce, 0xc1, 0x9a, 0x8d, 0xa0, 0x71, 0x26, 0x1f, 0xc0, 0xa4, 0x38, 0x74, 0x56, 0x1f, 0xac, + 0xef, 0xd2, 0x05, 0x67, 0x5f, 0xb8, 0x14, 0xa0, 0xfe, 0x27, 0x4e, 0x2a, 0xdb, 0x7f, 0x60, 0x47, + 0xbb, 0xd4, 0x76, 0x1d, 0x4d, 0x3c, 0xa7, 0x08, 0xc9, 0x37, 0x60, 0x74, 0xd9, 0xc7, 0x67, 0x24, + 0x14, 0x35, 0x25, 0xe4, 0xf3, 0x45, 0x0c, 0xd5, 0xe4, 0xe0, 0xd4, 0x21, 0xf2, 0xf3, 0x83, 0xca, + 0xdb, 0x27, 0x5d, 0x85, 0x4a, 0x05, 0x96, 0x5a, 0x1b, 0x99, 0x87, 0xe2, 0x16, 0xdd, 0x66, 0xbd, + 0x4d, 0x87, 0x19, 0x49, 0x30, 0x97, 0x17, 0x8f, 0xc4, 0x2f, 0xf5, 0x8d, 0x46, 0x62, 0x98, 0xff, + 0xd6, 0xc0, 0x15, 0x48, 0xae, 0xa1, 0x5b, 0x57, 0xec, 0x2f, 0x8d, 0x96, 0xa5, 0xd3, 0xe9, 0xe8, + 0x1e, 0xcf, 0x1c, 0x85, 0x99, 0xa1, 0xb7, 0x9d, 0x06, 0x8d, 0xe4, 0xed, 0x23, 0x22, 0x3f, 0x40, + 0x88, 0x6a, 0x86, 0x72, 0x1c, 0xf2, 0x05, 0x38, 0xbb, 0x40, 0x1f, 0x7a, 0x0d, 0x5a, 0x8d, 0x22, + 0x1a, 0xf2, 0xde, 0xce, 0x57, 0xf9, 0x33, 0x5d, 0xa9, 0xf6, 0xc2, 0xe1, 0x41, 0xe5, 0xb2, 0x8b, + 0xe5, 0xb6, 0x93, 0x20, 0xd8, 0x0d, 0x47, 0xe5, 0x95, 0xc9, 0xc1, 0xfc, 0x47, 0xb9, 0x64, 0x04, + 0xc8, 0xcb, 0x50, 0xb0, 0xd6, 0xe2, 0xf6, 0xf3, 0x17, 0xb8, 0x54, 0xf3, 0x11, 0x81, 0x7c, 0x19, + 0x66, 0x14, 0x3e, 0xb8, 0x38, 0xa8, 0xcb, 0x1a, 0xc4, 0x3b, 0xf3, 0x22, 0x3e, 0xb9, 0x28, 0x2d, + 0x71, 0x38, 0x46, 0xaa, 0x45, 0xd9, 0x3c, 0x58, 0x67, 0x95, 0x82, 0x05, 0xda, 0xf6, 0x38, 0x6f, + 0xa5, 0xb3, 0x2a, 0x6f, 0x17, 0x11, 0xd2, 0x9d, 0xcd, 0xe2, 0x40, 0xe6, 0xa0, 0xb8, 0xe0, 0x85, + 0xcc, 0x22, 0x70, 0x85, 0x7f, 0x16, 0x8f, 0xdc, 0x12, 0x30, 0x2d, 0x72, 0x4b, 0xc0, 0xcc, 0xbf, + 0x35, 0x94, 0x08, 0xf9, 0x53, 0x7a, 0xd6, 0xbc, 0xa9, 0x9d, 0x35, 0x67, 0x05, 0x69, 0xdc, 0x2b, + 0x56, 0x96, 0xa9, 0x1f, 0x4c, 0xc2, 0xb8, 0x86, 0x84, 0xee, 0xae, 0x1b, 0x21, 0x0d, 0xf8, 0x6d, + 0xe2, 0x27, 0xcb, 0xdd, 0x35, 0xee, 0xd7, 0x40, 0x5e, 0x8c, 0x3f, 0x35, 0x60, 0x32, 0x45, 0xc1, + 0x46, 0x83, 0x81, 0xd4, 0xd1, 0xe8, 0x86, 0x34, 0xb0, 0x10, 0xca, 0x9d, 0xe3, 0x96, 0x75, 0xe7, + 0xb8, 0xa6, 0xc5, 0x60, 0xe4, 0xf3, 0x30, 0xb4, 0x81, 0xba, 0xbf, 0xee, 0x5f, 0x11, 0xf3, 0xc7, + 0x42, 0xbe, 0x1f, 0xbb, 0xec, 0x5f, 0x55, 0x9c, 0x60, 0x19, 0xa9, 0xc3, 0xc8, 0x7c, 0x40, 0x31, + 0x16, 0xbe, 0x30, 0xf8, 0x43, 0x58, 0x83, 0x93, 0xa4, 0x1f, 0xc2, 0x04, 0x27, 0xf3, 0xf7, 0x72, + 0x40, 0x92, 0x3e, 0xd2, 0x46, 0x40, 0xa3, 0xf0, 0xd4, 0x4e, 0xfa, 0xfb, 0xda, 0xa4, 0x3f, 0xdb, + 0x33, 0xe9, 0xbc, 0x7b, 0x03, 0xcd, 0xfd, 0x9f, 0x1a, 0x70, 0x2e, 0x9b, 0x90, 0x3c, 0x0f, 0xc3, + 0xab, 0xeb, 0x6b, 0xd2, 0x45, 0x47, 0x74, 0xc5, 0xef, 0xa0, 0x4e, 0x6b, 0x89, 0x22, 0xf2, 0x2a, + 0x0c, 0x7f, 0x68, 0xcd, 0xb3, 0xc3, 0x4e, 0x89, 0x38, 0xf9, 0x7a, 0x60, 0x37, 0x74, 0x63, 0x49, + 0x20, 0xa9, 0x73, 0x9b, 0x7f, 0x6a, 0x73, 0xfb, 0x9d, 0x1c, 0x4c, 0x56, 0x1b, 0x0d, 0x1a, 0x86, + 0x4c, 0x95, 0xa1, 0x61, 0x74, 0x6a, 0x27, 0x36, 0xdb, 0xf9, 0x46, 0xeb, 0xdb, 0x40, 0xb3, 0xfa, + 0xe7, 0x06, 0xcc, 0x48, 0xaa, 0x87, 0x1e, 0x7d, 0xb4, 0xbe, 0x1b, 0xd0, 0x70, 0xd7, 0x6f, 0xba, + 0x83, 0xc6, 0x23, 0xe1, 0x99, 0xee, 0x35, 0x23, 0x1a, 0xa8, 0x57, 0xcb, 0x0f, 0x10, 0xa2, 0x9d, + 0xe9, 0x08, 0x21, 0x37, 0x60, 0xa4, 0xda, 0xe9, 0x04, 0xfe, 0x43, 0xbe, 0xed, 0xc7, 0xc5, 0xbb, + 0x20, 0x07, 0x69, 0xef, 0x88, 0x1c, 0xc4, 0x9a, 0xb1, 0x40, 0xdb, 0xdc, 0xb3, 0x78, 0x9c, 0x37, + 0xc3, 0xa5, 0x6d, 0x55, 0xb7, 0xc2, 0x72, 0xf3, 0xdb, 0x05, 0x18, 0x53, 0x3b, 0x42, 0x4c, 0x18, + 0xe6, 0x6e, 0x22, 0xea, 0x73, 0xbd, 0x83, 0x10, 0x4b, 0x94, 0x24, 0xde, 0x37, 0xb9, 0x63, 0xbd, + 0x6f, 0xb6, 0x60, 0x7c, 0x2d, 0xf0, 0x3b, 0x7e, 0x48, 0x5d, 0x9e, 0xce, 0x84, 0x4b, 0xad, 0xe9, + 0xd8, 0x25, 0x95, 0x8f, 0x39, 0x2b, 0xe2, 0x8a, 0x7c, 0x47, 0x60, 0xdb, 0xe9, 0x64, 0x27, 0x3a, + 0x1f, 0x7e, 0x35, 0xef, 0x84, 0xc2, 0x6d, 0x3f, 0xbe, 0x9a, 0x67, 0x10, 0xfd, 0x6a, 0x9e, 0x41, + 0xd4, 0x6d, 0x31, 0xf4, 0xb4, 0xb6, 0x05, 0xf9, 0x3d, 0x03, 0x46, 0xab, 0xed, 0xb6, 0xf0, 0xbe, + 0x91, 0x31, 0xc1, 0x33, 0xc9, 0xf5, 0x3c, 0x77, 0xcf, 0xe4, 0xb7, 0xf3, 0x5f, 0x11, 0xb7, 0xf3, + 0x6f, 0x7f, 0xa4, 0xdb, 0xf9, 0xf5, 0xc0, 0xf1, 0xa2, 0x10, 0x1f, 0x55, 0x93, 0x0a, 0x55, 0x17, + 0x5c, 0xa5, 0x1d, 0xe4, 0x6d, 0x28, 0xc7, 0xeb, 0x71, 0xa9, 0xed, 0xd2, 0xc7, 0x94, 0x3b, 0x2b, + 0x8d, 0xf3, 0x1c, 0x4b, 0xda, 0xb3, 0x43, 0x1a, 0xd1, 0xfc, 0x8e, 0x01, 0xe7, 0xd4, 0x05, 0x51, + 0xef, 0x6e, 0xb7, 0x3c, 0x34, 0x5c, 0xc8, 0x75, 0x28, 0x89, 0xf9, 0x8a, 0xd5, 0xbe, 0xde, 0x1c, + 0x38, 0x09, 0x0a, 0x59, 0x64, 0x53, 0xc4, 0x78, 0x08, 0x2b, 0x7f, 0x3a, 0xb5, 0xdd, 0x58, 0x51, + 0x6d, 0x56, 0x0c, 0x76, 0x39, 0xc0, 0xdf, 0xfa, 0xdc, 0x31, 0x88, 0xf9, 0x1e, 0x4c, 0xe9, 0xad, + 0xac, 0x53, 0x0c, 0x05, 0x93, 0x5d, 0x33, 0xb2, 0xbb, 0x26, 0xcb, 0xcd, 0x2d, 0x20, 0x3d, 0xf4, + 0x21, 0x3e, 0x31, 0xd1, 0x48, 0x3e, 0x81, 0xca, 0x8b, 0xaa, 0x1e, 0xc4, 0x38, 0xfb, 0xd3, 0xa8, + 0x3a, 0xdc, 0x48, 0x6a, 0xfe, 0xa2, 0x04, 0xd3, 0x19, 0xa2, 0xe3, 0x98, 0xa3, 0xbd, 0xa2, 0x6f, + 0x9e, 0x52, 0xfc, 0x32, 0x2f, 0xb7, 0xcc, 0x7b, 0x32, 0xf3, 0xcf, 0x11, 0x5b, 0xe5, 0xa8, 0x74, + 0x40, 0x1f, 0xc7, 0xf1, 0xae, 0x3a, 0xcf, 0x0c, 0x3d, 0x35, 0xe7, 0x99, 0x1a, 0x8c, 0x8b, 0x5e, + 0x89, 0xad, 0x3c, 0x9c, 0x18, 0xf4, 0x01, 0x2f, 0xb0, 0x7b, 0xb6, 0xb4, 0x4e, 0xc2, 0x79, 0x84, + 0x7e, 0xf3, 0x21, 0x15, 0x3c, 0x46, 0x54, 0x1e, 0x58, 0x90, 0xc9, 0x43, 0x21, 0x21, 0x7f, 0x64, + 0x00, 0x11, 0x10, 0x75, 0x3f, 0x17, 0x8f, 0xda, 0xcf, 0xee, 0xd3, 0xd9, 0xcf, 0xcf, 0xca, 0x36, + 0x66, 0xef, 0xeb, 0x8c, 0x66, 0x91, 0x7f, 0x6e, 0xc0, 0x14, 0xf7, 0xe0, 0x50, 0x1b, 0x5b, 0x3a, + 0xaa, 0xb1, 0x8d, 0xa7, 0xd3, 0xd8, 0x4b, 0x21, 0x56, 0xdb, 0xa7, 0xad, 0xbd, 0x8d, 0x22, 0x5f, + 0x02, 0x88, 0x77, 0x94, 0xf4, 0x14, 0xbc, 0x94, 0x21, 0x05, 0x62, 0xa4, 0x24, 0xd8, 0x31, 0x8a, + 0xe9, 0x54, 0xdf, 0x9a, 0x84, 0x1b, 0xf9, 0x0d, 0x38, 0xcb, 0xf6, 0x4b, 0x0c, 0x11, 0xfe, 0x66, + 0xb3, 0xa3, 0x58, 0xcb, 0xeb, 0xfd, 0x8f, 0xf6, 0xeb, 0x59, 0x64, 0x3c, 0x5e, 0x23, 0x09, 0x27, + 0x8f, 0x5a, 0xaa, 0x81, 0x98, 0x45, 0x81, 0x8e, 0xa5, 0xd8, 0xfa, 0x70, 0x76, 0x0c, 0xeb, 0xcc, + 0x94, 0x6f, 0x17, 0xe4, 0x5e, 0xe0, 0xf2, 0x2d, 0xd4, 0x03, 0x2e, 0x10, 0x44, 0x3e, 0x04, 0x52, + 0xef, 0xee, 0xec, 0xd0, 0x30, 0xa2, 0x2e, 0x87, 0xd1, 0x20, 0x9c, 0x1d, 0x47, 0xf9, 0x80, 0x17, + 0x4c, 0xa1, 0x2c, 0xb5, 0x03, 0x59, 0xac, 0x2e, 0x92, 0x5e, 0xe2, 0x8b, 0xdb, 0x70, 0xa1, 0x6f, + 0x37, 0x33, 0x82, 0x29, 0x6e, 0xe8, 0xc1, 0x14, 0x17, 0xfa, 0x89, 0xc3, 0x50, 0x0d, 0xa8, 0xf8, + 0xc7, 0x46, 0x4a, 0xfe, 0x09, 0x65, 0x85, 0x27, 0x49, 0xeb, 0x77, 0x40, 0xe4, 0x30, 0xd0, 0x9c, + 0x4b, 0xc8, 0x5c, 0xa2, 0x24, 0x31, 0x09, 0xa9, 0x4a, 0x58, 0x94, 0x95, 0x4f, 0x28, 0x0a, 0xcd, + 0x7f, 0x6d, 0x00, 0xe1, 0x2d, 0x9c, 0x77, 0x3a, 0xce, 0xb6, 0xd7, 0xf4, 0x22, 0x8f, 0x86, 0xe4, + 0x1e, 0x94, 0x05, 0x0b, 0x66, 0xb6, 0xab, 0x7e, 0x52, 0xe2, 0xe9, 0x35, 0x2e, 0xb3, 0xd3, 0x6a, + 0x4d, 0x0f, 0x61, 0x9f, 0xc9, 0xcb, 0x3d, 0xc1, 0xe4, 0x99, 0x7f, 0x6d, 0xc0, 0x85, 0xde, 0x66, + 0x8b, 0x9a, 0xe3, 0xc1, 0x33, 0x8e, 0x19, 0xbc, 0xac, 0x5e, 0xe6, 0xf0, 0x22, 0xe3, 0xa9, 0xf5, + 0x32, 0x9f, 0xdc, 0x81, 0x9e, 0xbc, 0x97, 0xbf, 0x9d, 0x83, 0xb1, 0xb5, 0x66, 0x77, 0xc7, 0x6b, + 0x2f, 0x38, 0x91, 0x73, 0x6a, 0x4d, 0x8a, 0xb7, 0x34, 0x93, 0x22, 0xf6, 0xa5, 0x8a, 0x3b, 0x36, + 0x58, 0xc2, 0x2a, 0x03, 0x26, 0x13, 0x12, 0xbe, 0x4b, 0xef, 0x42, 0x81, 0xfd, 0x10, 0x1a, 0xca, + 0xe5, 0x1e, 0xc6, 0x88, 0x75, 0x3d, 0xfe, 0x4f, 0x28, 0xf9, 0x7a, 0x9a, 0x30, 0xe4, 0x70, 0xf1, + 0x33, 0x3c, 0xcb, 0xcf, 0xc9, 0x33, 0x12, 0xfe, 0x89, 0x01, 0xe5, 0x74, 0x4f, 0xc8, 0x3d, 0x18, + 0x61, 0x9c, 0xbc, 0x38, 0x63, 0xd0, 0x0b, 0x7d, 0xfa, 0x7c, 0x5d, 0xa0, 0xf1, 0xe6, 0xe1, 0xe0, + 0x53, 0x0e, 0xb1, 0x24, 0x87, 0x8b, 0x16, 0x8c, 0xa9, 0x58, 0x19, 0xad, 0x7b, 0x45, 0x17, 0x4d, + 0xe7, 0xb2, 0xc7, 0x41, 0x6d, 0xf5, 0x1f, 0x68, 0xad, 0x16, 0x42, 0x69, 0xd0, 0xd4, 0x6f, 0x18, + 0x1a, 0xc6, 0x33, 0x62, 0xa8, 0xeb, 0x4c, 0x26, 0xcf, 0xd0, 0x43, 0xc3, 0x38, 0x8c, 0xd9, 0x22, + 0xbc, 0x3e, 0xb1, 0xce, 0xd0, 0x16, 0xe9, 0x20, 0x44, 0xd5, 0x67, 0x39, 0x8e, 0xf9, 0x0f, 0xf3, + 0x70, 0x2e, 0x69, 0x1e, 0x4f, 0x84, 0xb7, 0xe6, 0x04, 0x4e, 0x2b, 0x3c, 0x66, 0x07, 0x5c, 0xe9, + 0x69, 0x1a, 0x86, 0x3e, 0xcb, 0xa6, 0x29, 0x0d, 0x32, 0x53, 0x0d, 0x42, 0x23, 0x8e, 0x37, 0x48, + 0x36, 0x83, 0xdc, 0x83, 0x7c, 0x9d, 0x46, 0x22, 0x40, 0xf2, 0xa5, 0x9e, 0x51, 0x55, 0xdb, 0x75, + 0xbd, 0x4e, 0x23, 0x3e, 0x89, 0xdc, 0xc7, 0x9c, 0x6a, 0x3e, 0xdf, 0x4c, 0x1d, 0xdf, 0x82, 0xe1, + 0xc5, 0xc7, 0x1d, 0xda, 0x88, 0x44, 0x5c, 0xe4, 0xd5, 0xa3, 0xf9, 0x71, 0x5c, 0x25, 0xfa, 0x92, + 0x22, 0x40, 0x1d, 0x2c, 0x8e, 0x72, 0xf1, 0x4d, 0x28, 0xca, 0xca, 0x4f, 0x14, 0x45, 0xf8, 0x16, + 0x8c, 0x2a, 0x95, 0x9c, 0x68, 0xd1, 0xff, 0xc2, 0x80, 0x61, 0x26, 0xf4, 0x36, 0x5f, 0x3f, 0xa5, + 0x12, 0xe9, 0x96, 0x26, 0x91, 0xa6, 0x94, 0x70, 0x17, 0xdc, 0x97, 0xaf, 0x1f, 0x23, 0x8b, 0x0e, + 0x0c, 0x80, 0x04, 0x99, 0xdc, 0x81, 0x11, 0xfe, 0xec, 0x23, 0xb3, 0x4c, 0xaa, 0xf1, 0x33, 0xa2, + 0x24, 0xd1, 0x72, 0xfc, 0x4e, 0x5a, 0x2d, 0x94, 0xd4, 0x64, 0x21, 0xf1, 0x31, 0x56, 0x03, 0x36, + 0x19, 0x9b, 0x79, 0xbf, 0xcd, 0xe3, 0x29, 0x42, 0x25, 0x1b, 0x53, 0xb6, 0xb3, 0x71, 0x55, 0x5c, + 0x6c, 0xe4, 0x8f, 0x62, 0x72, 0x4e, 0x30, 0xc9, 0xbe, 0xf3, 0xf8, 0x13, 0xe0, 0x11, 0x0a, 0xb2, + 0x61, 0xef, 0xc2, 0xd8, 0x6d, 0x3f, 0x78, 0xe4, 0x04, 0x6e, 0x75, 0x87, 0x0a, 0xef, 0xf0, 0x22, + 0xba, 0x78, 0x8f, 0x3f, 0xe0, 0x70, 0xdb, 0x61, 0x05, 0x3f, 0x3f, 0xa8, 0x14, 0x6a, 0xbe, 0xdf, + 0xb4, 0x34, 0x74, 0xb2, 0x0a, 0xe3, 0xf7, 0x9d, 0xc7, 0xe2, 0x75, 0x6f, 0x7d, 0x7d, 0x59, 0x78, + 0xa5, 0x5c, 0x3d, 0x3c, 0xa8, 0x5c, 0x68, 0x39, 0x8f, 0xe3, 0x57, 0xc1, 0xfe, 0x6e, 0xd0, 0x3a, + 0x3d, 0xf1, 0x60, 0x62, 0xcd, 0x0f, 0x22, 0x51, 0x09, 0xd3, 0x69, 0xf3, 0x7d, 0x1e, 0xe7, 0x6e, + 0x64, 0x3e, 0xce, 0x5d, 0x60, 0x8a, 0xbc, 0xfd, 0x20, 0x26, 0xd7, 0xc2, 0xea, 0x34, 0xc6, 0xe4, + 0x5d, 0x98, 0x9a, 0xa7, 0x41, 0xe4, 0x3d, 0xf0, 0x1a, 0x4e, 0x44, 0x6f, 0xfb, 0x41, 0xcb, 0x89, + 0xc4, 0x85, 0x0a, 0x1a, 0xd4, 0x0d, 0xca, 0x39, 0xb5, 0x9c, 0xc8, 0xea, 0xc5, 0x24, 0x5f, 0xce, + 0xf2, 0xf3, 0x19, 0xc2, 0xee, 0xbf, 0xca, 0x94, 0x82, 0x0c, 0x3f, 0x9f, 0x3e, 0x43, 0x90, 0xe1, + 0xf1, 0xb3, 0x73, 0xd4, 0x23, 0x69, 0xb1, 0x76, 0x53, 0x3c, 0xd8, 0x1e, 0xff, 0x08, 0x1a, 0xcf, + 0x5b, 0x9f, 0xc7, 0xd0, 0x39, 0xc8, 0xd7, 0xd6, 0x6e, 0xe3, 0x15, 0x89, 0x78, 0x94, 0xa4, 0xed, + 0x5d, 0xa7, 0xdd, 0x40, 0x5d, 0x46, 0x78, 0x3a, 0xa8, 0x02, 0xaf, 0xb6, 0x76, 0x9b, 0x38, 0x30, + 0xbd, 0x46, 0x83, 0x96, 0x17, 0x7d, 0xe1, 0xe6, 0x4d, 0x65, 0xa2, 0x8a, 0xd8, 0xb4, 0x1b, 0xa2, + 0x69, 0x95, 0x0e, 0xa2, 0xd8, 0x8f, 0x6f, 0xde, 0xcc, 0x9c, 0x8e, 0xb8, 0x61, 0x59, 0xbc, 0xc8, + 0x22, 0x4c, 0xdc, 0x77, 0x1e, 0x8b, 0xe7, 0xeb, 0xd8, 0xc6, 0xcb, 0xa3, 0x57, 0x3c, 0x2e, 0xac, + 0x46, 0x52, 0xa4, 0x4e, 0xb1, 0x4e, 0x44, 0xde, 0x81, 0xd1, 0x64, 0x79, 0x85, 0xf8, 0x70, 0x99, + 0xe7, 0x0e, 0x94, 0xca, 0xe2, 0xd4, 0xee, 0x92, 0x14, 0x74, 0xb2, 0x11, 0x9b, 0xe8, 0x5c, 0x21, + 0x45, 0xb7, 0xc2, 0x52, 0xed, 0x86, 0x6a, 0xa2, 0x3b, 0x58, 0xa2, 0x75, 0x6b, 0x32, 0x56, 0xd1, + 0xb9, 0x5f, 0x8d, 0xa5, 0x73, 0x51, 0x2c, 0xff, 0xb5, 0xc0, 0x6f, 0x75, 0x22, 0xf4, 0x2f, 0x4c, + 0x59, 0xfe, 0x1d, 0x2c, 0xc9, 0xb0, 0xfc, 0x39, 0x49, 0xf6, 0xab, 0xfc, 0xf8, 0x13, 0xbc, 0xca, + 0x53, 0x28, 0x2c, 0xfb, 0x8d, 0x3d, 0x74, 0x28, 0x2c, 0xd5, 0x3e, 0x64, 0xf2, 0xa3, 0xe9, 0x37, + 0xf6, 0x9e, 0xde, 0x6b, 0x32, 0xb2, 0x27, 0x2b, 0xac, 0xef, 0x6c, 0x59, 0x89, 0xaa, 0x67, 0x27, + 0xb5, 0x97, 0x36, 0xad, 0x8c, 0x2b, 0x2a, 0x7c, 0x15, 0xca, 0x8e, 0x58, 0x3a, 0x39, 0xa1, 0x50, + 0x5e, 0xa0, 0xe1, 0x5e, 0xe4, 0x77, 0xe6, 0x9b, 0x5e, 0x67, 0xdb, 0x77, 0x02, 0x77, 0xb6, 0xdc, + 0x47, 0x60, 0xbc, 0x9c, 0x29, 0x30, 0xa6, 0x5c, 0x4e, 0x6f, 0x37, 0x24, 0x03, 0xab, 0x87, 0xa5, + 0xf9, 0xa5, 0x54, 0xb3, 0xc9, 0x12, 0x8c, 0x08, 0x24, 0x71, 0x30, 0xf4, 0x56, 0xf7, 0x6c, 0x66, + 0x75, 0x23, 0xa2, 0x3a, 0x4b, 0xd2, 0x9b, 0x7f, 0x36, 0x0a, 0x13, 0xba, 0x08, 0x67, 0x3a, 0xd5, + 0xb2, 0xbf, 0xe3, 0xb5, 0xa5, 0x65, 0xc6, 0x93, 0x34, 0x20, 0x44, 0x4b, 0xf6, 0x8d, 0x10, 0xf2, + 0x22, 0x40, 0xfc, 0xf8, 0x28, 0x8d, 0x2f, 0x91, 0x9a, 0x5c, 0x29, 0x20, 0xbf, 0x02, 0xb0, 0xe2, + 0xbb, 0x34, 0xce, 0xf3, 0x71, 0xc4, 0x95, 0xc9, 0xcb, 0xe2, 0xca, 0x44, 0xa4, 0x13, 0x3f, 0x3c, + 0xa8, 0xcc, 0xb4, 0x7d, 0x97, 0xf6, 0x26, 0xf8, 0x50, 0x38, 0x92, 0xcf, 0xc1, 0x90, 0xd5, 0x6d, + 0x52, 0x99, 0x76, 0x62, 0x54, 0x4e, 0x69, 0xb7, 0xa9, 0xa4, 0x19, 0x0c, 0xba, 0xe9, 0x9b, 0x72, + 0x06, 0x20, 0xef, 0x03, 0xdc, 0xeb, 0x6e, 0xd3, 0x3b, 0x81, 0xdf, 0xed, 0xc8, 0xb8, 0x56, 0x34, + 0xd4, 0xf6, 0xe2, 0x24, 0x45, 0xf6, 0x0e, 0x16, 0xaa, 0x95, 0x27, 0x24, 0x64, 0x15, 0x46, 0xc4, + 0x06, 0x11, 0x37, 0xd1, 0xcf, 0x65, 0xdd, 0x81, 0x28, 0xa7, 0xa4, 0xc8, 0x03, 0x81, 0x60, 0xfd, + 0x5a, 0x82, 0x1b, 0x9a, 0xef, 0x40, 0x89, 0xb1, 0x67, 0xc6, 0x64, 0x28, 0xa4, 0x23, 0xfa, 0xd3, + 0x29, 0x0d, 0x62, 0x86, 0xa7, 0x96, 0x8d, 0x2a, 0x26, 0x20, 0x5f, 0xc6, 0xcc, 0x2d, 0x62, 0xa8, + 0x8f, 0xbc, 0x4a, 0x7b, 0xa9, 0x67, 0xa8, 0xcf, 0x3a, 0x9d, 0x4e, 0x46, 0xaa, 0xab, 0x98, 0x1f, + 0xd9, 0x89, 0x63, 0x4e, 0xe2, 0x5c, 0xb3, 0x47, 0x54, 0x70, 0xad, 0xa7, 0x82, 0x59, 0x19, 0x46, + 0xd1, 0x9b, 0xaf, 0x45, 0xe3, 0x4b, 0x3a, 0x50, 0x4e, 0x92, 0x44, 0x89, 0xba, 0xe0, 0xa8, 0xba, + 0x5e, 0xed, 0xa9, 0x4b, 0x9d, 0xc0, 0x9e, 0xea, 0x7a, 0xb8, 0x13, 0x37, 0xc9, 0x0b, 0x2a, 0xea, + 0x1b, 0x3d, 0xaa, 0xbe, 0x17, 0x7b, 0xea, 0x9b, 0x76, 0xb7, 0x7b, 0xeb, 0x49, 0xf1, 0x24, 0xef, + 0xc0, 0xb8, 0x84, 0xe0, 0xfe, 0xc0, 0x2b, 0x2c, 0xa1, 0xc1, 0xba, 0xdb, 0xe8, 0x44, 0xa5, 0x27, + 0x2b, 0x51, 0x91, 0x55, 0x6a, 0xbe, 0x3a, 0xc6, 0x35, 0xea, 0xf4, 0xaa, 0xd0, 0x91, 0xc9, 0x17, + 0x61, 0x74, 0xa9, 0xc5, 0x3a, 0xe2, 0xb7, 0x9d, 0x88, 0xa2, 0xb8, 0x4d, 0xae, 0x05, 0x95, 0x12, + 0x65, 0xa9, 0xf2, 0xac, 0x80, 0x49, 0x91, 0x7a, 0x5c, 0x29, 0x14, 0x6c, 0xf0, 0xf8, 0x05, 0x83, + 0x58, 0xc3, 0xa1, 0x10, 0xae, 0xcf, 0x66, 0x5c, 0xcd, 0x29, 0xec, 0xf1, 0x48, 0xe5, 0xf7, 0x16, + 0xb6, 0xd8, 0x10, 0xda, 0xe0, 0xe9, 0x3c, 0xc9, 0xbb, 0x30, 0x2a, 0xe2, 0xf5, 0xaa, 0xd6, 0x4a, + 0x38, 0x5b, 0xc6, 0xce, 0x63, 0xa6, 0x31, 0x19, 0xda, 0x67, 0x3b, 0x41, 0xea, 0x7d, 0x26, 0xc1, + 0x27, 0x5f, 0x80, 0xb3, 0x5b, 0x5e, 0xdb, 0xf5, 0x1f, 0x85, 0x42, 0xfe, 0x09, 0x41, 0x37, 0x95, + 0xf8, 0xac, 0x3c, 0xe2, 0xe5, 0xb6, 0x14, 0xcc, 0x3d, 0x82, 0x2f, 0x93, 0x03, 0xf9, 0xf5, 0x1e, + 0xce, 0x7c, 0x05, 0x91, 0xa3, 0x56, 0xd0, 0x5c, 0xcf, 0x0a, 0xea, 0xad, 0x3e, 0xbd, 0x9c, 0x32, + 0xab, 0x31, 0xff, 0x26, 0x0f, 0xe7, 0xfb, 0x08, 0x9b, 0xe4, 0xcd, 0xd0, 0x38, 0xf6, 0xcd, 0xf0, + 0x2b, 0x6c, 0x73, 0x3b, 0x5e, 0x2b, 0x5c, 0xf7, 0x93, 0x97, 0x92, 0xe4, 0x7a, 0x15, 0xcb, 0x64, + 0xe0, 0xbe, 0x0c, 0x32, 0xbf, 0xd0, 0x40, 0x0a, 0x3b, 0xf2, 0x7b, 0x2e, 0xb3, 0x74, 0x66, 0x3d, + 0xaf, 0x76, 0xf9, 0x5f, 0x92, 0x57, 0x3b, 0xfd, 0xae, 0xbc, 0xf0, 0x54, 0xef, 0xca, 0xb3, 0x6f, + 0xef, 0x86, 0x9e, 0xe4, 0x8e, 0xf2, 0x3f, 0xa6, 0xde, 0x09, 0x7f, 0x19, 0xa7, 0xfa, 0x2a, 0x0c, + 0x6d, 0xed, 0xd2, 0x40, 0x3a, 0x8a, 0x62, 0x43, 0x1e, 0x31, 0x80, 0xda, 0x10, 0xc4, 0x30, 0xbf, + 0x01, 0x63, 0x6a, 0x65, 0xa4, 0x02, 0x43, 0xf8, 0x5b, 0x98, 0xfe, 0xf8, 0x4a, 0x87, 0xf5, 0x5a, + 0x1c, 0x7e, 0x6c, 0x9a, 0x9e, 0x64, 0x14, 0xf2, 0xc7, 0x8d, 0x82, 0xf9, 0x67, 0x06, 0x14, 0x30, + 0x4a, 0xf9, 0x0d, 0x28, 0xc9, 0x3b, 0x1c, 0x35, 0x72, 0x77, 0x5a, 0x5e, 0xf1, 0x84, 0xfa, 0x43, + 0xab, 0x00, 0xb2, 0xaa, 0x36, 0x69, 0xb0, 0xad, 0xbd, 0xc7, 0x3f, 0x64, 0x00, 0xb5, 0x2a, 0xc4, + 0x38, 0xc1, 0x90, 0xa0, 0xcf, 0x81, 0x30, 0x3c, 0x0a, 0xc8, 0x97, 0xfb, 0x1c, 0xf4, 0x18, 0x1c, + 0x12, 0xcb, 0xfc, 0x81, 0x01, 0x33, 0x99, 0xe2, 0x9b, 0xd5, 0xca, 0xcf, 0x09, 0x65, 0x45, 0xa4, + 0x0f, 0x09, 0x8e, 0x71, 0x12, 0xdf, 0x82, 0x13, 0x4c, 0xef, 0xa7, 0xa0, 0x14, 0x6b, 0xa5, 0xe4, + 0xac, 0x9c, 0x3a, 0x34, 0xf4, 0x65, 0x5a, 0xa5, 0x5f, 0x18, 0x30, 0xcc, 0x9a, 0x70, 0x6a, 0x9d, + 0xc4, 0xb3, 0xaf, 0x7d, 0x58, 0x97, 0x06, 0x72, 0x0d, 0xff, 0xe1, 0x30, 0x40, 0x82, 0x4c, 0xb6, + 0x61, 0x62, 0x75, 0x69, 0x61, 0x7e, 0xc9, 0xa5, 0xed, 0x08, 0x9f, 0x1f, 0x52, 0xc1, 0xc2, 0x8b, + 0x8f, 0x23, 0x1a, 0xb4, 0x9d, 0xa6, 0x40, 0xd8, 0x4f, 0xb6, 0xa7, 0xef, 0xb9, 0x0d, 0xdb, 0x8b, + 0xe9, 0xd4, 0x73, 0x54, 0xe7, 0xc8, 0xea, 0xa8, 0x57, 0xef, 0x2f, 0x2b, 0x75, 0xe4, 0x06, 0xac, + 0x23, 0x74, 0x5a, 0xcd, 0x3e, 0x75, 0xe8, 0x1c, 0xc9, 0x2e, 0x94, 0xef, 0xa0, 0xec, 0x56, 0x6a, + 0xc9, 0x1f, 0x5d, 0xcb, 0xf3, 0xa2, 0x96, 0x67, 0xb8, 0xd0, 0xcf, 0xae, 0xa7, 0x87, 0x6b, 0xb2, + 0x72, 0x0b, 0xc7, 0xae, 0xdc, 0xdf, 0x32, 0x60, 0x98, 0x1f, 0x0e, 0x71, 0x0e, 0xfa, 0xcc, 0xe3, + 0x67, 0xeb, 0xe9, 0x1c, 0x3f, 0xe5, 0x08, 0xff, 0x53, 0xed, 0x26, 0x5e, 0x46, 0x16, 0x52, 0x09, + 0xed, 0xe5, 0xdd, 0x1e, 0xea, 0x13, 0xbc, 0x24, 0xf1, 0xd0, 0xe0, 0xb9, 0xec, 0x55, 0x2e, 0x1c, + 0x43, 0xfd, 0x9c, 0xd6, 0xc8, 0x13, 0x7e, 0x4e, 0x6b, 0x19, 0x4a, 0xc2, 0xe5, 0xa0, 0xb6, 0x2f, + 0xac, 0x06, 0x69, 0x56, 0xc6, 0x70, 0x25, 0x23, 0x2e, 0x07, 0xd9, 0xdb, 0x5a, 0x3e, 0xab, 0x18, + 0x91, 0xac, 0x42, 0x29, 0xf1, 0x70, 0x2f, 0x69, 0x0f, 0x34, 0x31, 0x5c, 0xf8, 0xe4, 0xf1, 0x20, + 0xaa, 0x4c, 0x87, 0xf6, 0x84, 0x87, 0xf9, 0x6d, 0x03, 0xca, 0xe9, 0xf5, 0x42, 0xde, 0x81, 0xd1, + 0x38, 0xc8, 0x20, 0x7e, 0xf8, 0xc4, 0x1b, 0x96, 0x24, 0x2a, 0x41, 0x7b, 0x02, 0x55, 0xd1, 0xc9, + 0x1c, 0x14, 0xd9, 0xb6, 0x53, 0x12, 0x9a, 0xa2, 0x3c, 0xe9, 0x0a, 0x98, 0xfa, 0xe0, 0x20, 0xf1, + 0x94, 0x5d, 0xfb, 0x9f, 0xf2, 0x30, 0xaa, 0x4c, 0x16, 0xb9, 0x0a, 0xc5, 0xa5, 0x70, 0xd9, 0x6f, + 0xec, 0x51, 0x57, 0xdc, 0x63, 0xe2, 0xd7, 0xd2, 0xbc, 0xd0, 0x6e, 0x22, 0xd0, 0x8a, 0x8b, 0x49, + 0x0d, 0xc6, 0xf9, 0x7f, 0x32, 0x98, 0x2c, 0x97, 0xdc, 0xc1, 0x70, 0x64, 0x19, 0x46, 0xa6, 0x9e, + 0xb0, 0x1a, 0x09, 0xf9, 0x2a, 0x00, 0x07, 0xb0, 0xf9, 0x1d, 0xc0, 0xe3, 0x50, 0x6e, 0xe0, 0x19, + 0x51, 0x41, 0xe4, 0xa9, 0x3d, 0xc4, 0xa5, 0xa0, 0x30, 0xc4, 0x2f, 0x37, 0xf9, 0x8d, 0xbd, 0xc1, + 0xbf, 0xd5, 0x96, 0x7c, 0xb9, 0xc9, 0x6f, 0xec, 0xd9, 0xd9, 0xee, 0x27, 0x2a, 0x4b, 0xf2, 0x1d, + 0x03, 0x2e, 0x5a, 0xb4, 0xe1, 0x3f, 0xa4, 0xc1, 0x7e, 0x35, 0x42, 0x2c, 0xb5, 0xc6, 0xe3, 0x7d, + 0x5d, 0x6e, 0x89, 0x1a, 0x5f, 0x0e, 0x04, 0x17, 0xf4, 0xaa, 0x6f, 0x75, 0x22, 0xfb, 0x88, 0x26, + 0x1c, 0x51, 0xa5, 0xf9, 0x97, 0x86, 0xb2, 0x05, 0xc8, 0x0a, 0x94, 0xe2, 0xc5, 0x22, 0xae, 0x59, + 0x62, 0xe5, 0x48, 0xc2, 0x2d, 0xfa, 0xa0, 0xf6, 0x8c, 0xb8, 0x72, 0x9c, 0x8e, 0x97, 0x9c, 0xb6, + 0x23, 0x24, 0x90, 0x7c, 0x1e, 0x0a, 0x38, 0x55, 0xc7, 0x67, 0xc0, 0x91, 0x47, 0x4d, 0x81, 0xcd, + 0x11, 0xb6, 0x1a, 0x29, 0xc9, 0x6b, 0xe2, 0xf9, 0x39, 0xaf, 0xe5, 0x96, 0x64, 0x20, 0xd6, 0x8e, + 0xf8, 0x8c, 0x49, 0x3c, 0x9e, 0x94, 0xd5, 0xfa, 0x77, 0x0c, 0x98, 0xde, 0x98, 0xbb, 0x6d, 0xd1, + 0x1d, 0x0f, 0x83, 0xf1, 0x3c, 0x1f, 0xdf, 0x86, 0xc8, 0x05, 0xc8, 0x5b, 0xce, 0x23, 0x91, 0xa9, + 0x0e, 0xdd, 0x9d, 0x03, 0xe7, 0x91, 0xc5, 0x60, 0xe4, 0x15, 0x28, 0xdd, 0xa3, 0xfb, 0x77, 0x9d, + 0xb6, 0xdb, 0xa4, 0x22, 0x23, 0x1d, 0xe6, 0x41, 0xd8, 0xa3, 0xfb, 0xf6, 0x2e, 0x42, 0xad, 0x04, + 0x01, 0x1f, 0xbe, 0xba, 0xdb, 0xf7, 0x28, 0x7f, 0x1f, 0x18, 0x13, 0x0f, 0x5f, 0xdd, 0x6d, 0xf4, + 0xa8, 0xe5, 0x25, 0xe6, 0x1f, 0xe5, 0xa1, 0x9c, 0xde, 0xfd, 0xe4, 0x7d, 0x18, 0x5b, 0x73, 0xc2, + 0xf0, 0x91, 0x1f, 0xb8, 0x77, 0x9d, 0x70, 0x57, 0x34, 0x05, 0x6d, 0xba, 0x8e, 0x80, 0xdb, 0xbb, + 0x8e, 0x96, 0x5c, 0x49, 0x23, 0x60, 0x5a, 0xc1, 0xba, 0xf0, 0xe6, 0x55, 0x76, 0x71, 0xe4, 0x47, + 0x9d, 0x54, 0xd2, 0x3c, 0x89, 0x46, 0x5c, 0x98, 0x4c, 0x8d, 0x45, 0xbc, 0x81, 0xe2, 0xb0, 0xa4, + 0xf4, 0x48, 0xf1, 0x0b, 0x98, 0xee, 0xdc, 0x03, 0x4c, 0x3c, 0x23, 0x4b, 0xd4, 0x88, 0x99, 0x14, + 0x11, 0x79, 0x0b, 0x60, 0x63, 0xee, 0x36, 0xc6, 0xaa, 0xd2, 0x40, 0xb8, 0x83, 0xa2, 0x35, 0xcd, + 0x98, 0x34, 0x38, 0x58, 0xb5, 0x1a, 0x12, 0x64, 0xf2, 0x06, 0xe4, 0x79, 0xa0, 0x93, 0x9a, 0x12, + 0xe6, 0xfe, 0xed, 0x2a, 0x8f, 0x0d, 0xe1, 0x6f, 0x81, 0xfa, 0xa5, 0x2a, 0xc3, 0x27, 0xcb, 0x4a, + 0x98, 0xcc, 0xb0, 0x96, 0x4c, 0x43, 0x82, 0xe3, 0xd1, 0x1f, 0x20, 0x5e, 0xe6, 0x5f, 0xe4, 0xa1, + 0x14, 0xd7, 0x49, 0x08, 0xa0, 0x26, 0x26, 0x1e, 0xf2, 0xf0, 0x7f, 0x72, 0x01, 0x8a, 0x52, 0xf9, + 0x12, 0x8f, 0x79, 0x23, 0xa1, 0x50, 0xbc, 0x66, 0x41, 0x6a, 0x59, 0x5c, 0xf1, 0xb2, 0xe4, 0x4f, + 0x72, 0x13, 0x62, 0x15, 0xaa, 0x9f, 0xae, 0x55, 0x60, 0x4b, 0xd9, 0x8a, 0xd1, 0xc8, 0x04, 0xe4, + 0x3c, 0xee, 0x3e, 0x5a, 0xb2, 0x72, 0x9e, 0x4b, 0xde, 0x87, 0xa2, 0xe3, 0xba, 0xd4, 0xb5, 0x9d, + 0x68, 0x80, 0x2f, 0x0c, 0x16, 0x19, 0x37, 0x7e, 0xd6, 0x21, 0x55, 0x35, 0x22, 0x55, 0x28, 0xe1, + 0x07, 0xe6, 0xba, 0xe1, 0x40, 0x5f, 0xa5, 0x4b, 0x38, 0x14, 0x19, 0xd9, 0x46, 0x48, 0x5d, 0xf2, + 0x32, 0x14, 0xd8, 0x12, 0x13, 0x27, 0x65, 0x9c, 0xdc, 0x6b, 0x75, 0x7d, 0x8d, 0x0f, 0xd8, 0xdd, + 0x33, 0x16, 0x22, 0x90, 0x17, 0x20, 0xdf, 0x9d, 0x7b, 0x20, 0xce, 0xc0, 0x72, 0xb2, 0xc0, 0x62, + 0x34, 0x56, 0x4c, 0x6e, 0x41, 0xf1, 0x91, 0x1e, 0xe1, 0x34, 0x93, 0x9a, 0xba, 0x18, 0x3f, 0x46, + 0xac, 0x15, 0x61, 0x98, 0xc7, 0x13, 0x99, 0xcf, 0x01, 0x24, 0x55, 0xf7, 0xbe, 0xb9, 0x9a, 0x5f, + 0x85, 0x52, 0x5c, 0x25, 0x79, 0x16, 0x94, 0x3d, 0xcc, 0xf7, 0x9b, 0x55, 0xda, 0x8b, 0x77, 0xf2, + 0x79, 0x18, 0xe9, 0xb0, 0x59, 0x95, 0x79, 0x28, 0x2d, 0xb6, 0x8d, 0xd9, 0xb6, 0x99, 0x85, 0x11, + 0xb1, 0x6c, 0xb9, 0x2b, 0xb4, 0x25, 0x7f, 0x9a, 0x7f, 0x61, 0x60, 0x4c, 0xb3, 0xd2, 0x4e, 0xf2, + 0x3c, 0x8c, 0x37, 0x02, 0x8a, 0x07, 0xb5, 0xc3, 0x14, 0x46, 0x51, 0xcf, 0x58, 0x02, 0x5c, 0x72, + 0xc9, 0x4b, 0x30, 0x99, 0x24, 0xc6, 0xb4, 0x1b, 0xdb, 0x22, 0xbe, 0x71, 0xcc, 0x1a, 0xef, 0xc8, + 0xcc, 0x98, 0xf3, 0xdb, 0xe8, 0xf6, 0x5c, 0x56, 0x63, 0x89, 0x22, 0x99, 0xe4, 0xb2, 0x64, 0x4d, + 0x2a, 0x70, 0x0c, 0x98, 0x3c, 0x07, 0xc3, 0x8e, 0xb3, 0xd3, 0xf5, 0xb8, 0x0b, 0xe6, 0x98, 0x25, + 0x7e, 0x91, 0x4f, 0xc3, 0x54, 0xe8, 0xed, 0xb4, 0x9d, 0xa8, 0x1b, 0x50, 0xb9, 0xfb, 0x70, 0x49, + 0x8d, 0x5b, 0xe5, 0xb8, 0x40, 0xec, 0x3f, 0xb3, 0x06, 0x53, 0x3d, 0x3b, 0x86, 0xbc, 0xca, 0xad, + 0x14, 0xa1, 0x67, 0x8c, 0x71, 0xa3, 0x8c, 0x09, 0xdb, 0xd4, 0x17, 0x43, 0x39, 0x92, 0xd9, 0x86, + 0x31, 0xf5, 0x9c, 0x38, 0x26, 0xce, 0xf3, 0x1c, 0x7a, 0x6e, 0x71, 0xf9, 0x35, 0x7c, 0x78, 0x50, + 0xc9, 0x79, 0x2e, 0xfa, 0x6b, 0x5d, 0x81, 0xa2, 0xd4, 0x76, 0xd4, 0x6f, 0x1c, 0x08, 0xc5, 0x78, + 0xdf, 0x8a, 0x4b, 0xcd, 0x97, 0x61, 0x44, 0x1c, 0x05, 0x47, 0xa7, 0xb9, 0x35, 0xbf, 0x99, 0x83, + 0x49, 0x8b, 0xb2, 0xed, 0x28, 0xbe, 0x1e, 0xf0, 0x09, 0x4b, 0xe8, 0xa9, 0xf5, 0xed, 0x88, 0xb0, + 0xea, 0x1f, 0x19, 0x30, 0x9d, 0x81, 0xfb, 0x91, 0x72, 0x06, 0xbd, 0x09, 0xa5, 0x05, 0xcf, 0x69, + 0x56, 0x5d, 0x37, 0xf6, 0x40, 0x43, 0xad, 0xd6, 0x65, 0x8b, 0xdf, 0x61, 0x50, 0x55, 0x29, 0x88, + 0x51, 0xc9, 0x35, 0xb1, 0x28, 0x92, 0x1c, 0x65, 0x32, 0x65, 0x28, 0xf0, 0x36, 0x25, 0x09, 0x43, + 0x31, 0xce, 0x87, 0x03, 0x93, 0x47, 0xc6, 0x53, 0x3b, 0x75, 0xd9, 0x71, 0x3e, 0xe9, 0xee, 0x0d, + 0x64, 0x3e, 0x7f, 0x3b, 0x07, 0xe7, 0xb2, 0x09, 0x3f, 0x6a, 0xfa, 0x27, 0x8c, 0x69, 0x57, 0xb2, + 0xb2, 0xa2, 0xda, 0xc3, 0x03, 0xe0, 0x11, 0x3f, 0x41, 0x20, 0x0f, 0x60, 0x7c, 0xd9, 0x09, 0xa3, + 0xbb, 0xd4, 0x09, 0xa2, 0x6d, 0xea, 0x44, 0x03, 0x68, 0xe2, 0xf1, 0x77, 0x3a, 0xf1, 0x08, 0xda, + 0x95, 0x94, 0xe9, 0xef, 0x74, 0x6a, 0x6c, 0xe3, 0x85, 0x52, 0x18, 0x60, 0xa1, 0x7c, 0x1d, 0x26, + 0xeb, 0xb4, 0xe5, 0x74, 0x76, 0xfd, 0x80, 0x0a, 0x1f, 0xac, 0xeb, 0x30, 0x1e, 0x83, 0x32, 0x57, + 0x8b, 0x5e, 0xac, 0xe1, 0x2b, 0x03, 0x91, 0x88, 0x12, 0xbd, 0xd8, 0xfc, 0xfd, 0x1c, 0x9c, 0xaf, + 0x36, 0xc4, 0xb3, 0xae, 0x28, 0x90, 0x8f, 0x59, 0x1f, 0x73, 0xdd, 0xe4, 0x06, 0x94, 0xee, 0x3b, + 0x8f, 0xf1, 0x03, 0xd3, 0xa1, 0x48, 0x22, 0xc2, 0x15, 0x24, 0xe7, 0xb1, 0x1d, 0x5f, 0xdf, 0x59, + 0x09, 0xce, 0xd3, 0xfc, 0x06, 0xb5, 0x09, 0xc3, 0x77, 0xfd, 0xa6, 0x2b, 0x8e, 0x12, 0xe1, 0xee, + 0xb5, 0x8b, 0x10, 0x4b, 0x94, 0x98, 0x7f, 0x6d, 0xc0, 0x44, 0xdc, 0x62, 0x6c, 0xc2, 0xc7, 0x3e, + 0x24, 0xa9, 0xaf, 0x71, 0x97, 0x06, 0xf8, 0x1a, 0xf7, 0xd0, 0x93, 0x8d, 0x84, 0xf9, 0x2f, 0x0d, + 0x98, 0xd2, 0x7b, 0xc9, 0x4e, 0x22, 0xa5, 0x21, 0xc6, 0x80, 0x0d, 0xc9, 0x3d, 0xb5, 0x29, 0xc9, + 0xf7, 0x9d, 0x92, 0x6f, 0xe5, 0x60, 0x34, 0x6e, 0xec, 0x27, 0x2c, 0x40, 0x36, 0xee, 0xd7, 0x40, + 0xee, 0xaf, 0x75, 0x45, 0x56, 0x08, 0x2f, 0xd3, 0xcf, 0xc3, 0xb0, 0xd8, 0x4c, 0x7a, 0x84, 0x4e, + 0xcf, 0xec, 0x26, 0xdf, 0x5a, 0xc4, 0x09, 0x0d, 0x2d, 0x41, 0x87, 0xfe, 0xc5, 0x5b, 0x74, 0x5b, + 0xb8, 0x2b, 0x9c, 0xda, 0x33, 0x2a, 0xdb, 0xbf, 0x38, 0xe9, 0xd8, 0x40, 0xa7, 0xd3, 0x3f, 0x29, + 0x40, 0x39, 0x4d, 0x72, 0x7c, 0x08, 0xf2, 0x5a, 0x77, 0x5b, 0x98, 0xdc, 0x68, 0x93, 0x77, 0xba, + 0xdb, 0x16, 0x83, 0x91, 0x97, 0xa0, 0xb0, 0x16, 0x78, 0x0f, 0x85, 0x8d, 0x8d, 0x2e, 0x2a, 0x9d, + 0xc0, 0x7b, 0xa8, 0x3a, 0xda, 0xb1, 0x72, 0xb4, 0x89, 0x97, 0xeb, 0xca, 0x67, 0x6e, 0xb9, 0x4d, + 0xdc, 0x0c, 0xd3, 0x59, 0x2a, 0x24, 0x1a, 0x3b, 0x2a, 0x6b, 0xd4, 0x09, 0x44, 0xb8, 0xac, 0x10, + 0x67, 0x78, 0x54, 0x6e, 0x23, 0x98, 0xa7, 0xa0, 0xb4, 0x54, 0x24, 0xd2, 0x04, 0xa2, 0xfc, 0x1c, + 0xfc, 0x9b, 0xef, 0xf2, 0xdb, 0x2d, 0x67, 0x55, 0xd6, 0xb6, 0xba, 0x9b, 0x33, 0xf8, 0x3e, 0xcd, + 0xbb, 0xce, 0x35, 0x28, 0xe1, 0xd5, 0x1d, 0x5e, 0xc8, 0x14, 0x8f, 0x65, 0x26, 0x9d, 0x1a, 0x01, + 0x1f, 0x83, 0xed, 0xf8, 0x5a, 0x26, 0x61, 0x42, 0xde, 0x83, 0x51, 0xd5, 0x13, 0x8f, 0xfb, 0x8b, + 0x5d, 0xe2, 0x21, 0x18, 0x7d, 0xb2, 0x39, 0xa9, 0x04, 0xe6, 0x6b, 0xea, 0x2a, 0x11, 0x87, 0xf6, + 0x91, 0xab, 0xc4, 0xfc, 0x3e, 0xaa, 0xf1, 0x2d, 0x3f, 0xa2, 0x42, 0x7b, 0x39, 0xb5, 0x72, 0x2c, + 0xb9, 0x0a, 0x1f, 0xd2, 0x1c, 0x12, 0xb4, 0xde, 0x9d, 0xe0, 0x03, 0xaf, 0xff, 0xd4, 0x80, 0x99, + 0x4c, 0x5a, 0x72, 0x1d, 0x20, 0xd1, 0x11, 0xc5, 0x28, 0xf1, 0xdc, 0x9e, 0x31, 0xd4, 0x52, 0x30, + 0xc8, 0x57, 0xd2, 0xda, 0xdd, 0xf1, 0x87, 0x93, 0xcc, 0x67, 0x3f, 0xa1, 0x6b, 0x77, 0x19, 0x3a, + 0x9d, 0xf9, 0xa3, 0x3c, 0x4c, 0xf5, 0x7c, 0x07, 0xed, 0x98, 0x6f, 0x94, 0xec, 0xa5, 0xbe, 0xb2, + 0xc3, 0x9f, 0x6d, 0xae, 0xf5, 0xfb, 0x0a, 0x5b, 0xc6, 0x37, 0x77, 0xf0, 0x66, 0x4d, 0xa4, 0x95, + 0x3d, 0xe6, 0xd3, 0x3b, 0x61, 0xf6, 0xf7, 0x99, 0x3e, 0xdd, 0xb7, 0xb6, 0xa7, 0xf0, 0x9d, 0xa6, + 0x5f, 0xe2, 0xcf, 0xd8, 0x7c, 0x3f, 0x07, 0xd3, 0x3d, 0x7d, 0x3e, 0xb5, 0xbb, 0xee, 0xf3, 0xda, + 0xe9, 0xf6, 0x5c, 0xbf, 0x39, 0x1d, 0x48, 0x8b, 0xf8, 0x9f, 0x06, 0x9c, 0xef, 0x43, 0x49, 0xf6, + 0xd3, 0x8b, 0x88, 0x6b, 0x15, 0x37, 0x8f, 0xae, 0xf0, 0xa9, 0x2c, 0xa5, 0x8f, 0x6d, 0x25, 0x7c, + 0x33, 0x07, 0xb0, 0x45, 0xb7, 0x4f, 0x77, 0x7e, 0x95, 0xec, 0x6f, 0x71, 0xcb, 0x6e, 0x0d, 0x34, + 0xef, 0xab, 0x78, 0xed, 0x37, 0x78, 0x72, 0x95, 0x38, 0x67, 0x7f, 0x2e, 0x3b, 0x67, 0xbf, 0xb9, + 0x0d, 0x67, 0xef, 0xd0, 0x28, 0x39, 0x09, 0xa5, 0x0d, 0x79, 0x34, 0xdb, 0x57, 0xa0, 0x24, 0xf0, + 0xf5, 0x8c, 0xcd, 0xd2, 0xff, 0xd8, 0x73, 0xad, 0x04, 0xc1, 0xa4, 0x70, 0x7e, 0x81, 0x36, 0x69, + 0x44, 0x3f, 0xde, 0x6a, 0xea, 0x40, 0x78, 0x57, 0x78, 0x2a, 0xf7, 0x81, 0x6a, 0x38, 0x76, 0x7c, + 0x36, 0x61, 0x26, 0x6e, 0xfb, 0xd3, 0xe4, 0x7b, 0x83, 0xe9, 0x12, 0x22, 0x98, 0x29, 0xe1, 0x78, + 0xc4, 0x25, 0xe2, 0x63, 0xb8, 0x28, 0x09, 0xb6, 0xbc, 0xf8, 0x31, 0x67, 0x20, 0x5a, 0xf2, 0x0e, + 0x8c, 0x2a, 0x34, 0x22, 0x32, 0x12, 0x5f, 0x6d, 0x1f, 0x79, 0xd1, 0xae, 0x1d, 0x72, 0xb8, 0xfa, + 0x6a, 0xab, 0xa0, 0x9b, 0x5f, 0x86, 0x67, 0x62, 0xff, 0x9b, 0x8c, 0xaa, 0x53, 0xcc, 0x8d, 0x93, + 0x31, 0x5f, 0x49, 0xba, 0xb5, 0xd4, 0x8e, 0xdd, 0x97, 0x25, 0x6f, 0xa2, 0x76, 0x4b, 0x74, 0xe6, + 0x92, 0x92, 0x77, 0x4a, 0x9c, 0x45, 0x09, 0xc0, 0x7c, 0x5b, 0x69, 0x6c, 0x06, 0x43, 0x8d, 0xd8, + 0x48, 0x13, 0x7f, 0x33, 0x07, 0x93, 0xab, 0x4b, 0x0b, 0xf3, 0xf1, 0x35, 0xf2, 0x27, 0x2c, 0xf9, + 0x8b, 0xd6, 0xb7, 0xfe, 0xf2, 0xc6, 0xdc, 0x80, 0xe9, 0xd4, 0x30, 0xe0, 0x97, 0x2a, 0xde, 0xe3, + 0x7e, 0x32, 0x31, 0x58, 0x9e, 0x2c, 0xe7, 0xb2, 0xd8, 0x6f, 0xde, 0xb2, 0x52, 0xd8, 0xe6, 0x8f, + 0x86, 0x53, 0x7c, 0x85, 0x08, 0x7b, 0x05, 0x4a, 0x4b, 0x61, 0xd8, 0xa5, 0xc1, 0x86, 0xb5, 0xac, + 0xea, 0x88, 0x1e, 0x02, 0xed, 0x6e, 0xd0, 0xb4, 0x12, 0x04, 0x72, 0x15, 0x8a, 0x22, 0x80, 0x46, + 0xca, 0x04, 0x7c, 0xf6, 0x8f, 0xe3, 0x6f, 0xac, 0xb8, 0x98, 0xbc, 0x01, 0x63, 0xfc, 0x7f, 0xbe, + 0xda, 0xc4, 0x80, 0xe3, 0x5d, 0x95, 0x40, 0xe7, 0xab, 0xd3, 0xd2, 0xd0, 0x98, 0x65, 0x26, 0x3f, + 0x85, 0xc7, 0x5a, 0x54, 0x48, 0x2c, 0x33, 0xf9, 0xd5, 0x3c, 0x6c, 0x93, 0x8a, 0x44, 0xae, 0x41, + 0xbe, 0x3a, 0x6f, 0xa9, 0x49, 0x6a, 0x9d, 0x46, 0xc0, 0x93, 0x3c, 0xeb, 0xdf, 0xf7, 0x9f, 0xb7, + 0xc8, 0x1c, 0x14, 0xf1, 0xfb, 0x03, 0x2e, 0x0d, 0x44, 0x1a, 0x08, 0x5c, 0x35, 0x1d, 0x01, 0x53, + 0xdf, 0x06, 0x25, 0x1e, 0xb9, 0x01, 0x23, 0x0b, 0x5e, 0xd8, 0x69, 0x3a, 0xfb, 0x22, 0xeb, 0x03, + 0x3e, 0x86, 0xb8, 0x1c, 0xa4, 0xae, 0x33, 0x81, 0x45, 0xae, 0xc2, 0x50, 0xbd, 0xe1, 0x77, 0x98, + 0xb5, 0x15, 0xbb, 0xe8, 0x84, 0x0c, 0xa0, 0x85, 0x8e, 0x33, 0x00, 0xc6, 0x74, 0xf2, 0xd0, 0x94, + 0x92, 0x12, 0xd3, 0x99, 0x0e, 0x49, 0x11, 0x38, 0xbd, 0x7e, 0x8c, 0xf0, 0x34, 0xfd, 0x18, 0xb7, + 0xe1, 0xfc, 0x1d, 0x54, 0xf5, 0xeb, 0x34, 0xc0, 0xb4, 0x7c, 0xfc, 0xcb, 0x24, 0x1b, 0xd6, 0x92, + 0x08, 0xc7, 0xb9, 0x72, 0x78, 0x50, 0x79, 0x81, 0x5b, 0x03, 0x76, 0xc8, 0x71, 0xe4, 0x47, 0x4d, + 0x52, 0x09, 0xdc, 0xfb, 0x31, 0x22, 0x5f, 0x80, 0xb3, 0x59, 0x45, 0x22, 0x30, 0x07, 0x9d, 0x92, + 0xb3, 0x2b, 0x50, 0xbd, 0x82, 0xb3, 0x38, 0x90, 0x65, 0x28, 0x73, 0x78, 0xd5, 0x6d, 0x79, 0xed, + 0xc5, 0x96, 0xe3, 0x35, 0x31, 0x4c, 0x47, 0xc4, 0x5a, 0x09, 0xae, 0x0e, 0x2b, 0xb4, 0x29, 0x2b, + 0xd5, 0xbc, 0xac, 0x52, 0x94, 0x28, 0x8e, 0xea, 0xd5, 0xfb, 0xcb, 0xc9, 0x9e, 0xfa, 0x64, 0xbd, + 0x1b, 0x69, 0x7d, 0x3b, 0xe2, 0xdd, 0x68, 0x03, 0xa6, 0x53, 0xc3, 0x20, 0xc5, 0x91, 0x06, 0x4e, + 0x8b, 0xa3, 0x14, 0x8d, 0x95, 0xc2, 0x36, 0xff, 0xf3, 0x70, 0x8a, 0xaf, 0xb8, 0x2b, 0x32, 0x61, + 0x98, 0x4b, 0x1b, 0x35, 0x2d, 0x14, 0x97, 0x45, 0x96, 0x28, 0x21, 0x17, 0x20, 0x5f, 0xaf, 0xaf, + 0xaa, 0x49, 0xeb, 0xc2, 0xd0, 0xb7, 0x18, 0x8c, 0xcd, 0x10, 0x5e, 0x03, 0xe5, 0x93, 0x19, 0x6a, + 0xd0, 0x20, 0x12, 0xdf, 0x4a, 0x7c, 0x31, 0xd9, 0xc7, 0x85, 0x64, 0xbc, 0xc5, 0x3e, 0x4e, 0x76, + 0xef, 0x3c, 0xcc, 0x56, 0xc3, 0x90, 0x06, 0x11, 0xcf, 0x91, 0x1d, 0x76, 0x5b, 0x34, 0x10, 0x6b, + 0x4d, 0xc8, 0x18, 0xfe, 0xa5, 0xe5, 0x46, 0x68, 0xf5, 0x45, 0x24, 0x57, 0xa0, 0x58, 0xed, 0xba, + 0x1e, 0x6d, 0x37, 0xa8, 0x90, 0x33, 0x78, 0x19, 0xec, 0x08, 0x98, 0x15, 0x97, 0x92, 0x0f, 0x61, + 0x46, 0x10, 0x49, 0x81, 0x23, 0x46, 0x80, 0xcb, 0x1a, 0x6e, 0xc1, 0x8a, 0xbd, 0x20, 0xc5, 0x94, + 0x2d, 0x86, 0x24, 0x9b, 0x92, 0x54, 0xa1, 0xbc, 0x88, 0xef, 0xa4, 0xf2, 0x8b, 0xa9, 0x7e, 0x20, + 0x72, 0xa1, 0xa2, 0xe4, 0xe2, 0x6f, 0xa8, 0xb6, 0x1b, 0x17, 0x5a, 0x3d, 0xe8, 0xe4, 0x1e, 0x4c, + 0xa7, 0x61, 0x4c, 0x1e, 0x97, 0x92, 0x2f, 0x1a, 0xf5, 0x70, 0x41, 0xc1, 0x9c, 0x45, 0x45, 0xb6, + 0x61, 0xaa, 0x1a, 0x45, 0x81, 0xb7, 0xdd, 0x8d, 0x68, 0x4a, 0x74, 0xc9, 0x8b, 0xc6, 0xb8, 0x5c, + 0x8a, 0xaf, 0x67, 0xc4, 0x62, 0x9c, 0x76, 0x62, 0xca, 0x58, 0x84, 0x59, 0xbd, 0xec, 0x88, 0x1b, + 0x7f, 0x14, 0x4d, 0x7c, 0x38, 0x4c, 0xc4, 0xb3, 0xc8, 0x0b, 0xdd, 0x6a, 0xb8, 0xdf, 0x6a, 0xd1, + 0x28, 0xc0, 0x77, 0x76, 0xfc, 0xb0, 0x98, 0x29, 0x7c, 0x99, 0x2e, 0x2a, 0xdf, 0x02, 0xc4, 0x8f, + 0xc7, 0x69, 0x6e, 0x9e, 0x1a, 0x4f, 0xed, 0xf8, 0x18, 0x1b, 0xf0, 0xf8, 0x68, 0xc2, 0xd4, 0x62, + 0xbb, 0x11, 0xec, 0x63, 0x5c, 0x9a, 0x6c, 0xdc, 0xf8, 0x31, 0x8d, 0x93, 0xdf, 0x19, 0xb8, 0xe4, + 0xc8, 0x15, 0x96, 0xd5, 0xbc, 0x5e, 0xc6, 0xe6, 0xff, 0x07, 0xe5, 0xf4, 0x58, 0x3e, 0xe1, 0x97, + 0x60, 0x4f, 0xe2, 0x62, 0xce, 0x66, 0x3a, 0xdd, 0x17, 0x72, 0x43, 0xfb, 0xdc, 0xa7, 0x91, 0x84, + 0xfd, 0x2a, 0x1f, 0xe6, 0xd4, 0x3e, 0xf2, 0x29, 0xb7, 0x71, 0x2e, 0x6b, 0x1b, 0x9b, 0xbf, 0x9d, + 0x83, 0x29, 0xee, 0x15, 0x7b, 0xfa, 0x75, 0xc5, 0xf7, 0x34, 0xe1, 0x2c, 0xef, 0x02, 0x53, 0xbd, + 0x3b, 0x42, 0x5b, 0xfc, 0x2a, 0xcc, 0xf4, 0x0c, 0x05, 0x0a, 0xe8, 0x05, 0xe9, 0x8f, 0xdc, 0x23, + 0xa2, 0x67, 0xb3, 0x2b, 0xd9, 0xbc, 0x65, 0xf5, 0x50, 0x98, 0xff, 0x2c, 0xd7, 0xc3, 0x5f, 0xe8, + 0x8d, 0xaa, 0x26, 0x68, 0x9c, 0x4c, 0x13, 0xcc, 0x7d, 0x24, 0x4d, 0x30, 0x3f, 0x88, 0x26, 0xf8, + 0x21, 0x8c, 0xaf, 0x53, 0x87, 0x69, 0x34, 0x22, 0xd6, 0xa9, 0xa0, 0x7d, 0x8a, 0x93, 0x95, 0x49, + 0xf9, 0x12, 0xc7, 0x49, 0x46, 0x8c, 0x80, 0x89, 0x16, 0x1e, 0xfc, 0x64, 0xe9, 0x1c, 0xd4, 0x43, + 0x63, 0xa8, 0xff, 0xa1, 0x61, 0x7e, 0x3b, 0x07, 0xa3, 0x0a, 0x7b, 0xf2, 0x3a, 0x8c, 0xad, 0x06, + 0x3b, 0x4e, 0xdb, 0xfb, 0x35, 0x47, 0xb9, 0x7e, 0xc5, 0xe6, 0xfb, 0x0a, 0xdc, 0xd2, 0xb0, 0xd0, + 0x6d, 0x86, 0x3a, 0x2d, 0x75, 0xe1, 0xb3, 0xe6, 0x59, 0x08, 0x55, 0x62, 0x55, 0xf3, 0x03, 0xc4, + 0xaa, 0xea, 0x81, 0x9e, 0x85, 0x93, 0x07, 0x7a, 0x6a, 0x71, 0x99, 0x43, 0x27, 0x8c, 0xcb, 0x34, + 0x7f, 0x37, 0x07, 0x65, 0xf1, 0xd1, 0x4a, 0x79, 0x79, 0xf8, 0xc9, 0x4a, 0x8b, 0xaf, 0x77, 0xee, + 0x88, 0xe7, 0xb1, 0xc2, 0x0f, 0xfe, 0xb0, 0x82, 0x9f, 0x20, 0x4c, 0x0f, 0x87, 0xfc, 0x04, 0xa1, + 0x0e, 0x4f, 0x47, 0x40, 0xa4, 0xa9, 0xac, 0x34, 0xbe, 0xf9, 0x93, 0x5c, 0x9a, 0xb7, 0xd0, 0xa6, + 0x5e, 0x84, 0x11, 0xfe, 0x95, 0x22, 0xe9, 0xa4, 0x2d, 0x92, 0xe3, 0x20, 0xc8, 0x92, 0x65, 0x27, + 0x89, 0x85, 0x39, 0xee, 0x3b, 0x94, 0xe4, 0x4d, 0x18, 0x43, 0x7f, 0x91, 0xaa, 0xeb, 0x06, 0x34, + 0x0c, 0x85, 0xa2, 0x85, 0x6f, 0x77, 0x8f, 0xe8, 0xb6, 0xcd, 0xfd, 0x4a, 0x1c, 0xd7, 0x0d, 0x2c, + 0x0d, 0x8f, 0xcc, 0xc3, 0x59, 0xcd, 0x3d, 0x49, 0xd2, 0x0f, 0x25, 0xa7, 0x45, 0x84, 0x05, 0x9c, + 0x38, 0x13, 0xf9, 0xe9, 0x7d, 0x83, 0xd7, 0xfc, 0x5f, 0x06, 0xdb, 0x6b, 0x8d, 0xbd, 0x4f, 0x58, + 0x94, 0x0e, 0xeb, 0xd2, 0x11, 0xca, 0xfe, 0x5f, 0x18, 0xdc, 0xcf, 0x5e, 0x2c, 0x9f, 0xb7, 0x60, + 0x98, 0x7f, 0x13, 0x49, 0x78, 0x84, 0xab, 0x5c, 0x78, 0x41, 0xf2, 0x3e, 0xc5, 0xbf, 0xac, 0x64, + 0x09, 0x02, 0x66, 0x32, 0xeb, 0xee, 0xfe, 0xa8, 0x78, 0xf6, 0xfa, 0xf9, 0x4b, 0x2c, 0x35, 0xf1, + 0xe3, 0x60, 0x09, 0x85, 0x8d, 0xe3, 0x13, 0x3f, 0x9a, 0xff, 0x27, 0xc7, 0xfb, 0x23, 0x1a, 0x35, + 0x68, 0x46, 0xb3, 0x97, 0xa0, 0x80, 0xdf, 0xd2, 0x54, 0xd2, 0xc6, 0xa5, 0xbe, 0xa3, 0x89, 0xe5, + 0x6c, 0xdf, 0xa0, 0xac, 0x55, 0x03, 0xc3, 0x50, 0x1c, 0xab, 0xfb, 0x06, 0x31, 0x30, 0x5d, 0xaf, + 0xef, 0x52, 0x75, 0x3b, 0xb4, 0xf5, 0xcc, 0xca, 0x58, 0x4e, 0xde, 0x54, 0xbc, 0x90, 0xd5, 0x0b, + 0x8d, 0xd6, 0x03, 0xc7, 0xe6, 0xde, 0xaf, 0xaa, 0xb4, 0x4d, 0x1c, 0x96, 0x17, 0x61, 0x42, 0x0f, + 0x95, 0x15, 0x46, 0x07, 0x46, 0x1c, 0xa7, 0xc2, 0x6c, 0x55, 0xf5, 0x56, 0x27, 0x22, 0x35, 0x18, + 0xd7, 0x02, 0x6b, 0xd5, 0x2c, 0x97, 0x3c, 0xfd, 0x86, 0xdd, 0x1b, 0xc8, 0xaf, 0x93, 0x28, 0x17, + 0xe6, 0xaf, 0x41, 0x59, 0xec, 0xcc, 0x38, 0x46, 0x0f, 0x55, 0xbb, 0xa5, 0x05, 0x4b, 0xdd, 0x4d, + 0x0d, 0xcf, 0x0d, 0x2c, 0x84, 0x9a, 0xdf, 0x33, 0xe0, 0x82, 0xf8, 0xd6, 0x93, 0x45, 0x43, 0xa6, + 0x43, 0x62, 0x60, 0x9f, 0x48, 0x11, 0xf4, 0x8e, 0xcc, 0xec, 0xa3, 0x0b, 0xc8, 0x74, 0x1d, 0xb5, + 0x71, 0xb1, 0x28, 0x87, 0x30, 0xb7, 0x8f, 0xcc, 0xe8, 0xf3, 0x96, 0xc8, 0xe8, 0x93, 0x3b, 0x9a, + 0x38, 0xde, 0x17, 0x2e, 0x6d, 0xcb, 0x4c, 0x3e, 0xdf, 0xcd, 0xc1, 0x4c, 0x46, 0xb3, 0x4e, 0x6d, + 0xe6, 0xa6, 0x9a, 0x26, 0x1c, 0x64, 0xca, 0xb7, 0xbe, 0x03, 0x9f, 0x29, 0x2b, 0xfe, 0xc0, 0x80, + 0xf3, 0xfa, 0xea, 0x11, 0xb6, 0xe8, 0xe6, 0x2d, 0xf2, 0x36, 0x0c, 0xdf, 0xa5, 0x8e, 0x4b, 0x65, + 0x28, 0x49, 0x9c, 0x3e, 0x49, 0xdc, 0x0e, 0xf3, 0x42, 0xce, 0xf6, 0x27, 0x7c, 0x2b, 0x9f, 0xb1, + 0x04, 0x09, 0x59, 0x10, 0x8d, 0xe3, 0xcf, 0x53, 0xa6, 0x7c, 0xa9, 0xc9, 0xaa, 0xea, 0x08, 0xc5, + 0xf8, 0x1b, 0xf0, 0xcc, 0x11, 0x24, 0x6c, 0xde, 0xd8, 0xcc, 0xab, 0xf3, 0x86, 0xe7, 0x0a, 0x42, + 0xc9, 0x7b, 0x30, 0xb9, 0x2e, 0x02, 0xde, 0xe4, 0x6c, 0x28, 0xd9, 0xb3, 0x65, 0x2c, 0x9c, 0x2d, + 0xa7, 0x25, 0x8d, 0x8c, 0xe1, 0x5b, 0x7a, 0xed, 0x4f, 0x3a, 0x28, 0xef, 0x6a, 0x83, 0xf2, 0x4c, + 0xf6, 0xa0, 0xf4, 0x1f, 0x8d, 0x9e, 0x54, 0x00, 0x03, 0x0d, 0x83, 0x09, 0xc3, 0x0b, 0x7e, 0xcb, + 0xf1, 0x64, 0xef, 0xf1, 0x32, 0xc6, 0x45, 0x88, 0x25, 0x4a, 0xcc, 0xff, 0x50, 0x80, 0x0b, 0x3c, + 0x10, 0x84, 0x06, 0x1b, 0xa1, 0xd7, 0xde, 0xd1, 0x1e, 0x6a, 0xd0, 0x3d, 0x4d, 0xc9, 0xe3, 0x2c, + 0xdc, 0xd3, 0x18, 0xc4, 0x12, 0x25, 0xcc, 0x92, 0x60, 0xa2, 0x4f, 0xf1, 0xf4, 0x43, 0x4b, 0x02, + 0xb3, 0xa0, 0xa0, 0x95, 0x1a, 0x17, 0x93, 0x6b, 0x42, 0x30, 0x2b, 0x0e, 0xc4, 0x4c, 0x30, 0xa7, + 0xbe, 0x35, 0xcc, 0x85, 0x73, 0xac, 0xa9, 0x14, 0xfa, 0x68, 0x2a, 0xf7, 0xe1, 0x6c, 0xf2, 0x79, + 0xf5, 0xb5, 0xc0, 0x6b, 0x37, 0xbc, 0x8e, 0xd3, 0x94, 0x9a, 0x2e, 0xff, 0xf2, 0x72, 0xf2, 0x85, + 0xf6, 0x4e, 0x8c, 0x60, 0x65, 0x92, 0xb1, 0x6e, 0x2c, 0xac, 0xd4, 0x79, 0x92, 0x8b, 0x61, 0x64, + 0x81, 0xdd, 0x70, 0xdb, 0x21, 0xcf, 0x72, 0x61, 0xc5, 0xc5, 0xa8, 0x23, 0xa1, 0xc7, 0x3f, 0xff, + 0x3a, 0x3a, 0x0a, 0x59, 0xe9, 0xdf, 0xc4, 0x03, 0x04, 0xc4, 0x17, 0xfd, 0x2d, 0x0d, 0x2f, 0xa1, + 0xe3, 0x5f, 0x63, 0xc7, 0x2b, 0x1d, 0x9d, 0x2e, 0x0c, 0x77, 0x55, 0x3a, 0x8e, 0xc7, 0xec, 0x6f, + 0xee, 0x21, 0x82, 0x73, 0x5d, 0x4a, 0x34, 0x2a, 0xfe, 0x79, 0x74, 0xae, 0x51, 0x29, 0x28, 0xe4, + 0x1d, 0x98, 0x5e, 0x9c, 0x9f, 0x93, 0xce, 0xf6, 0x0b, 0x7e, 0xa3, 0xdb, 0xa2, 0xed, 0x08, 0x43, + 0x35, 0x44, 0xac, 0x13, 0x6d, 0xcc, 0x31, 0x23, 0x2f, 0x0b, 0x8d, 0xbc, 0x01, 0xa4, 0xbe, 0x5e, + 0x97, 0x60, 0x79, 0x92, 0x8c, 0x22, 0xb1, 0x48, 0x96, 0x93, 0x81, 0x20, 0x3c, 0xf5, 0x79, 0xbc, + 0xda, 0xbc, 0xef, 0xd2, 0x70, 0xf3, 0xe6, 0x27, 0xcc, 0x53, 0x5f, 0xe9, 0x1b, 0xee, 0xbf, 0x9b, + 0x99, 0x7b, 0xf5, 0x1f, 0xa0, 0xa7, 0x7e, 0x0f, 0x2e, 0xf9, 0x2c, 0x0c, 0xe1, 0x4f, 0x71, 0xfa, + 0x4d, 0x67, 0xb0, 0x4d, 0x4e, 0xbe, 0x06, 0xc3, 0xb4, 0x38, 0x01, 0x59, 0x4a, 0x32, 0x75, 0x9f, + 0xc0, 0xdf, 0x54, 0x04, 0xbd, 0xea, 0x9f, 0x68, 0x70, 0x61, 0x4c, 0xad, 0x90, 0x2d, 0xad, 0xbb, + 0x4e, 0xb8, 0x4b, 0xdd, 0x79, 0xf9, 0x49, 0xb6, 0x31, 0xbe, 0xb4, 0x76, 0x11, 0x8a, 0x9f, 0x8f, + 0xb0, 0x14, 0x14, 0xf2, 0x3c, 0x0c, 0x2f, 0x85, 0x1b, 0xa1, 0x68, 0x8a, 0xb0, 0x48, 0x3c, 0xb4, + 0x24, 0x5d, 0x4b, 0x14, 0x5d, 0x7b, 0x1f, 0x26, 0x65, 0x2a, 0x97, 0xf5, 0xe5, 0x3a, 0x7e, 0x14, + 0x69, 0x12, 0x46, 0x37, 0x17, 0xad, 0xa5, 0xdb, 0x5f, 0xb4, 0x6f, 0x6f, 0x2c, 0x2f, 0x97, 0xcf, + 0x90, 0x71, 0x28, 0x09, 0xc0, 0x7c, 0xb5, 0x6c, 0x90, 0x31, 0x28, 0x2e, 0xad, 0xd4, 0x17, 0xe7, + 0x37, 0xac, 0xc5, 0x72, 0xee, 0xda, 0x8b, 0x30, 0x91, 0x5c, 0x27, 0x61, 0xc8, 0xc9, 0x08, 0xe4, + 0xad, 0xea, 0x56, 0xf9, 0x0c, 0x01, 0x18, 0x5e, 0xbb, 0x37, 0x5f, 0xbf, 0x79, 0xb3, 0x6c, 0x5c, + 0x7b, 0x2d, 0xe3, 0x93, 0x82, 0x8c, 0x53, 0x9d, 0x76, 0x9c, 0xc0, 0x89, 0x28, 0xaf, 0xe6, 0x7e, + 0xb7, 0x19, 0x79, 0x9d, 0x26, 0x7d, 0x5c, 0x36, 0xae, 0xbd, 0xd5, 0xf3, 0x65, 0x40, 0x32, 0x03, + 0x53, 0x1b, 0x2b, 0xd5, 0xfb, 0xb5, 0xa5, 0x3b, 0x1b, 0xab, 0x1b, 0x75, 0xfb, 0x7e, 0x75, 0x7d, + 0xfe, 0x6e, 0xf9, 0x0c, 0x6b, 0xf0, 0xfd, 0xd5, 0xfa, 0xba, 0x6d, 0x2d, 0xce, 0x2f, 0xae, 0xac, + 0x97, 0x8d, 0x6b, 0x3e, 0x4c, 0xe8, 0x1f, 0x4f, 0x21, 0x97, 0xe1, 0xd2, 0x46, 0x7d, 0xd1, 0xb2, + 0xd7, 0x57, 0xef, 0x2d, 0xae, 0xd8, 0x1b, 0xf5, 0xea, 0x9d, 0x45, 0x7b, 0x63, 0xa5, 0xbe, 0xb6, + 0x38, 0xbf, 0x74, 0x7b, 0x69, 0x71, 0xa1, 0x7c, 0x86, 0x54, 0xe0, 0x19, 0x05, 0xc3, 0x5a, 0x9c, + 0x5f, 0xdd, 0x5c, 0xb4, 0xec, 0xb5, 0x6a, 0xbd, 0xbe, 0xb5, 0x6a, 0x2d, 0x94, 0x0d, 0x72, 0x11, + 0xce, 0x65, 0x20, 0xdc, 0xbf, 0x5d, 0x2d, 0xe7, 0xae, 0xbd, 0xcf, 0xe6, 0x2a, 0xc9, 0x60, 0x4c, + 0x8a, 0x50, 0x58, 0x59, 0x5d, 0x59, 0x2c, 0x9f, 0x21, 0xa3, 0x30, 0xb2, 0xb6, 0xb8, 0xb2, 0xb0, + 0xb4, 0x72, 0x87, 0x8f, 0x5c, 0x75, 0x6d, 0xcd, 0x5a, 0xdd, 0x5c, 0x5c, 0x28, 0xe7, 0xd8, 0xf0, + 0x2c, 0x2c, 0xae, 0xb0, 0xda, 0xf3, 0xb5, 0xf2, 0x8f, 0x7f, 0xfa, 0xdc, 0x99, 0x1f, 0xff, 0xec, + 0x39, 0xe3, 0x27, 0x3f, 0x7b, 0xce, 0xf8, 0xef, 0x3f, 0x7b, 0xce, 0xd8, 0x1e, 0xc6, 0x05, 0x73, + 0xeb, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x8f, 0xbd, 0x12, 0xf1, 0xa9, 0x00, 0x00, } func (m *KeepAlive) Marshal() (dAtA []byte, err error) { @@ -11658,6 +11682,13 @@ func (m *TokenRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.AWSARN) > 0 { + i -= len(m.AWSARN) + copy(dAtA[i:], m.AWSARN) + i = encodeVarintTypes(dAtA, i, uint64(len(m.AWSARN))) + i-- + dAtA[i] = 0x22 + } if len(m.AWSRole) > 0 { i -= len(m.AWSRole) copy(dAtA[i:], m.AWSRole) @@ -11708,6 +11739,13 @@ func (m *ProvisionTokenSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.JoinMethod) > 0 { + i -= len(m.JoinMethod) + copy(dAtA[i:], m.JoinMethod) + i = encodeVarintTypes(dAtA, i, uint64(len(m.JoinMethod))) + i-- + dAtA[i] = 0x22 + } if m.AWSIIDTTL != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.AWSIIDTTL)) i-- @@ -18838,6 +18876,13 @@ func (m *RegisterUsingTokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.STSIdentityRequest) > 0 { + i -= len(m.STSIdentityRequest) + copy(dAtA[i:], m.STSIdentityRequest) + i = encodeVarintTypes(dAtA, i, uint64(len(m.STSIdentityRequest))) + i-- + dAtA[i] = 0x5a + } if len(m.EC2IdentityDocument) > 0 { i -= len(m.EC2IdentityDocument) copy(dAtA[i:], m.EC2IdentityDocument) @@ -20226,6 +20271,10 @@ func (m *TokenRule) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = len(m.AWSARN) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -20253,6 +20302,10 @@ func (m *ProvisionTokenSpecV2) Size() (n int) { if m.AWSIIDTTL != 0 { n += 1 + sovTypes(uint64(m.AWSIIDTTL)) } + l = len(m.JoinMethod) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -23476,6 +23529,10 @@ func (m *RegisterUsingTokenRequest) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = len(m.STSIdentityRequest) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -31612,6 +31669,38 @@ func (m *TokenRule) Unmarshal(dAtA []byte) error { } m.AWSRole = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AWSARN", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + 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 ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AWSARN = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -31748,6 +31837,38 @@ func (m *ProvisionTokenSpecV2) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JoinMethod", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + 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 ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JoinMethod = JoinMethod(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -53260,6 +53381,40 @@ func (m *RegisterUsingTokenRequest) Unmarshal(dAtA []byte) error { m.EC2IdentityDocument = []byte{} } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field STSIdentityRequest", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.STSIdentityRequest = append(m.STSIdentityRequest[:0], dAtA[iNdEx:postIndex]...) + if m.STSIdentityRequest == nil { + m.STSIdentityRequest = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/api/types/types.proto b/api/types/types.proto index c644b970f1580..f227d7c3a5742 100644 --- a/api/types/types.proto +++ b/api/types/types.proto @@ -703,10 +703,20 @@ message ProvisionTokenV2List { repeated ProvisionTokenV2 ProvisionTokens = 1; } +// TokenRule is a rule that a joining node must match in order to use the +// associated token. message TokenRule { + // AWSAccount is the AWS account ID. string AWSAccount = 1 [ (gogoproto.jsontag) = "aws_account,omitempty" ]; + // AWSRegions is used for the EC2 join method and is a list of AWS regions a + // node is allowed to join from. repeated string AWSRegions = 2 [ (gogoproto.jsontag) = "aws_regions,omitempty" ]; + // AWSRole is used for the EC2 join method and is the the ARN of the AWS + // role that the auth server will assume in order to call the ec2 API. string AWSRole = 3 [ (gogoproto.jsontag) = "aws_role,omitempty" ]; + // AWSARN is used for the IAM join method, the AWS identity of joining nodes + // must match this ARN. Supports wildcards "*" and "?". + string AWSARN = 4 [ (gogoproto.jsontag) = "aws_arn,omitempty" ]; } // ProvisionTokenSpecV2 is a specification for V2 token @@ -716,9 +726,17 @@ message ProvisionTokenSpecV2 { // certificates issued to the user of the token repeated string Roles = 1 [ (gogoproto.jsontag) = "roles", (gogoproto.casttype) = "SystemRole" ]; - repeated TokenRule allow = 2 [ (gogoproto.jsontag) = "allow,omitempty" ]; + // Allow is a list of TokenRules, nodes using this token must match one + // allow rule to use this token. + repeated TokenRule Allow = 2 [ (gogoproto.jsontag) = "allow,omitempty" ]; + // AWSIIDTTL is the TTL to use for AWS EC2 Instance Identity Documents used + // to join the cluster with this token. int64 AWSIIDTTL = 3 [ (gogoproto.jsontag) = "aws_iid_ttl,omitempty", (gogoproto.casttype) = "Duration" ]; + // JoinMethod is the joining method required in order to use this token. + // Supported joining methods include "token", "ec2", and "iam". + string JoinMethod = 4 + [ (gogoproto.jsontag) = "join_method", (gogoproto.casttype) = "JoinMethod" ]; } // StaticTokensV2 implements the StaticTokens interface. @@ -2712,9 +2730,12 @@ message RegisterUsingTokenRequest { // RemoteAddr is the remote address of the host requesting a host certificate. // It is used to replace 0.0.0.0 in the list of additional principals. string RemoteAddr = 9 [ (gogoproto.jsontag) = "remote_addr" ]; - // EC2IdentityDocument is used for Simplified Node Joining to prove the - // identity of a joining EC2 instance. + // EC2IdentityDocument is used for the EC2 join method to prove the identity + // of a joining EC2 instance. bytes EC2IdentityDocument = 10 [ (gogoproto.jsontag) = "ec2_id" ]; + // STSIdentityRequest is used for the IAM join method to prove the AWS + // identity of a joining node. + bytes STSIdentityRequest = 11 [ (gogoproto.jsontag) = "-" ]; } // RecoveryCodes holds a user's recovery code information. Recovery codes allows users to regain diff --git a/integration/ec2_test.go b/integration/ec2_test.go index 71c69834ac0c2..fa266ebec6311 100644 --- a/integration/ec2_test.go +++ b/integration/ec2_test.go @@ -40,7 +40,7 @@ import ( func newNodeConfig(t *testing.T, authAddr utils.NetAddr, awsTokenName string) *service.Config { config := service.MakeDefaultConfig() config.Token = awsTokenName - config.JoinMethod = service.JoinMethodEC2 + config.JoinMethod = types.JoinMethodEC2 config.SSH.Enabled = true config.SSH.Addr.Addr = net.JoinHostPort(Host, ports.Pop()) config.Auth.Enabled = false diff --git a/lib/auth/apiserver.go b/lib/auth/apiserver.go index 20770c8b22bc3..1cc5e4674efd7 100644 --- a/lib/auth/apiserver.go +++ b/lib/auth/apiserver.go @@ -633,7 +633,7 @@ func (s *APIServer) validateTrustedCluster(auth ClientI, w http.ResponseWriter, return nil, trace.Wrap(err) } - validateResponse, err := auth.ValidateTrustedCluster(validateRequest) + validateResponse, err := auth.ValidateTrustedCluster(r.Context(), validateRequest) if err != nil { return nil, trace.Wrap(err) } @@ -1033,7 +1033,7 @@ func (s *APIServer) registerUsingToken(auth ClientI, w http.ResponseWriter, r *h // Pass along the remote address the request came from to the registration function. req.RemoteAddr = r.RemoteAddr - certs, err := auth.RegisterUsingToken(req) + certs, err := auth.RegisterUsingToken(r.Context(), &req) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/auth.go b/lib/auth/auth.go index e9a5fb335195d..6543be6d0744f 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -2262,9 +2262,8 @@ func (a *Server) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequ // ValidateToken takes a provisioning token value and finds if it's valid. Returns // a list of roles this token allows its owner to assume and token labels, or an error if the token // cannot be found. -func (a *Server) ValidateToken(token string) (types.SystemRoles, map[string]string, error) { - ctx := context.TODO() - tkns, err := a.GetCache().GetStaticTokens() +func (a *Server) ValidateToken(ctx context.Context, token string) (types.SystemRoles, map[string]string, error) { + tkns, err := a.GetStaticTokens() if err != nil { return nil, nil, trace.Wrap(err) } @@ -2279,7 +2278,7 @@ func (a *Server) ValidateToken(token string) (types.SystemRoles, map[string]stri // If it's not a static token, check if it's a ephemeral token in the backend. // If a ephemeral token is found, make sure it's still valid. - tok, err := a.GetCache().GetToken(ctx, token) + tok, err := a.GetToken(ctx, token) if err != nil { return nil, nil, trace.Wrap(err) } @@ -2307,74 +2306,6 @@ func (a *Server) checkTokenTTL(tok types.ProvisionToken) bool { return true } -// RegisterUsingToken adds a new node to the Teleport cluster using previously issued token. -// A node must also request a specific role (and the role must match one of the roles -// the token was generated for). -// -// If a token was generated with a TTL, it gets enforced (can't register new nodes after TTL expires) -// If a token was generated with a TTL=0, it means it's a single-use token and it gets destroyed -// after a successful registration. -func (a *Server) RegisterUsingToken(req types.RegisterUsingTokenRequest) (*proto.Certs, error) { - log.Infof("Node %q [%v] is trying to join with role: %v.", req.NodeName, req.HostID, req.Role) - - if err := req.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - - // If the request uses Simplified Node Joining check that the identity is - // valid and matches the token allow rules. - err := a.CheckEC2Request(context.Background(), req) - if err != nil { - return nil, trace.Wrap(err) - } - - // make sure the token is valid - roles, _, err := a.ValidateToken(req.Token) - if err != nil { - log.Warningf("%q [%v] can not join the cluster with role %s, token error: %v", req.NodeName, req.HostID, req.Role, err) - return nil, trace.AccessDenied(fmt.Sprintf("%q [%v] can not join the cluster with role %s, the token is not valid", req.NodeName, req.HostID, req.Role)) - } - - // make sure the caller is requested the role allowed by the token - if !roles.Include(req.Role) { - msg := fmt.Sprintf("node %q [%v] can not join the cluster, the token does not allow %q role", req.NodeName, req.HostID, req.Role) - log.Warn(msg) - return nil, trace.BadParameter(msg) - } - - // generate and return host certificate and keys - certs, err := a.GenerateHostCerts(context.Background(), - &proto.HostCertsRequest{ - HostID: req.HostID, - NodeName: req.NodeName, - Role: req.Role, - AdditionalPrincipals: req.AdditionalPrincipals, - PublicTLSKey: req.PublicTLSKey, - PublicSSHKey: req.PublicSSHKey, - RemoteAddr: req.RemoteAddr, - DNSNames: req.DNSNames, - }) - if err != nil { - return nil, trace.Wrap(err) - } - log.Infof("Node %q [%v] has joined the cluster.", req.NodeName, req.HostID) - return certs, nil -} - -func (a *Server) RegisterNewAuthServer(ctx context.Context, token string) error { - tok, err := a.Provisioner.GetToken(ctx, token) - if err != nil { - return trace.Wrap(err) - } - if !tok.GetRoles().Include(types.RoleAuth) { - return trace.AccessDenied("role does not match") - } - if err := a.DeleteToken(ctx, token); err != nil { - return trace.Wrap(err) - } - return nil -} - func (a *Server) DeleteToken(ctx context.Context, token string) (err error) { tkns, err := a.GetStaticTokens() if err != nil { diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index 30807eb050e1a..8662cd30fbe90 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -1,5 +1,5 @@ /* -Copyright 2015-2019 Gravitational, Inc. +Copyright 2015-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. @@ -39,7 +39,6 @@ import ( apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" - apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/sshutils" "github.com/gravitational/teleport/lib/auth/testauthority" authority "github.com/gravitational/teleport/lib/auth/testauthority" @@ -155,6 +154,10 @@ func newTestPack(ctx context.Context, dataDir string) (testPack, error) { return p, trace.Wrap(err) } + if err := p.a.UpsertNamespace(types.DefaultNamespace()); err != nil { + return p, trace.Wrap(err) + } + p.mockEmitter = &events.MockEmitter{} p.a.emitter = p.mockEmitter return p, nil @@ -564,37 +567,18 @@ func (s *AuthSuite) TestTokensCRUD(c *C) { c.Assert(len(tokens), Equals, 1) c.Assert(tokens[0].GetName(), Equals, tok) - roles, _, err := s.a.ValidateToken(tok) + roles, _, err := s.a.ValidateToken(ctx, tok) c.Assert(err, IsNil) c.Assert(roles.Include(types.RoleNode), Equals, true) c.Assert(roles.Include(types.RoleProxy), Equals, false) - priv, pub, err := s.a.GenerateKeyPair("") - c.Assert(err, IsNil) - - tlsPublicKey, err := PrivateKeyToPublicKeyTLS(priv) - c.Assert(err, IsNil) - - // unsuccessful registration (wrong role) - certs, err := s.a.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: tok, - HostID: "bad-host-id", - NodeName: "bad-node-name", - Role: types.RoleProxy, - PublicTLSKey: tlsPublicKey, - PublicSSHKey: pub, - }) - c.Assert(certs, IsNil) - c.Assert(err, NotNil) - c.Assert(err, ErrorMatches, `node "bad-node-name" \[bad-host-id\] can not join the cluster, the token does not allow "Proxy" role`) - // generate predefined token customToken := "custom-token" tok, err = s.a.GenerateToken(ctx, GenerateTokenRequest{Roles: types.SystemRoles{types.RoleNode}, Token: customToken}) c.Assert(err, IsNil) c.Assert(tok, Equals, customToken) - roles, _, err = s.a.ValidateToken(tok) + roles, _, err = s.a.ValidateToken(ctx, tok) c.Assert(err, IsNil) c.Assert(roles.Include(types.RoleNode), Equals, true) c.Assert(roles.Include(types.RoleProxy), Equals, false) @@ -602,56 +586,6 @@ func (s *AuthSuite) TestTokensCRUD(c *C) { err = s.a.DeleteToken(ctx, customToken) c.Assert(err, IsNil) - // generate multi-use token with long TTL: - multiUseToken, err := s.a.GenerateToken(ctx, GenerateTokenRequest{Roles: types.SystemRoles{types.RoleProxy}, TTL: time.Hour}) - c.Assert(err, IsNil) - _, _, err = s.a.ValidateToken(multiUseToken) - c.Assert(err, IsNil) - - // use it twice: - certs, err = s.a.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: multiUseToken, - HostID: "once", - NodeName: "node-name", - Role: types.RoleProxy, - AdditionalPrincipals: []string{"example.com"}, - PublicTLSKey: tlsPublicKey, - PublicSSHKey: pub, - }) - c.Assert(err, IsNil) - - // along the way, make sure that additional principals work - hostCert, err := sshutils.ParseCertificate(certs.SSH) - c.Assert(err, IsNil) - comment := Commentf("can't find example.com in %v", hostCert.ValidPrincipals) - c.Assert(apiutils.SliceContainsStr(hostCert.ValidPrincipals, "example.com"), Equals, true, comment) - - _, err = s.a.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: multiUseToken, - HostID: "twice", - NodeName: "node-name", - Role: types.RoleProxy, - PublicTLSKey: tlsPublicKey, - PublicSSHKey: pub, - }) - c.Assert(err, IsNil) - - // try to use after TTL: - s.a.SetClock(clockwork.NewFakeClockAt(time.Now().UTC().Add(time.Hour + 1))) - _, err = s.a.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: multiUseToken, - HostID: "late.bird", - NodeName: "node-name", - Role: types.RoleProxy, - PublicTLSKey: tlsPublicKey, - PublicSSHKey: pub, - }) - c.Assert(err, ErrorMatches, `"node-name" \[late.bird\] can not join the cluster with role Proxy, the token is not valid`) - - // expired token should be gone now - err = s.a.DeleteToken(ctx, multiUseToken) - c.Assert(trace.IsNotFound(err), Equals, true, Commentf("%#v", err)) - // lets use static tokens now roles = types.SystemRoles{types.RoleProxy} st, err := types.NewStaticTokens(types.StaticTokensSpecV2{ @@ -662,27 +596,11 @@ func (s *AuthSuite) TestTokensCRUD(c *C) { }}, }) c.Assert(err, IsNil) + err = s.a.SetStaticTokens(st) c.Assert(err, IsNil) - _, err = s.a.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: "static-token-value", - HostID: "static.host", - NodeName: "node-name", - Role: types.RoleProxy, - PublicTLSKey: tlsPublicKey, - PublicSSHKey: pub, - }) - c.Assert(err, IsNil) - _, err = s.a.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: "static-token-value", - HostID: "wrong.role", - NodeName: "node-name", - Role: types.RoleAuth, - PublicTLSKey: tlsPublicKey, - PublicSSHKey: pub, - }) - c.Assert(err, NotNil) - r, _, err := s.a.ValidateToken("static-token-value") + + r, _, err := s.a.ValidateToken(ctx, "static-token-value") c.Assert(err, IsNil) c.Assert(r, DeepEquals, roles) @@ -695,11 +613,11 @@ func (s *AuthSuite) TestTokensCRUD(c *C) { func (s *AuthSuite) TestBadTokens(c *C) { ctx := context.Background() // empty - _, _, err := s.a.ValidateToken("") + _, _, err := s.a.ValidateToken(ctx, "") c.Assert(err, NotNil) // garbage - _, _, err = s.a.ValidateToken("bla bla") + _, _, err = s.a.ValidateToken(ctx, "bla bla") c.Assert(err, NotNil) // tampered @@ -707,7 +625,7 @@ func (s *AuthSuite) TestBadTokens(c *C) { c.Assert(err, IsNil) tampered := string(tok[0]+1) + tok[1:] - _, _, err = s.a.ValidateToken(tampered) + _, _, err = s.a.ValidateToken(ctx, tampered) c.Assert(err, NotNil) } diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index c061534923641..ede1541257473 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -456,9 +456,9 @@ func (a *ServerWithRoles) GenerateToken(ctx context.Context, req GenerateTokenRe return a.authServer.GenerateToken(ctx, req) } -func (a *ServerWithRoles) RegisterUsingToken(req types.RegisterUsingTokenRequest) (*proto.Certs, error) { +func (a *ServerWithRoles) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) { // tokens have authz mechanism on their own, no need to check - return a.authServer.RegisterUsingToken(req) + return a.authServer.RegisterUsingToken(ctx, req) } func (a *ServerWithRoles) RegisterNewAuthServer(ctx context.Context, token string) error { @@ -466,6 +466,18 @@ func (a *ServerWithRoles) RegisterNewAuthServer(ctx context.Context, token strin return a.authServer.RegisterNewAuthServer(ctx, token) } +// RegisterUsingIAMMethod registers the caller using the IAM join method and +// returns signed certs to join the cluster. +// +// See (*Server).RegisterUsingIAMMethod for further documentation. +// +// This wrapper does not do any extra authz checks, as the register method has +// its own authz mechanism. +func (a *ServerWithRoles) RegisterUsingIAMMethod(ctx context.Context, challengeResponse ChallengeResponseFunc) (*proto.Certs, error) { + certs, err := a.authServer.RegisterUsingIAMMethod(ctx, challengeResponse) + return certs, trace.Wrap(err) +} + // GenerateHostCerts generates new host certificates (signed // by the host certificate authority) for a node. func (a *ServerWithRoles) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequest) (*proto.Certs, error) { @@ -2716,9 +2728,9 @@ func (a *ServerWithRoles) UpsertTrustedCluster(ctx context.Context, tc types.Tru return a.authServer.UpsertTrustedCluster(ctx, tc) } -func (a *ServerWithRoles) ValidateTrustedCluster(validateRequest *ValidateTrustedClusterRequest) (*ValidateTrustedClusterResponse, error) { +func (a *ServerWithRoles) ValidateTrustedCluster(ctx context.Context, validateRequest *ValidateTrustedClusterRequest) (*ValidateTrustedClusterResponse, error) { // the token provides it's own authorization and authentication - return a.authServer.validateTrustedCluster(validateRequest) + return a.authServer.validateTrustedCluster(ctx, validateRequest) } // DeleteTrustedCluster deletes a trusted cluster by name. diff --git a/lib/auth/clt.go b/lib/auth/clt.go index 40da91c8f5e34..49a5f23b83845 100644 --- a/lib/auth/clt.go +++ b/lib/auth/clt.go @@ -542,7 +542,7 @@ func (c *Client) GenerateToken(ctx context.Context, req GenerateTokenRequest) (s // RegisterUsingToken calls the auth service API to register a new node using a registration token // which was previously issued via GenerateToken. -func (c *Client) RegisterUsingToken(req types.RegisterUsingTokenRequest) (*proto.Certs, error) { +func (c *Client) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) { if err := req.CheckAndSetDefaults(); err != nil { return nil, trace.Wrap(err) } @@ -1548,7 +1548,7 @@ func (c *Client) DeleteAllUsers() error { return trace.NotImplemented(notImplementedMessage) } -func (c *Client) ValidateTrustedCluster(validateRequest *ValidateTrustedClusterRequest) (*ValidateTrustedClusterResponse, error) { +func (c *Client) ValidateTrustedCluster(ctx context.Context, validateRequest *ValidateTrustedClusterRequest) (*ValidateTrustedClusterResponse, error) { validateRequestRaw, err := validateRequest.ToRaw() if err != nil { return nil, trace.Wrap(err) @@ -1872,7 +1872,7 @@ type ProvisioningService interface { // RegisterUsingToken calls the auth service API to register a new node via registration token // which has been previously issued via GenerateToken - RegisterUsingToken(req types.RegisterUsingTokenRequest) (*proto.Certs, error) + RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) // RegisterNewAuthServer is used to register new auth server with token RegisterNewAuthServer(ctx context.Context, token string) error @@ -1916,7 +1916,7 @@ type ClientI interface { // ValidateTrustedCluster validates trusted cluster token with // main cluster, in case if validation is successful, main cluster // adds remote cluster - ValidateTrustedCluster(*ValidateTrustedClusterRequest) (*ValidateTrustedClusterResponse, error) + ValidateTrustedCluster(context.Context, *ValidateTrustedClusterRequest) (*ValidateTrustedClusterResponse, error) // GetDomainName returns auth server cluster name GetDomainName() (string, error) diff --git a/lib/auth/join.go b/lib/auth/join.go new file mode 100644 index 0000000000000..5e3e9e2d36e04 --- /dev/null +++ b/lib/auth/join.go @@ -0,0 +1,131 @@ +/* +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 auth + +import ( + "context" + "fmt" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/trace" +) + +// tokenJoinMethod returns the join method of the token with the given tokenName +func (a *Server) tokenJoinMethod(ctx context.Context, tokenName string) types.JoinMethod { + provisionToken, err := a.GetToken(ctx, tokenName) + if err != nil { + // could not find dynamic token, assume static token. If it does not + // exist this will be caught later. + return types.JoinMethodToken + } + return provisionToken.GetJoinMethod() +} + +// checkTokenJoinRequestCommon checks all token join rules that are common to +// all join methods, including token existence, token TTL, and allowed roles. +func (a *Server) checkTokenJoinRequestCommon(ctx context.Context, req *types.RegisterUsingTokenRequest) error { + // make sure the token is valid + roles, _, err := a.ValidateToken(ctx, req.Token) + if err != nil { + log.Warningf("%q [%v] can not join the cluster with role %s, token error: %v", req.NodeName, req.HostID, req.Role, err) + return trace.AccessDenied(fmt.Sprintf("%q [%v] can not join the cluster with role %s, the token is not valid", req.NodeName, req.HostID, req.Role)) + } + + // make sure the caller is requesting a role allowed by the token + if !roles.Include(req.Role) { + msg := fmt.Sprintf("node %q [%v] can not join the cluster, the token does not allow %q role", req.NodeName, req.HostID, req.Role) + log.Warn(msg) + return trace.BadParameter(msg) + } + + return nil +} + +// RegisterUsingToken returns credentials for a new node to join the Teleport +// cluster using a previously issued token. +// +// A node must also request a specific role (and the role must match one of the roles +// the token was generated for.) +// +// If a token was generated with a TTL, it gets enforced (can't register new +// nodes after TTL expires.) +// +// If the token includes a specific join method, the rules for that join method +// will be checked. +func (a *Server) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) { + log.Infof("Node %q [%v] is trying to join with role: %v.", req.NodeName, req.HostID, req.Role) + if err := req.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + + switch a.tokenJoinMethod(ctx, req.Token) { + case types.JoinMethodEC2: + if err := a.checkEC2JoinRequest(ctx, req); err != nil { + return nil, trace.Wrap(err) + } + case types.JoinMethodIAM: + // IAM join method must use the gRPC RegisterUsingIAMMethod + return nil, trace.AccessDenied("this token is only valid for the IAM " + + "join method but the node has connected to the wrong endpoint, make " + + "sure your node is configured to use the IAM join method") + case types.JoinMethodToken: + // carry on to common token checking logic + default: + // this is a logic error, all valid join methods should be captured + // above (empty join method will be set to JoinMethodToken by + // CheckAndSetDefaults) + return nil, trace.BadParameter("unrecognized token join method") + } + + // perform common token checks + if err := a.checkTokenJoinRequestCommon(ctx, req); err != nil { + return nil, trace.Wrap(err) + } + + // generate and return host certificate and keys + certs, err := a.GenerateHostCerts(ctx, + &proto.HostCertsRequest{ + HostID: req.HostID, + NodeName: req.NodeName, + Role: req.Role, + AdditionalPrincipals: req.AdditionalPrincipals, + PublicTLSKey: req.PublicTLSKey, + PublicSSHKey: req.PublicSSHKey, + RemoteAddr: req.RemoteAddr, + DNSNames: req.DNSNames, + }) + if err != nil { + return nil, trace.Wrap(err) + } + log.Infof("Node %q [%v] has joined the cluster.", req.NodeName, req.HostID) + return certs, nil +} + +func (a *Server) RegisterNewAuthServer(ctx context.Context, token string) error { + tok, err := a.GetToken(ctx, token) + if err != nil { + return trace.Wrap(err) + } + if !tok.GetRoles().Include(types.RoleAuth) { + return trace.AccessDenied("role does not match") + } + if err := a.DeleteToken(ctx, token); err != nil { + return trace.Wrap(err) + } + return nil +} diff --git a/lib/auth/ec2_join.go b/lib/auth/join_ec2.go similarity index 88% rename from lib/auth/ec2_join.go rename to lib/auth/join_ec2.go index a547f5c203b00..c5f893ecf7ec9 100644 --- a/lib/auth/ec2_join.go +++ b/lib/auth/join_ec2.go @@ -68,13 +68,13 @@ func ec2ClientFromConfig(ctx context.Context, cfg aws.Config) ec2Client { func checkEC2AllowRules(ctx context.Context, iid *imds.InstanceIdentityDocument, provisionToken types.ProvisionToken) error { allowRules := provisionToken.GetAllowRules() for _, rule := range allowRules { - // If this rule specifies and AWS account, the IID must match + // if this rule specifies an AWS account, the IID must match if len(rule.AWSAccount) > 0 { if rule.AWSAccount != iid.AccountID { continue } } - // If this rule specifies any AWS regions, the IID must match one of them + // if this rule specifies any AWS regions, the IID must match one of them if len(rule.AWSRegions) > 0 { if !apiutils.SliceContainsStr(rule.AWSRegions, iid.Region) { continue @@ -258,7 +258,7 @@ func dbExists(ctx context.Context, presence services.Presence, hostID string) (b // only allow the roles which will actually be used by all expected instances so // that a stolen IID could not be used to join the cluster with a different // role. -func (a *Server) checkInstanceUnique(ctx context.Context, req types.RegisterUsingTokenRequest, iid *imds.InstanceIdentityDocument) error { +func (a *Server) checkInstanceUnique(ctx context.Context, req *types.RegisterUsingTokenRequest, iid *imds.InstanceIdentityDocument) error { requestedHostID := req.HostID expectedHostID := utils.NodeIDFromIID(iid) if requestedHostID != expectedHostID { @@ -294,7 +294,7 @@ func (a *Server) checkInstanceUnique(ctx context.Context, req types.RegisterUsin return nil } -// CheckEC2Request checks register requests which use EC2 Simplified Node +// checkEC2JoinRequest checks register requests which use EC2 Simplified Node // Joining. This method checks that: // 1. The given Instance Identity Document has a valid signature (signed by AWS). // 2. A node has not already joined the cluster from this EC2 instance (to @@ -304,34 +304,21 @@ func (a *Server) checkInstanceUnique(ctx context.Context, req types.RegisterUsin // If the request does not include an Instance Identity Document, and the // token does not include any allow rules, this method returns nil and the // normal token checking logic resumes. -func (a *Server) CheckEC2Request(ctx context.Context, req types.RegisterUsingTokenRequest) error { - requestIncludesIID := req.EC2IdentityDocument != nil +func (a *Server) checkEC2JoinRequest(ctx context.Context, req *types.RegisterUsingTokenRequest) error { tokenName := req.Token - provisionToken, err := a.GetCache().GetToken(ctx, tokenName) + provisionToken, err := a.GetToken(ctx, tokenName) if err != nil { - if trace.IsNotFound(err) && !requestIncludesIID { - // This is not a Simplified Node Joining request, pass on to the - // regular token checking logic in case this is a static token. - return nil - } return trace.Wrap(err) } - tokenRequiresIID := len(provisionToken.GetAllowRules()) > 0 - - if !requestIncludesIID && !tokenRequiresIID { - // not a simplified node joining request, pass on to the regular token - // checking logic - return nil - } - if tokenRequiresIID && !requestIncludesIID { - return trace.AccessDenied("this token requires an EC2 Identity Document from the node") - } - if !tokenRequiresIID && requestIncludesIID { - return trace.BadParameter("an EC2 Identity Document is included in a register request for a token which does not expect it") - } log.Debugf("Received Simplified Node Joining request for host %q", req.HostID) + if len(req.EC2IdentityDocument) == 0 { + return trace.AccessDenied("this token is only valid for the EC2 join " + + "method but the node has not included an EC2 Instance Identity " + + "Document, make sure your node is configured to use the EC2 join method") + } + iid, err := parseAndVerifyIID(req.EC2IdentityDocument) if err != nil { return trace.Wrap(err) diff --git a/lib/auth/ec2_join_test.go b/lib/auth/join_ec2_test.go similarity index 91% rename from lib/auth/ec2_join_test.go rename to lib/auth/join_ec2_test.go index 4e742474ae00b..e42bc8d655660 100644 --- a/lib/auth/ec2_join_test.go +++ b/lib/auth/join_ec2_test.go @@ -25,9 +25,6 @@ import ( "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/auth/testauthority" - "github.com/gravitational/teleport/lib/backend/lite" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/trace" "github.com/aws/aws-sdk-go-v2/service/ec2" @@ -141,44 +138,13 @@ func (c ec2ClientRunning) DescribeInstances(ctx context.Context, params *ec2.Des }, nil } -func newAuthServer(t *testing.T) *Server { - b, err := lite.NewWithConfig(context.Background(), lite.Config{ - Path: t.TempDir(), - PollStreamPeriod: 200 * time.Millisecond, - }) +func TestAuth_RegisterUsingToken_EC2(t *testing.T) { + ctx := context.Background() + p, err := newTestPack(ctx, t.TempDir()) require.NoError(t, err) + a := p.a - clusterName, err := services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ - ClusterName: "test-cluster", - }) - require.NoError(t, err) - - authConfig := &InitConfig{ - ClusterName: clusterName, - Backend: b, - Authority: testauthority.New(), - SkipPeriodicOperations: true, - } - - a, err := NewServer(authConfig) - require.NoError(t, err) - - staticTokens, err := types.NewStaticTokens(types.StaticTokensSpecV2{ - StaticTokens: []types.ProvisionTokenV1{}, - }) - require.NoError(t, err) - err = a.SetStaticTokens(staticTokens) - require.NoError(t, err) - - err = a.UpsertNamespace(types.DefaultNamespace()) - require.NoError(t, err) - - return a -} - -func TestSimplifiedNodeJoin(t *testing.T) { - a := newAuthServer(t) - + // upsert a node to test duplicates node := &types.ServerV2{ Kind: types.KindNode, Version: types.V2, @@ -187,7 +153,13 @@ func TestSimplifiedNodeJoin(t *testing.T) { Namespace: defaults.Namespace, }, } - _, err := a.UpsertNode(context.Background(), node) + _, err = a.UpsertNode(ctx, node) + require.NoError(t, err) + + sshPrivateKey, sshPublicKey, err := a.GenerateKeyPair("") + require.NoError(t, err) + + tlsPublicKey, err := PrivateKeyToPublicKeyTLS(sshPrivateKey) require.NoError(t, err) isNil := func(err error) bool { @@ -196,7 +168,6 @@ func TestSimplifiedNodeJoin(t *testing.T) { testCases := []struct { desc string - tokenRules []*types.TokenRule tokenSpec types.ProvisionTokenSpecV2 ec2Client ec2Client request types.RegisterUsingTokenRequest @@ -360,6 +331,27 @@ func TestSimplifiedNodeJoin(t *testing.T) { expectError: trace.IsAccessDenied, clock: clockwork.NewFakeClockAt(instance1.pendingTime), }, + { + desc: "no identity document", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: instance1.account, + AWSRegions: []string{instance1.region}, + }, + }, + }, + ec2Client: ec2ClientRunning{}, + request: types.RegisterUsingTokenRequest{ + Token: "test_token", + NodeName: "node_name", + Role: types.RoleNode, + HostID: instance1.account + "-" + instance1.instanceID, + }, + expectError: trace.IsAccessDenied, + clock: clockwork.NewFakeClockAt(instance1.pendingTime), + }, { desc: "bad identity document", tokenSpec: types.ProvisionTokenSpecV2{ @@ -558,7 +550,12 @@ func TestSimplifiedNodeJoin(t *testing.T) { ctx := context.WithValue(context.Background(), ec2ClientKey{}, tc.ec2Client) - err = a.CheckEC2Request(ctx, tc.request) + // set common request values here to avoid setting them in every + // testcase + tc.request.PublicSSHKey = sshPublicKey + tc.request.PublicTLSKey = tlsPublicKey + + _, err = a.RegisterUsingToken(ctx, &tc.request) require.True(t, tc.expectError(err)) err = a.DeleteToken(context.Background(), token.GetName()) @@ -576,16 +573,26 @@ func TestAWSCerts(t *testing.T) { } } -// TestHostUniqueCheck tests the uniqueness check used by CheckEC2Request +// TestHostUniqueCheck tests the uniqueness check used by checkEC2JoinRequest func TestHostUniqueCheck(t *testing.T) { - a := newAuthServer(t) + ctx := context.Background() + p, err := newTestPack(ctx, t.TempDir()) + require.NoError(t, err) + a := p.a + a.clock = clockwork.NewFakeClockAt(instance1.pendingTime) token, err := types.NewProvisionTokenFromSpec( "test_token", time.Now().Add(time.Minute), types.ProvisionTokenSpecV2{ - Roles: []types.SystemRole{types.RoleNode, types.RoleKube}, + Roles: []types.SystemRole{ + types.RoleNode, + types.RoleProxy, + types.RoleKube, + types.RoleDatabase, + types.RoleApp, + }, Allow: []*types.TokenRule{ &types.TokenRule{ AWSAccount: instance1.account, @@ -598,6 +605,12 @@ func TestHostUniqueCheck(t *testing.T) { err = a.UpsertToken(context.Background(), token) require.NoError(t, err) + sshPrivateKey, sshPublicKey, err := a.GenerateKeyPair("") + require.NoError(t, err) + + tlsPublicKey, err := PrivateKeyToPublicKeyTLS(sshPrivateKey) + require.NoError(t, err) + testCases := []struct { role types.SystemRole upserter func(name string) @@ -692,7 +705,7 @@ func TestHostUniqueCheck(t *testing.T) { }, } - ctx := context.WithValue(context.Background(), ec2ClientKey{}, ec2ClientRunning{}) + ctx = context.WithValue(ctx, ec2ClientKey{}, ec2ClientRunning{}) for _, tc := range testCases { t.Run(string(tc.role), func(t *testing.T) { @@ -702,10 +715,12 @@ func TestHostUniqueCheck(t *testing.T) { Role: tc.role, HostID: instance1.account + "-" + instance1.instanceID, EC2IdentityDocument: instance1.iid, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, } // request works with no existing host - err = a.CheckEC2Request(ctx, request) + _, err = a.RegisterUsingToken(ctx, &request) require.NoError(t, err) // add the server @@ -713,8 +728,9 @@ func TestHostUniqueCheck(t *testing.T) { tc.upserter(name) // request should fail - err = a.CheckEC2Request(ctx, request) - require.Error(t, err) + _, err = a.RegisterUsingToken(ctx, &request) + expectedErr := &trace.AccessDeniedError{} + require.ErrorAs(t, err, &expectedErr) }) } diff --git a/lib/auth/join_iam.go b/lib/auth/join_iam.go new file mode 100644 index 0000000000000..7c85c9f930069 --- /dev/null +++ b/lib/auth/join_iam.go @@ -0,0 +1,350 @@ +/* +Copyright 2021-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 auth + +import ( + "bufio" + "bytes" + "context" + "crypto/rand" + "encoding/base64" + "encoding/json" + "io" + "net" + "net/http" + "net/url" + "regexp" + "strings" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/lib/utils/aws" + + "github.com/gravitational/trace" +) + +const ( + // Hardcoding the sts API version here may be more strict than necessary, + // but this is set by the Teleport node and can only be changed when we + // update our AWS SDK dependency. Since Auth should always be upgraded + // before nodes, we will have a chance to update the check on Auth if we + // ever have a need to allow a newer API version. + expectedSTSIdentityRequestBody = "Action=GetCallerIdentity&Version=2011-06-15" + + // Only allowing the global sts endpoint here, Teleport nodes will only send + // requests for this endpoint. If we want to start using regional endpoints + // we can update this check before updating the nodes. + stsHost = "sts.amazonaws.com" + + // AWS SignedHeaders will always be lowercase + // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html#sigv4-auth-header-overview + challengeHeaderKey = "x-teleport-challenge" +) + +// validateSTSIdentityRequest checks that a received sts:GetCallerIdentity +// request is valid and includes the challenge as a signed header. An example +// valid request looks like: +// ``` +// POST / HTTP/1.1 +// Host: sts.amazonaws.com +// Accept: application/json +// Authorization: AWS4-HMAC-SHA256 Credential=AAAAAAAAAAAAAAAAAAAA/20211108/us-east-1/sts/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-date;x-amz-security-token;x-teleport-challenge, Signature=999... +// Content-Length: 43 +// Content-Type: application/x-www-form-urlencoded; charset=utf-8 +// User-Agent: aws-sdk-go/1.37.17 (go1.17.1; darwin; amd64) +// X-Amz-Date: 20211108T190420Z +// X-Amz-Security-Token: aaa... +// X-Teleport-Challenge: 0ezlc3usTAkXeZTcfOazUq0BGrRaKmb4EwODk8U7J5A +// +// Action=GetCallerIdentity&Version=2011-06-15 +// ``` +func validateSTSIdentityRequest(req *http.Request, challenge string) error { + if req.Host != stsHost { + return trace.AccessDenied("sts identity request is for unknown host %q", req.Host) + } + + if req.Method != http.MethodPost { + return trace.AccessDenied("sts identity request method %q does not match expected method %q", req.RequestURI, http.MethodPost) + } + + if req.Header.Get(challengeHeaderKey) != challenge { + return trace.AccessDenied("sts identity request does not include challenge header or it does not match") + } + + authHeader := req.Header.Get(aws.AuthorizationHeader) + + sigV4, err := aws.ParseSigV4(authHeader) + if err != nil { + return trace.Wrap(err) + } + if !utils.SliceContainsStr(sigV4.SignedHeaders, challengeHeaderKey) { + return trace.AccessDenied("sts identity request auth header %q does not include "+ + challengeHeaderKey+" as a signed header", authHeader) + } + + body, err := aws.GetAndReplaceReqBody(req) + if err != nil { + return trace.Wrap(err) + } + if !bytes.Equal([]byte(expectedSTSIdentityRequestBody), body) { + return trace.BadParameter("sts request body %q does not equal expected %q", string(body), expectedSTSIdentityRequestBody) + } + + return nil +} + +func parseSTSRequest(req []byte) (*http.Request, error) { + httpReq, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(req))) + if err != nil { + return nil, trace.Wrap(err) + } + + // Unset RequestURI and set req.URL instead (necessary quirk of sending a + // request parsed by http.ReadRequest). Also, force https here. + if httpReq.RequestURI != "/" { + return nil, trace.AccessDenied("unexpected sts identity request URI: %q", httpReq.RequestURI) + } + httpReq.RequestURI = "" + httpReq.URL = &url.URL{ + Scheme: "https", + Host: stsHost, + } + return httpReq, nil +} + +// awsIdentity holds aws Account and Arn, used for JSON parsing +type awsIdentity struct { + Account string `json:"Account"` + Arn string `json:"Arn"` +} + +// getCallerIdentityReponse is used for JSON parsing +type getCallerIdentityResponse struct { + GetCallerIdentityResult awsIdentity `json:"GetCallerIdentityResult"` +} + +// stsIdentityResponse is used for JSON parsing +type stsIdentityResponse struct { + GetCallerIdentityResponse getCallerIdentityResponse `json:"GetCallerIdentityResponse"` +} + +type stsClient interface { + Do(*http.Request) (*http.Response, error) +} + +type stsClientKey struct{} + +// stsClientFromContext allows the default http client to be overridden for tests +func stsClientFromContext(ctx context.Context) stsClient { + client, ok := ctx.Value(stsClientKey{}).(stsClient) + if ok { + return client + } + return http.DefaultClient +} + +// executeSTSIdentityRequest sends the sts:GetCallerIdentity HTTP request to the +// AWS API, parses the response, and returns the awsIdentity +func executeSTSIdentityRequest(ctx context.Context, req *http.Request) (*awsIdentity, error) { + client := stsClientFromContext(ctx) + + // set the http request context so it can be cancelled + req = req.WithContext(ctx) + resp, err := client.Do(req) + if err != nil { + return nil, trace.Wrap(err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, trace.Wrap(err) + } + + if resp.StatusCode != http.StatusOK { + return nil, trace.AccessDenied("aws sts api returned status: %q body: %q", + resp.Status, body) + } + + var identityResponse stsIdentityResponse + if err := json.Unmarshal(body, &identityResponse); err != nil { + return nil, trace.Wrap(err) + } + + id := &identityResponse.GetCallerIdentityResponse.GetCallerIdentityResult + if id.Account == "" { + return nil, trace.BadParameter("received empty AWS account ID from sts API") + } + if id.Arn == "" { + return nil, trace.BadParameter("received empty AWS identity ARN from sts API") + } + return id, nil +} + +// arnMatches returns true if arn matches the pattern. +// Pattern should be an AWS ARN which may include "*" to match any combination +// of zero or more characters and "?" to match any single character. +// See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html +func arnMatches(pattern, arn string) (bool, error) { + pattern = regexp.QuoteMeta(pattern) + pattern = strings.ReplaceAll(pattern, `\*`, ".*") + pattern = strings.ReplaceAll(pattern, `\?`, ".") + pattern = "^" + pattern + "$" + matched, err := regexp.MatchString(pattern, arn) + return matched, trace.Wrap(err) +} + +// checkIAMAllowRules checks if the given identity matches any of the given +// allowRules. +func checkIAMAllowRules(identity *awsIdentity, allowRules []*types.TokenRule) error { + for _, rule := range allowRules { + // if this rule specifies an AWS account, the identity must match + if len(rule.AWSAccount) > 0 { + if rule.AWSAccount != identity.Account { + // account doesn't match, continue to check the next rule + continue + } + } + // if this rule specifies an AWS ARN, the identity must match + if len(rule.AWSARN) > 0 { + matches, err := arnMatches(rule.AWSARN, identity.Arn) + if err != nil { + return trace.Wrap(err) + } + if !matches { + // arn doesn't match, continue to check the next rule + continue + } + } + // node identity matches this allow rule + return nil + } + return trace.AccessDenied("instance did not match any allow rules") +} + +// checkIAMRequest checks if the given request satisfies the token rules and +// included the required challenge. +func (a *Server) checkIAMRequest(ctx context.Context, challenge string, req *types.RegisterUsingTokenRequest) error { + tokenName := req.Token + provisionToken, err := a.GetToken(ctx, tokenName) + if err != nil { + return trace.Wrap(err) + } + if provisionToken.GetJoinMethod() != types.JoinMethodIAM { + return trace.AccessDenied("this token does not support the IAM join method") + } + + // parse the incoming http request to the sts:GetCallerIdentity endpoint + identityRequest, err := parseSTSRequest(req.STSIdentityRequest) + if err != nil { + return trace.Wrap(err) + } + + // validate that the host, method, and headers are correct and the expected + // challenge is included in the signed portion of the request + if err := validateSTSIdentityRequest(identityRequest, challenge); err != nil { + return trace.Wrap(err) + } + + // send the signed request to the public AWS API and get the node identity + // from the response + identity, err := executeSTSIdentityRequest(ctx, identityRequest) + if err != nil { + return trace.Wrap(err) + } + + // check that the node identity matches an allow rule for this token + if err := checkIAMAllowRules(identity, provisionToken.GetAllowRules()); err != nil { + return trace.Wrap(err) + } + + return nil +} + +func generateChallenge() (string, error) { + // read 32 crypto-random bytes to generate the challenge + challengeRawBytes := make([]byte, 32) + if _, err := rand.Read(challengeRawBytes); err != nil { + return "", trace.Wrap(err) + } + + // encode the challenge to base64 so it can be sent in an HTTP header + return base64.RawStdEncoding.EncodeToString(challengeRawBytes), nil +} + +// ChallengeResponseFunc is a function type meant to be passed to +// RegisterUsingIAMMethod. It must return a *types.RegisterUsingTokenRequest for +// a given challenge, or an error. +type ChallengeResponseFunc func(challenge string) (*types.RegisterUsingTokenRequest, error) + +// RegisterUsingIAMMethod registers the caller using the IAM join method and +// returns signed certs to join the cluster. +// +// The caller must provide a ChallengeResponseFunc which returns a +// *types.RegisterUsingTokenRequest with a signed sts:GetCallerIdentity request +// including the challenge as a signed header. +func (a *Server) RegisterUsingIAMMethod(ctx context.Context, challengeResponse ChallengeResponseFunc) (*proto.Certs, error) { + clientAddr, ok := ctx.Value(ContextClientAddr).(net.Addr) + if !ok { + return nil, trace.BadParameter("logic error: client address was not set") + } + + challenge, err := generateChallenge() + if err != nil { + return nil, trace.Wrap(err) + } + + req, err := challengeResponse(challenge) + if err != nil { + return nil, trace.Wrap(err) + } + + // fill in the client remote addr to the register request + req.RemoteAddr = clientAddr.String() + if err := req.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + + // perform common token checks + if err := a.checkTokenJoinRequestCommon(ctx, req); err != nil { + return nil, trace.Wrap(err) + } + + // check that the GetCallerIdentity request is valid and matches the token + if err := a.checkIAMRequest(ctx, challenge, req); err != nil { + return nil, trace.Wrap(err) + } + + // generate and return host certificate and keys + certs, err := a.GenerateHostCerts(ctx, + &proto.HostCertsRequest{ + HostID: req.HostID, + NodeName: req.NodeName, + Role: req.Role, + AdditionalPrincipals: req.AdditionalPrincipals, + PublicTLSKey: req.PublicTLSKey, + PublicSSHKey: req.PublicSSHKey, + RemoteAddr: req.RemoteAddr, + DNSNames: req.DNSNames, + }) + if err != nil { + return nil, trace.Wrap(err) + } + log.Infof("Node %q [%v] has joined the cluster.", req.NodeName, req.HostID) + return certs, nil +} diff --git a/lib/auth/join_iam_test.go b/lib/auth/join_iam_test.go new file mode 100644 index 0000000000000..ff9548badd8fb --- /dev/null +++ b/lib/auth/join_iam_test.go @@ -0,0 +1,422 @@ +/* +Copyright 2021-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 auth + +import ( + "context" + "fmt" + "io" + "net" + "net/http" + "strings" + "testing" + "time" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" +) + +func responseFromAWSIdentity(id awsIdentity) string { + return fmt.Sprintf(`{ + "GetCallerIdentityResponse": { + "GetCallerIdentityResult": { + "Account": "%s", + "Arn": "%s" + }}}`, id.Account, id.Arn) +} + +type mockClient struct { + respStatusCode int + respBody string +} + +func (c *mockClient) Do(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: c.respStatusCode, + Body: io.NopCloser(strings.NewReader(c.respBody)), + }, nil +} + +const identityRequestTemplate = `POST / HTTP/1.1 +Host: sts.amazonaws.com +User-Agent: aws-sdk-go/1.37.17 (go1.17.1; darwin; amd64) +Content-Length: 43 +Accept: application/json +Authorization: AWS4-HMAC-SHA256 Credential=AAAAAAAAAAAAAAAAAAAA/20211102/us-east-1/sts/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-date;x-amz-security-token;x-teleport-challenge, Signature=111 +Content-Type: application/x-www-form-urlencoded; charset=utf-8 +X-Amz-Date: 20211102T204300Z +X-Amz-Security-Token: aaa +X-Teleport-Challenge: %s + +Action=GetCallerIdentity&Version=2011-06-15` + +const wrongHostTemplate = `POST / HTTP/1.1 +Host: sts.example.com +User-Agent: aws-sdk-go/1.37.17 (go1.17.1; darwin; amd64) +Content-Length: 43 +Accept: application/json +Authorization: AWS4-HMAC-SHA256 Credential=AAAAAAAAAAAAAAAAAAAA/20211102/us-east-1/sts/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-date;x-amz-security-token;x-teleport-challenge, Signature=111 +Content-Type: application/x-www-form-urlencoded; charset=utf-8 +X-Amz-Date: 20211102T204300Z +X-Amz-Security-Token: aaa +X-Teleport-Challenge: %s + +Action=GetCallerIdentity&Version=2011-06-15` + +const unsignedChallengeTemplate = `POST / HTTP/1.1 +Host: sts.amazonaws.com +User-Agent: aws-sdk-go/1.37.17 (go1.17.1; darwin; amd64) +Content-Length: 43 +Accept: application/json +Authorization: AWS4-HMAC-SHA256 Credential=AAAAAAAAAAAAAAAAAAAA/20211102/us-east-1/sts/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-date;x-amz-security-token, Signature=111 +Content-Type: application/x-www-form-urlencoded; charset=utf-8 +X-Amz-Date: 20211102T204300Z +X-Amz-Security-Token: aaa +X-Teleport-Challenge: %s + +Action=GetCallerIdentity&Version=2011-06-15` + +func TestAuth_RegisterUsingIAMMethod(t *testing.T) { + ctx := context.Background() + p, err := newTestPack(ctx, t.TempDir()) + require.NoError(t, err) + a := p.a + + sshPrivateKey, sshPublicKey, err := a.GenerateKeyPair("") + require.NoError(t, err) + + tlsPublicKey, err := PrivateKeyToPublicKeyTLS(sshPrivateKey) + require.NoError(t, err) + + isAccessDenied := func(t require.TestingT, err error, _ ...interface{}) { + require.True(t, trace.IsAccessDenied(err), "expected Access Denied error, actual error: %v", err) + } + isBadParameter := func(t require.TestingT, err error, _ ...interface{}) { + require.True(t, trace.IsBadParameter(err), "expected Bad Parameter error, actual error: %v", err) + } + + testCases := []struct { + desc string + tokenName string + requestTokenName string + tokenSpec types.ProvisionTokenSpecV2 + stsClient stsClient + challengeResponseOverride string + requestTemplate string + challengeResponseErr error + assertError require.ErrorAssertionFunc + }{ + { + desc: "basic passing case", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::1111", + }), + }, + requestTemplate: identityRequestTemplate, + assertError: require.NoError, + }, + { + desc: "wildcard arn 1", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::role/admins-*", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::role/admins-test", + }), + }, + requestTemplate: identityRequestTemplate, + assertError: require.NoError, + }, + { + desc: "wildcard arn 2", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::role/admins-???", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::role/admins-123", + }), + }, + requestTemplate: identityRequestTemplate, + assertError: require.NoError, + }, + { + desc: "wrong token", + tokenName: "test-token", + requestTokenName: "wrong-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::1111", + }), + }, + requestTemplate: identityRequestTemplate, + assertError: isAccessDenied, + }, + { + desc: "challenge response error", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::1111", + }), + }, + requestTemplate: identityRequestTemplate, + challengeResponseErr: trace.BadParameter("test error"), + assertError: isBadParameter, + }, + { + desc: "wrong arn", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::role/admins-???", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::role/admins-1234", + }), + }, + requestTemplate: identityRequestTemplate, + assertError: isAccessDenied, + }, + { + desc: "wrong challenge", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::1111", + }), + }, + challengeResponseOverride: "wrong-challenge", + requestTemplate: identityRequestTemplate, + assertError: isAccessDenied, + }, + { + desc: "wrong account", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "5678", + Arn: "arn:aws::1111", + }), + }, + requestTemplate: identityRequestTemplate, + assertError: isAccessDenied, + }, + { + desc: "sts api error", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusForbidden, + respBody: "access denied", + }, + requestTemplate: identityRequestTemplate, + assertError: isAccessDenied, + }, + { + desc: "wrong sts host", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::1111", + }), + }, + requestTemplate: wrongHostTemplate, + assertError: isAccessDenied, + }, + { + desc: "unsigned challenge header", + tokenName: "test-token", + requestTokenName: "test-token", + tokenSpec: types.ProvisionTokenSpecV2{ + Roles: []types.SystemRole{types.RoleNode}, + Allow: []*types.TokenRule{ + &types.TokenRule{ + AWSAccount: "1234", + AWSARN: "arn:aws::1111", + }, + }, + JoinMethod: types.JoinMethodIAM, + }, + stsClient: &mockClient{ + respStatusCode: http.StatusOK, + respBody: responseFromAWSIdentity(awsIdentity{ + Account: "1234", + Arn: "arn:aws::1111", + }), + }, + requestTemplate: unsignedChallengeTemplate, + assertError: isAccessDenied, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + // add token to auth server + token, err := types.NewProvisionTokenFromSpec( + tc.tokenName, + time.Now().Add(time.Minute), + tc.tokenSpec) + require.NoError(t, err) + require.NoError(t, a.UpsertToken(ctx, token)) + t.Cleanup(func() { require.NoError(t, a.DeleteToken(ctx, token.GetName())) }) + + requestContext := context.Background() + requestContext = context.WithValue(requestContext, ContextClientAddr, &net.IPAddr{}) + requestContext = context.WithValue(requestContext, stsClientKey{}, tc.stsClient) + + _, err = a.RegisterUsingIAMMethod(requestContext, func(challenge string) (*types.RegisterUsingTokenRequest, error) { + if tc.challengeResponseOverride != "" { + challenge = tc.challengeResponseOverride + } + identityRequest := []byte(fmt.Sprintf(tc.requestTemplate, challenge)) + req := &types.RegisterUsingTokenRequest{ + Token: tc.requestTokenName, + HostID: "test-node", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + STSIdentityRequest: identityRequest, + } + return req, tc.challengeResponseErr + }) + tc.assertError(t, err) + }) + } +} diff --git a/lib/auth/join_test.go b/lib/auth/join_test.go new file mode 100644 index 0000000000000..5a7da88a11620 --- /dev/null +++ b/lib/auth/join_test.go @@ -0,0 +1,251 @@ +/* +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 auth + +import ( + "context" + "testing" + "time" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/sshutils" + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" +) + +func TestAuth_RegisterUsingToken(t *testing.T) { + ctx := context.Background() + p, err := newTestPack(ctx, t.TempDir()) + require.NoError(t, err) + a := p.a + + // create a static token + staticToken := types.ProvisionTokenV1{ + Roles: []types.SystemRole{types.RoleNode}, + Token: "static_token", + } + staticTokens, err := types.NewStaticTokens(types.StaticTokensSpecV2{ + StaticTokens: []types.ProvisionTokenV1{staticToken}, + }) + require.NoError(t, err) + err = p.a.SetStaticTokens(staticTokens) + require.NoError(t, err) + + // create a dynamic token + dynamicToken, err := a.GenerateToken(ctx, GenerateTokenRequest{ + Roles: types.SystemRoles{types.RoleNode}, + TTL: time.Hour, + }) + require.NoError(t, err) + require.NotNil(t, dynamicToken) + + sshPrivateKey, sshPublicKey, err := a.GenerateKeyPair("") + require.NoError(t, err) + + tlsPublicKey, err := PrivateKeyToPublicKeyTLS(sshPrivateKey) + require.NoError(t, err) + + testcases := []struct { + desc string + req *types.RegisterUsingTokenRequest + certsAssertion func(*proto.Certs) + errorAssertion func(error) bool + clock clockwork.Clock + }{ + { + desc: "reject empty", + req: &types.RegisterUsingTokenRequest{}, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "reject no token", + req: &types.RegisterUsingTokenRequest{ + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "reject no HostID", + req: &types.RegisterUsingTokenRequest{ + Token: staticToken.Token, + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "allow no NodeName", + req: &types.RegisterUsingTokenRequest{ + Token: staticToken.Token, + HostID: "localhost", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + }, + { + desc: "reject no SSH pub", + req: &types.RegisterUsingTokenRequest{ + Token: staticToken.Token, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicTLSKey: tlsPublicKey, + }, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "reject no TLS pub", + req: &types.RegisterUsingTokenRequest{ + Token: staticToken.Token, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + }, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "reject bad token", + req: &types.RegisterUsingTokenRequest{ + Token: "not a token", + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + errorAssertion: trace.IsAccessDenied, + }, + { + desc: "allow static token", + req: &types.RegisterUsingTokenRequest{ + Token: staticToken.Token, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + }, + { + desc: "reject wrong role static", + req: &types.RegisterUsingTokenRequest{ + Token: staticToken.Token, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleProxy, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "allow dynamic token", + req: &types.RegisterUsingTokenRequest{ + Token: dynamicToken, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + }, + { + desc: "reject wrong role dynamic", + req: &types.RegisterUsingTokenRequest{ + Token: dynamicToken, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleProxy, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + errorAssertion: trace.IsBadParameter, + }, + { + desc: "check additional pricipals", + req: &types.RegisterUsingTokenRequest{ + Token: dynamicToken, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + AdditionalPrincipals: []string{"example.com"}, + }, + certsAssertion: func(certs *proto.Certs) { + hostCert, err := sshutils.ParseCertificate(certs.SSH) + require.NoError(t, err) + require.Contains(t, hostCert.ValidPrincipals, "example.com") + }, + }, + { + desc: "reject expired dynamic token", + req: &types.RegisterUsingTokenRequest{ + Token: dynamicToken, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + clock: clockwork.NewFakeClockAt(time.Now().Add(time.Hour + 1)), + errorAssertion: trace.IsAccessDenied, + }, + { + // relies on token being deleted during previous testcase + desc: "expired token should be gone", + req: &types.RegisterUsingTokenRequest{ + Token: dynamicToken, + HostID: "localhost", + NodeName: "node-name", + Role: types.RoleNode, + PublicSSHKey: sshPublicKey, + PublicTLSKey: tlsPublicKey, + }, + clock: clockwork.NewRealClock(), + errorAssertion: trace.IsAccessDenied, + }, + } + + for _, tc := range testcases { + t.Run(tc.desc, func(t *testing.T) { + if tc.clock == nil { + tc.clock = clockwork.NewRealClock() + } + a.SetClock(tc.clock) + certs, err := a.RegisterUsingToken(ctx, tc.req) + if tc.errorAssertion != nil { + require.True(t, tc.errorAssertion(err)) + return + } + require.NoError(t, err) + if tc.certsAssertion != nil { + tc.certsAssertion(certs) + } + }) + } +} diff --git a/lib/auth/register.go b/lib/auth/register.go index 49b5d8b5ef1c1..58620665be634 100644 --- a/lib/auth/register.go +++ b/lib/auth/register.go @@ -227,17 +227,18 @@ func registerThroughAuth(token string, params RegisterParams) (*Identity, error) defer client.Close() // Get the SSH and X509 certificates for a node. - certs, err := client.RegisterUsingToken(types.RegisterUsingTokenRequest{ - Token: token, - HostID: params.ID.HostUUID, - NodeName: params.ID.NodeName, - Role: params.ID.Role, - AdditionalPrincipals: params.AdditionalPrincipals, - DNSNames: params.DNSNames, - PublicTLSKey: params.PublicTLSKey, - PublicSSHKey: params.PublicSSHKey, - EC2IdentityDocument: params.EC2IdentityDocument, - }) + certs, err := client.RegisterUsingToken(context.Background(), + &types.RegisterUsingTokenRequest{ + Token: token, + HostID: params.ID.HostUUID, + NodeName: params.ID.NodeName, + Role: params.ID.Role, + AdditionalPrincipals: params.AdditionalPrincipals, + DNSNames: params.DNSNames, + PublicTLSKey: params.PublicTLSKey, + PublicSSHKey: params.PublicSSHKey, + EC2IdentityDocument: params.EC2IdentityDocument, + }) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/trustedcluster.go b/lib/auth/trustedcluster.go index 2e61a07e5d84f..ee1d30b905eb5 100644 --- a/lib/auth/trustedcluster.go +++ b/lib/auth/trustedcluster.go @@ -452,7 +452,7 @@ func (a *Server) GetRemoteClusters(opts ...services.MarshalOption) ([]types.Remo return remoteClusters, nil } -func (a *Server) validateTrustedCluster(validateRequest *ValidateTrustedClusterRequest) (resp *ValidateTrustedClusterResponse, err error) { +func (a *Server) validateTrustedCluster(ctx context.Context, validateRequest *ValidateTrustedClusterRequest) (resp *ValidateTrustedClusterResponse, err error) { defer func() { if err != nil { log.WithError(err).Info("Trusted cluster validation failed") @@ -467,7 +467,7 @@ func (a *Server) validateTrustedCluster(validateRequest *ValidateTrustedClusterR } // validate that we generated the token - tokenLabels, err := a.validateTrustedClusterToken(validateRequest.Token) + tokenLabels, err := a.validateTrustedClusterToken(ctx, validateRequest.Token) if err != nil { return nil, trace.Wrap(err) } @@ -526,8 +526,8 @@ func (a *Server) validateTrustedCluster(validateRequest *ValidateTrustedClusterR return &validateResponse, nil } -func (a *Server) validateTrustedClusterToken(token string) (map[string]string, error) { - roles, labels, err := a.ValidateToken(token) +func (a *Server) validateTrustedClusterToken(ctx context.Context, token string) (map[string]string, error) { + roles, labels, err := a.ValidateToken(ctx, token) if err != nil { return nil, trace.AccessDenied("the remote server denied access: invalid cluster token") } diff --git a/lib/config/configuration.go b/lib/config/configuration.go index 6983f01410004..83abb69a31e7a 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -1960,7 +1960,7 @@ func splitRoles(roles string) []string { // applyTokenConfig applies the auth_token and join_params to the config func applyTokenConfig(fc *FileConfig, cfg *service.Config) error { if fc.AuthToken != "" { - cfg.JoinMethod = service.JoinMethodToken + cfg.JoinMethod = types.JoinMethodToken _, err := cfg.ApplyToken(fc.AuthToken) return trace.Wrap(err) } @@ -1972,7 +1972,7 @@ func applyTokenConfig(fc *FileConfig, cfg *service.Config) error { if fc.JoinParams.Method != "ec2" { return trace.BadParameter(`unknown value for join_params.method: %q, expected "ec2"`, fc.JoinParams.Method) } - cfg.JoinMethod = service.JoinMethodEC2 + cfg.JoinMethod = types.JoinMethodEC2 } return nil } diff --git a/lib/service/cfg.go b/lib/service/cfg.go index 6aa0159ae6513..acdabdef49031 100644 --- a/lib/service/cfg.go +++ b/lib/service/cfg.go @@ -87,7 +87,7 @@ type Config struct { Token string // JoinMethod is the method the instance will use to join the auth server - JoinMethod JoinMethod + JoinMethod types.JoinMethod // AuthServers is a list of auth servers, proxies and peer auth servers to // connect to. Yes, this is not just auth servers, the field name is @@ -1145,14 +1145,3 @@ func ApplyFIPSDefaults(cfg *Config) { // entire cluster is FedRAMP/FIPS 140-2 compliant. cfg.Auth.SessionRecordingConfig.SetMode(types.RecordAtNode) } - -// JoinMethod is the method the instance will use to join the auth server. -type JoinMethod int - -const ( - // JoinMethodToken means the instance will use a basic token. - JoinMethodToken JoinMethod = iota - // JoinMethodEC2 means the instance will use Simplified Node Joining and send an - // EC2 Instance Identity Document. - JoinMethodEC2 -) diff --git a/lib/service/connect.go b/lib/service/connect.go index a1c836b16d63f..84c17948b01ae 100644 --- a/lib/service/connect.go +++ b/lib/service/connect.go @@ -382,7 +382,7 @@ func (process *TeleportProcess) firstTimeConnect(role types.SystemRole) (*Connec } var ec2IdentityDocument []byte - if process.Config.JoinMethod == JoinMethodEC2 { + if process.Config.JoinMethod == types.JoinMethodEC2 { ec2IdentityDocument, err = utils.GetEC2IdentityDocument() if err != nil { return nil, trace.Wrap(err) diff --git a/lib/service/service.go b/lib/service/service.go index 825ea3998e408..b059e6be6bef2 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -648,9 +648,9 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { cfg.Log.Infof("Taking host UUID from first identity: %v.", cfg.HostUUID) } else { switch cfg.JoinMethod { - case JoinMethodToken: + case types.JoinMethodToken, types.JoinMethodUnspecified, types.JoinMethodIAM: cfg.HostUUID = uuid.New().String() - case JoinMethodEC2: + case types.JoinMethodEC2: cfg.HostUUID, err = utils.GetEC2NodeID() if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/alpnproxy/local_proxy.go b/lib/srv/alpnproxy/local_proxy.go index 9715c0ab39dd7..31eb5c21cb238 100644 --- a/lib/srv/alpnproxy/local_proxy.go +++ b/lib/srv/alpnproxy/local_proxy.go @@ -34,8 +34,8 @@ import ( "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/srv/alpnproxy/common" - appaws "github.com/gravitational/teleport/lib/srv/app/aws" "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/lib/utils/aws" ) // LocalProxy allows upgrading incoming connection to TLS where custom TLS values are set SNI ALPN and @@ -323,7 +323,7 @@ func (l *LocalProxy) StartAWSAccessProxy(ctx context.Context) error { Transport: tr, } err := http.Serve(l.cfg.Listener, http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - if err := appaws.VerifyAWSSignature(req, l.cfg.AWSCredentials); err != nil { + if err := aws.VerifyAWSSignature(req, l.cfg.AWSCredentials); err != nil { log.WithError(err).Errorf("AWS signature verification failed.") rw.WriteHeader(http.StatusForbidden) return diff --git a/lib/srv/app/aws/handler.go b/lib/srv/app/aws/handler.go index dd963068c5b80..4a5a820cb099e 100644 --- a/lib/srv/app/aws/handler.go +++ b/lib/srv/app/aws/handler.go @@ -38,6 +38,7 @@ import ( "github.com/gravitational/teleport/lib/defaults" appcommon "github.com/gravitational/teleport/lib/srv/app/common" "github.com/gravitational/teleport/lib/tlsca" + awsutils "github.com/gravitational/teleport/lib/utils/aws" ) // NewSigningService creates a new instance of SigningService. @@ -187,7 +188,7 @@ func (s *SigningService) formatForwardResponseError(rw http.ResponseWriter, r *h // resolveEndpoint extracts the aws-service on and aws-region from the request authorization header // and resolves the aws-service and aws-region to AWS endpoint. func resolveEndpoint(r *http.Request) (*endpoints.ResolvedEndpoint, error) { - awsAuthHeader, err := ParseSigV4(r.Header.Get(authorizationHeader)) + awsAuthHeader, err := awsutils.ParseSigV4(r.Header.Get(awsutils.AuthorizationHeader)) if err != nil { return nil, trace.Wrap(err) } @@ -201,7 +202,7 @@ func resolveEndpoint(r *http.Request) (*endpoints.ResolvedEndpoint, error) { // prepareSignedRequest creates a new HTTP request and rewrites the header from the original request and returns a new // HTTP request signed by STS AWS API. func (s *SigningService) prepareSignedRequest(r *http.Request, re *endpoints.ResolvedEndpoint, identity *tlsca.Identity) (*http.Request, error) { - payload, err := GetAndReplaceReqBody(r) + payload, err := awsutils.GetAndReplaceReqBody(r) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/app/aws/handler_test.go b/lib/srv/app/aws/handler_test.go index 9df0a07d82d45..ae0547d250803 100644 --- a/lib/srv/app/aws/handler_test.go +++ b/lib/srv/app/aws/handler_test.go @@ -35,6 +35,7 @@ import ( "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/tlsca" + awsutils "github.com/gravitational/teleport/lib/utils/aws" ) // TestAWSSignerHandler test the AWS SigningService APP handler logic with mocked STS signing credentials. @@ -117,7 +118,7 @@ func TestAWSSignerHandler(t *testing.T) { t.Run(tc.name, func(t *testing.T) { handler := func(writer http.ResponseWriter, request *http.Request) { require.Equal(t, tc.wantHost, request.Host) - awsAuthHeader, err := ParseSigV4(request.Header.Get(authorizationHeader)) + awsAuthHeader, err := awsutils.ParseSigV4(request.Header.Get(awsutils.AuthorizationHeader)) require.NoError(t, err) require.Equal(t, tc.wantAuthCredRegion, awsAuthHeader.Region) require.Equal(t, tc.wantAuthCredKeyID, awsAuthHeader.KeyID) diff --git a/lib/srv/app/server.go b/lib/srv/app/server.go index f9ebe1d306a06..148a039f3c3dc 100644 --- a/lib/srv/app/server.go +++ b/lib/srv/app/server.go @@ -41,6 +41,7 @@ import ( appaws "github.com/gravitational/teleport/lib/srv/app/aws" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/lib/utils/aws" "github.com/gravitational/trace" @@ -591,7 +592,7 @@ func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) error { // access from AWS CLI where the request is already singed by the AWS Signature Version 4 algorithm. // AWS CLI, automatically use SigV4 for all services that support it (All services expect Amazon SimpleDB // but this AWS service has been deprecated) - if appaws.IsSignedByAWSSigV4(r) && app.IsAWSConsole() { + if aws.IsSignedByAWSSigV4(r) && app.IsAWSConsole() { // Sign the request based on RouteToApp.AWSRoleARN user identity and route signed request to the AWS API. s.awsSigner.Handle(w, r) return nil diff --git a/lib/utils/aws.go b/lib/utils/aws.go deleted file mode 100644 index da4edc2efbf68..0000000000000 --- a/lib/utils/aws.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -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 utils - -import ( - "strings" - - "github.com/aws/aws-sdk-go/aws/arn" -) - -// FilterAWSRoles returns role ARNs from the provided list that belong to the -// specified AWS account ID. -// -// If AWS account ID is empty, all roles are returned. -func FilterAWSRoles(arns []string, accountID string) (result []AWSRole) { - for _, roleARN := range arns { - parsed, err := arn.Parse(roleARN) - if err != nil || (accountID != "" && parsed.AccountID != accountID) { - continue - } - - // In AWS convention, the display of the role is the last - // /-delineated substring. - // - // Example ARNs: - // arn:aws:iam::1234567890:role/EC2FullAccess (display: EC2FullAccess) - // arn:aws:iam::1234567890:role/path/to/customrole (display: customrole) - parts := strings.Split(parsed.Resource, "/") - numParts := len(parts) - if numParts < 2 || parts[0] != "role" { - continue - } - result = append(result, AWSRole{ - Display: parts[numParts-1], - ARN: roleARN, - }) - } - return result -} - -// AWSRole describes an AWS IAM role for AWS console access. -type AWSRole struct { - // Display is the role display name. - Display string `json:"display"` - // ARN is the full role ARN. - ARN string `json:"arn"` -} diff --git a/lib/srv/app/aws/aws.go b/lib/utils/aws/aws.go similarity index 84% rename from lib/srv/app/aws/aws.go rename to lib/utils/aws/aws.go index d3871a2933786..41408446a5e0e 100644 --- a/lib/srv/app/aws/aws.go +++ b/lib/utils/aws/aws.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/aws/credentials" v4 "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/gravitational/trace" @@ -45,7 +46,7 @@ const ( // https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html AmzDateHeader = "X-Amz-Date" - authorizationHeader = "Authorization" + AuthorizationHeader = "Authorization" credentialAuthHeaderElem = "Credential" signedHeaderAuthHeaderElem = "SignedHeaders" signatureAuthHeaderElem = "Signature" @@ -118,7 +119,7 @@ func ParseSigV4(header string) (*SigV4, error) { // IsSignedByAWSSigV4 checks is the request was signed by AWS Signature Version 4 algorithm. // https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html func IsSignedByAWSSigV4(r *http.Request) bool { - return strings.HasPrefix(r.Header.Get(authorizationHeader), AmazonSigV4AuthorizationPrefix) + return strings.HasPrefix(r.Header.Get(AuthorizationHeader), AmazonSigV4AuthorizationPrefix) } // GetAndReplaceReqBody returns the request and replace the drained body reader with io.NopCloser @@ -208,3 +209,41 @@ func filterHeaders(r *http.Request, headers []string) { } r.Header = out } + +// FilterAWSRoles returns role ARNs from the provided list that belong to the +// specified AWS account ID. +// +// If AWS account ID is empty, all roles are returned. +func FilterAWSRoles(arns []string, accountID string) (result []AWSRole) { + for _, roleARN := range arns { + parsed, err := arn.Parse(roleARN) + if err != nil || (accountID != "" && parsed.AccountID != accountID) { + continue + } + + // In AWS convention, the display of the role is the last + // /-delineated substring. + // + // Example ARNs: + // arn:aws:iam::1234567890:role/EC2FullAccess (display: EC2FullAccess) + // arn:aws:iam::1234567890:role/path/to/customrole (display: customrole) + parts := strings.Split(parsed.Resource, "/") + numParts := len(parts) + if numParts < 2 || parts[0] != "role" { + continue + } + result = append(result, AWSRole{ + Display: parts[numParts-1], + ARN: roleARN, + }) + } + return result +} + +// AWSRole describes an AWS IAM role for AWS console access. +type AWSRole struct { + // Display is the role display name. + Display string `json:"display"` + // ARN is the full role ARN. + ARN string `json:"arn"` +} diff --git a/lib/srv/app/aws/aws_test.go b/lib/utils/aws/aws_test.go similarity index 68% rename from lib/srv/app/aws/aws_test.go rename to lib/utils/aws/aws_test.go index 1f1874911cb07..832111d09e572 100644 --- a/lib/srv/app/aws/aws_test.go +++ b/lib/utils/aws/aws_test.go @@ -89,3 +89,53 @@ func TestExtractCredFromAuthHeader(t *testing.T) { }) } } + +// TestFilterAWSRoles verifies filtering AWS role ARNs by AWS account ID. +func TestFilterAWSRoles(t *testing.T) { + acc1ARN1 := AWSRole{ + ARN: "arn:aws:iam::1234567890:role/EC2FullAccess", + Display: "EC2FullAccess", + } + acc1ARN2 := AWSRole{ + ARN: "arn:aws:iam::1234567890:role/EC2ReadOnly", + Display: "EC2ReadOnly", + } + acc1ARN3 := AWSRole{ + ARN: "arn:aws:iam::1234567890:role/path/to/customrole", + Display: "customrole", + } + acc2ARN1 := AWSRole{ + ARN: "arn:aws:iam::0987654321:role/test-role", + Display: "test-role", + } + invalidARN := AWSRole{ + ARN: "invalid-arn", + } + allARNS := []string{ + acc1ARN1.ARN, acc1ARN2.ARN, acc1ARN3.ARN, acc2ARN1.ARN, invalidARN.ARN, + } + tests := []struct { + name string + accountID string + outARNs []AWSRole + }{ + { + name: "first account roles", + accountID: "1234567890", + outARNs: []AWSRole{acc1ARN1, acc1ARN2, acc1ARN3}, + }, + { + name: "second account roles", + accountID: "0987654321", + outARNs: []AWSRole{acc2ARN1}, + }, + { + name: "all roles", + accountID: "", + outARNs: []AWSRole{acc1ARN1, acc1ARN2, acc1ARN3, acc2ARN1}, + }, + } + for _, test := range tests { + require.Equal(t, test.outARNs, FilterAWSRoles(allARNS, test.accountID)) + } +} diff --git a/lib/utils/aws_test.go b/lib/utils/aws_test.go deleted file mode 100644 index 6295cc18fd67b..0000000000000 --- a/lib/utils/aws_test.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -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 utils - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -// TestFilterAWSRoles verifies filtering AWS role ARNs by AWS account ID. -func TestFilterAWSRoles(t *testing.T) { - acc1ARN1 := AWSRole{ - ARN: "arn:aws:iam::1234567890:role/EC2FullAccess", - Display: "EC2FullAccess", - } - acc1ARN2 := AWSRole{ - ARN: "arn:aws:iam::1234567890:role/EC2ReadOnly", - Display: "EC2ReadOnly", - } - acc1ARN3 := AWSRole{ - ARN: "arn:aws:iam::1234567890:role/path/to/customrole", - Display: "customrole", - } - acc2ARN1 := AWSRole{ - ARN: "arn:aws:iam::0987654321:role/test-role", - Display: "test-role", - } - invalidARN := AWSRole{ - ARN: "invalid-arn", - } - allARNS := []string{ - acc1ARN1.ARN, acc1ARN2.ARN, acc1ARN3.ARN, acc2ARN1.ARN, invalidARN.ARN, - } - tests := []struct { - name string - accountID string - outARNs []AWSRole - }{ - { - name: "first account roles", - accountID: "1234567890", - outARNs: []AWSRole{acc1ARN1, acc1ARN2, acc1ARN3}, - }, - { - name: "second account roles", - accountID: "0987654321", - outARNs: []AWSRole{acc2ARN1}, - }, - { - name: "all roles", - accountID: "", - outARNs: []AWSRole{acc1ARN1, acc1ARN2, acc1ARN3, acc2ARN1}, - }, - } - for _, test := range tests { - require.Equal(t, test.outARNs, FilterAWSRoles(allARNS, test.accountID)) - } -} diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index 01c8085407874..8899bc6b6391f 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -2318,7 +2318,7 @@ func (h *Handler) hostCredentials(w http.ResponseWriter, r *http.Request, p http } authClient := h.cfg.ProxyClient - certs, err := authClient.RegisterUsingToken(req) + certs, err := authClient.RegisterUsingToken(r.Context(), &req) if err != nil { return nil, trace.Wrap(err) } @@ -2397,7 +2397,7 @@ func (h *Handler) validateTrustedCluster(w http.ResponseWriter, r *http.Request, return nil, trace.Wrap(err) } - validateResponse, err := h.auth.ValidateTrustedCluster(validateRequest) + validateResponse, err := h.auth.ValidateTrustedCluster(r.Context(), validateRequest) if err != nil { h.log.WithError(err).Error("Failed validating trusted cluster") if trace.IsAccessDenied(err) { diff --git a/lib/web/sessions.go b/lib/web/sessions.go index a4fca307fbd87..896d5dad3408b 100644 --- a/lib/web/sessions.go +++ b/lib/web/sessions.go @@ -666,8 +666,8 @@ func (s *sessionCache) Ping(ctx context.Context) (proto.PingResponse, error) { return s.proxyClient.Ping(ctx) } -func (s *sessionCache) ValidateTrustedCluster(validateRequest *auth.ValidateTrustedClusterRequest) (*auth.ValidateTrustedClusterResponse, error) { - return s.proxyClient.ValidateTrustedCluster(validateRequest) +func (s *sessionCache) ValidateTrustedCluster(ctx context.Context, validateRequest *auth.ValidateTrustedClusterRequest) (*auth.ValidateTrustedClusterResponse, error) { + return s.proxyClient.ValidateTrustedCluster(ctx, validateRequest) } // validateSession validates the session given with user and session ID. diff --git a/lib/web/ui/app.go b/lib/web/ui/app.go index fdec68400dac8..0f04bdafc71f2 100644 --- a/lib/web/ui/app.go +++ b/lib/web/ui/app.go @@ -22,7 +22,7 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/tlsca" - "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/lib/utils/aws" ) // App describes an application @@ -44,7 +44,7 @@ type App struct { // AWSConsole if true, indicates that the app represents AWS management console. AWSConsole bool `json:"awsConsole"` // AWSRoles is a list of AWS IAM roles for the application representing AWS console. - AWSRoles []utils.AWSRole `json:"awsRoles,omitempty"` + AWSRoles []aws.AWSRole `json:"awsRoles,omitempty"` } // MakeAppsConfig contains parameters for converting apps to UI representation. @@ -88,7 +88,7 @@ func MakeApps(c MakeAppsConfig) []App { } if teleApp.IsAWSConsole() { - app.AWSRoles = utils.FilterAWSRoles(c.Identity.AWSRoleARNs, + app.AWSRoles = aws.FilterAWSRoles(c.Identity.AWSRoleARNs, teleApp.GetAWSAccountID()) }