diff --git a/api/client/client.go b/api/client/client.go index f0b04ec8a25b2..b600223535d9e 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -478,7 +478,7 @@ func (c *Client) dialGRPC(ctx context.Context, addr string) error { otelUnaryClientInterceptor(), metadata.UnaryClientInterceptor, interceptors.GRPCClientUnaryErrorInterceptor, - interceptors.WithMFAUnaryInterceptor(c.performMFACeremony), + interceptors.WithMFAUnaryInterceptor(c.performAdminActionMFACeremony), breaker.UnaryClientInterceptor(cb), ), grpc.WithChainStreamInterceptor( diff --git a/api/client/mfa.go b/api/client/mfa.go index cc81ca66405d6..a4538f2913c77 100644 --- a/api/client/mfa.go +++ b/api/client/mfa.go @@ -23,17 +23,19 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/mfa" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" ) -// performMFACeremony retrieves an MFA challenge from the server, prompts the -// user to answer the challenge, and returns the resulting MFA response. -func (c *Client) performMFACeremony(ctx context.Context, promptOpts ...mfa.PromptOpt) (*proto.MFAAuthenticateResponse, error) { +// performAdminActionMFACeremony retrieves an MFA challenge from the server, +// prompts the user to answer the challenge, and returns the resulting MFA response. +func (c *Client) performAdminActionMFACeremony(ctx context.Context, promptOpts ...mfa.PromptOpt) (*proto.MFAAuthenticateResponse, error) { if c.c.MFAPromptConstructor == nil { return nil, trace.BadParameter("missing PromptAdminRequestMFA field, client cannot perform MFA ceremony") } chal, err := c.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{ Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{}, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, }) if err != nil { return nil, trace.Wrap(err) diff --git a/api/client/mfa_test.go b/api/client/mfa_test.go index 22ae22d69cd40..9550c4f4b2d2c 100644 --- a/api/client/mfa_test.go +++ b/api/client/mfa_test.go @@ -70,7 +70,7 @@ func TestPerformMFACeremony(t *testing.T) { clt, err := New(ctx, cfg) require.NoError(t, err) - resp, err := clt.performMFACeremony(ctx) + resp, err := clt.performAdminActionMFACeremony(ctx) require.NoError(t, err) require.Equal(t, mfaTestResp.Response, resp.Response) } diff --git a/api/client/proto/authservice.pb.go b/api/client/proto/authservice.pb.go index 284ef92c81317..9c45a4d163a2c 100644 --- a/api/client/proto/authservice.pb.go +++ b/api/client/proto/authservice.pb.go @@ -6033,10 +6033,19 @@ type MFAAuthenticateChallenge struct { // If `MFA_REQUIRED_NO` is returned then the server may opt to end ongoing // communications, in case of streaming RPCs. It may also return empty // challenges for all other fields. - MFARequired MFARequired `protobuf:"varint,4,opt,name=MFARequired,proto3,enum=proto.MFARequired" json:"MFARequired,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + MFARequired MFARequired `protobuf:"varint,4,opt,name=MFARequired,proto3,enum=proto.MFARequired" json:"MFARequired,omitempty"` + // Scope is an authorization scope for this MFA challenge. + // Required. Only applies to webauthn challenges. + Scope webauthn.ChallengeScope `protobuf:"varint,5,opt,name=Scope,proto3,enum=webauthn.ChallengeScope" json:"scope,omitempty"` + // AllowReuse means webauthn credentials resolved from this challenge can be + // reused for a short span of time before the challenge expires. + // + // Reuse is only permitted for specific actions by the discretion of the server. + // See the server implementation for details. + AllowReuse bool `protobuf:"varint,6,opt,name=AllowReuse,proto3" json:"allow_reuse,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *MFAAuthenticateChallenge) Reset() { *m = MFAAuthenticateChallenge{} } @@ -6093,16 +6102,39 @@ func (m *MFAAuthenticateChallenge) GetMFARequired() MFARequired { return MFARequired_MFA_REQUIRED_UNSPECIFIED } +func (m *MFAAuthenticateChallenge) GetScope() webauthn.ChallengeScope { + if m != nil { + return m.Scope + } + return webauthn.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED +} + +func (m *MFAAuthenticateChallenge) GetAllowReuse() bool { + if m != nil { + return m.AllowReuse + } + return false +} + // MFAAuthenticateResponse is a response to MFAAuthenticateChallenge using one // of the MFA devices registered for a user. type MFAAuthenticateResponse struct { // Types that are valid to be assigned to Response: // *MFAAuthenticateResponse_TOTP // *MFAAuthenticateResponse_Webauthn - Response isMFAAuthenticateResponse_Response `protobuf_oneof:"Response"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Response isMFAAuthenticateResponse_Response `protobuf_oneof:"Response"` + // Scope is an authorization scope for this MFA challenge response. + // Required. Only applies to webauthn challenges. + Scope webauthn.ChallengeScope `protobuf:"varint,4,opt,name=Scope,proto3,enum=webauthn.ChallengeScope" json:"scope,omitempty"` + // AllowReuse means webauthn credentials resolved from this challenge can be + // reused for a short span of time before the challenge expires. + // + // Reuse is only permitted for specific actions by the discretion of the server. + // See the server implementation for details. + AllowReuse bool `protobuf:"varint,5,opt,name=AllowReuse,proto3" json:"allow_reuse,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *MFAAuthenticateResponse) Reset() { *m = MFAAuthenticateResponse{} } @@ -6175,6 +6207,20 @@ func (m *MFAAuthenticateResponse) GetWebauthn() *webauthn.CredentialAssertionRes return nil } +func (m *MFAAuthenticateResponse) GetScope() webauthn.ChallengeScope { + if m != nil { + return m.Scope + } + return webauthn.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED +} + +func (m *MFAAuthenticateResponse) GetAllowReuse() bool { + if m != nil { + return m.AllowReuse + } + return false +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*MFAAuthenticateResponse) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -10424,10 +10470,19 @@ type CreateAuthenticateChallengeRequest struct { // MFA verification should run in the cluster that holds the target resource. // If you are issuing challenges from the root cluster, but accessing a leaf, // call [AuthService.IsMFARequired] in the leaf instead of setting this field. - MFARequiredCheck *IsMFARequiredRequest `protobuf:"bytes,5,opt,name=MFARequiredCheck,proto3" json:"mfa_required_check,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + MFARequiredCheck *IsMFARequiredRequest `protobuf:"bytes,5,opt,name=MFARequiredCheck,proto3" json:"mfa_required_check,omitempty"` + // Scope is an authorization scope for this MFA challenge. + // Required. Only applies to webauthn challenges. + Scope webauthn.ChallengeScope `protobuf:"varint,6,opt,name=Scope,proto3,enum=webauthn.ChallengeScope" json:"scope,omitempty"` + // AllowReuse means webauthn credentials resolved from this challenge can be + // reused for a short span of time before the challenge expires. + // + // Reuse is only permitted for specific actions by the discretion of the server. + // See the server implementation for details. + AllowReuse bool `protobuf:"varint,7,opt,name=AllowReuse,proto3" json:"allow_reuse,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CreateAuthenticateChallengeRequest) Reset() { *m = CreateAuthenticateChallengeRequest{} } @@ -10533,6 +10588,20 @@ func (m *CreateAuthenticateChallengeRequest) GetMFARequiredCheck() *IsMFARequire return nil } +func (m *CreateAuthenticateChallengeRequest) GetScope() webauthn.ChallengeScope { + if m != nil { + return m.Scope + } + return webauthn.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED +} + +func (m *CreateAuthenticateChallengeRequest) GetAllowReuse() bool { + if m != nil { + return m.AllowReuse + } + return false +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*CreateAuthenticateChallengeRequest) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -15208,866 +15277,871 @@ func init() { } var fileDescriptor_0ffcffcda38ae159 = []byte{ - // 13739 bytes of a gzipped FileDescriptorProto + // 13815 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0xbd, 0x5b, 0x6c, 0x1c, 0x49, 0x96, 0x18, 0xca, 0x2a, 0x92, 0x22, 0x79, 0xf8, 0x2a, 0x05, 0x49, 0x91, 0x2a, 0x51, 0x2a, 0x29, 0xd5, 0x52, 0xab, 0x35, 0x33, 0x7a, 0x50, 0xdd, 0x3d, 0xfd, 0xee, 0xa9, 0x2a, 0x52, 0x24, 0x25, - 0x3e, 0xaa, 0xb3, 0xf8, 0xe8, 0x9e, 0xe9, 0x9d, 0x9a, 0x64, 0x55, 0x88, 0xcc, 0xab, 0x62, 0x66, - 0x4d, 0x66, 0x96, 0x1e, 0xb3, 0x77, 0xf7, 0xde, 0xf5, 0xda, 0x0b, 0xff, 0x78, 0xbd, 0x06, 0x76, - 0x8d, 0x5d, 0x78, 0x81, 0xb5, 0x61, 0x1b, 0xb0, 0x0d, 0x18, 0xd8, 0x1f, 0x63, 0x3f, 0xfc, 0x65, - 0xd8, 0x80, 0xc7, 0x06, 0x16, 0x30, 0xb0, 0x6b, 0x18, 0xf0, 0x07, 0xd7, 0x3b, 0x80, 0x7f, 0x88, - 0xf5, 0x87, 0x61, 0xd8, 0x86, 0x07, 0x36, 0x60, 0xc4, 0x33, 0x23, 0xf2, 0x55, 0x45, 0x49, 0x3d, - 0xf6, 0x8f, 0xc4, 0x8a, 0x38, 0xe7, 0x44, 0xc4, 0x89, 0xc8, 0x88, 0x13, 0x27, 0xce, 0x03, 0xee, - 0x04, 0xb8, 0x8d, 0x3b, 0xae, 0x17, 0xdc, 0x6d, 0xe3, 0x43, 0xab, 0xf9, 0xf2, 0x6e, 0xb3, 0x6d, - 0x63, 0x27, 0xb8, 0xdb, 0xf1, 0xdc, 0xc0, 0xbd, 0x6b, 0x75, 0x83, 0x23, 0x1f, 0x7b, 0xcf, 0xec, - 0x26, 0xbe, 0x43, 0x4b, 0xd0, 0x30, 0xfd, 0xaf, 0x38, 0x7b, 0xe8, 0x1e, 0xba, 0x0c, 0x86, 0xfc, - 0xc5, 0x2a, 0x8b, 0x97, 0x0e, 0x5d, 0xf7, 0xb0, 0x8d, 0x19, 0xf2, 0x41, 0xf7, 0xc9, 0x5d, 0x7c, - 0xdc, 0x09, 0x5e, 0xf2, 0xca, 0x52, 0xb4, 0x32, 0xb0, 0x8f, 0xb1, 0x1f, 0x58, 0xc7, 0x1d, 0x0e, - 0xf0, 0x8e, 0xec, 0x8a, 0x15, 0x04, 0xa4, 0x26, 0xb0, 0x5d, 0xe7, 0xee, 0xb3, 0xfb, 0xea, 0x4f, - 0x0e, 0x7a, 0x2b, 0xb3, 0xd7, 0x4d, 0xec, 0x05, 0x7e, 0x5f, 0x90, 0xf8, 0x19, 0x76, 0x82, 0x58, - 0xf3, 0x1c, 0x32, 0x78, 0xd9, 0xc1, 0x3e, 0x03, 0x11, 0xff, 0x71, 0xd0, 0x6b, 0xc9, 0xa0, 0xf4, - 0x5f, 0x0e, 0xf2, 0x9d, 0x64, 0x90, 0xe7, 0xf8, 0x80, 0xf0, 0xd4, 0x91, 0x7f, 0xf4, 0x00, 0xf7, - 0xac, 0x4e, 0x07, 0x7b, 0xe1, 0x1f, 0xb1, 0xbe, 0x76, 0x7d, 0xeb, 0x10, 0xf3, 0x3e, 0x3e, 0xbb, - 0xaf, 0xfe, 0x64, 0xa0, 0xc6, 0x1f, 0xe4, 0x60, 0x78, 0xdf, 0x0a, 0x9a, 0x47, 0xe8, 0x73, 0x18, - 0x7e, 0x6c, 0x3b, 0x2d, 0x7f, 0x21, 0x77, 0x75, 0xf0, 0xd6, 0xf8, 0x52, 0xe1, 0x0e, 0xeb, 0x2f, - 0xad, 0x24, 0x15, 0x95, 0xf9, 0x9f, 0x9e, 0x94, 0x06, 0x4e, 0x4f, 0x4a, 0xd3, 0x4f, 0x09, 0xd8, - 0xb7, 0xdd, 0x63, 0x3b, 0xa0, 0x13, 0x68, 0x32, 0x3c, 0xb4, 0x0b, 0x33, 0xe5, 0x76, 0xdb, 0x7d, - 0x5e, 0xb3, 0xbc, 0xc0, 0xb6, 0xda, 0xf5, 0x6e, 0xb3, 0x89, 0x7d, 0x7f, 0x21, 0x7f, 0x35, 0x77, - 0x6b, 0xb4, 0x72, 0xfd, 0xf4, 0xa4, 0x54, 0xb2, 0x48, 0x75, 0xa3, 0xc3, 0xea, 0x1b, 0x3e, 0x03, - 0x50, 0x08, 0x25, 0xe1, 0x1b, 0x7f, 0x31, 0x0c, 0x85, 0x35, 0xd7, 0x0f, 0xaa, 0x64, 0xda, 0x4c, - 0xfc, 0xe3, 0x2e, 0xf6, 0x03, 0x74, 0x1d, 0xce, 0x91, 0xb2, 0xf5, 0xe5, 0x85, 0xdc, 0xd5, 0xdc, - 0xad, 0xb1, 0xca, 0xf8, 0xe9, 0x49, 0x69, 0xe4, 0xc8, 0xf5, 0x83, 0x86, 0xdd, 0x32, 0x79, 0x15, - 0x7a, 0x07, 0x46, 0xb7, 0xdc, 0x16, 0xde, 0xb2, 0x8e, 0x31, 0xed, 0xc5, 0x58, 0x65, 0xf2, 0xf4, - 0xa4, 0x34, 0xe6, 0xb8, 0x2d, 0xdc, 0x70, 0xac, 0x63, 0x6c, 0xca, 0x6a, 0xb4, 0x07, 0x43, 0xa6, - 0xdb, 0xc6, 0x0b, 0x83, 0x14, 0xac, 0x72, 0x7a, 0x52, 0x1a, 0xf2, 0xdc, 0x36, 0xfe, 0xf9, 0x49, - 0xe9, 0xfd, 0x43, 0x3b, 0x38, 0xea, 0x1e, 0xdc, 0x69, 0xba, 0xc7, 0x77, 0x0f, 0x3d, 0xeb, 0x99, - 0xcd, 0x56, 0x9a, 0xd5, 0xbe, 0x1b, 0xae, 0xc7, 0x8e, 0xcd, 0x27, 0xb7, 0xfe, 0xd2, 0x0f, 0xf0, - 0x31, 0xa1, 0x64, 0x52, 0x7a, 0x68, 0x1f, 0x66, 0xcb, 0xad, 0x96, 0xcd, 0x30, 0x6a, 0x9e, 0xed, - 0x34, 0xed, 0x8e, 0xd5, 0xf6, 0x17, 0x86, 0xae, 0x0e, 0xde, 0x1a, 0xe3, 0x4c, 0x91, 0xf5, 0x8d, - 0x8e, 0x04, 0x50, 0x98, 0x92, 0x48, 0x00, 0x3d, 0x80, 0xd1, 0xe5, 0xad, 0x3a, 0xe9, 0xbb, 0xbf, - 0x30, 0x4c, 0x89, 0xcd, 0x9f, 0x9e, 0x94, 0x66, 0x5a, 0x8e, 0x4f, 0x87, 0xa6, 0x12, 0x90, 0x80, - 0xe8, 0x7d, 0x98, 0xa8, 0x75, 0x0f, 0xda, 0x76, 0x73, 0x67, 0xa3, 0xfe, 0x18, 0xbf, 0x5c, 0x38, - 0x77, 0x35, 0x77, 0x6b, 0xa2, 0x82, 0x4e, 0x4f, 0x4a, 0x53, 0x1d, 0x5a, 0xde, 0x08, 0xda, 0x7e, - 0xe3, 0x29, 0x7e, 0x69, 0x6a, 0x70, 0x21, 0x5e, 0xbd, 0xbe, 0x46, 0xf0, 0x46, 0x62, 0x78, 0xbe, - 0x7f, 0xa4, 0xe2, 0x31, 0x38, 0x74, 0x17, 0xc0, 0xc4, 0xc7, 0x6e, 0x80, 0xcb, 0xad, 0x96, 0xb7, - 0x30, 0x4a, 0x79, 0x3b, 0x7d, 0x7a, 0x52, 0x1a, 0xf7, 0x68, 0x69, 0xc3, 0x6a, 0xb5, 0x3c, 0x53, - 0x01, 0x41, 0x55, 0x18, 0x35, 0x5d, 0xc6, 0xe0, 0x85, 0xb1, 0xab, 0xb9, 0x5b, 0xe3, 0x4b, 0xd3, - 0x7c, 0x19, 0x8a, 0xe2, 0xca, 0x85, 0xd3, 0x93, 0x12, 0xf2, 0xf8, 0x2f, 0x75, 0x94, 0x02, 0x02, - 0x95, 0x60, 0x64, 0xcb, 0xad, 0x5a, 0xcd, 0x23, 0xbc, 0x00, 0x74, 0xed, 0x0d, 0x9f, 0x9e, 0x94, - 0x72, 0xdf, 0x31, 0x45, 0x29, 0x7a, 0x06, 0xe3, 0xe1, 0x44, 0xf9, 0x0b, 0xe3, 0x94, 0x7d, 0x3b, - 0xa7, 0x27, 0xa5, 0x0b, 0x3e, 0x2d, 0x6e, 0x90, 0xa9, 0x57, 0x38, 0xf8, 0x1a, 0xab, 0x40, 0x6d, - 0xe8, 0xd1, 0xd0, 0xe8, 0x44, 0x61, 0xd2, 0xbc, 0xbc, 0xeb, 0xf8, 0x81, 0x75, 0xd0, 0xc6, 0x61, - 0x55, 0xd9, 0xf7, 0xb1, 0x47, 0xe8, 0xad, 0x2f, 0x1b, 0xff, 0x2b, 0x07, 0x68, 0xbb, 0x83, 0x9d, - 0x7a, 0x7d, 0x8d, 0xac, 0x78, 0xb1, 0xe0, 0xbf, 0x0d, 0x63, 0x8c, 0xb5, 0x84, 0xff, 0x79, 0xca, - 0xff, 0xa9, 0xd3, 0x93, 0x12, 0x70, 0xfe, 0x13, 0xde, 0x87, 0x00, 0xe8, 0x06, 0x0c, 0xee, 0xec, - 0x6c, 0xd0, 0xd5, 0x3c, 0x58, 0x99, 0x39, 0x3d, 0x29, 0x0d, 0x06, 0x41, 0xfb, 0xe7, 0x27, 0xa5, - 0xd1, 0xe5, 0xae, 0x47, 0x3b, 0x6e, 0x92, 0x7a, 0x74, 0x03, 0x46, 0xaa, 0xed, 0xae, 0x1f, 0x60, - 0x6f, 0x61, 0x28, 0xfc, 0x8c, 0x9a, 0xac, 0xc8, 0x14, 0x75, 0xe8, 0x5b, 0x30, 0xb4, 0xeb, 0x63, - 0x6f, 0x61, 0x98, 0xce, 0xc8, 0x24, 0x9f, 0x11, 0x52, 0xb4, 0xb7, 0x54, 0x19, 0x25, 0xdf, 0x4a, - 0xd7, 0xc7, 0x9e, 0x49, 0x81, 0xd0, 0x1d, 0x18, 0x66, 0x6c, 0x3d, 0x47, 0xb7, 0x91, 0x49, 0x39, - 0x7f, 0x6d, 0xbc, 0xf7, 0x7e, 0x65, 0xec, 0xf4, 0xa4, 0x34, 0x4c, 0xd9, 0x6b, 0x0e, 0x0b, 0xa6, - 0xe4, 0x0a, 0x79, 0x73, 0x94, 0xe0, 0x92, 0x85, 0x6b, 0x7c, 0x0b, 0xc6, 0x95, 0xe1, 0xa3, 0x45, - 0x18, 0x22, 0xff, 0xd3, 0xcf, 0x7c, 0x82, 0x35, 0x46, 0xf6, 0x6f, 0x93, 0x96, 0x1a, 0xbf, 0x3f, - 0x0d, 0x05, 0x82, 0xa9, 0xed, 0x0d, 0x1a, 0xab, 0x72, 0xbd, 0x58, 0x75, 0x0b, 0x64, 0xdb, 0x7c, - 0x93, 0x98, 0x38, 0x3d, 0x29, 0x8d, 0x76, 0x79, 0x59, 0xd8, 0x33, 0x54, 0x87, 0x91, 0x95, 0x17, - 0x1d, 0xdb, 0xc3, 0x3e, 0x65, 0xec, 0xf8, 0x52, 0xf1, 0x0e, 0x3b, 0xb3, 0xee, 0x88, 0x33, 0xeb, - 0xce, 0x8e, 0x38, 0xb3, 0x2a, 0x97, 0xf9, 0x66, 0x79, 0x1e, 0x33, 0x94, 0x70, 0x35, 0xfd, 0xd6, - 0x9f, 0x95, 0x72, 0xa6, 0xa0, 0x84, 0xbe, 0x0d, 0xe7, 0x1e, 0xba, 0xde, 0xb1, 0x15, 0xf0, 0x19, - 0x98, 0x3d, 0x3d, 0x29, 0x15, 0x9e, 0xd0, 0x12, 0x65, 0x71, 0x73, 0x18, 0xf4, 0x10, 0xa6, 0x4c, - 0xb7, 0x1b, 0xe0, 0x1d, 0x57, 0xcc, 0xdb, 0x30, 0xc5, 0xba, 0x72, 0x7a, 0x52, 0x2a, 0x7a, 0xa4, - 0xa6, 0x11, 0xb8, 0x0d, 0x3e, 0x81, 0x0a, 0x7e, 0x04, 0x0b, 0xad, 0xc0, 0x54, 0x99, 0xee, 0xae, - 0x9c, 0x67, 0x6c, 0xb6, 0xc6, 0x2a, 0x97, 0x4f, 0x4f, 0x4a, 0x17, 0x2d, 0x5a, 0xd3, 0xf0, 0x78, - 0x95, 0x4a, 0x46, 0x47, 0x42, 0x5b, 0x70, 0xfe, 0x71, 0xf7, 0x00, 0x7b, 0x0e, 0x0e, 0xb0, 0x2f, - 0x7a, 0x34, 0x42, 0x7b, 0x74, 0xf5, 0xf4, 0xa4, 0xb4, 0xf8, 0x54, 0x56, 0x26, 0xf4, 0x29, 0x8e, - 0x8a, 0x30, 0x4c, 0xf3, 0x8e, 0x2e, 0x5b, 0x81, 0x75, 0x60, 0xf9, 0x98, 0x6e, 0x1a, 0xe3, 0x4b, - 0x17, 0x18, 0x8b, 0xef, 0x44, 0x6a, 0x2b, 0xd7, 0x39, 0x97, 0x2f, 0xc9, 0xb1, 0xb7, 0x78, 0x95, - 0xd2, 0x50, 0x94, 0x26, 0xd9, 0x3b, 0xe5, 0xb9, 0x30, 0x46, 0x7b, 0x4b, 0xf7, 0x4e, 0x79, 0x2e, - 0xa8, 0xbb, 0x8a, 0x3c, 0x21, 0x36, 0x60, 0x78, 0x97, 0x9c, 0x9e, 0x74, 0x4f, 0x99, 0x5a, 0xba, - 0xc6, 0x7b, 0x14, 0x5d, 0x7d, 0x77, 0xc8, 0x0f, 0x0a, 0x48, 0xbf, 0xbb, 0x69, 0x7a, 0xe2, 0xaa, - 0x67, 0x25, 0xad, 0x43, 0x5f, 0x00, 0xf0, 0x5e, 0x95, 0x3b, 0x9d, 0x85, 0x71, 0x3a, 0xc8, 0xf3, - 0xfa, 0x20, 0xcb, 0x9d, 0x4e, 0xe5, 0x0a, 0x1f, 0xdf, 0x05, 0x39, 0x3e, 0xab, 0xd3, 0x51, 0xa8, - 0x29, 0x44, 0xd0, 0xe7, 0x30, 0x41, 0xb7, 0x1c, 0x31, 0xa3, 0x13, 0x74, 0x46, 0x2f, 0x9d, 0x9e, - 0x94, 0xe6, 0xc9, 0x07, 0x97, 0x34, 0x9f, 0x1a, 0x02, 0xfa, 0x55, 0x98, 0xe3, 0xe4, 0xf6, 0x6d, - 0xa7, 0xe5, 0x3e, 0xf7, 0x97, 0xb1, 0xff, 0x34, 0x70, 0x3b, 0x0b, 0x93, 0xb4, 0x7b, 0x8b, 0x7a, - 0xf7, 0x74, 0x98, 0xca, 0x6d, 0xde, 0x53, 0x43, 0xf6, 0xf4, 0x39, 0x03, 0x68, 0xb4, 0x18, 0x84, - 0xd2, 0x6c, 0x72, 0x33, 0x68, 0x1d, 0xa6, 0x77, 0x7d, 0xac, 0x8d, 0x61, 0x8a, 0xee, 0xdf, 0x25, - 0x32, 0xc3, 0x5d, 0x1f, 0x37, 0xd2, 0xc6, 0x11, 0xc5, 0x43, 0x26, 0xa0, 0x65, 0xcf, 0xed, 0x44, - 0xd6, 0xf8, 0x34, 0xe5, 0x88, 0x71, 0x7a, 0x52, 0xba, 0xd2, 0xf2, 0xdc, 0x4e, 0x23, 0x7d, 0xa1, - 0x27, 0x60, 0xa3, 0x1f, 0xc2, 0x85, 0xaa, 0xeb, 0x38, 0xb8, 0x49, 0xf6, 0xcf, 0x65, 0xdb, 0x3a, - 0x74, 0x5c, 0x3f, 0xb0, 0x9b, 0xeb, 0xcb, 0x0b, 0x05, 0xba, 0x86, 0x6e, 0x92, 0xd1, 0x37, 0x25, - 0x44, 0xa3, 0x25, 0x41, 0x1a, 0x76, 0x4b, 0xa1, 0x9d, 0x42, 0x05, 0xfd, 0x00, 0x26, 0x79, 0x5b, - 0xd8, 0xa3, 0x4b, 0xf3, 0x7c, 0xf6, 0x42, 0x93, 0xc0, 0xec, 0x20, 0xf6, 0xc4, 0x4f, 0x26, 0xda, - 0xe8, 0xb4, 0xd0, 0xd7, 0x30, 0xbe, 0xf9, 0xb0, 0x6c, 0x62, 0xbf, 0xe3, 0x3a, 0x3e, 0x5e, 0x40, - 0x74, 0x46, 0xaf, 0x70, 0xd2, 0x9b, 0x0f, 0xcb, 0xe5, 0x6e, 0x70, 0x84, 0x9d, 0xc0, 0x6e, 0x5a, - 0x01, 0x16, 0x50, 0x95, 0x22, 0x59, 0x79, 0xc7, 0x4f, 0xac, 0x86, 0xc7, 0x4b, 0x94, 0x51, 0xa8, - 0xe4, 0x50, 0x11, 0x46, 0xeb, 0xf5, 0xb5, 0x0d, 0xf7, 0xd0, 0x76, 0x16, 0x66, 0x08, 0x33, 0x4c, - 0xf9, 0x1b, 0x1d, 0xc0, 0x9c, 0x22, 0xa0, 0x37, 0xc8, 0xff, 0xf8, 0x18, 0x3b, 0xc1, 0xc2, 0x2c, - 0xed, 0xc3, 0x77, 0xe4, 0x0d, 0xe3, 0x8e, 0x2a, 0xc7, 0x3f, 0xbb, 0x7f, 0xa7, 0x1c, 0xfe, 0xac, - 0x0b, 0x24, 0x73, 0xd6, 0x4a, 0x28, 0x45, 0x3b, 0x30, 0x52, 0xeb, 0x7a, 0x1d, 0xd7, 0xc7, 0x0b, - 0x73, 0x94, 0x69, 0xd7, 0xb3, 0xbe, 0x4e, 0x0e, 0x5a, 0x99, 0x23, 0xdb, 0x73, 0x87, 0xfd, 0x50, - 0x46, 0x26, 0x48, 0x19, 0x5f, 0xc2, 0x98, 0xfc, 0x98, 0xd1, 0x08, 0x0c, 0x96, 0xdb, 0xed, 0xc2, - 0x00, 0xf9, 0xa3, 0x5e, 0x5f, 0x2b, 0xe4, 0xd0, 0x14, 0x40, 0xb8, 0x83, 0x15, 0xf2, 0x68, 0x02, - 0x46, 0xc5, 0x0e, 0x53, 0x18, 0xa4, 0xf0, 0x9d, 0x4e, 0x61, 0x08, 0x21, 0x98, 0xd2, 0xd7, 0x79, - 0x61, 0xd8, 0x78, 0x01, 0x63, 0x72, 0x7a, 0xd0, 0x34, 0x8c, 0xef, 0x6e, 0xd5, 0x6b, 0x2b, 0xd5, - 0xf5, 0x87, 0xeb, 0x2b, 0xcb, 0x85, 0x01, 0x74, 0x19, 0x2e, 0xee, 0xd4, 0xd7, 0x1a, 0xcb, 0x95, - 0xc6, 0xc6, 0x76, 0xb5, 0xbc, 0xd1, 0xa8, 0x99, 0xdb, 0x5f, 0x7e, 0xd5, 0xd8, 0xd9, 0xdd, 0xda, - 0x5a, 0xd9, 0x28, 0xe4, 0xd0, 0x02, 0xcc, 0x92, 0xea, 0xc7, 0xbb, 0x95, 0x15, 0x15, 0xa0, 0x90, - 0x47, 0xd7, 0xe0, 0x72, 0x52, 0x4d, 0x63, 0x6d, 0xa5, 0xbc, 0xbc, 0xb1, 0x52, 0xaf, 0x17, 0x06, - 0x8d, 0x36, 0x8c, 0x2b, 0x2c, 0x40, 0x8b, 0xb0, 0x50, 0x5d, 0x31, 0x77, 0x1a, 0xb5, 0x5d, 0xb3, - 0xb6, 0x5d, 0x5f, 0x69, 0xe8, 0x1d, 0x89, 0xd6, 0x6e, 0x6c, 0xaf, 0xae, 0x6f, 0x35, 0x48, 0x51, - 0xbd, 0x90, 0x23, 0xad, 0x69, 0xb5, 0xf5, 0xf5, 0xad, 0xd5, 0x8d, 0x95, 0xc6, 0x6e, 0x7d, 0x85, - 0x83, 0xe4, 0x8d, 0x7f, 0x97, 0x8b, 0x6d, 0xe8, 0x68, 0x09, 0xc6, 0xeb, 0xec, 0xca, 0x48, 0x17, - 0x39, 0x13, 0xdf, 0x0b, 0xa7, 0x27, 0xa5, 0x09, 0x7e, 0x93, 0x64, 0xeb, 0x57, 0x05, 0x22, 0x67, - 0x74, 0x8d, 0xcc, 0x67, 0xd3, 0x6d, 0xab, 0x67, 0x74, 0x87, 0x97, 0x99, 0xb2, 0x16, 0x2d, 0x29, - 0xa7, 0x39, 0x93, 0xe5, 0xa9, 0xbc, 0x28, 0x4e, 0x73, 0x75, 0x67, 0x97, 0xe7, 0xfa, 0x52, 0x38, - 0x71, 0xfc, 0x10, 0xa6, 0x38, 0x09, 0x27, 0x89, 0x84, 0x33, 0xba, 0x29, 0x7b, 0x25, 0xfa, 0x38, - 0x3a, 0xdd, 0x7c, 0x84, 0xf4, 0x30, 0x88, 0x6c, 0x89, 0x66, 0x04, 0x14, 0x95, 0x60, 0x98, 0x7d, - 0x44, 0x6c, 0x90, 0x54, 0x58, 0x6a, 0x93, 0x02, 0x93, 0x95, 0x1b, 0xbf, 0x39, 0xa8, 0x9e, 0x1b, - 0x44, 0x38, 0x52, 0x98, 0x48, 0x85, 0x23, 0xca, 0x3c, 0x5a, 0x4a, 0xe4, 0xa0, 0x3a, 0xf6, 0x7d, - 0x2a, 0x56, 0x72, 0x8a, 0x54, 0x0e, 0xf2, 0x59, 0x21, 0xb9, 0x29, 0x85, 0x00, 0x44, 0x56, 0x67, - 0x42, 0x11, 0x95, 0xd5, 0x07, 0x43, 0x59, 0x9d, 0x8b, 0x4d, 0x4c, 0x56, 0x0f, 0x41, 0xc8, 0x44, - 0xf2, 0x73, 0x9b, 0xf6, 0x61, 0x28, 0x9c, 0x48, 0x7e, 0xd6, 0xf3, 0x89, 0x54, 0x80, 0xd0, 0x47, - 0x00, 0xe5, 0xfd, 0x3a, 0x15, 0x79, 0xcd, 0x2d, 0x2e, 0xbb, 0xd0, 0x5d, 0xc6, 0x7a, 0xee, 0xb3, - 0xdd, 0xdd, 0xf2, 0x54, 0xa1, 0x5e, 0x81, 0x46, 0x15, 0x98, 0x2c, 0xff, 0xa4, 0xeb, 0xe1, 0xf5, - 0x16, 0xd9, 0xa8, 0x02, 0x76, 0x7b, 0x19, 0xab, 0x2c, 0x9e, 0x9e, 0x94, 0x16, 0x2c, 0x52, 0xd1, - 0xb0, 0x79, 0x8d, 0x42, 0x40, 0x47, 0x41, 0xdb, 0x70, 0x7e, 0xb5, 0x5a, 0xe3, 0x4b, 0xab, 0xdc, - 0x6c, 0xba, 0x5d, 0x27, 0xe0, 0x02, 0xcb, 0xb5, 0xd3, 0x93, 0xd2, 0xe5, 0xc3, 0x66, 0xa7, 0x21, - 0x96, 0xa1, 0xc5, 0xaa, 0x55, 0x89, 0x25, 0x86, 0x6b, 0xb4, 0x61, 0x6a, 0x15, 0x07, 0x64, 0x29, - 0x09, 0xe9, 0x33, 0x7b, 0x4e, 0x3e, 0x81, 0xf1, 0x7d, 0x3b, 0x38, 0xaa, 0xe3, 0xa6, 0x87, 0x03, - 0x71, 0x37, 0xa6, 0x1c, 0x78, 0x6e, 0x07, 0x47, 0x0d, 0x9f, 0x95, 0xab, 0xfb, 0xac, 0x02, 0x6e, - 0xac, 0xc0, 0x34, 0x6f, 0x4d, 0x0a, 0xbb, 0x4b, 0x3a, 0xc1, 0x1c, 0x25, 0x48, 0x67, 0x41, 0x25, - 0xa8, 0x93, 0xf9, 0x27, 0x79, 0x98, 0xab, 0x1e, 0x59, 0xce, 0x21, 0xae, 0x59, 0xbe, 0xff, 0xdc, - 0xf5, 0x5a, 0x4a, 0xe7, 0xa9, 0xa4, 0x1f, 0xeb, 0x3c, 0x15, 0xed, 0x97, 0x60, 0x7c, 0xbb, 0xdd, - 0x12, 0x38, 0xfc, 0x16, 0x42, 0xdb, 0x72, 0xdb, 0xad, 0x46, 0x47, 0xd0, 0x52, 0x81, 0x08, 0xce, - 0x16, 0x7e, 0x2e, 0x71, 0x06, 0x43, 0x1c, 0x07, 0x3f, 0x57, 0x70, 0x14, 0x20, 0xb4, 0x02, 0xe7, - 0xeb, 0xb8, 0xe9, 0x3a, 0xad, 0x87, 0x56, 0x33, 0x70, 0xbd, 0x1d, 0xf7, 0x29, 0x76, 0xf8, 0xfa, - 0xa2, 0x82, 0x9a, 0x4f, 0x2b, 0x1b, 0x4f, 0x68, 0x6d, 0x23, 0x20, 0xd5, 0x66, 0x1c, 0x03, 0x6d, - 0xc3, 0xe8, 0x3e, 0x57, 0xa3, 0xf0, 0xab, 0xcb, 0x8d, 0x3b, 0x52, 0xaf, 0x52, 0xf5, 0x30, 0x5d, - 0x14, 0x56, 0x5b, 0x5e, 0xbe, 0xe4, 0xb9, 0x47, 0x37, 0x17, 0x01, 0x69, 0x4a, 0x22, 0xc6, 0x2e, - 0x4c, 0xd6, 0xda, 0xdd, 0x43, 0xdb, 0x21, 0xdb, 0x40, 0x1d, 0xff, 0x18, 0x2d, 0x03, 0x84, 0x05, - 0x5c, 0x6f, 0x32, 0xc3, 0x2f, 0x3c, 0x61, 0xc5, 0xde, 0x03, 0xfe, 0x21, 0xd1, 0x12, 0x2a, 0xa1, - 0x9a, 0x0a, 0x9e, 0xf1, 0x3f, 0x06, 0x01, 0xf1, 0x09, 0xa0, 0x47, 0x5a, 0x1d, 0x07, 0xe4, 0x5c, - 0xb8, 0x00, 0x79, 0xa9, 0xde, 0x38, 0x77, 0x7a, 0x52, 0xca, 0xdb, 0x2d, 0x33, 0xbf, 0xbe, 0x8c, - 0xde, 0x85, 0x61, 0x0a, 0x46, 0xf9, 0x3f, 0x25, 0xdb, 0x53, 0x29, 0xb0, 0x9d, 0x83, 0x1e, 0xb5, - 0x26, 0x03, 0x46, 0xef, 0xc1, 0xd8, 0x32, 0x6e, 0xe3, 0x43, 0x2b, 0x70, 0xc5, 0xd7, 0xcd, 0x14, - 0x06, 0xa2, 0x50, 0x59, 0x73, 0x21, 0x24, 0xb9, 0x9e, 0x98, 0xd8, 0xf2, 0x5d, 0x47, 0xbd, 0x9e, - 0x78, 0xb4, 0x44, 0xbd, 0x9e, 0x30, 0x18, 0xf4, 0x3b, 0x39, 0x18, 0x2f, 0x3b, 0x0e, 0xbf, 0x88, - 0xfb, 0x9c, 0xeb, 0x73, 0x77, 0xa4, 0x7a, 0x6a, 0xc3, 0x3a, 0xc0, 0xed, 0x3d, 0xab, 0xdd, 0xc5, - 0x7e, 0xe5, 0x6b, 0x22, 0x31, 0xfe, 0xfb, 0x93, 0xd2, 0xc7, 0x67, 0xb8, 0x5a, 0x87, 0x8a, 0xae, - 0x1d, 0xcf, 0xb2, 0x03, 0xff, 0xf4, 0xa4, 0x34, 0x67, 0x85, 0x0d, 0xaa, 0xdf, 0x8d, 0xd2, 0x0f, - 0xf4, 0x8e, 0x7a, 0x27, 0xe5, 0x7b, 0x71, 0xe4, 0x8e, 0xcf, 0xaf, 0xa3, 0xe8, 0x18, 0xa6, 0xcb, - 0xbe, 0xdf, 0x3d, 0xc6, 0xf5, 0xc0, 0xf2, 0x02, 0x72, 0x9f, 0xa3, 0xfb, 0x43, 0xf6, 0x65, 0xef, - 0xed, 0x9f, 0x9e, 0x94, 0x72, 0x44, 0x48, 0xb5, 0x28, 0x2a, 0x11, 0x72, 0xbc, 0xa0, 0x11, 0xd8, - 0xea, 0x81, 0x43, 0xaf, 0x7d, 0x51, 0xda, 0xc6, 0x75, 0x29, 0x09, 0xac, 0x2f, 0xa7, 0xcd, 0xb8, - 0x51, 0x85, 0xc5, 0x55, 0x1c, 0x98, 0xd8, 0xc7, 0x81, 0xf8, 0x46, 0xe8, 0x0a, 0x0f, 0x95, 0x61, - 0x23, 0xf4, 0xb7, 0x44, 0xa6, 0xd3, 0xcf, 0xbe, 0x0b, 0x51, 0x63, 0xfc, 0xe5, 0x1c, 0x94, 0xaa, - 0x1e, 0x66, 0xf2, 0x5d, 0x0a, 0xa1, 0xec, 0xbd, 0x6b, 0x11, 0x86, 0x76, 0x5e, 0x76, 0xc4, 0x2d, - 0x99, 0xd6, 0x92, 0x49, 0x31, 0x69, 0x69, 0x9f, 0x2a, 0x07, 0xe3, 0x09, 0xcc, 0x99, 0xd8, 0xc1, - 0xcf, 0xad, 0x83, 0x36, 0xd6, 0x6e, 0xed, 0x25, 0x18, 0x66, 0x1f, 0x7a, 0x6c, 0x08, 0xac, 0xfc, - 0x6c, 0x1a, 0x10, 0xe3, 0x1f, 0xe6, 0xa1, 0xc0, 0x86, 0x5b, 0x71, 0x83, 0xfe, 0xc6, 0xc7, 0x47, - 0x90, 0xef, 0xa1, 0x34, 0xb9, 0x19, 0x72, 0x7b, 0x30, 0x94, 0x45, 0x68, 0x57, 0xc9, 0x91, 0x2a, - 0x2a, 0xc9, 0x80, 0xd8, 0xa2, 0x63, 0xba, 0xbe, 0x98, 0xe6, 0x03, 0xfd, 0x46, 0x0e, 0xce, 0xb1, - 0x65, 0x9c, 0xfd, 0xa1, 0xec, 0xbf, 0x99, 0x0f, 0xa5, 0x10, 0xd0, 0xbf, 0xd4, 0xcf, 0x96, 0xd5, - 0x19, 0xff, 0x38, 0x0f, 0xe7, 0x15, 0x5e, 0x71, 0xa1, 0xfe, 0x1d, 0x26, 0x4a, 0x29, 0x0c, 0xa3, - 0xda, 0x53, 0x22, 0x4a, 0x35, 0x42, 0xcd, 0x08, 0xe5, 0xdc, 0x3b, 0x30, 0x4a, 0x86, 0x14, 0x55, - 0xb4, 0xd2, 0x03, 0x9d, 0x81, 0x8a, 0xea, 0xbe, 0xb9, 0x77, 0x17, 0x46, 0xe9, 0x9f, 0x64, 0x46, - 0x86, 0xd2, 0x67, 0x44, 0x02, 0x21, 0x1b, 0xe0, 0x91, 0x6b, 0x3b, 0x9b, 0x38, 0x38, 0x72, 0x5b, - 0x5c, 0xb4, 0x58, 0x27, 0xdb, 0xee, 0xff, 0xe3, 0xda, 0x4e, 0xe3, 0x98, 0x16, 0x9f, 0x55, 0x91, - 0x17, 0x12, 0x34, 0x15, 0xe2, 0xc6, 0x3d, 0x28, 0x90, 0x1d, 0xb2, 0xff, 0xa5, 0x65, 0xcc, 0x02, - 0x5a, 0xc5, 0x41, 0xc5, 0xd5, 0xce, 0x6e, 0x63, 0x12, 0xc6, 0x6b, 0xb6, 0x73, 0x28, 0x7e, 0xfe, - 0xe1, 0x20, 0x4c, 0xb0, 0xdf, 0x7c, 0x06, 0x22, 0x12, 0x56, 0xae, 0x1f, 0x09, 0xeb, 0x03, 0x98, - 0x24, 0x22, 0x0a, 0xf6, 0xf6, 0xb0, 0x47, 0x24, 0x3b, 0x3e, 0x1f, 0xf4, 0x8a, 0xe8, 0xd3, 0x8a, - 0xc6, 0x33, 0x56, 0x63, 0xea, 0x80, 0x68, 0x03, 0xa6, 0x58, 0xc1, 0x43, 0x6c, 0x05, 0xdd, 0x50, - 0xcb, 0x35, 0xcd, 0xef, 0x52, 0xa2, 0x98, 0x6d, 0x9f, 0x9c, 0xd6, 0x13, 0x5e, 0x68, 0x46, 0x70, - 0xd1, 0xe7, 0x30, 0x5d, 0xf3, 0xdc, 0x17, 0x2f, 0x15, 0x99, 0x92, 0x9d, 0x20, 0xec, 0xd6, 0x45, - 0xaa, 0x1a, 0xaa, 0x64, 0x19, 0x85, 0x26, 0x6b, 0x6a, 0xdd, 0xaf, 0xb8, 0x9e, 0xed, 0x1c, 0xd2, - 0xd9, 0x1c, 0x65, 0x6b, 0xca, 0xf6, 0x1b, 0x07, 0xb4, 0xd0, 0x94, 0xd5, 0x11, 0x35, 0xf3, 0x48, - 0x6f, 0x35, 0xf3, 0x3d, 0x80, 0x0d, 0xd7, 0x6a, 0x95, 0xdb, 0xed, 0x6a, 0xd9, 0xa7, 0x2a, 0x26, - 0x2e, 0x33, 0xb5, 0x5d, 0xab, 0xd5, 0xb0, 0xda, 0xed, 0x46, 0xd3, 0xf2, 0x4d, 0x05, 0xe6, 0xd1, - 0xd0, 0xe8, 0xb9, 0xc2, 0x88, 0x39, 0xbd, 0x61, 0x37, 0xb1, 0xe3, 0xe3, 0x7d, 0xcb, 0x73, 0x6c, - 0xe7, 0xd0, 0x37, 0x7e, 0x7f, 0x1c, 0x46, 0xe5, 0x90, 0xef, 0xa8, 0x17, 0x42, 0x2e, 0x89, 0xd1, - 0x1d, 0x2a, 0x54, 0x83, 0x99, 0x0a, 0x04, 0xba, 0x48, 0xaf, 0x88, 0x5c, 0x06, 0x1c, 0x21, 0xab, - 0xdb, 0xea, 0x74, 0x4c, 0x52, 0x46, 0x4e, 0x82, 0xe5, 0x0a, 0xe5, 0xff, 0x28, 0x3b, 0x09, 0x5a, - 0x07, 0x66, 0x7e, 0xb9, 0x42, 0x56, 0xd9, 0xf6, 0xfa, 0x72, 0x95, 0xb2, 0x72, 0x94, 0xad, 0x32, - 0xd7, 0x6e, 0x35, 0x4d, 0x5a, 0x4a, 0x6a, 0xeb, 0xe5, 0xcd, 0x0d, 0xce, 0x2e, 0x5a, 0xeb, 0x5b, - 0xc7, 0x6d, 0x93, 0x96, 0x92, 0x9b, 0x09, 0xd3, 0x68, 0x54, 0x5d, 0x27, 0xf0, 0xdc, 0xb6, 0x4f, - 0x05, 0xe8, 0x51, 0x36, 0x9d, 0x5c, 0x15, 0xd2, 0xe4, 0x55, 0x66, 0x04, 0x14, 0xed, 0xc3, 0x7c, - 0xb9, 0xf5, 0xcc, 0x72, 0x9a, 0xb8, 0xc5, 0x6a, 0xf6, 0x5d, 0xef, 0xe9, 0x93, 0xb6, 0xfb, 0xdc, - 0xa7, 0xfc, 0x1e, 0xe5, 0x9a, 0x43, 0x0e, 0x22, 0x34, 0x2b, 0xcf, 0x05, 0x90, 0x99, 0x86, 0x4d, - 0x76, 0xc9, 0x6a, 0xdb, 0xed, 0xb6, 0xf8, 0x2c, 0xd0, 0x5d, 0xb2, 0x49, 0x0a, 0x4c, 0x56, 0x4e, - 0xb8, 0xb4, 0x56, 0xdf, 0xa4, 0x7a, 0x3a, 0xce, 0xa5, 0x23, 0xff, 0xd8, 0x24, 0x65, 0xe8, 0x06, - 0x8c, 0x88, 0x4b, 0x16, 0x53, 0xf4, 0x53, 0xf5, 0xb5, 0xb8, 0x5c, 0x89, 0x3a, 0xf2, 0x49, 0x98, - 0xb8, 0xe9, 0x3e, 0xc3, 0xde, 0xcb, 0xaa, 0xdb, 0xc2, 0x42, 0xab, 0xc4, 0xb5, 0x26, 0xac, 0xa2, - 0xd1, 0x24, 0x35, 0xa6, 0x0e, 0x48, 0x1a, 0x60, 0x72, 0x9a, 0xbf, 0x30, 0x1d, 0x36, 0xc0, 0xe4, - 0x38, 0xdf, 0x14, 0x75, 0x68, 0x19, 0xce, 0x97, 0xbb, 0x81, 0x7b, 0x6c, 0x05, 0x76, 0x73, 0xb7, - 0x73, 0xe8, 0x59, 0xa4, 0x91, 0x02, 0x45, 0xa0, 0x37, 0x49, 0x4b, 0x54, 0x36, 0xba, 0xbc, 0xd6, - 0x8c, 0x23, 0xa0, 0xf7, 0x61, 0x62, 0xdd, 0x67, 0x9a, 0x43, 0xcb, 0xc7, 0x2d, 0xaa, 0xfe, 0xe1, - 0xbd, 0xb4, 0xfd, 0x06, 0xd5, 0x23, 0x36, 0xc8, 0xdd, 0xb3, 0x65, 0x6a, 0x70, 0xc8, 0x80, 0x73, - 0x65, 0xdf, 0xb7, 0xfd, 0x80, 0x6a, 0x75, 0x46, 0x2b, 0x70, 0x7a, 0x52, 0x3a, 0x67, 0xd1, 0x12, - 0x93, 0xd7, 0xa0, 0x7d, 0x18, 0x5f, 0xc6, 0xe4, 0xde, 0xb2, 0xe3, 0x75, 0xfd, 0x80, 0xea, 0x68, - 0xc6, 0x97, 0x2e, 0xf2, 0x0f, 0x5b, 0xa9, 0xe1, 0x6b, 0x99, 0xdd, 0x48, 0x5a, 0xb4, 0xbc, 0x11, - 0x90, 0x0a, 0x55, 0xb2, 0x52, 0xe0, 0xc9, 0xa5, 0x8c, 0xe3, 0xac, 0xd9, 0x2d, 0xf2, 0xa9, 0xce, - 0xd2, 0x3e, 0xd0, 0x4b, 0x19, 0xdf, 0x1b, 0x1a, 0x47, 0xb4, 0x46, 0xbd, 0x94, 0x69, 0x28, 0xa8, - 0x19, 0x53, 0x46, 0xcf, 0x69, 0x0a, 0x47, 0xbd, 0x52, 0x74, 0xf1, 0x8c, 0xaa, 0xea, 0x4f, 0x60, - 0xbc, 0xda, 0xf5, 0x03, 0xf7, 0x78, 0xe7, 0x08, 0x1f, 0xe3, 0x85, 0x0b, 0xe1, 0xd5, 0xb3, 0x49, - 0x8b, 0x1b, 0x01, 0x29, 0x57, 0x87, 0xa9, 0x80, 0xa3, 0x2f, 0x00, 0x89, 0x3b, 0xe4, 0x2a, 0x59, - 0x1f, 0x0e, 0x59, 0xcb, 0x0b, 0xf3, 0x74, 0xac, 0xf4, 0xe2, 0x28, 0xae, 0x9e, 0x8d, 0x43, 0x59, - 0xad, 0xaa, 0x13, 0xe3, 0xc8, 0xa4, 0x43, 0xac, 0x8b, 0xab, 0x9e, 0xd5, 0x39, 0x5a, 0x58, 0x08, - 0x6f, 0x82, 0x7c, 0x50, 0x87, 0xa4, 0x5c, 0x93, 0x68, 0x43, 0x70, 0x54, 0x07, 0x60, 0x3f, 0x37, - 0xc8, 0xc4, 0x5f, 0xa4, 0xfc, 0x5a, 0xd0, 0xf8, 0x45, 0x2a, 0x04, 0xaf, 0x2e, 0x52, 0x39, 0x99, - 0x91, 0x6d, 0xdb, 0xda, 0x6c, 0x2a, 0x64, 0xd0, 0x53, 0x28, 0xb0, 0x5f, 0x9b, 0xae, 0x63, 0x07, - 0x6c, 0xeb, 0x2d, 0x6a, 0x9a, 0xc2, 0x68, 0xb5, 0x68, 0x80, 0x6a, 0x68, 0x79, 0x03, 0xc7, 0xb2, - 0x56, 0x69, 0x26, 0x46, 0x18, 0xd5, 0x60, 0xbc, 0xe6, 0xb9, 0xad, 0x6e, 0x33, 0xa0, 0x42, 0xe5, - 0x25, 0x7a, 0x99, 0x41, 0xbc, 0x1d, 0xa5, 0x86, 0xf1, 0xa4, 0xc3, 0x0a, 0x1a, 0xe4, 0x5c, 0x56, - 0x79, 0xa2, 0x00, 0x3e, 0x1a, 0x1a, 0x1d, 0x2f, 0x4c, 0xb0, 0x47, 0xb6, 0x47, 0x43, 0xa3, 0x93, - 0x85, 0x29, 0xe3, 0x77, 0x73, 0x80, 0xe2, 0xab, 0x1b, 0xdd, 0x85, 0x11, 0xec, 0x10, 0x01, 0xb4, - 0xc5, 0x77, 0x69, 0x7a, 0x26, 0xf1, 0x22, 0x55, 0x13, 0xc8, 0x8b, 0xd0, 0x17, 0x30, 0xc3, 0x3e, - 0x06, 0xf1, 0x1d, 0xb6, 0xed, 0x63, 0x3b, 0xa0, 0x3b, 0xf7, 0x30, 0x9b, 0xff, 0x84, 0x6a, 0x55, - 0x71, 0xc0, 0xab, 0xe9, 0x57, 0xbb, 0x41, 0x2a, 0x8d, 0x2e, 0xcc, 0x25, 0xae, 0x6b, 0xb4, 0x09, - 0x73, 0xc7, 0xae, 0x13, 0x1c, 0xb5, 0x5f, 0x8a, 0x65, 0xcd, 0x5b, 0xcb, 0xd1, 0xd6, 0xe8, 0x54, - 0x26, 0x02, 0x98, 0x33, 0xbc, 0x98, 0x53, 0xa4, 0xed, 0x3c, 0x1a, 0x1a, 0xcd, 0x17, 0x06, 0xe5, - 0x48, 0x0c, 0x13, 0xce, 0xc7, 0x96, 0x07, 0xfa, 0x14, 0x26, 0x9a, 0x54, 0xfc, 0xd3, 0x5a, 0x62, - 0x1f, 0x87, 0x52, 0xae, 0xf2, 0x9d, 0x95, 0xb3, 0xa1, 0xfc, 0xfd, 0x1c, 0xcc, 0xa7, 0x2c, 0x8c, - 0xb3, 0xb3, 0xfa, 0x2b, 0xb8, 0x70, 0x6c, 0xbd, 0x68, 0x78, 0x54, 0x14, 0x6b, 0x78, 0x96, 0x13, - 0xe1, 0xf6, 0x5b, 0xa7, 0x27, 0xa5, 0xab, 0xc9, 0x10, 0xaa, 0x21, 0xc1, 0xb1, 0xf5, 0xc2, 0xa4, - 0x00, 0x26, 0xa9, 0x67, 0xfd, 0xbc, 0x0f, 0xe7, 0x99, 0xd8, 0xd6, 0xb7, 0xba, 0xc6, 0xa8, 0x01, - 0xd4, 0xf1, 0xb1, 0xd5, 0x39, 0x72, 0xc9, 0x01, 0x5f, 0x51, 0x7f, 0xf1, 0xeb, 0x3e, 0xe2, 0xd7, - 0x6f, 0x59, 0xb1, 0xf7, 0x40, 0x68, 0xd9, 0x04, 0xa4, 0xa9, 0x60, 0x19, 0x7f, 0x9c, 0x07, 0x54, - 0xee, 0xb6, 0xec, 0xa0, 0x1e, 0x78, 0xd8, 0x3a, 0x16, 0xdd, 0xf8, 0x10, 0x26, 0x98, 0x04, 0xce, - 0x8a, 0x69, 0x77, 0xc6, 0x97, 0x66, 0xf8, 0xe7, 0xa0, 0x56, 0xad, 0x0d, 0x98, 0x1a, 0x28, 0x41, - 0x35, 0x31, 0xbb, 0x55, 0x52, 0xd4, 0xbc, 0x86, 0xaa, 0x56, 0x11, 0x54, 0xf5, 0x37, 0xfa, 0x1c, - 0xa6, 0xaa, 0xee, 0x71, 0x87, 0xf0, 0x84, 0x23, 0x0f, 0xf2, 0x8b, 0x08, 0x6f, 0x57, 0xab, 0x5c, - 0x1b, 0x30, 0x23, 0xe0, 0x68, 0x0b, 0x66, 0x1e, 0xb6, 0xbb, 0xfe, 0x51, 0xd9, 0x69, 0x55, 0xdb, - 0xae, 0x2f, 0xa8, 0x0c, 0xf1, 0x1b, 0x33, 0x17, 0x1c, 0xe3, 0x10, 0x6b, 0x03, 0x66, 0x12, 0x22, - 0xba, 0x01, 0xc3, 0x2b, 0xcf, 0xb0, 0x13, 0xc8, 0xa7, 0x66, 0x6e, 0xab, 0xb2, 0xed, 0xe0, 0xed, - 0x27, 0x6b, 0x03, 0x26, 0xab, 0xad, 0x8c, 0xc1, 0x88, 0x10, 0x9a, 0xef, 0x92, 0xb3, 0x57, 0xb2, - 0xb3, 0x1e, 0x58, 0x41, 0xd7, 0x47, 0x45, 0x18, 0xdd, 0xed, 0x10, 0x59, 0x4e, 0xdc, 0x88, 0x4d, - 0xf9, 0xdb, 0xf8, 0xb6, 0xce, 0x69, 0xb4, 0xa8, 0x6a, 0x49, 0x19, 0x70, 0x58, 0x60, 0xac, 0xe9, - 0xcc, 0xcd, 0x86, 0xd6, 0xda, 0xcd, 0x47, 0xda, 0x2d, 0x44, 0x79, 0x6d, 0xcc, 0x25, 0x32, 0xcf, - 0xf8, 0x12, 0xae, 0xec, 0x76, 0x7c, 0xec, 0x05, 0xe5, 0x4e, 0xa7, 0x6d, 0x37, 0xd9, 0x53, 0x07, - 0x15, 0xae, 0xc5, 0x62, 0x79, 0x1f, 0xce, 0xb1, 0x02, 0xbe, 0x4c, 0xc4, 0x1a, 0x2c, 0x77, 0x3a, - 0x5c, 0xa4, 0x7f, 0xc0, 0xa4, 0x00, 0x26, 0xa4, 0x9b, 0x1c, 0xda, 0xf8, 0xad, 0x1c, 0x5c, 0x61, - 0x5f, 0x40, 0x2a, 0xe9, 0x6f, 0xc1, 0x18, 0x35, 0x15, 0xe9, 0x58, 0x4d, 0xed, 0xd6, 0xe7, 0x88, - 0x42, 0x33, 0xac, 0x57, 0x8c, 0x70, 0xf2, 0xe9, 0x46, 0x38, 0xe2, 0x03, 0x1b, 0x4c, 0xfc, 0xc0, - 0xbe, 0x00, 0x83, 0xf7, 0xa8, 0xdd, 0x8e, 0x75, 0xca, 0x7f, 0x95, 0x5e, 0x19, 0xff, 0x29, 0x0f, - 0xf3, 0xab, 0xd8, 0xc1, 0x9e, 0x45, 0xc7, 0xa9, 0x29, 0x38, 0xd4, 0xc7, 0xfe, 0x5c, 0xe6, 0x63, - 0xbf, 0xbc, 0xbd, 0xe7, 0x53, 0x6e, 0xef, 0x17, 0x61, 0x70, 0xd7, 0x5c, 0xe7, 0xc3, 0xa2, 0x72, - 0x69, 0xd7, 0xb3, 0x4d, 0x52, 0x86, 0xd6, 0x43, 0x43, 0x81, 0xa1, 0x9e, 0xba, 0xa3, 0x19, 0xfe, - 0x70, 0x3a, 0xc2, 0x0d, 0x05, 0x74, 0xf3, 0x80, 0x2d, 0x45, 0x45, 0x40, 0xb6, 0x9b, 0xdb, 0xfc, - 0x9b, 0x4a, 0x19, 0x20, 0xbf, 0xed, 0xaf, 0x38, 0x81, 0xf7, 0x92, 0x2d, 0x01, 0x76, 0xe9, 0x17, - 0x57, 0xfd, 0xe2, 0x17, 0x30, 0xae, 0x80, 0xa0, 0x02, 0x0c, 0x3e, 0xe5, 0x46, 0x12, 0x63, 0x26, - 0xf9, 0x13, 0x7d, 0x1b, 0x86, 0x9f, 0x59, 0xed, 0x2e, 0xe6, 0xdb, 0xc8, 0x85, 0x50, 0x25, 0x51, - 0x0f, 0xc8, 0xc6, 0xce, 0x74, 0x12, 0x26, 0x03, 0xfa, 0x28, 0xff, 0x41, 0xce, 0xf8, 0x18, 0x16, - 0xe2, 0xbd, 0xe1, 0x37, 0xd8, 0x5e, 0x4a, 0x1d, 0x63, 0x19, 0x66, 0x57, 0x71, 0x40, 0x17, 0x2e, - 0xfd, 0x88, 0x14, 0x1b, 0x8e, 0xc8, 0x77, 0x96, 0xf1, 0x76, 0x61, 0xd4, 0x61, 0x2e, 0x42, 0x85, - 0xb7, 0xff, 0x11, 0x8c, 0xf0, 0x22, 0xb9, 0xa3, 0x72, 0xab, 0x36, 0x7c, 0xc0, 0x2b, 0xf6, 0x96, - 0xd8, 0xba, 0xe5, 0x94, 0x4d, 0x81, 0x60, 0x1c, 0xc1, 0x05, 0x72, 0x48, 0x86, 0x54, 0xe5, 0x72, - 0xbc, 0x04, 0x63, 0x1d, 0x72, 0xcc, 0xfb, 0xf6, 0x4f, 0xd8, 0x32, 0x1a, 0x36, 0x47, 0x49, 0x41, - 0xdd, 0xfe, 0x09, 0x46, 0x97, 0x01, 0x68, 0x25, 0x1d, 0x26, 0xdf, 0x05, 0x28, 0x38, 0xd3, 0x62, - 0x21, 0xa0, 0xc6, 0x32, 0x6c, 0xdd, 0x98, 0xf4, 0x6f, 0xc3, 0x83, 0xf9, 0x58, 0x4b, 0x7c, 0x00, - 0x77, 0x61, 0x94, 0x77, 0xcc, 0x8f, 0xe8, 0x97, 0xd5, 0x11, 0x98, 0x12, 0x08, 0xdd, 0x84, 0x69, - 0x07, 0xbf, 0x08, 0x1a, 0xb1, 0x3e, 0x4c, 0x92, 0xe2, 0x9a, 0xe8, 0x87, 0xf1, 0x4b, 0x54, 0xa7, - 0x58, 0x77, 0xdc, 0xe7, 0x4f, 0xda, 0xd6, 0x53, 0x1c, 0x6b, 0xf8, 0x53, 0x18, 0xad, 0xf7, 0x6e, - 0x98, 0x7d, 0x3e, 0xa2, 0x71, 0x53, 0xa2, 0x18, 0x6d, 0x28, 0x92, 0x21, 0x91, 0x8b, 0xe7, 0x7a, - 0xab, 0xf6, 0x4d, 0x33, 0xf0, 0x19, 0x5c, 0x4a, 0x6c, 0xed, 0x9b, 0x66, 0xe2, 0x9f, 0xe7, 0x61, - 0x9e, 0x1d, 0x26, 0xf1, 0x15, 0xdc, 0xff, 0x56, 0xf3, 0x0b, 0x79, 0x79, 0xbb, 0x97, 0xf0, 0xf2, - 0x46, 0x51, 0xd4, 0x97, 0x37, 0xed, 0xbd, 0xed, 0x83, 0xe4, 0xf7, 0x36, 0x7a, 0x21, 0xd5, 0xdf, - 0xdb, 0xa2, 0xaf, 0x6c, 0x2b, 0xe9, 0xaf, 0x6c, 0xf4, 0xcd, 0x21, 0xe1, 0x95, 0x2d, 0xe1, 0x6d, - 0x8d, 0x89, 0xae, 0xc6, 0x1e, 0x2c, 0xc4, 0x59, 0xfc, 0x06, 0x3e, 0xef, 0x3f, 0xca, 0xc1, 0x65, - 0x2e, 0x08, 0x44, 0x3e, 0x82, 0xb3, 0xcf, 0xe0, 0x7b, 0x30, 0xc1, 0x71, 0x77, 0xc2, 0xc5, 0x52, - 0x39, 0x7f, 0x7a, 0x52, 0x9a, 0x14, 0x1b, 0x16, 0xdb, 0xf5, 0x34, 0x30, 0xf4, 0x9e, 0xa2, 0xe3, - 0x64, 0x7a, 0x73, 0x22, 0xdd, 0x8f, 0x31, 0x65, 0x68, 0xaa, 0xa6, 0xd3, 0xf8, 0x1a, 0xae, 0xa4, - 0x75, 0xfc, 0x0d, 0xf0, 0xe5, 0x9f, 0xe5, 0xe0, 0x12, 0x27, 0xaf, 0x7d, 0x4e, 0xaf, 0xb4, 0x33, - 0x9f, 0xc1, 0xba, 0xee, 0x11, 0x8c, 0x93, 0x06, 0x45, 0xbf, 0x07, 0xf9, 0xf1, 0xc3, 0xa5, 0xeb, - 0xb0, 0x66, 0xd9, 0x0a, 0x2c, 0x6e, 0x2f, 0x60, 0x1d, 0xb7, 0x1b, 0xa2, 0xff, 0x2a, 0xb2, 0xf1, - 0x7d, 0x58, 0x4c, 0x1e, 0xc2, 0x1b, 0xe0, 0xcf, 0x23, 0x28, 0x26, 0x6c, 0x9c, 0xaf, 0x76, 0x6e, - 0x7d, 0x05, 0x97, 0x12, 0x69, 0xbd, 0x81, 0x6e, 0xae, 0x91, 0x53, 0x39, 0x78, 0x03, 0x53, 0x68, - 0xec, 0xc3, 0xc5, 0x04, 0x4a, 0x6f, 0xa0, 0x8b, 0xab, 0x30, 0x2f, 0xa5, 0xd1, 0xd7, 0xea, 0xe1, - 0x26, 0x5c, 0x66, 0x84, 0xde, 0xcc, 0xac, 0x3c, 0x86, 0x4b, 0x9c, 0xdc, 0x1b, 0xe0, 0xde, 0x1a, - 0x2c, 0x86, 0x97, 0xce, 0x04, 0x59, 0xa2, 0xef, 0x4d, 0xc6, 0xd8, 0x80, 0xab, 0x21, 0xa5, 0x94, - 0x83, 0xb5, 0x7f, 0x6a, 0x4c, 0x64, 0x0a, 0x67, 0xe9, 0x8d, 0xcc, 0xe8, 0x3e, 0x5c, 0xd0, 0x88, - 0xbe, 0x31, 0x71, 0x62, 0x1d, 0x66, 0x18, 0x61, 0x5d, 0xbc, 0x5c, 0x52, 0xc5, 0xcb, 0xf1, 0xa5, - 0xf3, 0x21, 0x49, 0x5a, 0xbc, 0xf7, 0x20, 0x41, 0xe2, 0xdc, 0xa4, 0x12, 0xa7, 0x00, 0x09, 0x7b, + 0x8a, 0xac, 0xce, 0xe2, 0xa3, 0x7b, 0xa6, 0x77, 0x6a, 0x92, 0x55, 0x21, 0x32, 0xaf, 0x8a, 0x99, + 0x35, 0x99, 0x59, 0x7a, 0xcc, 0xde, 0xdd, 0x7b, 0xd7, 0x6b, 0x2f, 0xfc, 0xe3, 0xf5, 0x1a, 0xd8, + 0x35, 0x76, 0xe1, 0x05, 0xd6, 0x86, 0x6d, 0xc0, 0x36, 0x60, 0x60, 0x7f, 0x8c, 0xfd, 0xf0, 0x97, + 0x61, 0x03, 0x1e, 0x1b, 0x58, 0xc0, 0xc0, 0xae, 0x61, 0xc0, 0x1f, 0x5c, 0xef, 0x00, 0xfe, 0x21, + 0xd6, 0x1f, 0x86, 0x61, 0x1b, 0x1e, 0xd8, 0x80, 0x11, 0xcf, 0x8c, 0xc8, 0x57, 0x15, 0x25, 0xf6, + 0xd8, 0x3f, 0x12, 0x2b, 0xe2, 0x9c, 0x13, 0x11, 0x27, 0x22, 0x23, 0x4e, 0x9c, 0x38, 0x0f, 0xb8, + 0x13, 0xe0, 0x36, 0xee, 0xb8, 0x5e, 0x70, 0xb7, 0x8d, 0x0f, 0xac, 0xe6, 0xab, 0xbb, 0xcd, 0xb6, + 0x8d, 0x9d, 0xe0, 0x6e, 0xc7, 0x73, 0x03, 0xf7, 0xae, 0xd5, 0x0d, 0x0e, 0x7d, 0xec, 0x3d, 0xb7, + 0x9b, 0xf8, 0x0e, 0x2d, 0x41, 0xc3, 0xf4, 0xbf, 0xe2, 0xec, 0x81, 0x7b, 0xe0, 0x32, 0x18, 0xf2, + 0x17, 0xab, 0x2c, 0x5e, 0x3a, 0x70, 0xdd, 0x83, 0x36, 0x66, 0xc8, 0xfb, 0xdd, 0xa7, 0x77, 0xf1, + 0x51, 0x27, 0x78, 0xc5, 0x2b, 0x4b, 0xd1, 0xca, 0xc0, 0x3e, 0xc2, 0x7e, 0x60, 0x1d, 0x75, 0x38, + 0xc0, 0x3b, 0xb2, 0x2b, 0x56, 0x10, 0x90, 0x9a, 0xc0, 0x76, 0x9d, 0xbb, 0xcf, 0xef, 0xab, 0x3f, + 0x39, 0xe8, 0xad, 0xcc, 0x5e, 0x37, 0xb1, 0x17, 0xf8, 0x7d, 0x41, 0xe2, 0xe7, 0xd8, 0x09, 0x62, + 0xcd, 0x73, 0xc8, 0xe0, 0x55, 0x07, 0xfb, 0x0c, 0x44, 0xfc, 0xc7, 0x41, 0xaf, 0x25, 0x83, 0xd2, + 0x7f, 0x39, 0xc8, 0x77, 0x92, 0x41, 0x5e, 0xe0, 0x7d, 0xc2, 0x53, 0x47, 0xfe, 0xd1, 0x03, 0xdc, + 0xb3, 0x3a, 0x1d, 0xec, 0x85, 0x7f, 0xc4, 0xfa, 0xda, 0xf5, 0xad, 0x03, 0xcc, 0xfb, 0xf8, 0xfc, + 0xbe, 0xfa, 0x93, 0x81, 0x1a, 0x7f, 0x90, 0x83, 0xe1, 0x3d, 0x2b, 0x68, 0x1e, 0xa2, 0xcf, 0x61, + 0xf8, 0xb1, 0xed, 0xb4, 0xfc, 0x85, 0xdc, 0xd5, 0xc1, 0x5b, 0xe3, 0x4b, 0x85, 0x3b, 0xac, 0xbf, + 0xb4, 0x92, 0x54, 0x54, 0xe6, 0x7f, 0x7a, 0x5c, 0x1a, 0x38, 0x39, 0x2e, 0x4d, 0x3f, 0x23, 0x60, + 0xdf, 0x76, 0x8f, 0xec, 0x80, 0x4e, 0xa0, 0xc9, 0xf0, 0xd0, 0x0e, 0xcc, 0x94, 0xdb, 0x6d, 0xf7, + 0x45, 0xcd, 0xf2, 0x02, 0xdb, 0x6a, 0xd7, 0xbb, 0xcd, 0x26, 0xf6, 0xfd, 0x85, 0xfc, 0xd5, 0xdc, + 0xad, 0xd1, 0xca, 0xf5, 0x93, 0xe3, 0x52, 0xc9, 0x22, 0xd5, 0x8d, 0x0e, 0xab, 0x6f, 0xf8, 0x0c, + 0x40, 0x21, 0x94, 0x84, 0x6f, 0xfc, 0xc5, 0x30, 0x14, 0xd6, 0x5c, 0x3f, 0xa8, 0x92, 0x69, 0x33, + 0xf1, 0x8f, 0xbb, 0xd8, 0x0f, 0xd0, 0x75, 0x38, 0x47, 0xca, 0xd6, 0x97, 0x17, 0x72, 0x57, 0x73, + 0xb7, 0xc6, 0x2a, 0xe3, 0x27, 0xc7, 0xa5, 0x91, 0x43, 0xd7, 0x0f, 0x1a, 0x76, 0xcb, 0xe4, 0x55, + 0xe8, 0x1d, 0x18, 0xdd, 0x74, 0x5b, 0x78, 0xd3, 0x3a, 0xc2, 0xb4, 0x17, 0x63, 0x95, 0xc9, 0x93, + 0xe3, 0xd2, 0x98, 0xe3, 0xb6, 0x70, 0xc3, 0xb1, 0x8e, 0xb0, 0x29, 0xab, 0xd1, 0x2e, 0x0c, 0x99, + 0x6e, 0x1b, 0x2f, 0x0c, 0x52, 0xb0, 0xca, 0xc9, 0x71, 0x69, 0xc8, 0x73, 0xdb, 0xf8, 0xe7, 0xc7, + 0xa5, 0xf7, 0x0f, 0xec, 0xe0, 0xb0, 0xbb, 0x7f, 0xa7, 0xe9, 0x1e, 0xdd, 0x3d, 0xf0, 0xac, 0xe7, + 0x36, 0x5b, 0x69, 0x56, 0xfb, 0x6e, 0xb8, 0x1e, 0x3b, 0x36, 0x9f, 0xdc, 0xfa, 0x2b, 0x3f, 0xc0, + 0x47, 0x84, 0x92, 0x49, 0xe9, 0xa1, 0x3d, 0x98, 0x2d, 0xb7, 0x5a, 0x36, 0xc3, 0xa8, 0x79, 0xb6, + 0xd3, 0xb4, 0x3b, 0x56, 0xdb, 0x5f, 0x18, 0xba, 0x3a, 0x78, 0x6b, 0x8c, 0x33, 0x45, 0xd6, 0x37, + 0x3a, 0x12, 0x40, 0x61, 0x4a, 0x22, 0x01, 0xf4, 0x00, 0x46, 0x97, 0x37, 0xeb, 0xa4, 0xef, 0xfe, + 0xc2, 0x30, 0x25, 0x36, 0x7f, 0x72, 0x5c, 0x9a, 0x69, 0x39, 0x3e, 0x1d, 0x9a, 0x4a, 0x40, 0x02, + 0xa2, 0xf7, 0x61, 0xa2, 0xd6, 0xdd, 0x6f, 0xdb, 0xcd, 0xed, 0x8d, 0xfa, 0x63, 0xfc, 0x6a, 0xe1, + 0xdc, 0xd5, 0xdc, 0xad, 0x89, 0x0a, 0x3a, 0x39, 0x2e, 0x4d, 0x75, 0x68, 0x79, 0x23, 0x68, 0xfb, + 0x8d, 0x67, 0xf8, 0x95, 0xa9, 0xc1, 0x85, 0x78, 0xf5, 0xfa, 0x1a, 0xc1, 0x1b, 0x89, 0xe1, 0xf9, + 0xfe, 0xa1, 0x8a, 0xc7, 0xe0, 0xd0, 0x5d, 0x00, 0x13, 0x1f, 0xb9, 0x01, 0x2e, 0xb7, 0x5a, 0xde, + 0xc2, 0x28, 0xe5, 0xed, 0xf4, 0xc9, 0x71, 0x69, 0xdc, 0xa3, 0xa5, 0x0d, 0xab, 0xd5, 0xf2, 0x4c, + 0x05, 0x04, 0x55, 0x61, 0xd4, 0x74, 0x19, 0x83, 0x17, 0xc6, 0xae, 0xe6, 0x6e, 0x8d, 0x2f, 0x4d, + 0xf3, 0x65, 0x28, 0x8a, 0x2b, 0x17, 0x4e, 0x8e, 0x4b, 0xc8, 0xe3, 0xbf, 0xd4, 0x51, 0x0a, 0x08, + 0x54, 0x82, 0x91, 0x4d, 0xb7, 0x6a, 0x35, 0x0f, 0xf1, 0x02, 0xd0, 0xb5, 0x37, 0x7c, 0x72, 0x5c, + 0xca, 0x7d, 0xc7, 0x14, 0xa5, 0xe8, 0x39, 0x8c, 0x87, 0x13, 0xe5, 0x2f, 0x8c, 0x53, 0xf6, 0x6d, + 0x9f, 0x1c, 0x97, 0x2e, 0xf8, 0xb4, 0xb8, 0x41, 0xa6, 0x5e, 0xe1, 0xe0, 0x1b, 0xac, 0x02, 0xb5, + 0xa1, 0x47, 0x43, 0xa3, 0x13, 0x85, 0x49, 0xf3, 0xf2, 0x8e, 0xe3, 0x07, 0xd6, 0x7e, 0x1b, 0x87, + 0x55, 0x65, 0xdf, 0xc7, 0x1e, 0xa1, 0xb7, 0xbe, 0x6c, 0xfc, 0xaf, 0x1c, 0xa0, 0xad, 0x0e, 0x76, + 0xea, 0xf5, 0x35, 0xb2, 0xe2, 0xc5, 0x82, 0xff, 0x36, 0x8c, 0x31, 0xd6, 0x12, 0xfe, 0xe7, 0x29, + 0xff, 0xa7, 0x4e, 0x8e, 0x4b, 0xc0, 0xf9, 0x4f, 0x78, 0x1f, 0x02, 0xa0, 0x1b, 0x30, 0xb8, 0xbd, + 0xbd, 0x41, 0x57, 0xf3, 0x60, 0x65, 0xe6, 0xe4, 0xb8, 0x34, 0x18, 0x04, 0xed, 0x9f, 0x1f, 0x97, + 0x46, 0x97, 0xbb, 0x1e, 0xed, 0xb8, 0x49, 0xea, 0xd1, 0x0d, 0x18, 0xa9, 0xb6, 0xbb, 0x7e, 0x80, + 0xbd, 0x85, 0xa1, 0xf0, 0x33, 0x6a, 0xb2, 0x22, 0x53, 0xd4, 0xa1, 0x6f, 0xc1, 0xd0, 0x8e, 0x8f, + 0xbd, 0x85, 0x61, 0x3a, 0x23, 0x93, 0x7c, 0x46, 0x48, 0xd1, 0xee, 0x52, 0x65, 0x94, 0x7c, 0x2b, + 0x5d, 0x1f, 0x7b, 0x26, 0x05, 0x42, 0x77, 0x60, 0x98, 0xb1, 0xf5, 0x1c, 0xdd, 0x46, 0x26, 0xe5, + 0xfc, 0xb5, 0xf1, 0xee, 0xfb, 0x95, 0xb1, 0x93, 0xe3, 0xd2, 0x30, 0x65, 0xaf, 0x39, 0x2c, 0x98, + 0x92, 0x2b, 0xe4, 0xcd, 0x51, 0x82, 0x4b, 0x16, 0xae, 0xf1, 0x2d, 0x18, 0x57, 0x86, 0x8f, 0x16, + 0x61, 0x88, 0xfc, 0x4f, 0x3f, 0xf3, 0x09, 0xd6, 0x18, 0xd9, 0xbf, 0x4d, 0x5a, 0x6a, 0xfc, 0xfe, + 0x34, 0x14, 0x08, 0xa6, 0xb6, 0x37, 0x68, 0xac, 0xca, 0xf5, 0x62, 0xd5, 0x2d, 0x90, 0x6d, 0xf3, + 0x4d, 0x62, 0xe2, 0xe4, 0xb8, 0x34, 0xda, 0xe5, 0x65, 0x61, 0xcf, 0x50, 0x1d, 0x46, 0x56, 0x5e, + 0x76, 0x6c, 0x0f, 0xfb, 0x94, 0xb1, 0xe3, 0x4b, 0xc5, 0x3b, 0xec, 0xcc, 0xba, 0x23, 0xce, 0xac, + 0x3b, 0xdb, 0xe2, 0xcc, 0xaa, 0x5c, 0xe6, 0x9b, 0xe5, 0x79, 0xcc, 0x50, 0xc2, 0xd5, 0xf4, 0x5b, + 0x7f, 0x56, 0xca, 0x99, 0x82, 0x12, 0xfa, 0x36, 0x9c, 0x7b, 0xe8, 0x7a, 0x47, 0x56, 0xc0, 0x67, + 0x60, 0xf6, 0xe4, 0xb8, 0x54, 0x78, 0x4a, 0x4b, 0x94, 0xc5, 0xcd, 0x61, 0xd0, 0x43, 0x98, 0x32, + 0xdd, 0x6e, 0x80, 0xb7, 0x5d, 0x31, 0x6f, 0xc3, 0x14, 0xeb, 0xca, 0xc9, 0x71, 0xa9, 0xe8, 0x91, + 0x9a, 0x46, 0xe0, 0x36, 0xf8, 0x04, 0x2a, 0xf8, 0x11, 0x2c, 0xb4, 0x02, 0x53, 0x65, 0xba, 0xbb, + 0x72, 0x9e, 0xb1, 0xd9, 0x1a, 0xab, 0x5c, 0x3e, 0x39, 0x2e, 0x5d, 0xb4, 0x68, 0x4d, 0xc3, 0xe3, + 0x55, 0x2a, 0x19, 0x1d, 0x09, 0x6d, 0xc2, 0xf9, 0xc7, 0xdd, 0x7d, 0xec, 0x39, 0x38, 0xc0, 0xbe, + 0xe8, 0xd1, 0x08, 0xed, 0xd1, 0xd5, 0x93, 0xe3, 0xd2, 0xe2, 0x33, 0x59, 0x99, 0xd0, 0xa7, 0x38, + 0x2a, 0xc2, 0x30, 0xcd, 0x3b, 0xba, 0x6c, 0x05, 0xd6, 0xbe, 0xe5, 0x63, 0xba, 0x69, 0x8c, 0x2f, + 0x5d, 0x60, 0x2c, 0xbe, 0x13, 0xa9, 0xad, 0x5c, 0xe7, 0x5c, 0xbe, 0x24, 0xc7, 0xde, 0xe2, 0x55, + 0x4a, 0x43, 0x51, 0x9a, 0x64, 0xef, 0x94, 0xe7, 0xc2, 0x18, 0xed, 0x2d, 0xdd, 0x3b, 0xe5, 0xb9, + 0xa0, 0xee, 0x2a, 0xf2, 0x84, 0xd8, 0x80, 0xe1, 0x1d, 0x72, 0x7a, 0xd2, 0x3d, 0x65, 0x6a, 0xe9, + 0x1a, 0xef, 0x51, 0x74, 0xf5, 0xdd, 0x21, 0x3f, 0x28, 0x20, 0xfd, 0xee, 0xa6, 0xe9, 0x89, 0xab, + 0x9e, 0x95, 0xb4, 0x0e, 0x7d, 0x01, 0xc0, 0x7b, 0x55, 0xee, 0x74, 0x16, 0xc6, 0xe9, 0x20, 0xcf, + 0xeb, 0x83, 0x2c, 0x77, 0x3a, 0x95, 0x2b, 0x7c, 0x7c, 0x17, 0xe4, 0xf8, 0xac, 0x4e, 0x47, 0xa1, + 0xa6, 0x10, 0x41, 0x9f, 0xc3, 0x04, 0xdd, 0x72, 0xc4, 0x8c, 0x4e, 0xd0, 0x19, 0xbd, 0x74, 0x72, + 0x5c, 0x9a, 0x27, 0x1f, 0x5c, 0xd2, 0x7c, 0x6a, 0x08, 0xe8, 0x57, 0x61, 0x8e, 0x93, 0xdb, 0xb3, + 0x9d, 0x96, 0xfb, 0xc2, 0x5f, 0xc6, 0xfe, 0xb3, 0xc0, 0xed, 0x2c, 0x4c, 0xd2, 0xee, 0x2d, 0xea, + 0xdd, 0xd3, 0x61, 0x2a, 0xb7, 0x79, 0x4f, 0x0d, 0xd9, 0xd3, 0x17, 0x0c, 0xa0, 0xd1, 0x62, 0x10, + 0x4a, 0xb3, 0xc9, 0xcd, 0xa0, 0x75, 0x98, 0xde, 0xf1, 0xb1, 0x36, 0x86, 0x29, 0xba, 0x7f, 0x97, + 0xc8, 0x0c, 0x77, 0x7d, 0xdc, 0x48, 0x1b, 0x47, 0x14, 0x0f, 0x99, 0x80, 0x96, 0x3d, 0xb7, 0x13, + 0x59, 0xe3, 0xd3, 0x94, 0x23, 0xc6, 0xc9, 0x71, 0xe9, 0x4a, 0xcb, 0x73, 0x3b, 0x8d, 0xf4, 0x85, + 0x9e, 0x80, 0x8d, 0x7e, 0x08, 0x17, 0xaa, 0xae, 0xe3, 0xe0, 0x26, 0xd9, 0x3f, 0x97, 0x6d, 0xeb, + 0xc0, 0x71, 0xfd, 0xc0, 0x6e, 0xae, 0x2f, 0x2f, 0x14, 0xe8, 0x1a, 0xba, 0x49, 0x46, 0xdf, 0x94, + 0x10, 0x8d, 0x96, 0x04, 0x69, 0xd8, 0x2d, 0x85, 0x76, 0x0a, 0x15, 0xf4, 0x03, 0x98, 0xe4, 0x6d, + 0x61, 0x8f, 0x2e, 0xcd, 0xf3, 0xd9, 0x0b, 0x4d, 0x02, 0xb3, 0x83, 0xd8, 0x13, 0x3f, 0x99, 0x68, + 0xa3, 0xd3, 0x42, 0x5f, 0xc3, 0xf8, 0x93, 0x87, 0x65, 0x13, 0xfb, 0x1d, 0xd7, 0xf1, 0xf1, 0x02, + 0xa2, 0x33, 0x7a, 0x85, 0x93, 0x7e, 0xf2, 0xb0, 0x5c, 0xee, 0x06, 0x87, 0xd8, 0x09, 0xec, 0xa6, + 0x15, 0x60, 0x01, 0x55, 0x29, 0x92, 0x95, 0x77, 0xf4, 0xd4, 0x6a, 0x78, 0xbc, 0x44, 0x19, 0x85, + 0x4a, 0x0e, 0x15, 0x61, 0xb4, 0x5e, 0x5f, 0xdb, 0x70, 0x0f, 0x6c, 0x67, 0x61, 0x86, 0x30, 0xc3, + 0x94, 0xbf, 0xd1, 0x3e, 0xcc, 0x29, 0x02, 0x7a, 0x83, 0xfc, 0x8f, 0x8f, 0xb0, 0x13, 0x2c, 0xcc, + 0xd2, 0x3e, 0x7c, 0x47, 0xde, 0x30, 0xee, 0xa8, 0x72, 0xfc, 0xf3, 0xfb, 0x77, 0xca, 0xe1, 0xcf, + 0xba, 0x40, 0x32, 0x67, 0xad, 0x84, 0x52, 0xb4, 0x0d, 0x23, 0xb5, 0xae, 0xd7, 0x71, 0x7d, 0xbc, + 0x30, 0x47, 0x99, 0x76, 0x3d, 0xeb, 0xeb, 0xe4, 0xa0, 0x95, 0x39, 0xb2, 0x3d, 0x77, 0xd8, 0x0f, + 0x65, 0x64, 0x82, 0x94, 0xf1, 0x25, 0x8c, 0xc9, 0x8f, 0x19, 0x8d, 0xc0, 0x60, 0xb9, 0xdd, 0x2e, + 0x0c, 0x90, 0x3f, 0xea, 0xf5, 0xb5, 0x42, 0x0e, 0x4d, 0x01, 0x84, 0x3b, 0x58, 0x21, 0x8f, 0x26, + 0x60, 0x54, 0xec, 0x30, 0x85, 0x41, 0x0a, 0xdf, 0xe9, 0x14, 0x86, 0x10, 0x82, 0x29, 0x7d, 0x9d, + 0x17, 0x86, 0x8d, 0x97, 0x30, 0x26, 0xa7, 0x07, 0x4d, 0xc3, 0xf8, 0xce, 0x66, 0xbd, 0xb6, 0x52, + 0x5d, 0x7f, 0xb8, 0xbe, 0xb2, 0x5c, 0x18, 0x40, 0x97, 0xe1, 0xe2, 0x76, 0x7d, 0xad, 0xb1, 0x5c, + 0x69, 0x6c, 0x6c, 0x55, 0xcb, 0x1b, 0x8d, 0x9a, 0xb9, 0xf5, 0xe5, 0x57, 0x8d, 0xed, 0x9d, 0xcd, + 0xcd, 0x95, 0x8d, 0x42, 0x0e, 0x2d, 0xc0, 0x2c, 0xa9, 0x7e, 0xbc, 0x53, 0x59, 0x51, 0x01, 0x0a, + 0x79, 0x74, 0x0d, 0x2e, 0x27, 0xd5, 0x34, 0xd6, 0x56, 0xca, 0xcb, 0x1b, 0x2b, 0xf5, 0x7a, 0x61, + 0xd0, 0x68, 0xc3, 0xb8, 0xc2, 0x02, 0xb4, 0x08, 0x0b, 0xd5, 0x15, 0x73, 0xbb, 0x51, 0xdb, 0x31, + 0x6b, 0x5b, 0xf5, 0x95, 0x86, 0xde, 0x91, 0x68, 0xed, 0xc6, 0xd6, 0xea, 0xfa, 0x66, 0x83, 0x14, + 0xd5, 0x0b, 0x39, 0xd2, 0x9a, 0x56, 0x5b, 0x5f, 0xdf, 0x5c, 0xdd, 0x58, 0x69, 0xec, 0xd4, 0x57, + 0x38, 0x48, 0xde, 0xf8, 0x77, 0xb9, 0xd8, 0x86, 0x8e, 0x96, 0x60, 0xbc, 0xce, 0xae, 0x8c, 0x74, + 0x91, 0x33, 0xf1, 0xbd, 0x70, 0x72, 0x5c, 0x9a, 0xe0, 0x37, 0x49, 0xb6, 0x7e, 0x55, 0x20, 0x72, + 0x46, 0xd7, 0xc8, 0x7c, 0x36, 0xdd, 0xb6, 0x7a, 0x46, 0x77, 0x78, 0x99, 0x29, 0x6b, 0xd1, 0x92, + 0x72, 0x9a, 0x33, 0x59, 0x9e, 0xca, 0x8b, 0xe2, 0x34, 0x57, 0x77, 0x76, 0x79, 0xae, 0x2f, 0x85, + 0x13, 0xc7, 0x0f, 0x61, 0x8a, 0x93, 0x70, 0x92, 0x48, 0x38, 0xa3, 0x9b, 0xb2, 0x57, 0xa2, 0x8f, + 0xa3, 0xd3, 0xcd, 0x47, 0x48, 0x0f, 0x83, 0xc8, 0x96, 0x68, 0x46, 0x40, 0x51, 0x09, 0x86, 0xd9, + 0x47, 0xc4, 0x06, 0x49, 0x85, 0xa5, 0x36, 0x29, 0x30, 0x59, 0xb9, 0xf1, 0x9b, 0x83, 0xea, 0xb9, + 0x41, 0x84, 0x23, 0x85, 0x89, 0x54, 0x38, 0xa2, 0xcc, 0xa3, 0xa5, 0x44, 0x0e, 0xaa, 0x63, 0xdf, + 0xa7, 0x62, 0x25, 0xa7, 0x48, 0xe5, 0x20, 0x9f, 0x15, 0x92, 0x9b, 0x52, 0x08, 0x40, 0x64, 0x75, + 0x26, 0x14, 0x51, 0x59, 0x7d, 0x30, 0x94, 0xd5, 0xb9, 0xd8, 0xc4, 0x64, 0xf5, 0x10, 0x84, 0x4c, + 0x24, 0x3f, 0xb7, 0x69, 0x1f, 0x86, 0xc2, 0x89, 0xe4, 0x67, 0x3d, 0x9f, 0x48, 0x05, 0x08, 0x7d, + 0x04, 0x50, 0xde, 0xab, 0x53, 0x91, 0xd7, 0xdc, 0xe4, 0xb2, 0x0b, 0xdd, 0x65, 0xac, 0x17, 0x3e, + 0xdb, 0xdd, 0x2d, 0x4f, 0x15, 0xea, 0x15, 0x68, 0x54, 0x81, 0xc9, 0xf2, 0x4f, 0xba, 0x1e, 0x5e, + 0x6f, 0x91, 0x8d, 0x2a, 0x60, 0xb7, 0x97, 0xb1, 0xca, 0xe2, 0xc9, 0x71, 0x69, 0xc1, 0x22, 0x15, + 0x0d, 0x9b, 0xd7, 0x28, 0x04, 0x74, 0x14, 0xb4, 0x05, 0xe7, 0x57, 0xab, 0x35, 0xbe, 0xb4, 0xca, + 0xcd, 0xa6, 0xdb, 0x75, 0x02, 0x2e, 0xb0, 0x5c, 0x3b, 0x39, 0x2e, 0x5d, 0x3e, 0x68, 0x76, 0x1a, + 0x62, 0x19, 0x5a, 0xac, 0x5a, 0x95, 0x58, 0x62, 0xb8, 0x46, 0x1b, 0xa6, 0x56, 0x71, 0x40, 0x96, + 0x92, 0x90, 0x3e, 0xb3, 0xe7, 0xe4, 0x13, 0x18, 0xdf, 0xb3, 0x83, 0xc3, 0x3a, 0x6e, 0x7a, 0x38, + 0x10, 0x77, 0x63, 0xca, 0x81, 0x17, 0x76, 0x70, 0xd8, 0xf0, 0x59, 0xb9, 0xba, 0xcf, 0x2a, 0xe0, + 0xc6, 0x0a, 0x4c, 0xf3, 0xd6, 0xa4, 0xb0, 0xbb, 0xa4, 0x13, 0xcc, 0x51, 0x82, 0x74, 0x16, 0x54, + 0x82, 0x3a, 0x99, 0x7f, 0x92, 0x87, 0xb9, 0xea, 0xa1, 0xe5, 0x1c, 0xe0, 0x9a, 0xe5, 0xfb, 0x2f, + 0x5c, 0xaf, 0xa5, 0x74, 0x9e, 0x4a, 0xfa, 0xb1, 0xce, 0x53, 0xd1, 0x7e, 0x09, 0xc6, 0xb7, 0xda, + 0x2d, 0x81, 0xc3, 0x6f, 0x21, 0xb4, 0x2d, 0xb7, 0xdd, 0x6a, 0x74, 0x04, 0x2d, 0x15, 0x88, 0xe0, + 0x6c, 0xe2, 0x17, 0x12, 0x67, 0x30, 0xc4, 0x71, 0xf0, 0x0b, 0x05, 0x47, 0x01, 0x42, 0x2b, 0x70, + 0xbe, 0x8e, 0x9b, 0xae, 0xd3, 0x7a, 0x68, 0x35, 0x03, 0xd7, 0xdb, 0x76, 0x9f, 0x61, 0x87, 0xaf, + 0x2f, 0x2a, 0xa8, 0xf9, 0xb4, 0xb2, 0xf1, 0x94, 0xd6, 0x36, 0x02, 0x52, 0x6d, 0xc6, 0x31, 0xd0, + 0x16, 0x8c, 0xee, 0x71, 0x35, 0x0a, 0xbf, 0xba, 0xdc, 0xb8, 0x23, 0xf5, 0x2a, 0x55, 0x0f, 0xd3, + 0x45, 0x61, 0xb5, 0xe5, 0xe5, 0x4b, 0x9e, 0x7b, 0x74, 0x73, 0x11, 0x90, 0xa6, 0x24, 0x62, 0xec, + 0xc0, 0x64, 0xad, 0xdd, 0x3d, 0xb0, 0x1d, 0xb2, 0x0d, 0xd4, 0xf1, 0x8f, 0xd1, 0x32, 0x40, 0x58, + 0xc0, 0xf5, 0x26, 0x33, 0xfc, 0xc2, 0x13, 0x56, 0xec, 0x3e, 0xe0, 0x1f, 0x12, 0x2d, 0xa1, 0x12, + 0xaa, 0xa9, 0xe0, 0x19, 0xff, 0x63, 0x10, 0x10, 0x9f, 0x00, 0x7a, 0xa4, 0xd5, 0x71, 0x40, 0xce, + 0x85, 0x0b, 0x90, 0x97, 0xea, 0x8d, 0x73, 0x27, 0xc7, 0xa5, 0xbc, 0xdd, 0x32, 0xf3, 0xeb, 0xcb, + 0xe8, 0x5d, 0x18, 0xa6, 0x60, 0x94, 0xff, 0x53, 0xb2, 0x3d, 0x95, 0x02, 0xdb, 0x39, 0xe8, 0x51, + 0x6b, 0x32, 0x60, 0xf4, 0x1e, 0x8c, 0x2d, 0xe3, 0x36, 0x3e, 0xb0, 0x02, 0x57, 0x7c, 0xdd, 0x4c, + 0x61, 0x20, 0x0a, 0x95, 0x35, 0x17, 0x42, 0x92, 0xeb, 0x89, 0x89, 0x2d, 0xdf, 0x75, 0xd4, 0xeb, + 0x89, 0x47, 0x4b, 0xd4, 0xeb, 0x09, 0x83, 0x41, 0xbf, 0x93, 0x83, 0xf1, 0xb2, 0xe3, 0xf0, 0x8b, + 0xb8, 0xcf, 0xb9, 0x3e, 0x77, 0x47, 0xaa, 0xa7, 0x36, 0xac, 0x7d, 0xdc, 0xde, 0xb5, 0xda, 0x5d, + 0xec, 0x57, 0xbe, 0x26, 0x12, 0xe3, 0xbf, 0x3f, 0x2e, 0x7d, 0x7c, 0x8a, 0xab, 0x75, 0xa8, 0xe8, + 0xda, 0xf6, 0x2c, 0x3b, 0xf0, 0x4f, 0x8e, 0x4b, 0x73, 0x56, 0xd8, 0xa0, 0xfa, 0xdd, 0x28, 0xfd, + 0x40, 0xef, 0xa8, 0x77, 0x52, 0xbe, 0x17, 0x47, 0xee, 0xf8, 0xfc, 0x3a, 0x8a, 0x8e, 0x60, 0xba, + 0xec, 0xfb, 0xdd, 0x23, 0x5c, 0x0f, 0x2c, 0x2f, 0x20, 0xf7, 0x39, 0xba, 0x3f, 0x64, 0x5f, 0xf6, + 0xde, 0xfe, 0xe9, 0x71, 0x29, 0x47, 0x84, 0x54, 0x8b, 0xa2, 0x12, 0x21, 0xc7, 0x0b, 0x1a, 0x81, + 0xad, 0x1e, 0x38, 0xf4, 0xda, 0x17, 0xa5, 0x6d, 0x5c, 0x97, 0x92, 0xc0, 0xfa, 0x72, 0xda, 0x8c, + 0x1b, 0x55, 0x58, 0x5c, 0xc5, 0x81, 0x89, 0x7d, 0x1c, 0x88, 0x6f, 0x84, 0xae, 0xf0, 0x50, 0x19, + 0x36, 0x42, 0x7f, 0x4b, 0x64, 0x3a, 0xfd, 0xec, 0xbb, 0x10, 0x35, 0xc6, 0x5f, 0xce, 0x41, 0xa9, + 0xea, 0x61, 0x26, 0xdf, 0xa5, 0x10, 0xca, 0xde, 0xbb, 0x16, 0x61, 0x68, 0xfb, 0x55, 0x47, 0xdc, + 0x92, 0x69, 0x2d, 0x99, 0x14, 0x93, 0x96, 0xf6, 0xa9, 0x72, 0x30, 0x9e, 0xc2, 0x9c, 0x89, 0x1d, + 0xfc, 0xc2, 0xda, 0x6f, 0x63, 0xed, 0xd6, 0x5e, 0x82, 0x61, 0xf6, 0xa1, 0xc7, 0x86, 0xc0, 0xca, + 0x4f, 0xa7, 0x01, 0x31, 0xfe, 0x61, 0x1e, 0x0a, 0x6c, 0xb8, 0x15, 0x37, 0xe8, 0x6f, 0x7c, 0x7c, + 0x04, 0xf9, 0x1e, 0x4a, 0x93, 0x9b, 0x21, 0xb7, 0x07, 0x43, 0x59, 0x84, 0x76, 0x95, 0x1c, 0xa9, + 0xa2, 0x92, 0x0c, 0x88, 0x2d, 0x3a, 0xa6, 0xeb, 0x8b, 0x69, 0x3e, 0xd0, 0x6f, 0xe4, 0xe0, 0x1c, + 0x5b, 0xc6, 0xd9, 0x1f, 0xca, 0xde, 0xd9, 0x7c, 0x28, 0x85, 0x80, 0xfe, 0xa5, 0x7e, 0xb6, 0xac, + 0xce, 0xf8, 0xc7, 0x79, 0x38, 0xaf, 0xf0, 0x8a, 0x0b, 0xf5, 0xef, 0x30, 0x51, 0x4a, 0x61, 0x18, + 0xd5, 0x9e, 0x12, 0x51, 0xaa, 0x11, 0x6a, 0x46, 0x28, 0xe7, 0xde, 0x81, 0x51, 0x32, 0xa4, 0xa8, + 0xa2, 0x95, 0x1e, 0xe8, 0x0c, 0x54, 0x54, 0xf7, 0xcd, 0xbd, 0xbb, 0x30, 0x4a, 0xff, 0x24, 0x33, + 0x32, 0x94, 0x3e, 0x23, 0x12, 0x08, 0xd9, 0x00, 0x8f, 0x5c, 0xdb, 0x79, 0x82, 0x83, 0x43, 0xb7, + 0xc5, 0x45, 0x8b, 0x75, 0xb2, 0xed, 0xfe, 0x3f, 0xae, 0xed, 0x34, 0x8e, 0x68, 0xf1, 0x69, 0x15, + 0x79, 0x21, 0x41, 0x53, 0x21, 0x6e, 0xdc, 0x83, 0x02, 0xd9, 0x21, 0xfb, 0x5f, 0x5a, 0xc6, 0x2c, + 0xa0, 0x55, 0x1c, 0x54, 0x5c, 0xed, 0xec, 0x36, 0x26, 0x61, 0xbc, 0x66, 0x3b, 0x07, 0xe2, 0xe7, + 0x1f, 0x0e, 0xc2, 0x04, 0xfb, 0xcd, 0x67, 0x20, 0x22, 0x61, 0xe5, 0xfa, 0x91, 0xb0, 0x3e, 0x80, + 0x49, 0x22, 0xa2, 0x60, 0x6f, 0x17, 0x7b, 0x44, 0xb2, 0xe3, 0xf3, 0x41, 0xaf, 0x88, 0x3e, 0xad, + 0x68, 0x3c, 0x67, 0x35, 0xa6, 0x0e, 0x88, 0x36, 0x60, 0x8a, 0x15, 0x3c, 0xc4, 0x56, 0xd0, 0x0d, + 0xb5, 0x5c, 0xd3, 0xfc, 0x2e, 0x25, 0x8a, 0xd9, 0xf6, 0xc9, 0x69, 0x3d, 0xe5, 0x85, 0x66, 0x04, + 0x17, 0x7d, 0x0e, 0xd3, 0x35, 0xcf, 0x7d, 0xf9, 0x4a, 0x91, 0x29, 0xd9, 0x09, 0xc2, 0x6e, 0x5d, + 0xa4, 0xaa, 0xa1, 0x4a, 0x96, 0x51, 0x68, 0xb2, 0xa6, 0xd6, 0xfd, 0x8a, 0xeb, 0xd9, 0xce, 0x01, + 0x9d, 0xcd, 0x51, 0xb6, 0xa6, 0x6c, 0xbf, 0xb1, 0x4f, 0x0b, 0x4d, 0x59, 0x1d, 0x51, 0x33, 0x8f, + 0xf4, 0x56, 0x33, 0xdf, 0x03, 0xd8, 0x70, 0xad, 0x56, 0xb9, 0xdd, 0xae, 0x96, 0x7d, 0xaa, 0x62, + 0xe2, 0x32, 0x53, 0xdb, 0xb5, 0x5a, 0x0d, 0xab, 0xdd, 0x6e, 0x34, 0x2d, 0xdf, 0x54, 0x60, 0x1e, + 0x0d, 0x8d, 0x9e, 0x2b, 0x8c, 0x98, 0xd3, 0x1b, 0x76, 0x13, 0x3b, 0x3e, 0xde, 0xb3, 0x3c, 0xc7, + 0x76, 0x0e, 0x7c, 0xe3, 0xf7, 0xc7, 0x61, 0x54, 0x0e, 0xf9, 0x8e, 0x7a, 0x21, 0xe4, 0x92, 0x18, + 0xdd, 0xa1, 0x42, 0x35, 0x98, 0xa9, 0x40, 0xa0, 0x8b, 0xf4, 0x8a, 0xc8, 0x65, 0xc0, 0x11, 0xb2, + 0xba, 0xad, 0x4e, 0xc7, 0x24, 0x65, 0xe4, 0x24, 0x58, 0xae, 0x50, 0xfe, 0x8f, 0xb2, 0x93, 0xa0, + 0xb5, 0x6f, 0xe6, 0x97, 0x2b, 0x64, 0x95, 0x6d, 0xad, 0x2f, 0x57, 0x29, 0x2b, 0x47, 0xd9, 0x2a, + 0x73, 0xed, 0x56, 0xd3, 0xa4, 0xa5, 0xa4, 0xb6, 0x5e, 0x7e, 0xb2, 0xc1, 0xd9, 0x45, 0x6b, 0x7d, + 0xeb, 0xa8, 0x6d, 0xd2, 0x52, 0x72, 0x33, 0x61, 0x1a, 0x8d, 0xaa, 0xeb, 0x04, 0x9e, 0xdb, 0xf6, + 0xa9, 0x00, 0x3d, 0xca, 0xa6, 0x93, 0xab, 0x42, 0x9a, 0xbc, 0xca, 0x8c, 0x80, 0xa2, 0x3d, 0x98, + 0x2f, 0xb7, 0x9e, 0x5b, 0x4e, 0x13, 0xb7, 0x58, 0xcd, 0x9e, 0xeb, 0x3d, 0x7b, 0xda, 0x76, 0x5f, + 0xf8, 0x94, 0xdf, 0xa3, 0x5c, 0x73, 0xc8, 0x41, 0x84, 0x66, 0xe5, 0x85, 0x00, 0x32, 0xd3, 0xb0, + 0xc9, 0x2e, 0x59, 0x6d, 0xbb, 0xdd, 0x16, 0x9f, 0x05, 0xba, 0x4b, 0x36, 0x49, 0x81, 0xc9, 0xca, + 0x09, 0x97, 0xd6, 0xea, 0x4f, 0xa8, 0x9e, 0x8e, 0x73, 0xe9, 0xd0, 0x3f, 0x32, 0x49, 0x19, 0xba, + 0x01, 0x23, 0xe2, 0x92, 0xc5, 0x14, 0xfd, 0x54, 0x7d, 0x2d, 0x2e, 0x57, 0xa2, 0x8e, 0x7c, 0x12, + 0x26, 0x6e, 0xba, 0xcf, 0xb1, 0xf7, 0xaa, 0xea, 0xb6, 0xb0, 0xd0, 0x2a, 0x71, 0xad, 0x09, 0xab, + 0x68, 0x34, 0x49, 0x8d, 0xa9, 0x03, 0x92, 0x06, 0x98, 0x9c, 0xe6, 0x2f, 0x4c, 0x87, 0x0d, 0x30, + 0x39, 0xce, 0x37, 0x45, 0x1d, 0x5a, 0x86, 0xf3, 0xe5, 0x6e, 0xe0, 0x1e, 0x59, 0x81, 0xdd, 0xdc, + 0xe9, 0x1c, 0x78, 0x16, 0x69, 0xa4, 0x40, 0x11, 0xe8, 0x4d, 0xd2, 0x12, 0x95, 0x8d, 0x2e, 0xaf, + 0x35, 0xe3, 0x08, 0xe8, 0x7d, 0x98, 0x58, 0xf7, 0x99, 0xe6, 0xd0, 0xf2, 0x71, 0x8b, 0xaa, 0x7f, + 0x78, 0x2f, 0x6d, 0xbf, 0x41, 0xf5, 0x88, 0x0d, 0x72, 0xf7, 0x6c, 0x99, 0x1a, 0x1c, 0x32, 0xe0, + 0x5c, 0xd9, 0xf7, 0x6d, 0x3f, 0xa0, 0x5a, 0x9d, 0xd1, 0x0a, 0x9c, 0x1c, 0x97, 0xce, 0x59, 0xb4, + 0xc4, 0xe4, 0x35, 0x68, 0x0f, 0xc6, 0x97, 0x31, 0xb9, 0xb7, 0x6c, 0x7b, 0x5d, 0x3f, 0xa0, 0x3a, + 0x9a, 0xf1, 0xa5, 0x8b, 0xfc, 0xc3, 0x56, 0x6a, 0xf8, 0x5a, 0x66, 0x37, 0x92, 0x16, 0x2d, 0x6f, + 0x04, 0xa4, 0x42, 0x95, 0xac, 0x14, 0x78, 0x72, 0x29, 0xe3, 0x38, 0x6b, 0x76, 0x8b, 0x7c, 0xaa, + 0xb3, 0xb4, 0x0f, 0xf4, 0x52, 0xc6, 0xf7, 0x86, 0xc6, 0x21, 0xad, 0x51, 0x2f, 0x65, 0x1a, 0x0a, + 0x6a, 0xc6, 0x94, 0xd1, 0x73, 0x9a, 0xc2, 0x51, 0xaf, 0x14, 0x5d, 0x3c, 0xa5, 0xaa, 0xfa, 0x13, + 0x18, 0xaf, 0x76, 0xfd, 0xc0, 0x3d, 0xda, 0x3e, 0xc4, 0x47, 0x78, 0xe1, 0x42, 0x78, 0xf5, 0x6c, + 0xd2, 0xe2, 0x46, 0x40, 0xca, 0xd5, 0x61, 0x2a, 0xe0, 0xe8, 0x0b, 0x40, 0xe2, 0x0e, 0xb9, 0x4a, + 0xd6, 0x87, 0x43, 0xd6, 0xf2, 0xc2, 0x3c, 0x1d, 0x2b, 0xbd, 0x38, 0x8a, 0xab, 0x67, 0xe3, 0x40, + 0x56, 0xab, 0xea, 0xc4, 0x38, 0x32, 0xe9, 0x10, 0xeb, 0xe2, 0xaa, 0x67, 0x75, 0x0e, 0x17, 0x16, + 0xc2, 0x9b, 0x20, 0x1f, 0xd4, 0x01, 0x29, 0xd7, 0x24, 0xda, 0x10, 0x1c, 0xd5, 0x01, 0xd8, 0xcf, + 0x0d, 0x32, 0xf1, 0x17, 0x29, 0xbf, 0x16, 0x34, 0x7e, 0x91, 0x0a, 0xc1, 0xab, 0x8b, 0x54, 0x4e, + 0x66, 0x64, 0xdb, 0xb6, 0x36, 0x9b, 0x0a, 0x19, 0xf4, 0x0c, 0x0a, 0xec, 0xd7, 0x13, 0xd7, 0xb1, + 0x03, 0xb6, 0xf5, 0x16, 0x35, 0x4d, 0x61, 0xb4, 0x5a, 0x34, 0x40, 0x35, 0xb4, 0xbc, 0x81, 0x23, + 0x59, 0xab, 0x34, 0x13, 0x23, 0x8c, 0x6a, 0x30, 0x5e, 0xf3, 0xdc, 0x56, 0xb7, 0x19, 0x50, 0xa1, + 0xf2, 0x12, 0xbd, 0xcc, 0x20, 0xde, 0x8e, 0x52, 0xc3, 0x78, 0xd2, 0x61, 0x05, 0x0d, 0x72, 0x2e, + 0xab, 0x3c, 0x51, 0x00, 0x1f, 0x0d, 0x8d, 0x8e, 0x17, 0x26, 0xd8, 0x23, 0xdb, 0xa3, 0xa1, 0xd1, + 0xc9, 0xc2, 0x94, 0xf1, 0xbb, 0x39, 0x40, 0xf1, 0xd5, 0x8d, 0xee, 0xc2, 0x08, 0x76, 0x88, 0x00, + 0xda, 0xe2, 0xbb, 0x34, 0x3d, 0x93, 0x78, 0x91, 0xaa, 0x09, 0xe4, 0x45, 0xe8, 0x0b, 0x98, 0x61, + 0x1f, 0x83, 0xf8, 0x0e, 0xdb, 0xf6, 0x91, 0x1d, 0xd0, 0x9d, 0x7b, 0x98, 0xcd, 0x7f, 0x42, 0xb5, + 0xaa, 0x38, 0xe0, 0xd5, 0xf4, 0xab, 0xdd, 0x20, 0x95, 0x46, 0x17, 0xe6, 0x12, 0xd7, 0x35, 0x7a, + 0x02, 0x73, 0x47, 0xae, 0x13, 0x1c, 0xb6, 0x5f, 0x89, 0x65, 0xcd, 0x5b, 0xcb, 0xd1, 0xd6, 0xe8, + 0x54, 0x26, 0x02, 0x98, 0x33, 0xbc, 0x98, 0x53, 0xa4, 0xed, 0x3c, 0x1a, 0x1a, 0xcd, 0x17, 0x06, + 0xe5, 0x48, 0x0c, 0x13, 0xce, 0xc7, 0x96, 0x07, 0xfa, 0x14, 0x26, 0x9a, 0x54, 0xfc, 0xd3, 0x5a, + 0x62, 0x1f, 0x87, 0x52, 0xae, 0xf2, 0x9d, 0x95, 0xb3, 0xa1, 0xfc, 0xfd, 0x1c, 0xcc, 0xa7, 0x2c, + 0x8c, 0xd3, 0xb3, 0xfa, 0x2b, 0xb8, 0x70, 0x64, 0xbd, 0x6c, 0x78, 0x54, 0x14, 0x6b, 0x78, 0x96, + 0x13, 0xe1, 0xf6, 0x5b, 0x27, 0xc7, 0xa5, 0xab, 0xc9, 0x10, 0xaa, 0x21, 0xc1, 0x91, 0xf5, 0xd2, + 0xa4, 0x00, 0x26, 0xa9, 0x67, 0xfd, 0xbc, 0x0f, 0xe7, 0x99, 0xd8, 0xd6, 0xb7, 0xba, 0xc6, 0xa8, + 0x01, 0xd4, 0xf1, 0x91, 0xd5, 0x39, 0x74, 0xc9, 0x01, 0x5f, 0x51, 0x7f, 0xf1, 0xeb, 0x3e, 0xe2, + 0xd7, 0x6f, 0x59, 0xb1, 0xfb, 0x40, 0x68, 0xd9, 0x04, 0xa4, 0xa9, 0x60, 0x19, 0x7f, 0x9c, 0x07, + 0x54, 0xee, 0xb6, 0xec, 0xa0, 0x1e, 0x78, 0xd8, 0x3a, 0x12, 0xdd, 0xf8, 0x10, 0x26, 0x98, 0x04, + 0xce, 0x8a, 0x69, 0x77, 0xc6, 0x97, 0x66, 0xf8, 0xe7, 0xa0, 0x56, 0xad, 0x0d, 0x98, 0x1a, 0x28, + 0x41, 0x35, 0x31, 0xbb, 0x55, 0x52, 0xd4, 0xbc, 0x86, 0xaa, 0x56, 0x11, 0x54, 0xf5, 0x37, 0xfa, + 0x1c, 0xa6, 0xaa, 0xee, 0x51, 0x87, 0xf0, 0x84, 0x23, 0x0f, 0xf2, 0x8b, 0x08, 0x6f, 0x57, 0xab, + 0x5c, 0x1b, 0x30, 0x23, 0xe0, 0x68, 0x13, 0x66, 0x1e, 0xb6, 0xbb, 0xfe, 0x61, 0xd9, 0x69, 0x55, + 0xdb, 0xae, 0x2f, 0xa8, 0x0c, 0xf1, 0x1b, 0x33, 0x17, 0x1c, 0xe3, 0x10, 0x6b, 0x03, 0x66, 0x12, + 0x22, 0xba, 0x01, 0xc3, 0x2b, 0xcf, 0xb1, 0x13, 0xc8, 0xa7, 0x66, 0x6e, 0xab, 0xb2, 0xe5, 0xe0, + 0xad, 0xa7, 0x6b, 0x03, 0x26, 0xab, 0xad, 0x8c, 0xc1, 0x88, 0x10, 0x9a, 0xef, 0x92, 0xb3, 0x57, + 0xb2, 0xb3, 0x1e, 0x58, 0x41, 0xd7, 0x47, 0x45, 0x18, 0xdd, 0xe9, 0x10, 0x59, 0x4e, 0xdc, 0x88, + 0x4d, 0xf9, 0xdb, 0xf8, 0xb6, 0xce, 0x69, 0xb4, 0xa8, 0x6a, 0x49, 0x19, 0x70, 0x58, 0x60, 0xac, + 0xe9, 0xcc, 0xcd, 0x86, 0xd6, 0xda, 0xcd, 0x47, 0xda, 0x2d, 0x44, 0x79, 0x6d, 0xcc, 0x25, 0x32, + 0xcf, 0xf8, 0x12, 0xae, 0xec, 0x74, 0x7c, 0xec, 0x05, 0xe5, 0x4e, 0xa7, 0x6d, 0x37, 0xd9, 0x53, + 0x07, 0x15, 0xae, 0xc5, 0x62, 0x79, 0x1f, 0xce, 0xb1, 0x02, 0xbe, 0x4c, 0xc4, 0x1a, 0x2c, 0x77, + 0x3a, 0x5c, 0xa4, 0x7f, 0xc0, 0xa4, 0x00, 0x26, 0xa4, 0x9b, 0x1c, 0xda, 0xf8, 0xad, 0x1c, 0x5c, + 0x61, 0x5f, 0x40, 0x2a, 0xe9, 0x6f, 0xc1, 0x18, 0x35, 0x15, 0xe9, 0x58, 0x4d, 0xed, 0xd6, 0xe7, + 0x88, 0x42, 0x33, 0xac, 0x57, 0x8c, 0x70, 0xf2, 0xe9, 0x46, 0x38, 0xe2, 0x03, 0x1b, 0x4c, 0xfc, + 0xc0, 0xbe, 0x00, 0x83, 0xf7, 0xa8, 0xdd, 0x8e, 0x75, 0xca, 0x7f, 0x9d, 0x5e, 0x19, 0xff, 0x29, + 0x0f, 0xf3, 0xab, 0xd8, 0xc1, 0x9e, 0x45, 0xc7, 0xa9, 0x29, 0x38, 0xd4, 0xc7, 0xfe, 0x5c, 0xe6, + 0x63, 0xbf, 0xbc, 0xbd, 0xe7, 0x53, 0x6e, 0xef, 0x17, 0x61, 0x70, 0xc7, 0x5c, 0xe7, 0xc3, 0xa2, + 0x72, 0x69, 0xd7, 0xb3, 0x4d, 0x52, 0x86, 0xd6, 0x43, 0x43, 0x81, 0xa1, 0x9e, 0xba, 0xa3, 0x19, + 0xfe, 0x70, 0x3a, 0xc2, 0x0d, 0x05, 0x74, 0xf3, 0x80, 0x4d, 0x45, 0x45, 0x40, 0xb6, 0x9b, 0xdb, + 0xfc, 0x9b, 0x4a, 0x19, 0x20, 0xbf, 0xed, 0xaf, 0x38, 0x81, 0xf7, 0x8a, 0x2d, 0x01, 0x76, 0xe9, + 0x17, 0x57, 0xfd, 0xe2, 0x17, 0x30, 0xae, 0x80, 0xa0, 0x02, 0x0c, 0x3e, 0xe3, 0x46, 0x12, 0x63, + 0x26, 0xf9, 0x13, 0x7d, 0x1b, 0x86, 0x9f, 0x5b, 0xed, 0x2e, 0xe6, 0xdb, 0xc8, 0x85, 0x50, 0x25, + 0x51, 0x0f, 0xc8, 0xc6, 0xce, 0x74, 0x12, 0x26, 0x03, 0xfa, 0x28, 0xff, 0x41, 0xce, 0xf8, 0x18, + 0x16, 0xe2, 0xbd, 0xe1, 0x37, 0xd8, 0x5e, 0x4a, 0x1d, 0x63, 0x19, 0x66, 0x57, 0x71, 0x40, 0x17, + 0x2e, 0xfd, 0x88, 0x14, 0x1b, 0x8e, 0xc8, 0x77, 0x96, 0xf1, 0x76, 0x61, 0xd4, 0x61, 0x2e, 0x42, + 0x85, 0xb7, 0xff, 0x11, 0x8c, 0xf0, 0x22, 0xb9, 0xa3, 0x72, 0xab, 0x36, 0xbc, 0xcf, 0x2b, 0x76, + 0x97, 0xd8, 0xba, 0xe5, 0x94, 0x4d, 0x81, 0x60, 0x1c, 0xc2, 0x05, 0x72, 0x48, 0x86, 0x54, 0xe5, + 0x72, 0xbc, 0x04, 0x63, 0x1d, 0x72, 0xcc, 0xfb, 0xf6, 0x4f, 0xd8, 0x32, 0x1a, 0x36, 0x47, 0x49, + 0x41, 0xdd, 0xfe, 0x09, 0x46, 0x97, 0x01, 0x68, 0x25, 0x1d, 0x26, 0xdf, 0x05, 0x28, 0x38, 0xd3, + 0x62, 0x21, 0xa0, 0xc6, 0x32, 0x6c, 0xdd, 0x98, 0xf4, 0x6f, 0xc3, 0x83, 0xf9, 0x58, 0x4b, 0x7c, + 0x00, 0x77, 0x61, 0x94, 0x77, 0xcc, 0x8f, 0xe8, 0x97, 0xd5, 0x11, 0x98, 0x12, 0x08, 0xdd, 0x84, + 0x69, 0x07, 0xbf, 0x0c, 0x1a, 0xb1, 0x3e, 0x4c, 0x92, 0xe2, 0x9a, 0xe8, 0x87, 0xf1, 0x4b, 0x54, + 0xa7, 0x58, 0x77, 0xdc, 0x17, 0x4f, 0xdb, 0xd6, 0x33, 0x1c, 0x6b, 0xf8, 0x53, 0x18, 0xad, 0xf7, + 0x6e, 0x98, 0x7d, 0x3e, 0xa2, 0x71, 0x53, 0xa2, 0x18, 0x6d, 0x28, 0x92, 0x21, 0x91, 0x8b, 0xe7, + 0x7a, 0xab, 0xf6, 0x4d, 0x33, 0xf0, 0x39, 0x5c, 0x4a, 0x6c, 0xed, 0x9b, 0x66, 0xe2, 0x9f, 0xe7, + 0x61, 0x9e, 0x1d, 0x26, 0xf1, 0x15, 0xdc, 0xff, 0x56, 0xf3, 0x0b, 0x79, 0x79, 0xbb, 0x97, 0xf0, + 0xf2, 0x46, 0x51, 0xd4, 0x97, 0x37, 0xed, 0xbd, 0xed, 0x83, 0xe4, 0xf7, 0x36, 0x7a, 0x21, 0xd5, + 0xdf, 0xdb, 0xa2, 0xaf, 0x6c, 0x2b, 0xe9, 0xaf, 0x6c, 0xf4, 0xcd, 0x21, 0xe1, 0x95, 0x2d, 0xe1, + 0x6d, 0x8d, 0x89, 0xae, 0xc6, 0x2e, 0x2c, 0xc4, 0x59, 0x7c, 0x06, 0x9f, 0xf7, 0x1f, 0xe5, 0xe0, + 0x32, 0x17, 0x04, 0x22, 0x1f, 0xc1, 0xe9, 0x67, 0xf0, 0x3d, 0x98, 0xe0, 0xb8, 0xdb, 0xe1, 0x62, + 0xa9, 0x9c, 0x3f, 0x39, 0x2e, 0x4d, 0x8a, 0x0d, 0x8b, 0xed, 0x7a, 0x1a, 0x18, 0x7a, 0x4f, 0xd1, + 0x71, 0x32, 0xbd, 0x39, 0x91, 0xee, 0xc7, 0x98, 0x32, 0x34, 0x55, 0xd3, 0x69, 0x7c, 0x0d, 0x57, + 0xd2, 0x3a, 0x7e, 0x06, 0x7c, 0xf9, 0x67, 0x39, 0xb8, 0xc4, 0xc9, 0x6b, 0x9f, 0xd3, 0x6b, 0xed, + 0xcc, 0xa7, 0xb0, 0xae, 0x7b, 0x04, 0xe3, 0xa4, 0x41, 0xd1, 0xef, 0x41, 0x7e, 0xfc, 0x70, 0xe9, + 0x3a, 0xac, 0x59, 0xb6, 0x02, 0x8b, 0xdb, 0x0b, 0x58, 0x47, 0xed, 0x86, 0xe8, 0xbf, 0x8a, 0x6c, + 0x7c, 0x1f, 0x16, 0x93, 0x87, 0x70, 0x06, 0xfc, 0x79, 0x04, 0xc5, 0x84, 0x8d, 0xf3, 0xf5, 0xce, + 0xad, 0xaf, 0xe0, 0x52, 0x22, 0xad, 0x33, 0xe8, 0xe6, 0x1a, 0x39, 0x95, 0x83, 0x33, 0x98, 0x42, + 0x63, 0x0f, 0x2e, 0x26, 0x50, 0x3a, 0x83, 0x2e, 0xae, 0xc2, 0xbc, 0x94, 0x46, 0xdf, 0xa8, 0x87, + 0x4f, 0xe0, 0x32, 0x23, 0x74, 0x36, 0xb3, 0xf2, 0x18, 0x2e, 0x71, 0x72, 0x67, 0xc0, 0xbd, 0x35, + 0x58, 0x0c, 0x2f, 0x9d, 0x09, 0xb2, 0x44, 0xdf, 0x9b, 0x8c, 0xb1, 0x01, 0x57, 0x43, 0x4a, 0x29, + 0x07, 0x6b, 0xff, 0xd4, 0x98, 0xc8, 0x14, 0xce, 0xd2, 0x99, 0xcc, 0xe8, 0x1e, 0x5c, 0xd0, 0x88, + 0x9e, 0x99, 0x38, 0xb1, 0x0e, 0x33, 0x8c, 0xb0, 0x2e, 0x5e, 0x2e, 0xa9, 0xe2, 0xe5, 0xf8, 0xd2, + 0xf9, 0x90, 0x24, 0x2d, 0xde, 0x7d, 0x90, 0x20, 0x71, 0x3e, 0xa1, 0x12, 0xa7, 0x00, 0x09, 0x7b, 0xf8, 0x1e, 0x9c, 0x63, 0x25, 0xbc, 0x7f, 0x09, 0xc4, 0x98, 0x40, 0xcd, 0xd0, 0x38, 0xb0, 0xf1, 0x43, 0xb8, 0xcc, 0x6e, 0x6b, 0xa1, 0x62, 0x5f, 0xbf, 0x51, 0x7d, 0x1a, 0xb9, 0xac, 0x5d, 0xe4, - 0x74, 0xa3, 0xf0, 0x29, 0x77, 0xb6, 0x03, 0xb1, 0xb6, 0xd3, 0xe8, 0xf7, 0xe5, 0x09, 0x21, 0x2e, + 0x74, 0xa3, 0xf0, 0x29, 0x77, 0xb6, 0x7d, 0xb1, 0xb6, 0xd3, 0xe8, 0xf7, 0xe5, 0x09, 0x21, 0x2e, 0x61, 0xf9, 0xc4, 0x4b, 0xd8, 0x75, 0xb8, 0x26, 0x2f, 0x61, 0xd1, 0x66, 0xe4, 0x63, 0xd5, 0xf7, 0xe1, 0x12, 0x1b, 0xa8, 0xb0, 0x81, 0xd2, 0xbb, 0xf1, 0x71, 0x64, 0x98, 0xf3, 0x7c, 0x98, 0x3a, - 0x74, 0xca, 0x20, 0xff, 0x5a, 0x4e, 0x7c, 0x72, 0xc9, 0xc4, 0x7f, 0xd1, 0xb7, 0xd2, 0x2d, 0x28, - 0x49, 0x86, 0xe8, 0x3d, 0x7a, 0xb5, 0x2b, 0xe9, 0x26, 0xcc, 0xa9, 0x64, 0xec, 0x26, 0xde, 0xbb, - 0x4f, 0x35, 0xae, 0xef, 0x92, 0xcf, 0x82, 0x16, 0x88, 0x65, 0xb7, 0x90, 0xc0, 0x37, 0x0a, 0x6f, - 0x4a, 0x48, 0xa3, 0x01, 0x8b, 0xf1, 0xa9, 0xb0, 0x9b, 0xc2, 0xfc, 0x15, 0x7d, 0x4e, 0x3e, 0x61, - 0x5a, 0xc2, 0x27, 0x23, 0x95, 0xa8, 0xf8, 0x8e, 0x19, 0xba, 0xc0, 0x32, 0x0c, 0xb1, 0xd5, 0x44, - 0xc6, 0x4f, 0x5a, 0x17, 0xeb, 0xe1, 0x57, 0x00, 0x89, 0xaa, 0x6a, 0xdd, 0x14, 0x4d, 0x5f, 0x84, - 0xc1, 0x6a, 0xdd, 0xe4, 0x56, 0xf7, 0xf4, 0x56, 0xdc, 0xf4, 0x3d, 0x93, 0x94, 0x45, 0xa5, 0xd6, - 0x7c, 0x1f, 0x52, 0xeb, 0xa3, 0xa1, 0xd1, 0xc1, 0xc2, 0x90, 0x89, 0xea, 0xf6, 0xa1, 0xb3, 0x6f, - 0x07, 0x47, 0xb2, 0xc1, 0xb2, 0xf1, 0x03, 0x98, 0xd1, 0x9a, 0xe7, 0x5f, 0x71, 0xa6, 0xbb, 0x00, - 0xba, 0x09, 0x23, 0xd5, 0x32, 0xb5, 0x3a, 0xa0, 0xd7, 0xfa, 0x09, 0xb6, 0xdf, 0x34, 0xad, 0x06, - 0x75, 0x09, 0x33, 0x45, 0xa5, 0xf1, 0xf7, 0x86, 0x14, 0xea, 0x8a, 0x13, 0x46, 0xc6, 0xe8, 0xee, - 0x03, 0xb0, 0x15, 0xa2, 0x0c, 0x8e, 0x08, 0x80, 0xe3, 0xfc, 0xa1, 0x94, 0x6d, 0xc9, 0xa6, 0x02, - 0xd4, 0xaf, 0x93, 0x06, 0x37, 0x98, 0x64, 0x48, 0xc2, 0x9a, 0x40, 0x1a, 0x4c, 0x72, 0xd2, 0xbe, - 0xa9, 0x02, 0xa1, 0x1f, 0x46, 0x6d, 0x89, 0x87, 0xa9, 0x7a, 0xfd, 0x2d, 0xf1, 0xe2, 0x13, 0x1f, - 0xdb, 0xd9, 0xcc, 0x89, 0x9f, 0xc3, 0x1c, 0xc1, 0xb5, 0x9f, 0x50, 0x83, 0xe1, 0x95, 0x17, 0x01, - 0x76, 0xd8, 0xde, 0x7e, 0x8e, 0xb6, 0x73, 0x23, 0xa3, 0x9d, 0x10, 0x98, 0x6b, 0x98, 0x43, 0x3a, - 0x0d, 0x2c, 0xeb, 0xcc, 0x64, 0xfa, 0x74, 0x11, 0x99, 0x1b, 0x2b, 0x4e, 0xab, 0xe3, 0xda, 0xf2, - 0x52, 0xc1, 0x16, 0x91, 0xd7, 0x6e, 0x60, 0x5e, 0x6e, 0xaa, 0x40, 0xc6, 0xcd, 0x4c, 0x6b, 0xdb, - 0x51, 0x18, 0xda, 0xa9, 0xee, 0x6c, 0x14, 0x72, 0xc6, 0x5d, 0x00, 0xa5, 0x25, 0x80, 0x73, 0x5b, - 0xdb, 0xe6, 0x66, 0x79, 0xa3, 0x30, 0x80, 0xe6, 0xe0, 0xfc, 0xfe, 0xfa, 0xd6, 0xf2, 0xf6, 0x7e, - 0xbd, 0x51, 0xdf, 0x2c, 0x9b, 0x3b, 0xd5, 0xb2, 0xb9, 0x5c, 0xc8, 0x19, 0x5f, 0xc3, 0xac, 0x3e, - 0xc2, 0x37, 0xba, 0x08, 0x03, 0x98, 0x91, 0xf2, 0xcc, 0xa3, 0xfd, 0x1d, 0xc5, 0xe0, 0x8f, 0x5f, - 0x90, 0xa2, 0x46, 0x01, 0xfc, 0x2a, 0xc5, 0x3f, 0x23, 0x05, 0x48, 0x33, 0xe5, 0xc8, 0x67, 0x9a, - 0x72, 0x18, 0xdf, 0x85, 0x59, 0xbd, 0xd5, 0x7e, 0x35, 0x39, 0x6f, 0x51, 0x4b, 0x48, 0xc5, 0x0a, - 0x9f, 0xdc, 0xd4, 0xc3, 0x2e, 0xf2, 0x9d, 0xf5, 0xbb, 0x50, 0xe0, 0x50, 0xe1, 0xc9, 0x7b, 0x5d, - 0xa8, 0xda, 0x72, 0x09, 0x1e, 0x43, 0x5c, 0xdd, 0x66, 0xbc, 0x2f, 0x4c, 0x54, 0xd4, 0x16, 0xae, - 0x71, 0xaf, 0xbd, 0x9c, 0xe6, 0x98, 0xc4, 0x11, 0x69, 0x15, 0xc1, 0xdb, 0xed, 0xb4, 0x5e, 0x11, - 0x8f, 0xec, 0xb1, 0x67, 0xc4, 0x7b, 0x5b, 0x3c, 0x32, 0xf4, 0xe2, 0xc4, 0x1f, 0xe7, 0x60, 0x21, - 0x62, 0x78, 0x5f, 0x3d, 0xb2, 0xda, 0x6d, 0xec, 0x1c, 0x62, 0x74, 0x0b, 0x86, 0x76, 0xb6, 0x77, - 0x6a, 0x5c, 0x09, 0x37, 0xcb, 0x3f, 0x27, 0x52, 0x24, 0x61, 0x4c, 0x0a, 0x81, 0x1e, 0xc3, 0x79, - 0x61, 0x9f, 0x28, 0xab, 0xf8, 0xe5, 0xe9, 0x72, 0xb6, 0xb5, 0x63, 0x1c, 0x0f, 0xbd, 0xcb, 0xbd, - 0x04, 0x7e, 0xdc, 0xb5, 0x3d, 0xdc, 0xa2, 0x8a, 0x85, 0xf0, 0x4d, 0x4e, 0xa9, 0x31, 0x55, 0x30, - 0xe6, 0xc1, 0x65, 0xfc, 0x4e, 0x0e, 0xe6, 0x53, 0x1c, 0x09, 0xd0, 0x3b, 0xda, 0x70, 0x66, 0x94, - 0xe1, 0x08, 0x90, 0xb5, 0x01, 0x3e, 0x9e, 0xaa, 0x62, 0xb4, 0x39, 0x78, 0x06, 0xa3, 0xcd, 0xb5, - 0x81, 0xd0, 0x50, 0xb3, 0x02, 0x30, 0x2a, 0xca, 0x8d, 0x69, 0x98, 0xd4, 0xf8, 0x66, 0x18, 0x30, - 0xa1, 0xb6, 0x4c, 0x26, 0xa7, 0xea, 0xb6, 0xe4, 0xe4, 0x90, 0xbf, 0x8d, 0xbf, 0x91, 0x83, 0x59, - 0x3a, 0xc4, 0x43, 0x9b, 0xec, 0x1a, 0x21, 0x87, 0x96, 0xb4, 0x91, 0x2c, 0x6a, 0x23, 0x89, 0xc0, - 0xca, 0x21, 0x7d, 0x14, 0x1b, 0xd2, 0x62, 0xd2, 0x90, 0xe8, 0xf2, 0xb6, 0x5d, 0x47, 0x1b, 0x89, - 0xf2, 0xd2, 0xf1, 0xbb, 0x39, 0x98, 0x51, 0xfa, 0x24, 0xfb, 0x7f, 0x5f, 0xeb, 0xd2, 0xa5, 0x84, - 0x2e, 0xc5, 0x98, 0x5c, 0x89, 0xf5, 0xe8, 0xad, 0xac, 0x1e, 0xf5, 0xe4, 0xf1, 0x7f, 0xcc, 0xc1, - 0x5c, 0x22, 0x0f, 0xd0, 0x05, 0x22, 0x16, 0x36, 0x3d, 0x1c, 0x70, 0xf6, 0xf2, 0x5f, 0xa4, 0x7c, - 0xdd, 0xf7, 0xbb, 0xd8, 0xe3, 0x8a, 0x35, 0xfe, 0x0b, 0xbd, 0x05, 0x93, 0x35, 0xec, 0xd9, 0x6e, - 0x8b, 0x99, 0xf3, 0x32, 0x1b, 0xa4, 0x49, 0x53, 0x2f, 0x44, 0x8b, 0x30, 0x56, 0x6e, 0x1f, 0xba, - 0x9e, 0x1d, 0x1c, 0xb1, 0xc7, 0xa6, 0x31, 0x33, 0x2c, 0x20, 0xb4, 0x97, 0xed, 0x43, 0x61, 0x56, - 0x37, 0x69, 0xf2, 0x5f, 0x68, 0x01, 0x46, 0x84, 0x32, 0x8a, 0xaa, 0xb2, 0x4c, 0xf1, 0x93, 0x60, - 0x7c, 0x61, 0xd2, 0x45, 0x40, 0x3d, 0x5b, 0x4d, 0xfe, 0x0b, 0x4d, 0x51, 0x83, 0x4c, 0xea, 0xb7, - 0x4a, 0x0d, 0x31, 0x3f, 0x82, 0xd9, 0x24, 0xbe, 0x26, 0x2d, 0x21, 0x8e, 0x9b, 0x97, 0xb8, 0xff, - 0x7f, 0x1e, 0x66, 0xca, 0xad, 0xd6, 0xe6, 0xc3, 0x32, 0x7b, 0x91, 0x16, 0x7b, 0xc3, 0xbb, 0x30, - 0xb4, 0xee, 0xf0, 0x47, 0x57, 0xe5, 0xa1, 0x3d, 0x0e, 0x49, 0xa0, 0xc8, 0x0c, 0x92, 0xff, 0x91, - 0x09, 0x33, 0x2b, 0x2f, 0x6c, 0x3f, 0xb0, 0x9d, 0x43, 0xd5, 0xaf, 0x27, 0xdf, 0x8f, 0x5f, 0xcf, - 0xda, 0x80, 0x99, 0x84, 0x8c, 0x76, 0xe0, 0xc2, 0x16, 0x7e, 0x9e, 0xb0, 0xc4, 0xa4, 0xbb, 0xa3, - 0xb2, 0x11, 0xc4, 0x56, 0x56, 0x0a, 0xae, 0xba, 0x82, 0x7f, 0x23, 0x4f, 0xbd, 0xa1, 0x95, 0x81, - 0xf1, 0x96, 0x77, 0x61, 0x56, 0xe9, 0x50, 0xb8, 0x8f, 0x31, 0x9e, 0x94, 0x92, 0x87, 0xa3, 0x7e, - 0x68, 0x89, 0xe8, 0x68, 0x1f, 0xe6, 0xf5, 0x4e, 0x85, 0x94, 0xf5, 0x8f, 0x25, 0x09, 0x64, 0x6d, - 0xc0, 0x4c, 0xc3, 0x46, 0x4b, 0x30, 0x58, 0x6e, 0x3e, 0xe5, 0x6c, 0x49, 0x9e, 0x32, 0x36, 0xb2, - 0x72, 0xf3, 0xe9, 0xda, 0x80, 0x49, 0x80, 0xb5, 0xef, 0xe5, 0x5f, 0xe4, 0x60, 0x3e, 0x65, 0x86, - 0xd1, 0x15, 0x00, 0x56, 0xa8, 0x9c, 0x18, 0x4a, 0x09, 0x11, 0x34, 0xb9, 0x49, 0xc3, 0xcb, 0x0e, - 0x9b, 0x99, 0x29, 0xe9, 0x39, 0x18, 0x56, 0x98, 0x0a, 0x10, 0xaa, 0x09, 0xeb, 0x1f, 0xe6, 0xc0, - 0xa8, 0x6f, 0xeb, 0x4a, 0x8d, 0x66, 0xf6, 0x13, 0x75, 0x5c, 0x54, 0x49, 0x70, 0xd5, 0x6c, 0x35, - 0x3a, 0x0a, 0x39, 0x68, 0x74, 0x0b, 0xce, 0xb1, 0x42, 0x3e, 0x87, 0x22, 0x9a, 0x40, 0x08, 0xcc, - 0xeb, 0x8d, 0xbf, 0x9d, 0x83, 0x0b, 0xec, 0xc4, 0x8c, 0x7d, 0x1a, 0xdf, 0xd5, 0x3e, 0x8d, 0x6b, - 0xb2, 0xc3, 0x49, 0xc0, 0xda, 0xd7, 0x51, 0xd1, 0xbd, 0xdd, 0xfa, 0xfd, 0x2a, 0x54, 0x24, 0x75, - 0xdd, 0xfe, 0xdd, 0x9c, 0xd0, 0x54, 0xc5, 0x97, 0xee, 0x0a, 0x4c, 0xbc, 0xda, 0x92, 0xd5, 0xd0, - 0xd0, 0x7b, 0x6c, 0x45, 0xe5, 0xb3, 0x47, 0x9a, 0xb9, 0xa8, 0x3e, 0x81, 0x62, 0x3a, 0x6b, 0x7a, - 0x2d, 0x2b, 0xe3, 0x61, 0x02, 0xf6, 0xab, 0x4c, 0xe7, 0x5f, 0xe4, 0x62, 0x84, 0xea, 0x2f, 0x9d, - 0xa6, 0x98, 0xd2, 0x9b, 0x51, 0x53, 0xf5, 0x54, 0xf3, 0x5f, 0xb5, 0xbb, 0xf9, 0xf0, 0x4d, 0x84, - 0xaf, 0x4e, 0x2a, 0xb5, 0xaa, 0x9f, 0x45, 0x37, 0x79, 0x43, 0x1c, 0xec, 0xcb, 0xd1, 0x91, 0xc6, - 0x61, 0xc0, 0x1c, 0xbd, 0x91, 0xe2, 0xf1, 0x98, 0x44, 0xdf, 0xf8, 0xcd, 0x41, 0xfd, 0x1b, 0x78, - 0x95, 0xb1, 0xd6, 0x60, 0xbc, 0xea, 0x3a, 0x01, 0x7e, 0x11, 0x28, 0x5e, 0xf6, 0x48, 0x9a, 0x60, - 0xc8, 0x1a, 0x7e, 0x5f, 0x62, 0x05, 0x0d, 0x22, 0xbc, 0x6b, 0xe6, 0x6a, 0x21, 0x20, 0xaa, 0xc2, - 0xe4, 0x16, 0x7e, 0x1e, 0x63, 0x20, 0x35, 0x99, 0x73, 0xf0, 0xf3, 0x86, 0xc2, 0x44, 0xd5, 0x2c, - 0x4f, 0xc3, 0x41, 0x07, 0x30, 0x25, 0xf6, 0xbf, 0x7e, 0x8f, 0x01, 0xe6, 0x87, 0x4e, 0x5a, 0x48, - 0xe1, 0x61, 0x84, 0xe2, 0x9b, 0xdf, 0x99, 0x8c, 0x1a, 0x2c, 0xc4, 0xe7, 0x83, 0xb7, 0xf6, 0x6e, - 0xaf, 0x55, 0xcc, 0x94, 0x53, 0x2d, 0x7d, 0x45, 0xaf, 0x51, 0x85, 0xa1, 0x84, 0x91, 0x1a, 0xa0, - 0x7b, 0xd1, 0xe9, 0xa5, 0xb6, 0x9e, 0x62, 0x7a, 0x55, 0xdb, 0x26, 0xe1, 0x82, 0x51, 0xa5, 0x3a, - 0x57, 0x95, 0x12, 0xef, 0xd8, 0x6d, 0x18, 0xe1, 0x45, 0x91, 0xe0, 0x2b, 0xe1, 0xf7, 0x25, 0x00, - 0x8c, 0xdf, 0xcb, 0xc1, 0x45, 0xaa, 0x01, 0xb6, 0x9d, 0xc3, 0x36, 0xde, 0xf5, 0x75, 0x2f, 0x8a, - 0xef, 0x68, 0x5b, 0xe6, 0x7c, 0x8a, 0x1b, 0xec, 0x37, 0xb5, 0x51, 0xfe, 0x41, 0x0e, 0x8a, 0x49, - 0x7d, 0x7b, 0xb3, 0x7b, 0xe5, 0x1d, 0x7e, 0xbd, 0xce, 0x6b, 0x56, 0x8f, 0xb2, 0x4d, 0x31, 0x58, - 0x32, 0x48, 0xf2, 0xbf, 0xb6, 0x49, 0xfe, 0xb7, 0x1c, 0xcc, 0xae, 0xfb, 0xea, 0x55, 0x86, 0x33, - 0xee, 0x4e, 0x52, 0x28, 0x03, 0x3a, 0xaf, 0x6b, 0x03, 0x49, 0xa1, 0x0a, 0xde, 0x55, 0x9c, 0x46, - 0xf3, 0x59, 0x31, 0x0a, 0x88, 0xd0, 0x2c, 0x9d, 0x5f, 0x6f, 0xc2, 0xd0, 0x16, 0x11, 0x14, 0x07, - 0xf9, 0xfa, 0x63, 0x18, 0xa4, 0x88, 0xfa, 0x77, 0x92, 0x2e, 0x93, 0x1f, 0xe8, 0x61, 0xcc, 0x8b, - 0x74, 0xa8, 0xb7, 0x0f, 0xfe, 0xda, 0x40, 0xd4, 0xa1, 0xb4, 0x32, 0x0a, 0xe7, 0x76, 0x2c, 0xef, - 0x10, 0x07, 0xc6, 0xf7, 0xa1, 0xc8, 0x4d, 0xa4, 0x98, 0x4e, 0x9d, 0x1a, 0x52, 0xf9, 0xa1, 0x15, - 0x5c, 0x96, 0x59, 0xd3, 0x15, 0x00, 0xea, 0xb1, 0xb4, 0xee, 0xb4, 0xf0, 0x0b, 0x66, 0x87, 0x67, - 0x2a, 0x25, 0xc6, 0x7b, 0x30, 0x26, 0x87, 0x40, 0xef, 0xba, 0x8a, 0x2c, 0x4c, 0x87, 0x33, 0xab, - 0xf9, 0xb5, 0x0a, 0x67, 0x56, 0x1b, 0xe6, 0x22, 0x53, 0x11, 0xba, 0x93, 0xcb, 0x3b, 0x28, 0xb5, - 0x1a, 0x34, 0xe5, 0xef, 0xe8, 0x15, 0x35, 0xdf, 0xd7, 0x15, 0xd5, 0xa8, 0xc2, 0xf9, 0xd8, 0xfa, - 0x40, 0x88, 0x7a, 0x72, 0x33, 0x2d, 0x0d, 0x39, 0x50, 0xeb, 0xf5, 0x35, 0x52, 0xb6, 0xb3, 0x51, - 0x67, 0xee, 0x45, 0xa4, 0x6c, 0x67, 0xa3, 0x5e, 0x39, 0xc7, 0xd6, 0x9b, 0xf1, 0x8f, 0xf2, 0x54, - 0x79, 0x11, 0xe3, 0x5c, 0x44, 0x0f, 0xac, 0xea, 0xa2, 0x2b, 0x30, 0x46, 0xf9, 0xb4, 0x2c, 0xfc, - 0xf5, 0xb2, 0x6d, 0x81, 0x46, 0x7f, 0x7a, 0x52, 0x1a, 0xa0, 0x06, 0x40, 0x21, 0x1a, 0xfa, 0x0c, - 0x46, 0x56, 0x9c, 0x16, 0xa5, 0x30, 0x78, 0x06, 0x0a, 0x02, 0x89, 0xcc, 0x1e, 0xed, 0x32, 0x11, - 0x05, 0xb9, 0xfa, 0xd0, 0x54, 0x4a, 0xe8, 0xe4, 0x50, 0x03, 0xcb, 0x61, 0x3a, 0xb1, 0xec, 0x07, - 0x75, 0xe9, 0x27, 0x5d, 0x10, 0x61, 0x82, 0xc6, 0x4c, 0xf9, 0x1b, 0x19, 0x30, 0xbc, 0xed, 0xb5, - 0x78, 0xa8, 0x8f, 0xa9, 0xa5, 0x09, 0xce, 0x7d, 0x5a, 0x66, 0xb2, 0x2a, 0xe3, 0xbf, 0xe4, 0x60, - 0x7e, 0x15, 0x07, 0x89, 0xab, 0x4d, 0xe3, 0x4a, 0xee, 0xb5, 0xb9, 0x92, 0x7f, 0x15, 0xae, 0xc8, - 0x51, 0x0f, 0xa6, 0x8d, 0x7a, 0x28, 0x6d, 0xd4, 0xc3, 0xe9, 0xa3, 0x5e, 0x85, 0x73, 0x6c, 0xa8, - 0xe8, 0x3a, 0x0c, 0xaf, 0x07, 0xf8, 0x38, 0x54, 0x6a, 0xa9, 0x96, 0x8c, 0x26, 0xab, 0x23, 0x37, - 0xd2, 0x0d, 0xcb, 0x0f, 0x84, 0x43, 0xdb, 0x98, 0x29, 0x7e, 0x1a, 0x3f, 0xa2, 0x9e, 0xbe, 0x1b, - 0x6e, 0xf3, 0xa9, 0xf2, 0xe2, 0x30, 0xc2, 0xbe, 0xe5, 0xe8, 0x0b, 0x15, 0x81, 0x62, 0x35, 0xa6, - 0x80, 0x40, 0x57, 0x61, 0x7c, 0xdd, 0x79, 0xe8, 0x7a, 0x4d, 0xbc, 0xed, 0xb4, 0x19, 0xf5, 0x51, - 0x53, 0x2d, 0xe2, 0x9a, 0x38, 0xde, 0x42, 0xa8, 0x89, 0xa3, 0x05, 0x11, 0x4d, 0x1c, 0x29, 0xdb, - 0x5b, 0x32, 0x59, 0x1d, 0x57, 0xf4, 0x91, 0xbf, 0xb3, 0xd4, 0x5b, 0x52, 0x0f, 0xd6, 0x0b, 0xf0, - 0x00, 0x2e, 0x9a, 0xb8, 0xd3, 0xb6, 0x88, 0xc0, 0x79, 0xec, 0x32, 0x78, 0x39, 0xe6, 0xab, 0x09, - 0x1e, 0x50, 0xba, 0x5d, 0x8b, 0xec, 0x72, 0x3e, 0xa3, 0xcb, 0xc7, 0x70, 0x6d, 0x15, 0x07, 0xfa, - 0xde, 0x18, 0xbe, 0x67, 0xf0, 0xc1, 0xaf, 0xc1, 0xa8, 0xaf, 0xbf, 0xc5, 0x5c, 0x11, 0x4f, 0x80, - 0x49, 0x88, 0x7b, 0x0f, 0xc4, 0x6b, 0x25, 0xa7, 0x23, 0xff, 0x32, 0x3e, 0x87, 0x52, 0x5a, 0x73, - 0xfd, 0x99, 0x1d, 0xdb, 0x70, 0x35, 0x9d, 0x80, 0x3c, 0x4c, 0xc5, 0xbb, 0x8d, 0x54, 0x1d, 0x64, - 0xf7, 0x56, 0x7f, 0xea, 0xe1, 0x7f, 0x18, 0x15, 0x61, 0x80, 0xf9, 0x1a, 0xdd, 0x6d, 0x50, 0x93, - 0x08, 0x9d, 0x40, 0xc8, 0xd7, 0x32, 0x8c, 0x8a, 0x32, 0xce, 0xd7, 0xf9, 0xc4, 0x9e, 0x0a, 0x86, - 0xb6, 0x04, 0x01, 0x89, 0x66, 0xfc, 0x48, 0x3c, 0x0f, 0xea, 0x18, 0xfd, 0xb9, 0x75, 0xf6, 0xf3, - 0x1e, 0x68, 0xb8, 0x70, 0x51, 0xa7, 0xad, 0x3e, 0xfb, 0x14, 0x94, 0x67, 0x1f, 0xf6, 0xda, 0x73, - 0x55, 0x7f, 0x86, 0xc8, 0xf3, 0x75, 0x19, 0x16, 0xa1, 0x2b, 0xea, 0xe3, 0xce, 0x44, 0xdc, 0x0f, - 0xf6, 0x1e, 0x14, 0x93, 0x1a, 0x54, 0x14, 0x4a, 0xf2, 0x05, 0x81, 0xc7, 0xba, 0xfa, 0xb5, 0x1c, - 0x18, 0x9a, 0x95, 0x1b, 0x9d, 0xa1, 0x9a, 0xe7, 0x3e, 0xb3, 0x5b, 0xca, 0xc3, 0xe4, 0x3b, 0x62, - 0x63, 0x63, 0x56, 0xfc, 0xd4, 0xbb, 0x2b, 0x6a, 0x1e, 0xcf, 0x77, 0xbb, 0x7b, 0x30, 0xb2, 0x85, - 0x5f, 0x84, 0xdb, 0x0f, 0x93, 0x60, 0xa9, 0xe5, 0xdb, 0x53, 0xac, 0x46, 0x51, 0x10, 0x60, 0x44, - 0x7c, 0xba, 0x9e, 0xd9, 0x07, 0xde, 0xff, 0x03, 0x28, 0x44, 0xeb, 0xf8, 0xdc, 0x97, 0x14, 0x8b, - 0x9e, 0x38, 0x85, 0xbd, 0xfb, 0xcc, 0x41, 0x40, 0x58, 0x87, 0x75, 0x24, 0xe5, 0x18, 0xbd, 0xb3, - 0xf7, 0x1e, 0x7d, 0x08, 0xb0, 0xe3, 0x06, 0x56, 0xbb, 0x4a, 0x75, 0x80, 0x83, 0xa1, 0x3f, 0x45, - 0x40, 0x4a, 0x1b, 0xd1, 0x70, 0x0f, 0x0a, 0xb0, 0xf1, 0x3d, 0xfa, 0x45, 0x26, 0x77, 0xba, 0xbf, - 0x8f, 0xa4, 0x0a, 0xd7, 0x23, 0x56, 0x25, 0xaf, 0x40, 0x24, 0x80, 0x39, 0xc2, 0x7e, 0x22, 0xc2, - 0xac, 0x7a, 0x6e, 0xb7, 0xf3, 0x8b, 0x99, 0xf5, 0x7f, 0x9d, 0x63, 0xa6, 0xb0, 0x6a, 0xb3, 0x7c, - 0xa2, 0xab, 0x00, 0x61, 0x69, 0xc4, 0x25, 0x42, 0x56, 0xec, 0xdd, 0x67, 0x77, 0x77, 0xfa, 0xde, - 0x74, 0xc8, 0x08, 0x28, 0x68, 0xbf, 0xd8, 0x99, 0x7c, 0x40, 0x4d, 0x49, 0x64, 0xeb, 0xfd, 0xf1, - 0xfd, 0x7d, 0xa1, 0xa3, 0x3a, 0x23, 0xde, 0x11, 0xcc, 0x92, 0x6f, 0x97, 0xdc, 0x6b, 0x5c, 0xcf, - 0x0e, 0x84, 0x6b, 0x0e, 0xaa, 0x71, 0x57, 0x7a, 0x86, 0xf5, 0xc9, 0xcf, 0x4f, 0x4a, 0x1f, 0x9c, - 0xc5, 0x2f, 0x59, 0xd0, 0xdc, 0x91, 0xee, 0xf7, 0xc6, 0x3c, 0x0c, 0x56, 0xcd, 0x0d, 0xba, 0x55, - 0x99, 0x1b, 0x72, 0xab, 0x32, 0x37, 0x8c, 0xff, 0x9c, 0x87, 0x12, 0x0b, 0xf6, 0x41, 0x2d, 0x90, - 0xc2, 0x1b, 0x96, 0x62, 0xd2, 0xd4, 0xaf, 0xa6, 0x22, 0x12, 0xcc, 0x23, 0xdf, 0x4f, 0x30, 0x8f, - 0x5f, 0x7e, 0x75, 0xad, 0x72, 0xe5, 0xed, 0xd3, 0x93, 0xd2, 0xf5, 0x50, 0x9d, 0xc0, 0x6a, 0x93, - 0xf4, 0x0a, 0x29, 0x4d, 0xc4, 0x15, 0x21, 0x43, 0xaf, 0xa0, 0x08, 0xb9, 0x07, 0x23, 0xf4, 0xc2, - 0xb2, 0x5e, 0xe3, 0x76, 0xb3, 0x74, 0x79, 0xd2, 0xb8, 0x3c, 0x0d, 0x5b, 0x8d, 0x6b, 0x26, 0xc0, - 0x8c, 0xbf, 0x99, 0x87, 0xab, 0xe9, 0x3c, 0xe7, 0x7d, 0x5b, 0x06, 0x08, 0x6d, 0x9f, 0xb2, 0x6c, - 0xad, 0xe8, 0xb7, 0xf3, 0x1c, 0x1f, 0x48, 0x5b, 0x47, 0x05, 0x8f, 0x48, 0x2d, 0xc2, 0x67, 0x35, - 0xf2, 0x5a, 0xa8, 0xb9, 0xb2, 0xf2, 0xb0, 0x99, 0xbc, 0x48, 0x0b, 0x9b, 0xc9, 0xcb, 0xd0, 0x01, - 0xcc, 0xd7, 0x3c, 0xfb, 0x99, 0x15, 0xe0, 0xc7, 0xf8, 0x65, 0xcd, 0x6d, 0xdb, 0xcd, 0x97, 0x2b, - 0xdc, 0x75, 0x8b, 0x39, 0x22, 0xdf, 0x3a, 0x3d, 0x29, 0xbd, 0xd5, 0x61, 0x20, 0xe4, 0xc3, 0x6c, - 0x74, 0x28, 0x50, 0x23, 0xee, 0xcd, 0x95, 0x46, 0xc8, 0xf8, 0x57, 0x39, 0xb8, 0x44, 0x05, 0x6a, - 0xfe, 0xf2, 0x22, 0x1a, 0x7f, 0x25, 0x93, 0x5b, 0x75, 0x80, 0x7c, 0x2d, 0x52, 0x93, 0x5b, 0xcd, - 0xa7, 0xd7, 0xd4, 0xc0, 0xd0, 0x3a, 0x8c, 0xf3, 0xdf, 0x8a, 0xfa, 0x7c, 0x4e, 0xd9, 0xb0, 0xe8, - 0x52, 0x67, 0x3a, 0x27, 0xba, 0xb0, 0x39, 0x31, 0xea, 0x78, 0x68, 0xaa, 0xb8, 0xc6, 0xcf, 0xf2, - 0xb0, 0xb8, 0x87, 0x3d, 0xfb, 0xc9, 0xcb, 0x94, 0xc1, 0x6c, 0xc3, 0xac, 0x28, 0x62, 0x01, 0x3f, - 0xb4, 0x4f, 0x8c, 0x05, 0xe6, 0x13, 0x5d, 0xe5, 0x11, 0x43, 0xc4, 0x17, 0x97, 0x88, 0x78, 0x06, - 0x63, 0xda, 0x77, 0x61, 0x34, 0x12, 0x72, 0x87, 0xce, 0xbf, 0xf8, 0x42, 0xc3, 0xa9, 0x5a, 0x1b, - 0x30, 0x25, 0x24, 0xfa, 0xf5, 0xf4, 0x27, 0x5c, 0xae, 0x7f, 0xe8, 0xa5, 0x48, 0xa5, 0x1f, 0x2c, - 0xf9, 0x58, 0x2d, 0xa5, 0x36, 0xe1, 0x83, 0x5d, 0x1b, 0x30, 0xd3, 0x5a, 0xaa, 0x8c, 0xc3, 0x58, - 0x99, 0x3e, 0x4b, 0x93, 0x8b, 0xfb, 0x7f, 0xcd, 0xc3, 0x15, 0xe1, 0x36, 0x95, 0xc2, 0xe6, 0x2f, - 0x61, 0x5e, 0x14, 0x95, 0x3b, 0x44, 0x60, 0xc0, 0x2d, 0x9d, 0xd3, 0x2c, 0x38, 0xa6, 0xe0, 0xb4, - 0xc5, 0x61, 0x42, 0x66, 0xa7, 0xa1, 0xbf, 0x19, 0x35, 0xea, 0x67, 0x49, 0x01, 0x90, 0xa8, 0x3a, - 0x53, 0xdd, 0x33, 0x35, 0xd6, 0x68, 0xfb, 0x67, 0x2b, 0xa6, 0x86, 0x1d, 0x7a, 0x5d, 0x35, 0xec, - 0xda, 0x40, 0x54, 0x11, 0x5b, 0x99, 0x82, 0x89, 0x2d, 0xfc, 0x3c, 0xe4, 0xfb, 0x5f, 0xc9, 0x45, - 0x9c, 0xe6, 0x89, 0x84, 0xc1, 0xbc, 0xe7, 0x73, 0x61, 0x0c, 0x1d, 0xea, 0x34, 0xaf, 0x4a, 0x18, - 0x0c, 0x74, 0x1d, 0x46, 0x98, 0xad, 0x46, 0xab, 0x8f, 0xbb, 0xb9, 0xf4, 0x7f, 0x62, 0x2e, 0xa5, - 0x2d, 0x76, 0x4d, 0xe7, 0xf8, 0xc6, 0x63, 0xb8, 0xc6, 0xad, 0xff, 0xf5, 0xc9, 0xa7, 0x0d, 0x9d, - 0xf1, 0xf8, 0x32, 0x2c, 0xb8, 0xb2, 0x8a, 0xa3, 0x5b, 0x8f, 0xe6, 0x1f, 0xf6, 0x39, 0x4c, 0x6b, - 0xe5, 0x92, 0x22, 0x95, 0x4a, 0xe5, 0x1a, 0x92, 0xa4, 0xa3, 0xd0, 0xc6, 0xd5, 0xa4, 0x26, 0xd4, - 0xce, 0x1a, 0x98, 0x46, 0xb9, 0xf4, 0xc2, 0x57, 0x76, 0xff, 0x0c, 0xbb, 0xde, 0x2d, 0xe5, 0xbb, - 0x66, 0x3b, 0x1e, 0x0b, 0x84, 0x27, 0x4e, 0x5e, 0x59, 0x6b, 0x4c, 0x6a, 0x8f, 0x0a, 0xc6, 0x14, - 0x4c, 0x88, 0xaa, 0x36, 0xf6, 0x7d, 0xe3, 0x37, 0x86, 0xc0, 0xe0, 0x8c, 0x4d, 0xd2, 0xb9, 0x0a, - 0x7e, 0x1c, 0xc4, 0x3a, 0xcb, 0x0f, 0xaa, 0x0b, 0xaa, 0x66, 0x39, 0xac, 0x65, 0x2b, 0x8f, 0xca, - 0x79, 0xcd, 0xb0, 0x54, 0x5b, 0x79, 0xb1, 0xd1, 0xff, 0x20, 0x65, 0x9b, 0x64, 0x1f, 0xdb, 0x8d, - 0xd3, 0x93, 0xd2, 0xb5, 0x94, 0x6d, 0x52, 0xa3, 0x9b, 0xbc, 0x65, 0x9a, 0xfa, 0xdb, 0xca, 0xe0, - 0xab, 0xbc, 0xad, 0x90, 0x2f, 0x52, 0x7d, 0x5d, 0xd9, 0xd5, 0x79, 0xc9, 0xbf, 0x47, 0x61, 0xd5, - 0xa2, 0x56, 0x71, 0xdf, 0x75, 0xa5, 0x44, 0xa3, 0xaa, 0x91, 0x41, 0x36, 0x14, 0x14, 0x95, 0x65, - 0xf5, 0x08, 0x37, 0x9f, 0xf2, 0xb7, 0x20, 0xf1, 0x4c, 0x9d, 0xa4, 0xb8, 0x66, 0x81, 0x76, 0xd9, - 0x77, 0xce, 0x2a, 0x1a, 0x4d, 0x82, 0xaa, 0xfa, 0xde, 0x47, 0xc9, 0xaa, 0x2a, 0xfb, 0xdf, 0x96, - 0xee, 0x1e, 0xe4, 0xcc, 0xb6, 0xdb, 0x98, 0xfb, 0x36, 0x89, 0x15, 0x90, 0xf2, 0xae, 0x96, 0xfb, - 0x86, 0xdf, 0xd5, 0xfe, 0x30, 0x2f, 0x9c, 0x5c, 0x62, 0xaf, 0xef, 0x67, 0x7f, 0x5e, 0x4b, 0x1c, - 0x41, 0x5f, 0x07, 0x5a, 0xb2, 0xa1, 0x44, 0x45, 0x7b, 0x82, 0xcf, 0xa7, 0x3c, 0xc1, 0x6b, 0xef, - 0x95, 0x41, 0x8f, 0x37, 0xf9, 0xc1, 0xd7, 0x7f, 0xf9, 0xfa, 0xa7, 0x23, 0x70, 0xbe, 0x66, 0x1d, - 0xda, 0x0e, 0xd9, 0x38, 0x4d, 0xec, 0xbb, 0x5d, 0xaf, 0x89, 0x51, 0x19, 0xa6, 0x74, 0x0b, 0xe6, - 0x1e, 0xf6, 0xd9, 0xe4, 0x6c, 0xd0, 0xcb, 0xd0, 0x12, 0x8c, 0x49, 0xcf, 0x62, 0xbe, 0xa1, 0x27, - 0x78, 0x1c, 0xaf, 0x0d, 0x98, 0x21, 0x18, 0xfa, 0x50, 0x7b, 0xe8, 0x98, 0x96, 0x4e, 0xf2, 0x14, - 0x76, 0x89, 0x99, 0x98, 0x3a, 0x6e, 0x4b, 0x3f, 0x94, 0xd8, 0x63, 0xc1, 0x8f, 0x62, 0x6f, 0x1f, - 0xc3, 0x5a, 0x8f, 0x63, 0x5a, 0x23, 0x7a, 0x1e, 0xa7, 0x46, 0x1b, 0x8e, 0xbf, 0x8a, 0xa0, 0xef, - 0xc3, 0xf8, 0xe3, 0xee, 0x01, 0x16, 0xaf, 0x3c, 0xe7, 0xf8, 0x19, 0x15, 0xb5, 0xcb, 0xe7, 0xf5, - 0x7b, 0x0f, 0xd8, 0x1c, 0x3c, 0xed, 0x1e, 0xe0, 0x78, 0x18, 0x6b, 0xb2, 0x39, 0x28, 0xc4, 0xd0, - 0x11, 0x14, 0xa2, 0x26, 0xf4, 0x3c, 0x80, 0x5c, 0x86, 0xe1, 0x3f, 0x0d, 0x9f, 0xa1, 0x04, 0xcb, - 0x66, 0x86, 0xbd, 0x5a, 0x23, 0x31, 0xaa, 0xe8, 0x57, 0x60, 0x2e, 0x51, 0x67, 0xc7, 0x43, 0x66, - 0xf7, 0x52, 0x07, 0xd2, 0x8d, 0x35, 0xc2, 0x35, 0xe1, 0x95, 0xa7, 0xb5, 0x9c, 0xdc, 0x0a, 0x6a, - 0xc1, 0x74, 0xc4, 0x34, 0x9c, 0x47, 0xec, 0x4f, 0x37, 0x36, 0xa7, 0x87, 0x83, 0x08, 0xab, 0x9a, - 0xd8, 0x56, 0x94, 0x24, 0xda, 0x80, 0x31, 0x79, 0xe5, 0xa6, 0x41, 0x7e, 0x92, 0xd5, 0x0b, 0x0b, - 0xa7, 0x27, 0xa5, 0xd9, 0x50, 0xbd, 0xa0, 0xd1, 0x0c, 0x09, 0xa0, 0x9f, 0xc0, 0x35, 0xb9, 0x44, - 0xb7, 0xbd, 0x64, 0x45, 0x0c, 0x0f, 0xc6, 0x7d, 0x3b, 0xba, 0xc2, 0xd3, 0xe0, 0xf7, 0xee, 0xaf, - 0x0d, 0x98, 0xbd, 0xc9, 0x56, 0x00, 0x46, 0x3d, 0xfe, 0x51, 0x3e, 0x1a, 0x1a, 0x1d, 0x2a, 0x0c, - 0xb3, 0x75, 0x23, 0x4c, 0xee, 0xff, 0xfb, 0x39, 0xe6, 0xc3, 0xba, 0xeb, 0xd8, 0x4f, 0xec, 0xf0, - 0xfb, 0x55, 0x15, 0x3c, 0x61, 0x76, 0x0e, 0x2e, 0x7e, 0xa5, 0xe4, 0xe1, 0x90, 0xba, 0xa0, 0x7c, - 0x4f, 0x5d, 0xd0, 0x03, 0xe5, 0xbd, 0x43, 0x09, 0x0a, 0xc9, 0x8e, 0x59, 0x5d, 0xf7, 0x12, 0x3e, - 0x84, 0x7c, 0x0d, 0xe7, 0x68, 0x78, 0x3a, 0xf6, 0x98, 0x34, 0xbe, 0x74, 0x87, 0xef, 0x5a, 0x19, - 0xdd, 0x67, 0xf1, 0xec, 0xb8, 0x5f, 0x3a, 0x8d, 0x21, 0xd9, 0xa6, 0x05, 0x6a, 0x30, 0x3a, 0x06, - 0x82, 0x76, 0x60, 0xa6, 0xe6, 0xe1, 0x16, 0x37, 0xfc, 0xee, 0x78, 0xfc, 0x7e, 0xcc, 0x6e, 0xde, - 0x34, 0x76, 0x77, 0x47, 0x54, 0x37, 0xb0, 0xac, 0x57, 0xcf, 0x93, 0x04, 0x74, 0xb4, 0x02, 0x53, - 0x75, 0x6c, 0x79, 0xcd, 0xa3, 0xc7, 0xf8, 0x25, 0x39, 0x71, 0xb5, 0x80, 0xf7, 0x3e, 0xad, 0x21, - 0xe3, 0xa5, 0x55, 0xaa, 0xbd, 0x82, 0x8e, 0x84, 0xbe, 0x07, 0xe7, 0xea, 0xae, 0x17, 0x54, 0x5e, - 0xf2, 0x6f, 0x5a, 0x3c, 0x37, 0xb0, 0xc2, 0xca, 0x45, 0x11, 0xf4, 0xdf, 0x77, 0xbd, 0xa0, 0x71, - 0xa0, 0xb2, 0x8f, 0xe3, 0xa1, 0x97, 0x30, 0xab, 0x7f, 0x4f, 0x0f, 0xed, 0x36, 0xd9, 0x84, 0x46, - 0xf9, 0x49, 0x9f, 0xf4, 0xd1, 0x32, 0x90, 0xca, 0x2d, 0x4e, 0xfd, 0x6a, 0xf4, 0xab, 0x7d, 0x42, - 0xeb, 0xd5, 0x94, 0x21, 0x49, 0xf8, 0x68, 0x93, 0xe6, 0x4a, 0x60, 0x23, 0x2a, 0xfb, 0xcc, 0xe4, - 0x7a, 0x2c, 0x0c, 0x61, 0xd4, 0xa5, 0xdf, 0x24, 0xe5, 0x84, 0xe5, 0x47, 0x53, 0x60, 0x98, 0x31, - 0x54, 0x54, 0x83, 0xf3, 0xbb, 0x3e, 0xae, 0x79, 0xf8, 0x99, 0x8d, 0x9f, 0x0b, 0x7a, 0x2c, 0x0e, - 0x17, 0x9d, 0x26, 0x42, 0xaf, 0xc3, 0x6a, 0x93, 0x08, 0xc6, 0x91, 0xd1, 0x87, 0x00, 0x35, 0xdb, - 0x71, 0x70, 0x8b, 0xbe, 0x59, 0x8d, 0x53, 0x52, 0x54, 0xab, 0xd7, 0xa1, 0xa5, 0x0d, 0xd7, 0x69, - 0xab, 0x2c, 0x55, 0x80, 0x8b, 0x1f, 0xc2, 0xb8, 0xb2, 0xc4, 0x12, 0xe2, 0x1a, 0xcc, 0xaa, 0x71, - 0x0d, 0xc6, 0xd4, 0xf8, 0x05, 0x7f, 0x27, 0x07, 0x8b, 0xc9, 0x4b, 0x97, 0x1f, 0xf7, 0xdb, 0x30, - 0x26, 0x0b, 0xa5, 0x97, 0x8e, 0x10, 0xf6, 0x22, 0xe7, 0x2d, 0xfb, 0x7e, 0xc4, 0x87, 0xae, 0x8e, - 0x37, 0xa4, 0xf1, 0x0a, 0x1a, 0xd8, 0x7f, 0x3e, 0x02, 0xb3, 0xa4, 0x8f, 0xb1, 0x6d, 0xe1, 0x73, - 0x1a, 0x9f, 0x84, 0x96, 0x29, 0x0a, 0x45, 0xae, 0x5b, 0x60, 0xe5, 0xd1, 0x98, 0x49, 0x1a, 0x02, - 0x7a, 0x4f, 0x7d, 0xbf, 0xce, 0x2b, 0xc9, 0x10, 0x44, 0xa1, 0x3a, 0x84, 0xf0, 0x61, 0xfb, 0x1d, - 0xed, 0xf9, 0xb4, 0xef, 0x3d, 0x66, 0xa8, 0xdf, 0x3d, 0x66, 0x57, 0xee, 0x31, 0x2c, 0xee, 0xc5, - 0xdb, 0xca, 0x1e, 0xf3, 0xe6, 0x37, 0x97, 0x73, 0x6f, 0x7a, 0x73, 0x19, 0x79, 0xbd, 0xcd, 0x65, - 0xf4, 0x15, 0x37, 0x97, 0x87, 0x30, 0xb5, 0x85, 0x71, 0x4b, 0x51, 0x8d, 0xb3, 0xef, 0x9b, 0xeb, - 0x03, 0xa8, 0xd2, 0x23, 0x49, 0x3f, 0x1e, 0xc1, 0x4a, 0xdd, 0xa4, 0xe0, 0xff, 0xcc, 0x26, 0x35, - 0xfe, 0x86, 0x37, 0xa9, 0x89, 0xd7, 0xd8, 0xa4, 0x5e, 0x67, 0xa7, 0xf9, 0x8c, 0x5a, 0x92, 0xd5, - 0xeb, 0x6b, 0xfc, 0x95, 0x5e, 0x79, 0x16, 0x5f, 0x73, 0x7d, 0x61, 0x22, 0x4f, 0xff, 0x26, 0x65, - 0x35, 0xd7, 0x13, 0x4f, 0x8b, 0xf4, 0x6f, 0xa3, 0x42, 0xed, 0xc7, 0x54, 0x7c, 0xe9, 0x5f, 0x31, - 0xc2, 0xdd, 0x13, 0xf9, 0xfe, 0x14, 0x15, 0xb8, 0x4d, 0x51, 0x6f, 0xfc, 0xdb, 0x1c, 0x7b, 0x42, - 0xfa, 0xbf, 0x71, 0x9b, 0x7b, 0x9d, 0x67, 0x9d, 0x5f, 0x0f, 0xc3, 0x16, 0xf0, 0x10, 0x0b, 0x9e, - 0xd5, 0x7c, 0x1a, 0xbe, 0xab, 0xfd, 0x90, 0x7c, 0xa3, 0x6a, 0x05, 0x8d, 0xe8, 0x18, 0xde, 0x2a, - 0xf4, 0xca, 0xbd, 0xfb, 0xe2, 0xe3, 0xe5, 0xd1, 0x1b, 0x58, 0xb1, 0xfe, 0xf1, 0xaa, 0x08, 0xd4, - 0x09, 0x66, 0xda, 0x30, 0x99, 0xd7, 0x7d, 0x62, 0x0f, 0xde, 0x8f, 0xfb, 0x8d, 0x53, 0xb1, 0x35, - 0xf4, 0x1b, 0x57, 0xd9, 0x18, 0x7a, 0x90, 0xef, 0xc2, 0x25, 0x13, 0x1f, 0xbb, 0xcf, 0xf0, 0x9b, - 0x25, 0xfb, 0x03, 0xb8, 0xa8, 0x13, 0x64, 0x6e, 0x52, 0x2c, 0x5a, 0xf8, 0x67, 0xc9, 0x31, 0xc6, - 0x39, 0x02, 0x8b, 0x31, 0xce, 0xc2, 0xc0, 0x92, 0x3f, 0xd5, 0x3d, 0x9f, 0xd6, 0x19, 0x2e, 0x2c, - 0xea, 0xc4, 0xcb, 0xad, 0x16, 0x4d, 0xeb, 0xd6, 0xb4, 0x3b, 0x96, 0x13, 0xa0, 0x6d, 0x18, 0x57, - 0x7e, 0x46, 0x2e, 0x95, 0x4a, 0x0d, 0x3f, 0xfe, 0xc3, 0x02, 0x2d, 0xf6, 0x5f, 0x58, 0x6c, 0x60, - 0x28, 0x45, 0xd9, 0x43, 0x58, 0xa6, 0xb6, 0x59, 0x81, 0x49, 0xe5, 0xa7, 0x54, 0x30, 0xd1, 0x50, - 0x95, 0x4a, 0x0b, 0x3a, 0xc3, 0x74, 0x14, 0xa3, 0x09, 0xc5, 0x24, 0xa6, 0xd1, 0x68, 0x4d, 0x2f, - 0xd1, 0x4a, 0x18, 0xf7, 0xa9, 0xb7, 0x55, 0xd3, 0x74, 0x5a, 0xcc, 0x27, 0xe3, 0xaf, 0x0f, 0xc1, - 0x25, 0x3e, 0x19, 0x6f, 0x72, 0xc6, 0xd1, 0x8f, 0x60, 0x5c, 0x99, 0x63, 0xce, 0xf4, 0xab, 0xc2, - 0x7c, 0x32, 0x6d, 0x2d, 0xb0, 0xcb, 0x6f, 0x97, 0x16, 0x34, 0x22, 0xd3, 0x4d, 0x2e, 0xbf, 0xea, - 0xb2, 0x69, 0xc3, 0x94, 0x3e, 0xd1, 0xfc, 0xfe, 0x7f, 0x3d, 0xb1, 0x11, 0x1d, 0x54, 0x44, 0x90, - 0x6d, 0x35, 0x12, 0xa7, 0x9b, 0x5c, 0xe3, 0x23, 0x8b, 0xe8, 0x05, 0x9c, 0x8f, 0xcd, 0x32, 0x57, - 0xeb, 0xdc, 0x4c, 0x6c, 0x30, 0x06, 0xcd, 0x94, 0x67, 0x1e, 0x2d, 0x4e, 0x6d, 0x36, 0xde, 0x08, - 0x6a, 0xc1, 0x84, 0x3a, 0xf1, 0x5c, 0x41, 0x71, 0x2d, 0x83, 0x95, 0x0c, 0x90, 0x09, 0x66, 0x9c, - 0x97, 0x74, 0xee, 0x5f, 0xea, 0x0a, 0x41, 0x0d, 0x78, 0x14, 0xce, 0xb1, 0xdf, 0x64, 0x0b, 0xa8, - 0x79, 0xd8, 0xc7, 0x4e, 0x13, 0xab, 0x96, 0xb0, 0xaf, 0xbb, 0x05, 0xfc, 0xcb, 0x1c, 0x2c, 0x24, - 0xd1, 0xad, 0x63, 0xa7, 0x85, 0x6a, 0x50, 0x88, 0x36, 0xc4, 0x57, 0xb5, 0x21, 0x83, 0x74, 0xa6, - 0x76, 0x69, 0x6d, 0xc0, 0x8c, 0x61, 0xa3, 0x2d, 0x38, 0xaf, 0x94, 0x9d, 0xd1, 0xe4, 0x38, 0x8e, - 0xaa, 0x6a, 0x31, 0xd7, 0xe8, 0xc9, 0xb8, 0xec, 0x1e, 0x5b, 0xb6, 0x43, 0x84, 0x54, 0x25, 0xf4, - 0x13, 0x84, 0xa5, 0x9c, 0x37, 0x4c, 0x2f, 0x47, 0x4b, 0x85, 0x1f, 0x81, 0x04, 0x31, 0x3e, 0xa1, - 0x3b, 0x38, 0xd7, 0xe6, 0x30, 0x57, 0x5c, 0x49, 0xec, 0x2a, 0x0c, 0xef, 0x6c, 0xd4, 0xab, 0x65, - 0xee, 0xd8, 0xcb, 0xc2, 0x41, 0xb4, 0xfd, 0x46, 0xd3, 0x32, 0x59, 0x85, 0xf1, 0x31, 0x8d, 0xf3, - 0xcd, 0xa3, 0x44, 0x4b, 0xbc, 0x1b, 0x30, 0xc2, 0x8b, 0x38, 0x26, 0x35, 0x41, 0x6a, 0x73, 0x28, - 0x51, 0x67, 0xd4, 0x84, 0x8c, 0xdf, 0xc6, 0x96, 0xaf, 0x1c, 0xcc, 0x1f, 0xc0, 0xa8, 0xc7, 0xcb, - 0xf8, 0xb9, 0x3c, 0x25, 0x73, 0x3e, 0xd0, 0x62, 0xa6, 0xf9, 0x14, 0x30, 0xa6, 0xfc, 0xcb, 0xd8, - 0xa0, 0xa1, 0x5b, 0xb6, 0xd7, 0x97, 0xab, 0x84, 0xab, 0x9c, 0x59, 0x62, 0x3a, 0xee, 0x52, 0xab, - 0xde, 0x00, 0xab, 0x6e, 0xbd, 0x94, 0x35, 0xf4, 0x23, 0xe7, 0x01, 0x8b, 0x14, 0x10, 0xe3, 0x81, - 0x0c, 0x04, 0x93, 0x40, 0x2d, 0x2d, 0x77, 0xc1, 0x16, 0x0d, 0x71, 0xb3, 0x4a, 0x8d, 0x1b, 0xde, - 0x44, 0x27, 0x2c, 0x28, 0xb2, 0x63, 0x9e, 0x8c, 0x8a, 0x67, 0xd2, 0x72, 0xe5, 0xd6, 0x58, 0x85, - 0x31, 0x59, 0x26, 0x5f, 0x2a, 0x18, 0xaf, 0x34, 0xf8, 0xbd, 0x07, 0xcc, 0x03, 0xba, 0x29, 0x09, - 0x84, 0x78, 0xa4, 0x09, 0xf6, 0xdd, 0x7d, 0xc3, 0x4d, 0xf8, 0xd8, 0x0b, 0xbe, 0xd1, 0x26, 0xc2, - 0x18, 0x48, 0x67, 0x69, 0x42, 0x83, 0xdf, 0x5b, 0xea, 0x87, 0x51, 0xdf, 0x70, 0x13, 0x84, 0x51, - 0xdf, 0x5c, 0x13, 0x58, 0x04, 0x8b, 0x62, 0x8b, 0x34, 0xd6, 0xc8, 0x4a, 0xbc, 0x11, 0xa1, 0xe2, - 0x8c, 0x60, 0x64, 0xce, 0x07, 0x86, 0x45, 0xc6, 0xac, 0x5f, 0x40, 0x33, 0x84, 0x61, 0xdf, 0x6c, - 0x33, 0xbf, 0x97, 0x63, 0xa1, 0xab, 0xea, 0xdb, 0x4a, 0x0e, 0x3b, 0xe7, 0x89, 0xab, 0x3c, 0xa4, - 0x2a, 0x5f, 0xfb, 0x63, 0xdb, 0x69, 0xa9, 0x0f, 0xa9, 0x56, 0x37, 0x38, 0x92, 0xc1, 0x8b, 0x9f, - 0xda, 0x4e, 0xcb, 0x8c, 0x42, 0xa3, 0x0f, 0x61, 0x52, 0x29, 0x92, 0xd2, 0x1a, 0x0b, 0x56, 0xaf, - 0xa2, 0xdb, 0x2d, 0x53, 0x87, 0x34, 0x7e, 0x3b, 0x0f, 0x17, 0x76, 0x3b, 0x3e, 0xf5, 0x76, 0x58, - 0x77, 0x9e, 0x61, 0x27, 0x70, 0xbd, 0x97, 0xd4, 0xee, 0x1a, 0xbd, 0x07, 0xc3, 0x6b, 0xb8, 0xdd, - 0x76, 0xf9, 0xc8, 0x2f, 0x8b, 0x57, 0xcc, 0x28, 0x34, 0x05, 0x5a, 0x1b, 0x30, 0x19, 0x34, 0xfa, - 0x10, 0xc6, 0xd6, 0xb0, 0xe5, 0x05, 0x07, 0xd8, 0x12, 0xc2, 0xaa, 0x08, 0x9e, 0xae, 0xa0, 0x70, - 0x80, 0xb5, 0x01, 0x33, 0x84, 0x46, 0x4b, 0xe4, 0x1e, 0xe7, 0x1c, 0x4a, 0xc7, 0xef, 0x94, 0x06, - 0x09, 0xcc, 0xda, 0x80, 0x49, 0x61, 0xd1, 0x26, 0x4c, 0x96, 0x0f, 0xb1, 0x13, 0x6c, 0xe2, 0xc0, - 0x6a, 0x59, 0x81, 0xc5, 0x85, 0x9a, 0x1b, 0x69, 0xc8, 0x1a, 0xf0, 0xda, 0x80, 0xa9, 0x63, 0x57, - 0x86, 0x61, 0x70, 0xd3, 0x3f, 0x34, 0x4e, 0x72, 0xb0, 0xb0, 0xec, 0x3e, 0x77, 0x12, 0x19, 0xf3, - 0x5d, 0x9d, 0x31, 0xc2, 0x27, 0x27, 0x01, 0x3e, 0xc2, 0x9a, 0x77, 0x61, 0xa8, 0x66, 0x3b, 0x87, - 0x91, 0x73, 0x3c, 0x01, 0x8f, 0x40, 0xd1, 0x11, 0xda, 0xce, 0x21, 0xda, 0x10, 0x02, 0x14, 0x57, - 0xf2, 0x0c, 0x6a, 0x52, 0x5b, 0x02, 0xb6, 0x0a, 0x1d, 0x0a, 0x4a, 0xec, 0xb7, 0x18, 0xe0, 0x3b, - 0x30, 0x9f, 0xd2, 0x2e, 0x77, 0xc6, 0x26, 0x63, 0x1b, 0xa2, 0xa7, 0xd2, 0xdb, 0x30, 0x97, 0x38, - 0x05, 0x31, 0xc0, 0x7f, 0x90, 0xb4, 0x96, 0xd8, 0xc8, 0x17, 0x60, 0x44, 0xe4, 0xd8, 0x60, 0x17, - 0x77, 0xf1, 0x93, 0x7a, 0x11, 0xd0, 0xeb, 0x76, 0x18, 0x06, 0x58, 0xfc, 0x46, 0x7b, 0x4a, 0xc4, - 0x9f, 0x41, 0xaa, 0x25, 0xfa, 0xe8, 0x35, 0xd2, 0x0b, 0x4b, 0x5a, 0xa4, 0xcd, 0x35, 0xd7, 0x0f, - 0x1c, 0x69, 0xe4, 0x66, 0xca, 0xdf, 0xe8, 0x36, 0x14, 0x56, 0x5e, 0x04, 0xd8, 0x73, 0xac, 0x36, - 0xcf, 0x36, 0xc0, 0xf3, 0xc6, 0x9a, 0xb1, 0x72, 0xf4, 0x01, 0xcc, 0x47, 0xcb, 0xc4, 0x28, 0x99, - 0x1b, 0x48, 0x5a, 0xb5, 0xf1, 0xa7, 0x79, 0x1a, 0xb8, 0x38, 0x63, 0x69, 0x12, 0xee, 0x6e, 0xd7, - 0x39, 0xb7, 0xf2, 0xdb, 0x75, 0xb4, 0x08, 0x63, 0xdb, 0x75, 0x2d, 0x51, 0x89, 0x19, 0x16, 0x90, - 0x6e, 0x93, 0x21, 0x94, 0xbd, 0xe6, 0x91, 0x1d, 0xe0, 0x66, 0xd0, 0xf5, 0x78, 0xbc, 0x26, 0x33, - 0x56, 0x8e, 0x0c, 0x98, 0x58, 0x6d, 0xdb, 0x07, 0x4d, 0x41, 0x8c, 0xb1, 0x40, 0x2b, 0x43, 0x37, - 0x61, 0x6a, 0xdd, 0xf1, 0x03, 0xab, 0xdd, 0x66, 0x79, 0x5c, 0x78, 0xe2, 0x6c, 0x33, 0x52, 0x4a, - 0xda, 0xad, 0xba, 0x4e, 0x60, 0xd9, 0x0e, 0xf6, 0xcc, 0xae, 0x13, 0xd8, 0xc7, 0x98, 0x8f, 0x3d, - 0x56, 0x8e, 0xde, 0x85, 0x39, 0x59, 0xb6, 0xed, 0x35, 0x8f, 0xb0, 0x1f, 0x78, 0x34, 0xc5, 0x16, - 0x8d, 0x4c, 0x63, 0x26, 0x57, 0xd2, 0x16, 0xda, 0x6e, 0xb7, 0xb5, 0xe2, 0x3c, 0xb3, 0x3d, 0xd7, - 0xa1, 0xe9, 0x30, 0x47, 0x79, 0x0b, 0x91, 0x72, 0xa3, 0x96, 0xf8, 0xd5, 0xbe, 0xc6, 0x12, 0x34, - 0x4e, 0x73, 0xb0, 0x98, 0xf8, 0x61, 0x89, 0xcd, 0x5b, 0x45, 0xce, 0x45, 0xd6, 0xef, 0x6d, 0x18, - 0xa2, 0xbb, 0x39, 0x53, 0x0c, 0x08, 0x33, 0x10, 0x8a, 0xcf, 0x48, 0x91, 0x5a, 0x93, 0xc2, 0xa0, - 0x55, 0xa9, 0xc4, 0x1d, 0xa4, 0x62, 0xeb, 0xdd, 0xe8, 0x9e, 0x99, 0xd0, 0xb8, 0xaa, 0xcc, 0x15, - 0x6a, 0xdb, 0xd7, 0xd1, 0xb9, 0xfd, 0x69, 0x0e, 0x4a, 0x3d, 0xf6, 0x13, 0x39, 0xa6, 0x5c, 0x1f, - 0x63, 0x7a, 0x24, 0xc7, 0xc4, 0x1c, 0x4e, 0x96, 0xfa, 0xdb, 0xb3, 0xde, 0xf4, 0xb0, 0xaa, 0x80, - 0xe2, 0x27, 0x0f, 0xfa, 0x0e, 0x8c, 0xd5, 0xeb, 0x6b, 0xda, 0x3b, 0x7f, 0x4c, 0x13, 0x18, 0x42, - 0x18, 0xef, 0xc3, 0x05, 0x49, 0x84, 0x45, 0x4e, 0x57, 0xbc, 0xda, 0xf8, 0x59, 0x2f, 0x5d, 0xf0, - 0xc2, 0x02, 0xe3, 0x4f, 0x86, 0x62, 0x88, 0xf5, 0xee, 0xf1, 0xb1, 0xe5, 0xbd, 0x44, 0x65, 0x1d, - 0x71, 0xb0, 0xe7, 0x21, 0x5b, 0x19, 0xfa, 0xe9, 0x49, 0x69, 0x40, 0xa1, 0x8e, 0xde, 0x82, 0x49, - 0xfa, 0x41, 0x3a, 0x4d, 0xcc, 0xf4, 0x80, 0x79, 0x16, 0x02, 0x44, 0x2b, 0x44, 0x7b, 0x30, 0xc9, - 0xd7, 0x3a, 0xfd, 0x2d, 0x96, 0xd8, 0xbd, 0xe8, 0x12, 0xd3, 0xba, 0x77, 0x47, 0x43, 0x61, 0x93, - 0xa1, 0x93, 0x41, 0x5f, 0xc1, 0x94, 0xd8, 0xd8, 0x38, 0x61, 0xf6, 0xc8, 0x79, 0x3f, 0x9b, 0xb0, - 0x8e, 0xc3, 0x28, 0x47, 0x08, 0x91, 0x2e, 0xf3, 0xed, 0x9a, 0x53, 0x1e, 0xee, 0xa7, 0xcb, 0x1a, - 0x0a, 0xef, 0xb2, 0x56, 0x56, 0xfc, 0x1e, 0xa0, 0xf8, 0xb8, 0x7a, 0xad, 0xa6, 0x49, 0x65, 0x35, - 0x15, 0xcb, 0x30, 0x93, 0x30, 0x80, 0x33, 0x91, 0xf8, 0x1e, 0xa0, 0x78, 0x4f, 0xcf, 0x42, 0xc1, - 0xb8, 0x05, 0x37, 0x25, 0x0b, 0xe4, 0x6a, 0xd0, 0x68, 0x8a, 0xdb, 0xfe, 0xaf, 0xe5, 0xa1, 0xd4, - 0x03, 0x14, 0xfd, 0xad, 0x5c, 0x94, 0xdb, 0x6c, 0x35, 0x7e, 0x18, 0xe5, 0x76, 0x32, 0x7e, 0x02, - 0xdb, 0x2b, 0x1f, 0xfd, 0xa5, 0x3f, 0x7b, 0xe5, 0x83, 0x3a, 0x3e, 0x65, 0x67, 0xe7, 0xd6, 0x90, - 0xca, 0x2d, 0x13, 0x66, 0x35, 0x11, 0xa7, 0x9f, 0xbd, 0xfb, 0x0a, 0x00, 0x4f, 0xe8, 0xb4, 0xe1, - 0x1e, 0x72, 0x9f, 0x40, 0xa5, 0xc4, 0x78, 0x08, 0x73, 0x11, 0x9a, 0x5c, 0x03, 0xf1, 0x1d, 0x90, - 0xde, 0x4b, 0x94, 0xe8, 0x60, 0xe5, 0xfc, 0xcf, 0x4f, 0x4a, 0x93, 0xe4, 0x04, 0xbc, 0x13, 0x06, - 0x28, 0x16, 0x7f, 0x19, 0x9b, 0xaa, 0x0e, 0xa5, 0xdc, 0xd6, 0x7c, 0xc0, 0xef, 0xc3, 0x39, 0x56, - 0x12, 0x09, 0x03, 0xaa, 0x42, 0xf3, 0x3d, 0x81, 0x03, 0x1a, 0x73, 0xd4, 0x63, 0x83, 0xfe, 0x28, - 0x87, 0xbe, 0x81, 0xc6, 0x2e, 0x0b, 0x1d, 0x1f, 0x16, 0xcb, 0x50, 0xa3, 0x43, 0xe5, 0xd0, 0x87, - 0x51, 0x3c, 0x56, 0x09, 0x38, 0xc7, 0x7d, 0xde, 0xc6, 0xad, 0x43, 0x9a, 0x37, 0xba, 0x32, 0xc1, - 0x1f, 0xab, 0x86, 0x2c, 0x42, 0x80, 0xa2, 0x19, 0x9f, 0xc3, 0x5c, 0xb5, 0x8d, 0x2d, 0x2f, 0xda, - 0x1e, 0xba, 0x09, 0x23, 0xb4, 0x4c, 0xb7, 0x37, 0xb3, 0x48, 0x11, 0xb5, 0x37, 0xe3, 0x95, 0xc6, - 0x06, 0x5c, 0x64, 0x37, 0x30, 0x75, 0x48, 0xa1, 0xbe, 0x63, 0x98, 0xfe, 0x8e, 0xd8, 0xfb, 0x27, - 0x8c, 0x9e, 0xc1, 0x19, 0x9f, 0x51, 0x83, 0xd2, 0xa4, 0x94, 0xe1, 0xfd, 0x79, 0xa0, 0xfc, 0x7f, - 0xb0, 0x58, 0xee, 0x74, 0xb0, 0xd3, 0x0a, 0x11, 0x77, 0x3c, 0xab, 0x4f, 0xcf, 0x3e, 0x54, 0x86, - 0x61, 0x0a, 0x2d, 0x95, 0xc5, 0xbc, 0xbb, 0x09, 0xdd, 0xa1, 0x70, 0x3c, 0x2e, 0x1c, 0x6d, 0x80, - 0x61, 0x1a, 0x2d, 0x98, 0xaf, 0x77, 0x0f, 0x8e, 0x6d, 0x96, 0x47, 0x9b, 0x7a, 0xc7, 0x8a, 0xb6, - 0xd7, 0x45, 0xb6, 0x0f, 0xc6, 0x8c, 0x5b, 0x61, 0x2a, 0x70, 0x6a, 0xe8, 0xc6, 0x3d, 0x66, 0x9f, - 0xdd, 0xbf, 0x13, 0xa2, 0xd2, 0xdb, 0x0a, 0x6b, 0x85, 0x56, 0xf3, 0x8c, 0x20, 0xc6, 0x0c, 0x9c, - 0x57, 0x15, 0x6f, 0x6c, 0x85, 0xcc, 0xc1, 0x8c, 0xae, 0x50, 0x63, 0xc5, 0x5f, 0xc3, 0x2c, 0xbb, - 0xf0, 0xb3, 0xb8, 0xae, 0x4b, 0x61, 0x08, 0xd3, 0xfc, 0xde, 0x52, 0xc4, 0x3c, 0x8e, 0x9a, 0xef, - 0xc8, 0x88, 0xdd, 0x7b, 0x4b, 0xcc, 0x29, 0xe0, 0xd9, 0x92, 0xa6, 0xb6, 0xcd, 0xef, 0x2d, 0x55, - 0x46, 0x78, 0x7c, 0x3c, 0x42, 0x9d, 0x4d, 0xff, 0x37, 0x42, 0x7d, 0x89, 0xfa, 0xa1, 0xad, 0x61, - 0x8b, 0xda, 0x8c, 0x26, 0x7b, 0xf3, 0x4c, 0x41, 0xde, 0x6e, 0x09, 0x29, 0xdb, 0x6e, 0x19, 0x7f, - 0x94, 0x83, 0x5b, 0x4c, 0x16, 0x49, 0xc6, 0xa3, 0xda, 0xb5, 0x14, 0x64, 0xf4, 0x01, 0xb0, 0x3c, - 0xb2, 0x5c, 0xe0, 0x33, 0x78, 0xcf, 0xb3, 0x28, 0x31, 0x04, 0x54, 0x86, 0x09, 0xd5, 0xe2, 0xb3, - 0xbf, 0x50, 0x2c, 0xe6, 0xf8, 0xf1, 0x13, 0x4b, 0x5a, 0x81, 0x3e, 0x85, 0x4b, 0x2b, 0x2f, 0xc8, - 0x82, 0xe0, 0xa7, 0x13, 0x7f, 0x31, 0x0e, 0xbd, 0x45, 0xa6, 0x77, 0xf8, 0x8a, 0xd1, 0xc5, 0xe0, - 0x68, 0x31, 0xb9, 0x1e, 0x88, 0x03, 0x4e, 0x4a, 0xaf, 0x63, 0xa6, 0x56, 0x66, 0xfc, 0x49, 0x0e, - 0x16, 0x93, 0x5b, 0xe3, 0x1b, 0xcb, 0x3a, 0x9c, 0xaf, 0x5a, 0x8e, 0xeb, 0xd8, 0x4d, 0xab, 0x5d, - 0x6f, 0x1e, 0xe1, 0x56, 0x57, 0x86, 0x02, 0x94, 0xbb, 0x0c, 0xb9, 0xee, 0x70, 0x74, 0x01, 0x62, - 0xc6, 0xb1, 0xd0, 0xfb, 0x70, 0x81, 0x1a, 0x0d, 0xb2, 0xbd, 0xb7, 0x8d, 0x3d, 0x49, 0x8f, 0xf5, - 0x2c, 0xa5, 0x16, 0xdd, 0x83, 0x19, 0x76, 0xa8, 0xb4, 0x76, 0x1d, 0x3b, 0x90, 0x48, 0xec, 0x56, - 0x94, 0x54, 0x65, 0xd4, 0xe0, 0x2d, 0x2d, 0xcf, 0x54, 0xb9, 0xdd, 0x76, 0x9f, 0xe3, 0x56, 0xcd, - 0x73, 0x8f, 0xdd, 0x40, 0x0b, 0x76, 0xcf, 0x73, 0x00, 0x86, 0x1a, 0x17, 0xce, 0xcb, 0x48, 0xb1, - 0xf1, 0xff, 0xc2, 0x8d, 0x1e, 0x14, 0x39, 0xbf, 0xea, 0x70, 0xde, 0x8a, 0xd4, 0x89, 0x87, 0xb1, - 0x1b, 0x82, 0x5f, 0x59, 0x84, 0x7c, 0x33, 0x8e, 0x7f, 0x7b, 0x47, 0x4b, 0x1b, 0x86, 0x16, 0x60, - 0xb6, 0x66, 0x6e, 0x2f, 0xef, 0x56, 0x77, 0x1a, 0x3b, 0x5f, 0xd5, 0x56, 0x1a, 0xbb, 0x5b, 0x8f, - 0xb7, 0xb6, 0xf7, 0xb7, 0x58, 0xcc, 0x4e, 0xad, 0x66, 0x67, 0xa5, 0xbc, 0x59, 0xc8, 0xa1, 0x59, - 0x28, 0x68, 0xc5, 0x2b, 0xbb, 0x95, 0x42, 0xfe, 0x76, 0x43, 0xb5, 0xe8, 0x45, 0x97, 0x60, 0x7e, - 0x79, 0x65, 0x6f, 0xbd, 0xba, 0x22, 0x68, 0xaa, 0xf1, 0x42, 0x67, 0xa1, 0xa0, 0x56, 0xee, 0x6c, - 0xef, 0xd4, 0x58, 0x52, 0x7e, 0xb5, 0x74, 0x7f, 0xa5, 0x52, 0xde, 0xdd, 0x59, 0xdb, 0x2a, 0x0c, - 0x1a, 0x43, 0xa3, 0xf9, 0x42, 0xfe, 0xf6, 0x8f, 0x34, 0x73, 0x5f, 0xb4, 0x08, 0x0b, 0x1c, 0x7c, - 0xb7, 0x5e, 0x5e, 0x4d, 0x6f, 0x82, 0xd5, 0x6e, 0x3e, 0x2c, 0x17, 0x72, 0xe8, 0x32, 0x5c, 0xd4, - 0x4a, 0x6b, 0xe5, 0x7a, 0x7d, 0x7f, 0xdb, 0x64, 0x99, 0xfd, 0xf3, 0xb7, 0xf7, 0xb4, 0xc0, 0x18, - 0xa4, 0x85, 0xcd, 0x87, 0xe5, 0x86, 0xb9, 0xf2, 0xc5, 0xee, 0xba, 0xb9, 0xb2, 0x1c, 0x6f, 0x41, - 0xab, 0xfd, 0x6a, 0xa5, 0x5e, 0xc8, 0xa1, 0x19, 0x98, 0xd6, 0x4a, 0xb7, 0xb6, 0x0b, 0xf9, 0xdb, - 0x37, 0x79, 0xd8, 0x03, 0x34, 0x05, 0xb0, 0xbc, 0x52, 0xaf, 0xae, 0x6c, 0x2d, 0xaf, 0x6f, 0xad, - 0x16, 0x06, 0xd0, 0x24, 0x8c, 0x95, 0xe5, 0xcf, 0xdc, 0xed, 0x8f, 0x60, 0x3a, 0x72, 0x63, 0x22, - 0x10, 0xf2, 0xb2, 0x51, 0x18, 0x20, 0x3c, 0x92, 0x3f, 0xe9, 0x35, 0x97, 0x5d, 0x7e, 0x0a, 0xb9, - 0xa5, 0xff, 0xf9, 0x7b, 0x39, 0x18, 0x27, 0xdb, 0x81, 0x30, 0xfb, 0xfc, 0x5a, 0xb9, 0x60, 0xf0, - 0xcf, 0x80, 0x27, 0x60, 0x4a, 0xbd, 0x4d, 0xd0, 0x93, 0xa1, 0x98, 0xa1, 0xb8, 0xa2, 0x00, 0xb7, - 0x72, 0xf7, 0x72, 0xc8, 0xa4, 0xaf, 0x34, 0x11, 0x79, 0x5b, 0x52, 0x4e, 0xbe, 0x12, 0x15, 0x2f, - 0x67, 0x8a, 0xe9, 0xe8, 0x97, 0xc1, 0x50, 0x69, 0xa6, 0x48, 0xa5, 0xdf, 0xe9, 0x4f, 0xfa, 0x14, - 0x6d, 0xde, 0xec, 0x0f, 0x1c, 0x3d, 0x82, 0x49, 0x22, 0xaf, 0x49, 0x30, 0x74, 0x29, 0x8a, 0xa8, - 0x88, 0x88, 0xc5, 0xc5, 0xe4, 0x4a, 0x19, 0xff, 0x7d, 0x82, 0x0e, 0x84, 0x5d, 0xb6, 0x7c, 0x24, - 0x9c, 0xe3, 0x44, 0x09, 0xb3, 0xd3, 0x29, 0x9e, 0x8f, 0x14, 0xef, 0xdd, 0xbf, 0x97, 0x43, 0x75, - 0x1a, 0x53, 0x42, 0x13, 0xfc, 0x90, 0xb0, 0x43, 0x8e, 0x4b, 0x84, 0xac, 0x37, 0x25, 0x99, 0xd1, - 0x28, 0x45, 0x62, 0xdc, 0x02, 0x14, 0x97, 0xa7, 0xd0, 0xd5, 0x70, 0x1d, 0x24, 0x8b, 0x5a, 0xc5, - 0x0b, 0xb1, 0xc7, 0xf7, 0x15, 0x72, 0xa2, 0xa2, 0x15, 0x98, 0xe2, 0x9e, 0x2f, 0x5c, 0xc2, 0x43, - 0x59, 0x32, 0x62, 0x2a, 0x99, 0x55, 0xca, 0x27, 0x29, 0x25, 0xa2, 0x62, 0x38, 0x8e, 0xa8, 0xe8, - 0x58, 0xbc, 0x94, 0x58, 0xc7, 0xc7, 0xf7, 0x10, 0xa6, 0x74, 0x81, 0x13, 0x89, 0x09, 0x4a, 0x94, - 0x43, 0x53, 0x3b, 0xd4, 0x80, 0xf9, 0x4d, 0xcb, 0xa6, 0xea, 0x26, 0xfe, 0xc4, 0x2b, 0x1e, 0x68, - 0x51, 0x29, 0xe3, 0xc5, 0xb6, 0x8e, 0x9d, 0x56, 0xb1, 0x57, 0x0c, 0x26, 0xfa, 0xd9, 0xd4, 0x85, - 0xdc, 0xa4, 0x3f, 0x70, 0x23, 0x43, 0xcf, 0x52, 0x97, 0x64, 0xb3, 0x50, 0x4c, 0x33, 0xb3, 0x41, - 0x9b, 0x54, 0x70, 0x8b, 0x50, 0x54, 0xd6, 0xc4, 0x99, 0xc9, 0x2d, 0x50, 0xff, 0xab, 0xc0, 0x8e, - 0xda, 0xcb, 0xf8, 0x28, 0x85, 0x71, 0xa9, 0xc4, 0xee, 0xe5, 0xd0, 0xd7, 0xf4, 0xab, 0x4e, 0x24, - 0xb7, 0x6f, 0x07, 0x47, 0xdc, 0x66, 0xed, 0x52, 0x22, 0x01, 0xfe, 0xa1, 0x64, 0x50, 0x37, 0x61, - 0x36, 0xc9, 0xb2, 0x47, 0x32, 0x34, 0xc3, 0xec, 0x27, 0x75, 0x15, 0x98, 0x44, 0xfc, 0x6c, 0xa5, - 0x4f, 0x52, 0x86, 0x61, 0x49, 0x2a, 0xcd, 0x4f, 0x60, 0x8a, 0xac, 0x92, 0xc7, 0x18, 0x77, 0xca, - 0x6d, 0xfb, 0x19, 0xf6, 0x91, 0x88, 0x4f, 0x26, 0x8b, 0xd2, 0x70, 0x6f, 0xe5, 0xd0, 0xb7, 0x60, - 0x7c, 0xdf, 0x0a, 0x9a, 0x47, 0x3c, 0x30, 0x8e, 0x88, 0x9b, 0x43, 0xcb, 0x8a, 0xe2, 0x17, 0xad, - 0xbc, 0x97, 0x43, 0x9f, 0xc2, 0xc8, 0x2a, 0x0e, 0xa8, 0x1f, 0xc8, 0x35, 0xf9, 0xc8, 0xcd, 0x0c, - 0xca, 0xd6, 0x1d, 0x69, 0x7e, 0x2a, 0x3a, 0x1c, 0x55, 0x6e, 0xa1, 0xbb, 0x00, 0x6c, 0x43, 0xa0, - 0x14, 0xa2, 0xd5, 0xc5, 0x58, 0xb7, 0xd1, 0x2a, 0x39, 0xf8, 0xdb, 0x38, 0xc0, 0xfd, 0x36, 0x99, - 0xc6, 0xa3, 0x0d, 0x98, 0x92, 0x21, 0xf3, 0xb7, 0xa8, 0x17, 0xa4, 0x11, 0x21, 0xe6, 0x9f, 0x81, - 0xda, 0x47, 0xe4, 0xab, 0x60, 0x39, 0xd5, 0x64, 0xec, 0x36, 0x94, 0x16, 0xcd, 0x4d, 0x32, 0x91, - 0x81, 0x29, 0xb8, 0x6b, 0xae, 0x1f, 0xe8, 0xb8, 0xb2, 0x24, 0x19, 0x17, 0x43, 0x51, 0x6d, 0x57, - 0x8f, 0xe3, 0x16, 0xee, 0xb9, 0x69, 0xe1, 0xe7, 0x8a, 0xd7, 0x32, 0x20, 0xd8, 0x76, 0x47, 0x77, - 0x92, 0x65, 0x72, 0xa3, 0x67, 0xcd, 0x6c, 0x77, 0xb0, 0x53, 0xaf, 0xaf, 0xd1, 0x80, 0x5c, 0xe2, - 0x4d, 0x4d, 0x29, 0x13, 0x84, 0x51, 0xbc, 0x8a, 0x9c, 0x7a, 0x9a, 0x47, 0x1c, 0xca, 0xf2, 0x93, - 0x0b, 0x4f, 0xbd, 0xc4, 0x90, 0x63, 0x8f, 0x99, 0x8e, 0x41, 0xcb, 0xc8, 0xba, 0xb7, 0x84, 0x8a, - 0x49, 0x72, 0x2a, 0xff, 0xb0, 0x2f, 0x24, 0xd5, 0xed, 0x3d, 0xb8, 0x97, 0x43, 0x2b, 0x30, 0x23, - 0x9d, 0x56, 0xc3, 0x2a, 0x94, 0x82, 0x90, 0x71, 0xc2, 0xcc, 0x25, 0x90, 0xd9, 0x5b, 0xca, 0x20, - 0x94, 0x58, 0x8e, 0x3e, 0x87, 0x19, 0xbe, 0x36, 0xb5, 0xfe, 0x14, 0xe4, 0x36, 0xc3, 0x45, 0xfb, - 0xd4, 0x9e, 0x3c, 0x82, 0xb9, 0x7a, 0x84, 0x3b, 0xcc, 0xe0, 0xeb, 0xa2, 0x4e, 0x82, 0x16, 0xd6, - 0x71, 0xc0, 0xd8, 0x93, 0x4c, 0xeb, 0x31, 0x20, 0xa6, 0x0f, 0x10, 0xe4, 0x9e, 0xd9, 0xf8, 0x39, - 0xba, 0x1c, 0xe9, 0x3a, 0x29, 0xa4, 0x60, 0x74, 0x9f, 0x4a, 0x1d, 0xd9, 0x0e, 0x4b, 0xfc, 0xc7, - 0x72, 0x95, 0x5b, 0x1d, 0xeb, 0xc0, 0x6e, 0xdb, 0x81, 0x8d, 0xc9, 0x52, 0x55, 0x11, 0xd4, 0x2a, - 0xb1, 0x1e, 0x2e, 0xa6, 0x42, 0xa0, 0x5f, 0xa5, 0xe1, 0xa2, 0xb2, 0xef, 0x26, 0xe8, 0x5b, 0x49, - 0xd9, 0xa9, 0x53, 0x6e, 0x57, 0xc5, 0x6f, 0xf7, 0x07, 0xcc, 0x17, 0xe3, 0x67, 0x30, 0xb9, 0x8a, - 0x03, 0x96, 0x5d, 0x7c, 0xd9, 0x0a, 0x2c, 0x24, 0xf5, 0x05, 0xb2, 0x88, 0xaf, 0x41, 0x11, 0xeb, - 0x21, 0xac, 0xa8, 0xe3, 0x1f, 0xa3, 0x75, 0x28, 0xb0, 0x6d, 0x5e, 0x21, 0x71, 0x39, 0x46, 0x82, - 0x83, 0x58, 0x9e, 0x75, 0xec, 0xa7, 0xce, 0xd6, 0x5d, 0xf6, 0xbc, 0x8b, 0x64, 0x62, 0x66, 0x45, - 0x8e, 0x9c, 0xd1, 0xca, 0x64, 0x44, 0x4f, 0x32, 0x23, 0x26, 0xf6, 0x71, 0x20, 0xbc, 0x5b, 0x59, - 0xb2, 0xb3, 0xeb, 0xe1, 0x99, 0x1e, 0xaf, 0x0d, 0x3f, 0xf3, 0x48, 0x24, 0x86, 0xbd, 0x07, 0x48, - 0x26, 0x80, 0x4b, 0x20, 0x7a, 0x53, 0x13, 0x3d, 0xce, 0x46, 0xb7, 0x0a, 0x63, 0x0c, 0xad, 0xe2, - 0x06, 0x72, 0x7f, 0x94, 0x25, 0x02, 0x73, 0x21, 0x5e, 0xc1, 0x95, 0x13, 0x83, 0x7f, 0x35, 0x9f, - 0x43, 0x65, 0x18, 0x63, 0x9f, 0x96, 0x4a, 0x44, 0x96, 0xf4, 0xd8, 0xe6, 0x19, 0x89, 0xcf, 0x60, - 0x7c, 0x15, 0x07, 0x15, 0x97, 0x3a, 0x17, 0xfb, 0xf2, 0x93, 0x52, 0xca, 0x04, 0x99, 0x49, 0x65, - 0x14, 0x7b, 0x4b, 0x14, 0xfb, 0x5e, 0x0e, 0xbd, 0x4b, 0x8f, 0x4c, 0xea, 0x99, 0x3c, 0x17, 0xe2, - 0x2a, 0x39, 0x8e, 0x93, 0xf0, 0xc8, 0x99, 0x4e, 0x24, 0xee, 0xae, 0xe7, 0x61, 0x87, 0x21, 0xa7, - 0x89, 0x47, 0x49, 0xd8, 0x9f, 0xd1, 0xed, 0x52, 0xc1, 0x66, 0xd6, 0xf6, 0xbd, 0x48, 0xb0, 0x4c, - 0x09, 0xf7, 0x72, 0xe8, 0x03, 0x18, 0xe5, 0x7d, 0x24, 0x48, 0x5a, 0xa7, 0x7b, 0x8c, 0xf6, 0x03, - 0x00, 0x36, 0x15, 0xb4, 0xcf, 0x3a, 0x4c, 0x36, 0x9f, 0x3f, 0x20, 0xb2, 0x41, 0xeb, 0x55, 0x30, - 0xab, 0x42, 0x48, 0xa0, 0x98, 0x0b, 0xda, 0x2c, 0xab, 0x7c, 0xce, 0x24, 0x42, 0xc4, 0x7c, 0x1a, - 0x12, 0x46, 0x46, 0x76, 0x90, 0x62, 0xbe, 0x56, 0xdc, 0x4b, 0x34, 0x58, 0x87, 0x42, 0xb9, 0x49, - 0x4f, 0x2f, 0x99, 0x55, 0x5a, 0xde, 0xb1, 0xa2, 0x15, 0x82, 0xd6, 0x5c, 0x34, 0x49, 0xf5, 0x06, - 0xb6, 0x68, 0xc4, 0xbb, 0x79, 0x29, 0x09, 0x45, 0xaa, 0x92, 0x31, 0x32, 0xee, 0x54, 0xb3, 0x55, - 0x72, 0x0b, 0x6c, 0xbf, 0x1e, 0x99, 0x8f, 0xe8, 0xc6, 0xa7, 0x64, 0xdc, 0xbe, 0x10, 0xc5, 0x97, - 0xb7, 0x4f, 0x61, 0x6a, 0x2b, 0x41, 0xcb, 0x30, 0xcd, 0xe3, 0x6b, 0x49, 0xb6, 0xa4, 0x61, 0xa7, - 0x35, 0xff, 0x5d, 0x98, 0x5a, 0x21, 0x07, 0x53, 0xb7, 0x65, 0xb3, 0x28, 0x9f, 0x48, 0x0f, 0xdb, - 0x98, 0x8a, 0xb8, 0x26, 0x92, 0x93, 0x28, 0xa9, 0xa8, 0xe5, 0x87, 0x1c, 0xcf, 0xf6, 0x5d, 0x9c, - 0x15, 0x64, 0xd5, 0xac, 0xd5, 0x5c, 0x35, 0x31, 0x9f, 0x92, 0xfc, 0x19, 0xdd, 0xd0, 0x6e, 0xbc, - 0x69, 0x19, 0x9c, 0x13, 0x64, 0xdc, 0x2f, 0x95, 0x3c, 0x7b, 0x29, 0x34, 0xb3, 0xb3, 0x42, 0xa7, - 0x8e, 0x5b, 0xc6, 0xe5, 0x4b, 0xcc, 0xde, 0x8c, 0xde, 0xd1, 0xa9, 0x67, 0x64, 0x78, 0x4e, 0x6d, - 0x81, 0x6a, 0x14, 0xf4, 0xe4, 0xc2, 0xe8, 0x4a, 0x76, 0x0e, 0x64, 0x45, 0xa3, 0x90, 0x92, 0x95, - 0xf8, 0x11, 0x5d, 0x66, 0x61, 0x32, 0x3e, 0xa4, 0xde, 0xcf, 0xa3, 0xb9, 0x08, 0xa5, 0xe0, 0x98, - 0x9c, 0x61, 0xb8, 0x06, 0xd3, 0x91, 0xdc, 0xbd, 0x52, 0x91, 0x94, 0x9c, 0x3d, 0xb8, 0x78, 0x25, - 0xad, 0x5a, 0xaa, 0x4d, 0x0b, 0xd1, 0x84, 0xa7, 0x72, 0xc8, 0x29, 0xc9, 0x66, 0xe5, 0x90, 0x53, - 0x33, 0xa5, 0x3e, 0x82, 0x42, 0x34, 0xd7, 0xa2, 0x24, 0x9a, 0x92, 0x84, 0x31, 0x75, 0x4e, 0x1e, - 0xc2, 0xac, 0x3a, 0xa3, 0x72, 0xdc, 0x69, 0xbb, 0x7f, 0x1a, 0x9d, 0x1d, 0x98, 0x4b, 0x4c, 0x8d, - 0x28, 0x45, 0x85, 0xac, 0xc4, 0x89, 0xa9, 0x54, 0x31, 0x5c, 0x48, 0xce, 0x8e, 0x8a, 0xde, 0xd2, - 0xf5, 0x14, 0xc9, 0xb9, 0x22, 0x8b, 0x37, 0x7a, 0x40, 0x71, 0x86, 0x7e, 0x4d, 0x4f, 0xc0, 0x58, - 0x1b, 0xd7, 0x14, 0xcd, 0x45, 0x4a, 0x03, 0x46, 0x16, 0x88, 0x5c, 0x03, 0xb3, 0x49, 0xd9, 0x99, - 0x53, 0x59, 0x7c, 0x3d, 0x9d, 0x66, 0xb8, 0xb0, 0xf6, 0x44, 0x10, 0xbb, 0x54, 0xce, 0x64, 0x66, - 0xd1, 0xcc, 0xb8, 0xfa, 0x16, 0xe5, 0x7a, 0xe8, 0xbf, 0xcb, 0xe9, 0x6a, 0xac, 0xd9, 0xa4, 0xdc, - 0xad, 0x51, 0x2d, 0x53, 0x52, 0x6a, 0x4e, 0xc9, 0x86, 0xcc, 0xe4, 0xaf, 0x7b, 0x4c, 0xe3, 0xa4, - 0x53, 0x57, 0x35, 0x4e, 0x89, 0xa4, 0xaf, 0xa6, 0x03, 0x84, 0x2b, 0x22, 0x21, 0x09, 0xb5, 0x5c, - 0x11, 0xe9, 0xe9, 0xb0, 0xe5, 0x8a, 0xc8, 0xca, 0x61, 0x6d, 0x8a, 0x8f, 0x2e, 0x85, 0x2d, 0x19, - 0x19, 0x4b, 0x33, 0xae, 0x75, 0x0b, 0xe1, 0xc4, 0x45, 0xba, 0x7d, 0xd6, 0x69, 0xfb, 0x1a, 0x2e, - 0xa6, 0x66, 0x27, 0x45, 0x6f, 0xc7, 0x3e, 0xe8, 0x14, 0x4e, 0xa4, 0xf7, 0x74, 0x52, 0x4b, 0x2c, - 0x2a, 0x55, 0x6e, 0x91, 0x1c, 0xa6, 0xb1, 0x1d, 0x3b, 0x21, 0xc1, 0xe9, 0x2a, 0x95, 0x7c, 0x95, - 0x24, 0xa5, 0xa9, 0x63, 0xbd, 0x9c, 0x44, 0xc7, 0x8f, 0xef, 0xa9, 0x4a, 0xbf, 0x84, 0x24, 0x16, - 0xad, 0x38, 0xcb, 0x9e, 0xda, 0x4f, 0xd7, 0xd2, 0xe8, 0x2c, 0xd3, 0xcb, 0x84, 0xc8, 0x59, 0x8a, - 0x2e, 0x6a, 0x6c, 0xd2, 0x4e, 0xc9, 0xa2, 0x36, 0x38, 0xfd, 0x80, 0xac, 0x52, 0xdd, 0xb6, 0xcc, - 0x91, 0x9a, 0xda, 0x8b, 0x4b, 0x71, 0x1a, 0x9a, 0x5e, 0x5b, 0x72, 0x81, 0xf5, 0x66, 0x31, 0xca, - 0x1c, 0xad, 0x43, 0xe9, 0x43, 0x42, 0x2a, 0x6b, 0x7a, 0x74, 0x29, 0x5d, 0x42, 0x9d, 0xe1, 0x79, - 0xe0, 0x68, 0x94, 0x69, 0x11, 0xae, 0xe5, 0x82, 0x54, 0xd2, 0x29, 0xa5, 0x19, 0x3a, 0x99, 0x1a, - 0x35, 0x07, 0x4e, 0x48, 0xf7, 0x2a, 0xf7, 0xd0, 0xcc, 0x6c, 0xb0, 0x09, 0xd2, 0x99, 0xdc, 0x95, - 0x53, 0x29, 0x66, 0xe6, 0x7f, 0x4d, 0xed, 0xe9, 0x0f, 0x95, 0x5d, 0x39, 0x96, 0xd4, 0x15, 0xdd, - 0x8a, 0x8a, 0x66, 0x69, 0x79, 0x5f, 0x33, 0x76, 0xfd, 0xd9, 0xa4, 0x7c, 0xb0, 0x8a, 0xa2, 0x39, - 0x35, 0x59, 0x6c, 0x02, 0x17, 0xe4, 0xf6, 0x96, 0x42, 0x2d, 0x23, 0x3b, 0x6c, 0x6a, 0x0f, 0xbf, - 0xaf, 0x6c, 0x6f, 0x91, 0x2c, 0xae, 0x52, 0x71, 0xd0, 0x23, 0xcd, 0x6b, 0x2a, 0xed, 0x2d, 0x6a, - 0x40, 0x1e, 0x4f, 0xc1, 0x2a, 0x65, 0x97, 0xac, 0x04, 0xad, 0x89, 0x7a, 0xe8, 0xb9, 0xf8, 0x10, - 0x09, 0xbd, 0x0b, 0x11, 0x2d, 0x72, 0xaf, 0x8e, 0xc9, 0x7d, 0x38, 0x21, 0x75, 0x6b, 0x64, 0x1f, - 0x4e, 0x4f, 0xee, 0x9a, 0x71, 0xd1, 0x99, 0xae, 0xdb, 0x87, 0x8e, 0x92, 0x79, 0x55, 0x5e, 0x73, - 0xe2, 0xc9, 0x60, 0xe5, 0x16, 0x93, 0x94, 0xa8, 0x75, 0x9b, 0x48, 0x38, 0x4c, 0x3e, 0x57, 0x73, - 0x68, 0xa2, 0x62, 0x7a, 0xea, 0x50, 0xb9, 0xdd, 0x24, 0x26, 0xdd, 0x54, 0x08, 0xaa, 0x09, 0x2c, - 0x25, 0xc1, 0x84, 0x5c, 0x9a, 0x92, 0x60, 0x62, 0xc6, 0xcb, 0xbb, 0x54, 0xaf, 0x62, 0xba, 0x6d, - 0xac, 0xea, 0x55, 0x94, 0xb4, 0x8e, 0x11, 0xb5, 0x06, 0xfa, 0x98, 0x2a, 0x35, 0xb2, 0x35, 0x21, - 0xf3, 0x3a, 0x25, 0x35, 0xfd, 0x34, 0x84, 0xf9, 0x2d, 0x91, 0xae, 0x75, 0xca, 0x68, 0xf3, 0x3d, - 0xa1, 0xd4, 0xd0, 0xd0, 0x62, 0x19, 0x2f, 0xa3, 0x68, 0xdf, 0x85, 0x89, 0x30, 0xbb, 0xe5, 0xde, - 0x92, 0x82, 0x18, 0x49, 0x79, 0x19, 0x45, 0xfc, 0x40, 0x3c, 0xb0, 0xd0, 0xf6, 0xf4, 0xca, 0x5e, - 0x6a, 0x2e, 0x08, 0x13, 0x63, 0x46, 0x94, 0x28, 0x6a, 0x83, 0xe9, 0x3b, 0xef, 0x84, 0x9a, 0xd8, - 0x47, 0xce, 0x6b, 0x42, 0x1e, 0x35, 0x39, 0xaf, 0x49, 0xd9, 0xc9, 0x68, 0x6f, 0xe8, 0x5d, 0xfb, - 0x2b, 0xa1, 0x31, 0x08, 0x89, 0x5e, 0xce, 0xcc, 0x31, 0x56, 0xbc, 0x92, 0x9d, 0x98, 0x2b, 0x24, - 0x5d, 0x87, 0x42, 0x34, 0x0b, 0x11, 0x4a, 0xca, 0x13, 0xa7, 0xa4, 0x8b, 0x92, 0x77, 0xb8, 0xd4, - 0xf4, 0x45, 0x35, 0xa1, 0xc6, 0xd7, 0xe9, 0xa6, 0x64, 0x0b, 0x53, 0x49, 0x67, 0x8b, 0x55, 0x61, - 0x42, 0x22, 0xf5, 0x22, 0x1c, 0x4b, 0x78, 0xa4, 0x8a, 0x55, 0x09, 0x39, 0x8c, 0x6c, 0x11, 0x7f, - 0x21, 0x39, 0xa3, 0xe9, 0x3b, 0xfa, 0x0d, 0x35, 0x23, 0xe8, 0x64, 0xcf, 0xc7, 0x68, 0xf4, 0x4b, - 0x30, 0x9f, 0x12, 0x1b, 0x10, 0xdd, 0x88, 0x28, 0x84, 0x93, 0x63, 0x07, 0x16, 0xb3, 0x12, 0xff, - 0xa1, 0x4d, 0x6a, 0xc5, 0xa0, 0x79, 0x5a, 0xc6, 0x5e, 0x06, 0xf7, 0xed, 0xe0, 0x88, 0xa5, 0xb2, - 0x54, 0xf6, 0xcc, 0x44, 0x17, 0x4d, 0x54, 0xa7, 0xf7, 0x0d, 0xad, 0x34, 0xe1, 0x71, 0x30, 0x81, - 0x60, 0x31, 0x99, 0x20, 0x4d, 0x1c, 0x5e, 0x13, 0x4f, 0x4c, 0xd1, 0x6e, 0xaa, 0xc3, 0x4f, 0x72, - 0x2e, 0x4d, 0xed, 0x66, 0x4d, 0x08, 0x48, 0xc9, 0x14, 0xd3, 0x3d, 0x62, 0x53, 0x29, 0x3e, 0x22, - 0x14, 0x63, 0x4e, 0xae, 0x28, 0x05, 0x3c, 0x7b, 0xf7, 0x30, 0xc5, 0x79, 0xab, 0x63, 0x2d, 0x29, - 0xfd, 0x4b, 0x73, 0xa7, 0x4d, 0xed, 0xdf, 0x8a, 0xf8, 0x9e, 0x92, 0xfb, 0xd7, 0xef, 0x89, 0x2b, - 0x9f, 0xe9, 0x22, 0x7e, 0xd6, 0xda, 0x40, 0x95, 0xf2, 0x62, 0x4a, 0x39, 0xda, 0xa2, 0x66, 0x49, - 0xd1, 0x52, 0xe5, 0xe2, 0x99, 0xec, 0xc8, 0x9d, 0x4a, 0x8f, 0xad, 0x63, 0xcd, 0x11, 0xf6, 0x2c, - 0xeb, 0x38, 0xe2, 0x41, 0xcb, 0xd7, 0xb1, 0x56, 0x7a, 0xb6, 0x75, 0x1c, 0x21, 0xa8, 0xaf, 0xe3, - 0x68, 0x37, 0xa3, 0x17, 0xf9, 0xd4, 0x59, 0x8d, 0x76, 0x53, 0xae, 0xe3, 0x64, 0x8a, 0xe9, 0x0e, - 0xcb, 0xa9, 0x14, 0xe5, 0x3a, 0xd6, 0x29, 0xa6, 0x80, 0xf7, 0xb9, 0x8e, 0xa3, 0x8d, 0xe8, 0xeb, - 0xf8, 0x4c, 0xfd, 0x93, 0xeb, 0x38, 0xb9, 0x7f, 0x67, 0x5e, 0xc7, 0x11, 0x0f, 0x7f, 0x6d, 0xa0, - 0x49, 0xeb, 0x38, 0x0a, 0xcf, 0xd6, 0x71, 0xb4, 0x34, 0xa2, 0x40, 0xc9, 0x58, 0xc7, 0x51, 0xcc, - 0x2f, 0x28, 0xbd, 0x88, 0x77, 0x72, 0x3f, 0x2b, 0x39, 0xd5, 0xb1, 0x19, 0xed, 0x53, 0xed, 0x5d, - 0xa4, 0xbc, 0xbf, 0xd5, 0xbc, 0x98, 0x46, 0x94, 0xae, 0xe7, 0x3d, 0xc1, 0xc4, 0x68, 0x77, 0x75, - 0xd5, 0x54, 0xb2, 0x73, 0x76, 0x46, 0x87, 0xf7, 0xc8, 0xba, 0x69, 0x65, 0xd0, 0xcd, 0xf2, 0x2d, - 0xcf, 0xa0, 0x2b, 0xef, 0x31, 0x51, 0xba, 0xa9, 0x28, 0xd9, 0xeb, 0xfb, 0x4b, 0xf1, 0x7e, 0x11, - 0xc5, 0x5b, 0x8a, 0xdc, 0x8c, 0xce, 0xdc, 0x53, 0x79, 0x43, 0x8a, 0xf6, 0xf4, 0xac, 0xeb, 0x7c, - 0x53, 0x48, 0x0f, 0xb1, 0xa0, 0x14, 0x91, 0x41, 0xab, 0x6b, 0x3d, 0xb5, 0x06, 0xed, 0x50, 0x55, - 0x6d, 0xbc, 0x5c, 0x51, 0xf3, 0xa6, 0x45, 0xbf, 0xe8, 0x49, 0x35, 0xe6, 0x5e, 0xaf, 0x52, 0x4d, - 0xf3, 0xbd, 0x97, 0x54, 0xe3, 0xd8, 0x9f, 0x53, 0xd5, 0x17, 0xf7, 0x07, 0x72, 0x9e, 0xb8, 0xe9, - 0xf7, 0x94, 0x19, 0xcd, 0x74, 0x8a, 0xc0, 0x52, 0x8b, 0xb5, 0x4f, 0xf8, 0x03, 0x9d, 0x28, 0x4c, - 0x65, 0x7e, 0x12, 0x3e, 0xfa, 0x1c, 0x0a, 0x7c, 0x7b, 0x0b, 0x09, 0x24, 0x01, 0xa6, 0x4e, 0x5d, - 0x45, 0x68, 0xdc, 0xfa, 0xe8, 0x41, 0x3f, 0x9a, 0xb6, 0x7e, 0x38, 0x91, 0xae, 0x96, 0x22, 0xc7, - 0xe1, 0x8e, 0xd7, 0xf5, 0x03, 0xdc, 0x8a, 0xab, 0x93, 0xf4, 0xce, 0x08, 0x03, 0x0e, 0x1d, 0x7c, - 0x6f, 0x09, 0xad, 0xd3, 0xbd, 0x4d, 0x2f, 0xce, 0xd2, 0xb7, 0x25, 0x93, 0xa1, 0x5b, 0xcf, 0x9a, - 0x74, 0x3c, 0xd1, 0xfb, 0x94, 0xd6, 0x76, 0x7a, 0xa7, 0x24, 0x8b, 0xfa, 0x1c, 0x5d, 0x1a, 0x8b, - 0xd8, 0x85, 0x98, 0xe9, 0xfe, 0x7a, 0x71, 0x26, 0xea, 0x0a, 0x83, 0xbe, 0x07, 0x63, 0x02, 0xb9, - 0x37, 0x43, 0xa2, 0xd8, 0x94, 0x21, 0xcb, 0x30, 0xa9, 0xf9, 0xf9, 0xc8, 0xdb, 0x4d, 0x92, 0xf7, - 0x4f, 0xc6, 0x3c, 0x4f, 0x6a, 0xfe, 0x3c, 0x92, 0x4a, 0x92, 0x97, 0x4f, 0x2a, 0x95, 0x4f, 0x61, - 0x9c, 0xb3, 0x34, 0x93, 0x1b, 0xe9, 0xca, 0xb6, 0x39, 0xc5, 0x3e, 0xba, 0xdb, 0xb2, 0x83, 0xaa, - 0xeb, 0x3c, 0xb1, 0x0f, 0x7b, 0x32, 0x26, 0x8e, 0xb2, 0xb7, 0x84, 0xf6, 0x68, 0xbe, 0x36, 0x91, - 0x45, 0x0f, 0x07, 0xcf, 0x5d, 0xef, 0xa9, 0xed, 0x1c, 0xf6, 0x20, 0x79, 0x55, 0x27, 0x19, 0xc5, - 0x63, 0x74, 0xeb, 0xe9, 0x74, 0x7b, 0xe2, 0x67, 0x28, 0xdb, 0x16, 0xa9, 0x69, 0xcf, 0x59, 0x7b, - 0x9c, 0xfe, 0xf0, 0x78, 0x31, 0xb4, 0x2c, 0x36, 0x71, 0xd3, 0xf5, 0x5a, 0xbd, 0x89, 0x95, 0x74, - 0x3b, 0xde, 0x08, 0xda, 0xde, 0x12, 0xa1, 0x5a, 0x4f, 0xa5, 0xda, 0x0b, 0x3b, 0xe3, 0xb4, 0xba, - 0x44, 0xc7, 0x7e, 0xc6, 0xde, 0x66, 0xef, 0x5a, 0xe4, 0xa4, 0xa9, 0x79, 0xf8, 0x09, 0xf6, 0xa8, - 0x79, 0x78, 0x2f, 0xc3, 0x68, 0x1d, 0x7c, 0x6f, 0x89, 0x50, 0xa9, 0xc7, 0xa8, 0xa4, 0x41, 0x67, - 0xa9, 0xe4, 0xe9, 0xd0, 0xfa, 0xec, 0x4d, 0x1a, 0x99, 0x0f, 0xe8, 0x93, 0xc7, 0xee, 0x7a, 0x0f, - 0x8e, 0x08, 0x87, 0x05, 0x01, 0xb8, 0x77, 0x9f, 0x60, 0xd6, 0x15, 0xcc, 0x38, 0x44, 0x6a, 0x9b, - 0xdf, 0x13, 0x6f, 0x1b, 0x3d, 0x9b, 0x4d, 0xa3, 0xf0, 0x80, 0x6e, 0x6f, 0xdc, 0x26, 0x5a, 0xd1, - 0x0a, 0x6a, 0x99, 0x52, 0x8b, 0x93, 0xaa, 0x79, 0xb4, 0x8f, 0xca, 0xec, 0x46, 0xa7, 0xe6, 0x54, - 0x55, 0xac, 0x21, 0x12, 0x93, 0xad, 0x46, 0x49, 0x30, 0xad, 0xe6, 0x86, 0xdb, 0x7c, 0xaa, 0x6a, - 0x35, 0x95, 0x24, 0x9d, 0x45, 0x3d, 0x85, 0x26, 0xdf, 0xc4, 0x69, 0x1e, 0x4d, 0xd5, 0x54, 0x4b, - 0x4d, 0xd3, 0xa9, 0x6a, 0x35, 0xf5, 0x84, 0xa2, 0x0f, 0x84, 0xba, 0x90, 0x36, 0xa8, 0x53, 0x4e, - 0x65, 0x8d, 0xd4, 0x14, 0x52, 0x24, 0x5d, 0x53, 0xa8, 0x76, 0x34, 0x7d, 0xbb, 0x40, 0xf1, 0x8c, - 0xa2, 0xf2, 0xfe, 0x91, 0x9a, 0x6c, 0x34, 0xc3, 0xe2, 0x6a, 0x26, 0x21, 0x75, 0xb2, 0xbc, 0xb1, - 0xa5, 0xa7, 0x55, 0x2e, 0xea, 0xe6, 0x43, 0xf7, 0x72, 0x68, 0x0b, 0x2e, 0xac, 0xe2, 0x80, 0x6f, - 0x60, 0x26, 0xf6, 0x03, 0xcf, 0x6e, 0x06, 0x99, 0x0f, 0x7d, 0xe2, 0xba, 0x91, 0x80, 0xb3, 0xf7, - 0x2e, 0xa1, 0x57, 0x4f, 0xa6, 0x97, 0x89, 0x97, 0x61, 0x9c, 0xcb, 0x5f, 0x0f, 0xce, 0xd2, 0xc5, - 0xf4, 0x25, 0x3e, 0xc2, 0x6c, 0x66, 0xd2, 0x51, 0x0b, 0x61, 0x94, 0x7d, 0x7e, 0x81, 0xba, 0x03, - 0xe7, 0x18, 0x52, 0xea, 0x19, 0x39, 0xa1, 0xe2, 0xa0, 0xfb, 0xc2, 0x8a, 0x93, 0xa0, 0x68, 0x55, - 0xa9, 0xfd, 0xba, 0x0f, 0x63, 0xec, 0xb6, 0xd4, 0x3f, 0xca, 0xc7, 0xc2, 0xcc, 0x33, 0xab, 0x63, - 0x69, 0xc8, 0x9f, 0xc3, 0xa4, 0x6a, 0x2f, 0x73, 0x76, 0x46, 0x7e, 0x4a, 0x9f, 0x63, 0xc5, 0xab, - 0x47, 0x3a, 0xfe, 0x5c, 0x24, 0xf3, 0x02, 0x67, 0x29, 0xdb, 0x20, 0x65, 0x0e, 0xf2, 0xb4, 0xee, - 0x9f, 0x8f, 0x61, 0xa3, 0x8f, 0x85, 0xab, 0x94, 0x44, 0x8e, 0x03, 0x65, 0xf0, 0x6c, 0x8a, 0xb1, - 0xf9, 0x55, 0x90, 0xe5, 0x06, 0xdb, 0xb3, 0xdb, 0xfd, 0x3c, 0x1b, 0xf7, 0x66, 0x5d, 0x1a, 0x95, - 0x6d, 0x2a, 0x78, 0xc5, 0x72, 0x82, 0xa4, 0x13, 0xba, 0x92, 0x9e, 0x46, 0x84, 0x4e, 0xc6, 0x23, - 0x7a, 0xb1, 0x8b, 0xe7, 0x93, 0x4f, 0x1b, 0x5e, 0x46, 0x5a, 0x92, 0xf0, 0x26, 0x1b, 0x27, 0x97, - 0x81, 0x96, 0x75, 0x31, 0xe6, 0xce, 0x9b, 0x6f, 0x84, 0xdc, 0xba, 0x30, 0x3b, 0xec, 0x7f, 0xb0, - 0x19, 0x42, 0x50, 0xc2, 0x43, 0x75, 0xcf, 0xb9, 0x48, 0x23, 0xf7, 0x4b, 0x54, 0xfe, 0x4b, 0x4e, - 0x07, 0x9d, 0x4a, 0xec, 0x96, 0x62, 0xeb, 0x90, 0x9d, 0x48, 0xfa, 0x29, 0xf5, 0x41, 0x4b, 0xce, - 0x9a, 0x72, 0xb3, 0x07, 0x15, 0xc1, 0x89, 0xb7, 0x7b, 0xc2, 0xc9, 0x67, 0xcf, 0x4b, 0xec, 0x84, - 0x4d, 0x6e, 0xaf, 0x47, 0x16, 0x98, 0x84, 0x97, 0xe8, 0x94, 0x5c, 0xcb, 0x82, 0xa0, 0x6e, 0xd3, - 0x99, 0x39, 0x86, 0x34, 0xf6, 0x7f, 0x01, 0xa5, 0xd0, 0xa0, 0xe3, 0x6c, 0x93, 0x90, 0x2e, 0xd1, - 0xa3, 0x78, 0x06, 0x6a, 0x94, 0x15, 0xa8, 0xbe, 0x78, 0x2d, 0x8d, 0xc3, 0xbe, 0x62, 0x29, 0xc4, - 0x4d, 0xd1, 0x22, 0xf9, 0x83, 0xd2, 0x32, 0x11, 0x65, 0xa8, 0x56, 0xb9, 0x53, 0xde, 0x1b, 0x21, - 0x14, 0x9f, 0xed, 0xb3, 0x13, 0x92, 0xf6, 0x16, 0x11, 0x42, 0x46, 0xc6, 0xf4, 0x9e, 0xc5, 0x9c, - 0x2c, 0x3a, 0x15, 0x67, 0x9d, 0x50, 0x2b, 0x74, 0x44, 0x8b, 0xa7, 0xc9, 0x96, 0xb2, 0x5c, 0x6a, - 0xca, 0x6e, 0x39, 0xbb, 0x19, 0x39, 0xb6, 0xab, 0xe4, 0x33, 0x65, 0x4d, 0x68, 0x39, 0x7a, 0xab, - 0xe6, 0x46, 0xa8, 0x29, 0x48, 0x48, 0xde, 0x5b, 0x04, 0x51, 0x69, 0x6e, 0xa0, 0xba, 0x88, 0xb2, - 0x9a, 0x14, 0x12, 0x45, 0x3a, 0xdd, 0x24, 0x55, 0x66, 0xdc, 0x2e, 0xea, 0x22, 0xae, 0xea, 0x9b, - 0x24, 0xda, 0x80, 0xf9, 0x94, 0x40, 0x32, 0xf2, 0xd1, 0x34, 0x3b, 0xd0, 0x4c, 0x31, 0xbb, 0x61, - 0xf4, 0x03, 0x98, 0x4b, 0x8c, 0x34, 0x23, 0x15, 0xbf, 0x59, 0x71, 0x68, 0x7a, 0x11, 0x7f, 0x0a, - 0x0b, 0x69, 0x09, 0x75, 0x43, 0x27, 0xa0, 0xec, 0x2c, 0xc7, 0x72, 0x4f, 0xed, 0x99, 0x99, 0x77, - 0x0b, 0x66, 0x93, 0x92, 0xd4, 0xca, 0x8f, 0x23, 0x23, 0x83, 0x6d, 0xa2, 0xa7, 0x51, 0x0d, 0xe6, - 0x12, 0x13, 0xc5, 0x4a, 0xce, 0x64, 0xa5, 0x91, 0x4d, 0xa4, 0xf8, 0x25, 0xcc, 0xa7, 0x64, 0x45, - 0x0d, 0x5f, 0xc0, 0x33, 0xb3, 0xa6, 0x66, 0xd8, 0x0f, 0x15, 0xd3, 0x13, 0x6e, 0x4a, 0xb3, 0xb1, - 0x9e, 0x39, 0x39, 0x8b, 0x89, 0x59, 0x88, 0xd1, 0x0e, 0x5d, 0x84, 0x49, 0x19, 0x38, 0xd5, 0x45, - 0x98, 0x91, 0xa1, 0x33, 0xc5, 0x43, 0x6c, 0x3e, 0x25, 0xe9, 0x66, 0x06, 0xd5, 0x3e, 0x7a, 0xbb, - 0x25, 0xf6, 0x7f, 0x3d, 0x35, 0x62, 0xc4, 0x14, 0x39, 0x31, 0x6f, 0x62, 0x62, 0x3f, 0x95, 0xd0, - 0x0a, 0xed, 0x76, 0x86, 0x18, 0x84, 0xd4, 0xd8, 0x0a, 0x04, 0x92, 0xea, 0xce, 0x27, 0x55, 0xdc, - 0xac, 0x1d, 0x35, 0x86, 0x4c, 0x05, 0xcf, 0x8f, 0x60, 0xa2, 0xae, 0x36, 0x9e, 0xd0, 0x48, 0xea, - 0xa2, 0x90, 0xbe, 0x35, 0xbd, 0xfb, 0x9e, 0xa1, 0xec, 0x91, 0x87, 0x43, 0x5f, 0xa3, 0x48, 0xb5, - 0x58, 0xd1, 0xb2, 0x97, 0xc8, 0x9d, 0x3a, 0x29, 0x31, 0x90, 0xb4, 0x58, 0x49, 0x4e, 0x78, 0xd2, - 0x60, 0xf1, 0xd6, 0xa3, 0x79, 0x9f, 0x90, 0xd1, 0x3b, 0x9f, 0x99, 0xb4, 0x34, 0xcf, 0x4c, 0x1c, - 0xc5, 0xcc, 0x6b, 0xc2, 0x7c, 0x2d, 0xaa, 0x79, 0x4d, 0x2c, 0x0b, 0x8c, 0x6a, 0x5e, 0x93, 0x90, - 0xe2, 0x65, 0x85, 0xd2, 0x0a, 0x03, 0xd5, 0x67, 0x28, 0x0c, 0x24, 0x99, 0x84, 0x78, 0xf8, 0x8f, - 0xd5, 0x08, 0x1d, 0x2c, 0xbc, 0x7d, 0x86, 0xc6, 0x33, 0x1a, 0x99, 0x23, 0x12, 0x0f, 0xff, 0x11, - 0x14, 0xa2, 0xa1, 0xbd, 0xa4, 0x3a, 0x2a, 0x25, 0xe6, 0x57, 0xc6, 0x12, 0x83, 0x30, 0x80, 0x97, - 0x54, 0xfa, 0xc4, 0x62, 0x7a, 0x15, 0x2f, 0x26, 0xd4, 0x48, 0x71, 0x6d, 0x42, 0x0d, 0xf7, 0x25, - 0x2d, 0xc4, 0x12, 0x62, 0x80, 0x15, 0x2f, 0x25, 0xd6, 0x71, 0x42, 0x01, 0x4b, 0xc5, 0x97, 0x9c, - 0xc8, 0x2f, 0x74, 0x6b, 0xca, 0x80, 0x11, 0xcd, 0xdc, 0xee, 0x07, 0x94, 0xb7, 0x8a, 0x65, 0x78, - 0xfd, 0x38, 0x14, 0x7a, 0x3b, 0xc1, 0xfd, 0x40, 0x83, 0x08, 0x8d, 0xa7, 0xc2, 0x47, 0xf4, 0xa4, - 0x64, 0x85, 0x68, 0x5f, 0x84, 0x3b, 0x4f, 0x69, 0xa9, 0x17, 0x81, 0xd4, 0x19, 0xdc, 0x17, 0x01, - 0xce, 0xdf, 0x34, 0xe1, 0x03, 0x58, 0x8c, 0x78, 0x37, 0xe8, 0x84, 0x6f, 0x27, 0xbb, 0x40, 0x24, - 0xb2, 0x27, 0x5d, 0x1e, 0xbe, 0x1a, 0x77, 0x85, 0x88, 0xcc, 0xfb, 0x59, 0xf7, 0xaa, 0x4d, 0x98, - 0xa2, 0xdb, 0x83, 0x48, 0x3f, 0x19, 0x06, 0x76, 0xd1, 0x8b, 0xa3, 0x11, 0x86, 0xa2, 0xb5, 0xd2, - 0x2b, 0x7c, 0x82, 0xbb, 0xc8, 0xb2, 0x64, 0x96, 0x45, 0xdd, 0x6f, 0x96, 0x16, 0x26, 0x9d, 0x3e, - 0x3c, 0x47, 0x26, 0xfa, 0x14, 0xa6, 0x43, 0xcf, 0x59, 0x46, 0x22, 0x01, 0x2c, 0x43, 0x09, 0x35, - 0x1d, 0xba, 0xcf, 0x9e, 0x1d, 0x7d, 0x4d, 0x1c, 0x21, 0x21, 0xfa, 0xe5, 0x98, 0x57, 0x88, 0x36, - 0x86, 0x7e, 0x4e, 0x12, 0x85, 0xb7, 0x67, 0x9d, 0x9d, 0x26, 0xfd, 0xdc, 0x92, 0xe3, 0xd8, 0xa9, - 0x9f, 0x5b, 0x66, 0xac, 0x3d, 0x29, 0xb6, 0xa6, 0xd0, 0xd9, 0x84, 0xeb, 0x34, 0xce, 0x49, 0x0d, - 0x3b, 0x2d, 0xdb, 0x39, 0x4c, 0x86, 0x4a, 0xef, 0x7b, 0x34, 0x3a, 0x4a, 0x1b, 0xae, 0xf5, 0x0c, - 0xe4, 0x87, 0xee, 0x6a, 0x16, 0x21, 0xbd, 0x43, 0xfe, 0x65, 0x79, 0x62, 0x25, 0xc5, 0xc3, 0x93, - 0xe7, 0x63, 0x46, 0x68, 0x3e, 0x79, 0x3e, 0x66, 0x06, 0xd4, 0xfb, 0x92, 0xe6, 0x10, 0xe0, 0x67, - 0x0b, 0x8d, 0x5d, 0x84, 0x1d, 0x16, 0xe1, 0x37, 0xf3, 0x49, 0xe5, 0x9a, 0xfe, 0x90, 0x18, 0x43, - 0xa4, 0x77, 0x91, 0x2b, 0xfc, 0x06, 0x95, 0x46, 0xbc, 0x37, 0x91, 0x0c, 0x4b, 0xe4, 0x2b, 0x6c, - 0x01, 0x9e, 0xb9, 0xe7, 0x29, 0xe5, 0x95, 0xe5, 0x9f, 0xfe, 0xf9, 0x95, 0xdc, 0x4f, 0x7f, 0x76, - 0x25, 0xf7, 0x6f, 0x7e, 0x76, 0x25, 0xf7, 0x1f, 0x7e, 0x76, 0x25, 0xf7, 0xfd, 0xa5, 0xfe, 0xe2, - 0xcc, 0x36, 0xdb, 0x36, 0x76, 0x82, 0xbb, 0x8c, 0xdc, 0x39, 0xfa, 0xdf, 0x83, 0xff, 0x1d, 0x00, - 0x00, 0xff, 0xff, 0x0a, 0xaf, 0x3d, 0x6e, 0xb4, 0xdb, 0x00, 0x00, + 0x74, 0xca, 0x20, 0xff, 0x5a, 0x4e, 0x7c, 0x72, 0xc9, 0xc4, 0x7f, 0xd1, 0xb7, 0xd2, 0x4d, 0x28, + 0x49, 0x86, 0xe8, 0x3d, 0x7a, 0xbd, 0x2b, 0xe9, 0x13, 0x98, 0x53, 0xc9, 0xd8, 0x4d, 0xbc, 0x7b, + 0x9f, 0x6a, 0x5c, 0xdf, 0x25, 0x9f, 0x05, 0x2d, 0x10, 0xcb, 0x6e, 0x21, 0x81, 0x6f, 0x14, 0xde, + 0x94, 0x90, 0x46, 0x03, 0x16, 0xe3, 0x53, 0x61, 0x37, 0x85, 0xf9, 0x2b, 0xfa, 0x9c, 0x7c, 0xc2, + 0xb4, 0x84, 0x4f, 0x46, 0x2a, 0x51, 0xf1, 0x1d, 0x33, 0x74, 0x81, 0x65, 0x18, 0x62, 0xab, 0x89, + 0x8c, 0x9f, 0xb4, 0x2e, 0xd6, 0xc3, 0xaf, 0x00, 0x12, 0x55, 0xd5, 0xba, 0x29, 0x9a, 0xbe, 0x08, + 0x83, 0xd5, 0xba, 0xc9, 0xad, 0xee, 0xe9, 0xad, 0xb8, 0xe9, 0x7b, 0x26, 0x29, 0x8b, 0x4a, 0xad, + 0xf9, 0x3e, 0xa4, 0xd6, 0x47, 0x43, 0xa3, 0x83, 0x85, 0x21, 0x13, 0xd5, 0xed, 0x03, 0x67, 0xcf, + 0x0e, 0x0e, 0x65, 0x83, 0x65, 0xe3, 0x07, 0x30, 0xa3, 0x35, 0xcf, 0xbf, 0xe2, 0x4c, 0x77, 0x01, + 0x74, 0x13, 0x46, 0xaa, 0x65, 0x6a, 0x75, 0x40, 0xaf, 0xf5, 0x13, 0x6c, 0xbf, 0x69, 0x5a, 0x0d, + 0xea, 0x12, 0x66, 0x8a, 0x4a, 0xe3, 0xef, 0x0d, 0x29, 0xd4, 0x15, 0x27, 0x8c, 0x8c, 0xd1, 0xdd, + 0x07, 0x60, 0x2b, 0x44, 0x19, 0x1c, 0x11, 0x00, 0xc7, 0xf9, 0x43, 0x29, 0xdb, 0x92, 0x4d, 0x05, + 0xa8, 0x5f, 0x27, 0x0d, 0x6e, 0x30, 0xc9, 0x90, 0x84, 0x35, 0x81, 0x34, 0x98, 0xe4, 0xa4, 0x7d, + 0x53, 0x05, 0x42, 0x3f, 0x8c, 0xda, 0x12, 0x0f, 0x53, 0xf5, 0xfa, 0x5b, 0xe2, 0xc5, 0x27, 0x3e, + 0xb6, 0xd3, 0x99, 0x13, 0xbf, 0x80, 0x39, 0x82, 0x6b, 0x3f, 0xa5, 0x06, 0xc3, 0x2b, 0x2f, 0x03, + 0xec, 0xb0, 0xbd, 0xfd, 0x1c, 0x6d, 0xe7, 0x46, 0x46, 0x3b, 0x21, 0x30, 0xd7, 0x30, 0x87, 0x74, + 0x1a, 0x58, 0xd6, 0x99, 0xc9, 0xf4, 0xe9, 0x22, 0x32, 0x37, 0x56, 0x9c, 0x56, 0xc7, 0xb5, 0xe5, + 0xa5, 0x82, 0x2d, 0x22, 0xaf, 0xdd, 0xc0, 0xbc, 0xdc, 0x54, 0x81, 0x8c, 0x9b, 0x99, 0xd6, 0xb6, + 0xa3, 0x30, 0xb4, 0x5d, 0xdd, 0xde, 0x28, 0xe4, 0x8c, 0xbb, 0x00, 0x4a, 0x4b, 0x00, 0xe7, 0x36, + 0xb7, 0xcc, 0x27, 0xe5, 0x8d, 0xc2, 0x00, 0x9a, 0x83, 0xf3, 0x7b, 0xeb, 0x9b, 0xcb, 0x5b, 0x7b, + 0xf5, 0x46, 0xfd, 0x49, 0xd9, 0xdc, 0xae, 0x96, 0xcd, 0xe5, 0x42, 0xce, 0xf8, 0x1a, 0x66, 0xf5, + 0x11, 0x9e, 0xe9, 0x22, 0x0c, 0x60, 0x46, 0xca, 0x33, 0x8f, 0xf6, 0xb6, 0x15, 0x83, 0x3f, 0x7e, + 0x41, 0x8a, 0x1a, 0x05, 0xf0, 0xab, 0x14, 0xff, 0x8c, 0x14, 0x20, 0xcd, 0x94, 0x23, 0x9f, 0x69, + 0xca, 0x61, 0x7c, 0x17, 0x66, 0xf5, 0x56, 0xfb, 0xd5, 0xe4, 0xbc, 0x45, 0x2d, 0x21, 0x15, 0x2b, + 0x7c, 0x72, 0x53, 0x0f, 0xbb, 0xc8, 0x77, 0xd6, 0xef, 0x42, 0x81, 0x43, 0x85, 0x27, 0xef, 0x75, + 0xa1, 0x6a, 0xcb, 0x25, 0x78, 0x0c, 0x71, 0x75, 0x9b, 0xf1, 0xbe, 0x30, 0x51, 0x51, 0x5b, 0xb8, + 0xc6, 0xbd, 0xf6, 0x72, 0x9a, 0x63, 0x12, 0x47, 0xa4, 0x55, 0x04, 0x6f, 0xa7, 0xd3, 0x7a, 0x4d, + 0x3c, 0xb2, 0xc7, 0x9e, 0x12, 0xef, 0x6d, 0xf1, 0xc8, 0xd0, 0x8b, 0x13, 0x7f, 0x9c, 0x87, 0x85, + 0x88, 0xe1, 0x7d, 0xf5, 0xd0, 0x6a, 0xb7, 0xb1, 0x73, 0x80, 0xd1, 0x2d, 0x18, 0xda, 0xde, 0xda, + 0xae, 0x71, 0x25, 0xdc, 0x2c, 0xff, 0x9c, 0x48, 0x91, 0x84, 0x31, 0x29, 0x04, 0x7a, 0x0c, 0xe7, + 0x85, 0x7d, 0xa2, 0xac, 0xe2, 0x97, 0xa7, 0xcb, 0xd9, 0xd6, 0x8e, 0x71, 0x3c, 0xf4, 0x2e, 0xf7, + 0x12, 0xf8, 0x71, 0xd7, 0xf6, 0x70, 0x8b, 0x2a, 0x16, 0xc2, 0x37, 0x39, 0xa5, 0xc6, 0x54, 0xc1, + 0x50, 0x15, 0x86, 0xeb, 0x4d, 0xb7, 0x23, 0x36, 0x99, 0x05, 0xa5, 0x59, 0x41, 0x99, 0xd6, 0x73, + 0xc3, 0x11, 0xf2, 0xa7, 0x6a, 0x77, 0x47, 0xeb, 0xd0, 0x87, 0x00, 0xd4, 0xf9, 0xd3, 0xc4, 0x5d, + 0x1f, 0x73, 0xcb, 0x04, 0xf6, 0x6c, 0x49, 0x7d, 0x46, 0x3d, 0x52, 0xac, 0x3d, 0x5b, 0x4a, 0x60, + 0xe6, 0x41, 0x66, 0xfc, 0x4e, 0x1e, 0xe6, 0x53, 0x1c, 0x19, 0xd0, 0x3b, 0x1a, 0x3b, 0x67, 0x14, + 0x76, 0x0a, 0x90, 0xb5, 0x01, 0xce, 0xcf, 0xaa, 0x62, 0x34, 0x3a, 0x78, 0x0a, 0xa3, 0xd1, 0xb5, + 0x81, 0xd0, 0x50, 0x34, 0xe4, 0xc8, 0xd0, 0x99, 0x71, 0x64, 0xf8, 0x14, 0x1c, 0xa9, 0x00, 0x8c, + 0x8a, 0x7e, 0x19, 0xd3, 0x30, 0xa9, 0xad, 0x1b, 0xc3, 0x80, 0x09, 0x75, 0xe4, 0x64, 0x71, 0x56, + 0xdd, 0x96, 0x5c, 0x9c, 0xe4, 0x6f, 0xe3, 0x6f, 0xe4, 0x60, 0x96, 0x4e, 0xf1, 0x81, 0x4d, 0x76, + 0xcd, 0x70, 0x85, 0x2c, 0x69, 0x9c, 0x5c, 0xd4, 0x38, 0x19, 0x81, 0x95, 0x2c, 0xfd, 0x28, 0xc6, + 0xd2, 0xc5, 0x24, 0x96, 0xd2, 0xcf, 0xdb, 0x76, 0x1d, 0x95, 0x93, 0xea, 0x4b, 0xcf, 0xef, 0xe6, + 0x60, 0x46, 0xe9, 0x93, 0xec, 0xff, 0x7d, 0xad, 0x4b, 0x97, 0x12, 0xba, 0x14, 0x9b, 0xe4, 0x4a, + 0xac, 0x47, 0x6f, 0x65, 0xf5, 0x28, 0x69, 0x8e, 0x35, 0x1e, 0xff, 0xc7, 0x1c, 0xcc, 0x25, 0xf2, + 0x00, 0x5d, 0x20, 0x62, 0x71, 0xd3, 0xc3, 0x01, 0x67, 0x2f, 0xff, 0x45, 0xca, 0xd7, 0x7d, 0xbf, + 0x8b, 0x3d, 0xae, 0x58, 0xe4, 0xbf, 0xd0, 0x5b, 0x30, 0x59, 0xc3, 0x9e, 0xed, 0xb6, 0x98, 0x39, + 0x33, 0xb3, 0xc1, 0x9a, 0x34, 0xf5, 0x42, 0xb4, 0x08, 0x63, 0xe5, 0xf6, 0x81, 0xeb, 0xd9, 0xc1, + 0x21, 0x7b, 0x6c, 0x1b, 0x33, 0xc3, 0x02, 0x42, 0x7b, 0xd9, 0x3e, 0x10, 0x66, 0x85, 0x93, 0x26, + 0xff, 0x85, 0x16, 0x60, 0x44, 0x28, 0xe3, 0xa8, 0x2a, 0xcf, 0x14, 0x3f, 0x09, 0xc6, 0x17, 0x26, + 0x5d, 0x04, 0xd4, 0xb3, 0xd7, 0xe4, 0xbf, 0xd0, 0x14, 0x35, 0x48, 0xa5, 0x7e, 0xbb, 0xd4, 0x10, + 0xf5, 0x23, 0x98, 0x4d, 0xe2, 0x6b, 0xd2, 0x12, 0xe2, 0xb8, 0x79, 0x89, 0xfb, 0xff, 0xe7, 0x61, + 0xa6, 0xdc, 0x6a, 0x3d, 0x79, 0x58, 0x66, 0x2f, 0xf2, 0x62, 0x6f, 0x7c, 0x17, 0x86, 0xd6, 0x1d, + 0xfe, 0xe8, 0xac, 0x18, 0x1a, 0xc4, 0x21, 0x09, 0x14, 0x99, 0x41, 0xf2, 0x3f, 0x32, 0x61, 0x66, + 0xe5, 0xa5, 0xed, 0x07, 0xb6, 0x73, 0xa0, 0xfa, 0x35, 0xe5, 0xfb, 0xf1, 0x6b, 0x5a, 0x1b, 0x30, + 0x93, 0x90, 0xd1, 0x36, 0x5c, 0xd8, 0xc4, 0x2f, 0x12, 0x96, 0x98, 0x74, 0xf7, 0x54, 0x36, 0xc2, + 0xd8, 0xca, 0x4a, 0xc1, 0x55, 0x57, 0xf0, 0x6f, 0xe4, 0xa9, 0x37, 0xb8, 0x32, 0x30, 0xde, 0xf2, + 0x0e, 0xcc, 0x2a, 0x1d, 0x0a, 0xf7, 0x71, 0xc6, 0x93, 0x52, 0xf2, 0x70, 0xd4, 0x0f, 0x2d, 0x11, + 0x1d, 0xed, 0xc1, 0xbc, 0xde, 0xa9, 0x90, 0xb2, 0xfe, 0xb1, 0x24, 0x81, 0xac, 0x0d, 0x98, 0x69, + 0xd8, 0x68, 0x09, 0x06, 0xcb, 0xcd, 0x67, 0x9c, 0x2d, 0xc9, 0x53, 0xc6, 0x46, 0x56, 0x6e, 0x3e, + 0x5b, 0x1b, 0x30, 0x09, 0xb0, 0xf6, 0xbd, 0xfc, 0x8b, 0x1c, 0xcc, 0xa7, 0xcc, 0x30, 0xba, 0x02, + 0xc0, 0x0a, 0x95, 0x13, 0x53, 0x29, 0x21, 0x82, 0x36, 0x37, 0xe9, 0x78, 0xd5, 0x61, 0x33, 0x33, + 0x25, 0x3d, 0x27, 0xc3, 0x0a, 0x53, 0x01, 0x42, 0x35, 0x61, 0xfd, 0xc4, 0x1c, 0x38, 0xf5, 0x63, + 0x4d, 0xa9, 0xd1, 0xcc, 0x9e, 0xa2, 0x8e, 0x9b, 0x2a, 0x09, 0xae, 0x9a, 0xae, 0x46, 0x47, 0x21, + 0x07, 0x8d, 0x6e, 0xc1, 0x39, 0x56, 0xc8, 0xe7, 0x50, 0x44, 0x53, 0x08, 0x81, 0x79, 0xbd, 0xf1, + 0xb7, 0x73, 0x70, 0x81, 0x49, 0x0c, 0xb1, 0x4f, 0xe3, 0xbb, 0xda, 0xa7, 0x71, 0x4d, 0x76, 0x38, + 0x09, 0x58, 0xfb, 0x3a, 0x2a, 0xba, 0xb7, 0x5f, 0xbf, 0x5f, 0x85, 0x8a, 0xa4, 0xae, 0xdb, 0xbf, + 0x9b, 0x13, 0x9a, 0xba, 0xf8, 0xd2, 0x5d, 0x81, 0x89, 0xd7, 0x5b, 0xb2, 0x1a, 0x1a, 0x7a, 0x8f, + 0xad, 0xa8, 0x7c, 0xf6, 0x48, 0x33, 0x17, 0xd5, 0x27, 0x50, 0x4c, 0x67, 0x4d, 0xaf, 0x65, 0x65, + 0x3c, 0x4c, 0xc0, 0x7e, 0x9d, 0xe9, 0xfc, 0x8b, 0x5c, 0x8c, 0x50, 0xfd, 0x95, 0xd3, 0x14, 0x53, + 0x7a, 0x33, 0x6a, 0xaa, 0x9f, 0x6a, 0xfe, 0xac, 0x76, 0x37, 0x1f, 0xbe, 0x09, 0xf1, 0xd5, 0x49, + 0xa5, 0x76, 0xf5, 0xb3, 0xe8, 0x26, 0x6f, 0x88, 0x83, 0x7d, 0x39, 0x7a, 0xd2, 0x38, 0x14, 0x98, + 0xa3, 0x37, 0x52, 0x3c, 0x3e, 0x93, 0xe8, 0x1b, 0xbf, 0x39, 0xa8, 0x7f, 0x03, 0xaf, 0x33, 0xd6, + 0x1a, 0x8c, 0x57, 0x5d, 0x27, 0xc0, 0x2f, 0x03, 0x25, 0xca, 0x00, 0x92, 0x26, 0x28, 0xb2, 0x86, + 0xdf, 0x17, 0x59, 0x41, 0x83, 0x5c, 0x5e, 0x34, 0x73, 0xbd, 0x10, 0x10, 0x55, 0x61, 0x72, 0x13, + 0xbf, 0x88, 0x31, 0x90, 0x9a, 0x0c, 0x3a, 0xf8, 0x45, 0x43, 0x61, 0xa2, 0x6a, 0x96, 0xa8, 0xe1, + 0xa0, 0x7d, 0x98, 0x12, 0xfb, 0x5f, 0xbf, 0xc7, 0x00, 0xf3, 0xc3, 0x27, 0x2d, 0xa4, 0xf0, 0x30, + 0x42, 0xf1, 0xec, 0x77, 0x26, 0xa3, 0x06, 0x0b, 0xf1, 0xf9, 0xe0, 0xad, 0xbd, 0xdb, 0x6b, 0x15, + 0x33, 0xe5, 0x5c, 0x4b, 0x5f, 0xd1, 0x6b, 0x54, 0x61, 0x2a, 0x61, 0xa4, 0x06, 0xec, 0x5e, 0x74, + 0x7a, 0xa9, 0xad, 0xab, 0x98, 0x5e, 0xd5, 0xb6, 0x4b, 0xb8, 0xa0, 0x54, 0xa9, 0xce, 0x59, 0xa5, + 0xc4, 0x3b, 0x76, 0x1b, 0x46, 0x78, 0x51, 0x24, 0xf8, 0x4c, 0xf8, 0x7d, 0x09, 0x00, 0xe3, 0xf7, + 0x72, 0x70, 0x91, 0x6a, 0xc0, 0x6d, 0xe7, 0xa0, 0x8d, 0x77, 0x7c, 0xdd, 0x8b, 0xe4, 0x3b, 0xda, + 0x96, 0x39, 0x9f, 0xe2, 0x06, 0xfc, 0x4d, 0x6d, 0x94, 0x7f, 0x90, 0x83, 0x62, 0x52, 0xdf, 0xce, + 0x76, 0xaf, 0xbc, 0xc3, 0xd5, 0x0b, 0x79, 0xcd, 0xea, 0x53, 0xb6, 0x29, 0x06, 0x4b, 0x06, 0x49, + 0xfe, 0xd7, 0x36, 0xc9, 0xff, 0x96, 0x83, 0xd9, 0x75, 0x5f, 0xbd, 0xca, 0x71, 0xc6, 0xdd, 0x49, + 0x0a, 0xe5, 0x40, 0xe7, 0x75, 0x6d, 0x20, 0x29, 0x54, 0xc3, 0xbb, 0x8a, 0xd3, 0x6c, 0x3e, 0x2b, + 0x46, 0x03, 0x11, 0x9a, 0xa5, 0xf3, 0xef, 0x4d, 0x18, 0xda, 0x24, 0x82, 0xe2, 0x20, 0x5f, 0x7f, + 0x0c, 0x83, 0x14, 0x51, 0xff, 0x56, 0xd2, 0x65, 0xf2, 0x03, 0x3d, 0x8c, 0x79, 0xd1, 0x0e, 0xf5, + 0x8e, 0x41, 0xb0, 0x36, 0x10, 0x75, 0xa8, 0xad, 0x8c, 0xc2, 0xb9, 0x6d, 0xcb, 0x3b, 0xc0, 0x81, + 0xf1, 0x7d, 0x28, 0x72, 0x13, 0x31, 0xf6, 0xa6, 0x40, 0x0d, 0xc9, 0xfc, 0xd0, 0x0a, 0x30, 0xcb, + 0xac, 0xeb, 0x0a, 0x00, 0xf5, 0xd8, 0x5a, 0x77, 0x5a, 0xf8, 0x25, 0xb3, 0x43, 0x34, 0x95, 0x12, + 0xe3, 0x3d, 0x18, 0x93, 0x43, 0xa0, 0x77, 0x7d, 0x45, 0x16, 0xa6, 0xc3, 0x99, 0xd5, 0xfc, 0x7a, + 0x85, 0x33, 0xaf, 0x0d, 0x73, 0x91, 0xa9, 0x08, 0xdd, 0xe9, 0xe5, 0x1d, 0x9c, 0x5a, 0x4d, 0x9a, + 0xf2, 0x77, 0xf4, 0x8a, 0x9e, 0xef, 0xeb, 0x8a, 0x6e, 0x54, 0xe1, 0x7c, 0x6c, 0x7d, 0x20, 0x44, + 0x3d, 0xd9, 0x99, 0x96, 0x8a, 0x1c, 0xa8, 0xf5, 0xfa, 0x1a, 0x29, 0xdb, 0xde, 0xa8, 0x33, 0xf7, + 0x2a, 0x52, 0xb6, 0xbd, 0x51, 0xaf, 0x9c, 0x63, 0xeb, 0xcd, 0xf8, 0x47, 0x79, 0xaa, 0xbc, 0x89, + 0x71, 0x2e, 0xa2, 0x07, 0x57, 0x75, 0xf1, 0x15, 0x18, 0xa3, 0x7c, 0x5a, 0x16, 0xfe, 0x8a, 0xd9, + 0xb6, 0x50, 0xa3, 0x3f, 0x3d, 0x2e, 0x0d, 0x50, 0x03, 0xa8, 0x10, 0x0d, 0x7d, 0x06, 0x23, 0x2b, + 0x4e, 0x8b, 0x52, 0x18, 0x3c, 0x05, 0x05, 0x81, 0x44, 0x66, 0x8f, 0x76, 0x99, 0x88, 0x82, 0x5c, + 0x7d, 0x6a, 0x2a, 0x25, 0x74, 0x72, 0xa8, 0x81, 0xe9, 0x30, 0x9d, 0x58, 0xf6, 0x83, 0x86, 0x34, + 0x20, 0x5d, 0x10, 0x61, 0x92, 0xc6, 0x4c, 0xf9, 0x1b, 0x19, 0x30, 0xbc, 0xe5, 0xb5, 0x78, 0xa8, + 0x93, 0xa9, 0xa5, 0x09, 0xce, 0x7d, 0x5a, 0x66, 0xb2, 0x2a, 0xe3, 0xbf, 0xe4, 0x60, 0x7e, 0x15, + 0x07, 0x89, 0xab, 0x4d, 0xe3, 0x4a, 0xee, 0x8d, 0xb9, 0x92, 0x7f, 0x1d, 0xae, 0xc8, 0x51, 0x0f, + 0xa6, 0x8d, 0x7a, 0x28, 0x6d, 0xd4, 0xc3, 0xe9, 0xa3, 0x5e, 0x85, 0x73, 0x6c, 0xa8, 0xe8, 0x3a, + 0x0c, 0xaf, 0x07, 0xf8, 0x28, 0x54, 0xea, 0xa9, 0x96, 0x9c, 0x26, 0xab, 0x23, 0x37, 0xd2, 0x0d, + 0xcb, 0x0f, 0x84, 0x43, 0xdf, 0x98, 0x29, 0x7e, 0x1a, 0x3f, 0xa2, 0x9e, 0xce, 0x1b, 0x6e, 0xf3, + 0x99, 0xf2, 0xe2, 0x32, 0xc2, 0xbe, 0xe5, 0xe8, 0x0b, 0x1d, 0x81, 0x62, 0x35, 0xa6, 0x80, 0x40, + 0x57, 0x61, 0x7c, 0xdd, 0x79, 0xe8, 0x7a, 0x4d, 0xbc, 0xe5, 0xb4, 0x19, 0xf5, 0x51, 0x53, 0x2d, + 0xe2, 0x9a, 0x48, 0xde, 0x42, 0xa8, 0x89, 0xa4, 0x05, 0x11, 0x4d, 0x24, 0x29, 0xdb, 0x5d, 0x32, + 0x59, 0x1d, 0x57, 0x74, 0x92, 0xbf, 0xb3, 0xd4, 0x7b, 0x52, 0x0f, 0xd8, 0x0b, 0x70, 0x1f, 0x2e, + 0x9a, 0xb8, 0xd3, 0xb6, 0x88, 0xc0, 0x79, 0xe4, 0x32, 0x78, 0x39, 0xe6, 0xab, 0x09, 0x1e, 0x60, + 0xba, 0x5d, 0x8f, 0xec, 0x72, 0x3e, 0xa3, 0xcb, 0x47, 0x70, 0x6d, 0x15, 0x07, 0xfa, 0xde, 0x18, + 0xbe, 0xe7, 0xf0, 0xc1, 0xaf, 0xc1, 0xa8, 0xaf, 0xbf, 0x45, 0x5d, 0x11, 0x4f, 0xa0, 0x49, 0x88, + 0xbb, 0x0f, 0xc4, 0x6b, 0x2d, 0xa7, 0x23, 0xff, 0x32, 0x3e, 0x87, 0x52, 0x5a, 0x73, 0xfd, 0x99, + 0x5d, 0xdb, 0x70, 0x35, 0x9d, 0x80, 0x3c, 0x4c, 0xc5, 0xbb, 0x95, 0x54, 0x1d, 0x64, 0xf7, 0x56, + 0x7f, 0xea, 0xe2, 0x7f, 0x18, 0x15, 0x61, 0x80, 0xfa, 0x06, 0xdd, 0x6d, 0x50, 0x93, 0x10, 0x9d, + 0x40, 0xc8, 0xd7, 0x32, 0x8c, 0x8a, 0x32, 0xce, 0xd7, 0xf9, 0xc4, 0x9e, 0x0a, 0x86, 0xb6, 0x04, + 0x01, 0x89, 0x66, 0xfc, 0x48, 0x3c, 0x8f, 0xea, 0x18, 0xfd, 0xb9, 0xb5, 0xf6, 0xf3, 0x1e, 0x6a, + 0xb8, 0x70, 0x51, 0xa7, 0xad, 0x3e, 0x7b, 0x15, 0x94, 0x67, 0x2f, 0xf6, 0xda, 0x75, 0x55, 0x7f, + 0x86, 0xc9, 0xf3, 0x75, 0x19, 0x16, 0xa1, 0x2b, 0xea, 0xe3, 0xd6, 0x44, 0xdc, 0x0f, 0xf8, 0x1e, + 0x14, 0x93, 0x1a, 0x54, 0x14, 0x4a, 0xf2, 0x05, 0x85, 0xc7, 0xfa, 0xfa, 0xb5, 0x1c, 0x18, 0x9a, + 0x95, 0x1f, 0x9d, 0xa1, 0x9a, 0xe7, 0x3e, 0xb7, 0x5b, 0xca, 0xc3, 0xec, 0x3b, 0x62, 0x63, 0x63, + 0x5e, 0x0c, 0x54, 0xc3, 0x1a, 0x75, 0x0f, 0xe0, 0xbb, 0xdd, 0x3d, 0x18, 0xd9, 0xc4, 0x2f, 0xc3, + 0xed, 0x87, 0x49, 0xb0, 0xd4, 0xf2, 0xef, 0x19, 0x56, 0xa3, 0x48, 0x08, 0x30, 0x22, 0x3e, 0x5d, + 0xcf, 0xec, 0x03, 0xef, 0xff, 0x3e, 0x14, 0xa2, 0x75, 0x7c, 0xee, 0x4b, 0x8a, 0x45, 0x53, 0x9c, + 0xc2, 0xee, 0x7d, 0xe6, 0x20, 0x21, 0xac, 0xe3, 0x3a, 0x92, 0x72, 0x8c, 0xde, 0xe9, 0x7b, 0x8f, + 0x3e, 0x04, 0xd8, 0x76, 0x03, 0xab, 0x5d, 0xa5, 0x3a, 0xc0, 0xc1, 0xd0, 0x9f, 0x24, 0x20, 0xa5, + 0x8d, 0x68, 0xb8, 0x0b, 0x05, 0xd8, 0xf8, 0x1e, 0xfd, 0x22, 0x93, 0x3b, 0xdd, 0xdf, 0x47, 0x52, + 0x85, 0xeb, 0x11, 0xab, 0x9a, 0xd7, 0x20, 0x12, 0xc0, 0x1c, 0x61, 0x3f, 0x11, 0x61, 0x56, 0x3d, + 0xb7, 0xdb, 0xf9, 0xc5, 0xcc, 0xfa, 0xbf, 0xce, 0x31, 0x53, 0x60, 0xb5, 0x59, 0x3e, 0xd1, 0x55, + 0x80, 0xb0, 0x34, 0xe2, 0x12, 0x22, 0x2b, 0x76, 0xef, 0xb3, 0xbb, 0x3b, 0x7d, 0x6f, 0x3b, 0x60, + 0x04, 0x14, 0xb4, 0x5f, 0xec, 0x4c, 0x3e, 0xa0, 0xa6, 0x34, 0xb2, 0xf5, 0xfe, 0xf8, 0xfe, 0xbe, + 0xd0, 0x51, 0x9d, 0x12, 0xef, 0x10, 0x66, 0xc9, 0xb7, 0x4b, 0xee, 0x35, 0xae, 0x67, 0x07, 0xc2, + 0x35, 0x09, 0xd5, 0x78, 0x28, 0x01, 0x86, 0xf5, 0xc9, 0xcf, 0x8f, 0x4b, 0x1f, 0x9c, 0xc6, 0x2f, + 0x5b, 0xd0, 0xdc, 0x96, 0xe1, 0x07, 0x8c, 0x79, 0x18, 0xac, 0x9a, 0x1b, 0x74, 0xab, 0x32, 0x37, + 0xe4, 0x56, 0x65, 0x6e, 0x18, 0xff, 0x39, 0x0f, 0x25, 0x16, 0xec, 0x84, 0x5a, 0x60, 0x85, 0x37, + 0x2c, 0xc5, 0xa4, 0xab, 0x5f, 0x4d, 0x45, 0x24, 0x98, 0x49, 0xbe, 0x9f, 0x60, 0x26, 0xbf, 0xfc, + 0xfa, 0x5a, 0xe5, 0xca, 0xdb, 0x27, 0xc7, 0xa5, 0xeb, 0xa1, 0x3a, 0x81, 0xd5, 0x26, 0xe9, 0x15, + 0x52, 0x9a, 0x88, 0x2b, 0x42, 0x86, 0x5e, 0x43, 0x11, 0x72, 0x0f, 0x46, 0xe8, 0x85, 0x65, 0xbd, + 0xc6, 0xed, 0x86, 0xe9, 0xf2, 0xa4, 0x71, 0x89, 0x1a, 0xb6, 0x1a, 0xd7, 0x4d, 0x80, 0x19, 0x7f, + 0x33, 0x0f, 0x57, 0xd3, 0x79, 0xce, 0xfb, 0xb6, 0x0c, 0x10, 0xda, 0x7e, 0x65, 0xd9, 0x9a, 0xd1, + 0x6f, 0xe7, 0x05, 0xde, 0x97, 0xb6, 0x9e, 0x0a, 0x1e, 0x91, 0x5a, 0x84, 0xcf, 0x6e, 0xe4, 0xb5, + 0x54, 0x73, 0xe5, 0xe5, 0x61, 0x43, 0x79, 0x91, 0x16, 0x36, 0x94, 0x97, 0xa1, 0x7d, 0x98, 0xaf, + 0x79, 0xf6, 0x73, 0x2b, 0xc0, 0x8f, 0xf1, 0xab, 0x9a, 0xdb, 0xb6, 0x9b, 0xaf, 0x56, 0xb8, 0xeb, + 0x1a, 0x73, 0xc4, 0xbe, 0x75, 0x72, 0x5c, 0x7a, 0xab, 0xc3, 0x40, 0xc8, 0x87, 0xd9, 0xe8, 0x50, + 0xa0, 0x46, 0xdc, 0x9b, 0x2d, 0x8d, 0x90, 0xf1, 0xaf, 0x72, 0x70, 0x89, 0x0a, 0xd4, 0xfc, 0xe5, + 0x45, 0x34, 0xfe, 0x5a, 0x26, 0xc7, 0xea, 0x00, 0xf9, 0x5a, 0xa4, 0x26, 0xc7, 0x9a, 0x4f, 0xb3, + 0xa9, 0x81, 0xa1, 0x75, 0x18, 0xe7, 0xbf, 0x15, 0xf5, 0xf9, 0x9c, 0xb2, 0x61, 0xd1, 0xa5, 0xce, + 0x74, 0x4e, 0x74, 0x61, 0x73, 0x62, 0xd4, 0xf1, 0xd2, 0x54, 0x71, 0x8d, 0x9f, 0xe5, 0x61, 0x71, + 0x17, 0x7b, 0xf6, 0xd3, 0x57, 0x29, 0x83, 0xd9, 0x82, 0x59, 0x51, 0xc4, 0x02, 0x9e, 0x68, 0x9f, + 0x18, 0x0b, 0x4c, 0x28, 0xba, 0xca, 0x23, 0xa6, 0x88, 0x2f, 0x2e, 0x11, 0xf1, 0x14, 0xc6, 0xc4, + 0xef, 0xc2, 0x68, 0x24, 0xe4, 0x10, 0x9d, 0x7f, 0xf1, 0x85, 0x86, 0x53, 0xb5, 0x36, 0x60, 0x4a, + 0x48, 0xf4, 0xeb, 0xb9, 0xd4, 0x27, 0x64, 0xae, 0x7f, 0xe8, 0xa5, 0x48, 0xa5, 0x1f, 0x2c, 0xf9, + 0x58, 0x2d, 0xa5, 0x36, 0xe1, 0x83, 0x5d, 0x1b, 0x30, 0xd3, 0x5a, 0xaa, 0x8c, 0xc3, 0x58, 0x99, + 0x3e, 0xcb, 0x93, 0x8b, 0xfb, 0x7f, 0xcd, 0xc3, 0x15, 0xe1, 0x36, 0x96, 0xc2, 0xe6, 0x2f, 0x61, + 0x5e, 0x14, 0x95, 0x3b, 0x44, 0x60, 0xc0, 0x2d, 0x9d, 0xd3, 0x2c, 0x38, 0xa8, 0xe0, 0xb4, 0xc5, + 0x61, 0x42, 0x66, 0xa7, 0xa1, 0x9f, 0x8d, 0x1a, 0xf5, 0xb3, 0xa4, 0x00, 0x50, 0x54, 0x9d, 0xa9, + 0xee, 0x99, 0x1a, 0x6b, 0xb4, 0xfd, 0xb3, 0x15, 0x53, 0xc3, 0x0e, 0xbd, 0xa9, 0x1a, 0x76, 0x6d, + 0x20, 0xaa, 0x88, 0xad, 0x4c, 0xc1, 0xc4, 0x26, 0x7e, 0x11, 0xf2, 0xfd, 0xaf, 0xe4, 0x22, 0x41, + 0x03, 0x88, 0x84, 0xc1, 0xa2, 0x07, 0xe4, 0xc2, 0x18, 0x42, 0x34, 0x68, 0x80, 0x2a, 0x61, 0x30, + 0xd0, 0x75, 0x18, 0x61, 0xb6, 0x2a, 0xad, 0x3e, 0xee, 0xe6, 0xd2, 0xff, 0x8b, 0xb9, 0xd4, 0xb6, + 0xd8, 0x35, 0x9d, 0xe3, 0x1b, 0x8f, 0xe1, 0x1a, 0xf7, 0x7e, 0xd0, 0x27, 0x9f, 0x36, 0x74, 0xca, + 0xe3, 0xcb, 0xb0, 0xe0, 0xca, 0x2a, 0x8e, 0x6e, 0x3d, 0x9a, 0x7f, 0xdc, 0xe7, 0x30, 0xad, 0x95, + 0x4b, 0x8a, 0x54, 0x2a, 0x95, 0x6b, 0x48, 0x92, 0x8e, 0x42, 0x1b, 0x57, 0x93, 0x9a, 0x50, 0x3b, + 0x6b, 0x60, 0x1a, 0xe5, 0xd3, 0x0b, 0x5f, 0xd9, 0xfd, 0x53, 0xec, 0x7a, 0xb7, 0x94, 0xef, 0x9a, + 0xed, 0x78, 0x2c, 0x10, 0xa0, 0x38, 0x79, 0x65, 0xad, 0x31, 0xa9, 0x3d, 0x2a, 0x18, 0x53, 0x30, + 0x21, 0xaa, 0xda, 0xd8, 0xf7, 0x8d, 0xdf, 0x18, 0x06, 0x83, 0x33, 0x36, 0x49, 0xe7, 0x2a, 0xf8, + 0xb1, 0x1f, 0xeb, 0x2c, 0x3f, 0xa8, 0x2e, 0xa8, 0x9a, 0xe5, 0xb0, 0x96, 0xad, 0x3c, 0x2a, 0xe7, + 0x35, 0xc3, 0x52, 0x6d, 0xe5, 0xc5, 0x46, 0xff, 0x83, 0x94, 0x6d, 0x92, 0x7d, 0x6c, 0x37, 0x4e, + 0x8e, 0x4b, 0xd7, 0x52, 0xb6, 0x49, 0x8d, 0x6e, 0xf2, 0x96, 0x69, 0xea, 0x6f, 0x2b, 0x83, 0xaf, + 0xf3, 0xb6, 0x42, 0xbe, 0x48, 0xf5, 0x75, 0x65, 0x47, 0xe7, 0x25, 0xff, 0x1e, 0x85, 0x55, 0x8d, + 0x5a, 0xc5, 0x7d, 0xf7, 0x95, 0x12, 0x8d, 0xaa, 0x46, 0x06, 0xd9, 0x50, 0x50, 0x54, 0x96, 0xd5, + 0x43, 0xdc, 0x7c, 0xc6, 0xdf, 0x82, 0xc4, 0x33, 0x75, 0x92, 0xe2, 0x9a, 0x05, 0x1a, 0x66, 0xdf, + 0x39, 0xab, 0x68, 0x34, 0x09, 0xaa, 0x1a, 0x7b, 0x20, 0x4a, 0x36, 0xb4, 0xcf, 0x39, 0x77, 0x66, + 0xf6, 0x39, 0x23, 0xa7, 0xb1, 0xcf, 0x51, 0x9e, 0x0c, 0x7e, 0x5b, 0xba, 0xdb, 0x10, 0x99, 0xc1, + 0x6e, 0x63, 0xee, 0x5b, 0x26, 0x56, 0x60, 0xca, 0xbb, 0x5e, 0xee, 0x1b, 0x7e, 0xd7, 0xfb, 0xc3, + 0xbc, 0x70, 0x32, 0x8a, 0xbd, 0xfe, 0x9f, 0xfe, 0x79, 0x2f, 0x71, 0x04, 0x7d, 0x1d, 0xa8, 0xc9, + 0x86, 0x1a, 0x15, 0xcd, 0x04, 0x20, 0x9f, 0x62, 0x02, 0xa0, 0xbd, 0x97, 0x06, 0x3d, 0x6c, 0x02, + 0x06, 0xdf, 0xfc, 0xe5, 0xed, 0x9f, 0x8e, 0xc0, 0xf9, 0x9a, 0x75, 0x60, 0x3b, 0x64, 0xe3, 0x36, + 0xb1, 0xef, 0x76, 0xbd, 0x26, 0x46, 0x65, 0x98, 0xd2, 0x2d, 0xc8, 0x7b, 0xd8, 0xc7, 0x93, 0xb3, + 0x49, 0x2f, 0x43, 0x4b, 0x30, 0x26, 0x3d, 0xbb, 0xf9, 0x81, 0x92, 0xe0, 0xf1, 0xbd, 0x36, 0x60, + 0x86, 0x60, 0xe8, 0x43, 0xed, 0xa1, 0x65, 0x5a, 0x06, 0x29, 0xa0, 0xb0, 0x4b, 0xcc, 0xc4, 0xd7, + 0x71, 0x5b, 0xfa, 0xa1, 0xc8, 0x1e, 0x2b, 0x7e, 0x14, 0x7b, 0x7b, 0x19, 0xd6, 0x7a, 0x1c, 0xd3, + 0x5a, 0x51, 0x79, 0x20, 0x35, 0xda, 0x73, 0xfc, 0x55, 0x06, 0x7d, 0x1f, 0xc6, 0x1f, 0x77, 0xf7, + 0xb1, 0x78, 0x65, 0x3a, 0xc7, 0xcf, 0xc8, 0xa8, 0x5f, 0x04, 0xaf, 0xdf, 0x7d, 0xc0, 0xe6, 0xe0, + 0x59, 0x77, 0x1f, 0xc7, 0xc3, 0x88, 0x93, 0xcd, 0x49, 0x21, 0x86, 0x0e, 0xa1, 0x10, 0x75, 0x61, + 0xe0, 0x01, 0xfc, 0x32, 0x1c, 0x2f, 0x68, 0xf8, 0x12, 0x25, 0x58, 0x39, 0x33, 0xac, 0xd6, 0x1a, + 0x89, 0x51, 0x45, 0xbf, 0x02, 0x73, 0x89, 0x3a, 0x43, 0x1e, 0xb2, 0xbc, 0x97, 0x3a, 0x92, 0x6e, + 0xec, 0x11, 0xae, 0x09, 0xaf, 0x48, 0xad, 0xe5, 0xe4, 0x56, 0x50, 0x0b, 0xa6, 0x23, 0xa6, 0xf9, + 0x3c, 0x63, 0x42, 0xba, 0xb1, 0x3f, 0x3d, 0x9c, 0x44, 0x58, 0xdb, 0xc4, 0xb6, 0xa2, 0x24, 0xd1, + 0x06, 0x8c, 0xc9, 0x2b, 0x3f, 0x0d, 0xb2, 0x94, 0xac, 0xde, 0x58, 0x38, 0x39, 0x2e, 0xcd, 0x86, + 0xea, 0x0d, 0x8d, 0x66, 0x48, 0x00, 0xfd, 0x04, 0xae, 0xc9, 0x25, 0xba, 0xe5, 0x25, 0x2b, 0x82, + 0x78, 0x30, 0xf4, 0xdb, 0xd1, 0x15, 0x9e, 0x06, 0xbf, 0x7b, 0x7f, 0x6d, 0xc0, 0xec, 0x4d, 0xb6, + 0x02, 0x30, 0xea, 0xf1, 0x8f, 0xf2, 0xd1, 0xd0, 0xe8, 0x50, 0x61, 0x98, 0xad, 0x1b, 0xe1, 0xf2, + 0xf0, 0xdf, 0xcf, 0x31, 0x1f, 0xe2, 0x1d, 0xc7, 0x7e, 0x6a, 0x87, 0xdf, 0xaf, 0xaa, 0x60, 0x0a, + 0xb3, 0xa3, 0x70, 0xf1, 0x2f, 0x25, 0x0f, 0x8a, 0xd4, 0x45, 0xe5, 0x7b, 0xea, 0xa2, 0x1e, 0x28, + 0xef, 0x2d, 0x4a, 0x50, 0x4e, 0x76, 0xcc, 0xeb, 0xba, 0x9f, 0xf0, 0x21, 0xe6, 0x6b, 0x38, 0x47, + 0xc3, 0x03, 0xb2, 0xc7, 0xac, 0xf1, 0xa5, 0x3b, 0x7c, 0xd7, 0xca, 0xe8, 0x3e, 0x8b, 0x27, 0xc8, + 0xe3, 0x02, 0xd0, 0x18, 0x9e, 0x6d, 0x5a, 0xa0, 0x06, 0x03, 0x64, 0x20, 0x68, 0x1b, 0x66, 0x6a, + 0x1e, 0x6e, 0x71, 0xc3, 0xfb, 0x8e, 0xc7, 0xef, 0xe7, 0xec, 0xe6, 0x4f, 0x63, 0xa7, 0x77, 0x44, + 0x75, 0x03, 0xcb, 0x7a, 0xf5, 0x3c, 0x49, 0x40, 0x47, 0x2b, 0x30, 0x55, 0xc7, 0x96, 0xd7, 0x3c, + 0x7c, 0x8c, 0x5f, 0x91, 0x13, 0x5f, 0x4b, 0x38, 0xe0, 0xd3, 0x1a, 0x32, 0x5e, 0x5a, 0xa5, 0xda, + 0x4b, 0xe8, 0x48, 0xe8, 0x7b, 0x70, 0xae, 0xee, 0x7a, 0x41, 0xe5, 0x15, 0xff, 0xa6, 0xc5, 0x73, + 0x07, 0x2b, 0xac, 0x5c, 0x14, 0x49, 0x17, 0x7c, 0xd7, 0x0b, 0x1a, 0xfb, 0x2a, 0xfb, 0x38, 0x1e, + 0x7a, 0x05, 0xb3, 0xfa, 0xf7, 0xf4, 0xd0, 0x6e, 0x93, 0x4d, 0x68, 0x94, 0x4b, 0x1a, 0x49, 0x1f, + 0x2d, 0x03, 0xa9, 0xdc, 0xe2, 0xd4, 0xaf, 0x46, 0xbf, 0xda, 0xa7, 0xb4, 0x5e, 0x4d, 0xd9, 0x92, + 0x84, 0x8f, 0x9e, 0xd0, 0x5c, 0x15, 0x6c, 0x44, 0x65, 0x9f, 0x99, 0xbc, 0x8f, 0x85, 0x21, 0xa4, + 0xba, 0xf4, 0x9b, 0xa4, 0x9c, 0xb0, 0xfc, 0x68, 0x0a, 0x12, 0x33, 0x86, 0x8a, 0x6a, 0x70, 0x7e, + 0xc7, 0xc7, 0x35, 0x0f, 0x3f, 0xb7, 0xf1, 0x0b, 0x41, 0x8f, 0xc5, 0x41, 0xa3, 0xd3, 0x44, 0xe8, + 0x75, 0x58, 0x6d, 0x12, 0xc1, 0x38, 0x32, 0x91, 0x68, 0x6a, 0xb6, 0xe3, 0xe0, 0x16, 0x7d, 0x33, + 0x1b, 0x0f, 0x25, 0x9a, 0x0e, 0x2d, 0x6d, 0xb8, 0x4e, 0x5b, 0x65, 0xa9, 0x02, 0x5c, 0xfc, 0x10, + 0xc6, 0x95, 0x25, 0x96, 0x10, 0x57, 0x62, 0x56, 0x8d, 0x2b, 0x31, 0xa6, 0xc6, 0x8f, 0xf8, 0x3b, + 0x39, 0x58, 0x4c, 0x5e, 0xba, 0xfc, 0xb8, 0xdf, 0x82, 0x31, 0x59, 0x28, 0xbd, 0xa4, 0x84, 0xb0, + 0x19, 0x39, 0x6f, 0xd9, 0xf7, 0x23, 0x3e, 0x74, 0x75, 0xbc, 0x21, 0x8d, 0xd7, 0xd0, 0x00, 0xff, + 0xf3, 0x11, 0x98, 0x25, 0x7d, 0x8c, 0x6d, 0x0b, 0x9f, 0xd3, 0xf8, 0x30, 0xb4, 0x4c, 0x51, 0x68, + 0x72, 0xdd, 0x06, 0x2b, 0x8f, 0xc6, 0xac, 0xd2, 0x10, 0xd0, 0x7b, 0xea, 0xfb, 0x79, 0x5e, 0x49, + 0x46, 0x21, 0x0a, 0xd5, 0x21, 0x84, 0x0f, 0xeb, 0xef, 0x68, 0xcf, 0xb7, 0x7d, 0xef, 0x31, 0x43, + 0xfd, 0xee, 0x31, 0x3b, 0x72, 0x8f, 0x61, 0x71, 0x47, 0xde, 0x56, 0xf6, 0x98, 0xb3, 0xdf, 0x5c, + 0xce, 0x9d, 0xf5, 0xe6, 0x32, 0xf2, 0x66, 0x9b, 0xcb, 0xe8, 0x6b, 0x6e, 0x2e, 0x0f, 0x61, 0x6a, + 0x13, 0xe3, 0x96, 0xa2, 0x9a, 0x67, 0xdf, 0x37, 0xd7, 0x47, 0x50, 0xa5, 0x4b, 0x92, 0x7e, 0x3e, + 0x82, 0x95, 0xba, 0x49, 0xc1, 0xff, 0x99, 0x4d, 0x6a, 0xfc, 0x8c, 0x37, 0xa9, 0x89, 0x37, 0xd8, + 0xa4, 0xde, 0x64, 0xa7, 0xf9, 0x8c, 0x5a, 0xb2, 0xd5, 0xeb, 0x6b, 0xdc, 0x4a, 0x40, 0x79, 0x96, + 0x5f, 0x73, 0x7d, 0x61, 0xa2, 0x4f, 0xff, 0x26, 0x65, 0x35, 0xd7, 0x13, 0x4f, 0x9b, 0xf4, 0x6f, + 0xa3, 0x42, 0xed, 0xd7, 0x54, 0x7c, 0xe9, 0x5f, 0x32, 0xc2, 0xdd, 0x43, 0xf9, 0xfe, 0x14, 0x15, + 0xb8, 0x4d, 0x51, 0x6f, 0xfc, 0xdb, 0x1c, 0x7b, 0xc2, 0xfa, 0xbf, 0x71, 0x9b, 0x7b, 0x93, 0x67, + 0xa5, 0x5f, 0x0f, 0xc3, 0x46, 0xf0, 0x10, 0x17, 0x9e, 0xd5, 0x7c, 0x16, 0xbe, 0xeb, 0xfd, 0x90, + 0x7c, 0xa3, 0x6a, 0x05, 0x8d, 0xa8, 0x19, 0xde, 0x2a, 0xf4, 0xca, 0xdd, 0xfb, 0xe2, 0xe3, 0xe5, + 0xd1, 0x33, 0x58, 0xb1, 0xfe, 0xf1, 0xaa, 0x08, 0xd4, 0x09, 0x68, 0xda, 0x30, 0x59, 0xd4, 0x83, + 0xc4, 0x1e, 0xbc, 0x1f, 0xf7, 0xdb, 0xa7, 0x62, 0x6b, 0xe8, 0xb7, 0xaf, 0xb2, 0x31, 0xf4, 0xe0, + 0xdf, 0x81, 0x4b, 0x26, 0x3e, 0x72, 0x9f, 0xe3, 0xb3, 0x25, 0xfb, 0x03, 0xb8, 0xa8, 0x13, 0x64, + 0x6e, 0x6a, 0x2c, 0x5a, 0xfb, 0x67, 0xc9, 0x31, 0xde, 0x39, 0x02, 0x8b, 0xf1, 0xce, 0x74, 0x13, + 0xe4, 0x4f, 0x4d, 0x37, 0x41, 0x0a, 0x0c, 0x17, 0x16, 0x75, 0xe2, 0xe5, 0x56, 0x8b, 0xa6, 0xd5, + 0x6b, 0xda, 0x1d, 0xcb, 0x09, 0xd0, 0x16, 0x8c, 0x2b, 0x3f, 0x23, 0x97, 0x4a, 0xa5, 0x86, 0x1f, + 0xff, 0x61, 0x81, 0x16, 0x7b, 0x31, 0x2c, 0x36, 0x30, 0x94, 0xa2, 0xec, 0x21, 0x2c, 0x53, 0xdb, + 0xac, 0xc0, 0xa4, 0xf2, 0x53, 0x2a, 0xb8, 0x68, 0xa8, 0x50, 0xa5, 0x05, 0x9d, 0x61, 0x3a, 0x8a, + 0xd1, 0x84, 0x62, 0x12, 0xd3, 0x68, 0xb4, 0xac, 0x57, 0x68, 0x25, 0x8c, 0xbb, 0xd5, 0xdb, 0xaa, + 0x6a, 0x3a, 0x2d, 0xe6, 0x96, 0xf1, 0xd7, 0x87, 0xe0, 0x12, 0x9f, 0x8c, 0xb3, 0x9c, 0x71, 0xf4, + 0x23, 0x18, 0x57, 0xe6, 0x98, 0x33, 0xfd, 0xaa, 0x30, 0xdf, 0x4c, 0x5b, 0x0b, 0xec, 0xf2, 0xdb, + 0xa5, 0x05, 0x8d, 0xc8, 0x74, 0x93, 0xcb, 0xaf, 0xba, 0x6c, 0xda, 0x30, 0xa5, 0x4f, 0x34, 0xbf, + 0xff, 0x5f, 0x4f, 0x6c, 0x44, 0x07, 0x15, 0x11, 0x7c, 0x5b, 0x8d, 0xc4, 0xe9, 0x26, 0xd7, 0xf8, + 0xc8, 0x22, 0x7a, 0x09, 0xe7, 0x63, 0xb3, 0xcc, 0xd5, 0x3a, 0x37, 0x13, 0x1b, 0x8c, 0x41, 0x33, + 0xe5, 0x9d, 0x47, 0x8b, 0x53, 0x9b, 0x8d, 0x37, 0x82, 0x5a, 0x30, 0xa1, 0x4e, 0x3c, 0x57, 0x50, + 0x5c, 0xcb, 0x60, 0x25, 0x03, 0x64, 0x82, 0x19, 0xe7, 0x25, 0x9d, 0xfb, 0x57, 0xba, 0x42, 0x52, + 0x03, 0x1e, 0x85, 0x73, 0xec, 0x37, 0xd9, 0x02, 0x6a, 0x1e, 0xf6, 0xb1, 0xd3, 0xc4, 0xaa, 0x25, + 0xee, 0x9b, 0x6e, 0x01, 0xff, 0x32, 0x07, 0x0b, 0x49, 0x74, 0xeb, 0xd8, 0x69, 0xa1, 0x1a, 0x14, + 0xa2, 0x0d, 0xf1, 0x55, 0x6d, 0xc8, 0x20, 0xa9, 0xa9, 0x5d, 0x5a, 0x1b, 0x30, 0x63, 0xd8, 0x68, + 0x13, 0xce, 0x2b, 0x65, 0xa7, 0x34, 0x79, 0x8e, 0xa3, 0xaa, 0x5a, 0xcc, 0x35, 0x7a, 0x32, 0x2e, + 0xbb, 0x47, 0x96, 0xed, 0x10, 0x21, 0x55, 0x09, 0xbd, 0x05, 0x61, 0x29, 0xe7, 0x0d, 0xd3, 0xcb, + 0xd1, 0x52, 0xe1, 0xc7, 0x20, 0x41, 0x8c, 0x4f, 0xe8, 0x0e, 0xce, 0xb5, 0x39, 0xcc, 0x15, 0x5a, + 0x12, 0xbb, 0x0a, 0xc3, 0xdb, 0x1b, 0xf5, 0x6a, 0x99, 0x3b, 0x56, 0xb3, 0x70, 0x1c, 0x6d, 0xbf, + 0xd1, 0xb4, 0x4c, 0x56, 0x61, 0x7c, 0x4c, 0xe3, 0xac, 0xf3, 0x28, 0xdd, 0x12, 0xef, 0x06, 0x8c, + 0xf0, 0x22, 0x8e, 0x49, 0x4d, 0xa0, 0xda, 0x1c, 0x4a, 0xd4, 0x19, 0x35, 0x21, 0xe3, 0xb7, 0xb1, + 0xe5, 0x2b, 0x07, 0xf3, 0x07, 0x30, 0xea, 0xf1, 0x32, 0x7e, 0x2e, 0x4f, 0xc9, 0x9c, 0x1b, 0xb4, + 0x98, 0x69, 0x3e, 0x05, 0x8c, 0x29, 0xff, 0x32, 0x36, 0x68, 0xe8, 0x9c, 0xad, 0xf5, 0xe5, 0x2a, + 0xe1, 0x2a, 0x67, 0x96, 0x98, 0x8e, 0xbb, 0xd4, 0xaa, 0x38, 0xc0, 0xaa, 0x5b, 0x35, 0x65, 0x0d, + 0xfd, 0xc8, 0x79, 0xc0, 0x28, 0x05, 0xc4, 0x78, 0x20, 0x03, 0xf1, 0x24, 0x50, 0x4b, 0xcb, 0x1d, + 0xb1, 0x49, 0x43, 0x0c, 0xad, 0x52, 0xe3, 0x8a, 0xb3, 0xe8, 0x84, 0x05, 0x45, 0x76, 0xcc, 0x93, + 0x51, 0xf1, 0x4c, 0x66, 0xae, 0xdc, 0x1a, 0xab, 0x30, 0x26, 0xcb, 0xe4, 0x4b, 0x09, 0xe3, 0x95, + 0x06, 0xbf, 0xfb, 0x80, 0x79, 0xa0, 0x37, 0x25, 0x81, 0x10, 0x8f, 0x34, 0xc1, 0xbe, 0xbb, 0x6f, + 0xb8, 0x09, 0x1f, 0x7b, 0xc1, 0x37, 0xda, 0x44, 0x18, 0x83, 0xea, 0x34, 0x4d, 0x68, 0xf0, 0xbb, + 0x4b, 0xfd, 0x30, 0xea, 0x1b, 0x6e, 0x82, 0x30, 0xea, 0x9b, 0x6b, 0x02, 0x8b, 0x60, 0x5d, 0x6c, + 0x91, 0xc6, 0x1a, 0x59, 0x89, 0x37, 0x22, 0x54, 0x9c, 0x11, 0x8c, 0xcc, 0xf9, 0xc0, 0xb0, 0xc8, + 0x98, 0xf5, 0x0b, 0x68, 0x86, 0x30, 0xec, 0x9b, 0x6d, 0xe6, 0xf7, 0x72, 0x2c, 0x74, 0x58, 0x7d, + 0x4b, 0xc9, 0x21, 0xe8, 0x3c, 0x75, 0x95, 0x87, 0x5c, 0xe5, 0x6b, 0x7f, 0x6c, 0x3b, 0x2d, 0xf5, + 0x21, 0xd7, 0xea, 0x06, 0x87, 0x32, 0x78, 0xf4, 0x33, 0xdb, 0x69, 0x99, 0x51, 0x68, 0xf4, 0x21, + 0x4c, 0x2a, 0x45, 0x52, 0x5a, 0x63, 0xc9, 0x02, 0x54, 0x74, 0xbb, 0x65, 0xea, 0x90, 0xc6, 0x6f, + 0xe7, 0xe1, 0xc2, 0x4e, 0xc7, 0xa7, 0xde, 0x16, 0xeb, 0xce, 0x73, 0xec, 0x04, 0xae, 0xf7, 0x8a, + 0xda, 0x7d, 0xa3, 0xf7, 0x60, 0x78, 0x0d, 0xb7, 0xdb, 0x2e, 0x1f, 0xf9, 0x65, 0xf1, 0x8a, 0x1a, + 0x85, 0xa6, 0x40, 0x6b, 0x03, 0x26, 0x83, 0x46, 0x1f, 0xc2, 0xd8, 0x1a, 0xb6, 0xbc, 0x60, 0x1f, + 0x5b, 0x42, 0x58, 0x15, 0xc1, 0xeb, 0x15, 0x14, 0x0e, 0xb0, 0x36, 0x60, 0x86, 0xd0, 0x68, 0x89, + 0xdc, 0xe3, 0x9c, 0x03, 0xe9, 0x78, 0x9e, 0xd2, 0x20, 0x81, 0x59, 0x1b, 0x30, 0x29, 0x2c, 0x7a, + 0x02, 0x93, 0xe5, 0x03, 0xec, 0x04, 0x4f, 0x70, 0x60, 0xb5, 0xac, 0xc0, 0xe2, 0x42, 0xcd, 0x8d, + 0x34, 0x64, 0x0d, 0x78, 0x6d, 0xc0, 0xd4, 0xb1, 0x2b, 0xc3, 0x30, 0xf8, 0xc4, 0x3f, 0x30, 0x8e, + 0x73, 0xb0, 0xb0, 0xec, 0xbe, 0x70, 0x12, 0x19, 0xf3, 0x5d, 0x9d, 0x31, 0xc2, 0x27, 0x28, 0x01, + 0x3e, 0xc2, 0x9a, 0x77, 0x61, 0xa8, 0x66, 0x3b, 0x07, 0x91, 0x73, 0x3c, 0x01, 0x8f, 0x40, 0xd1, + 0x11, 0xda, 0xce, 0x01, 0xda, 0x10, 0x02, 0x14, 0x57, 0xf2, 0x0c, 0x6a, 0x52, 0x5b, 0x02, 0xb6, + 0x0a, 0x1d, 0x0a, 0x4a, 0xec, 0xb7, 0x18, 0xe0, 0x3b, 0x30, 0x9f, 0xd2, 0x2e, 0x77, 0x06, 0x27, + 0x63, 0x1b, 0xa2, 0xa7, 0xd2, 0xdb, 0x30, 0x97, 0x38, 0x05, 0x31, 0xc0, 0x7f, 0x90, 0xb4, 0x96, + 0xd8, 0xc8, 0x17, 0x60, 0x44, 0xe4, 0x38, 0x61, 0x17, 0x77, 0xf1, 0x93, 0x7a, 0x31, 0xd0, 0xeb, + 0x76, 0x18, 0x86, 0x59, 0xfc, 0x46, 0xbb, 0x4a, 0xc4, 0xa5, 0x41, 0xaa, 0x25, 0xfa, 0xe8, 0x0d, + 0xd2, 0x3b, 0x4b, 0x5a, 0xa4, 0xcd, 0x35, 0xd7, 0x0f, 0x1c, 0x69, 0x64, 0x67, 0xca, 0xdf, 0xe8, + 0x36, 0x14, 0x56, 0x5e, 0x06, 0xd8, 0x73, 0xac, 0x36, 0xcf, 0xf6, 0xc0, 0xf3, 0xf6, 0x9a, 0xb1, + 0x72, 0xf4, 0x01, 0xcc, 0x47, 0xcb, 0xc4, 0x28, 0x99, 0x1b, 0x4a, 0x5a, 0xb5, 0xf1, 0xa7, 0x79, + 0x1a, 0x38, 0x3a, 0x63, 0x69, 0x12, 0xee, 0x6e, 0xd5, 0x39, 0xb7, 0xf2, 0x5b, 0x75, 0xb4, 0x08, + 0x63, 0x5b, 0x75, 0x2d, 0x51, 0x8c, 0x19, 0x16, 0x90, 0x6e, 0x93, 0x21, 0x94, 0xbd, 0xe6, 0xa1, + 0x1d, 0xe0, 0x66, 0xd0, 0xf5, 0x78, 0xbc, 0x2c, 0x33, 0x56, 0x8e, 0x0c, 0x98, 0x58, 0x6d, 0xdb, + 0xfb, 0x4d, 0x41, 0x8c, 0xb1, 0x40, 0x2b, 0x43, 0x37, 0x61, 0x6a, 0xdd, 0xf1, 0x03, 0xab, 0xdd, + 0x66, 0x79, 0x74, 0x78, 0xe2, 0x72, 0x33, 0x52, 0x4a, 0xda, 0xad, 0xba, 0x4e, 0x60, 0xd9, 0x0e, + 0xf6, 0xcc, 0xae, 0x13, 0xd8, 0x47, 0x98, 0x8f, 0x3d, 0x56, 0x8e, 0xde, 0x85, 0x39, 0x59, 0xb6, + 0xe5, 0x35, 0x0f, 0xb1, 0x1f, 0x78, 0x34, 0xc5, 0x19, 0x8d, 0x0c, 0x64, 0x26, 0x57, 0xd2, 0x16, + 0xda, 0x6e, 0xb7, 0xb5, 0xe2, 0x3c, 0xb7, 0x3d, 0xd7, 0xa1, 0xe9, 0x48, 0x47, 0x79, 0x0b, 0x91, + 0x72, 0xa3, 0x96, 0xf8, 0xd5, 0xbe, 0xc1, 0x12, 0x34, 0x4e, 0x72, 0xb0, 0x98, 0xf8, 0x61, 0x89, + 0xcd, 0x5b, 0x45, 0xce, 0x45, 0xd6, 0xef, 0x6d, 0x18, 0xa2, 0xbb, 0x39, 0x53, 0x0c, 0x08, 0x33, + 0x14, 0x8a, 0xcf, 0x48, 0x91, 0x5a, 0x93, 0xc2, 0xa0, 0x55, 0xa9, 0xc4, 0x1d, 0xa4, 0x62, 0xeb, + 0xdd, 0xe8, 0x9e, 0x99, 0xd0, 0xb8, 0xaa, 0xcc, 0x15, 0x6a, 0xdb, 0x37, 0xd1, 0xb9, 0xfd, 0x69, + 0x0e, 0x4a, 0x3d, 0xf6, 0x13, 0x39, 0xa6, 0x5c, 0x1f, 0x63, 0x7a, 0x24, 0xc7, 0xc4, 0x1c, 0x5e, + 0x96, 0xfa, 0xdb, 0xb3, 0xce, 0x7a, 0x58, 0x55, 0x40, 0xf1, 0x93, 0x07, 0x7d, 0x07, 0xc6, 0xea, + 0xf5, 0x35, 0xed, 0x9d, 0x3f, 0xa6, 0x09, 0x0c, 0x21, 0x8c, 0xf7, 0xe1, 0x82, 0x24, 0xc2, 0x22, + 0xd7, 0x2b, 0x5e, 0x75, 0xfc, 0xac, 0x97, 0x2e, 0x80, 0x61, 0x81, 0xf1, 0x27, 0x43, 0x31, 0xc4, + 0x7a, 0xf7, 0xe8, 0xc8, 0xf2, 0x5e, 0xa1, 0xb2, 0x8e, 0x38, 0xd8, 0xf3, 0x90, 0xad, 0x0c, 0xfd, + 0xf4, 0xb8, 0x34, 0xa0, 0x50, 0x47, 0x6f, 0xc1, 0x24, 0xfd, 0x20, 0x9d, 0x26, 0x66, 0x7a, 0xc0, + 0x3c, 0x0b, 0x41, 0xa2, 0x15, 0xa2, 0x5d, 0x98, 0xe4, 0x6b, 0x9d, 0xfe, 0x16, 0x4b, 0xec, 0x5e, + 0x74, 0x89, 0x69, 0xdd, 0xbb, 0xa3, 0xa1, 0xb0, 0xc9, 0xd0, 0xc9, 0xa0, 0xaf, 0x60, 0x4a, 0x6c, + 0x6c, 0x9c, 0x30, 0x7b, 0xe4, 0xbc, 0x9f, 0x4d, 0x58, 0xc7, 0x61, 0x94, 0x23, 0x84, 0x48, 0x97, + 0xf9, 0x76, 0xcd, 0x29, 0x0f, 0xf7, 0xd3, 0x65, 0x0d, 0x85, 0x77, 0x59, 0x2b, 0x2b, 0x7e, 0x0f, + 0x50, 0x7c, 0x5c, 0xbd, 0x56, 0xd3, 0xa4, 0xb2, 0x9a, 0x8a, 0x65, 0x98, 0x49, 0x18, 0xc0, 0xa9, + 0x48, 0x7c, 0x0f, 0x50, 0xbc, 0xa7, 0xa7, 0xa1, 0x60, 0xdc, 0x82, 0x9b, 0x92, 0x05, 0x72, 0x35, + 0x68, 0x34, 0xc5, 0x6d, 0xff, 0xd7, 0xf2, 0x50, 0xea, 0x01, 0x8a, 0xfe, 0x56, 0x2e, 0xca, 0x6d, + 0xb6, 0x1a, 0x3f, 0x8c, 0x72, 0x3b, 0x19, 0x3f, 0x81, 0xed, 0x95, 0x8f, 0xfe, 0xd2, 0x9f, 0xbd, + 0xf6, 0x41, 0x1d, 0x9f, 0xb2, 0xd3, 0x73, 0x6b, 0x48, 0xe5, 0x96, 0x09, 0xb3, 0x9a, 0x88, 0xd3, + 0xcf, 0xde, 0x7d, 0x05, 0x80, 0x27, 0xd4, 0xda, 0x70, 0x0f, 0xb8, 0x4f, 0xa2, 0x52, 0x62, 0x3c, + 0x84, 0xb9, 0x08, 0x4d, 0xae, 0x81, 0xf8, 0x0e, 0x48, 0xef, 0x29, 0x4a, 0x74, 0xb0, 0x72, 0xfe, + 0xe7, 0xc7, 0xa5, 0x49, 0x72, 0x02, 0xde, 0x09, 0x03, 0x44, 0x8b, 0xbf, 0x8c, 0x27, 0xaa, 0x0e, + 0xa5, 0xdc, 0xd6, 0x7c, 0xd0, 0xef, 0xc3, 0x39, 0x56, 0x12, 0x09, 0xc3, 0xaa, 0x42, 0xf3, 0x3d, + 0x81, 0x03, 0x1a, 0x73, 0xd4, 0x63, 0x84, 0xfe, 0x28, 0x87, 0xbe, 0x89, 0xc6, 0x0e, 0x0b, 0xdd, + 0x1f, 0x16, 0xcb, 0x50, 0xaf, 0x43, 0xe5, 0xd0, 0x87, 0x52, 0x3c, 0x56, 0x09, 0x38, 0xc7, 0x7d, + 0xd1, 0xc6, 0xad, 0x03, 0x9a, 0xb7, 0xbb, 0x32, 0xc1, 0x1f, 0xab, 0x86, 0x2c, 0x42, 0x80, 0xa2, + 0x19, 0x9f, 0xc3, 0x5c, 0xb5, 0x8d, 0x2d, 0x2f, 0xda, 0x1e, 0xba, 0x09, 0x23, 0xb4, 0x4c, 0xb7, + 0x37, 0xb3, 0x48, 0x11, 0xb5, 0x37, 0xe3, 0x95, 0xc6, 0x06, 0x5c, 0x64, 0x37, 0x30, 0x75, 0x48, + 0xa1, 0xbe, 0x63, 0x98, 0xfe, 0x8e, 0xf8, 0x1b, 0x24, 0x8c, 0x9e, 0xc1, 0x19, 0x9f, 0x51, 0x83, + 0xd6, 0xa4, 0x94, 0xed, 0xfd, 0x79, 0xc0, 0xfc, 0x7f, 0xb0, 0x58, 0xee, 0x74, 0xb0, 0xd3, 0x0a, + 0x11, 0xb7, 0x3d, 0xab, 0x4f, 0xcf, 0x42, 0x54, 0x86, 0x61, 0x0a, 0x2d, 0x95, 0xc5, 0xbc, 0xbb, + 0x09, 0xdd, 0xa1, 0x70, 0x3c, 0x2e, 0x1f, 0x6d, 0x80, 0x61, 0x1a, 0x2d, 0x98, 0xaf, 0x77, 0xf7, + 0x8f, 0x6c, 0x96, 0xc7, 0x9c, 0x7a, 0xe7, 0x8a, 0xb6, 0xd7, 0x45, 0xb6, 0x15, 0xc6, 0x8c, 0x5b, + 0x61, 0x2a, 0x76, 0x6a, 0xe8, 0xc6, 0x3d, 0x76, 0x9f, 0xdf, 0xbf, 0x13, 0xa2, 0xd2, 0xdb, 0x0a, + 0x6b, 0x85, 0x56, 0xf3, 0x8c, 0x2c, 0xc6, 0x0c, 0x9c, 0x57, 0x15, 0x6f, 0x6c, 0x85, 0xcc, 0xc1, + 0x8c, 0xae, 0x50, 0x63, 0xc5, 0x5f, 0xc3, 0x2c, 0xbb, 0xf0, 0xb3, 0xb8, 0xba, 0x4b, 0x61, 0x08, + 0xd9, 0xfc, 0xee, 0x52, 0xc4, 0x3c, 0x8e, 0x9a, 0xef, 0xc8, 0x88, 0xe9, 0xbb, 0x4b, 0xcc, 0x29, + 0xe1, 0xf9, 0x92, 0xa6, 0xb6, 0xcd, 0xef, 0x2e, 0x55, 0x46, 0x78, 0x7c, 0x42, 0x42, 0x9d, 0x4d, + 0xff, 0x37, 0x42, 0x7d, 0x89, 0xfa, 0xc1, 0xad, 0x61, 0x8b, 0xda, 0xac, 0x26, 0x7b, 0x13, 0x4d, + 0x41, 0xde, 0x6e, 0x09, 0x29, 0xdb, 0x6e, 0x19, 0x7f, 0x94, 0x83, 0x5b, 0x4c, 0x16, 0x49, 0xc6, + 0xa3, 0xda, 0xb5, 0x14, 0x64, 0xf4, 0x01, 0xb0, 0x3c, 0xbe, 0x5c, 0xe0, 0x33, 0x78, 0xcf, 0xb3, + 0x28, 0x31, 0x04, 0x54, 0x86, 0x09, 0xd5, 0xe2, 0xb3, 0xbf, 0x50, 0x30, 0xe6, 0xf8, 0xd1, 0x53, + 0x4b, 0x5a, 0x81, 0x3e, 0x83, 0x4b, 0x2b, 0x2f, 0xc9, 0x82, 0xe0, 0xa7, 0x13, 0x7f, 0x31, 0x0e, + 0xbd, 0x55, 0xa6, 0xb7, 0xf9, 0x8a, 0xd1, 0xc5, 0xe0, 0x68, 0x31, 0xb9, 0x1e, 0x88, 0x03, 0x4e, + 0x4a, 0xaf, 0x63, 0xa6, 0x56, 0x66, 0xfc, 0x49, 0x0e, 0x16, 0x93, 0x5b, 0xe3, 0x1b, 0xcb, 0x3a, + 0x9c, 0xaf, 0x5a, 0x8e, 0xeb, 0xd8, 0x4d, 0xab, 0x5d, 0x6f, 0x1e, 0xe2, 0x56, 0x57, 0x86, 0x62, + 0x94, 0xbb, 0x0c, 0xb9, 0xee, 0x70, 0x74, 0x01, 0x62, 0xc6, 0xb1, 0xd0, 0xfb, 0x70, 0x81, 0x1a, + 0x0d, 0xb2, 0xbd, 0xb7, 0x8d, 0x3d, 0x49, 0x8f, 0xf5, 0x2c, 0xa5, 0x16, 0xdd, 0x83, 0x19, 0x76, + 0xa8, 0xb4, 0x76, 0x1c, 0x3b, 0x90, 0x48, 0xec, 0x56, 0x94, 0x54, 0x65, 0xd4, 0xe0, 0x2d, 0x2d, + 0xcf, 0x17, 0xb5, 0x02, 0xc6, 0xad, 0x9a, 0xe7, 0x1e, 0xb9, 0x81, 0x96, 0x6c, 0x80, 0xe7, 0x60, + 0x0c, 0x35, 0x2e, 0x9c, 0x97, 0x91, 0x62, 0xe3, 0xff, 0x85, 0x1b, 0x3d, 0x28, 0x72, 0x7e, 0xd5, + 0xe1, 0xbc, 0x15, 0xa9, 0x13, 0x0f, 0x63, 0x37, 0x04, 0xbf, 0xb2, 0x08, 0xf9, 0x66, 0x1c, 0xff, + 0xf6, 0xb6, 0x96, 0xb6, 0x0d, 0x2d, 0xc0, 0x6c, 0xcd, 0xdc, 0x5a, 0xde, 0xa9, 0x6e, 0x37, 0xb6, + 0xbf, 0xaa, 0xad, 0x34, 0x76, 0x36, 0x1f, 0x6f, 0x6e, 0xed, 0x6d, 0xb2, 0x98, 0xa9, 0x5a, 0xcd, + 0xf6, 0x4a, 0xf9, 0x49, 0x21, 0x87, 0x66, 0xa1, 0xa0, 0x15, 0xaf, 0xec, 0x54, 0x0a, 0xf9, 0xdb, + 0x0d, 0xd5, 0xa2, 0x17, 0x5d, 0x82, 0xf9, 0xe5, 0x95, 0xdd, 0xf5, 0xea, 0x8a, 0xa0, 0xa9, 0xc6, + 0x6b, 0x9d, 0x85, 0x82, 0x5a, 0xb9, 0xbd, 0xb5, 0x5d, 0x2b, 0xe4, 0x48, 0x3f, 0xd4, 0xd2, 0xbd, + 0x95, 0x4a, 0x79, 0x67, 0x7b, 0x6d, 0xb3, 0x30, 0x68, 0x0c, 0x8d, 0xe6, 0x0b, 0xf9, 0xdb, 0x3f, + 0xd2, 0xcc, 0x7d, 0xd1, 0x22, 0x2c, 0x70, 0xf0, 0x9d, 0x7a, 0x79, 0x35, 0xbd, 0x09, 0x56, 0xfb, + 0xe4, 0x61, 0xb9, 0x90, 0x43, 0x97, 0xe1, 0xa2, 0x56, 0x5a, 0x2b, 0xd7, 0xeb, 0x7b, 0x5b, 0xe6, + 0xf2, 0xc6, 0x4a, 0xbd, 0x5e, 0xc8, 0xdf, 0xde, 0xd5, 0x02, 0x73, 0x90, 0x16, 0x9e, 0x3c, 0x2c, + 0x37, 0xcc, 0x95, 0x2f, 0x76, 0xd6, 0xcd, 0x95, 0xe5, 0x78, 0x0b, 0x5a, 0xed, 0x57, 0x2b, 0xf5, + 0x42, 0x0e, 0xcd, 0xc0, 0xb4, 0x56, 0xba, 0xb9, 0x55, 0xc8, 0xdf, 0xbe, 0xc9, 0xc3, 0x2e, 0xa0, + 0x29, 0x80, 0xe5, 0x95, 0x7a, 0x75, 0x65, 0x73, 0x79, 0x7d, 0x73, 0xb5, 0x30, 0x80, 0x26, 0x61, + 0xac, 0x2c, 0x7f, 0xe6, 0x6e, 0x7f, 0x04, 0xd3, 0x91, 0x1b, 0x13, 0x81, 0x90, 0x97, 0x8d, 0xc2, + 0x00, 0xe1, 0x91, 0xfc, 0x49, 0xaf, 0xb9, 0xec, 0xf2, 0x53, 0xc8, 0x2d, 0xfd, 0xcf, 0xdf, 0xcb, + 0xc1, 0x38, 0xd9, 0x0e, 0x84, 0xd9, 0xe7, 0xd7, 0xca, 0x05, 0x83, 0x7f, 0x06, 0x3c, 0x01, 0x56, + 0xea, 0x6d, 0x82, 0x9e, 0x0c, 0xc5, 0x0c, 0xc5, 0x15, 0x05, 0xb8, 0x95, 0xbb, 0x97, 0x43, 0x26, + 0x7d, 0xa5, 0x89, 0xc8, 0xdb, 0x92, 0x72, 0xf2, 0x95, 0xa8, 0x78, 0x39, 0x53, 0x4c, 0x47, 0xbf, + 0x0c, 0x86, 0x4a, 0x33, 0x45, 0x2a, 0xfd, 0x4e, 0x7f, 0xd2, 0xa7, 0x68, 0xf3, 0x66, 0x7f, 0xe0, + 0xe8, 0x11, 0x4c, 0x12, 0x79, 0x4d, 0x82, 0xa1, 0x4b, 0x51, 0x44, 0x45, 0x44, 0x2c, 0x2e, 0x26, + 0x57, 0xca, 0xf8, 0xfb, 0x13, 0x74, 0x20, 0xec, 0xb2, 0xe5, 0x23, 0xe1, 0x9c, 0x27, 0x4a, 0x98, + 0x9d, 0x4e, 0xf1, 0x7c, 0xa4, 0x78, 0xf7, 0xfe, 0xbd, 0x1c, 0xaa, 0xd3, 0x98, 0x16, 0x9a, 0xe0, + 0x87, 0x84, 0x1d, 0x72, 0x5c, 0x22, 0x64, 0xbd, 0x29, 0xc9, 0x8c, 0x52, 0x29, 0x12, 0xe3, 0x26, + 0xa0, 0xb8, 0x3c, 0x85, 0xae, 0x86, 0xeb, 0x20, 0x59, 0xd4, 0x2a, 0x5e, 0x88, 0x3d, 0xbe, 0xaf, + 0x90, 0x13, 0x15, 0xad, 0xc0, 0x14, 0xf7, 0xbc, 0xe1, 0x12, 0x1e, 0xca, 0x92, 0x11, 0x53, 0xc9, + 0xac, 0x52, 0x3e, 0x49, 0x29, 0x11, 0x15, 0xc3, 0x71, 0x44, 0x45, 0xc7, 0xe2, 0xa5, 0xc4, 0x3a, + 0x3e, 0xbe, 0x87, 0x30, 0xa5, 0x0b, 0x9c, 0x48, 0x4c, 0x50, 0xa2, 0x1c, 0x9a, 0xda, 0xa1, 0x06, + 0xcc, 0x3f, 0xb1, 0x6c, 0xaa, 0x6e, 0xe2, 0x4f, 0xbc, 0xe2, 0x81, 0x16, 0x95, 0x32, 0x5e, 0x6c, + 0xeb, 0xd8, 0x69, 0x15, 0x7b, 0xc5, 0x80, 0xa2, 0x9f, 0x4d, 0x5d, 0xc8, 0x4d, 0xfa, 0x03, 0x37, + 0x32, 0xf4, 0x2c, 0x81, 0x49, 0x36, 0x0b, 0xc5, 0x34, 0x33, 0x1b, 0xf4, 0x84, 0x0a, 0x6e, 0x11, + 0x8a, 0xca, 0x9a, 0x38, 0x35, 0xb9, 0x05, 0xea, 0xff, 0x15, 0xd8, 0x51, 0x7b, 0x19, 0x1f, 0xa5, + 0x30, 0x2e, 0x95, 0xd8, 0xbd, 0x1c, 0xfa, 0x9a, 0x7e, 0xd5, 0x89, 0xe4, 0xf6, 0xec, 0xe0, 0x90, + 0xdb, 0xac, 0x5d, 0x4a, 0x24, 0xc0, 0x3f, 0x94, 0x0c, 0xea, 0x26, 0xcc, 0x26, 0x59, 0xf6, 0x48, + 0x86, 0x66, 0x98, 0xfd, 0xa4, 0xae, 0x02, 0x93, 0x88, 0x9f, 0xad, 0xf4, 0x49, 0xca, 0x30, 0x2c, + 0x49, 0xa5, 0xf9, 0x09, 0x4c, 0x91, 0x55, 0xf2, 0x18, 0xe3, 0x4e, 0xb9, 0x6d, 0x3f, 0xc7, 0x3e, + 0x12, 0xf1, 0xd1, 0x64, 0x51, 0x1a, 0xee, 0xad, 0x1c, 0xfa, 0x16, 0x8c, 0xef, 0x59, 0x41, 0xf3, + 0x90, 0x07, 0xe6, 0x11, 0x71, 0x7b, 0x68, 0x59, 0x51, 0xfc, 0xa2, 0x95, 0xf7, 0x72, 0xe8, 0x53, + 0x18, 0x59, 0xc5, 0x01, 0xf5, 0x03, 0xb9, 0x26, 0x1f, 0xb9, 0x99, 0x41, 0xd9, 0xba, 0x23, 0xcd, + 0x4f, 0x45, 0x87, 0xa3, 0xca, 0x2d, 0x74, 0x17, 0x80, 0x6d, 0x08, 0x94, 0x42, 0xb4, 0xba, 0x18, + 0xeb, 0x36, 0x5a, 0x25, 0x07, 0x7f, 0x1b, 0x07, 0xb8, 0xdf, 0x26, 0xd3, 0x78, 0xb4, 0x01, 0x53, + 0x32, 0x65, 0xc1, 0x26, 0xf5, 0xc2, 0x34, 0x22, 0xc4, 0xfc, 0x53, 0x50, 0xfb, 0x88, 0x7c, 0x15, + 0x2c, 0xa7, 0x9d, 0x8c, 0x1d, 0x87, 0xd2, 0xa2, 0xc9, 0x49, 0x26, 0x32, 0x30, 0x05, 0x77, 0xcd, + 0xf5, 0x03, 0x1d, 0x57, 0x96, 0x24, 0xe3, 0x62, 0x28, 0xaa, 0xed, 0xea, 0x71, 0xe4, 0xc2, 0x3d, + 0x37, 0x2d, 0xfc, 0x5d, 0xf1, 0x5a, 0x06, 0x04, 0xdb, 0xee, 0xe8, 0x4e, 0xb2, 0x4c, 0x6e, 0xf4, + 0xac, 0x99, 0xad, 0x0e, 0x76, 0xea, 0xf5, 0x35, 0x1a, 0x10, 0x4c, 0xbc, 0xa9, 0x29, 0x65, 0x82, + 0x30, 0x8a, 0x57, 0x91, 0x53, 0x4f, 0xf3, 0xc8, 0x43, 0x59, 0x7e, 0x7a, 0xe1, 0xa9, 0x97, 0x18, + 0xf2, 0xec, 0x31, 0xd3, 0x31, 0x68, 0x19, 0x71, 0x77, 0x97, 0x50, 0x31, 0x49, 0x4e, 0xe5, 0x1f, + 0xf6, 0x85, 0xa4, 0xba, 0xdd, 0x07, 0xf7, 0x72, 0x68, 0x05, 0x66, 0xa4, 0xd3, 0x6c, 0x58, 0x85, + 0x52, 0x10, 0x32, 0x4e, 0x98, 0xb9, 0x04, 0x32, 0xbb, 0x4b, 0x19, 0x84, 0x12, 0xcb, 0xd1, 0xe7, + 0x30, 0xc3, 0xd7, 0xa6, 0xd6, 0x9f, 0x82, 0xdc, 0x66, 0xb8, 0x68, 0x9f, 0xda, 0x93, 0x47, 0x30, + 0x57, 0x8f, 0x70, 0x87, 0x19, 0x7c, 0x5d, 0xd4, 0x49, 0xd0, 0xc2, 0x3a, 0x0e, 0x18, 0x7b, 0x92, + 0x69, 0x3d, 0x06, 0xc4, 0xf4, 0x01, 0x82, 0xdc, 0x73, 0x1b, 0xbf, 0x40, 0x97, 0x23, 0x5d, 0x27, + 0x85, 0x14, 0x8c, 0xee, 0x53, 0xa9, 0x23, 0xdb, 0x66, 0x89, 0x17, 0x59, 0xae, 0x78, 0xab, 0x63, + 0xed, 0xdb, 0x6d, 0x3b, 0xb0, 0x31, 0x59, 0xaa, 0x2a, 0x82, 0x5a, 0x25, 0xd6, 0xc3, 0xc5, 0x54, + 0x08, 0xf4, 0xab, 0x34, 0x5c, 0x55, 0xf6, 0xdd, 0x04, 0x7d, 0x2b, 0x29, 0x3b, 0x78, 0xca, 0xed, + 0xaa, 0xf8, 0xed, 0xfe, 0x80, 0xf9, 0x62, 0xfc, 0x0c, 0x26, 0x57, 0x71, 0xc0, 0xb2, 0xbb, 0x2f, + 0x5b, 0x81, 0x85, 0xa4, 0xbe, 0x40, 0x16, 0xf1, 0x35, 0x28, 0x62, 0x4d, 0x84, 0x15, 0x75, 0xfc, + 0x63, 0xb4, 0x0e, 0x05, 0xb6, 0xcd, 0x2b, 0x24, 0x2e, 0xc7, 0x48, 0x70, 0x10, 0xcb, 0xb3, 0x8e, + 0xfc, 0xd4, 0xd9, 0xba, 0xcb, 0x9e, 0x77, 0x91, 0x4c, 0x8c, 0xad, 0xc8, 0x91, 0x33, 0x5a, 0x99, + 0x8c, 0x28, 0x4a, 0x66, 0xc4, 0xc4, 0x3e, 0x0e, 0x84, 0x77, 0x2d, 0x4b, 0x36, 0x77, 0x3d, 0x3c, + 0xd3, 0xe3, 0xb5, 0xe1, 0x67, 0x1e, 0x89, 0x04, 0xb1, 0xfb, 0x00, 0xc9, 0x04, 0x7c, 0x09, 0x44, + 0x6f, 0x6a, 0xa2, 0xc7, 0xe9, 0xe8, 0x56, 0x61, 0x8c, 0xa1, 0x55, 0xdc, 0x40, 0xee, 0x8f, 0xb2, + 0x44, 0x60, 0x2e, 0xc4, 0x2b, 0xb8, 0x72, 0x62, 0xf0, 0xaf, 0xe6, 0x73, 0xa8, 0x0c, 0x63, 0xec, + 0xd3, 0x52, 0x89, 0xc8, 0x92, 0x1e, 0xdb, 0x3c, 0x23, 0xf1, 0x19, 0x8c, 0xaf, 0xe2, 0xa0, 0xe2, + 0x52, 0xe7, 0x66, 0x5f, 0x7e, 0x52, 0x4a, 0x99, 0x20, 0x33, 0xa9, 0x8c, 0x62, 0x77, 0x89, 0x62, + 0xdf, 0xcb, 0xa1, 0x77, 0xe9, 0x91, 0x49, 0x3d, 0xa3, 0xe7, 0x42, 0x5c, 0x25, 0xc7, 0x74, 0x12, + 0x1e, 0x39, 0xd3, 0x89, 0xc4, 0xdd, 0xf5, 0x3c, 0xec, 0x30, 0xe4, 0x34, 0xf1, 0x28, 0x09, 0xfb, + 0x33, 0xba, 0x5d, 0x2a, 0xd8, 0xcc, 0xda, 0xbe, 0x17, 0x09, 0x96, 0xa9, 0xe2, 0x5e, 0x0e, 0x7d, + 0x00, 0xa3, 0xbc, 0x8f, 0x04, 0x49, 0xeb, 0x74, 0x8f, 0xd1, 0x7e, 0x00, 0xc0, 0xa6, 0x82, 0xf6, + 0x59, 0x87, 0xc9, 0xe6, 0xf3, 0x07, 0x44, 0x36, 0x68, 0xbd, 0x0e, 0x66, 0x55, 0x08, 0x09, 0x14, + 0x73, 0x41, 0x9b, 0x65, 0x95, 0xcf, 0x99, 0x44, 0x88, 0x98, 0x4f, 0x43, 0xd2, 0xc8, 0xc8, 0x12, + 0x52, 0xcc, 0xd7, 0x8a, 0x7b, 0x89, 0x06, 0xeb, 0x50, 0x28, 0x37, 0xe9, 0xe9, 0x25, 0xb3, 0x7a, + 0xcb, 0x3b, 0x56, 0xb4, 0x42, 0xd0, 0x9a, 0x8b, 0x26, 0x09, 0xdf, 0xc0, 0x16, 0x8d, 0xb8, 0x37, + 0x2f, 0x25, 0xa1, 0x48, 0x55, 0x32, 0x46, 0xc6, 0x9d, 0x6a, 0xb6, 0x4a, 0x6e, 0x81, 0xed, 0x37, + 0x23, 0xf3, 0x11, 0xdd, 0xf8, 0x94, 0x8c, 0xe7, 0x17, 0xa2, 0xf8, 0xf2, 0xf6, 0x29, 0x4c, 0x6d, + 0x25, 0x68, 0x19, 0xa6, 0x79, 0x7c, 0x2f, 0xc9, 0x96, 0x34, 0xec, 0xb4, 0xe6, 0xbf, 0x0b, 0x53, + 0x2b, 0xe4, 0x60, 0xea, 0xb6, 0x6c, 0x16, 0x65, 0x14, 0xe9, 0x61, 0x23, 0x53, 0x11, 0xd7, 0x44, + 0x72, 0x18, 0x25, 0x15, 0xb8, 0xfc, 0x90, 0xe3, 0xd9, 0xd6, 0x8b, 0xb3, 0x82, 0xac, 0x9a, 0x35, + 0x9c, 0xab, 0x26, 0xe6, 0x53, 0x92, 0x6f, 0xa3, 0x1b, 0xda, 0x8d, 0x37, 0x2d, 0x83, 0x76, 0x82, + 0x8c, 0xfb, 0xa5, 0x92, 0xe7, 0x30, 0x85, 0x66, 0x76, 0x56, 0xee, 0xd4, 0x71, 0xcb, 0xb8, 0x80, + 0x89, 0xd9, 0xb3, 0xd1, 0x3b, 0x3a, 0xf5, 0x8c, 0x0c, 0xdb, 0xa9, 0x2d, 0x50, 0x8d, 0x82, 0x9e, + 0xdc, 0x19, 0x5d, 0xc9, 0xce, 0x41, 0xad, 0x68, 0x14, 0x52, 0xb2, 0x42, 0x3f, 0xa2, 0xcb, 0x2c, + 0x4c, 0x86, 0x88, 0xd4, 0xfb, 0x79, 0x34, 0x17, 0xa4, 0x14, 0x1c, 0x93, 0x33, 0x3c, 0xd7, 0x60, + 0x3a, 0x92, 0x3b, 0x59, 0x2a, 0x92, 0x92, 0xb3, 0x37, 0x17, 0xaf, 0xa4, 0x55, 0x4b, 0xb5, 0x69, + 0x21, 0x9a, 0x70, 0x56, 0x0e, 0x39, 0x25, 0xd9, 0xaf, 0x1c, 0x72, 0x6a, 0xa6, 0xda, 0x47, 0x50, + 0x88, 0xe6, 0xba, 0x94, 0x44, 0x53, 0x92, 0x60, 0xa6, 0xce, 0xc9, 0x43, 0x98, 0x55, 0x67, 0x54, + 0x8e, 0x3b, 0x6d, 0xf7, 0x4f, 0xa3, 0xb3, 0x0d, 0x73, 0x89, 0xa9, 0x29, 0xa5, 0xa8, 0x90, 0x95, + 0xb8, 0x32, 0x95, 0x2a, 0x86, 0x0b, 0xc9, 0xd9, 0x69, 0xd1, 0x5b, 0xba, 0x9e, 0x22, 0x39, 0x57, + 0x67, 0xf1, 0x46, 0x0f, 0x28, 0xce, 0xd0, 0xaf, 0xe9, 0x09, 0x18, 0x6b, 0xe3, 0x9a, 0xa2, 0xb9, + 0x48, 0x69, 0xc0, 0xc8, 0x02, 0x91, 0x6b, 0x60, 0x36, 0x29, 0x3b, 0x76, 0x2a, 0x8b, 0xaf, 0xa7, + 0xd3, 0x0c, 0x17, 0xd6, 0xae, 0x08, 0xa2, 0x97, 0xca, 0x99, 0xcc, 0x2c, 0xa6, 0x19, 0x57, 0xdf, + 0xa2, 0x5c, 0x0f, 0xfd, 0x77, 0x39, 0x5d, 0x8d, 0x35, 0x9b, 0x94, 0x3b, 0x37, 0xaa, 0x65, 0x4a, + 0x4a, 0x8d, 0x2a, 0xd9, 0x90, 0x99, 0x7c, 0x77, 0x97, 0x69, 0x9c, 0x74, 0xea, 0xaa, 0xc6, 0x29, + 0x91, 0xf4, 0xd5, 0x74, 0x80, 0x70, 0x45, 0x24, 0x24, 0x01, 0x97, 0x2b, 0x22, 0x3d, 0x1d, 0xb9, + 0x5c, 0x11, 0x59, 0x39, 0xc4, 0x4d, 0xf1, 0xd1, 0xa5, 0xb0, 0x25, 0x23, 0x63, 0x6c, 0xc6, 0xb5, + 0x6e, 0x21, 0x9c, 0xb8, 0x48, 0xb7, 0x4f, 0x3b, 0x6d, 0x5f, 0xc3, 0xc5, 0xd4, 0xec, 0xb0, 0xe8, + 0xed, 0xd8, 0x07, 0x9d, 0xc2, 0x89, 0xf4, 0x9e, 0x4e, 0x6a, 0x89, 0x5d, 0xa5, 0xca, 0x2d, 0x92, + 0x43, 0x36, 0xb6, 0x63, 0x27, 0x24, 0x98, 0x5d, 0xa5, 0x92, 0xaf, 0x92, 0x24, 0x36, 0x75, 0xac, + 0x97, 0x93, 0xe8, 0xf8, 0xf1, 0x3d, 0x55, 0xe9, 0x97, 0x90, 0xc4, 0xa2, 0x15, 0xa7, 0xd9, 0x53, + 0xfb, 0xe9, 0x5a, 0x1a, 0x9d, 0x65, 0x7a, 0x99, 0x10, 0x39, 0x63, 0xd1, 0x45, 0x8d, 0x4d, 0xda, + 0x29, 0x59, 0xd4, 0x06, 0xa7, 0x1f, 0x90, 0x55, 0xaa, 0xdb, 0x96, 0x39, 0x6a, 0x53, 0x7b, 0x71, + 0x29, 0x4e, 0x43, 0xd3, 0x6b, 0x4b, 0x2e, 0xb0, 0xde, 0x2c, 0x46, 0x99, 0xa3, 0x75, 0x28, 0x7d, + 0x48, 0x48, 0x65, 0x4d, 0x8f, 0x2e, 0xa5, 0x4b, 0xa8, 0x33, 0x3c, 0x0f, 0x1f, 0x8d, 0x72, 0x2d, + 0xc2, 0xb5, 0x5c, 0x90, 0x4a, 0x3a, 0xa5, 0x34, 0x43, 0x27, 0x53, 0xa3, 0xe6, 0xc0, 0x09, 0xe9, + 0x76, 0xe5, 0x1e, 0x9a, 0x99, 0x8d, 0x37, 0x41, 0x3a, 0x93, 0xbb, 0x72, 0x2a, 0xc5, 0xcc, 0xfc, + 0xbb, 0xa9, 0x3d, 0xfd, 0xa1, 0xb2, 0x2b, 0xc7, 0x92, 0xea, 0xa2, 0x5b, 0x51, 0xd1, 0x2c, 0x2d, + 0xef, 0x6e, 0xc6, 0xae, 0x3f, 0x9b, 0x94, 0x8f, 0x57, 0x51, 0x34, 0xa7, 0x26, 0xeb, 0x4d, 0xe0, + 0x82, 0xdc, 0xde, 0x52, 0xa8, 0x65, 0x64, 0xe7, 0x4d, 0xed, 0xe1, 0xf7, 0x95, 0xed, 0x2d, 0x92, + 0x45, 0x57, 0x2a, 0x0e, 0x7a, 0xa4, 0xd9, 0x4d, 0xa5, 0xbd, 0x49, 0x0d, 0xc8, 0xe3, 0x29, 0x70, + 0xa5, 0xec, 0x92, 0x95, 0x20, 0x37, 0x51, 0x0f, 0x3d, 0x17, 0x1f, 0x22, 0xa1, 0x77, 0x21, 0xa2, + 0x45, 0xee, 0xd5, 0x31, 0xb9, 0x0f, 0x27, 0xa4, 0xce, 0x8d, 0xec, 0xc3, 0xe9, 0xc9, 0x75, 0x33, + 0x2e, 0x3a, 0xd3, 0x75, 0xfb, 0xc0, 0x51, 0x32, 0xdf, 0xca, 0x6b, 0x4e, 0x3c, 0x19, 0xaf, 0xdc, + 0x62, 0x92, 0x12, 0xe5, 0x6e, 0x11, 0x09, 0x87, 0xc9, 0xe7, 0x6a, 0x0e, 0x53, 0x54, 0x4c, 0x4f, + 0xdd, 0x2a, 0xb7, 0x9b, 0xc4, 0xa4, 0xa7, 0x0a, 0x41, 0x35, 0x81, 0xa8, 0x24, 0x98, 0x90, 0xcb, + 0x54, 0x12, 0x4c, 0xcc, 0x38, 0x7a, 0x97, 0xea, 0x55, 0x4c, 0xb7, 0x8d, 0x55, 0xbd, 0x8a, 0x92, + 0x56, 0x33, 0xa2, 0xd6, 0x40, 0x1f, 0x53, 0xa5, 0x46, 0xb6, 0x26, 0x64, 0x5e, 0xa7, 0xa4, 0xa6, + 0xff, 0x86, 0x30, 0xbf, 0x28, 0xd2, 0xb5, 0x4e, 0x19, 0x6d, 0xbe, 0x27, 0x94, 0x1a, 0x1a, 0x5a, + 0x2c, 0xe3, 0x68, 0x14, 0xed, 0xbb, 0x30, 0x11, 0x66, 0x17, 0xdd, 0x5d, 0x52, 0x10, 0x23, 0x29, + 0x47, 0xa3, 0x88, 0x1f, 0x88, 0x07, 0x16, 0xda, 0x9e, 0x5e, 0xd9, 0x4b, 0xcd, 0x05, 0x61, 0x62, + 0xd2, 0x88, 0x12, 0x45, 0x6d, 0x30, 0x7d, 0xe7, 0x9d, 0x50, 0x13, 0x0b, 0xc9, 0x79, 0x4d, 0xc8, + 0xe3, 0x26, 0xe7, 0x35, 0x29, 0x3b, 0x1a, 0xed, 0x0d, 0xbd, 0x6b, 0x7f, 0x25, 0x34, 0x06, 0x21, + 0xd1, 0xcb, 0x99, 0x39, 0xce, 0x8a, 0x57, 0xb2, 0x13, 0x83, 0x85, 0xa4, 0xeb, 0x50, 0x88, 0x66, + 0x41, 0x42, 0x49, 0x79, 0xea, 0x94, 0x74, 0x55, 0xf2, 0x0e, 0x97, 0x9a, 0x3e, 0xa9, 0x26, 0xd4, + 0xf8, 0x3a, 0xdd, 0x94, 0x6c, 0x65, 0x2a, 0xe9, 0x6c, 0xb1, 0x2a, 0x4c, 0x88, 0xa4, 0x5e, 0x84, + 0x63, 0x09, 0x97, 0x54, 0xb1, 0x2a, 0x21, 0x87, 0x92, 0x2d, 0xe2, 0x2f, 0x24, 0x67, 0x94, 0x7d, + 0x47, 0xbf, 0xa1, 0x66, 0x04, 0xbd, 0xec, 0xf9, 0x18, 0x8d, 0x7e, 0x09, 0xe6, 0x53, 0x62, 0x03, + 0xa2, 0x1b, 0x11, 0x85, 0x70, 0x72, 0xec, 0xc0, 0x62, 0x56, 0xe2, 0x41, 0xf4, 0x84, 0x5a, 0x31, + 0x68, 0x9e, 0x96, 0xb1, 0x97, 0xc1, 0x3d, 0x3b, 0x38, 0x64, 0xa9, 0x34, 0x95, 0x3d, 0x33, 0xd1, + 0x45, 0x13, 0xd5, 0xe9, 0x7d, 0x43, 0x2b, 0x4d, 0x78, 0x1c, 0x4c, 0x20, 0x58, 0x4c, 0x26, 0x48, + 0x13, 0xb7, 0xd7, 0xc4, 0x13, 0x53, 0xb4, 0x9b, 0xea, 0xf0, 0x93, 0x9c, 0x4b, 0x53, 0xbb, 0x59, + 0x13, 0x02, 0x52, 0x32, 0xc5, 0x74, 0x8f, 0xd8, 0x54, 0x8a, 0x8f, 0x08, 0xc5, 0x98, 0x93, 0x2b, + 0x4a, 0x01, 0xcf, 0xde, 0x3d, 0x4c, 0x71, 0xde, 0xea, 0x58, 0x4b, 0x4a, 0xff, 0xd2, 0xdc, 0x69, + 0x53, 0xfb, 0xb7, 0x22, 0xbe, 0xa7, 0xe4, 0xfe, 0xf5, 0x7b, 0xe2, 0xca, 0x67, 0xba, 0x88, 0x9f, + 0xb5, 0x36, 0x50, 0xa5, 0xbc, 0x98, 0x52, 0x8e, 0x36, 0xa9, 0x59, 0x52, 0xb4, 0x54, 0xb9, 0x78, + 0x26, 0x3b, 0x72, 0xa7, 0xd2, 0x63, 0xeb, 0x58, 0x73, 0x84, 0x3d, 0xcd, 0x3a, 0x8e, 0x78, 0xd0, + 0xf2, 0x75, 0xac, 0x95, 0x9e, 0x6e, 0x1d, 0x47, 0x08, 0xea, 0xeb, 0x38, 0xda, 0xcd, 0xe8, 0x45, + 0x3e, 0x75, 0x56, 0xa3, 0xdd, 0x94, 0xeb, 0x38, 0x99, 0x62, 0xba, 0xc3, 0x72, 0x2a, 0x45, 0xb9, + 0x8e, 0x75, 0x8a, 0x29, 0xe0, 0x7d, 0xae, 0xe3, 0x68, 0x23, 0xfa, 0x3a, 0x3e, 0x55, 0xff, 0xe4, + 0x3a, 0x4e, 0xee, 0xdf, 0xa9, 0xd7, 0x71, 0xc4, 0xc3, 0x5f, 0x1b, 0x68, 0xd2, 0x3a, 0x8e, 0xc2, + 0xb3, 0x75, 0x1c, 0x2d, 0x8d, 0x28, 0x50, 0x32, 0xd6, 0x71, 0x14, 0xf3, 0x0b, 0x4a, 0x2f, 0xe2, + 0x9d, 0xdc, 0xcf, 0x4a, 0x4e, 0x75, 0x6c, 0x46, 0x7b, 0x54, 0x7b, 0x17, 0x29, 0xef, 0x6f, 0x35, + 0x2f, 0xa6, 0x11, 0xa5, 0xeb, 0x79, 0x57, 0x30, 0x31, 0xda, 0x5d, 0x5d, 0x35, 0x95, 0xec, 0x9c, + 0x9d, 0xd1, 0xe1, 0x5d, 0xb2, 0x6e, 0x5a, 0x19, 0x74, 0xb3, 0x7c, 0xcb, 0x33, 0xe8, 0xca, 0x7b, + 0x4c, 0x94, 0x6e, 0x2a, 0x4a, 0xf6, 0xfa, 0xfe, 0x52, 0xbc, 0x5f, 0x44, 0xf1, 0x96, 0x22, 0x37, + 0xa3, 0x53, 0xf7, 0x54, 0xde, 0x90, 0xa2, 0x3d, 0x3d, 0xed, 0x3a, 0x7f, 0x22, 0xa4, 0x87, 0x58, + 0x50, 0x8a, 0xc8, 0xa0, 0xd5, 0xb5, 0x9e, 0x5a, 0x83, 0xb6, 0xa9, 0xaa, 0x36, 0x5e, 0xae, 0xa8, + 0x79, 0xd3, 0xa2, 0x5f, 0xf4, 0xa4, 0x1a, 0x73, 0xaf, 0x57, 0xa9, 0xa6, 0xf9, 0xde, 0x4b, 0xaa, + 0x71, 0xec, 0xcf, 0xa9, 0xea, 0x8b, 0xfb, 0x03, 0x39, 0x4f, 0xdd, 0xf4, 0x7b, 0xca, 0x8c, 0x66, + 0x3a, 0x45, 0x60, 0xa9, 0xc5, 0xda, 0x27, 0xfc, 0x81, 0x4e, 0x14, 0xa6, 0x32, 0x3f, 0x09, 0x1f, + 0x7d, 0x0e, 0x05, 0xbe, 0xbd, 0x85, 0x04, 0x92, 0x00, 0x53, 0xa7, 0xae, 0x22, 0x34, 0x6e, 0x7d, + 0xf4, 0xa0, 0x1f, 0x4d, 0x5b, 0x3f, 0x9c, 0x48, 0x57, 0x4b, 0x91, 0xe3, 0x70, 0xdb, 0xeb, 0xfa, + 0x01, 0x6e, 0xc5, 0xd5, 0x49, 0x7a, 0x67, 0x84, 0x01, 0x87, 0x0e, 0xbe, 0xbb, 0x84, 0xd6, 0xe9, + 0xde, 0xa6, 0x17, 0x67, 0xe9, 0xdb, 0x92, 0xc9, 0xd0, 0xad, 0x67, 0x4d, 0x3a, 0x9e, 0xe8, 0x7d, + 0x4a, 0x6b, 0x3b, 0xbd, 0x53, 0x92, 0x45, 0x7d, 0x8e, 0x2e, 0x8d, 0x45, 0xec, 0x42, 0xcc, 0x74, + 0x7f, 0xbd, 0x38, 0x13, 0x75, 0x85, 0x41, 0xdf, 0x83, 0x31, 0x81, 0xdc, 0x9b, 0x21, 0x51, 0x6c, + 0xca, 0x90, 0x65, 0x98, 0xd4, 0xfc, 0x7c, 0xe4, 0xed, 0x26, 0xc9, 0xfb, 0x27, 0x63, 0x9e, 0x27, + 0x35, 0x7f, 0x1e, 0x49, 0x25, 0xc9, 0xcb, 0x27, 0x95, 0xca, 0xa7, 0x30, 0xce, 0x59, 0x9a, 0xc9, + 0x8d, 0x74, 0x65, 0xdb, 0x9c, 0x62, 0x1f, 0xdd, 0x6d, 0xd9, 0x41, 0xd5, 0x75, 0x9e, 0xda, 0x07, + 0x3d, 0x19, 0x13, 0x47, 0xd9, 0x5d, 0x42, 0xbb, 0x34, 0x5f, 0x9c, 0xc8, 0xe2, 0x87, 0x83, 0x17, + 0xae, 0xf7, 0xcc, 0x76, 0x0e, 0x7a, 0x90, 0xbc, 0xaa, 0x93, 0x8c, 0xe2, 0x31, 0xba, 0xf5, 0x74, + 0xba, 0x3d, 0xf1, 0x33, 0x94, 0x6d, 0x8b, 0xd4, 0xb4, 0xe7, 0xb4, 0x3d, 0x4e, 0x7f, 0x78, 0xbc, + 0x18, 0x5a, 0x16, 0x9b, 0xb8, 0xe9, 0x7a, 0xad, 0xde, 0xc4, 0x4a, 0xba, 0x1d, 0x6f, 0x04, 0x6d, + 0x77, 0x89, 0x50, 0xad, 0xa7, 0x52, 0xed, 0x85, 0x9d, 0x71, 0x5a, 0x5d, 0xa2, 0x63, 0x3f, 0x65, + 0x6f, 0xb3, 0x77, 0x2d, 0x72, 0xd2, 0xd4, 0x3c, 0xfc, 0x14, 0x7b, 0xd4, 0x3c, 0xbc, 0x97, 0x61, + 0xb4, 0x0e, 0xbe, 0xbb, 0x44, 0xa8, 0xd4, 0x63, 0x54, 0xd2, 0xa0, 0xb3, 0x54, 0xf2, 0x74, 0x68, + 0x7d, 0xf6, 0x26, 0x8d, 0xcc, 0x07, 0xf4, 0xc9, 0x63, 0x67, 0xbd, 0x07, 0x47, 0x84, 0xc3, 0x82, + 0x00, 0xdc, 0xbd, 0x4f, 0x30, 0xeb, 0x0a, 0x66, 0x1c, 0x22, 0xb5, 0xcd, 0xef, 0x89, 0xb7, 0x8d, + 0x9e, 0xcd, 0xa6, 0x51, 0x78, 0x40, 0xb7, 0x37, 0x6e, 0x13, 0xad, 0x68, 0x05, 0xb5, 0x4c, 0xad, + 0xc5, 0x49, 0xd5, 0x3c, 0xda, 0x47, 0x65, 0x76, 0xa3, 0x53, 0x73, 0xba, 0x2a, 0xd6, 0x10, 0x89, + 0xc9, 0x5e, 0xa3, 0x24, 0x98, 0x56, 0x73, 0xc3, 0x6d, 0x3e, 0x53, 0xb5, 0x9a, 0x4a, 0x92, 0xd0, + 0xa2, 0x9e, 0xc2, 0x93, 0x6f, 0xe2, 0x34, 0x8f, 0xa7, 0x6a, 0xaa, 0xa5, 0xa6, 0x09, 0x55, 0xb5, + 0x9a, 0x7a, 0x42, 0xd3, 0x07, 0x42, 0x5d, 0x48, 0x1b, 0xd4, 0x29, 0xa7, 0xb2, 0x46, 0x6a, 0x0a, + 0x29, 0x92, 0xae, 0x29, 0x54, 0x3b, 0x9a, 0xbe, 0x5d, 0xa0, 0x78, 0x46, 0x53, 0x79, 0xff, 0x48, + 0x4d, 0x76, 0x9a, 0x61, 0x71, 0x35, 0x93, 0x90, 0xba, 0x59, 0xde, 0xd8, 0xd2, 0xd3, 0x3a, 0x17, + 0x75, 0xf3, 0xa1, 0x7b, 0x39, 0xb4, 0x09, 0x17, 0x56, 0x71, 0xc0, 0x37, 0x30, 0x13, 0xfb, 0x81, + 0x67, 0x37, 0x83, 0xcc, 0x87, 0x3e, 0x71, 0xdd, 0x48, 0xc0, 0xd9, 0x7d, 0x97, 0xd0, 0xab, 0x27, + 0xd3, 0xcb, 0xc4, 0xcb, 0x30, 0xce, 0xe5, 0xaf, 0x07, 0xa7, 0xe9, 0x62, 0xfa, 0x12, 0x1f, 0x61, + 0x36, 0x33, 0xe9, 0xa8, 0x85, 0x30, 0xca, 0x3e, 0xbf, 0x40, 0xdd, 0x81, 0x73, 0x0c, 0x29, 0xf5, + 0x8c, 0x9c, 0x50, 0x71, 0xd0, 0x7d, 0x61, 0xc5, 0x49, 0x50, 0xb4, 0xaa, 0xd4, 0x7e, 0xdd, 0x87, + 0x31, 0x76, 0x5b, 0xea, 0x1f, 0xe5, 0x63, 0x61, 0xe6, 0x99, 0xd5, 0xb1, 0x34, 0xe4, 0xcf, 0x61, + 0x52, 0xb5, 0x97, 0x39, 0x3d, 0x23, 0x3f, 0xa5, 0xcf, 0xb1, 0xe2, 0xd5, 0x23, 0x1d, 0x7f, 0x2e, + 0x92, 0x79, 0x81, 0xb3, 0x94, 0x6d, 0x90, 0x32, 0x07, 0x7a, 0x5a, 0xf7, 0xcf, 0xc7, 0xb0, 0xd1, + 0xc7, 0xc2, 0x55, 0x4a, 0x22, 0xc7, 0x81, 0x32, 0x78, 0x36, 0xc5, 0xd8, 0xfc, 0x3a, 0xc8, 0x72, + 0x83, 0xed, 0xd9, 0xed, 0x7e, 0x9e, 0x8d, 0x7b, 0xb3, 0x2e, 0x8d, 0xca, 0x16, 0x15, 0xbc, 0x62, + 0x39, 0x41, 0xd2, 0x09, 0x5d, 0x49, 0x4f, 0x23, 0x42, 0x27, 0xe3, 0x11, 0xbd, 0xd8, 0xc5, 0xf3, + 0xd9, 0xa7, 0x0d, 0x2f, 0x23, 0x2d, 0x49, 0x78, 0x93, 0x8d, 0x93, 0xcb, 0x40, 0xcb, 0xba, 0x18, + 0x73, 0xe7, 0xcd, 0x33, 0x21, 0xb7, 0x2e, 0xcc, 0x0e, 0xfb, 0x1f, 0x6c, 0x86, 0x10, 0x94, 0xf0, + 0x50, 0xdd, 0x73, 0x2e, 0xd2, 0xc8, 0xfd, 0x12, 0x95, 0xff, 0x92, 0xd3, 0x51, 0xa7, 0x12, 0xbb, + 0xa5, 0xd8, 0x3a, 0x64, 0x27, 0xb2, 0x7e, 0x46, 0x7d, 0xd0, 0x92, 0xb3, 0xa6, 0xdc, 0xec, 0x41, + 0x45, 0x70, 0xe2, 0xed, 0x9e, 0x70, 0xf2, 0xd9, 0xf3, 0x12, 0x3b, 0x61, 0x93, 0xdb, 0xeb, 0x91, + 0x05, 0x26, 0xe1, 0x25, 0x3a, 0x25, 0xd7, 0xb3, 0x20, 0xa8, 0xdb, 0x74, 0x66, 0x8e, 0x21, 0x8d, + 0xfd, 0x5f, 0x40, 0x29, 0x34, 0xe8, 0x38, 0xdd, 0x24, 0xa4, 0x4b, 0xf4, 0x28, 0x9e, 0x01, 0x1b, + 0x65, 0x05, 0xaa, 0x2f, 0x5e, 0x4b, 0xe3, 0xb0, 0xaf, 0x58, 0x0a, 0x71, 0x53, 0xb4, 0x48, 0xfe, + 0xa0, 0xb4, 0x4c, 0x44, 0x19, 0xaa, 0x55, 0xee, 0x94, 0x77, 0x26, 0x84, 0xe2, 0xb3, 0x7d, 0x7a, + 0x42, 0xd2, 0xde, 0x22, 0x42, 0xc8, 0xc8, 0x98, 0xde, 0xd3, 0x98, 0x93, 0x45, 0xa7, 0xe2, 0xb4, + 0x13, 0x6a, 0x85, 0x8e, 0x68, 0xf1, 0x34, 0xdd, 0x52, 0x96, 0x4b, 0x4d, 0x19, 0x2e, 0x67, 0x37, + 0x23, 0xc7, 0x77, 0x95, 0x7c, 0xa6, 0xac, 0x09, 0x2d, 0x47, 0x70, 0xd5, 0xdc, 0x08, 0x35, 0x05, + 0x09, 0xc9, 0x83, 0x8b, 0x20, 0x2a, 0xcd, 0x0d, 0x54, 0x17, 0x51, 0x56, 0x93, 0x42, 0xa2, 0x48, + 0xa7, 0x9b, 0xa4, 0xca, 0x8c, 0xdb, 0x45, 0x5d, 0xc4, 0x55, 0x3d, 0x4b, 0xa2, 0x0d, 0x98, 0x4f, + 0x09, 0x24, 0x23, 0x1f, 0x4d, 0xb3, 0x03, 0xcd, 0x14, 0xb3, 0x1b, 0x46, 0x3f, 0x80, 0xb9, 0xc4, + 0x48, 0x33, 0x52, 0xf1, 0x9b, 0x15, 0x87, 0xa6, 0x17, 0xf1, 0x67, 0xb0, 0x90, 0x96, 0xd0, 0x37, + 0x74, 0x02, 0xca, 0xce, 0xb2, 0x2c, 0xf7, 0xd4, 0x9e, 0x99, 0x81, 0x37, 0x61, 0x36, 0x29, 0x49, + 0xae, 0xfc, 0x38, 0x32, 0x32, 0xe8, 0x26, 0x7a, 0x1a, 0xd5, 0x60, 0x2e, 0x31, 0x51, 0xad, 0xe4, + 0x4c, 0x56, 0x1a, 0xdb, 0x44, 0x8a, 0x5f, 0xc2, 0x7c, 0x4a, 0x56, 0xd6, 0xf0, 0x05, 0x3c, 0x33, + 0x6b, 0x6b, 0x86, 0xfd, 0x50, 0x31, 0x3d, 0xe1, 0xa7, 0x34, 0x1b, 0xeb, 0x99, 0x13, 0xb4, 0x98, + 0x98, 0x05, 0x19, 0x6d, 0xd3, 0x45, 0x98, 0x94, 0x01, 0x54, 0x5d, 0x84, 0x19, 0x19, 0x42, 0x53, + 0x3c, 0xc4, 0xe6, 0x53, 0x92, 0x7e, 0x66, 0x50, 0xed, 0xa3, 0xb7, 0x9b, 0x62, 0xff, 0xd7, 0x53, + 0x23, 0x46, 0x4c, 0x91, 0x13, 0xf3, 0x26, 0x26, 0xf6, 0x53, 0x09, 0xad, 0xd0, 0x6e, 0x67, 0x88, + 0x41, 0x48, 0x8d, 0xad, 0x40, 0x20, 0xa9, 0xee, 0x7c, 0x52, 0xc5, 0xcd, 0xda, 0x51, 0x63, 0xc8, + 0x54, 0xf0, 0xfc, 0x08, 0x26, 0xea, 0x6a, 0xe3, 0x09, 0x8d, 0xa4, 0x2e, 0x0a, 0xe9, 0x5b, 0xd3, + 0xbb, 0xef, 0x19, 0xca, 0x1e, 0x79, 0x38, 0xf4, 0x35, 0x8a, 0x54, 0x8b, 0x15, 0x2d, 0x7b, 0x89, + 0xdc, 0xa9, 0x93, 0x12, 0x03, 0x49, 0x8b, 0x95, 0xe4, 0x84, 0x27, 0x0d, 0x16, 0x6f, 0x3d, 0x9a, + 0xf7, 0x09, 0x19, 0xbd, 0xf3, 0x99, 0x49, 0x4b, 0xf3, 0xcc, 0xc4, 0x51, 0xcc, 0xbc, 0x26, 0xcc, + 0xd7, 0xa2, 0x9a, 0xd7, 0xc4, 0xb2, 0xc0, 0xa8, 0xe6, 0x35, 0x09, 0x29, 0x5e, 0x56, 0x28, 0xad, + 0x30, 0x50, 0x7d, 0x86, 0xc2, 0x40, 0x92, 0x49, 0x88, 0x87, 0xff, 0x58, 0x8d, 0xd0, 0xc1, 0xc2, + 0xdb, 0x67, 0x68, 0x3c, 0xa3, 0x91, 0x39, 0x22, 0xf1, 0xf0, 0x1f, 0x41, 0x21, 0x1a, 0xda, 0x4b, + 0xaa, 0xa3, 0x52, 0x62, 0x7e, 0x65, 0x2c, 0x31, 0x08, 0x03, 0x78, 0x49, 0xa5, 0x4f, 0x2c, 0xa6, + 0x57, 0xf1, 0x62, 0x42, 0x8d, 0x14, 0xd7, 0x26, 0xd4, 0x70, 0x5f, 0xd2, 0x42, 0x2c, 0x21, 0x06, + 0x58, 0xf1, 0x52, 0x62, 0x1d, 0x27, 0x14, 0xb0, 0x54, 0x7c, 0xc9, 0x89, 0xfc, 0x42, 0xb7, 0xa6, + 0x0c, 0x18, 0xd1, 0xcc, 0xed, 0x7e, 0x40, 0x79, 0xab, 0x58, 0x86, 0xd7, 0x8f, 0x43, 0xa1, 0xb7, + 0x13, 0xdc, 0x0f, 0x34, 0x88, 0xd0, 0x78, 0x2a, 0x7c, 0x44, 0x4f, 0x4a, 0x56, 0x88, 0xf6, 0x44, + 0xb8, 0xf3, 0x94, 0x96, 0x7a, 0x11, 0x48, 0x9d, 0xc1, 0x3d, 0x11, 0xe0, 0xfc, 0xac, 0x09, 0xef, + 0xc3, 0x62, 0xc4, 0xbb, 0x41, 0x27, 0x7c, 0x3b, 0xd9, 0x05, 0x22, 0x91, 0x3d, 0xe9, 0xf2, 0xf0, + 0xd5, 0xb8, 0x2b, 0x44, 0x64, 0xde, 0x4f, 0xbb, 0x57, 0x3d, 0x81, 0x29, 0xba, 0x3d, 0x88, 0xf4, + 0x93, 0x61, 0x60, 0x17, 0xbd, 0x38, 0x1a, 0x61, 0x28, 0x5a, 0x2b, 0xbd, 0xc2, 0x27, 0xb8, 0x8b, + 0x2c, 0x4b, 0x66, 0x59, 0xd4, 0xfd, 0x66, 0x69, 0x61, 0xd2, 0xe9, 0xc3, 0x73, 0x64, 0xa2, 0x4f, + 0x61, 0x3a, 0xf4, 0x9c, 0x65, 0x24, 0x12, 0xc0, 0x32, 0x94, 0x50, 0xd3, 0xa1, 0xfb, 0xec, 0xe9, + 0xd1, 0xd7, 0xc4, 0x11, 0x12, 0xa2, 0x5f, 0x8e, 0x79, 0x85, 0x68, 0x63, 0xe8, 0xe7, 0x24, 0x51, + 0x78, 0x7b, 0xda, 0xd9, 0x69, 0xd2, 0xcf, 0x2d, 0x39, 0x8e, 0x9d, 0xfa, 0xb9, 0x65, 0xc6, 0xda, + 0x93, 0x62, 0x6b, 0x0a, 0x9d, 0x27, 0x70, 0x9d, 0xc6, 0x39, 0xa9, 0x61, 0xa7, 0x65, 0x3b, 0x07, + 0xc9, 0x50, 0xe9, 0x7d, 0x8f, 0x46, 0x47, 0x69, 0xc3, 0xb5, 0x9e, 0x81, 0xfc, 0xd0, 0x5d, 0xcd, + 0x22, 0xa4, 0x77, 0xc8, 0xbf, 0x2c, 0x4f, 0xac, 0xa4, 0x78, 0x78, 0xf2, 0x7c, 0xcc, 0x08, 0xcd, + 0x27, 0xcf, 0xc7, 0xcc, 0x80, 0x7a, 0x5f, 0xd2, 0x1c, 0x02, 0xfc, 0x6c, 0xa1, 0xb1, 0x8b, 0xb0, + 0xc3, 0x22, 0xfc, 0x66, 0x3e, 0xa9, 0x5c, 0xd3, 0x1f, 0x12, 0x63, 0x88, 0xf4, 0x2e, 0x72, 0x85, + 0xdf, 0xa0, 0xd2, 0x88, 0xf7, 0x26, 0x92, 0x61, 0x89, 0x7c, 0x85, 0x2d, 0xc0, 0x53, 0xf7, 0x3c, + 0xa5, 0xbc, 0xb2, 0xfc, 0xd3, 0x3f, 0xbf, 0x92, 0xfb, 0xe9, 0xcf, 0xae, 0xe4, 0xfe, 0xcd, 0xcf, + 0xae, 0xe4, 0xfe, 0xc3, 0xcf, 0xae, 0xe4, 0xbe, 0xbf, 0xd4, 0x5f, 0x9c, 0xd9, 0x66, 0xdb, 0xc6, + 0x4e, 0x70, 0x97, 0x91, 0x3b, 0x47, 0xff, 0x7b, 0xf0, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xf5, + 0x16, 0xea, 0x03, 0x34, 0xdd, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -31016,6 +31090,21 @@ func (m *MFAAuthenticateChallenge) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AllowReuse { + i-- + if m.AllowReuse { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if m.Scope != 0 { + i = encodeVarintAuthservice(dAtA, i, uint64(m.Scope)) + i-- + dAtA[i] = 0x28 + } if m.MFARequired != 0 { i = encodeVarintAuthservice(dAtA, i, uint64(m.MFARequired)) i-- @@ -31072,6 +31161,21 @@ func (m *MFAAuthenticateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AllowReuse { + i-- + if m.AllowReuse { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if m.Scope != 0 { + i = encodeVarintAuthservice(dAtA, i, uint64(m.Scope)) + i-- + dAtA[i] = 0x20 + } if m.Response != nil { { size := m.Response.Size() @@ -34365,6 +34469,21 @@ func (m *CreateAuthenticateChallengeRequest) MarshalToSizedBuffer(dAtA []byte) ( i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AllowReuse { + i-- + if m.AllowReuse { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + if m.Scope != 0 { + i = encodeVarintAuthservice(dAtA, i, uint64(m.Scope)) + i-- + dAtA[i] = 0x30 + } if m.MFARequiredCheck != nil { { size, err := m.MFARequiredCheck.MarshalToSizedBuffer(dAtA[:i]) @@ -40012,6 +40131,12 @@ func (m *MFAAuthenticateChallenge) Size() (n int) { if m.MFARequired != 0 { n += 1 + sovAuthservice(uint64(m.MFARequired)) } + if m.Scope != 0 { + n += 1 + sovAuthservice(uint64(m.Scope)) + } + if m.AllowReuse { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -40027,6 +40152,12 @@ func (m *MFAAuthenticateResponse) Size() (n int) { if m.Response != nil { n += m.Response.Size() } + if m.Scope != 0 { + n += 1 + sovAuthservice(uint64(m.Scope)) + } + if m.AllowReuse { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -41612,6 +41743,12 @@ func (m *CreateAuthenticateChallengeRequest) Size() (n int) { l = m.MFARequiredCheck.Size() n += 1 + l + sovAuthservice(uint64(l)) } + if m.Scope != 0 { + n += 1 + sovAuthservice(uint64(m.Scope)) + } + if m.AllowReuse { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -54638,6 +54775,45 @@ func (m *MFAAuthenticateChallenge) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + } + m.Scope = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Scope |= webauthn.ChallengeScope(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowReuse", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AllowReuse = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -54759,6 +54935,45 @@ func (m *MFAAuthenticateResponse) Unmarshal(dAtA []byte) error { } m.Response = &MFAAuthenticateResponse_Webauthn{v} iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + } + m.Scope = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Scope |= webauthn.ChallengeScope(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowReuse", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AllowReuse = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) @@ -62332,6 +62547,45 @@ func (m *CreateAuthenticateChallengeRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + } + m.Scope = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Scope |= webauthn.ChallengeScope(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowReuse", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AllowReuse = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) diff --git a/api/proto/teleport/legacy/client/proto/authservice.proto b/api/proto/teleport/legacy/client/proto/authservice.proto index 226bf41080080..c4ce135f7f90e 100644 --- a/api/proto/teleport/legacy/client/proto/authservice.proto +++ b/api/proto/teleport/legacy/client/proto/authservice.proto @@ -1145,6 +1145,15 @@ message MFAAuthenticateChallenge { // communications, in case of streaming RPCs. It may also return empty // challenges for all other fields. MFARequired MFARequired = 4; + // Scope is an authorization scope for this MFA challenge. + // Required. Only applies to webauthn challenges. + webauthn.ChallengeScope Scope = 5 [(gogoproto.jsontag) = "scope,omitempty"]; + // AllowReuse means webauthn credentials resolved from this challenge can be + // reused for a short span of time before the challenge expires. + // + // Reuse is only permitted for specific actions by the discretion of the server. + // See the server implementation for details. + bool AllowReuse = 6 [(gogoproto.jsontag) = "allow_reuse,omitempty"]; } // MFAAuthenticateResponse is a response to MFAAuthenticateChallenge using one @@ -1155,6 +1164,15 @@ message MFAAuthenticateResponse { TOTPResponse TOTP = 2; webauthn.CredentialAssertionResponse Webauthn = 3; } + // Scope is an authorization scope for this MFA challenge response. + // Required. Only applies to webauthn challenges. + webauthn.ChallengeScope Scope = 4 [(gogoproto.jsontag) = "scope,omitempty"]; + // AllowReuse means webauthn credentials resolved from this challenge can be + // reused for a short span of time before the challenge expires. + // + // Reuse is only permitted for specific actions by the discretion of the server. + // See the server implementation for details. + bool AllowReuse = 5 [(gogoproto.jsontag) = "allow_reuse,omitempty"]; } // TOTPChallenge is a challenge for all TOTP devices registered for a user. @@ -1839,6 +1857,15 @@ message CreateAuthenticateChallengeRequest { // If you are issuing challenges from the root cluster, but accessing a leaf, // call [AuthService.IsMFARequired] in the leaf instead of setting this field. IsMFARequiredRequest MFARequiredCheck = 5 [(gogoproto.jsontag) = "mfa_required_check,omitempty"]; + // Scope is an authorization scope for this MFA challenge. + // Required. Only applies to webauthn challenges. + webauthn.ChallengeScope Scope = 6 [(gogoproto.jsontag) = "scope,omitempty"]; + // AllowReuse means webauthn credentials resolved from this challenge can be + // reused for a short span of time before the challenge expires. + // + // Reuse is only permitted for specific actions by the discretion of the server. + // See the server implementation for details. + bool AllowReuse = 7 [(gogoproto.jsontag) = "allow_reuse,omitempty"]; } // CreatePrivilegeTokenRequest defines a request to obtain a privilege token. diff --git a/api/proto/teleport/legacy/types/webauthn/webauthn.proto b/api/proto/teleport/legacy/types/webauthn/webauthn.proto index 8b3f0c4a8dfe0..d7b256627c7cd 100644 --- a/api/proto/teleport/legacy/types/webauthn/webauthn.proto +++ b/api/proto/teleport/legacy/types/webauthn/webauthn.proto @@ -56,6 +56,36 @@ message SessionData { // "required". // An empty value is treated equivalently to "discouraged". string user_verification = 5 [(gogoproto.jsontag) = "userVerification,omitempty"]; + // Scope authorized by this webauthn session. + ChallengeScope scope = 6 [(gogoproto.jsontag) = "scope,omitempty"]; + // AllowReuse indicates that this session can be used multiple times for + // authentication, until the session expires. + bool allow_reuse = 7 [(gogoproto.jsontag) = "allow_reuse,omitempty"]; +} + +// ChallengeScope is a scope authorized by a webauthn challenge's resolution. +enum ChallengeScope { + // Invalid, scope should always be specified. + CHALLENGE_SCOPE_UNSPECIFIED = 0; + // Standard webauthn login. + CHALLENGE_SCOPE_LOGIN = 1; + // Passwordless webauthn login. + CHALLENGE_SCOPE_PASSWORDLESS_LOGIN = 2; + // MFA device management. + CHALLENGE_SCOPE_MANAGE_DEVICES = 3; + // Account recovery. + CHALLENGE_SCOPE_RECOVERY = 4; + // Used for per-session MFA and moderated session presence checks. + CHALLENGE_SCOPE_SESSION = 5; + // Headless login approval. + CHALLENGE_SCOPE_HEADLESS = 6; + // Used for various administrative actions, such as adding, updating, or + // deleting administrative resources (users, roles, etc.). + // + // Note: this scope should not be used for new MFA capabilities that have + // more precise scope. Instead, new scopes should be added. This scope may + // also be split into multiple smaller scopes in the future. + CHALLENGE_SCOPE_ADMIN_ACTION = 7; } // User represents a WebAuthn user. diff --git a/api/types/webauthn/webauthn.pb.go b/api/types/webauthn/webauthn.pb.go index 35fdb48a7605a..2a889271c0cb8 100644 --- a/api/types/webauthn/webauthn.pb.go +++ b/api/types/webauthn/webauthn.pb.go @@ -39,6 +39,63 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// ChallengeScope is a scope authorized by a webauthn challenge's resolution. +type ChallengeScope int32 + +const ( + // Invalid, scope should always be specified. + ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED ChallengeScope = 0 + // Standard webauthn login. + ChallengeScope_CHALLENGE_SCOPE_LOGIN ChallengeScope = 1 + // Passwordless webauthn login. + ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN ChallengeScope = 2 + // MFA device management. + ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES ChallengeScope = 3 + // Account recovery. + ChallengeScope_CHALLENGE_SCOPE_RECOVERY ChallengeScope = 4 + // Used for per-session MFA and moderated session presence checks. + ChallengeScope_CHALLENGE_SCOPE_SESSION ChallengeScope = 5 + // Headless login approval. + ChallengeScope_CHALLENGE_SCOPE_HEADLESS ChallengeScope = 6 + // Used for various administrative actions, such as adding, updating, or + // deleting administrative resources (users, roles, etc.). + // + // Note: this scope should not be used for new MFA capabilities that have + // more precise scope. Instead, new scopes should be added. This scope may + // also be split into multiple smaller scopes in the future. + ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION ChallengeScope = 7 +) + +var ChallengeScope_name = map[int32]string{ + 0: "CHALLENGE_SCOPE_UNSPECIFIED", + 1: "CHALLENGE_SCOPE_LOGIN", + 2: "CHALLENGE_SCOPE_PASSWORDLESS_LOGIN", + 3: "CHALLENGE_SCOPE_MANAGE_DEVICES", + 4: "CHALLENGE_SCOPE_RECOVERY", + 5: "CHALLENGE_SCOPE_SESSION", + 6: "CHALLENGE_SCOPE_HEADLESS", + 7: "CHALLENGE_SCOPE_ADMIN_ACTION", +} + +var ChallengeScope_value = map[string]int32{ + "CHALLENGE_SCOPE_UNSPECIFIED": 0, + "CHALLENGE_SCOPE_LOGIN": 1, + "CHALLENGE_SCOPE_PASSWORDLESS_LOGIN": 2, + "CHALLENGE_SCOPE_MANAGE_DEVICES": 3, + "CHALLENGE_SCOPE_RECOVERY": 4, + "CHALLENGE_SCOPE_SESSION": 5, + "CHALLENGE_SCOPE_HEADLESS": 6, + "CHALLENGE_SCOPE_ADMIN_ACTION": 7, +} + +func (x ChallengeScope) String() string { + return proto.EnumName(ChallengeScope_name, int32(x)) +} + +func (ChallengeScope) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0d490a6db28e8798, []int{0} +} + // SessionData stored by the Relying Party during authentication ceremonies. // Mirrors https://pkg.go.dev/github.com/go-webauthn/webauthn/webauthn#SessionData. type SessionData struct { @@ -53,7 +110,12 @@ type SessionData struct { // Requested user verification requirement, either "discouraged" or // "required". // An empty value is treated equivalently to "discouraged". - UserVerification string `protobuf:"bytes,5,opt,name=user_verification,json=userVerification,proto3" json:"userVerification,omitempty"` + UserVerification string `protobuf:"bytes,5,opt,name=user_verification,json=userVerification,proto3" json:"userVerification,omitempty"` + // Scope authorized by this webauthn session. + Scope ChallengeScope `protobuf:"varint,6,opt,name=scope,proto3,enum=webauthn.ChallengeScope" json:"scope,omitempty"` + // AllowReuse indicates that this session can be used multiple times for + // authentication, until the session expires. + AllowReuse bool `protobuf:"varint,7,opt,name=allow_reuse,json=allowReuse,proto3" json:"allow_reuse,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -127,6 +189,20 @@ func (m *SessionData) GetUserVerification() string { return "" } +func (m *SessionData) GetScope() ChallengeScope { + if m != nil { + return m.Scope + } + return ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED +} + +func (m *SessionData) GetAllowReuse() bool { + if m != nil { + return m.AllowReuse + } + return false +} + // User represents a WebAuthn user. // Used mainly to correlated a WebAuthn user handle with a Teleport user. type User struct { @@ -1220,6 +1296,7 @@ func (m *UserEntity) GetDisplayName() string { } func init() { + proto.RegisterEnum("webauthn.ChallengeScope", ChallengeScope_name, ChallengeScope_value) proto.RegisterType((*SessionData)(nil), "webauthn.SessionData") proto.RegisterType((*User)(nil), "webauthn.User") proto.RegisterType((*CredentialAssertion)(nil), "webauthn.CredentialAssertion") @@ -1244,75 +1321,87 @@ func init() { } var fileDescriptor_0d490a6db28e8798 = []byte{ - // 1073 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x5b, 0x6f, 0x1b, 0x45, - 0x14, 0xd6, 0xda, 0xeb, 0xd4, 0x3e, 0x36, 0x95, 0x3b, 0x71, 0x5b, 0x53, 0x5a, 0xc7, 0x5d, 0x40, - 0xb2, 0xc8, 0xc5, 0x28, 0x88, 0x07, 0x28, 0x17, 0xe5, 0x52, 0x44, 0x12, 0xb5, 0x89, 0xb6, 0x02, - 0x09, 0x5e, 0x56, 0xe3, 0xdd, 0x83, 0x3d, 0x65, 0xbd, 0xbb, 0x9d, 0x99, 0x6d, 0x6a, 0xf1, 0x93, - 0x78, 0xe3, 0x89, 0x37, 0x5e, 0x91, 0x78, 0xe1, 0x17, 0x84, 0x2a, 0x8f, 0xf9, 0x15, 0x68, 0x67, - 0xaf, 0xb6, 0x37, 0x4d, 0x00, 0x89, 0xb7, 0xd9, 0x73, 0xce, 0x77, 0x66, 0xe6, 0x7c, 0xe7, 0x3b, - 0x3b, 0xb0, 0x29, 0xd1, 0xc5, 0xc0, 0xe7, 0x72, 0xe8, 0xe2, 0x98, 0xda, 0xb3, 0xa1, 0x9c, 0x05, - 0x28, 0x86, 0xa7, 0x38, 0xa2, 0xa1, 0x9c, 0x78, 0xd9, 0x62, 0x2b, 0xe0, 0xbe, 0xf4, 0x49, 0x3d, - 0xfd, 0xbe, 0xd7, 0x19, 0xfb, 0x63, 0x5f, 0x19, 0x87, 0xd1, 0x2a, 0xf6, 0x1b, 0x7f, 0x54, 0xa0, - 0xf9, 0x0c, 0x85, 0x60, 0xbe, 0xb7, 0x4f, 0x25, 0x25, 0x1f, 0x43, 0xc3, 0x9e, 0x50, 0xd7, 0x45, - 0x6f, 0x8c, 0x5d, 0xad, 0xaf, 0x0d, 0x5a, 0xbb, 0x77, 0x2f, 0xce, 0xd6, 0x56, 0x33, 0xe3, 0x86, - 0x3f, 0x65, 0x12, 0xa7, 0x81, 0x9c, 0x99, 0x79, 0x24, 0xd9, 0x84, 0x1b, 0xa1, 0x40, 0x6e, 0x31, - 0xa7, 0x5b, 0x51, 0xa0, 0xce, 0xc5, 0xd9, 0x5a, 0x3b, 0x32, 0x1d, 0x38, 0x05, 0xc4, 0x4a, 0x6c, - 0x21, 0x47, 0x70, 0x8b, 0xba, 0xae, 0x7f, 0x6a, 0xd9, 0x1c, 0x1d, 0xf4, 0x24, 0xa3, 0xae, 0xe8, - 0x56, 0xfb, 0xd5, 0x41, 0x6b, 0xb7, 0x77, 0x71, 0xb6, 0x76, 0x4f, 0x39, 0xf7, 0x72, 0x5f, 0x21, - 0x45, 0x7b, 0xd1, 0x47, 0x3e, 0x83, 0x16, 0x47, 0xc1, 0xa2, 0x6f, 0xeb, 0x47, 0x9c, 0x75, 0xf5, - 0xbe, 0x36, 0xa8, 0xef, 0xbe, 0x7d, 0x71, 0xb6, 0x76, 0x3b, 0xb5, 0x1f, 0xe1, 0xac, 0x90, 0xa2, - 0x59, 0x30, 0x47, 0x47, 0x51, 0x27, 0x7f, 0x89, 0x9c, 0xfd, 0xc0, 0x6c, 0x2a, 0x99, 0xef, 0x75, - 0x6b, 0x7d, 0x6d, 0xd0, 0x88, 0x8f, 0x12, 0x39, 0xbf, 0x2d, 0xf8, 0x8a, 0x47, 0x59, 0xf4, 0x19, - 0xeb, 0xa0, 0x7f, 0x23, 0x90, 0x93, 0x77, 0xe1, 0xad, 0x94, 0x26, 0x2b, 0x0a, 0x52, 0x95, 0x6c, - 0x98, 0xad, 0xd4, 0x18, 0x05, 0x19, 0x14, 0x56, 0xf3, 0x6b, 0xec, 0x08, 0x81, 0x3c, 0xca, 0x41, - 0x0e, 0x01, 0x82, 0x70, 0xe4, 0x32, 0x5b, 0x5d, 0x26, 0x02, 0x36, 0xb7, 0xd7, 0xb7, 0x32, 0x5a, - 0x4f, 0x94, 0xef, 0x08, 0x67, 0x39, 0xd6, 0xc4, 0x17, 0x21, 0x0a, 0x79, 0x1c, 0x44, 0x78, 0x61, - 0x36, 0x82, 0x34, 0xc4, 0xf8, 0xad, 0x02, 0x0f, 0xaf, 0x04, 0x90, 0xfb, 0x4b, 0x9c, 0x17, 0xa9, - 0x7d, 0x00, 0x20, 0xd9, 0x14, 0xfd, 0x50, 0x5a, 0x53, 0xa1, 0xd8, 0xad, 0x9a, 0x8d, 0xc4, 0xf2, - 0x44, 0x90, 0x55, 0xa8, 0xf1, 0x20, 0xe2, 0xbd, 0xaa, 0xae, 0xa8, 0xf3, 0xe0, 0x32, 0x7e, 0xf5, - 0x7e, 0x75, 0xd0, 0xdc, 0xee, 0xe5, 0x57, 0xc9, 0x0f, 0xb4, 0x8f, 0xc2, 0xe6, 0x2c, 0x90, 0x3e, - 0x2f, 0xe1, 0xf7, 0x29, 0x00, 0xbe, 0x92, 0xe8, 0x45, 0x3d, 0x2a, 0x14, 0x35, 0xcd, 0xed, 0xad, - 0x3c, 0xcb, 0x4e, 0x28, 0x27, 0x51, 0x68, 0x4c, 0xc1, 0xe3, 0x2c, 0x72, 0xcf, 0x65, 0xe8, 0xc9, - 0x03, 0x2f, 0x08, 0xa5, 0x30, 0x0b, 0x19, 0xc8, 0x7a, 0x19, 0xe3, 0x2b, 0xea, 0xf4, 0xcb, 0x8c, - 0xfe, 0xa5, 0xc1, 0x3b, 0x25, 0x2c, 0x99, 0x28, 0x02, 0xdf, 0x13, 0x48, 0x08, 0xe8, 0x91, 0x00, - 0x13, 0x82, 0xd5, 0x9a, 0xdc, 0x86, 0x15, 0x4e, 0x4f, 0x33, 0x2d, 0x98, 0x35, 0x4e, 0x4f, 0x0f, - 0x1c, 0xb2, 0x0f, 0x75, 0x9e, 0xc0, 0x54, 0xb1, 0x9a, 0xdb, 0x83, 0xd2, 0x5b, 0xf8, 0x7c, 0x69, - 0x1b, 0x33, 0x43, 0x92, 0xe3, 0xb9, 0x6a, 0xe8, 0x2a, 0xcf, 0xf0, 0xba, 0xd5, 0x38, 0x0e, 0xe5, - 0x62, 0x39, 0x8c, 0x5f, 0x35, 0xe8, 0xbd, 0x79, 0x77, 0x32, 0x80, 0xb6, 0xad, 0xf0, 0x96, 0x43, - 0x25, 0xb5, 0x9e, 0x0b, 0xdf, 0x4b, 0xfa, 0xe4, 0x66, 0x6c, 0x8f, 0x46, 0xc7, 0xa1, 0xf0, 0x3d, - 0xb2, 0x09, 0x84, 0x16, 0x73, 0x29, 0x40, 0x52, 0x86, 0x5b, 0x73, 0x1e, 0x35, 0x6d, 0xee, 0x43, - 0x43, 0xb0, 0xb1, 0x47, 0x65, 0xc8, 0xe3, 0x9a, 0xb4, 0xcc, 0xdc, 0x40, 0xd6, 0xa0, 0xa9, 0x88, - 0x9a, 0x50, 0xcf, 0x71, 0x51, 0xdd, 0xb5, 0x65, 0x42, 0x64, 0xfa, 0x5a, 0x59, 0x0c, 0x0a, 0x24, - 0xe7, 0x66, 0x8f, 0xa3, 0xba, 0x33, 0x39, 0x2a, 0x11, 0xd0, 0xc6, 0x1b, 0x05, 0x94, 0x42, 0x4b, - 0x14, 0xf4, 0xb3, 0x0e, 0xc6, 0xd5, 0x88, 0x2b, 0x24, 0xb4, 0x01, 0x15, 0x1e, 0xa8, 0x2a, 0x34, - 0xb7, 0xef, 0xe7, 0x27, 0x31, 0xd1, 0x9d, 0x31, 0x6f, 0x7c, 0x42, 0xb9, 0x9c, 0x3d, 0xf6, 0x24, - 0x93, 0x33, 0xb3, 0xc2, 0x03, 0x32, 0x00, 0x5d, 0xcd, 0x8c, 0xb8, 0x47, 0x3a, 0x79, 0x7c, 0x34, - 0x35, 0x92, 0x38, 0x15, 0x41, 0x4c, 0xb8, 0x9d, 0x0b, 0xcc, 0x0a, 0x28, 0xa7, 0x53, 0x94, 0xc8, - 0x53, 0xa9, 0x3d, 0x28, 0x93, 0xda, 0x49, 0x1a, 0x65, 0x76, 0xec, 0x65, 0xa3, 0x58, 0x90, 0x7b, - 0x6d, 0x51, 0xee, 0xc7, 0xb0, 0x8a, 0xaf, 0x6c, 0x37, 0x74, 0x70, 0x4e, 0xdb, 0x2b, 0xd7, 0xd2, - 0x36, 0x49, 0xa0, 0x45, 0x75, 0xf7, 0xa1, 0x49, 0xa5, 0x44, 0x21, 0x63, 0x1d, 0xde, 0x50, 0x3a, - 0x2a, 0x9a, 0x16, 0xf4, 0x5f, 0xff, 0xcf, 0xfa, 0xff, 0x0e, 0xee, 0xce, 0xf7, 0xa8, 0x40, 0x17, - 0x6d, 0xb5, 0x7b, 0x43, 0x25, 0xef, 0x5f, 0x22, 0xcb, 0x67, 0x69, 0x9c, 0x79, 0x87, 0x96, 0xda, - 0x8d, 0xd7, 0x1a, 0xdc, 0x5b, 0x6e, 0x92, 0x7f, 0x33, 0x2c, 0xbe, 0x5a, 0x1a, 0x16, 0x1f, 0x5c, - 0x36, 0x2c, 0xf2, 0x52, 0xfd, 0x1f, 0xe3, 0xe2, 0x27, 0xe8, 0x5f, 0xb5, 0xfd, 0x3f, 0x9c, 0x17, - 0x79, 0x02, 0xcb, 0x1f, 0x3d, 0x47, 0x5b, 0x66, 0xf3, 0x22, 0xf7, 0x1c, 0x2b, 0x87, 0xf1, 0x39, - 0xbc, 0x77, 0x1d, 0xba, 0xa3, 0xa2, 0xd2, 0x40, 0xfd, 0x95, 0xe2, 0x52, 0xd7, 0x68, 0x10, 0x1c, - 0x38, 0xc6, 0x17, 0xf0, 0xfe, 0xb5, 0x2e, 0xbc, 0x80, 0xaf, 0xa7, 0xf8, 0x5f, 0x34, 0xb8, 0x53, - 0xde, 0x11, 0xe4, 0x13, 0xe8, 0xce, 0x37, 0x15, 0x95, 0x92, 0xda, 0x93, 0x29, 0x7a, 0x32, 0x39, - 0xc3, 0x7c, 0xd3, 0xed, 0x64, 0x6e, 0xf2, 0x21, 0x74, 0x38, 0xbe, 0x08, 0x19, 0x47, 0x6b, 0xee, - 0x1d, 0x53, 0x51, 0x5b, 0x93, 0xc4, 0x67, 0x16, 0xde, 0x2c, 0xa5, 0x7f, 0xb0, 0xea, 0x25, 0x7f, - 0xb0, 0x4f, 0xa1, 0x53, 0x26, 0xc6, 0xd2, 0x66, 0xbc, 0x09, 0x95, 0xac, 0x11, 0x2b, 0xcc, 0x31, - 0x1e, 0x15, 0x9f, 0x28, 0xd9, 0x90, 0x28, 0x85, 0xb6, 0xa1, 0x4a, 0xdd, 0xb1, 0xc2, 0xd6, 0xcc, - 0x68, 0x69, 0xec, 0x03, 0x59, 0x9e, 0x70, 0xc9, 0x16, 0x31, 0xb2, 0xc2, 0x9c, 0x28, 0x97, 0x47, - 0xa7, 0xa8, 0x80, 0x0d, 0x53, 0xad, 0x0f, 0xf5, 0x7a, 0xb5, 0xad, 0x9b, 0x3a, 0xb3, 0x7d, 0xcf, - 0xb0, 0x00, 0xf2, 0xb9, 0x57, 0x40, 0xb7, 0x2e, 0x43, 0x93, 0x87, 0xd0, 0x72, 0x98, 0x08, 0x5c, - 0x3a, 0xb3, 0x94, 0x2f, 0x2e, 0x4c, 0x33, 0xb1, 0x3d, 0x8d, 0x37, 0xd0, 0xdb, 0xb5, 0x78, 0x83, - 0xdd, 0x27, 0xbf, 0x9f, 0xf7, 0xb4, 0x3f, 0xcf, 0x7b, 0xda, 0xeb, 0xf3, 0x9e, 0xf6, 0xfd, 0x97, - 0x63, 0x26, 0x27, 0xe1, 0x68, 0xcb, 0xf6, 0xa7, 0xc3, 0x31, 0xa7, 0x2f, 0x59, 0xdc, 0x7f, 0xd4, - 0x1d, 0x66, 0xef, 0x6e, 0x1a, 0xb0, 0x85, 0x47, 0xf7, 0xa3, 0x74, 0x11, 0x8c, 0x46, 0x2b, 0xea, - 0x5d, 0xfd, 0xd1, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x89, 0xb7, 0x8c, 0x49, 0xa8, 0x0b, 0x00, - 0x00, + // 1275 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcb, 0x6e, 0xdb, 0x46, + 0x17, 0xfe, 0x29, 0x51, 0xb2, 0x75, 0xa4, 0xdf, 0x55, 0xc6, 0x76, 0xa2, 0x24, 0x8e, 0xa4, 0xb0, + 0x17, 0x08, 0xb9, 0x58, 0x85, 0x8b, 0x2e, 0x9a, 0xf4, 0x02, 0x59, 0x62, 0x12, 0xc5, 0xb6, 0x64, + 0x90, 0x4d, 0x8a, 0x74, 0x43, 0x8c, 0xa9, 0xa9, 0xc4, 0x94, 0x22, 0x99, 0x99, 0x61, 0x1c, 0xa1, + 0x8f, 0xd1, 0xc7, 0xe8, 0xae, 0xab, 0xee, 0xba, 0xed, 0xa2, 0x8b, 0x3e, 0x81, 0x1b, 0x78, 0xe9, + 0xa7, 0x28, 0x38, 0x94, 0x44, 0x8a, 0xa2, 0x63, 0xb7, 0x05, 0xba, 0x1b, 0x9e, 0xef, 0x7c, 0x73, + 0x39, 0xf3, 0x7d, 0x87, 0x24, 0xdc, 0xe7, 0xc4, 0x26, 0x9e, 0x4b, 0x79, 0xd3, 0x26, 0x43, 0x6c, + 0x4e, 0x9a, 0x7c, 0xe2, 0x11, 0xd6, 0x3c, 0x26, 0x47, 0xd8, 0xe7, 0x23, 0x67, 0x3e, 0xd8, 0xf6, + 0xa8, 0xcb, 0x5d, 0xb4, 0x3a, 0x7b, 0xbe, 0xb1, 0x31, 0x74, 0x87, 0xae, 0x08, 0x36, 0x83, 0x51, + 0x88, 0x2b, 0xbf, 0x67, 0xa1, 0xa8, 0x13, 0xc6, 0x2c, 0xd7, 0xe9, 0x60, 0x8e, 0xd1, 0xa7, 0x50, + 0x30, 0x47, 0xd8, 0xb6, 0x89, 0x33, 0x24, 0x15, 0xa9, 0x2e, 0x35, 0x4a, 0xbb, 0xd7, 0xce, 0x4e, + 0x6a, 0xeb, 0xf3, 0xe0, 0x3d, 0x77, 0x6c, 0x71, 0x32, 0xf6, 0xf8, 0x44, 0x8b, 0x32, 0xd1, 0x7d, + 0x58, 0xf1, 0x19, 0xa1, 0x86, 0x35, 0xa8, 0x64, 0x04, 0x69, 0xe3, 0xec, 0xa4, 0x56, 0x0e, 0x42, + 0xdd, 0x41, 0x8c, 0x91, 0x0f, 0x23, 0x68, 0x0f, 0xae, 0x60, 0xdb, 0x76, 0x8f, 0x0d, 0x93, 0x92, + 0x01, 0x71, 0xb8, 0x85, 0x6d, 0x56, 0xc9, 0xd6, 0xb3, 0x8d, 0xd2, 0x6e, 0xf5, 0xec, 0xa4, 0x76, + 0x43, 0x80, 0xed, 0x08, 0x8b, 0x4d, 0x51, 0x4e, 0x62, 0xe8, 0x73, 0x28, 0x51, 0xc2, 0xac, 0xe0, + 0xd9, 0xf8, 0x9e, 0x4c, 0x2a, 0x72, 0x5d, 0x6a, 0xac, 0xee, 0x5e, 0x3f, 0x3b, 0xa9, 0x6d, 0xce, + 0xe2, 0x7b, 0x64, 0x12, 0x9b, 0xa2, 0x18, 0x0b, 0x07, 0x5b, 0x11, 0x3b, 0x7f, 0x4d, 0xa8, 0xf5, + 0x9d, 0x65, 0x62, 0x6e, 0xb9, 0x4e, 0x25, 0x57, 0x97, 0x1a, 0x85, 0x70, 0x2b, 0x01, 0xf8, 0x3c, + 0x86, 0xc5, 0xb7, 0x92, 0xc4, 0x50, 0x1b, 0x72, 0xcc, 0x74, 0x3d, 0x52, 0xc9, 0xd7, 0xa5, 0xc6, + 0xda, 0x4e, 0x65, 0x7b, 0x7e, 0x1b, 0xed, 0x59, 0xa9, 0xf4, 0x00, 0xdf, 0x5d, 0x3f, 0x3b, 0xa9, + 0xbd, 0x27, 0x52, 0x63, 0xf3, 0x85, 0x5c, 0xf4, 0x00, 0x8a, 0x61, 0x71, 0x28, 0xf1, 0x19, 0xa9, + 0xac, 0x44, 0xc7, 0x89, 0x85, 0x63, 0x34, 0x10, 0x61, 0x2d, 0x88, 0x2a, 0x77, 0x41, 0x7e, 0xc6, + 0x08, 0x45, 0xef, 0xc3, 0xff, 0x67, 0x3a, 0x31, 0x82, 0x5d, 0x8a, 0xab, 0x2c, 0x68, 0xa5, 0x59, + 0x30, 0x48, 0x52, 0x30, 0xac, 0x47, 0x75, 0x6c, 0x31, 0x46, 0xa8, 0x38, 0xc4, 0x53, 0x00, 0xcf, + 0x3f, 0xb2, 0x2d, 0x53, 0x54, 0x33, 0x20, 0x16, 0x77, 0xee, 0x46, 0x27, 0x39, 0x14, 0xd8, 0x1e, + 0x99, 0x44, 0x5c, 0x8d, 0xbc, 0xf2, 0x09, 0xe3, 0x7d, 0x2f, 0xe0, 0x33, 0xad, 0xe0, 0xcd, 0x52, + 0x94, 0x5f, 0x33, 0x70, 0xfb, 0x42, 0x02, 0xda, 0x5a, 0x12, 0x5d, 0x5c, 0x5b, 0xb7, 0x00, 0xb8, + 0x35, 0x26, 0xae, 0xcf, 0x8d, 0x31, 0x13, 0xf2, 0xca, 0x6a, 0x85, 0x69, 0xe4, 0x80, 0xa1, 0x75, + 0xc8, 0x51, 0x2f, 0x10, 0x5e, 0x56, 0x1c, 0x51, 0xa6, 0xde, 0x79, 0x02, 0x93, 0xeb, 0xd9, 0x46, + 0x71, 0xa7, 0x1a, 0xbb, 0x94, 0x39, 0xd8, 0x21, 0xcc, 0xa4, 0x96, 0xc7, 0x5d, 0x9a, 0x22, 0xb0, + 0x1e, 0x00, 0x79, 0xc3, 0x89, 0x13, 0x98, 0x84, 0x09, 0x6d, 0x14, 0x77, 0xb6, 0xa3, 0x59, 0x5a, + 0x3e, 0x1f, 0x05, 0xa9, 0xa1, 0x06, 0xd4, 0x79, 0x66, 0xdb, 0xb6, 0x88, 0xc3, 0xbb, 0x8e, 0xe7, + 0x73, 0xa6, 0xc5, 0x66, 0x40, 0x77, 0xd3, 0x24, 0x97, 0x17, 0xbb, 0x5f, 0x92, 0x94, 0xf2, 0xa7, + 0x04, 0x37, 0x53, 0x6e, 0x49, 0x23, 0xcc, 0x73, 0x1d, 0x46, 0x10, 0x02, 0x39, 0xe8, 0x00, 0xd3, + 0x0b, 0x16, 0x63, 0xb4, 0x09, 0x79, 0x8a, 0x8f, 0xe7, 0x66, 0xd4, 0x72, 0x14, 0x1f, 0x77, 0x07, + 0xa8, 0x03, 0xab, 0x74, 0x4a, 0x13, 0xc5, 0x2a, 0xee, 0x34, 0x52, 0x4f, 0xe1, 0xd2, 0xa5, 0x65, + 0xb4, 0x39, 0x13, 0xf5, 0x17, 0xaa, 0x21, 0x8b, 0x79, 0x9a, 0x97, 0xad, 0x46, 0xdf, 0xe7, 0xc9, + 0x72, 0x28, 0xbf, 0x48, 0x50, 0x7d, 0xf7, 0xea, 0xa8, 0x01, 0x65, 0x53, 0xf0, 0x8d, 0x01, 0xe6, + 0xd8, 0x78, 0xc9, 0x5c, 0x67, 0xaa, 0x93, 0xb5, 0x30, 0x1e, 0xf4, 0xae, 0xa7, 0xcc, 0x75, 0xd0, + 0x7d, 0x40, 0x38, 0x3e, 0x97, 0x20, 0x4c, 0xcb, 0x70, 0x65, 0x01, 0x11, 0xed, 0x6e, 0x0b, 0x0a, + 0xcc, 0x1a, 0x3a, 0x98, 0xfb, 0x34, 0xac, 0x49, 0x49, 0x8b, 0x02, 0xa8, 0x06, 0x45, 0x71, 0x51, + 0x23, 0xec, 0x0c, 0x6c, 0x22, 0xce, 0x5a, 0xd2, 0x20, 0x08, 0x3d, 0x11, 0x11, 0x05, 0x03, 0x8a, + 0xee, 0xa6, 0x4d, 0x49, 0xd8, 0x05, 0xf6, 0x52, 0x0c, 0x74, 0xef, 0x9d, 0x06, 0x9a, 0x51, 0x53, + 0x1c, 0xf4, 0x93, 0x0c, 0xca, 0xc5, 0x8c, 0x0b, 0x2c, 0x74, 0x0f, 0x32, 0xd4, 0x13, 0x55, 0x28, + 0xee, 0x6c, 0x45, 0x3b, 0xd1, 0x88, 0x3d, 0xb1, 0x9c, 0xe1, 0x21, 0xa6, 0x7c, 0xa2, 0x3a, 0xdc, + 0xe2, 0x13, 0x2d, 0x43, 0x3d, 0xd4, 0x00, 0x59, 0xf4, 0x8c, 0x50, 0x23, 0x1b, 0x51, 0x7e, 0xd0, + 0x35, 0xa6, 0x79, 0x22, 0x03, 0x69, 0xb0, 0x19, 0x19, 0xcc, 0xf0, 0x30, 0xc5, 0x63, 0xc2, 0x09, + 0x9d, 0x59, 0xed, 0x56, 0x9a, 0xd5, 0x0e, 0x67, 0x59, 0xda, 0x86, 0xb9, 0x1c, 0x64, 0x09, 0xbb, + 0xe7, 0x92, 0x76, 0xef, 0xc3, 0x3a, 0x79, 0x63, 0xda, 0xfe, 0x80, 0x2c, 0x78, 0x3b, 0x7f, 0x29, + 0x6f, 0xa3, 0x29, 0x35, 0xee, 0xee, 0x3a, 0x14, 0x31, 0xe7, 0x84, 0xf1, 0xd0, 0x87, 0x2b, 0xc2, + 0x47, 0xf1, 0x50, 0xc2, 0xff, 0xab, 0xff, 0xda, 0xff, 0x2f, 0xe0, 0xda, 0xa2, 0x46, 0x19, 0xb1, + 0x89, 0x29, 0x56, 0x2f, 0x88, 0xc9, 0xeb, 0xe7, 0xd8, 0x52, 0x9f, 0xe5, 0x69, 0x57, 0x71, 0x6a, + 0x5c, 0x79, 0x2b, 0xc1, 0x8d, 0x65, 0x91, 0xfc, 0x93, 0x66, 0xf1, 0x68, 0xa9, 0x59, 0xdc, 0x39, + 0xaf, 0x59, 0x44, 0xa5, 0xfa, 0x2f, 0xda, 0xc5, 0x0f, 0x50, 0xbf, 0x68, 0xf9, 0xbf, 0xd9, 0x2f, + 0xa2, 0x09, 0x0c, 0xf7, 0xe8, 0x25, 0x31, 0xf9, 0xbc, 0x5f, 0x44, 0x48, 0x5f, 0x00, 0xca, 0x17, + 0xf0, 0xc1, 0x65, 0xae, 0x3b, 0x28, 0x2a, 0xf6, 0xc4, 0x5b, 0x29, 0x2c, 0x75, 0x0e, 0x7b, 0x5e, + 0x77, 0xa0, 0x7c, 0x09, 0x1f, 0x5e, 0xea, 0xc0, 0x09, 0xfe, 0xea, 0x8c, 0xff, 0xb3, 0x04, 0x57, + 0xd3, 0x15, 0x81, 0x3e, 0x83, 0xca, 0xa2, 0xa8, 0x30, 0xe7, 0xd8, 0x1c, 0x8d, 0x89, 0xc3, 0xa7, + 0x7b, 0x58, 0x14, 0x5d, 0x6b, 0x0e, 0xa3, 0x8f, 0x61, 0x83, 0x92, 0x57, 0xbe, 0x45, 0x89, 0xb1, + 0xf0, 0x21, 0x95, 0x11, 0x4b, 0xa3, 0x29, 0xa6, 0xc5, 0x3e, 0x9a, 0x52, 0xdf, 0x60, 0xd9, 0x73, + 0xde, 0x60, 0x0f, 0x60, 0x23, 0xcd, 0x8c, 0xa9, 0x62, 0x5c, 0x83, 0xcc, 0x5c, 0x88, 0x19, 0x6b, + 0xa0, 0x3c, 0x8c, 0x7f, 0xa2, 0xcc, 0x9b, 0x44, 0x2a, 0xb5, 0x0c, 0x59, 0x6c, 0x0f, 0x05, 0x37, + 0xa7, 0x05, 0x43, 0xa5, 0x03, 0x68, 0xb9, 0xc3, 0x4d, 0x97, 0x08, 0x99, 0x19, 0x6b, 0x10, 0xcc, + 0xe5, 0xe0, 0x31, 0x11, 0xc4, 0x82, 0x26, 0xc6, 0x4f, 0xe5, 0xd5, 0x6c, 0x59, 0xd6, 0x64, 0xcb, + 0x74, 0x1d, 0xc5, 0x00, 0x88, 0xfa, 0x5e, 0x8c, 0x5d, 0x3a, 0x8f, 0x8d, 0x6e, 0x43, 0x69, 0x60, + 0x31, 0xcf, 0xc6, 0x13, 0x43, 0x60, 0x61, 0x61, 0x8a, 0xd3, 0x58, 0x2f, 0x5c, 0x40, 0x2e, 0xe7, + 0xc2, 0x05, 0xee, 0xfc, 0x98, 0x81, 0xb5, 0xc5, 0xcf, 0x43, 0x54, 0x83, 0x9b, 0xed, 0x27, 0xad, + 0xfd, 0x7d, 0xb5, 0xf7, 0x58, 0x35, 0xf4, 0x76, 0xff, 0x50, 0x35, 0x9e, 0xf5, 0xf4, 0x43, 0xb5, + 0xdd, 0x7d, 0xd4, 0x55, 0x3b, 0xe5, 0xff, 0xa1, 0xeb, 0xb0, 0x99, 0x4c, 0xd8, 0xef, 0x3f, 0xee, + 0xf6, 0xca, 0x12, 0xfa, 0x08, 0x94, 0x24, 0x74, 0xd8, 0xd2, 0xf5, 0x6f, 0xfa, 0x5a, 0x67, 0x5f, + 0xd5, 0xf5, 0x69, 0x5e, 0x06, 0x29, 0x50, 0x4d, 0xe6, 0x1d, 0xb4, 0x7a, 0xad, 0xc7, 0xaa, 0xd1, + 0x51, 0x9f, 0x77, 0xdb, 0xaa, 0x5e, 0xce, 0xa2, 0x2d, 0xa8, 0x24, 0x73, 0x34, 0xb5, 0xdd, 0x7f, + 0xae, 0x6a, 0x2f, 0xca, 0x32, 0xba, 0x09, 0xd7, 0x92, 0xa8, 0xae, 0xea, 0x7a, 0xb7, 0xdf, 0x2b, + 0xe7, 0xd2, 0xa8, 0x4f, 0xd4, 0x96, 0xd8, 0x42, 0x39, 0x8f, 0xea, 0xb0, 0x95, 0x44, 0x5b, 0x9d, + 0x83, 0x6e, 0xcf, 0x68, 0xb5, 0xbf, 0x0e, 0xf8, 0x2b, 0xbb, 0x07, 0xbf, 0x9d, 0x56, 0xa5, 0x3f, + 0x4e, 0xab, 0xd2, 0xdb, 0xd3, 0xaa, 0xf4, 0xed, 0x57, 0x43, 0x8b, 0x8f, 0xfc, 0xa3, 0x6d, 0xd3, + 0x1d, 0x37, 0x87, 0x14, 0xbf, 0xb6, 0x42, 0x57, 0x62, 0xbb, 0x39, 0xff, 0x1d, 0xc2, 0x9e, 0x95, + 0xf8, 0x17, 0x7a, 0x38, 0x1b, 0x78, 0x47, 0x47, 0x79, 0xf1, 0xbb, 0xf3, 0xc9, 0x5f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0xa3, 0x95, 0xc6, 0x0d, 0x3f, 0x0d, 0x00, 0x00, } func (m *SessionData) Marshal() (dAtA []byte, err error) { @@ -1339,6 +1428,21 @@ func (m *SessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AllowReuse { + i-- + if m.AllowReuse { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + if m.Scope != 0 { + i = encodeVarintWebauthn(dAtA, i, uint64(m.Scope)) + i-- + dAtA[i] = 0x30 + } if len(m.UserVerification) > 0 { i -= len(m.UserVerification) copy(dAtA[i:], m.UserVerification) @@ -2250,6 +2354,12 @@ func (m *SessionData) Size() (n int) { if l > 0 { n += 1 + l + sovWebauthn(uint64(l)) } + if m.Scope != 0 { + n += 1 + sovWebauthn(uint64(m.Scope)) + } + if m.AllowReuse { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2820,6 +2930,45 @@ func (m *SessionData) Unmarshal(dAtA []byte) error { } m.UserVerification = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + } + m.Scope = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWebauthn + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Scope |= ChallengeScope(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowReuse", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWebauthn + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AllowReuse = bool(v != 0) default: iNdEx = preIndex skippy, err := skipWebauthn(dAtA[iNdEx:]) diff --git a/lib/auth/accountrecovery.go b/lib/auth/accountrecovery.go index 051114c4e73e1..113fb20c3fa0c 100644 --- a/lib/auth/accountrecovery.go +++ b/lib/auth/accountrecovery.go @@ -32,6 +32,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/defaults" @@ -264,8 +265,8 @@ func (a *Server) VerifyAccountRecovery(ctx context.Context, req *proto.VerifyAcc } if err := a.verifyAuthnWithRecoveryLock(ctx, startToken, func() error { - _, _, err := a.ValidateMFAAuthResponse( - ctx, req.GetMFAAuthenticateResponse(), startToken.GetUser(), false /* passwordless */) + _, _, err := a.ValidateMFAAuthResponseWithScope( + ctx, req.GetMFAAuthenticateResponse(), startToken.GetUser(), webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES) return err }); err != nil { return nil, trace.Wrap(err) diff --git a/lib/auth/auth.go b/lib/auth/auth.go index d9fd624675e88..5e439c757206a 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -70,6 +70,7 @@ import ( "github.com/gravitational/teleport/api/metadata" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/types/wrappers" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/keys" @@ -2900,11 +2901,12 @@ func (a *Server) PreAuthenticatedSignIn(ctx context.Context, user string, identi // CreateAuthenticateChallenge implements AuthService.CreateAuthenticateChallenge. func (a *Server) CreateAuthenticateChallenge(ctx context.Context, req *proto.CreateAuthenticateChallengeRequest) (*proto.MFAAuthenticateChallenge, error) { var username string - var passwordless bool + scope := req.Scope switch req.GetRequest().(type) { case *proto.CreateAuthenticateChallengeRequest_UserCredentials: username = req.GetUserCredentials().GetUsername() + scope = webauthnpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN if err := a.WithUserLock(ctx, username, func() error { return a.checkPasswordWOToken(username, req.GetUserCredentials().GetPassword()) @@ -2924,11 +2926,13 @@ func (a *Server) CreateAuthenticateChallenge(ctx context.Context, req *proto.Cre } username = token.GetUser() + scope = webauthnpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN case *proto.CreateAuthenticateChallengeRequest_Passwordless: - passwordless = true // Allows empty username. + scope = webauthnpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN default: // unset or CreateAuthenticateChallengeRequest_ContextUser. + // TODO(Joerger): in v16.0.0, require scope to be specified in the request. var err error username, err = authz.GetClientUsername(ctx) if err != nil { @@ -2936,7 +2940,7 @@ func (a *Server) CreateAuthenticateChallenge(ctx context.Context, req *proto.Cre } } - challenges, err := a.mfaAuthChallenge(ctx, username, passwordless) + challenges, err := a.mfaAuthChallenge(ctx, username, scope, req.AllowReuse) if err != nil { log.Error(trace.DebugReport(err)) return nil, trace.AccessDenied("unable to create MFA challenges") @@ -3178,9 +3182,7 @@ func (a *Server) DeleteMFADeviceSync(ctx context.Context, req *proto.DeleteMFADe return trace.Wrap(err) } - if _, _, err := a.ValidateMFAAuthResponse( - ctx, req.ExistingMFAResponse, user, false, /* passwordless */ - ); err != nil { + if _, _, err := a.ValidateMFAAuthResponseWithScope(ctx, req.ExistingMFAResponse, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES); err != nil { return trace.Wrap(err) } @@ -5660,7 +5662,7 @@ func (a *Server) isMFARequired(ctx context.Context, checker services.AccessCheck // mfaAuthChallenge constructs an MFAAuthenticateChallenge for all MFA devices // registered by the user. -func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless bool) (*proto.MFAAuthenticateChallenge, error) { +func (a *Server) mfaAuthChallenge(ctx context.Context, user string, scope webauthnpb.ChallengeScope, allowReuse bool) (*proto.MFAAuthenticateChallenge, error) { // Check what kind of MFA is enabled. apref, err := a.GetAuthPreference(ctx) if err != nil { @@ -5688,8 +5690,13 @@ func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless webConfig = val } + challenge := &proto.MFAAuthenticateChallenge{ + Scope: scope, + AllowReuse: allowReuse, + } + // Handle passwordless separately, it works differently from MFA. - if passwordless { + if scope == webauthnpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN { if !enableWebauthn { return nil, trace.BadParameter("passwordless requires WebAuthn") } @@ -5701,9 +5708,8 @@ func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless if err != nil { return nil, trace.Wrap(err) } - return &proto.MFAAuthenticateChallenge{ - WebauthnChallenge: wantypes.CredentialAssertionToProto(assertion), - }, nil + challenge.WebauthnChallenge = wantypes.CredentialAssertionToProto(assertion) + return challenge, nil } // User required for non-passwordless. @@ -5716,7 +5722,6 @@ func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless return nil, trace.Wrap(err) } groupedDevs := groupByDeviceType(devs, enableWebauthn) - challenge := &proto.MFAAuthenticateChallenge{} // TOTP challenge. if enableTOTP && groupedDevs.TOTP { @@ -5730,7 +5735,7 @@ func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless Webauthn: webConfig, Identity: wanlib.WithDevices(a.Services, groupedDevs.Webauthn), } - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, scope, allowReuse) if err != nil { return nil, trace.Wrap(err) } @@ -5804,8 +5809,7 @@ func (a *Server) validateMFAAuthResponseForRegister( } if err := a.WithUserLock(ctx, username, func() error { - _, _, err := a.ValidateMFAAuthResponse( - ctx, resp, username, false /* passwordless */) + _, _, err := a.ValidateMFAAuthResponseWithScope(ctx, resp, username, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES) return err }); err != nil { return false, trace.Wrap(err) @@ -5814,9 +5818,28 @@ func (a *Server) validateMFAAuthResponseForRegister( return true, nil } -// ValidateMFAAuthResponse validates an MFA or passwordless challenge. -// Returns the device used to solve the challenge (if applicable) and the -// username. +// ValidateMFAAuthResponseWithScope validates an MFA or passwordless challenge. This also +// validates that the given required scope is satisfied by the given MFA challenge and +// associated stored webauthn credentials (if applicable). Returns the device used to +// solve the challenge (if applicable) and the username. +func (a *Server) ValidateMFAAuthResponseWithScope(ctx context.Context, resp *proto.MFAAuthenticateResponse, user string, requiredScope webauthnpb.ChallengeScope) (*types.MFADevice, string, error) { + // TODO (Joerger): DELETE IN v16.0.0 + // in v16 the correct challenge scope should be propagated by the client. + if resp.Scope == webauthnpb.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED { + resp.Scope = requiredScope + } + + if resp.Scope != requiredScope { + return nil, "", trace.BadParameter("mfa challenge has invalid scope %v, expected %v", resp.Scope, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES) + } + + return a.ValidateMFAAuthResponse(ctx, resp, user, resp.Scope == webauthnpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN) +} + +// ValidateMFAAuthResponse validates an MFA or passwordless challenge. If the challenge +// response if of type webauthn, this also validates that the challenge response scope +// and reusability is satisfied by the stored webauthn credentials. Returns the device +// used to solve the challenge (if applicable) and the username. func (a *Server) ValidateMFAAuthResponse(ctx context.Context, resp *proto.MFAAuthenticateResponse, user string, passwordless bool) (*types.MFADevice, string, error) { // Sanity check user/passwordless. if user == "" && !passwordless { @@ -5856,7 +5879,7 @@ func (a *Server) ValidateMFAAuthResponse(ctx context.Context, resp *proto.MFAAut Webauthn: webConfig, Identity: a.Services, } - dev, err = webLogin.Finish(ctx, user, wantypes.CredentialAssertionResponseFromProto(res.Webauthn)) + dev, err = webLogin.Finish(ctx, user, wantypes.CredentialAssertionResponseFromProto(res.Webauthn), resp.Scope, resp.AllowReuse) } if err != nil { return nil, "", trace.AccessDenied("MFA response validation failed: %v", err) diff --git a/lib/auth/auth_login_test.go b/lib/auth/auth_login_test.go index 65ae15ba4e15b..f7cb1ad6f8e0c 100644 --- a/lib/auth/auth_login_test.go +++ b/lib/auth/auth_login_test.go @@ -33,6 +33,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/types" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/lib/auth/mocku2f" wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" "github.com/gravitational/teleport/lib/defaults" @@ -185,7 +186,9 @@ func TestCreateAuthenticateChallenge_WithAuth(t *testing.T) { clt, err := srv.NewClient(TestUser(u.username)) require.NoError(t, err) - res, err := clt.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{}) + res, err := clt.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{ + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, + }) require.NoError(t, err) // MFA authentication works. @@ -414,6 +417,7 @@ func TestCreateAuthenticateChallenge_mfaVerification(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION, MFARequiredCheck: &proto.IsMFARequiredRequest{ Target: &proto.IsMFARequiredRequest_Node{ Node: &proto.NodeLogin{ @@ -537,6 +541,7 @@ func TestCreateRegisterChallenge(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) require.NoError(t, err, "CreateAuthenticateChallenge") authnSolved, err := u.webDev.SolveAuthn(authnChal) @@ -776,6 +781,7 @@ func TestServer_Authenticate_passwordless(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, // already authenticated }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) require.NoError(t, err) mfaResp, err := webDev.SolveAuthn(mfaChallenge) @@ -975,6 +981,7 @@ func TestServer_Authenticate_nonPasswordlessRequiresUsername(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, }) require.NoError(t, err) diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index 561930213de36..f969b43d0f71b 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -55,6 +55,7 @@ import ( "github.com/gravitational/teleport/api/types/installers" "github.com/gravitational/teleport/api/types/trait" "github.com/gravitational/teleport/api/types/userloginstate" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/types/wrappers" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/api/utils/sshutils" @@ -2202,6 +2203,7 @@ func TestDeleteMFADeviceSync(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) require.NoError(t, err, "CreateAuthenticateChallenge") @@ -2445,6 +2447,7 @@ func TestDeleteMFADeviceSync_lastDevice(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) if err != nil { return err @@ -2576,6 +2579,7 @@ func TestAddMFADeviceSync(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) require.NoError(t, err, "CreateAuthenticateChallenge") diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index c86931c0545af..81640a7ea2cd7 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -43,6 +43,7 @@ import ( "github.com/gravitational/teleport/api/internalutils/stream" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/types/wrappers" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/keys" @@ -2085,7 +2086,8 @@ func (a *ServerWithRoles) UpsertToken(ctx context.Context, token types.Provision return trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -2811,8 +2813,7 @@ func (a *ServerWithRoles) generateUserCerts(ctx context.Context, req proto.UserC var verifiedMFADeviceID string if req.MFAResponse != nil { - dev, _, err := a.authServer.ValidateMFAAuthResponse( - ctx, req.GetMFAResponse(), req.Username, false /* passwordless */) + dev, _, err := a.authServer.ValidateMFAAuthResponseWithScope(ctx, req.GetMFAResponse(), req.Username, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION) if err != nil { return nil, trace.Wrap(err) } @@ -3137,7 +3138,8 @@ func (a *ServerWithRoles) CreateResetPasswordToken(ctx context.Context, req Crea return nil, trace.AccessDenied("access denied") } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Allow reused MFA responses to allow creating a reset token after creating a user. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -3283,7 +3285,8 @@ func (a *ServerWithRoles) UpsertOIDCConnector(ctx context.Context, connector typ return nil, trace.AccessDenied("OIDC is only available in Teleport Enterprise") } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -3323,7 +3326,8 @@ func (a *ServerWithRoles) CreateOIDCConnector(ctx context.Context, connector typ return nil, trace.AccessDenied("OIDC is only available in Teleport Enterprise") } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -3438,7 +3442,8 @@ func (a *ServerWithRoles) UpsertSAMLConnector(ctx context.Context, connector typ return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -3639,7 +3644,8 @@ func (a *ServerWithRoles) UpsertGithubConnector(ctx context.Context, connector t return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -3657,7 +3663,8 @@ func (a *ServerWithRoles) CreateGithubConnector(ctx context.Context, connector t return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -4044,7 +4051,8 @@ func (a *ServerWithRoles) UpsertRole(ctx context.Context, role types.Role) (type return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return nil, trace.Wrap(err) } @@ -4260,7 +4268,8 @@ func (a *ServerWithRoles) SetAuthPreference(ctx context.Context, newAuthPref typ return trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -4332,7 +4341,8 @@ func (a *ServerWithRoles) SetClusterNetworkingConfig(ctx context.Context, newNet } } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -4394,7 +4404,8 @@ func (a *ServerWithRoles) SetSessionRecordingConfig(ctx context.Context, newRecC } } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -5314,7 +5325,8 @@ func (a *ServerWithRoles) SetNetworkRestrictions(ctx context.Context, nr types.N return trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -6365,7 +6377,8 @@ func (a *ServerWithRoles) CreateSAMLIdPServiceProvider(ctx context.Context, sp t return trace.Wrap(err) } - if err = authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err = authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -6403,7 +6416,8 @@ func (a *ServerWithRoles) UpdateSAMLIdPServiceProvider(ctx context.Context, sp t return trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, &a.context); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, &a.context); err != nil { return trace.Wrap(err) } @@ -6726,7 +6740,7 @@ func (a *ServerWithRoles) UpdateHeadlessAuthenticationState(ctx context.Context, return err } - mfaDevice, _, err := a.authServer.ValidateMFAAuthResponse(ctx, mfaResp, headlessAuthn.User, false /* passwordless */) + mfaDevice, _, err := a.authServer.ValidateMFAAuthResponseWithScope(ctx, mfaResp, headlessAuthn.User, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_HEADLESS) if err != nil { emitHeadlessLoginEvent(ctx, events.UserHeadlessLoginApprovedFailureCode, a.authServer.emitter, headlessAuthn, err) return trace.Wrap(err) diff --git a/lib/auth/auth_with_roles_test.go b/lib/auth/auth_with_roles_test.go index 94393d3601958..760c136a1e202 100644 --- a/lib/auth/auth_with_roles_test.go +++ b/lib/auth/auth_with_roles_test.go @@ -53,6 +53,7 @@ import ( apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/types/installers" wanpb "github.com/gravitational/teleport/api/types/webauthn" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/types/wrappers" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/sshutils" @@ -1822,7 +1823,7 @@ func serverWithAllowRules(t *testing.T, srv *TestAuthServer, allowRules []types. localUser := authz.LocalUser{Username: username, Identity: tlsca.Identity{Username: username}} authContext, err := authz.ContextForLocalUser(ctx, localUser, srv.AuthServer, srv.ClusterName, true /* disableDeviceAuthz */) require.NoError(t, err) - authContext.AdminActionAuthorized = true + authContext.AdminActionAuthState = authz.AdminActionAuthMFAVerified return &ServerWithRoles{ authServer: srv.AuthServer, @@ -5840,6 +5841,7 @@ func TestUpdateHeadlessAuthenticationState(t *testing.T) { challenge, err := client.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{ Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{}, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_HEADLESS, }) require.NoError(t, err) diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index 49189e64c2fc9..064d5857219d3 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -63,6 +63,7 @@ import ( "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/types/installers" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/types/wrappers" "github.com/gravitational/teleport/lib/auth/assist/assistv1" "github.com/gravitational/teleport/lib/auth/discoveryconfig/discoveryconfigv1" @@ -2192,8 +2193,7 @@ func (g *GRPCServer) DeleteRole(ctx context.Context, req *authpb.DeleteRoleReque func doMFAPresenceChallenge(ctx context.Context, actx *grpcContext, stream authpb.AuthService_MaintainSessionPresenceServer, challengeReq *authpb.PresenceMFAChallengeRequest) error { user := actx.User.GetName() - const passwordless = false - authChallenge, err := actx.authServer.mfaAuthChallenge(ctx, user, passwordless) + authChallenge, err := actx.authServer.mfaAuthChallenge(ctx, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION, false /* allowReuse */) if err != nil { return trace.Wrap(err) } @@ -2215,7 +2215,7 @@ func doMFAPresenceChallenge(ctx context.Context, actx *grpcContext, stream authp return trace.BadParameter("expected MFAAuthenticateResponse, got %T", challengeResp) } - if _, _, err := actx.authServer.ValidateMFAAuthResponse(ctx, challengeResp, user, passwordless); err != nil { + if _, _, err := actx.authServer.ValidateMFAAuthResponseWithScope(ctx, challengeResp, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION); err != nil { return trace.Wrap(err) } @@ -2349,8 +2349,7 @@ func addMFADeviceAuthChallenge(gctx *grpcContext, stream authpb.AuthService_AddM ctx := stream.Context() // Note: authChallenge may be empty if this user has no existing MFA devices. - const passwordless = false - authChallenge, err := auth.mfaAuthChallenge(ctx, user, passwordless) + authChallenge, err := auth.mfaAuthChallenge(ctx, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, false /* allowReuse */) if err != nil { return trace.Wrap(err) } @@ -2371,7 +2370,7 @@ func addMFADeviceAuthChallenge(gctx *grpcContext, stream authpb.AuthService_AddM } // Only validate if there was a challenge. if authChallenge.TOTP != nil || authChallenge.WebauthnChallenge != nil { - if _, _, err := auth.ValidateMFAAuthResponse(ctx, authResp, user, passwordless); err != nil { + if _, _, err := auth.ValidateMFAAuthResponseWithScope(ctx, authResp, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES); err != nil { return trace.Wrap(err) } } @@ -2492,8 +2491,7 @@ func deleteMFADeviceAuthChallenge(gctx *grpcContext, stream authpb.AuthService_D auth := gctx.authServer user := gctx.User.GetName() - const passwordless = false - authChallenge, err := auth.mfaAuthChallenge(ctx, user, passwordless) + authChallenge, err := auth.mfaAuthChallenge(ctx, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, false /* allowReuse */) if err != nil { return trace.Wrap(err) } @@ -2513,7 +2511,7 @@ func deleteMFADeviceAuthChallenge(gctx *grpcContext, stream authpb.AuthService_D if authResp == nil { return trace.BadParameter("expected MFAAuthenticateResponse, got %T", req) } - if _, _, err := auth.ValidateMFAAuthResponse(ctx, authResp, user, passwordless); err != nil { + if _, _, err := auth.ValidateMFAAuthResponseWithScope(ctx, authResp, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES); err != nil { return trace.Wrap(err) } return nil @@ -2723,8 +2721,7 @@ func userSingleUseCertsAuthChallenge(gctx *grpcContext, stream authpb.AuthServic auth := gctx.authServer user := gctx.User.GetName() - const passwordless = false - challenge, err := auth.mfaAuthChallenge(ctx, user, passwordless) + challenge, err := auth.mfaAuthChallenge(ctx, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION, false /* allowReuse */) if err != nil { return nil, trace.Wrap(err) } @@ -2749,7 +2746,7 @@ func userSingleUseCertsAuthChallenge(gctx *grpcContext, stream authpb.AuthServic if authResp == nil { return nil, trace.BadParameter("expected MFAAuthenticateResponse, got %T", req.Request) } - mfaDev, _, err := auth.ValidateMFAAuthResponse(ctx, authResp, user, passwordless) + mfaDev, _, err := auth.ValidateMFAAuthResponseWithScope(ctx, authResp, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/grpcserver_test.go b/lib/auth/grpcserver_test.go index 17e3e1a0479da..60555e3f9efb5 100644 --- a/lib/auth/grpcserver_test.go +++ b/lib/auth/grpcserver_test.go @@ -58,6 +58,7 @@ import ( "github.com/gravitational/teleport/api/observability/tracing" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/installers" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/sshutils" "github.com/gravitational/teleport/lib/auth/mocku2f" @@ -524,6 +525,7 @@ func testAddMFADevice(ctx context.Context, t *testing.T, authClient *Client, opt Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) require.NoError(t, err, "CreateAuthenticateChallenge") authnSolved := opts.authHandler(t, authChal) @@ -565,6 +567,7 @@ func testDeleteMFADevice(ctx context.Context, t *testing.T, authClient *Client, Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) require.NoError(t, err, "CreateAuthenticateChallenge") authnSolved := opts.authHandler(t, authnChal) @@ -874,6 +877,7 @@ func TestGenerateUserCerts_deviceAuthz(t *testing.T) { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) if err != nil { return nil, err @@ -1756,6 +1760,7 @@ func testGenerateUserSingleUseCertsUnary(ctx context.Context, t *testing.T, cl * Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION, }) require.NoError(t, err, "CreateAuthenticateChallenge") @@ -3374,7 +3379,9 @@ func TestCustomRateLimiting(t *testing.T) { name: "RPC CreateAuthenticateChallenge", burst: defaults.LimiterBurst, fn: func(clt *Client) error { - _, err := clt.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{}) + _, err := clt.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{ + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, + }) return err }, }, diff --git a/lib/auth/helpers_mfa.go b/lib/auth/helpers_mfa.go index ddadf6e56a91c..769e139e6699d 100644 --- a/lib/auth/helpers_mfa.go +++ b/lib/auth/helpers_mfa.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/lib/auth/mocku2f" wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" ) @@ -76,7 +77,8 @@ func NewTestDeviceFromChallenge(c *proto.MFARegisterChallenge, opts ...TestDevic // RegisterTestDevice creates and registers a TestDevice. // TOTP devices require a clock option. func RegisterTestDevice( - ctx context.Context, clt authClientI, devName string, devType proto.DeviceType, authenticator *TestDevice, opts ...TestDeviceOpt) (*TestDevice, error) { + ctx context.Context, clt authClientI, devName string, devType proto.DeviceType, authenticator *TestDevice, opts ...TestDeviceOpt, +) (*TestDevice, error) { dev := &TestDevice{} // Remaining parameters set during registration for _, opt := range opts { opt(dev) @@ -101,12 +103,14 @@ type authClientI interface { } func (d *TestDevice) registerDevice( - ctx context.Context, authClient authClientI, devName string, devType proto.DeviceType, authenticator *TestDevice) error { + ctx context.Context, authClient authClientI, devName string, devType proto.DeviceType, authenticator *TestDevice, +) error { // Re-authenticate using MFA. authnChal, err := authClient.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{ Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) if err != nil { return trace.Wrap(err) @@ -209,7 +213,6 @@ func (d *TestDevice) solveRegister(c *proto.MFARegisterChallenge) (*proto.MFAReg default: return nil, trace.BadParameter("unexpected challenge type: %T", c.Request) } - } func (d *TestDevice) solveRegisterWebauthn(c *proto.MFARegisterChallenge) (*proto.MFARegisterResponse, error) { diff --git a/lib/auth/machineid/machineidv1/bot_service.go b/lib/auth/machineid/machineidv1/bot_service.go index 9e6a4f1b6088e..1a0e6003d7ee6 100644 --- a/lib/auth/machineid/machineidv1/bot_service.go +++ b/lib/auth/machineid/machineidv1/bot_service.go @@ -263,7 +263,8 @@ func (bs *BotService) createBotAuthz(ctx context.Context) (*authz.Context, error } bs.logger.Warn("CreateBot authz fell back to legacy resource/verbs. Explicitly grant access to the Bot resource. From V16.0.0, this will fail!") } - if err := authz.AuthorizeAdminAction(ctx, authCtx); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, authCtx); err != nil { return nil, trace.Wrap(err) } return authCtx, nil @@ -382,7 +383,8 @@ func (bs *BotService) UpsertBot(ctx context.Context, req *pb.UpsertBotRequest) ( if err != nil { return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, authCtx); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, authCtx); err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/methods.go b/lib/auth/methods.go index 3fb063e5a6586..9a13881050eb3 100644 --- a/lib/auth/methods.go +++ b/lib/auth/methods.go @@ -32,6 +32,7 @@ import ( "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/utils/keys" wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" "github.com/gravitational/teleport/lib/authz" @@ -299,7 +300,7 @@ func (a *Server) authenticateUser(ctx context.Context, req AuthenticateUserReque Webauthn: wantypes.CredentialAssertionResponseToProto(req.Webauthn), }, } - dev, _, err := a.ValidateMFAAuthResponse(ctx, mfaResponse, user, passwordless) + dev, _, err := a.ValidateMFAAuthResponseWithScope(ctx, mfaResponse, user, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN) return dev, trace.Wrap(err) } authErr = authenticateWebauthnError @@ -393,7 +394,7 @@ func (a *Server) authenticatePasswordless(ctx context.Context, req AuthenticateU Webauthn: wantypes.CredentialAssertionResponseToProto(req.Webauthn), }, } - dev, user, err := a.ValidateMFAAuthResponse(ctx, mfaResponse, "", true /* passwordless */) + dev, user, err := a.ValidateMFAAuthResponseWithScope(ctx, mfaResponse, "" /* user */, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN) if err != nil { log.Debugf("Passwordless authentication failed: %v", err) return nil, "", trace.Wrap(authenticateWebauthnError) diff --git a/lib/auth/trust/trustv1/service.go b/lib/auth/trust/trustv1/service.go index da3a793525467..b425103fd967f 100644 --- a/lib/auth/trust/trustv1/service.go +++ b/lib/auth/trust/trustv1/service.go @@ -192,7 +192,8 @@ func (s *Service) UpsertCertAuthority(ctx context.Context, req *trustpb.UpsertCe return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, authzCtx); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, authzCtx); err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/trust/trustv1/service_test.go b/lib/auth/trust/trustv1/service_test.go index cadd1e8f673af..bd3d51f010a2a 100644 --- a/lib/auth/trust/trustv1/service_test.go +++ b/lib/auth/trust/trustv1/service_test.go @@ -68,8 +68,8 @@ type fakeAuthorizer struct { func (f *fakeAuthorizer) Authorize(ctx context.Context) (*authz.Context, error) { return &authz.Context{ - Checker: f.checker, - AdminActionAuthorized: true, + Checker: f.checker, + AdminActionAuthState: authz.AdminActionAuthMFAVerified, }, nil } diff --git a/lib/auth/users/usersv1/service.go b/lib/auth/users/usersv1/service.go index e85f2a6571d48..a1f875172a643 100644 --- a/lib/auth/users/usersv1/service.go +++ b/lib/auth/users/usersv1/service.go @@ -218,7 +218,8 @@ func (s *Service) CreateUser(ctx context.Context, req *userspb.CreateUserRequest return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, authzCtx); err != nil { + // Support reused MFA for bulk tctl create requests and chained invite commands (CreateResetPasswordToken). + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, authzCtx); err != nil { return nil, trace.Wrap(err) } @@ -284,7 +285,8 @@ func (s *Service) UpdateUser(ctx context.Context, req *userspb.UpdateUserRequest return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, authzCtx); err != nil { + // Allow reused MFA responses to allow Updating a user after get (WebUI). + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, authzCtx); err != nil { return nil, trace.Wrap(err) } @@ -354,7 +356,8 @@ func (s *Service) UpsertUser(ctx context.Context, req *userspb.UpsertUserRequest return nil, trace.Wrap(err) } - if err := authz.AuthorizeAdminAction(ctx, authzCtx); err != nil { + // Support reused MFA for bulk tctl create requests. + if err := authz.AuthorizeAdminActionAllowReusedMFA(ctx, authzCtx); err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/users/usersv1/service_test.go b/lib/auth/users/usersv1/service_test.go index 71774e1267e01..e517ca206ab96 100644 --- a/lib/auth/users/usersv1/service_test.go +++ b/lib/auth/users/usersv1/service_test.go @@ -73,8 +73,8 @@ func (a fakeAuthorizer) Authorize(ctx context.Context) (*authz.Context, error) { }, }, }, - Identity: identity, - AdminActionAuthorized: true, + Identity: identity, + AdminActionAuthState: authz.AdminActionAuthNotRequired, }, nil } @@ -103,7 +103,7 @@ func (a fakeAuthorizer) Authorize(ctx context.Context) (*authz.Context, error) { Username: "alice", }, }, - AdminActionAuthorized: true, + AdminActionAuthState: authz.AdminActionAuthNotRequired, }, nil } @@ -876,7 +876,7 @@ func TestRBAC(t *testing.T) { Groups: []string{"dev"}, }, }, - AdminActionAuthorized: true, + AdminActionAuthState: authz.AdminActionAuthNotRequired, }})) require.NoError(t, err, "creating test service") diff --git a/lib/auth/webauthn/login.go b/lib/auth/webauthn/login.go index cfd659278a542..35882e07188d5 100644 --- a/lib/auth/webauthn/login.go +++ b/lib/auth/webauthn/login.go @@ -67,13 +67,18 @@ type loginFlow struct { sessionData sessionIdentity } -func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) (*wantypes.CredentialAssertion, error) { - if user == "" && !passwordless { +func (f *loginFlow) begin(ctx context.Context, user string, scope wanpb.ChallengeScope, allowReuse bool) (*wantypes.CredentialAssertion, error) { + if allowReuse && scope != wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION { + return nil, trace.BadParameter("mfa challenges with scope %v cannot allow reuse", scope) + } + + isPasswordless := scope == wanpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN + if user == "" && !isPasswordless { return nil, trace.BadParameter("user required") } var u *webUser - if passwordless { + if isPasswordless { u = &webUser{} // Issue anonymous challenge. } else { webID, err := f.getWebID(ctx, user) @@ -145,7 +150,7 @@ func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) ( web, err := newWebAuthn(webAuthnParams{ cfg: f.Webauthn, rpID: f.Webauthn.RPID, - requireUserVerification: passwordless, + requireUserVerification: isPasswordless, }) if err != nil { return nil, trace.Wrap(err) @@ -153,7 +158,7 @@ func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) ( var assertion *protocol.CredentialAssertion var sessionData *wan.SessionData - if passwordless { + if isPasswordless { assertion, sessionData, err = web.BeginDiscoverableLogin(opts...) } else { assertion, sessionData, err = web.BeginLogin(u, opts...) @@ -167,6 +172,9 @@ func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) ( if err != nil { return nil, trace.Wrap(err) } + + sessionDataPB.AllowReuse = allowReuse + sessionDataPB.Scope = scope if err := f.sessionData.Upsert(ctx, user, sessionDataPB); err != nil { return nil, trace.Wrap(err) } @@ -185,9 +193,11 @@ func (f *loginFlow) getWebID(ctx context.Context, user string) ([]byte, error) { return wla.UserID, nil } -func (f *loginFlow) finish(ctx context.Context, user string, resp *wantypes.CredentialAssertionResponse, passwordless bool) (*types.MFADevice, string, error) { +func (f *loginFlow) finish(ctx context.Context, user string, scope wanpb.ChallengeScope, allowReuse bool, resp *wantypes.CredentialAssertionResponse) (*types.MFADevice, string, error) { + isPasswordless := scope == wanpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN + switch { - case user == "" && !passwordless: + case user == "" && !isPasswordless: return nil, "", trace.BadParameter("user required") case resp == nil: // resp != nil is good enough to proceed, we leave remaining validations to @@ -207,7 +217,7 @@ func (f *loginFlow) finish(ctx context.Context, user string, resp *wantypes.Cred } var webID []byte - if passwordless { + if isPasswordless { webID = parsedResp.Response.UserHandle if len(webID) == 0 { return nil, "", trace.BadParameter("webauthn user handle required for passwordless") @@ -260,6 +270,19 @@ func (f *loginFlow) finish(ctx context.Context, user string, resp *wantypes.Cred } sessionData := sessionFromPB(sessionDataPB) + // Check if the given requiredScope is satisfied by the challenge scope. + if scope != sessionDataPB.GetScope() { + // old clients do not yet provide a scope, so we only enforce scope opportunistically. + // TODO(Joerger): DELETE IN v16.0.0 + if sessionDataPB.GetScope() != wanpb.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED { + return nil, "", trace.AccessDenied("required scope %q is not satisfied by the given webauthn credentials with scope %q", scope, sessionDataPB.GetScope()) + } + } + + if !allowReuse && sessionDataPB.AllowReuse { + return nil, "", trace.AccessDenied("the given webauthn credentials allow reuse, which is not permitted in this context") + } + // Make sure _all_ credentials in the session are accounted for by the user. // webauthn.ValidateLogin requires it. for _, allowedCred := range sessionData.AllowedCredentialIDs { @@ -277,14 +300,14 @@ func (f *loginFlow) finish(ctx context.Context, user string, resp *wantypes.Cred cfg: f.Webauthn, rpID: rpID, origin: origin, - requireUserVerification: passwordless, + requireUserVerification: isPasswordless, }) if err != nil { return nil, "", trace.Wrap(err) } var credential *wan.Credential - if passwordless { + if isPasswordless { discoverUser := func(_, _ []byte) (wan.User, error) { return u, nil } credential, err = web.ValidateDiscoverableLogin(discoverUser, *sessionData, parsedResp) } else { @@ -313,9 +336,11 @@ func (f *loginFlow) finish(ctx context.Context, user string, resp *wantypes.Cred } // The user just solved the challenge, so let's make sure it won't be used - // again. - if err := f.sessionData.Delete(ctx, user, challenge); err != nil { - log.Warnf("WebAuthn: failed to delete login SessionData for user %v (passwordless = %v)", user, passwordless) + // again, unless reuse is explicitly allowed. + if !sessionDataPB.AllowReuse { + if err := f.sessionData.Delete(ctx, user, challenge); err != nil { + log.Warnf("WebAuthn: failed to delete login SessionData for user %v (scope = %v)", user, scope.String()) + } } return dev, user, nil diff --git a/lib/auth/webauthn/login_mfa.go b/lib/auth/webauthn/login_mfa.go index 0d8b100ca6029..70d60ece87df2 100644 --- a/lib/auth/webauthn/login_mfa.go +++ b/lib/auth/webauthn/login_mfa.go @@ -94,28 +94,28 @@ type LoginFlow struct { // assertion. // As a side effect Begin may assign (and record in storage) a WebAuthn ID for // the user. -func (f *LoginFlow) Begin(ctx context.Context, user string) (*wantypes.CredentialAssertion, error) { +func (f *LoginFlow) Begin(ctx context.Context, user string, scope wanpb.ChallengeScope, allowReuse bool) (*wantypes.CredentialAssertion, error) { lf := &loginFlow{ U2F: f.U2F, Webauthn: f.Webauthn, identity: mfaIdentity{f.Identity}, sessionData: (*userSessionStorage)(f), } - return lf.begin(ctx, user, false /* passwordless */) + return lf.begin(ctx, user, scope, allowReuse) } // Finish is the second and last step of the LoginFlow. // It returns the MFADevice used to solve the challenge. If login is successful, // Finish has the side effect of updating the counter and last used timestamp of // the returned device. -func (f *LoginFlow) Finish(ctx context.Context, user string, resp *wantypes.CredentialAssertionResponse) (*types.MFADevice, error) { +func (f *LoginFlow) Finish(ctx context.Context, user string, resp *wantypes.CredentialAssertionResponse, scope wanpb.ChallengeScope, allowReuse bool) (*types.MFADevice, error) { lf := &loginFlow{ U2F: f.U2F, Webauthn: f.Webauthn, identity: mfaIdentity{f.Identity}, sessionData: (*userSessionStorage)(f), } - dev, _, err := lf.finish(ctx, user, resp, false /* passwordless */) + dev, _, err := lf.finish(ctx, user, scope, allowReuse, resp) return dev, trace.Wrap(err) } diff --git a/lib/auth/webauthn/login_passwordless.go b/lib/auth/webauthn/login_passwordless.go index 932df3b2c107b..91b8b6797126e 100644 --- a/lib/auth/webauthn/login_passwordless.go +++ b/lib/auth/webauthn/login_passwordless.go @@ -55,7 +55,7 @@ func (f *PasswordlessFlow) Begin(ctx context.Context) (*wantypes.CredentialAsser identity: passwordlessIdentity{f.Identity}, sessionData: (*globalSessionStorage)(f), } - return lf.begin(ctx, "" /* user */, true /* passwordless */) + return lf.begin(ctx, "" /* user */, wanpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN, false /* allowReuse */) } // Finish is the last step of the passwordless login flow. @@ -67,7 +67,7 @@ func (f *PasswordlessFlow) Finish(ctx context.Context, resp *wantypes.Credential identity: passwordlessIdentity{f.Identity}, sessionData: (*globalSessionStorage)(f), } - return lf.finish(ctx, "" /* user */, resp, true /* passwordless */) + return lf.finish(ctx, "" /* user */, wanpb.ChallengeScope_CHALLENGE_SCOPE_PASSWORDLESS_LOGIN, false /* allowReuse */, resp) } type passwordlessIdentity struct { diff --git a/lib/auth/webauthn/login_test.go b/lib/auth/webauthn/login_test.go index 2b472c81a9ac1..8ff8887a7f2ee 100644 --- a/lib/auth/webauthn/login_test.go +++ b/lib/auth/webauthn/login_test.go @@ -120,7 +120,7 @@ func TestLoginFlow_BeginFinish(t *testing.T) { } // 1st step of the login ceremony. - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) // We care about a few specific settings, for everything else defaults are // OK. @@ -148,7 +148,7 @@ func TestLoginFlow_BeginFinish(t *testing.T) { // 2nd and last step of the login ceremony. beforeLastUsed := time.Now().Add(-1 * time.Second) - loginDevice, err := webLogin.Finish(ctx, user, assertionResp) + loginDevice, err := webLogin.Finish(ctx, user, assertionResp, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) // Last used time and counter are updated. require.True(t, beforeLastUsed.Before(loginDevice.LastUsed)) @@ -222,7 +222,7 @@ func TestLoginFlow_Begin_errors(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - _, err := webLogin.Begin(ctx, test.user) + _, err := webLogin.Begin(ctx, test.user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.True(t, test.assertErrType(err), "got err = %v, want BadParameter", err) require.Contains(t, err.Error(), test.wantErr) }) @@ -260,7 +260,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) { Webauthn: webConfig, Identity: identity, } - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) okResp, err := key.SignAssertion(webOrigin, assertion) require.NoError(t, err) @@ -289,7 +289,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) { name: "NOK assertion with bad origin", user: user, createResp: func() *wantypes.CredentialAssertionResponse { - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) resp, err := key.SignAssertion("https://badorigin.com", assertion) require.NoError(t, err) @@ -300,7 +300,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) { name: "NOK assertion with bad RPID", user: user, createResp: func() *wantypes.CredentialAssertionResponse { - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) assertion.Response.RelyingPartyID = "badrpid.com" @@ -313,7 +313,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) { name: "NOK assertion signed by unknown device", user: user, createResp: func() *wantypes.CredentialAssertionResponse { - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) unknownKey, err := mocku2f.Create() @@ -330,7 +330,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) { name: "NOK assertion with invalid signature", user: user, createResp: func() *wantypes.CredentialAssertionResponse { - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) // Flip a challenge bit, this should be enough to consistently fail // signature checking. @@ -344,7 +344,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - _, err := webLogin.Finish(ctx, test.user, test.createResp()) + _, err := webLogin.Finish(ctx, test.user, test.createResp(), wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.Error(t, err) }) } @@ -568,7 +568,7 @@ func TestCredentialRPID(t *testing.T) { Identity: identity, } - _, err := webLogin.Begin(ctx, user) + _, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) assert.NoError(t, err, "Begin failed, expected assertion for `dev1`") }) @@ -578,13 +578,13 @@ func TestCredentialRPID(t *testing.T) { Identity: identity, } - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err, "Begin failed") car, err := dev1Key.SignAssertion(origin, assertion) require.NoError(t, err, "SignAssertion failed") - mfaDev, err := webLogin.Finish(ctx, user, car) + mfaDev, err := webLogin.Finish(ctx, user, car, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err, "Finish failed") assert.Equal(t, rpID, mfaDev.GetWebauthn().CredentialRpId, "CredentialRpId mismatch") }) @@ -595,7 +595,7 @@ func TestCredentialRPID(t *testing.T) { Identity: identity, } - _, err := webLogin.Begin(ctx, user) + _, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) assert.ErrorIs(t, err, wanlib.ErrInvalidCredentials, "Begin error mismatch") }) @@ -612,7 +612,7 @@ func TestCredentialRPID(t *testing.T) { Webauthn: webOtherRP, Identity: identity, } - assertion, err := webLogin.Begin(ctx, user) + assertion, err := webLogin.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err, "Begin failed, expected assertion for device `other1`") // Verify that we got the correct device. @@ -624,6 +624,124 @@ func TestCredentialRPID(t *testing.T) { }) } +func TestLoginScopeAndReuse(t *testing.T) { + // webUser gets a newly registered device and a webID. + const webUser = "llama" + webIdentity := newFakeIdentity(webUser) + webConfig := &types.Webauthn{RPID: "example.com"} + + const webOrigin = "https://example.com" + ctx := context.Background() + + // Register a Webauthn device. + // Last registration step creates the user webID and adds the new device to + // identity. + webKey, err := mocku2f.Create() + require.NoError(t, err) + webKey.PreferRPID = true // Webauthn-registered device + webRegistration := &wanlib.RegistrationFlow{ + Webauthn: webConfig, + Identity: webIdentity, + } + cc, err := webRegistration.Begin(ctx, webUser, false /* passwordless */) + require.NoError(t, err) + ccr, err := webKey.SignCredentialCreation(webOrigin, cc) + require.NoError(t, err) + _, err = webRegistration.Finish(ctx, wanlib.RegisterResponse{ + User: webUser, + DeviceName: "webauthn1", + CreationResponse: ccr, + }) + require.NoError(t, err) + + tests := []struct { + name string + beginScope wanpb.ChallengeScope + beginAllowReuse bool + beginErr bool + finishScope wanpb.ChallengeScope + finishAllowReuse bool + finishErr bool + }{ + { + name: "NOK mismatched scope", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + finishScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED, + finishErr: true, + }, { + name: "OK matching scope", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + finishScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + }, { + // old clients do not yet provide a scope, so we only enforce scope + // opportunistically during login finish. + // TODO(Joerger): DELETE IN v16.0.0 + name: "OK scope not specified", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED, + finishScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + }, { + name: "NOK reuse not allowed for scope", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, + beginAllowReuse: true, + beginErr: true, + }, { + name: "NOK reuse requested but not allowed", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + beginAllowReuse: true, + finishScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + finishAllowReuse: false, + finishErr: true, + }, { + name: "OK reuse not requested but allowed", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + beginAllowReuse: false, + finishScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + finishAllowReuse: true, + }, { + name: "OK reuse requested allowed", + beginScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + beginAllowReuse: true, + finishScope: wanpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + finishAllowReuse: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + identity := webIdentity + user := webUser + + webLogin := &wanlib.LoginFlow{ + Webauthn: webConfig, + Identity: webIdentity, + } + + assertion, err := webLogin.Begin(ctx, user, test.beginScope, test.beginAllowReuse) + if test.beginErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + assertionResp, err := webKey.SignAssertion(webOrigin, assertion) + require.NoError(t, err) + + _, err = webLogin.Finish(ctx, user, assertionResp, test.finishScope, test.finishAllowReuse) + if test.finishErr { + require.Error(t, err) + return + } + require.NoError(t, err) + + // Session data should only be deleted if reuse was not requested on begin. + if test.beginAllowReuse { + require.NotEmpty(t, identity.SessionData) + } else { + require.Empty(t, identity.SessionData) + } + }) + } +} + type fakeIdentity struct { User *types.UserV2 // MappedUser is used as the reply to GetTeleportUserByWebauthnID. diff --git a/lib/auth/webauthncli/u2f_login_test.go b/lib/auth/webauthncli/u2f_login_test.go index 187a8278cddce..7548a2359e01d 100644 --- a/lib/auth/webauthncli/u2f_login_test.go +++ b/lib/auth/webauthncli/u2f_login_test.go @@ -141,7 +141,7 @@ func TestLogin(t *testing.T) { } test.setUserPresence.SetUserPresence(true) - assertion, err := loginFlow.Begin(ctx, username) + assertion, err := loginFlow.Begin(ctx, username, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) if test.removeAppID { assertion.Response.Extensions = nil @@ -160,7 +160,7 @@ func TestLogin(t *testing.T) { require.NotNil(t, mfaResp.GetWebauthn()) require.Equal(t, test.wantRawID, mfaResp.GetWebauthn().RawId) - _, err = loginFlow.Finish(ctx, username, wantypes.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn())) + _, err = loginFlow.Finish(ctx, username, wantypes.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn()), wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) }) } @@ -183,7 +183,7 @@ func TestLogin_errors(t *testing.T) { const user = "llama" const origin = "https://localhost" ctx := context.Background() - okAssertion, err := loginFlow.Begin(ctx, user) + okAssertion, err := loginFlow.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) tests := []struct { @@ -216,7 +216,7 @@ func TestLogin_errors(t *testing.T) { name: "NOK assertion missing challenge", origin: origin, getAssertion: func() *wantypes.CredentialAssertion { - assertion, err := loginFlow.Begin(ctx, user) + assertion, err := loginFlow.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) assertion.Response.Challenge = nil return assertion @@ -226,7 +226,7 @@ func TestLogin_errors(t *testing.T) { name: "NOK assertion missing RPID", origin: origin, getAssertion: func() *wantypes.CredentialAssertion { - assertion, err := loginFlow.Begin(ctx, user) + assertion, err := loginFlow.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) assertion.Response.RelyingPartyID = "" return assertion @@ -236,7 +236,7 @@ func TestLogin_errors(t *testing.T) { name: "NOK assertion missing credentials", origin: origin, getAssertion: func() *wantypes.CredentialAssertion { - assertion, err := loginFlow.Begin(ctx, user) + assertion, err := loginFlow.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) assertion.Response.AllowedCredentials = nil return assertion @@ -246,7 +246,7 @@ func TestLogin_errors(t *testing.T) { name: "NOK assertion invalid user verification requirement", origin: origin, getAssertion: func() *wantypes.CredentialAssertion { - assertion, err := loginFlow.Begin(ctx, user) + assertion, err := loginFlow.Begin(ctx, user, wanpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, false) require.NoError(t, err) assertion.Response.UserVerification = protocol.VerificationRequired return assertion diff --git a/lib/authz/permissions.go b/lib/authz/permissions.go index 6c5e7c2bc7aff..5e7f75ea0282f 100644 --- a/lib/authz/permissions.go +++ b/lib/authz/permissions.go @@ -39,6 +39,7 @@ import ( "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/keys" dtauthz "github.com/gravitational/teleport/lib/devicetrust/authz" @@ -151,8 +152,10 @@ type AuthorizerAccessPoint interface { // GetSessionRecordingConfig returns session recording configuration. GetSessionRecordingConfig(ctx context.Context, opts ...services.MarshalOption) (types.SessionRecordingConfig, error) - // ValidateMFAAuthResponse validates an MFA or passwordless challenge. - // Returns the device used to solve the challenge (if applicable) and the username. + // ValidateMFAAuthResponse validates an MFA or passwordless challenge. If the challenge + // response if of type webauthn, this also validates that the challenge response scope + // and reusability is satisfied by the stored webauthn credentials. Returns the device + // used to solve the challenge (if applicable) and the username. ValidateMFAAuthResponse(ctx context.Context, resp *proto.MFAAuthenticateResponse, user string, passwordless bool) (*types.MFADevice, string, error) } @@ -193,9 +196,22 @@ type Context struct { // AdminActionVerified is whether this auth request is verified for admin actions. This // either means that the request was MFA verified through the context or Hardware Key support, // or the identity does not require admin MFA (built in roles, bot impersonated user, etc). + // TODO(Joerger): Deprecated in favor of AdminActionAuthState, remove once e is no longer dependent. AdminActionAuthorized bool + + // AdminActionAuthState is the state of admin action authorization for this auth context. + AdminActionAuthState AdminActionAuthState } +type AdminActionAuthState int + +const ( + AdminActionAuthUnauthorized AdminActionAuthState = iota + AdminActionAuthNotRequired + AdminActionAuthMFAVerified + AdminActionAuthMFAVerifiedWithReuse +) + // GetUserMetadata returns information about the authenticated identity // to be included in audit events. func (c *Context) GetUserMetadata() apievents.UserMetadata { @@ -376,39 +392,44 @@ func (a *authorizer) fromUser(ctx context.Context, userI interface{}) (*Context, // checkAdminActionVerification checks if this auth request is verified for admin actions. func (a *authorizer) checkAdminActionVerification(ctx context.Context, authContext *Context) error { + required, err := a.isAdminActionAuthorizationRequired(ctx, authContext) + if err != nil { + return trace.Wrap(err) + } + + if !required { + authContext.AdminActionAuthState = AdminActionAuthNotRequired + return nil + } + if err := a.authorizeAdminAction(ctx, authContext); err != nil { - if trace.IsNotFound(err) { - // missing MFA verification should be a noop. - return nil - } return trace.Wrap(err) } - authContext.AdminActionAuthorized = true return nil } -func (a *authorizer) authorizeAdminAction(ctx context.Context, authContext *Context) error { +func (a *authorizer) isAdminActionAuthorizationRequired(ctx context.Context, authContext *Context) (bool, error) { // Builtin roles do not require MFA to perform admin actions. switch authContext.Identity.(type) { case BuiltinRole, RemoteBuiltinRole: - return nil + return false, nil } authpref, err := a.accessPoint.GetAuthPreference(ctx) if err != nil { - return trace.Wrap(err) + return false, trace.Wrap(err) } // Admin actions do not require MFA when Webauthn is not enabled. if authpref.GetPreferredLocalMFA() != constants.SecondFactorWebauthn { - return nil + return false, nil } // Skip MFA check if the user is a Bot. if user, err := a.accessPoint.GetUser(ctx, authContext.Identity.GetIdentity().Username, false); err == nil && user.IsBot() { a.logger.Debugf("Skipping admin action MFA check for bot identity: %v", authContext.Identity.GetIdentity()) - return nil + return false, nil } // Skip MFA if the identity is being impersonated by the Bot or Admin built in role. @@ -416,7 +437,7 @@ func (a *authorizer) authorizeAdminAction(ctx context.Context, authContext *Cont impersonatorUser, err := a.accessPoint.GetUser(ctx, impersonator, false) if err == nil && impersonatorUser.IsBot() { a.logger.Debugf("Skipping admin action MFA check for bot-impersonated identity: %v", authContext.Identity.GetIdentity()) - return nil + return false, nil } // If we don't find a user matching the impersonator, it may be the admin role impersonating. @@ -426,27 +447,51 @@ func (a *authorizer) authorizeAdminAction(ctx context.Context, authContext *Cont if hostFQDNParts[1] == a.clusterName { if _, err := uuid.Parse(hostFQDNParts[0]); err == nil { a.logger.Debugf("Skipping admin action MFA check for admin-impersonated identity: %v", authContext.Identity.GetIdentity()) - return nil + return false, nil } } } } + return true, nil +} + +func (a *authorizer) authorizeAdminAction(ctx context.Context, authContext *Context) error { // Certain hardware-key based private key policies require MFA for each request. if authContext.Identity.GetIdentity().PrivateKeyPolicy.MFAVerified() { + authContext.AdminActionAuthState = AdminActionAuthMFAVerified return nil } // MFA is required to be passed through the request context. mfaResp, err := mfa.CredentialsFromContext(ctx) if err != nil { + if trace.IsNotFound(err) { + // missing MFA verification should be a noop. + return nil + } return trace.Wrap(err) } + // TODO (Joerger): DELETE IN v16.0.0 + // in v16 the correct challenge scope should be propagated by the client. + if mfaResp.Scope == webauthnpb.ChallengeScope_CHALLENGE_SCOPE_UNSPECIFIED { + mfaResp.Scope = webauthnpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION + } + + if mfaResp.Scope != webauthnpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION { + return trace.BadParameter("mfa challenge has invalid scope %v, expected %v", mfaResp.Scope, webauthnpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION) + } + if _, _, err := a.accessPoint.ValidateMFAAuthResponse(ctx, mfaResp, authContext.User.GetName(), false); err != nil { return trace.Wrap(err) } + authContext.AdminActionAuthState = AdminActionAuthMFAVerified + if mfaResp.AllowReuse { + authContext.AdminActionAuthState = AdminActionAuthMFAVerifiedWithReuse + } + return nil } @@ -1100,8 +1145,8 @@ func ContextForBuiltinRole(r BuiltinRole, recConfig types.SessionRecordingConfig Checker: checker, Identity: r, UnmappedIdentity: r, - disableDeviceRoleMode: true, // Builtin roles skip device trust. - AdminActionAuthorized: true, // builtin roles skip mfa for admin actions. + disableDeviceRoleMode: true, // Builtin roles skip device trust. + AdminActionAuthState: AdminActionAuthNotRequired, // builtin roles skip mfa for admin actions. }, nil } @@ -1325,10 +1370,24 @@ func AuthorizeContextWithVerbs(ctx context.Context, log logrus.FieldLogger, auth // AuthorizeAdminAction will ensure that the user is authorized to perform admin actions. func AuthorizeAdminAction(ctx context.Context, authCtx *Context) error { - if !authCtx.AdminActionAuthorized { - return trace.Wrap(&mfa.ErrAdminActionMFARequired) + // TODO(Joerger): AdminActionAuthorized is deprecated in favor of AdminActionAuthState, remove once e is no longer dependent. + if authCtx.AdminActionAuthorized { + return nil } - return nil + switch authCtx.AdminActionAuthState { + case AdminActionAuthMFAVerified, AdminActionAuthNotRequired: + return nil + } + return trace.Wrap(&mfa.ErrAdminActionMFARequired) +} + +// AuthorizeAdminActionAllowReusedMFA will ensure that the user is authorized to perform +// admin actions. Additionally, MFA challenges that allow reuse will be accepted. +func AuthorizeAdminActionAllowReusedMFA(ctx context.Context, authCtx *Context) error { + if authCtx.AdminActionAuthState == AdminActionAuthMFAVerifiedWithReuse { + return nil + } + return AuthorizeAdminAction(ctx, authCtx) } // LocalUser is a local user diff --git a/lib/authz/permissions_test.go b/lib/authz/permissions_test.go index 43e1c1502a256..e9229d1246ec9 100644 --- a/lib/authz/permissions_test.go +++ b/lib/authz/permissions_test.go @@ -38,6 +38,7 @@ import ( "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib/backend/memory" "github.com/gravitational/teleport/lib/modules" @@ -485,12 +486,49 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { }) require.NoError(t, err, "NewAuthorizer failed") + validMFA := &proto.MFAAuthenticateResponse{ + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + Response: &proto.MFAAuthenticateResponse_TOTP{ + TOTP: &proto.TOTPResponse{ + Code: validTOTPCode, + }, + }, + } + + validMFAWithReuse := &proto.MFAAuthenticateResponse{ + AllowReuse: true, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_ADMIN_ACTION, + Response: &proto.MFAAuthenticateResponse_TOTP{ + TOTP: &proto.TOTPResponse{ + Code: validTOTPCode, + }, + }, + } + + mfaWithInvalidScope := &proto.MFAAuthenticateResponse{ + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_LOGIN, + Response: &proto.MFAAuthenticateResponse_TOTP{ + TOTP: &proto.TOTPResponse{ + Code: validTOTPCode, + }, + }, + } + + invalidMFA := &proto.MFAAuthenticateResponse{ + Response: &proto.MFAAuthenticateResponse_TOTP{ + TOTP: &proto.TOTPResponse{ + Code: "invalid", + }, + }, + } + for _, tt := range []struct { name string user IdentityGetter - withTOTPInContext string + withMFA *proto.MFAAuthenticateResponse + allowedReusedMFA bool contextGetter func() context.Context - wantErr string + wantErrContains string wantAdminActionAuthorized bool }{ { @@ -501,10 +539,10 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { Username: localUser.GetName(), }, }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: false, }, { - name: "NOK local user with mfa verified cert", + name: "NOK local user mfa verified cert", user: LocalUser{ Username: localUser.GetName(), Identity: tlsca.Identity{ @@ -512,7 +550,7 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { MFAVerified: "mfa-verified-test", }, }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: false, }, { // edge case for the admin role check. @@ -523,32 +561,66 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { Username: userWithHostName.GetName(), }, }, - wantErr: "", + wantErrContains: "", + wantAdminActionAuthorized: false, + }, { + name: "NOK local user invalid mfa", + user: LocalUser{ + Username: localUser.GetName(), + Identity: tlsca.Identity{ + Username: localUser.GetName(), + }, + }, + withMFA: invalidMFA, + wantErrContains: "invalid MFA", + wantAdminActionAuthorized: true, + }, { + name: "NOK local user invalid scope", + user: LocalUser{ + Username: localUser.GetName(), + Identity: tlsca.Identity{ + Username: localUser.GetName(), + }, + }, + withMFA: mfaWithInvalidScope, + wantErrContains: "scope", + wantAdminActionAuthorized: true, + }, { + name: "NOK local user reused mfa with reuse not allowed", + user: LocalUser{ + Username: localUser.GetName(), + Identity: tlsca.Identity{ + Username: localUser.GetName(), + }, + }, + withMFA: validMFAWithReuse, + wantErrContains: "", wantAdminActionAuthorized: false, }, { - name: "NOK local user with invalid mfa from context", + name: "OK local user valid mfa", user: LocalUser{ Username: localUser.GetName(), Identity: tlsca.Identity{ Username: localUser.GetName(), }, }, - withTOTPInContext: "invalid", - wantErr: "invalid MFA", + withMFA: validMFA, + wantErrContains: "", wantAdminActionAuthorized: true, }, { - name: "OK local user with valid mfa from context", + name: "OK local user reused mfa with reuse allowed", user: LocalUser{ Username: localUser.GetName(), Identity: tlsca.Identity{ Username: localUser.GetName(), }, }, - withTOTPInContext: validTOTPCode, - wantErr: "", + withMFA: validMFAWithReuse, + allowedReusedMFA: true, + wantErrContains: "", wantAdminActionAuthorized: true, }, { - name: "OK local user with mfa verified private key policy", + name: "OK local user mfa verified private key policy", user: LocalUser{ Username: localUser.GetName(), Identity: tlsca.Identity{ @@ -556,7 +628,7 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { PrivateKeyPolicy: keys.PrivateKeyPolicyHardwareKeyTouch, }, }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: true, }, { name: "OK admin", @@ -564,7 +636,7 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { Role: types.RoleAdmin, Username: hostFQDN(uuid.NewString(), clusterName), }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: true, }, { name: "OK bot", @@ -574,7 +646,7 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { Username: bot.GetName(), }, }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: true, }, { name: "OK admin impersonating local user", @@ -585,7 +657,7 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { Impersonator: hostFQDN(uuid.NewString(), clusterName), }, }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: true, }, { name: "OK bot impersonating local user", @@ -596,21 +668,14 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { Impersonator: bot.GetName(), }, }, - wantErr: "", + wantErrContains: "", wantAdminActionAuthorized: true, }, } { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - if tt.withTOTPInContext != "" { - mfaResp := &proto.MFAAuthenticateResponse{ - Response: &proto.MFAAuthenticateResponse_TOTP{ - TOTP: &proto.TOTPResponse{ - Code: tt.withTOTPInContext, - }, - }, - } - encodedMFAResp, err := mfa.EncodeMFAChallengeResponseCredentials(mfaResp) + if tt.withMFA != nil { + encodedMFAResp, err := mfa.EncodeMFAChallengeResponseCredentials(tt.withMFA) require.NoError(t, err) md := metadata.MD(map[string][]string{ mfa.ResponseMetadataKey: {encodedMFAResp}, @@ -619,13 +684,19 @@ func TestAuthorizer_AuthorizeAdminAction(t *testing.T) { } userCtx := context.WithValue(ctx, contextUser, tt.user) authCtx, err := authorizer.Authorize(userCtx) - if tt.wantErr != "" { - require.ErrorContains(t, err, tt.wantErr, "Expected matching Authorize error") + if tt.wantErrContains != "" { + require.ErrorContains(t, err, tt.wantErrContains, "Expected matching Authorize error") return } require.NoError(t, err) - authAdminActionErr := AuthorizeAdminAction(ctx, authCtx) + var authAdminActionErr error + if tt.allowedReusedMFA { + authAdminActionErr = AuthorizeAdminActionAllowReusedMFA(ctx, authCtx) + } else { + authAdminActionErr = AuthorizeAdminAction(ctx, authCtx) + } + if tt.wantAdminActionAuthorized { require.NoError(t, authAdminActionErr) } else { diff --git a/lib/client/api.go b/lib/client/api.go index aa429b93e7b5a..f780b1e5d9f2b 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -64,6 +64,7 @@ import ( "github.com/gravitational/teleport/api/profile" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/grpc/interceptors" "github.com/gravitational/teleport/api/utils/keys" @@ -5236,6 +5237,7 @@ func (tc *TeleportClient) HeadlessApprove(ctx context.Context, headlessAuthentic Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_HEADLESS, }) if err != nil { return trace.Wrap(err) diff --git a/lib/client/cluster_client.go b/lib/client/cluster_client.go index 2aec602aa0f85..b28162b3ff8c0 100644 --- a/lib/client/cluster_client.go +++ b/lib/client/cluster_client.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" proxyclient "github.com/gravitational/teleport/api/client/proxy" "github.com/gravitational/teleport/api/mfa" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/services" ) @@ -312,6 +313,7 @@ func PerformMFACeremony(ctx context.Context, params PerformMFACeremonyParams) (* Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_SESSION, MFARequiredCheck: mfaRequiredReq, }) if err != nil { diff --git a/lib/teleterm/clusters/cluster_headless.go b/lib/teleterm/clusters/cluster_headless.go index 8897f0aa95700..e15804af62cff 100644 --- a/lib/teleterm/clusters/cluster_headless.go +++ b/lib/teleterm/clusters/cluster_headless.go @@ -25,6 +25,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" ) // WatchPendingHeadlessAuthentications watches the backend for pending headless authentication requests for the user. @@ -117,6 +118,7 @@ func (c *Cluster) UpdateHeadlessAuthenticationState(ctx context.Context, headles Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_HEADLESS, }) if err != nil { return trace.Wrap(err) diff --git a/lib/web/mfa.go b/lib/web/mfa.go index 85fa932a83082..f26e7c570200b 100644 --- a/lib/web/mfa.go +++ b/lib/web/mfa.go @@ -26,6 +26,7 @@ import ( "github.com/julienschmidt/httprouter" "github.com/gravitational/teleport/api/client/proto" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/httplib" @@ -130,15 +131,31 @@ func (h *Handler) addMFADeviceHandle(w http.ResponseWriter, r *http.Request, par return OK(), nil } +type createAuthenticateChallengeRequest struct { + Scope string `json:"scope"` + AllowReuse bool `json:"allow_reuse"` +} + // createAuthenticateChallengeHandle creates and returns MFA authentication challenges for the user in context (logged in user). // Used when users need to re-authenticate their second factors. func (h *Handler) createAuthenticateChallengeHandle(w http.ResponseWriter, r *http.Request, p httprouter.Params, c *SessionContext) (interface{}, error) { + var req createAuthenticateChallengeRequest + if err := httplib.ReadJSON(r, &req); err != nil { + return nil, trace.Wrap(err) + } + clt, err := c.GetClient() if err != nil { return nil, trace.Wrap(err) } - chal, err := clt.CreateAuthenticateChallenge(r.Context(), &proto.CreateAuthenticateChallengeRequest{}) + chal, err := clt.CreateAuthenticateChallenge(r.Context(), &proto.CreateAuthenticateChallengeRequest{ + Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ + ContextUser: &proto.ContextUser{}, + }, + Scope: webauthnpb.ChallengeScope(webauthnpb.ChallengeScope_value[req.Scope]), + AllowReuse: req.AllowReuse, + }) if err != nil { return nil, trace.Wrap(err) } @@ -291,7 +308,8 @@ func (r *isMFARequiredRequest) checkAndGetProtoRequest() (*proto.IsMFARequiredRe Protocol: r.Database.Protocol, Database: r.Database.DatabaseName, Username: r.Database.Username, - }}, + }, + }, } } @@ -322,7 +340,8 @@ func (r *isMFARequiredRequest) checkAndGetProtoRequest() (*proto.IsMFARequiredRe WindowsDesktop: &proto.RouteToWindowsDesktop{ WindowsDesktop: r.WindowsDesktop.DesktopName, Login: r.WindowsDesktop.Login, - }}, + }, + }, } } @@ -340,7 +359,8 @@ func (r *isMFARequiredRequest) checkAndGetProtoRequest() (*proto.IsMFARequiredRe Node: &proto.NodeLogin{ Login: r.Node.Login, Node: r.Node.NodeName, - }}, + }, + }, } } diff --git a/tool/tsh/common/mfa.go b/tool/tsh/common/mfa.go index 572e958c1da87..b89e631dc223f 100644 --- a/tool/tsh/common/mfa.go +++ b/tool/tsh/common/mfa.go @@ -37,6 +37,7 @@ import ( "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" + webauthnpb "github.com/gravitational/teleport/api/types/webauthn" "github.com/gravitational/teleport/api/utils/prompt" "github.com/gravitational/teleport/lib/asciitable" "github.com/gravitational/teleport/lib/auth/touchid" @@ -334,7 +335,9 @@ func (c *mfaAddCommand) addDeviceRPC(ctx context.Context, tc *client.TeleportCli // Issue the authn challenge. // Required for the registration challenge. - authChallenge, err := aci.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{}) + authChallenge, err := aci.CreateAuthenticateChallenge(ctx, &proto.CreateAuthenticateChallengeRequest{ + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, + }) if err != nil { return trace.Wrap(err) } @@ -596,6 +599,7 @@ func (c *mfaRemoveCommand) run(cf *CLIConf) error { Request: &proto.CreateAuthenticateChallengeRequest_ContextUser{ ContextUser: &proto.ContextUser{}, }, + Scope: webauthnpb.ChallengeScope_CHALLENGE_SCOPE_MANAGE_DEVICES, }) if err != nil { return trace.Wrap(err) diff --git a/web/packages/teleport/src/Account/ManageDevices/ManageDevices.tsx b/web/packages/teleport/src/Account/ManageDevices/ManageDevices.tsx index df23b323f9359..0fc49ca3ab20a 100644 --- a/web/packages/teleport/src/Account/ManageDevices/ManageDevices.tsx +++ b/web/packages/teleport/src/Account/ManageDevices/ManageDevices.tsx @@ -104,6 +104,7 @@ export function ManageDevices({ onAuthenticated={setToken} onClose={hideReAuthenticate} actionText="registering a new device" + challengeScope="CHALLENGE_SCOPE_MANAGE_DEVICES" /> )} {isAddDeviceVisible && ( diff --git a/web/packages/teleport/src/Console/DocumentSsh/useGetScpUrl.ts b/web/packages/teleport/src/Console/DocumentSsh/useGetScpUrl.ts index 0757e16ce77ef..6e8df38679de7 100644 --- a/web/packages/teleport/src/Console/DocumentSsh/useGetScpUrl.ts +++ b/web/packages/teleport/src/Console/DocumentSsh/useGetScpUrl.ts @@ -35,7 +35,9 @@ export default function useGetScpUrl(addMfaToScpUrls: boolean) { return cfg.getScpUrl(params); } try { - let webauthn = await auth.getWebauthnResponse(); + let webauthn = await auth.getWebauthnResponse( + 'CHALLENGE_SCOPE_SESSION' + ); setAttempt({ status: 'success', statusText: '', diff --git a/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.story.tsx b/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.story.tsx index 088bedae810a2..6cb3c2c8a05ac 100644 --- a/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.story.tsx +++ b/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.story.tsx @@ -47,4 +47,5 @@ const props: State = { onClose: () => null, auth2faType: 'on', actionText: 'performing this action', + challengeScope: 'CHALLENGE_SCOPE_UNSPECIFIED', }; diff --git a/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.tsx b/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.tsx index 9c769393a970d..327f073cf16e7 100644 --- a/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.tsx +++ b/web/packages/teleport/src/components/ReAuthenticate/ReAuthenticate.tsx @@ -47,6 +47,7 @@ export function ReAuthenticate({ auth2faType, preferredMfaType, actionText, + challengeScope, }: State) { const [otpToken, setOtpToken] = useState(''); const mfaOptions = createMfaOptions({ @@ -60,7 +61,7 @@ export function ReAuthenticate({ e.preventDefault(); if (mfaOption?.value === 'webauthn') { - submitWithWebauthn(); + submitWithWebauthn(challengeScope); } if (mfaOption?.value === 'otp') { submitWithTotp(otpToken); diff --git a/web/packages/teleport/src/components/ReAuthenticate/useReAuthenticate.ts b/web/packages/teleport/src/components/ReAuthenticate/useReAuthenticate.ts index 3ad3116768fff..e11945faf961a 100644 --- a/web/packages/teleport/src/components/ReAuthenticate/useReAuthenticate.ts +++ b/web/packages/teleport/src/components/ReAuthenticate/useReAuthenticate.ts @@ -31,7 +31,11 @@ import type { MfaAuthnResponse } from 'teleport/services/mfa'; // token, and after successfully obtaining the token, the function // `onAuthenticated` will be called with this token. export default function useReAuthenticate(props: Props) { - const { onClose, actionText = defaultActionText } = props; + const { + onClose, + actionText = defaultActionText, + challengeScope = defaultChallengeScope, + } = props; // Note that attempt state "success" is not used or required. // After the user submits, the control is passed back @@ -52,12 +56,12 @@ export default function useReAuthenticate(props: Props) { .catch(handleError); } - function submitWithWebauthn() { + function submitWithWebauthn(scope) { setAttempt({ status: 'processing' }); if ('onMfaResponse' in props) { auth - .getWebauthnResponse() + .getWebauthnResponse(scope) .then(webauthnResponse => props.onMfaResponse({ webauthn_response: webauthnResponse }) ) @@ -66,7 +70,7 @@ export default function useReAuthenticate(props: Props) { } auth - .createPrivilegeTokenWithWebauthn() + .createPrivilegeTokenWithWebauthn(scope) .then(props.onAuthenticated) .catch((err: Error) => { // This catches a webauthn frontend error that occurs on Firefox and replaces it with a more helpful error message. @@ -96,11 +100,13 @@ export default function useReAuthenticate(props: Props) { auth2faType: cfg.getAuth2faType(), preferredMfaType: cfg.getPreferredMfaType(), actionText, + challengeScope, onClose, }; } const defaultActionText = 'performing this action'; +const defaultChallengeScope = 'CHALLENGE_SCOPE_UNSPECIFIED'; type BaseProps = { onClose: () => void; @@ -114,6 +120,13 @@ type BaseProps = { * * */ actionText?: string; + /** + * The MFA challenge scope of the action to perform, as defined in webauthn.proto. + * + * Default value: "CHALLENGE_SCOPE_UNSPECIFIED" + * + * */ + challengeScope?: string; }; // MfaResponseProps defines a function diff --git a/web/packages/teleport/src/services/api/api.ts b/web/packages/teleport/src/services/api/api.ts index 09107e3d3a70a..f11fdc80135a9 100644 --- a/web/packages/teleport/src/services/api/api.ts +++ b/web/packages/teleport/src/services/api/api.ts @@ -117,7 +117,9 @@ const api = { let webauthnResponseForRetry; try { - webauthnResponseForRetry = await auth.getWebauthnResponse(); + webauthnResponseForRetry = await auth.getWebauthnResponse( + 'CHALLENGE_SCOPE_ADMIN_ACTION' + ); } catch (err) { throw new Error( 'Failed to fetch webauthn credentials, please connect a registered hardware key and try again. If you do not have a hardware key registered, you can add one from your account settings page.' diff --git a/web/packages/teleport/src/services/auth/auth.ts b/web/packages/teleport/src/services/auth/auth.ts index a90e511d57c7e..037bc453f5319 100644 --- a/web/packages/teleport/src/services/auth/auth.ts +++ b/web/packages/teleport/src/services/auth/auth.ts @@ -245,7 +245,9 @@ const auth = { headlessSSOAccept(transactionId: string) { return auth .checkWebauthnSupport() - .then(() => api.post(cfg.api.mfaAuthnChallengePath)) + .then(() => + api.post(cfg.api.mfaAuthnChallengePath, { scope: 'SCOPE_HEADLESS' }) + ) .then(res => navigator.credentials.get({ publicKey: makeMfaAuthenticateChallenge(res).webauthnPublicKey, @@ -273,12 +275,12 @@ const auth = { return api.post(cfg.api.createPrivilegeTokenPath, { secondFactorToken }); }, - fetchWebauthnChallenge() { + fetchWebauthnChallenge(scope) { return auth .checkWebauthnSupport() .then(() => api - .post(cfg.api.mfaAuthnChallengePath) + .post(cfg.api.mfaAuthnChallengePath, { scope: scope }) .then(makeMfaAuthenticateChallenge) ) .then(res => @@ -288,8 +290,8 @@ const auth = { ); }, - createPrivilegeTokenWithWebauthn() { - return auth.fetchWebauthnChallenge().then(res => + createPrivilegeTokenWithWebauthn(scope) { + return auth.fetchWebauthnChallenge(scope).then(res => api.post(cfg.api.createPrivilegeTokenPath, { webauthnAssertionResponse: makeWebauthnAssertionResponse(res), }) @@ -300,9 +302,9 @@ const auth = { return api.post(cfg.api.createPrivilegeTokenPath, {}); }, - getWebauthnResponse() { + getWebauthnResponse(scope) { return auth - .fetchWebauthnChallenge() + .fetchWebauthnChallenge(scope) .then(res => makeWebauthnAssertionResponse(res)); }, };