diff --git a/api/types/github.go b/api/types/github.go index 1a6ad75377444..411705880207f 100644 --- a/api/types/github.go +++ b/api/types/github.go @@ -69,16 +69,6 @@ func NewGithubConnector(name string, spec GithubConnectorSpecV3) (GithubConnecto return c, nil } -// GithubClaims represents Github user information obtained during OAuth2 flow -type GithubClaims struct { - // Username is the user's username - Username string - // OrganizationToTeams is the user's organization and team membership - OrganizationToTeams map[string][]string - // Teams is the users team membership - Teams []string -} - // GetVersion returns resource version func (c *GithubConnectorV3) GetVersion() string { return c.Version @@ -161,6 +151,18 @@ func (c *GithubConnectorV3) CheckAndSetDefaults() error { if err := c.Metadata.CheckAndSetDefaults(); err != nil { return trace.Wrap(err) } + + // make sure claim mappings have either roles or a role template + for i, v := range c.Spec.TeamsToLogins { + if v.Team == "" { + return trace.BadParameter("team_to_logins mapping #%v is invalid, team is empty.", i+1) + } + } + + if len(c.Spec.TeamsToLogins) == 0 { + return trace.BadParameter("team_to_logins mapping is invalid, no mappings defined.") + } + return nil } diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 69a8442f3aee2..8a244c9d8dfc8 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -7960,9 +7960,15 @@ type SSODiagnosticInfo struct { OIDCTraitsFromClaims github_com_gravitational_teleport_api_types_wrappers.Traits `protobuf:"bytes,24,opt,name=OIDCTraitsFromClaims,proto3,customtype=github.com/gravitational/teleport/api/types/wrappers.Traits" json:"oidc_traits_from_claims,omitempty"` // OIDCConnectorTraitMapping represents connector-specific trait mapping. OIDCConnectorTraitMapping []TraitMapping `protobuf:"bytes,25,rep,name=OIDCConnectorTraitMapping,proto3" json:"oidc_connector_trait_mapping,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + // GithubClaims represents Github user information obtained during OAuth2 flow. + GithubClaims *GithubClaims `protobuf:"bytes,30,opt,name=GithubClaims,proto3" json:"github_claims,omitempty"` + // GithubTeamsToLogins is TeamsToLogins mapping from Github connector used in the SSO flow. + GithubTeamsToLogins []TeamMapping `protobuf:"bytes,31,rep,name=GithubTeamsToLogins,proto3" json:"github_teams_to_logins,omitempty"` + // GithubTokenInfo stores diagnostic info about Github OAuth2 token obtained during SSO flow. + GithubTokenInfo *GithubTokenInfo `protobuf:"bytes,32,opt,name=GithubTokenInfo,proto3" json:"github_token_info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SSODiagnosticInfo) Reset() { *m = SSODiagnosticInfo{} } @@ -7998,6 +8004,96 @@ func (m *SSODiagnosticInfo) XXX_DiscardUnknown() { var xxx_messageInfo_SSODiagnosticInfo proto.InternalMessageInfo +// GithubTokenInfo stores diagnostic info about Github OAuth2 token obtained during SSO flow. +// The token itself is secret and therefore not included. +type GithubTokenInfo struct { + TokenType string `protobuf:"bytes,1,opt,name=TokenType,proto3" json:"token_type"` + Expires int64 `protobuf:"varint,2,opt,name=Expires,proto3" json:"expires"` + Scope string `protobuf:"bytes,3,opt,name=Scope,proto3" json:"scope"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GithubTokenInfo) Reset() { *m = GithubTokenInfo{} } +func (m *GithubTokenInfo) String() string { return proto.CompactTextString(m) } +func (*GithubTokenInfo) ProtoMessage() {} +func (*GithubTokenInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{151} +} +func (m *GithubTokenInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GithubTokenInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GithubTokenInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GithubTokenInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_GithubTokenInfo.Merge(m, src) +} +func (m *GithubTokenInfo) XXX_Size() int { + return m.Size() +} +func (m *GithubTokenInfo) XXX_DiscardUnknown() { + xxx_messageInfo_GithubTokenInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_GithubTokenInfo proto.InternalMessageInfo + +// GithubClaims represents Github user information obtained during OAuth2 flow +type GithubClaims struct { + // Username is the user's username + Username string `protobuf:"bytes,1,opt,name=Username,proto3" json:"username"` + // OrganizationToTeams is the user's organization and team membership + OrganizationToTeams github_com_gravitational_teleport_api_types_wrappers.Traits `protobuf:"bytes,2,opt,name=OrganizationToTeams,proto3,customtype=github.com/gravitational/teleport/api/types/wrappers.Traits" json:"organization_to_teams"` + // Teams is the users team membership + Teams []string `protobuf:"bytes,3,rep,name=Teams,proto3" json:"teams"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GithubClaims) Reset() { *m = GithubClaims{} } +func (m *GithubClaims) String() string { return proto.CompactTextString(m) } +func (*GithubClaims) ProtoMessage() {} +func (*GithubClaims) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{152} +} +func (m *GithubClaims) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GithubClaims) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GithubClaims.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GithubClaims) XXX_Merge(src proto.Message) { + xxx_messageInfo_GithubClaims.Merge(m, src) +} +func (m *GithubClaims) XXX_Size() int { + return m.Size() +} +func (m *GithubClaims) XXX_DiscardUnknown() { + xxx_messageInfo_GithubClaims.DiscardUnknown(m) +} + +var xxx_messageInfo_GithubClaims proto.InternalMessageInfo + // TeamMapping represents a single team membership mapping. type TeamMapping struct { // Organization is a Github organization a user belongs to. @@ -8019,7 +8115,7 @@ func (m *TeamMapping) Reset() { *m = TeamMapping{} } func (m *TeamMapping) String() string { return proto.CompactTextString(m) } func (*TeamMapping) ProtoMessage() {} func (*TeamMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{151} + return fileDescriptor_d938547f84707355, []int{153} } func (m *TeamMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8068,7 +8164,7 @@ type TrustedClusterV2 struct { func (m *TrustedClusterV2) Reset() { *m = TrustedClusterV2{} } func (*TrustedClusterV2) ProtoMessage() {} func (*TrustedClusterV2) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{152} + return fileDescriptor_d938547f84707355, []int{154} } func (m *TrustedClusterV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8110,7 +8206,7 @@ func (m *TrustedClusterV2List) Reset() { *m = TrustedClusterV2List{} } func (m *TrustedClusterV2List) String() string { return proto.CompactTextString(m) } func (*TrustedClusterV2List) ProtoMessage() {} func (*TrustedClusterV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{153} + return fileDescriptor_d938547f84707355, []int{155} } func (m *TrustedClusterV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8166,7 +8262,7 @@ func (m *TrustedClusterSpecV2) Reset() { *m = TrustedClusterSpecV2{} } func (m *TrustedClusterSpecV2) String() string { return proto.CompactTextString(m) } func (*TrustedClusterSpecV2) ProtoMessage() {} func (*TrustedClusterSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{154} + return fileDescriptor_d938547f84707355, []int{156} } func (m *TrustedClusterSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8219,7 +8315,7 @@ func (m *LockV2) Reset() { *m = LockV2{} } func (m *LockV2) String() string { return proto.CompactTextString(m) } func (*LockV2) ProtoMessage() {} func (*LockV2) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{155} + return fileDescriptor_d938547f84707355, []int{157} } func (m *LockV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8265,7 +8361,7 @@ func (m *LockSpecV2) Reset() { *m = LockSpecV2{} } func (m *LockSpecV2) String() string { return proto.CompactTextString(m) } func (*LockSpecV2) ProtoMessage() {} func (*LockSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{156} + return fileDescriptor_d938547f84707355, []int{158} } func (m *LockSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8320,7 +8416,7 @@ type LockTarget struct { func (m *LockTarget) Reset() { *m = LockTarget{} } func (*LockTarget) ProtoMessage() {} func (*LockTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{157} + return fileDescriptor_d938547f84707355, []int{159} } func (m *LockTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8364,7 +8460,7 @@ func (m *AddressCondition) Reset() { *m = AddressCondition{} } func (m *AddressCondition) String() string { return proto.CompactTextString(m) } func (*AddressCondition) ProtoMessage() {} func (*AddressCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{158} + return fileDescriptor_d938547f84707355, []int{160} } func (m *AddressCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8407,7 +8503,7 @@ func (m *NetworkRestrictionsSpecV4) Reset() { *m = NetworkRestrictionsSp func (m *NetworkRestrictionsSpecV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsSpecV4) ProtoMessage() {} func (*NetworkRestrictionsSpecV4) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{159} + return fileDescriptor_d938547f84707355, []int{161} } func (m *NetworkRestrictionsSpecV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8460,7 +8556,7 @@ func (m *NetworkRestrictionsV4) Reset() { *m = NetworkRestrictionsV4{} } func (m *NetworkRestrictionsV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsV4) ProtoMessage() {} func (*NetworkRestrictionsV4) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{160} + return fileDescriptor_d938547f84707355, []int{162} } func (m *NetworkRestrictionsV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8504,7 +8600,7 @@ func (m *WindowsDesktopServiceV3) Reset() { *m = WindowsDesktopServiceV3 func (m *WindowsDesktopServiceV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceV3) ProtoMessage() {} func (*WindowsDesktopServiceV3) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{161} + return fileDescriptor_d938547f84707355, []int{163} } func (m *WindowsDesktopServiceV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8550,7 +8646,7 @@ func (m *WindowsDesktopServiceSpecV3) Reset() { *m = WindowsDesktopServi func (m *WindowsDesktopServiceSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceSpecV3) ProtoMessage() {} func (*WindowsDesktopServiceSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{162} + return fileDescriptor_d938547f84707355, []int{164} } func (m *WindowsDesktopServiceSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8594,7 +8690,7 @@ func (m *WindowsDesktopFilter) Reset() { *m = WindowsDesktopFilter{} } func (m *WindowsDesktopFilter) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopFilter) ProtoMessage() {} func (*WindowsDesktopFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{163} + return fileDescriptor_d938547f84707355, []int{165} } func (m *WindowsDesktopFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8638,7 +8734,7 @@ func (m *WindowsDesktopV3) Reset() { *m = WindowsDesktopV3{} } func (m *WindowsDesktopV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopV3) ProtoMessage() {} func (*WindowsDesktopV3) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{164} + return fileDescriptor_d938547f84707355, []int{166} } func (m *WindowsDesktopV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8684,7 +8780,7 @@ func (m *WindowsDesktopSpecV3) Reset() { *m = WindowsDesktopSpecV3{} } func (m *WindowsDesktopSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopSpecV3) ProtoMessage() {} func (*WindowsDesktopSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{165} + return fileDescriptor_d938547f84707355, []int{167} } func (m *WindowsDesktopSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8750,7 +8846,7 @@ func (m *RegisterUsingTokenRequest) Reset() { *m = RegisterUsingTokenReq func (m *RegisterUsingTokenRequest) String() string { return proto.CompactTextString(m) } func (*RegisterUsingTokenRequest) ProtoMessage() {} func (*RegisterUsingTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{166} + return fileDescriptor_d938547f84707355, []int{168} } func (m *RegisterUsingTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8804,7 +8900,7 @@ func (m *RecoveryCodesV1) Reset() { *m = RecoveryCodesV1{} } func (m *RecoveryCodesV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesV1) ProtoMessage() {} func (*RecoveryCodesV1) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{167} + return fileDescriptor_d938547f84707355, []int{169} } func (m *RecoveryCodesV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8849,7 +8945,7 @@ func (m *RecoveryCodesSpecV1) Reset() { *m = RecoveryCodesSpecV1{} } func (m *RecoveryCodesSpecV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesSpecV1) ProtoMessage() {} func (*RecoveryCodesSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{168} + return fileDescriptor_d938547f84707355, []int{170} } func (m *RecoveryCodesSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8893,7 +8989,7 @@ func (m *RecoveryCode) Reset() { *m = RecoveryCode{} } func (m *RecoveryCode) String() string { return proto.CompactTextString(m) } func (*RecoveryCode) ProtoMessage() {} func (*RecoveryCode) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{169} + return fileDescriptor_d938547f84707355, []int{171} } func (m *RecoveryCode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8937,7 +9033,7 @@ func (m *SessionTrackerV1) Reset() { *m = SessionTrackerV1{} } func (m *SessionTrackerV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerV1) ProtoMessage() {} func (*SessionTrackerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{170} + return fileDescriptor_d938547f84707355, []int{172} } func (m *SessionTrackerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9027,7 +9123,7 @@ func (m *SessionTrackerSpecV1) Reset() { *m = SessionTrackerSpecV1{} } func (m *SessionTrackerSpecV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerSpecV1) ProtoMessage() {} func (*SessionTrackerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{171} + return fileDescriptor_d938547f84707355, []int{173} } func (m *SessionTrackerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9074,7 +9170,7 @@ func (m *SessionTrackerPolicySet) Reset() { *m = SessionTrackerPolicySet func (m *SessionTrackerPolicySet) String() string { return proto.CompactTextString(m) } func (*SessionTrackerPolicySet) ProtoMessage() {} func (*SessionTrackerPolicySet) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{172} + return fileDescriptor_d938547f84707355, []int{174} } func (m *SessionTrackerPolicySet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9122,7 +9218,7 @@ func (m *Participant) Reset() { *m = Participant{} } func (m *Participant) String() string { return proto.CompactTextString(m) } func (*Participant) ProtoMessage() {} func (*Participant) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{173} + return fileDescriptor_d938547f84707355, []int{175} } func (m *Participant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9166,7 +9262,7 @@ func (m *SortBy) Reset() { *m = SortBy{} } func (m *SortBy) String() string { return proto.CompactTextString(m) } func (*SortBy) ProtoMessage() {} func (*SortBy) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{174} + return fileDescriptor_d938547f84707355, []int{176} } func (m *SortBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9373,6 +9469,8 @@ func init() { proto.RegisterType((*SSOWarnings)(nil), "types.SSOWarnings") proto.RegisterType((*CreateUserParams)(nil), "types.CreateUserParams") proto.RegisterType((*SSODiagnosticInfo)(nil), "types.SSODiagnosticInfo") + proto.RegisterType((*GithubTokenInfo)(nil), "types.GithubTokenInfo") + proto.RegisterType((*GithubClaims)(nil), "types.GithubClaims") proto.RegisterType((*TeamMapping)(nil), "types.TeamMapping") proto.RegisterType((*TrustedClusterV2)(nil), "types.TrustedClusterV2") proto.RegisterType((*TrustedClusterV2List)(nil), "types.TrustedClusterV2List") @@ -9402,799 +9500,810 @@ func init() { func init() { proto.RegisterFile("types.proto", fileDescriptor_d938547f84707355) } var fileDescriptor_d938547f84707355 = []byte{ - // 12664 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x7d, 0x6d, 0x6c, 0x1c, 0x49, - 0x76, 0x98, 0x7a, 0x66, 0x48, 0x0e, 0x1f, 0x87, 0xe4, 0xb0, 0x48, 0x49, 0x94, 0x56, 0xbb, 0xa3, - 0xed, 0xdd, 0xd5, 0x6a, 0xb5, 0xbb, 0xd2, 0x89, 0xba, 0xdd, 0xf3, 0xde, 0x7e, 0xce, 0x90, 0x94, - 0xc4, 0x15, 0x45, 0x72, 0x7b, 0xf8, 0x71, 0xe7, 0xbb, 0x73, 0xbb, 0x39, 0x5d, 0x24, 0x7b, 0x39, - 0x33, 0x3d, 0xd7, 0xdd, 0x23, 0x89, 0x76, 0x0c, 0xdb, 0x08, 0x2e, 0x86, 0x61, 0xf8, 0xce, 0x17, - 0x9c, 0x63, 0x3b, 0x70, 0x60, 0xc7, 0x88, 0x93, 0x38, 0xc1, 0x19, 0x81, 0x1d, 0x20, 0x09, 0x12, - 0x38, 0x30, 0x10, 0x18, 0x87, 0x20, 0x41, 0xfc, 0x2f, 0xf0, 0x25, 0x60, 0xe2, 0x3b, 0xff, 0x22, - 0x10, 0x20, 0x80, 0x7f, 0xf9, 0x12, 0x03, 0x41, 0xbd, 0xaa, 0xea, 0xae, 0xea, 0xe9, 0x21, 0x87, - 0x2b, 0x2d, 0x62, 0xed, 0x2f, 0x72, 0x5e, 0xbd, 0xf7, 0xaa, 0xba, 0xea, 0xd5, 0xab, 0x57, 0xaf, - 0x5e, 0xbd, 0x82, 0xb1, 0xe8, 0xa0, 0x43, 0xc3, 0xeb, 0x9d, 0xc0, 0x8f, 0x7c, 0x32, 0x84, 0x3f, - 0x2e, 0xce, 0xec, 0xfa, 0xbb, 0x3e, 0x42, 0x6e, 0xb0, 0xff, 0x78, 0xe1, 0xc5, 0xca, 0xae, 0xef, - 0xef, 0x36, 0xe9, 0x0d, 0xfc, 0xb5, 0xdd, 0xdd, 0xb9, 0x11, 0x79, 0x2d, 0x1a, 0x46, 0x4e, 0xab, - 0x23, 0x10, 0xe6, 0x77, 0xbd, 0x68, 0xaf, 0xbb, 0x7d, 0xbd, 0xe1, 0xb7, 0x6e, 0xec, 0x06, 0xce, - 0x03, 0x2f, 0x72, 0x22, 0xcf, 0x6f, 0x3b, 0xcd, 0x1b, 0x11, 0x6d, 0xd2, 0x8e, 0x1f, 0x44, 0x37, - 0x9c, 0x8e, 0x77, 0x03, 0xeb, 0xb8, 0xf1, 0x30, 0x70, 0x3a, 0x1d, 0x1a, 0x24, 0xff, 0x70, 0x26, - 0xe6, 0x3f, 0xcc, 0xc3, 0xe8, 0x3d, 0x4a, 0x3b, 0xd5, 0xa6, 0xf7, 0x80, 0x92, 0x17, 0xa0, 0xb0, - 0xe2, 0xb4, 0xe8, 0xac, 0x71, 0xd9, 0xb8, 0x3a, 0x5a, 0x9b, 0x3c, 0x3a, 0xac, 0x8c, 0x85, 0x34, - 0x78, 0x40, 0x03, 0xbb, 0xed, 0xb4, 0xa8, 0x85, 0x85, 0xe4, 0x55, 0x18, 0x65, 0x7f, 0xc3, 0x8e, - 0xd3, 0xa0, 0xb3, 0x39, 0xc4, 0x1c, 0x3f, 0x3a, 0xac, 0x8c, 0xb6, 0x25, 0xd0, 0x4a, 0xca, 0xc9, - 0x15, 0x18, 0x59, 0xa6, 0x4e, 0x48, 0x97, 0x16, 0x66, 0xf3, 0x97, 0x8d, 0xab, 0xf9, 0x5a, 0xe9, - 0xe8, 0xb0, 0x52, 0x6c, 0x32, 0x90, 0xed, 0xb9, 0x96, 0x2c, 0x24, 0x4b, 0x30, 0xb2, 0xf8, 0xa8, - 0xe3, 0x05, 0x34, 0x9c, 0x2d, 0x5c, 0x36, 0xae, 0x8e, 0xcd, 0x5d, 0xbc, 0xce, 0xbf, 0xff, 0xba, - 0xfc, 0xfe, 0xeb, 0xeb, 0xf2, 0xfb, 0x6b, 0xd3, 0xdf, 0x3b, 0xac, 0x9c, 0x39, 0x3a, 0xac, 0x8c, - 0x50, 0x4e, 0xf2, 0x2b, 0xff, 0xa3, 0x62, 0x58, 0x92, 0x9e, 0xbc, 0x03, 0x85, 0xf5, 0x83, 0x0e, - 0x9d, 0x1d, 0xbd, 0x6c, 0x5c, 0x9d, 0x98, 0x7b, 0xee, 0x3a, 0xef, 0xf1, 0xf8, 0x23, 0x93, 0xff, - 0x18, 0x56, 0xad, 0x78, 0x74, 0x58, 0x29, 0x30, 0x14, 0x0b, 0xa9, 0xc8, 0xeb, 0x30, 0x7c, 0xd7, - 0x0f, 0xa3, 0xa5, 0x85, 0x59, 0xc0, 0x4f, 0x3b, 0x7b, 0x74, 0x58, 0x99, 0xda, 0xf3, 0xc3, 0xc8, - 0xf6, 0xdc, 0xd7, 0xfc, 0x96, 0x17, 0xd1, 0x56, 0x27, 0x3a, 0xb0, 0x04, 0x92, 0xb9, 0x0d, 0xe3, - 0x1a, 0x3f, 0x32, 0x06, 0x23, 0x1b, 0x2b, 0xf7, 0x56, 0x56, 0xb7, 0x56, 0xca, 0x67, 0x48, 0x11, - 0x0a, 0x2b, 0xab, 0x0b, 0x8b, 0x65, 0x83, 0x8c, 0x40, 0xbe, 0xba, 0xb6, 0x56, 0xce, 0x91, 0x12, - 0x14, 0x17, 0xaa, 0xeb, 0xd5, 0x5a, 0xb5, 0xbe, 0x58, 0xce, 0x93, 0x69, 0x98, 0xdc, 0x5a, 0x5a, - 0x59, 0x58, 0xdd, 0xaa, 0xdb, 0x0b, 0x8b, 0xf5, 0x7b, 0xeb, 0xab, 0x6b, 0xe5, 0x02, 0x99, 0x00, - 0xb8, 0xb7, 0x51, 0x5b, 0xb4, 0x56, 0x16, 0xd7, 0x17, 0xeb, 0xe5, 0x21, 0xf3, 0x17, 0xf2, 0x50, - 0xbc, 0x4f, 0x23, 0xc7, 0x75, 0x22, 0x87, 0x5c, 0xd2, 0x86, 0x08, 0x5b, 0xaf, 0x8c, 0xcd, 0x0b, - 0xbd, 0x63, 0x33, 0x74, 0x74, 0x58, 0x31, 0x5e, 0x57, 0xc7, 0xe4, 0x6d, 0x18, 0x5b, 0xa0, 0x61, - 0x23, 0xf0, 0x3a, 0x4c, 0x5e, 0x70, 0x5c, 0x46, 0x6b, 0x17, 0x8e, 0x0e, 0x2b, 0x67, 0xdd, 0x04, - 0xac, 0x7c, 0xab, 0x8a, 0x4d, 0x96, 0x60, 0x78, 0xd9, 0xd9, 0xa6, 0xcd, 0x70, 0x76, 0xe8, 0x72, - 0xfe, 0xea, 0xd8, 0xdc, 0x33, 0xa2, 0x7f, 0x65, 0x03, 0xaf, 0xf3, 0xd2, 0xc5, 0x76, 0x14, 0x1c, - 0xd4, 0x66, 0x8e, 0x0e, 0x2b, 0xe5, 0x26, 0x02, 0xd4, 0xbe, 0xe3, 0x28, 0xa4, 0x9e, 0x8c, 0xf9, - 0xf0, 0x89, 0x63, 0xfe, 0xec, 0xf7, 0x0e, 0x2b, 0x06, 0x1b, 0x0b, 0x31, 0xe6, 0x09, 0x3f, 0x7d, - 0xf4, 0x2f, 0x43, 0x6e, 0x69, 0x61, 0x76, 0x04, 0x65, 0xad, 0x7c, 0x74, 0x58, 0x29, 0x69, 0xc3, - 0x96, 0x5b, 0x5a, 0xb8, 0xf8, 0x16, 0x8c, 0x29, 0x6d, 0x24, 0x65, 0xc8, 0xef, 0xd3, 0x03, 0xde, - 0x9f, 0x16, 0xfb, 0x97, 0xcc, 0xc0, 0xd0, 0x03, 0xa7, 0xd9, 0x15, 0x1d, 0x68, 0xf1, 0x1f, 0x5f, - 0xcc, 0xfd, 0x98, 0x61, 0xfe, 0xdd, 0x02, 0x14, 0x2d, 0x9f, 0xcf, 0x33, 0xf2, 0x0a, 0x0c, 0xd5, - 0x23, 0x27, 0x92, 0x43, 0x31, 0x7d, 0x74, 0x58, 0x99, 0x0c, 0x19, 0x40, 0xa9, 0x8f, 0x63, 0x30, - 0xd4, 0xb5, 0x3d, 0x27, 0x94, 0x43, 0x82, 0xa8, 0x1d, 0x06, 0x50, 0x51, 0x11, 0x83, 0x5c, 0x81, - 0xc2, 0x7d, 0xdf, 0xa5, 0x62, 0x54, 0xc8, 0xd1, 0x61, 0x65, 0xa2, 0xe5, 0xbb, 0x2a, 0x22, 0x96, - 0x93, 0xd7, 0x60, 0x74, 0xbe, 0x1b, 0x04, 0xb4, 0xcd, 0x44, 0xb5, 0x80, 0xc8, 0x13, 0x47, 0x87, - 0x15, 0x68, 0x70, 0x20, 0x9b, 0x5c, 0x09, 0x02, 0xeb, 0xea, 0x7a, 0xe4, 0x04, 0x11, 0x75, 0x67, - 0x87, 0x06, 0xea, 0x6a, 0x36, 0xbd, 0xa6, 0x42, 0x4e, 0x92, 0xee, 0x6a, 0xc1, 0x89, 0xdc, 0x85, - 0xb1, 0x3b, 0x81, 0xd3, 0xa0, 0x6b, 0x34, 0xf0, 0x7c, 0x17, 0xc7, 0x30, 0x5f, 0xbb, 0x72, 0x74, - 0x58, 0x39, 0xb7, 0xcb, 0xc0, 0x76, 0x07, 0xe1, 0x09, 0xf5, 0x8f, 0x0e, 0x2b, 0xc5, 0x85, 0x6e, - 0x80, 0xbd, 0x67, 0xa9, 0xa4, 0xe4, 0x27, 0xd9, 0x90, 0x84, 0x11, 0x76, 0x2d, 0x75, 0x71, 0xf4, - 0x8e, 0x6f, 0xa2, 0x29, 0x9a, 0x78, 0xae, 0xe9, 0x84, 0x91, 0x1d, 0x70, 0xba, 0x54, 0x3b, 0x55, - 0x96, 0x64, 0x15, 0x8a, 0xf5, 0xc6, 0x1e, 0x75, 0xbb, 0x4d, 0x3a, 0x5b, 0x44, 0xf6, 0xe7, 0x85, - 0xe0, 0xca, 0xf1, 0x94, 0xc5, 0xb5, 0x8b, 0x82, 0x37, 0x09, 0x05, 0x44, 0xe9, 0xfb, 0x98, 0xc9, - 0x17, 0x8b, 0xbf, 0xfe, 0xdb, 0x95, 0x33, 0x3f, 0xf7, 0xdf, 0x2f, 0x9f, 0x31, 0xff, 0x55, 0x0e, - 0xca, 0x69, 0x26, 0x64, 0x07, 0xc6, 0x37, 0x3a, 0xae, 0x13, 0xd1, 0xf9, 0xa6, 0x47, 0xdb, 0x51, - 0x88, 0x42, 0x72, 0xfc, 0x37, 0xbd, 0x28, 0xea, 0x9d, 0xed, 0x22, 0xa1, 0xdd, 0xe0, 0x94, 0xa9, - 0xaf, 0xd2, 0xd9, 0x26, 0xf5, 0xd4, 0x51, 0x4f, 0x87, 0x28, 0x61, 0xa7, 0xab, 0x87, 0x6b, 0xf8, - 0x3e, 0xf5, 0x08, 0xb6, 0x42, 0x80, 0xda, 0xee, 0xf6, 0x01, 0x4a, 0xe6, 0xe0, 0x02, 0xc4, 0x48, - 0x32, 0x04, 0x88, 0x81, 0xcd, 0xbf, 0x30, 0x60, 0xc2, 0xa2, 0xa1, 0xdf, 0x0d, 0x1a, 0xf4, 0x2e, - 0x75, 0x5c, 0x1a, 0x30, 0xf1, 0xbf, 0xe7, 0xb5, 0x5d, 0x31, 0xa7, 0x50, 0xfc, 0xf7, 0xbd, 0xb6, - 0x3a, 0x85, 0xb1, 0x9c, 0x7c, 0x0e, 0x46, 0xea, 0xdd, 0x6d, 0x44, 0xe5, 0x73, 0xea, 0x1c, 0x8e, - 0x58, 0x77, 0xdb, 0x4e, 0xa1, 0x4b, 0x34, 0x72, 0x03, 0x46, 0x36, 0x69, 0x10, 0x26, 0x1a, 0x0f, - 0x35, 0xfb, 0x03, 0x0e, 0x52, 0x09, 0x04, 0x16, 0xb9, 0x93, 0x68, 0x5d, 0xb1, 0x26, 0x4d, 0xa6, - 0x74, 0x5d, 0x22, 0x2a, 0x2d, 0x01, 0x51, 0x45, 0x45, 0x62, 0x99, 0xdf, 0xce, 0x41, 0x79, 0xc1, - 0x89, 0x9c, 0x6d, 0x27, 0x14, 0xfd, 0xb9, 0x79, 0x8b, 0xe9, 0x71, 0xe5, 0x43, 0x51, 0x8f, 0xb3, - 0x96, 0x7f, 0xe2, 0xcf, 0x7b, 0x29, 0xfd, 0x79, 0x63, 0x6c, 0x81, 0x14, 0x9f, 0x97, 0x7c, 0xd4, - 0xbb, 0x27, 0x7f, 0x54, 0x59, 0x7c, 0x54, 0x51, 0x7e, 0x54, 0xf2, 0x29, 0xe4, 0x5d, 0x28, 0xd4, - 0x3b, 0xb4, 0x21, 0x94, 0x88, 0xd4, 0xfd, 0xfa, 0xc7, 0x31, 0x84, 0xcd, 0x5b, 0xb5, 0x92, 0x60, - 0x53, 0x08, 0x3b, 0xb4, 0x61, 0x21, 0x99, 0x32, 0x69, 0xbe, 0x33, 0x0c, 0x33, 0x59, 0x64, 0xe4, - 0x5d, 0x7d, 0x71, 0xe2, 0xdd, 0xf3, 0x4c, 0xdf, 0xc5, 0x69, 0xd6, 0xd0, 0x97, 0xa7, 0x6b, 0x50, - 0x5c, 0x63, 0x02, 0xd9, 0xf0, 0x9b, 0xa2, 0xe7, 0x98, 0x56, 0x2c, 0x76, 0x24, 0xcc, 0xb0, 0xe2, - 0x72, 0xf2, 0x0c, 0xe4, 0x37, 0xac, 0x25, 0xd1, 0x5d, 0xa3, 0x47, 0x87, 0x95, 0x7c, 0x37, 0xf0, - 0x66, 0x0d, 0x8b, 0x41, 0xc9, 0x0d, 0x18, 0x9e, 0xaf, 0xce, 0xd3, 0x20, 0xc2, 0x6e, 0x2a, 0xd5, - 0xce, 0x33, 0x69, 0x69, 0x38, 0x76, 0x83, 0x06, 0x91, 0x56, 0xbd, 0x40, 0x23, 0xaf, 0x42, 0xbe, - 0xba, 0x55, 0x17, 0x3d, 0x03, 0xa2, 0x67, 0xaa, 0x5b, 0xf5, 0xda, 0xb8, 0xe8, 0x88, 0xbc, 0xf3, - 0x30, 0x64, 0xdc, 0xab, 0x5b, 0x75, 0x75, 0xb4, 0x86, 0x8f, 0x19, 0xad, 0xab, 0x50, 0x64, 0x76, - 0x06, 0x5b, 0xe0, 0x51, 0x29, 0x8e, 0x72, 0xf3, 0x69, 0x4f, 0xc0, 0xac, 0xb8, 0x94, 0xbc, 0x10, - 0x9b, 0x2d, 0xc5, 0x84, 0x9f, 0x30, 0x5b, 0xa4, 0xb1, 0x42, 0x1e, 0xc1, 0xf8, 0xc2, 0x41, 0xdb, - 0x69, 0x79, 0x0d, 0xb1, 0x84, 0x8f, 0xe2, 0x12, 0x7e, 0xfd, 0x98, 0x61, 0xbc, 0xae, 0x11, 0xf0, - 0x55, 0x5d, 0x2a, 0xdf, 0x59, 0x97, 0x97, 0xd9, 0xe9, 0x15, 0x7e, 0xd6, 0xb0, 0xf4, 0x8a, 0xd8, - 0x5c, 0x92, 0x2a, 0x12, 0xed, 0xaa, 0x44, 0xec, 0x24, 0x38, 0x99, 0x4b, 0x81, 0x80, 0xa8, 0x73, - 0x29, 0x5e, 0x74, 0xdf, 0x85, 0xfc, 0x9d, 0xf9, 0xb5, 0xd9, 0x31, 0xe4, 0x41, 0x04, 0x8f, 0x3b, - 0xf3, 0x6b, 0xf3, 0x4d, 0xbf, 0xeb, 0xd6, 0x3f, 0x5a, 0xae, 0x9d, 0x17, 0x6c, 0xc6, 0x77, 0x1b, - 0x1d, 0xad, 0x45, 0x8c, 0x8e, 0x2c, 0x42, 0x51, 0x7e, 0xe5, 0x6c, 0x09, 0x79, 0x4c, 0xa5, 0x3e, - 0x7e, 0xf3, 0x16, 0x9f, 0x6b, 0xae, 0xf8, 0xad, 0xb6, 0x42, 0xe2, 0x5c, 0xdc, 0x02, 0xd2, 0xdb, - 0x2f, 0x19, 0x96, 0xc4, 0xab, 0xaa, 0x25, 0x31, 0x36, 0x77, 0x56, 0xd4, 0x35, 0xef, 0xb7, 0x5a, - 0x4e, 0xdb, 0x45, 0xda, 0xcd, 0x39, 0xd5, 0xc0, 0xa8, 0xc2, 0x44, 0xd2, 0x90, 0x65, 0x2f, 0x8c, - 0xc8, 0x0d, 0x18, 0x95, 0x10, 0xb6, 0x88, 0xe4, 0x33, 0x9b, 0x6c, 0x25, 0x38, 0xe6, 0x9f, 0xe4, - 0x00, 0x92, 0x92, 0xa7, 0x54, 0xcf, 0x7c, 0x41, 0xd3, 0x33, 0x67, 0xd3, 0x02, 0xda, 0x57, 0xc3, - 0x90, 0xf7, 0x61, 0x98, 0x99, 0x5c, 0x5d, 0x69, 0x52, 0x9e, 0x4f, 0x93, 0x62, 0xe1, 0xe6, 0xad, - 0xda, 0x84, 0x20, 0x1e, 0x0e, 0x11, 0x62, 0x09, 0x32, 0x45, 0x45, 0xfd, 0xc1, 0x50, 0x32, 0x18, - 0x42, 0x39, 0x5d, 0x55, 0xb4, 0x8b, 0x91, 0xcc, 0x47, 0xa9, 0x5d, 0x14, 0xdd, 0x72, 0x81, 0xeb, - 0x16, 0xde, 0xa9, 0x23, 0x42, 0xb7, 0xa4, 0x35, 0x0b, 0xef, 0xc0, 0x13, 0x35, 0x4b, 0x27, 0x3d, - 0x6d, 0x0b, 0x28, 0x06, 0x57, 0x33, 0x7b, 0x25, 0x6b, 0xc2, 0x5e, 0x3e, 0x69, 0xc2, 0xa6, 0xa7, - 0xeb, 0xad, 0x7e, 0xba, 0xec, 0xac, 0x9c, 0x5d, 0xce, 0x43, 0x95, 0x1c, 0x75, 0xda, 0xdb, 0x7c, - 0x6a, 0x0e, 0xf7, 0x9d, 0x9a, 0x67, 0x33, 0xa7, 0x26, 0x9f, 0x98, 0x6f, 0xc3, 0x50, 0xf5, 0xa7, - 0xba, 0x01, 0x15, 0xb6, 0x5f, 0x49, 0xd6, 0xc9, 0x60, 0xf1, 0x9c, 0x9e, 0x74, 0xd8, 0x4f, 0xd5, - 0x66, 0xc6, 0x72, 0x56, 0xf3, 0xfa, 0x72, 0x5d, 0xd8, 0x75, 0x24, 0xd5, 0x2d, 0xeb, 0xcb, 0x4a, - 0xb3, 0x23, 0xed, 0xab, 0x19, 0x15, 0xb9, 0x01, 0xb9, 0xea, 0x02, 0x6e, 0x16, 0xc7, 0xe6, 0x46, - 0x65, 0xb5, 0x0b, 0xb5, 0x19, 0x41, 0x52, 0x72, 0xb4, 0xfd, 0x43, 0x75, 0x81, 0xd4, 0x60, 0xe8, - 0xfe, 0x41, 0xfd, 0xa3, 0x65, 0xa1, 0xc8, 0xa6, 0xa5, 0x5c, 0x33, 0xd8, 0x2a, 0xae, 0x42, 0x61, - 0xd2, 0xe2, 0xd6, 0x41, 0xf8, 0xf5, 0xa6, 0xda, 0x62, 0x44, 0xfb, 0xf4, 0x14, 0xc8, 0xbf, 0x30, - 0x14, 0x5b, 0x43, 0xc8, 0x3a, 0xdb, 0xd3, 0x0a, 0x89, 0x33, 0x12, 0xcb, 0xa7, 0x47, 0xe2, 0x62, - 0x79, 0x7b, 0x85, 0x8f, 0x7e, 0xae, 0x67, 0xf4, 0xc7, 0x94, 0x95, 0x8c, 0x8f, 0x79, 0xdc, 0x17, - 0xf9, 0x4f, 0xdc, 0x17, 0xe6, 0x1f, 0xe5, 0xb0, 0x3e, 0xf2, 0x1a, 0x0c, 0x5b, 0x74, 0x37, 0x59, - 0xf4, 0x71, 0xf3, 0x18, 0x20, 0x44, 0x6d, 0x24, 0xc7, 0xc1, 0x15, 0x85, 0xba, 0xe1, 0x9e, 0xb7, - 0x13, 0x89, 0x96, 0xc6, 0x2b, 0x8a, 0x00, 0x2b, 0x2b, 0x8a, 0x80, 0x68, 0x2b, 0x8a, 0x80, 0x31, - 0x59, 0xb7, 0x16, 0xea, 0xe2, 0x03, 0xe4, 0xd7, 0x5a, 0x0b, 0x8a, 0xd0, 0x04, 0xae, 0x26, 0x34, - 0xd6, 0x42, 0x9d, 0xbc, 0x09, 0xa3, 0xd5, 0x46, 0xc3, 0xef, 0x2a, 0xbb, 0xaf, 0xd9, 0xa3, 0xc3, - 0xca, 0x8c, 0xc3, 0x81, 0xba, 0xaf, 0x20, 0x41, 0x25, 0x75, 0x18, 0x5b, 0x64, 0x5b, 0x16, 0x6f, - 0xde, 0x69, 0xec, 0x51, 0x31, 0xc1, 0xa4, 0xc4, 0x2a, 0x25, 0xb1, 0x09, 0x7d, 0x96, 0x22, 0xb0, - 0xc1, 0x80, 0xea, 0x96, 0x5c, 0xc1, 0x35, 0x6b, 0x49, 0x57, 0xb0, 0x86, 0xcd, 0x37, 0xbb, 0x61, - 0x44, 0x83, 0xa5, 0x05, 0xd1, 0x8f, 0xd8, 0xb0, 0x06, 0x07, 0xa6, 0x1a, 0x16, 0xa3, 0x9a, 0xff, - 0xcd, 0xc0, 0x6e, 0x20, 0x6f, 0x01, 0x2c, 0xb5, 0x99, 0xd9, 0xde, 0xa0, 0x31, 0x03, 0x74, 0x0d, - 0x78, 0x02, 0xaa, 0x73, 0x50, 0x90, 0xf5, 0xaa, 0x73, 0x03, 0x57, 0xcd, 0xaa, 0x94, 0x9b, 0x00, - 0xe1, 0x25, 0x12, 0x55, 0x06, 0x02, 0x9a, 0xaa, 0x32, 0x41, 0x26, 0x57, 0x60, 0x64, 0xa9, 0x7a, - 0xbf, 0xda, 0x8d, 0xf6, 0x70, 0x10, 0x8a, 0x5c, 0x1d, 0x7b, 0x4e, 0xcb, 0x76, 0xba, 0xd1, 0x9e, - 0x25, 0x0b, 0xcd, 0xff, 0x98, 0xd3, 0xfa, 0x9d, 0x58, 0x40, 0x2c, 0xda, 0x69, 0x7a, 0x0d, 0x34, - 0x2a, 0xee, 0x04, 0x7e, 0xb7, 0x13, 0x7f, 0xad, 0x79, 0x74, 0x58, 0x79, 0x2e, 0x48, 0x4a, 0xed, - 0x5d, 0x56, 0xac, 0xb7, 0x21, 0x83, 0x9a, 0x7c, 0x00, 0xa5, 0x8d, 0x90, 0x06, 0xe2, 0x27, 0xdb, - 0x88, 0xe5, 0xaf, 0x8e, 0xd6, 0x2e, 0xe1, 0x46, 0x2b, 0xa4, 0x41, 0xcc, 0x46, 0x95, 0x25, 0x8d, - 0x82, 0xb8, 0x30, 0xbb, 0x1e, 0x38, 0xed, 0xd0, 0x8b, 0x16, 0xdb, 0x8d, 0xe0, 0x00, 0xa7, 0xcf, - 0x62, 0xdb, 0xd9, 0x6e, 0x52, 0x17, 0xbb, 0xa5, 0x58, 0xbb, 0x7a, 0x74, 0x58, 0x79, 0x31, 0xe2, - 0x38, 0x36, 0x8d, 0x91, 0x6c, 0xca, 0xb1, 0x14, 0xce, 0x7d, 0x39, 0x91, 0xf7, 0xa1, 0xb4, 0xd8, - 0x76, 0x3b, 0xbe, 0xd7, 0x8e, 0xd0, 0x4d, 0x56, 0x88, 0x2d, 0xec, 0xf3, 0x54, 0xc0, 0x6d, 0x26, - 0x8f, 0x6a, 0x33, 0x55, 0x02, 0xf3, 0xe7, 0x0c, 0x18, 0x53, 0xd4, 0x3a, 0x1b, 0xf7, 0xb5, 0xc0, - 0xff, 0x98, 0x36, 0x22, 0x5d, 0xe4, 0x3a, 0x1c, 0x98, 0x1a, 0xf7, 0x18, 0x35, 0x25, 0x6a, 0xb9, - 0x53, 0x88, 0x9a, 0x79, 0x43, 0xac, 0x16, 0x6c, 0xbb, 0xa8, 0x78, 0xc3, 0x70, 0xbb, 0xc8, 0xcc, - 0x61, 0x75, 0xbb, 0xc8, 0xca, 0xcd, 0xdf, 0x33, 0x98, 0x96, 0x27, 0x37, 0x00, 0xee, 0xd1, 0x83, - 0xc8, 0xd9, 0xbe, 0xed, 0x35, 0x35, 0x2f, 0xe7, 0x3e, 0x42, 0xed, 0x1d, 0xaf, 0x49, 0x2d, 0x05, - 0x85, 0xdc, 0x82, 0xe2, 0xbd, 0x60, 0xfb, 0x0d, 0x44, 0xcf, 0xc5, 0xab, 0xf5, 0xf4, 0x7e, 0xb0, - 0xfd, 0x06, 0x22, 0xab, 0x1a, 0x45, 0x22, 0x12, 0x13, 0x86, 0x17, 0xfc, 0x96, 0xe3, 0x49, 0x0b, - 0x09, 0x98, 0x99, 0xe1, 0x22, 0xc4, 0x12, 0x25, 0xcc, 0x3e, 0xa8, 0xaf, 0xad, 0x88, 0xce, 0x47, - 0xfb, 0x20, 0xec, 0xb4, 0x2d, 0x06, 0x33, 0xbf, 0x6b, 0xc0, 0x98, 0xb2, 0x78, 0x91, 0xcf, 0x0b, - 0x8f, 0x90, 0x81, 0xfe, 0xcc, 0x73, 0xbd, 0xcb, 0x1b, 0x2b, 0xe5, 0x96, 0x5d, 0xcb, 0x77, 0xa9, - 0xf0, 0x0f, 0x25, 0x3a, 0x3f, 0x37, 0x88, 0xce, 0x7f, 0x0b, 0x80, 0x9b, 0xfd, 0xd8, 0x9d, 0xca, - 0x24, 0x54, 0xfc, 0xbf, 0xea, 0x60, 0x24, 0xc8, 0xa6, 0x05, 0x25, 0x55, 0xdf, 0x93, 0x1a, 0x8c, - 0x8b, 0x5d, 0xae, 0xb0, 0x13, 0x79, 0x3f, 0xe3, 0x4c, 0x10, 0xdc, 0x7a, 0x77, 0xdd, 0x3a, 0x89, - 0xf9, 0xf3, 0x39, 0x28, 0x0a, 0xc8, 0xdc, 0x53, 0x6a, 0xc2, 0xbe, 0xa1, 0x99, 0xb0, 0x72, 0x65, - 0x54, 0xf6, 0x56, 0x73, 0x27, 0x6c, 0x91, 0xdf, 0x82, 0x92, 0xec, 0x02, 0xdc, 0x09, 0xbc, 0x02, - 0x23, 0xd2, 0xc9, 0xc3, 0xf7, 0x01, 0x93, 0x1a, 0xcf, 0xcd, 0x39, 0x4b, 0x96, 0x9b, 0xdf, 0x1e, - 0x92, 0xb4, 0xbc, 0x26, 0xd6, 0x85, 0x55, 0xd7, 0x0d, 0xd4, 0x2e, 0x74, 0x5c, 0x37, 0xb0, 0x10, - 0xca, 0x06, 0x7f, 0xad, 0xbb, 0xdd, 0xf4, 0x1a, 0x88, 0xa3, 0xcc, 0xc4, 0x0e, 0x42, 0x6d, 0x86, - 0xaa, 0x0e, 0x7e, 0x82, 0xac, 0xed, 0x50, 0xf3, 0xc7, 0xee, 0x50, 0x7f, 0x02, 0x46, 0xe7, 0x5b, - 0xae, 0x66, 0xc1, 0x9a, 0x19, 0x9d, 0x72, 0x3d, 0x46, 0xe2, 0xb6, 0xeb, 0x25, 0xd1, 0x47, 0x33, - 0x8d, 0x96, 0xdb, 0x6b, 0xb7, 0x26, 0x2c, 0xb5, 0x2d, 0xe6, 0xd0, 0xe3, 0x6c, 0x31, 0xdf, 0x84, - 0xd1, 0x8d, 0x90, 0xae, 0x77, 0xdb, 0x6d, 0xda, 0x44, 0x6b, 0xb6, 0xc8, 0xf5, 0x59, 0x37, 0xa4, - 0x76, 0x84, 0x50, 0xb5, 0x01, 0x31, 0xaa, 0x2a, 0x56, 0x23, 0xc7, 0x88, 0xd5, 0xe7, 0xa1, 0x50, - 0xed, 0x74, 0xe4, 0xde, 0x3b, 0x36, 0xaf, 0x3a, 0x1d, 0x34, 0x78, 0x26, 0x9c, 0x4e, 0x47, 0xdf, - 0x49, 0x23, 0x36, 0xa1, 0x40, 0xee, 0x75, 0xb7, 0x69, 0xd0, 0xa6, 0x11, 0x0d, 0xc5, 0xda, 0x19, - 0xce, 0x02, 0xf2, 0x98, 0x95, 0x47, 0x1c, 0x69, 0x04, 0xae, 0xd5, 0xf7, 0xbb, 0xdb, 0xd4, 0x16, - 0x8b, 0xb0, 0xda, 0x77, 0x19, 0x0c, 0x2f, 0xd6, 0x61, 0x42, 0xef, 0xff, 0x27, 0x60, 0x93, 0x7e, - 0x58, 0x28, 0x16, 0xcb, 0xa3, 0xe6, 0x2f, 0xe4, 0x60, 0xac, 0xda, 0xe9, 0x3c, 0xe5, 0x0e, 0xb0, - 0x1f, 0xd3, 0x66, 0xf5, 0xb9, 0x64, 0xf4, 0x4e, 0xe1, 0xfb, 0xfa, 0x2b, 0x03, 0x26, 0x53, 0x14, - 0x6a, 0xeb, 0x8d, 0x01, 0x1d, 0x42, 0xb9, 0x01, 0x1d, 0x42, 0xf9, 0xfe, 0x0e, 0x21, 0x75, 0xce, - 0x14, 0x1e, 0x67, 0xce, 0xbc, 0x0c, 0xf9, 0x6a, 0xa7, 0x23, 0x7a, 0xa5, 0x94, 0xf4, 0xca, 0xe6, - 0x2d, 0xbe, 0xb8, 0x39, 0x9d, 0x8e, 0xc5, 0x30, 0xcc, 0xd7, 0x61, 0x14, 0xc1, 0xa8, 0xd1, 0x2e, - 0x8b, 0xa9, 0xc0, 0xd5, 0x99, 0x46, 0xc6, 0xc5, 0xde, 0xfc, 0x3f, 0x06, 0x0c, 0xe1, 0xef, 0xa7, - 0x54, 0x5c, 0xe6, 0x34, 0x71, 0x29, 0x2b, 0xe2, 0x32, 0x88, 0xa0, 0xfc, 0x41, 0x1e, 0x7b, 0x4b, - 0x88, 0x88, 0x70, 0x29, 0x18, 0x19, 0x2e, 0x85, 0xc7, 0x50, 0xe0, 0xfb, 0x69, 0xe7, 0x42, 0x1e, - 0x07, 0xe3, 0x85, 0x74, 0x53, 0x9f, 0x88, 0x5f, 0xe1, 0x2e, 0x90, 0xa5, 0x76, 0x48, 0x1b, 0xdd, - 0x80, 0xd6, 0xf7, 0xbd, 0xce, 0x26, 0x0d, 0xbc, 0x9d, 0x03, 0x61, 0xba, 0xa3, 0x8e, 0xf5, 0x44, - 0xa9, 0x1d, 0xee, 0x7b, 0x1d, 0x66, 0x26, 0x78, 0x3b, 0x07, 0x56, 0x06, 0x0d, 0x79, 0x1f, 0x46, - 0x2c, 0xfa, 0x30, 0xf0, 0x22, 0xb9, 0x89, 0x9a, 0x88, 0x77, 0x7f, 0x08, 0xe5, 0xf6, 0x4e, 0xc0, - 0x7f, 0xa8, 0xe3, 0x2f, 0xca, 0x3f, 0xbd, 0x1d, 0xf8, 0x77, 0x86, 0x70, 0x2e, 0x9c, 0x70, 0x50, - 0x7b, 0x8c, 0x7f, 0x48, 0x1f, 0xcc, 0xfc, 0x69, 0x06, 0x73, 0x13, 0x4a, 0x6c, 0xd3, 0x9f, 0x72, - 0x14, 0x5d, 0x4a, 0xc6, 0xf2, 0xba, 0x5a, 0x7c, 0xdc, 0x19, 0xad, 0xc6, 0x87, 0xd8, 0x69, 0x21, - 0xe1, 0x67, 0xbf, 0xcf, 0x2a, 0x8c, 0x33, 0xc4, 0x23, 0x56, 0x1d, 0x0d, 0xde, 0x59, 0xa7, 0x16, - 0x8c, 0xe1, 0xc7, 0x13, 0x8c, 0x91, 0x4f, 0x22, 0x18, 0xe9, 0xd3, 0xf1, 0xe2, 0x69, 0x4e, 0xc7, - 0x2f, 0xbe, 0x0f, 0x53, 0x3d, 0x3d, 0x7c, 0x9a, 0x13, 0xe6, 0x4f, 0x4f, 0x2c, 0x7f, 0x26, 0xee, - 0x17, 0x32, 0x87, 0xfe, 0x02, 0x2f, 0xa0, 0x8d, 0x08, 0x55, 0xaf, 0xd0, 0x96, 0x81, 0x80, 0xa5, - 0xbc, 0x24, 0x08, 0x23, 0xef, 0xc1, 0x08, 0x3f, 0xa1, 0xe3, 0x1b, 0xdb, 0xb1, 0xb9, 0x71, 0x51, - 0x23, 0x87, 0x8a, 0x30, 0x09, 0x8e, 0xa1, 0xf6, 0xaa, 0x20, 0x32, 0xef, 0xc0, 0xb0, 0x38, 0xe1, - 0x3b, 0x7e, 0x5e, 0x54, 0x60, 0x68, 0x33, 0xe9, 0x19, 0x3c, 0x95, 0xe1, 0x1f, 0x61, 0x71, 0xb8, - 0xf9, 0x4b, 0x06, 0x4c, 0xe8, 0x5f, 0x49, 0xae, 0xc3, 0xb0, 0x38, 0x82, 0x36, 0xf0, 0x08, 0x9a, - 0x7d, 0xcd, 0x30, 0x3f, 0x7c, 0xd6, 0x8e, 0x9c, 0x05, 0x16, 0x53, 0xfd, 0x82, 0x83, 0xd8, 0xa4, - 0xa3, 0xea, 0x17, 0x42, 0x6a, 0xc9, 0x32, 0xb6, 0x8d, 0xb3, 0x68, 0xd8, 0x6d, 0x46, 0xea, 0x36, - 0x2e, 0x40, 0x88, 0x25, 0x4a, 0xcc, 0x43, 0x03, 0xa0, 0x5e, 0xbf, 0x7b, 0x8f, 0x1e, 0xac, 0x39, - 0x5e, 0x80, 0x5b, 0x61, 0x9c, 0x8d, 0xf7, 0xc4, 0x68, 0x95, 0xc4, 0x56, 0x98, 0xcf, 0xdc, 0x7d, - 0x7a, 0xa0, 0x6d, 0x85, 0x25, 0x2a, 0x4e, 0xf9, 0xc0, 0x7b, 0xe0, 0x44, 0x94, 0x11, 0xe6, 0x90, - 0x90, 0x4f, 0x79, 0x0e, 0x4d, 0x51, 0x2a, 0xc8, 0xe4, 0x6b, 0x30, 0x91, 0xfc, 0xc2, 0x0d, 0x7d, - 0x1e, 0xf7, 0x89, 0x52, 0x22, 0xf4, 0xc2, 0xda, 0x73, 0x47, 0x87, 0x95, 0x8b, 0x0a, 0xd7, 0xf4, - 0x56, 0x3f, 0xc5, 0xcc, 0xfc, 0x1d, 0x03, 0x60, 0x7d, 0xb9, 0x2e, 0x3f, 0xf0, 0x0a, 0x14, 0x62, - 0x3f, 0x62, 0x89, 0xef, 0xb7, 0x53, 0x1b, 0x4a, 0x2c, 0x27, 0x2f, 0x40, 0x3e, 0xf9, 0x92, 0xa9, - 0xa3, 0xc3, 0xca, 0xb8, 0xfe, 0x05, 0xac, 0x94, 0xdc, 0x81, 0x91, 0x81, 0xda, 0x8c, 0xd2, 0x99, - 0xd1, 0x56, 0x49, 0x8d, 0xa3, 0xf0, 0xe1, 0xd6, 0xfa, 0x67, 0x77, 0x14, 0xbe, 0x95, 0x83, 0x49, - 0xd6, 0xaf, 0xd5, 0x6e, 0xb4, 0xe7, 0x07, 0x5e, 0x74, 0xf0, 0xd4, 0xee, 0x8a, 0xdf, 0xd1, 0x0c, - 0xa2, 0x8b, 0x52, 0x6d, 0xa9, 0xdf, 0x36, 0xd0, 0xe6, 0xf8, 0xcf, 0x47, 0x60, 0x3a, 0x83, 0x8a, - 0xbc, 0x26, 0x82, 0xbf, 0x12, 0x3f, 0x14, 0x06, 0x77, 0xfd, 0xe8, 0xb0, 0x52, 0x92, 0xe8, 0xeb, - 0x49, 0xb0, 0xd7, 0x1c, 0x8c, 0x89, 0xad, 0xcf, 0x4a, 0x62, 0x51, 0x63, 0xd4, 0x90, 0x74, 0x5a, - 0xa2, 0x6a, 0x52, 0x91, 0x48, 0x15, 0x4a, 0xf3, 0x7b, 0xb4, 0xb1, 0xef, 0xb5, 0x77, 0xef, 0xd1, - 0x03, 0x6e, 0x2f, 0x95, 0x6a, 0xcf, 0xb2, 0x9d, 0x56, 0x43, 0xc0, 0xd9, 0x90, 0xea, 0x9b, 0x38, - 0x8d, 0x84, 0xbc, 0x07, 0x63, 0x75, 0x6f, 0xb7, 0x2d, 0x39, 0x14, 0x90, 0xc3, 0xa5, 0xa3, 0xc3, - 0xca, 0xb9, 0x90, 0x83, 0x7b, 0x19, 0xa8, 0x04, 0xe4, 0x15, 0x18, 0xb2, 0xfc, 0x26, 0xe5, 0xcb, - 0xb0, 0x08, 0x27, 0x0a, 0x18, 0x40, 0x75, 0xae, 0x23, 0x06, 0xb9, 0x0b, 0x23, 0xec, 0x9f, 0xfb, - 0x4e, 0x67, 0x76, 0x18, 0xf5, 0x36, 0x89, 0x0d, 0x7c, 0x84, 0x76, 0xbc, 0xf6, 0xae, 0x6a, 0xe3, - 0x37, 0xa9, 0xdd, 0x72, 0x3a, 0xda, 0xba, 0xc8, 0x11, 0xc9, 0x26, 0x8c, 0x25, 0x8a, 0x20, 0x9c, - 0x1d, 0xd1, 0x8e, 0x22, 0x93, 0x92, 0xda, 0xf3, 0x82, 0xd9, 0xf9, 0xa8, 0x19, 0xa2, 0x6c, 0x77, - 0x18, 0xbe, 0xfe, 0x31, 0x0a, 0x23, 0x6d, 0x0f, 0x52, 0xec, 0xbf, 0x07, 0x31, 0x4e, 0xdc, 0x83, - 0xb8, 0x00, 0xa2, 0x93, 0xaa, 0xcd, 0x5d, 0x11, 0xfd, 0xf7, 0x4a, 0x7f, 0x01, 0xbb, 0x9e, 0x20, - 0xe3, 0x9c, 0xe4, 0xde, 0x2e, 0xd1, 0xff, 0x4e, 0x73, 0x57, 0xf3, 0x76, 0xc5, 0xa8, 0xac, 0x1b, - 0x12, 0x55, 0x23, 0x77, 0xe0, 0xb2, 0x1b, 0x92, 0x92, 0xa4, 0x1b, 0x3e, 0x7e, 0x18, 0xf5, 0xeb, - 0x06, 0x85, 0x11, 0x59, 0x01, 0xa8, 0x36, 0x22, 0xef, 0x01, 0x45, 0x91, 0x18, 0xd3, 0x3a, 0x62, - 0xbe, 0x7a, 0x8f, 0x1e, 0xd4, 0x69, 0x94, 0x9c, 0x0a, 0x38, 0x88, 0x9a, 0x12, 0x13, 0x4b, 0xe1, - 0x40, 0x3a, 0x70, 0xb6, 0xea, 0xba, 0x1e, 0x8f, 0x08, 0x5d, 0x0f, 0x98, 0xfc, 0xba, 0xc8, 0xba, - 0x94, 0xcd, 0xfa, 0x15, 0xc1, 0xfa, 0x79, 0x27, 0xa6, 0xb2, 0x23, 0x4e, 0x96, 0xae, 0x26, 0x9b, - 0xb1, 0xb9, 0x0a, 0x13, 0x7a, 0x97, 0xea, 0xb1, 0x90, 0x25, 0x28, 0x5a, 0xf5, 0xaa, 0x5d, 0xbf, - 0x5b, 0xbd, 0x59, 0x36, 0x48, 0x19, 0x4a, 0xe2, 0xd7, 0x9c, 0x3d, 0xf7, 0xc6, 0x9b, 0xe5, 0x9c, - 0x06, 0x79, 0xe3, 0xe6, 0x5c, 0x39, 0x6f, 0xfe, 0x81, 0x01, 0x45, 0xd9, 0x3e, 0xf2, 0x26, 0xe4, - 0xeb, 0xf5, 0xbb, 0xa9, 0x13, 0xf0, 0x64, 0xe9, 0xe5, 0x8b, 0x4c, 0x18, 0xee, 0xa9, 0x8b, 0x4c, - 0xbd, 0x7e, 0x97, 0xd1, 0xad, 0x2f, 0xd7, 0x85, 0xd1, 0x92, 0x21, 0xae, 0x53, 0x7d, 0x8e, 0x05, - 0xdf, 0x84, 0xfc, 0x87, 0x5b, 0xeb, 0x62, 0x37, 0x94, 0x31, 0xbe, 0x48, 0xf7, 0xf1, 0x43, 0x75, - 0xe9, 0x63, 0x04, 0xa6, 0x05, 0x63, 0xca, 0xd4, 0xe2, 0x46, 0x44, 0xcb, 0x8f, 0xa3, 0x04, 0x85, - 0x11, 0xc1, 0x20, 0x96, 0x28, 0x61, 0x36, 0xcf, 0xb2, 0xdf, 0x70, 0x9a, 0xc2, 0x1a, 0x41, 0x9b, - 0xa7, 0xc9, 0x00, 0x16, 0x87, 0x9b, 0x7f, 0x6c, 0x40, 0x79, 0x2d, 0xf0, 0x1f, 0x78, 0x4c, 0x03, - 0xaf, 0xfb, 0xfb, 0xb4, 0xbd, 0x79, 0x93, 0xbc, 0x2e, 0x95, 0x00, 0x37, 0xe1, 0xce, 0x33, 0x2a, - 0x54, 0x02, 0x3f, 0x3a, 0xac, 0x40, 0xfd, 0x20, 0x8c, 0x68, 0x8b, 0x95, 0x4b, 0x45, 0xa0, 0x04, - 0x5b, 0xe6, 0x06, 0x0f, 0xe0, 0x3a, 0x21, 0xd8, 0xb2, 0x02, 0x43, 0xd8, 0x1c, 0x25, 0x86, 0x66, - 0x28, 0x62, 0x00, 0x8b, 0xc3, 0x15, 0x85, 0xfd, 0xed, 0x5c, 0xcf, 0x37, 0xcc, 0x7d, 0xa6, 0x82, - 0xa0, 0xf4, 0x8f, 0x1b, 0x68, 0x11, 0xfb, 0x32, 0xcc, 0xa4, 0xbb, 0x04, 0xfd, 0x22, 0x55, 0x98, - 0xd4, 0xe1, 0xd2, 0x45, 0x72, 0x3e, 0xb3, 0xae, 0xcd, 0x39, 0x2b, 0x8d, 0x6f, 0xfe, 0xc0, 0x80, - 0x51, 0xfc, 0xd7, 0xea, 0x36, 0x29, 0xb3, 0x6c, 0xaa, 0x5b, 0x75, 0x71, 0x0c, 0xa9, 0x9e, 0xea, - 0x39, 0x0f, 0x43, 0x5b, 0x9c, 0x59, 0x6a, 0x7a, 0x24, 0x46, 0x16, 0xa4, 0xfc, 0xd0, 0x55, 0x1e, - 0x6a, 0xc5, 0xa4, 0xfc, 0x74, 0x36, 0x4c, 0x91, 0x0a, 0x64, 0x36, 0x7e, 0xec, 0x97, 0xdf, 0x94, - 0xae, 0x61, 0x1c, 0x3f, 0xa4, 0xf3, 0xb5, 0xa3, 0x13, 0x89, 0x46, 0x5e, 0x87, 0x61, 0x56, 0xb5, - 0x25, 0x0f, 0x46, 0x70, 0x57, 0x81, 0x6d, 0x0c, 0xb4, 0x33, 0x60, 0x8e, 0x64, 0xfe, 0xeb, 0x5c, - 0xba, 0x03, 0x85, 0x15, 0x70, 0xca, 0xb9, 0xf1, 0x36, 0x0c, 0x55, 0x9b, 0x4d, 0xff, 0xa1, 0xd0, - 0x12, 0xd2, 0x4d, 0x13, 0xf7, 0x1f, 0x5f, 0x61, 0x1d, 0x86, 0xa2, 0x05, 0x1f, 0x30, 0x00, 0x99, - 0x87, 0xd1, 0xea, 0x56, 0x7d, 0x69, 0x69, 0x61, 0x7d, 0x7d, 0x59, 0xc4, 0xb8, 0xbf, 0x24, 0xfb, - 0xc7, 0xf3, 0x5c, 0x3b, 0x8a, 0x9a, 0x7d, 0x42, 0x60, 0x13, 0x3a, 0xf2, 0x2e, 0xc0, 0x87, 0xbe, - 0xd7, 0xbe, 0x4f, 0xa3, 0x3d, 0xdf, 0x15, 0x1f, 0xcf, 0x4c, 0x8a, 0xb1, 0x8f, 0x7d, 0xaf, 0x6d, - 0xb7, 0x10, 0xcc, 0xda, 0x9e, 0x20, 0x59, 0xca, 0xff, 0xac, 0xa7, 0x6b, 0x7e, 0x84, 0x36, 0xcc, - 0x50, 0xd2, 0xd3, 0xdb, 0x7e, 0x94, 0x3e, 0xb7, 0x91, 0x68, 0xe6, 0x2f, 0xe7, 0x60, 0x82, 0xef, - 0x54, 0xb9, 0xc0, 0x3c, 0xb5, 0x93, 0xf1, 0x6d, 0x6d, 0x32, 0x5e, 0x90, 0x0b, 0x83, 0xf2, 0x69, - 0x03, 0x4d, 0xc5, 0x3d, 0x20, 0xbd, 0x34, 0xc4, 0x92, 0xfe, 0x94, 0x41, 0x66, 0xe1, 0xcd, 0x24, - 0x62, 0x20, 0x44, 0x22, 0x1b, 0x55, 0x61, 0x68, 0x69, 0x3c, 0xcc, 0x5f, 0xca, 0xc1, 0xb8, 0x62, - 0x4f, 0x3e, 0xb5, 0x1d, 0xff, 0x45, 0xad, 0xe3, 0xe5, 0x19, 0x84, 0xf2, 0x65, 0x03, 0xf5, 0x7b, - 0x17, 0xa6, 0x7a, 0x48, 0xd2, 0x66, 0xb9, 0x31, 0x88, 0x59, 0xfe, 0x5a, 0x6f, 0xf4, 0x01, 0x8f, - 0x87, 0x8f, 0xa3, 0x0f, 0xd4, 0x70, 0x87, 0x6f, 0xe5, 0x60, 0x46, 0xfc, 0xaa, 0x76, 0x5d, 0x2f, - 0x9a, 0xf7, 0xdb, 0x3b, 0xde, 0xee, 0x53, 0x3b, 0x16, 0x55, 0x6d, 0x2c, 0x2a, 0xfa, 0x58, 0x28, - 0x1f, 0xd8, 0x7f, 0x48, 0xcc, 0x7f, 0x57, 0x84, 0xd9, 0x7e, 0x04, 0x6c, 0xdb, 0xaf, 0xec, 0xaa, - 0x70, 0xdb, 0x9f, 0xda, 0xb1, 0xf2, 0xfd, 0x54, 0x12, 0xc2, 0x93, 0x1b, 0x20, 0x84, 0x67, 0x19, - 0xca, 0x58, 0x55, 0x9d, 0x86, 0xac, 0x13, 0xc2, 0x24, 0x18, 0xf7, 0xf2, 0xd1, 0x61, 0xe5, 0x92, - 0xc3, 0xca, 0xec, 0x50, 0x14, 0xda, 0xdd, 0xc0, 0x53, 0x78, 0xf4, 0x50, 0x92, 0xdf, 0x31, 0x60, - 0x02, 0x81, 0x8b, 0x0f, 0x68, 0x3b, 0x42, 0x66, 0x05, 0x71, 0x48, 0x13, 0xdf, 0x79, 0xaa, 0x47, - 0x81, 0xd7, 0xde, 0x45, 0x47, 0x52, 0x58, 0xdb, 0x66, 0xbd, 0xf0, 0xfd, 0xc3, 0xca, 0x3b, 0x9f, - 0xe4, 0x1e, 0x95, 0x60, 0x15, 0xb2, 0x8d, 0x3c, 0x6f, 0x28, 0xc5, 0x6a, 0x53, 0xcd, 0x4c, 0xb5, - 0x88, 0xfc, 0x38, 0x9c, 0xe7, 0x71, 0x18, 0xf3, 0x7e, 0x3b, 0xf2, 0xda, 0x5d, 0xbf, 0x1b, 0xd6, - 0x9c, 0xc6, 0x7e, 0xb7, 0x13, 0x0a, 0x67, 0x27, 0x7e, 0x79, 0x23, 0x2e, 0xb4, 0xb7, 0x79, 0xa9, - 0xc2, 0xb2, 0x1f, 0x03, 0x72, 0x17, 0xa6, 0x78, 0x51, 0xb5, 0x1b, 0xf9, 0xf5, 0x86, 0xd3, 0xf4, - 0xda, 0xbb, 0xe8, 0x03, 0x2d, 0xd6, 0x2e, 0xb2, 0xbd, 0xa5, 0xd3, 0x8d, 0x7c, 0x3b, 0xe4, 0x70, - 0x85, 0x5f, 0x2f, 0x11, 0x59, 0x82, 0x49, 0x8b, 0x3a, 0xee, 0x7d, 0xe7, 0xd1, 0xbc, 0xd3, 0x71, - 0x1a, 0x5e, 0x74, 0x80, 0x3b, 0xb3, 0x7c, 0xad, 0x72, 0x74, 0x58, 0x79, 0x26, 0xa0, 0x8e, 0x6b, - 0xb7, 0x9c, 0x47, 0x76, 0x43, 0x14, 0x2a, 0xcc, 0xd2, 0x74, 0x31, 0x2b, 0xaf, 0x1d, 0xb3, 0x1a, - 0x4d, 0xb3, 0xf2, 0xda, 0xfd, 0x59, 0x25, 0x74, 0x92, 0xd5, 0xba, 0x13, 0xec, 0xd2, 0x88, 0x3b, - 0x09, 0xe1, 0xb2, 0x71, 0xd5, 0x50, 0x58, 0x45, 0x58, 0x66, 0xa3, 0xc3, 0x30, 0xcd, 0x4a, 0xa1, - 0x63, 0x92, 0xb7, 0x15, 0x78, 0x11, 0x55, 0xbf, 0x70, 0x0c, 0x9b, 0x85, 0xfd, 0x8f, 0x6e, 0xd2, - 0x7e, 0x9f, 0xd8, 0x43, 0x99, 0x70, 0x53, 0x3e, 0xb2, 0xd4, 0xc3, 0x2d, 0xfb, 0x2b, 0x7b, 0x28, - 0x63, 0x6e, 0xea, 0x77, 0x8e, 0xe3, 0x77, 0x2a, 0xdc, 0xfa, 0x7c, 0x68, 0x0f, 0x25, 0x59, 0x61, - 0x9d, 0x16, 0xd1, 0x36, 0x93, 0x68, 0xe1, 0x24, 0x9d, 0xc0, 0xa6, 0xbd, 0x28, 0xf6, 0xd4, 0xe5, - 0x40, 0x16, 0xdb, 0x19, 0x2e, 0xd3, 0x34, 0xf1, 0x87, 0x85, 0xe2, 0x50, 0x79, 0xd8, 0x2a, 0x73, - 0x91, 0x8f, 0x98, 0xe0, 0xa0, 0x2e, 0x36, 0x7f, 0x23, 0x07, 0x17, 0xa4, 0x3a, 0xa6, 0xd1, 0x43, - 0x3f, 0xd8, 0xf7, 0xda, 0xbb, 0x4f, 0xb9, 0x56, 0xbd, 0xad, 0x69, 0xd5, 0x17, 0x53, 0x2b, 0x5c, - 0xea, 0x2b, 0x8f, 0x51, 0xad, 0x7f, 0x36, 0x04, 0xcf, 0x1e, 0x4b, 0x45, 0x3e, 0x62, 0xab, 0xa0, - 0x47, 0xdb, 0xd1, 0x92, 0xdb, 0xa4, 0x6c, 0x1b, 0xe6, 0x77, 0x23, 0xe1, 0xcc, 0x7e, 0xe1, 0xe8, - 0xb0, 0x32, 0xcd, 0xaf, 0x02, 0xd9, 0x9e, 0xdb, 0xa4, 0x76, 0xc4, 0x8b, 0xb5, 0x61, 0xea, 0xa5, - 0x66, 0x2c, 0xe3, 0x8b, 0x89, 0x4b, 0xed, 0x88, 0x06, 0x0f, 0x1c, 0x7e, 0x23, 0x42, 0xb0, 0xdc, - 0xa7, 0xb4, 0x63, 0x3b, 0xac, 0xd4, 0xf6, 0x44, 0xb1, 0xce, 0xb2, 0x87, 0x9a, 0xdc, 0x56, 0x58, - 0xce, 0xb3, 0xcd, 0xc1, 0x7d, 0xe7, 0x91, 0xb0, 0x78, 0xd1, 0xbf, 0xaa, 0xb0, 0xe4, 0x51, 0x90, - 0x2d, 0xe7, 0x91, 0xd5, 0x4b, 0x42, 0xbe, 0x06, 0x67, 0x85, 0xe2, 0x66, 0x4a, 0x2c, 0xf0, 0x9b, - 0xf2, 0x8b, 0x0b, 0xc8, 0xeb, 0xe5, 0xa3, 0xc3, 0xca, 0x79, 0xa1, 0xf6, 0xed, 0x06, 0xc7, 0xc8, - 0xfc, 0xea, 0x6c, 0x2e, 0x64, 0x9d, 0x2d, 0x64, 0xa9, 0xee, 0xb8, 0x4f, 0xc3, 0xd0, 0xd9, 0x95, - 0xd6, 0x31, 0x3f, 0x51, 0x52, 0x3a, 0xd3, 0x6e, 0xf1, 0x72, 0xab, 0x2f, 0x25, 0xb9, 0x0b, 0x13, - 0x5b, 0x74, 0x5b, 0x1d, 0x9f, 0xe1, 0x78, 0x8a, 0x97, 0x1f, 0xd2, 0xed, 0xfe, 0x83, 0x93, 0xa2, - 0x23, 0x1e, 0x4c, 0xad, 0x05, 0xfe, 0xa3, 0x03, 0xb6, 0xd5, 0xa3, 0x6d, 0x1a, 0x60, 0x70, 0xd7, - 0x08, 0xba, 0xab, 0x66, 0x13, 0xcb, 0x52, 0x2f, 0xaf, 0x3d, 0x7f, 0x74, 0x58, 0x79, 0xb6, 0xc3, - 0xc0, 0x76, 0x53, 0xc0, 0xed, 0xd4, 0xbd, 0xc0, 0x5e, 0xae, 0xe4, 0x27, 0x61, 0xd2, 0xf2, 0xbb, - 0x91, 0xd7, 0xde, 0xad, 0x47, 0x81, 0x13, 0xd1, 0x5d, 0xae, 0xc8, 0x93, 0x28, 0xb2, 0x54, 0x29, - 0x77, 0x4c, 0x07, 0x1c, 0x68, 0x87, 0x02, 0xaa, 0x69, 0x52, 0x9d, 0xc0, 0xfc, 0xb5, 0x1c, 0xcc, - 0x8a, 0x61, 0xb0, 0x68, 0xc3, 0x0f, 0xdc, 0xa7, 0x7f, 0xda, 0x2f, 0x6a, 0xd3, 0xfe, 0x85, 0x38, - 0x46, 0x29, 0xeb, 0x23, 0x8f, 0x99, 0xf5, 0xbf, 0x6f, 0xc0, 0xa5, 0xe3, 0x88, 0x58, 0xef, 0xc4, - 0x71, 0x7d, 0xa3, 0x3d, 0xf1, 0x7b, 0x1d, 0x98, 0xc6, 0xf1, 0x44, 0xc7, 0x71, 0x78, 0xd7, 0x0f, - 0x23, 0xf4, 0xde, 0xe5, 0xb4, 0x40, 0x82, 0x9a, 0xef, 0x37, 0x51, 0xcf, 0xd7, 0x5e, 0x63, 0xea, - 0xfc, 0xfb, 0x87, 0x15, 0x60, 0x20, 0x1e, 0x89, 0xc7, 0xd6, 0x7c, 0x2e, 0x31, 0xe8, 0x97, 0x0e, - 0x6d, 0x8c, 0xfe, 0xd8, 0xa7, 0x07, 0xa1, 0x95, 0xc5, 0x1a, 0x3d, 0x34, 0xd5, 0x6e, 0xb4, 0xb7, - 0x16, 0xd0, 0x1d, 0x1a, 0xd0, 0x76, 0x83, 0x7e, 0xc6, 0x3c, 0x34, 0xfa, 0xc7, 0x0d, 0xb4, 0x3d, - 0xf9, 0xcb, 0x11, 0x98, 0xc9, 0x22, 0x63, 0xfd, 0xa2, 0x58, 0xc4, 0xe9, 0x4b, 0xe4, 0x7f, 0xdb, - 0x80, 0x52, 0x9d, 0x36, 0xfc, 0xb6, 0x7b, 0xdb, 0x69, 0x44, 0xbe, 0x0c, 0xc9, 0xb0, 0xb9, 0x66, - 0x63, 0x70, 0x7b, 0x07, 0x0b, 0x34, 0xcf, 0xc0, 0x07, 0x83, 0x19, 0xa2, 0x0d, 0x1f, 0x03, 0x61, - 0x23, 0x26, 0x93, 0x49, 0x15, 0x78, 0xaa, 0xa1, 0x55, 0x4a, 0x6a, 0x30, 0x3e, 0xef, 0xb7, 0xdb, - 0x94, 0xfd, 0x50, 0xc2, 0x3a, 0x31, 0x10, 0xb3, 0x21, 0x0b, 0xd2, 0x1e, 0x02, 0x9d, 0x84, 0xdc, - 0x82, 0xfc, 0xc6, 0xdc, 0x6d, 0x31, 0x06, 0x32, 0x58, 0x6d, 0x63, 0xee, 0x36, 0xee, 0x75, 0x99, - 0xfd, 0x30, 0xde, 0x9d, 0xdb, 0x51, 0x7d, 0xa0, 0x1b, 0x73, 0xb7, 0xc9, 0x2a, 0x4c, 0x59, 0xf4, - 0xeb, 0x5d, 0x2f, 0xa0, 0x62, 0x02, 0xdc, 0xbf, 0x5d, 0xc5, 0xb1, 0x28, 0x72, 0x3d, 0x16, 0xf0, - 0x42, 0x69, 0xdb, 0xdb, 0xad, 0x1d, 0xf5, 0xe2, 0x64, 0x2f, 0x2d, 0xf9, 0x59, 0x38, 0xbb, 0xe0, - 0x85, 0xa2, 0xcd, 0xdc, 0xf9, 0xe8, 0xe2, 0x39, 0xe4, 0x70, 0x9f, 0xe9, 0xf0, 0x85, 0xcc, 0xe9, - 0xf0, 0xbc, 0x1b, 0x33, 0xb1, 0xb9, 0x67, 0xd3, 0x4d, 0xc7, 0xc3, 0x66, 0xd7, 0x43, 0x3e, 0x86, - 0x09, 0xf4, 0xf6, 0xa0, 0x3f, 0x16, 0xe3, 0xcd, 0x47, 0xfa, 0xd4, 0xfc, 0xb9, 0xcc, 0x9a, 0x2f, - 0xa2, 0xf3, 0xc8, 0x46, 0xaf, 0x2e, 0xc6, 0xa6, 0x6b, 0x7b, 0x04, 0x8d, 0x33, 0xf9, 0x10, 0x26, - 0xc5, 0xa2, 0xb3, 0xba, 0xb3, 0xbe, 0x47, 0x17, 0x9c, 0x03, 0x11, 0x84, 0x80, 0xf6, 0x9f, 0x58, - 0xa9, 0x6c, 0x7f, 0xc7, 0x8e, 0xf6, 0xa8, 0xed, 0x3a, 0x9a, 0x7a, 0x4e, 0x11, 0x92, 0x9f, 0x86, - 0xb1, 0x65, 0x1f, 0x0f, 0x9e, 0x50, 0xd5, 0x8c, 0x22, 0x9f, 0x2f, 0xe3, 0xc5, 0x69, 0x0e, 0x4e, - 0x2d, 0x22, 0x3f, 0x3a, 0xac, 0xbc, 0x7d, 0x5a, 0x29, 0x54, 0x2a, 0xb0, 0xd4, 0xda, 0xc8, 0x3c, - 0x14, 0xb7, 0xe8, 0x36, 0xfb, 0xda, 0xf4, 0xa5, 0x3f, 0x09, 0xe6, 0xfa, 0xe2, 0xa1, 0xf8, 0xa5, - 0x9e, 0xea, 0x48, 0x0c, 0x12, 0xc0, 0x14, 0xf6, 0xcf, 0x9a, 0x13, 0x86, 0x0f, 0xfd, 0xc0, 0x6d, - 0xd2, 0x50, 0x1e, 0x8f, 0xf4, 0x76, 0xfe, 0x5c, 0x66, 0xe7, 0x5f, 0xe2, 0x9d, 0xdf, 0x51, 0x38, - 0xa8, 0xe2, 0xd6, 0xc3, 0xde, 0xfc, 0x37, 0x06, 0x4a, 0x3d, 0xb9, 0x86, 0xc1, 0x67, 0x71, 0x54, - 0x3b, 0xee, 0x66, 0x9d, 0x4e, 0xea, 0x2e, 0x00, 0x47, 0x61, 0x5b, 0xdf, 0xdb, 0x4e, 0x83, 0x46, - 0xd2, 0x47, 0x8a, 0xc8, 0x3b, 0x08, 0x51, 0xb7, 0xbe, 0x1c, 0x87, 0x7c, 0x09, 0x66, 0x16, 0xe8, - 0x03, 0xaf, 0x41, 0xab, 0x51, 0x44, 0x43, 0xde, 0xc3, 0xf3, 0x55, 0x7e, 0x98, 0x38, 0x5a, 0x7b, - 0xf1, 0xe8, 0xb0, 0x72, 0xd9, 0xc5, 0x72, 0xdb, 0x49, 0x10, 0xec, 0x86, 0xa3, 0xf2, 0xca, 0xe4, - 0x60, 0xfe, 0x6f, 0x23, 0xe9, 0x75, 0xf2, 0x32, 0x14, 0xac, 0xb5, 0xb8, 0xfd, 0xfc, 0x9c, 0x30, - 0xd5, 0x7c, 0x44, 0x20, 0x5f, 0x81, 0xb3, 0x0a, 0x1f, 0xec, 0x11, 0xea, 0xb2, 0x06, 0xf1, 0x8f, - 0x79, 0x09, 0x0f, 0x86, 0x94, 0x96, 0x38, 0x1c, 0x23, 0xd5, 0xa2, 0x6c, 0x1e, 0xec, 0x63, 0x95, - 0x82, 0x05, 0xda, 0xf6, 0x38, 0x6f, 0xe5, 0x63, 0x55, 0xde, 0x2e, 0x22, 0xa4, 0x3f, 0x36, 0x8b, - 0xc3, 0x87, 0x85, 0x62, 0xa1, 0x3c, 0x64, 0xfe, 0x95, 0xa1, 0x64, 0xbd, 0x78, 0x4a, 0x57, 0xac, - 0x37, 0xb5, 0x15, 0x6b, 0x46, 0x90, 0xc6, 0x5f, 0xc5, 0xca, 0x32, 0xad, 0x8c, 0x49, 0x18, 0xd7, - 0x90, 0x30, 0xcc, 0x76, 0x23, 0xa4, 0x01, 0xf7, 0x49, 0x7e, 0xb6, 0xc2, 0x6c, 0xe3, 0xef, 0x1a, - 0x28, 0x7a, 0xf2, 0xcf, 0x0d, 0x98, 0x4c, 0x51, 0xb0, 0xde, 0x60, 0x20, 0xb5, 0x37, 0xba, 0x21, - 0x0d, 0x2c, 0x84, 0xf2, 0xa0, 0xbc, 0x65, 0x3d, 0x28, 0xaf, 0x69, 0x31, 0x18, 0xf9, 0x00, 0x86, - 0x36, 0x70, 0x07, 0xa1, 0xc7, 0x75, 0xc4, 0xfc, 0xb1, 0x90, 0xcf, 0xb0, 0x2e, 0xfb, 0x57, 0x55, - 0x10, 0x58, 0x46, 0xea, 0x30, 0x32, 0x1f, 0x50, 0xcc, 0x6f, 0x51, 0x18, 0xfc, 0x00, 0xae, 0xc1, - 0x49, 0xd2, 0x07, 0x70, 0x82, 0x93, 0xf9, 0xab, 0x39, 0x20, 0xc9, 0x37, 0xd2, 0x46, 0x40, 0xa3, - 0xf0, 0xa9, 0x1d, 0xf4, 0xf7, 0xb5, 0x41, 0x7f, 0xb6, 0x67, 0xd0, 0xf9, 0xe7, 0x0d, 0x34, 0xf6, - 0x7f, 0x6c, 0xc0, 0xb9, 0x6c, 0x42, 0xf2, 0x02, 0x0c, 0xaf, 0xae, 0xaf, 0xc9, 0xd0, 0x20, 0xf1, - 0x29, 0x7e, 0x07, 0x2d, 0x63, 0x4b, 0x14, 0x91, 0xd7, 0x61, 0xf8, 0x23, 0x6b, 0x9e, 0x2d, 0x99, - 0xca, 0xed, 0x99, 0xaf, 0x07, 0x76, 0x43, 0xdf, 0x72, 0x09, 0x24, 0x75, 0x6c, 0xf3, 0x4f, 0x6c, - 0x6c, 0xbf, 0x95, 0x83, 0xc9, 0x6a, 0xa3, 0x41, 0xc3, 0x90, 0x19, 0x44, 0x34, 0x8c, 0x9e, 0xda, - 0x81, 0xcd, 0x0e, 0xfa, 0xd1, 0xbe, 0x6d, 0xa0, 0x51, 0xfd, 0x13, 0x03, 0xce, 0x4a, 0xaa, 0x07, - 0x1e, 0x7d, 0xb8, 0xbe, 0x17, 0xd0, 0x70, 0xcf, 0x6f, 0xba, 0x83, 0xde, 0x03, 0xc3, 0x55, 0xda, - 0x6b, 0x46, 0x34, 0x50, 0x1d, 0xd4, 0x3b, 0x08, 0xd1, 0x56, 0x69, 0x84, 0x90, 0x1b, 0x30, 0x52, - 0xed, 0x74, 0x02, 0xff, 0x01, 0x9f, 0xf6, 0xe3, 0xe2, 0x3c, 0x92, 0x83, 0xb4, 0xf3, 0x4b, 0x0e, - 0x62, 0xcd, 0x58, 0xa0, 0x6d, 0x1e, 0xd1, 0x3c, 0xce, 0x9b, 0xe1, 0xd2, 0xb6, 0x6a, 0xa1, 0x61, - 0xb9, 0xf9, 0xcd, 0x02, 0x94, 0xd4, 0x0f, 0x21, 0x26, 0x0c, 0xf3, 0xf0, 0x14, 0x35, 0x4c, 0xc0, - 0x41, 0x88, 0x25, 0x4a, 0x92, 0xa8, 0x9f, 0xdc, 0x89, 0x51, 0x3f, 0x5b, 0x30, 0xbe, 0x16, 0xf8, - 0x1d, 0x3f, 0xa4, 0x2e, 0x4f, 0x51, 0xc4, 0xb5, 0xd6, 0x74, 0x1c, 0x0a, 0xcb, 0xfb, 0x9c, 0x15, - 0xf1, 0xed, 0x40, 0x47, 0x60, 0xdb, 0xe9, 0x04, 0x46, 0x3a, 0x1f, 0xee, 0xe0, 0x77, 0x42, 0x71, - 0x5d, 0x20, 0x76, 0xf0, 0x33, 0x88, 0xee, 0xe0, 0x67, 0x10, 0x75, 0x5a, 0x0c, 0x3d, 0xa9, 0x69, - 0x41, 0x7e, 0xd5, 0x80, 0xb1, 0x6a, 0xbb, 0x2d, 0xa2, 0x7e, 0xe4, 0x3d, 0xff, 0xb3, 0x89, 0x93, - 0x9f, 0x87, 0x85, 0x72, 0x1f, 0xff, 0x57, 0x85, 0x8f, 0xff, 0xed, 0x4f, 0xe4, 0xe3, 0x5f, 0x0f, - 0x1c, 0x2f, 0x0a, 0xf1, 0x30, 0x37, 0xa9, 0x50, 0x0d, 0xfd, 0x55, 0xda, 0x41, 0xde, 0x86, 0x72, - 0x2c, 0x8f, 0x4b, 0x6d, 0x97, 0x3e, 0xa2, 0x3c, 0x48, 0x6a, 0x9c, 0xdf, 0x30, 0xd4, 0x0e, 0x2f, - 0xd2, 0x88, 0xe6, 0xb7, 0x0c, 0x38, 0xa7, 0x0a, 0x44, 0xbd, 0xbb, 0xdd, 0xf2, 0x70, 0xfb, 0x43, - 0xae, 0xc3, 0xa8, 0x18, 0xaf, 0xd8, 0x90, 0xeb, 0xcd, 0x6b, 0x95, 0xa0, 0x90, 0x45, 0x36, 0x44, - 0x8c, 0x87, 0xf0, 0x15, 0x4c, 0xa7, 0xa6, 0x1b, 0x2b, 0xaa, 0xcd, 0x8a, 0xce, 0x2e, 0x07, 0xf8, - 0x5b, 0x1f, 0x3b, 0x06, 0x31, 0xdf, 0x83, 0x29, 0xbd, 0x95, 0x75, 0x8a, 0x57, 0xd0, 0xe4, 0xa7, - 0x19, 0xd9, 0x9f, 0x26, 0xcb, 0xcd, 0x2d, 0x20, 0x3d, 0xf4, 0x21, 0x1e, 0x54, 0xd1, 0x48, 0x1e, - 0xa4, 0x4a, 0x77, 0x57, 0x0f, 0x62, 0x9c, 0xe1, 0x6d, 0x4c, 0xed, 0x6e, 0x24, 0x35, 0xff, 0x02, - 0x60, 0x3a, 0x43, 0x75, 0x9c, 0xb0, 0xb4, 0x57, 0xf4, 0xc9, 0x33, 0x1a, 0x47, 0x04, 0xc8, 0x29, - 0xf3, 0x9e, 0xcc, 0xe6, 0x75, 0xcc, 0x54, 0x39, 0x2e, 0xc5, 0xd7, 0xa7, 0xb1, 0xbc, 0xab, 0x41, - 0x3b, 0x43, 0x4f, 0x2c, 0x68, 0xa7, 0x06, 0xe3, 0xe2, 0xab, 0xc4, 0x54, 0x1e, 0x4e, 0xdc, 0x02, - 0x01, 0x2f, 0xb0, 0x7b, 0xa6, 0xb4, 0x4e, 0xc2, 0x79, 0x84, 0x7e, 0xf3, 0x01, 0x15, 0x3c, 0x46, - 0x54, 0x1e, 0x58, 0x90, 0xc9, 0x43, 0x21, 0x21, 0xff, 0xdc, 0x00, 0x22, 0x20, 0xea, 0x7c, 0x2e, - 0x1e, 0x37, 0x9f, 0xdd, 0x27, 0x33, 0x9f, 0x9f, 0x95, 0x6d, 0xcc, 0x9e, 0xd7, 0x19, 0xcd, 0x22, - 0xff, 0xd4, 0x80, 0x29, 0x1e, 0x39, 0xa2, 0x36, 0x76, 0xf4, 0xb8, 0xc6, 0x36, 0x9e, 0x4c, 0x63, - 0x2f, 0x85, 0x58, 0x6d, 0x9f, 0xb6, 0xf6, 0x36, 0x8a, 0xfc, 0x38, 0x40, 0x3c, 0xa3, 0x64, 0x84, - 0xe2, 0xa5, 0x0c, 0x2d, 0x10, 0x23, 0x25, 0x97, 0x2c, 0xa3, 0x98, 0x4e, 0x8d, 0xe9, 0x49, 0xb8, - 0x91, 0x9f, 0x85, 0x19, 0x36, 0x5f, 0x62, 0x88, 0x88, 0x73, 0x9b, 0x1d, 0xc3, 0x5a, 0x3e, 0xdf, - 0x7f, 0x69, 0xbf, 0x9e, 0x45, 0xc6, 0xef, 0x89, 0x24, 0x89, 0x16, 0xa2, 0x96, 0xba, 0xe5, 0xcb, - 0xa2, 0xc0, 0x80, 0x56, 0x6c, 0x7d, 0x38, 0x5b, 0xc2, 0x3a, 0x33, 0xf5, 0xdb, 0x05, 0x39, 0x17, - 0xb8, 0x7e, 0x0b, 0xf5, 0x8b, 0x1e, 0x08, 0x22, 0x1f, 0x01, 0xa9, 0x77, 0x77, 0x77, 0x69, 0x18, - 0x51, 0x97, 0xc3, 0x68, 0x10, 0xce, 0x8e, 0xa3, 0x7e, 0x40, 0x37, 0x55, 0x28, 0x4b, 0xed, 0x40, - 0x16, 0xab, 0x42, 0xd2, 0x4b, 0x4c, 0x28, 0xcc, 0x88, 0x8f, 0x66, 0x50, 0x99, 0xa6, 0x20, 0x9c, - 0x9d, 0xd0, 0xa2, 0x08, 0x93, 0x92, 0xda, 0x73, 0x32, 0x8f, 0x9d, 0x92, 0xeb, 0x40, 0xdb, 0xf6, - 0x66, 0xb1, 0xbb, 0xb8, 0x0d, 0x17, 0xfa, 0xf6, 0x66, 0xc6, 0x5d, 0x91, 0x1b, 0xfa, 0x5d, 0x91, - 0x0b, 0xfd, 0xb4, 0x6e, 0xa8, 0xde, 0x17, 0xf9, 0x2d, 0x23, 0xa5, 0x66, 0x85, 0x4d, 0xc4, 0xf3, - 0x2b, 0xf6, 0x5b, 0x87, 0x72, 0x98, 0x94, 0x81, 0x2b, 0xe2, 0x5c, 0x62, 0x8b, 0x31, 0x45, 0xac, - 0x2a, 0x72, 0x54, 0xc9, 0x8f, 0xa9, 0x71, 0xcd, 0x7f, 0x69, 0x00, 0xe1, 0x2d, 0x9c, 0x77, 0x3a, - 0xce, 0xb6, 0xd7, 0xf4, 0x22, 0x8f, 0x86, 0xe4, 0x1e, 0x94, 0x05, 0x0b, 0x67, 0xbb, 0x49, 0xd5, - 0x30, 0x30, 0x71, 0x4e, 0x1c, 0x97, 0xd9, 0x69, 0xeb, 0xa9, 0x87, 0xb0, 0x8f, 0x8c, 0xe4, 0x1e, - 0x43, 0x46, 0xcc, 0x1f, 0x1a, 0x70, 0xa1, 0xb7, 0xd9, 0xa2, 0xe6, 0xb8, 0xf3, 0x8c, 0x13, 0x3a, - 0x2f, 0xeb, 0x2b, 0x73, 0xe8, 0x61, 0x7d, 0x62, 0x5f, 0x99, 0x4f, 0x1c, 0xb6, 0xa7, 0xff, 0xca, - 0x87, 0x6a, 0x52, 0x0f, 0xf2, 0x7a, 0x56, 0x40, 0x0f, 0xbf, 0x75, 0xc3, 0xc1, 0x7a, 0x2c, 0x8f, - 0xdc, 0xe5, 0xe4, 0x32, 0x77, 0x39, 0xf2, 0x02, 0x51, 0x3e, 0xeb, 0x02, 0x91, 0xf9, 0x8b, 0x39, - 0x28, 0xad, 0x35, 0xbb, 0xbb, 0x5e, 0x7b, 0xc1, 0x89, 0x9c, 0xa7, 0x76, 0xcb, 0xf4, 0x96, 0xb6, - 0x65, 0x8a, 0x23, 0xce, 0xe2, 0x0f, 0x1b, 0x2c, 0xc9, 0x9e, 0x01, 0x93, 0x09, 0x09, 0x57, 0x0f, - 0x77, 0xa1, 0xc0, 0x7e, 0x08, 0x0b, 0xec, 0x72, 0x0f, 0x63, 0xc4, 0xba, 0x1e, 0xff, 0x27, 0x36, - 0x31, 0x7a, 0x6a, 0x43, 0xe4, 0x70, 0xf1, 0x0b, 0x3c, 0x33, 0xd9, 0xe9, 0xb3, 0xa8, 0xfe, 0xa1, - 0x01, 0xe5, 0xf4, 0x97, 0x90, 0x7b, 0x30, 0xc2, 0x38, 0x79, 0x71, 0x96, 0xb3, 0x17, 0xfb, 0x7c, - 0xf3, 0x75, 0x81, 0xc6, 0x9b, 0x87, 0x9d, 0x4f, 0x39, 0xc4, 0x92, 0x1c, 0x2e, 0x5a, 0x50, 0x52, - 0xb1, 0x32, 0x5a, 0xf7, 0x9a, 0xae, 0x13, 0xcf, 0x65, 0xf7, 0x83, 0xda, 0xea, 0xdf, 0xd4, 0x5a, - 0x2d, 0xb4, 0xe1, 0xa0, 0xe9, 0x2a, 0xf1, 0xca, 0x1d, 0x9f, 0x0e, 0xaa, 0x9c, 0x49, 0xad, 0xaf, - 0x5f, 0xb9, 0xe3, 0x30, 0xb6, 0xd7, 0xe2, 0xf5, 0x09, 0x39, 0xc3, 0xbd, 0x56, 0x07, 0x21, 0xaa, - 0xbd, 0xce, 0x71, 0xcc, 0x7f, 0x90, 0x87, 0x73, 0x49, 0xf3, 0x78, 0xf2, 0xce, 0x35, 0x27, 0x70, - 0x5a, 0xe1, 0x09, 0x33, 0xe0, 0x6a, 0x4f, 0xd3, 0xf0, 0x4a, 0xb9, 0x6c, 0x9a, 0xd2, 0x20, 0x33, - 0xd5, 0x20, 0xdc, 0xa4, 0xf2, 0x06, 0xc9, 0x66, 0x90, 0x7b, 0x90, 0xaf, 0xd3, 0x48, 0x5c, 0x3c, - 0xbd, 0xd2, 0xd3, 0xab, 0x6a, 0xbb, 0xae, 0xd7, 0x69, 0xc4, 0x07, 0x91, 0xc7, 0xee, 0x53, 0x2d, - 0x96, 0x9e, 0x6d, 0x37, 0xb6, 0x60, 0x78, 0xf1, 0x51, 0x87, 0x36, 0x22, 0x71, 0xdf, 0xf4, 0x95, - 0xe3, 0xf9, 0x71, 0x5c, 0xe5, 0x56, 0x2b, 0x45, 0x80, 0xda, 0x59, 0x1c, 0xe5, 0xe2, 0x9b, 0x50, - 0x94, 0x95, 0x9f, 0xea, 0x76, 0xe6, 0x5b, 0x30, 0xa6, 0x54, 0x72, 0x2a, 0xa1, 0xff, 0x6b, 0x03, - 0x86, 0x99, 0xb6, 0xdd, 0x7c, 0xe3, 0x29, 0xd5, 0x48, 0xb7, 0x34, 0x8d, 0x34, 0xa5, 0x5c, 0x23, - 0xc2, 0x79, 0xf9, 0xc6, 0x09, 0xba, 0xe8, 0xd0, 0x00, 0x48, 0x90, 0xc9, 0x1d, 0x18, 0x11, 0xf9, - 0x62, 0x44, 0x66, 0x5c, 0xf5, 0x5e, 0x92, 0xcc, 0x1c, 0x16, 0x5b, 0x71, 0x7e, 0x27, 0x6d, 0xf6, - 0x4a, 0x6a, 0xb2, 0x90, 0xc4, 0x6e, 0xab, 0x17, 0x61, 0x19, 0x9b, 0x79, 0xbf, 0xcd, 0xef, 0xa9, - 0x28, 0x39, 0xc8, 0xfa, 0x04, 0x71, 0x57, 0x85, 0xe3, 0x26, 0x7f, 0x1c, 0x93, 0x73, 0x82, 0x49, - 0xb6, 0x4f, 0xe7, 0x2f, 0x4b, 0xfc, 0xe6, 0x87, 0x6c, 0xd8, 0xbb, 0x50, 0xba, 0xed, 0x07, 0x0f, - 0x9d, 0xc0, 0xad, 0xee, 0x52, 0x11, 0x75, 0x5f, 0xc4, 0xd0, 0xf9, 0xf1, 0x1d, 0x0e, 0xb7, 0x1d, - 0x56, 0xf0, 0xa3, 0xc3, 0x4a, 0xa1, 0xe6, 0xfb, 0x4d, 0x4b, 0x43, 0x27, 0xab, 0x30, 0x7e, 0xdf, - 0x79, 0x24, 0xce, 0x40, 0xd7, 0xd7, 0x97, 0x45, 0xec, 0xce, 0x2b, 0x47, 0x87, 0x95, 0x0b, 0x2d, - 0xe7, 0x51, 0x7c, 0x76, 0xda, 0x3f, 0xbc, 0x5c, 0xa7, 0x27, 0x1e, 0x4c, 0xac, 0xf9, 0x41, 0x24, - 0x2a, 0x61, 0x36, 0x7b, 0xbe, 0xcf, 0x29, 0xda, 0x8d, 0xcc, 0x53, 0xb4, 0x0b, 0x6c, 0xa3, 0x62, - 0xef, 0xc4, 0xe4, 0xda, 0x75, 0x45, 0x8d, 0x31, 0x79, 0x17, 0xa6, 0xe6, 0x69, 0x10, 0x79, 0x3b, - 0x5e, 0xc3, 0x89, 0xe8, 0x6d, 0x3f, 0x68, 0x39, 0x91, 0x70, 0x18, 0xa1, 0xc3, 0xa0, 0x41, 0x39, - 0xa7, 0x96, 0x13, 0x59, 0xbd, 0x98, 0xe4, 0x2b, 0x59, 0xd1, 0x50, 0x43, 0xf8, 0xf9, 0xaf, 0x33, - 0x6b, 0x24, 0x23, 0x1a, 0xaa, 0x4f, 0x17, 0x64, 0xc4, 0x45, 0xed, 0x1e, 0x77, 0x94, 0x5c, 0xac, - 0xdd, 0x14, 0xc7, 0xda, 0x27, 0x1f, 0x15, 0xc7, 0xe3, 0xd6, 0xe7, 0xc8, 0x78, 0x0e, 0xf2, 0xb5, - 0xb5, 0xdb, 0xe8, 0x02, 0x12, 0x47, 0xb7, 0xb4, 0xbd, 0xe7, 0xb4, 0x1b, 0x68, 0x44, 0x89, 0x78, - 0x10, 0x55, 0xe1, 0xd5, 0xd6, 0x6e, 0x13, 0x07, 0xa6, 0xd7, 0x68, 0xd0, 0xf2, 0xa2, 0x2f, 0xdd, - 0xbc, 0xa9, 0x0c, 0x54, 0x11, 0x9b, 0x76, 0x43, 0x34, 0xad, 0xd2, 0x41, 0x14, 0xfb, 0xd1, 0xcd, - 0x9b, 0x99, 0xc3, 0x11, 0x37, 0x2c, 0x8b, 0x17, 0x59, 0x84, 0x89, 0xfb, 0xce, 0x23, 0x71, 0xc8, - 0x1f, 0xef, 0x61, 0xf3, 0x78, 0xdb, 0x00, 0x05, 0xab, 0x91, 0x14, 0xa9, 0x43, 0xac, 0x13, 0x91, - 0x77, 0x60, 0x2c, 0x11, 0xaf, 0x10, 0x8f, 0x77, 0xf3, 0x3c, 0xcc, 0x54, 0x11, 0x4e, 0xcd, 0x57, - 0xa6, 0xa0, 0x93, 0x8d, 0xd8, 0x05, 0xc1, 0x2d, 0x61, 0x3c, 0xd0, 0x1d, 0xad, 0xdd, 0x50, 0x5d, - 0x10, 0x0e, 0x96, 0x68, 0x9f, 0x35, 0x19, 0xef, 0x0d, 0x78, 0xf4, 0x91, 0xa5, 0x73, 0x51, 0x3c, - 0x1b, 0x6b, 0x81, 0xdf, 0xea, 0x44, 0x18, 0x85, 0x99, 0xf2, 0x6c, 0x74, 0xb0, 0x24, 0xc3, 0xb3, - 0xc1, 0x49, 0xb2, 0x63, 0x17, 0xc6, 0x1f, 0x23, 0x76, 0x81, 0x42, 0x61, 0xd9, 0x6f, 0xec, 0x63, - 0xd8, 0xe5, 0x68, 0xed, 0x23, 0xa6, 0x3f, 0x9a, 0x7e, 0x63, 0xff, 0xc9, 0x9d, 0xb9, 0x23, 0x7b, - 0xb2, 0xc2, 0xbe, 0x9d, 0x89, 0x95, 0xa8, 0x7a, 0x76, 0x52, 0x3b, 0x49, 0xd4, 0xca, 0xb8, 0xa1, - 0xc2, 0xa5, 0x50, 0x7e, 0x88, 0xa5, 0x93, 0x13, 0x0a, 0xe5, 0x05, 0x1a, 0xee, 0x47, 0x7e, 0x67, - 0xbe, 0xe9, 0x75, 0xb6, 0x7d, 0x27, 0x70, 0x67, 0xcb, 0x7d, 0x14, 0xc6, 0xcb, 0x99, 0x0a, 0x63, - 0xca, 0xe5, 0xf4, 0x76, 0x43, 0x32, 0xb0, 0x7a, 0x58, 0x92, 0xaf, 0xc0, 0x04, 0x9b, 0x2d, 0x8b, - 0x8f, 0x22, 0xda, 0xe6, 0xa2, 0x34, 0x85, 0x4b, 0xfd, 0x8c, 0x72, 0x71, 0x33, 0x2e, 0xe4, 0x42, - 0x8a, 0xda, 0x83, 0xc6, 0x04, 0xaa, 0x90, 0xea, 0xac, 0x88, 0x0b, 0xb3, 0xf7, 0x9d, 0x47, 0x4a, - 0x9a, 0x23, 0x45, 0xea, 0x09, 0x4a, 0x2c, 0x26, 0xd4, 0x63, 0x12, 0xbb, 0x1f, 0x23, 0xf5, 0x99, - 0x00, 0x7d, 0x39, 0x91, 0x9f, 0x86, 0xf3, 0xe2, 0xb3, 0x16, 0x30, 0x57, 0x82, 0x1f, 0x1c, 0xd4, - 0xf7, 0x9c, 0x80, 0x4d, 0xdc, 0xe9, 0xd3, 0x69, 0x58, 0xd9, 0x61, 0xae, 0xe4, 0x63, 0x87, 0x9c, - 0x91, 0xd5, 0xaf, 0x06, 0xf3, 0xc7, 0x53, 0xc3, 0x4e, 0x96, 0x60, 0x44, 0xe0, 0x8a, 0x85, 0xb5, - 0xb7, 0xf6, 0x67, 0x33, 0x6b, 0x1f, 0x11, 0xb5, 0x5b, 0x92, 0xde, 0xfc, 0x23, 0x03, 0xc6, 0xb5, - 0x1e, 0x25, 0x6f, 0x2a, 0x51, 0x4f, 0x49, 0xb4, 0xa2, 0x86, 0x93, 0xf9, 0xa8, 0xc6, 0x9b, 0x22, - 0xd4, 0x2d, 0xd7, 0x9f, 0x2e, 0x33, 0x89, 0xdd, 0xb1, 0x5b, 0xbd, 0x24, 0x57, 0x44, 0xa1, 0x4f, - 0xae, 0x88, 0x5f, 0x19, 0x87, 0x09, 0x7d, 0x0d, 0x67, 0x46, 0xf5, 0xb2, 0xbf, 0xeb, 0xb5, 0xa5, - 0x4f, 0x80, 0x67, 0x3f, 0x41, 0x88, 0xf6, 0x42, 0x05, 0x42, 0xc8, 0x4b, 0x00, 0xf1, 0xe9, 0xba, - 0xdc, 0xf6, 0x8b, 0xf7, 0x34, 0x94, 0x02, 0xf2, 0x13, 0x00, 0x2b, 0xbe, 0x4b, 0xe3, 0x04, 0x3a, - 0xc7, 0xf8, 0x04, 0x5f, 0x16, 0x3e, 0x41, 0xf1, 0x06, 0xc6, 0xd1, 0x61, 0xe5, 0x6c, 0xdb, 0x77, - 0x69, 0x6f, 0xe6, 0x1c, 0x85, 0x23, 0xf9, 0x22, 0x0c, 0x59, 0xdd, 0x26, 0x95, 0xf9, 0x5c, 0xc6, - 0xe4, 0x9c, 0xee, 0x36, 0x95, 0xdc, 0xb8, 0x41, 0x37, 0x7d, 0x14, 0xc4, 0x00, 0xe4, 0x7d, 0x00, - 0x26, 0xb6, 0x98, 0x64, 0x52, 0x5e, 0x18, 0x47, 0x17, 0x81, 0x22, 0xf1, 0x98, 0x9a, 0x52, 0xab, - 0x3c, 0x21, 0x21, 0xab, 0x30, 0x22, 0x34, 0xa4, 0x38, 0x6a, 0x79, 0x2e, 0xcb, 0xc9, 0xa7, 0x98, - 0x49, 0x22, 0xc1, 0x0a, 0x82, 0x75, 0xbf, 0x1b, 0x77, 0x71, 0xbc, 0x03, 0xa3, 0x8c, 0xfd, 0x46, - 0x48, 0xc5, 0x35, 0xf2, 0x51, 0x1e, 0x76, 0xaa, 0x34, 0xa8, 0x1b, 0xea, 0x1e, 0x86, 0x84, 0x80, - 0x7c, 0x05, 0x53, 0x22, 0x89, 0xae, 0x3e, 0xd6, 0x57, 0x7c, 0xa5, 0xa7, 0xab, 0x67, 0x9c, 0x4e, - 0x27, 0x23, 0x87, 0x5c, 0xcc, 0x8f, 0xec, 0xc6, 0x57, 0xb3, 0xe2, 0x04, 0xe9, 0xc7, 0x54, 0x70, - 0xad, 0xa7, 0x82, 0x59, 0x79, 0xdb, 0xa8, 0x37, 0x11, 0x92, 0xc6, 0x97, 0x74, 0xa0, 0x9c, 0x28, - 0x13, 0x51, 0x17, 0x1c, 0x57, 0xd7, 0xeb, 0x3d, 0x75, 0xa9, 0x03, 0xd8, 0x53, 0x5d, 0x0f, 0x77, - 0xe2, 0x26, 0xc9, 0xac, 0x45, 0x7d, 0x63, 0xc7, 0xd5, 0xf7, 0x52, 0x4f, 0x7d, 0xd3, 0xee, 0x76, - 0x6f, 0x3d, 0x29, 0x9e, 0xe4, 0x1d, 0x18, 0x97, 0x10, 0x9c, 0x1f, 0xe8, 0xa3, 0x15, 0x5b, 0x18, - 0x77, 0x1b, 0x63, 0x0d, 0xf5, 0x2c, 0x40, 0x2a, 0xb2, 0x4a, 0xcd, 0xa5, 0x63, 0x5c, 0xa3, 0x4e, - 0x4b, 0x85, 0x8e, 0x4c, 0xbe, 0x0c, 0x63, 0x4b, 0x2d, 0xf6, 0x21, 0x7e, 0xdb, 0x89, 0x28, 0xae, - 0xb7, 0x89, 0xdf, 0x5b, 0x29, 0x51, 0x44, 0x95, 0xa7, 0x1b, 0x4d, 0x8a, 0x54, 0x7b, 0x45, 0xa1, - 0x60, 0x9d, 0xc7, 0x5d, 0x5b, 0x42, 0x86, 0x43, 0xb1, 0xba, 0x3e, 0x9b, 0xe1, 0x7b, 0x56, 0xd8, - 0xe3, 0x72, 0xc5, 0x3d, 0x66, 0xb6, 0x98, 0x10, 0x5a, 0xe7, 0xe9, 0x3c, 0xc9, 0xbb, 0x30, 0x26, - 0x2e, 0xc2, 0x56, 0xad, 0x95, 0x70, 0xb6, 0x8c, 0x1f, 0x8f, 0x29, 0xfc, 0xe4, 0x9d, 0x59, 0xdb, - 0x09, 0x52, 0x07, 0x90, 0x09, 0x3e, 0xf9, 0x12, 0xcc, 0x6c, 0x79, 0x6d, 0xd7, 0x7f, 0x18, 0x0a, - 0x05, 0x2e, 0x14, 0xdd, 0x54, 0x12, 0x66, 0xf5, 0x90, 0x97, 0xdb, 0x72, 0xa1, 0xe9, 0x51, 0x7c, - 0x99, 0x1c, 0xc8, 0xcf, 0xf4, 0x70, 0xe6, 0x12, 0x44, 0x8e, 0x93, 0xa0, 0xb9, 0x1e, 0x09, 0xea, - 0xad, 0x3e, 0x2d, 0x4e, 0x99, 0xd5, 0x10, 0x1f, 0x88, 0x6e, 0x56, 0x7d, 0xe8, 0x7b, 0xed, 0xd9, - 0x69, 0xed, 0xf9, 0xa1, 0x38, 0xd2, 0x1a, 0xf1, 0xd6, 0xfc, 0xa6, 0xd7, 0x38, 0x90, 0xa9, 0x7c, - 0x75, 0x83, 0xed, 0x63, 0x5f, 0xf3, 0x9f, 0x64, 0xb0, 0x26, 0x5f, 0x86, 0x12, 0xfb, 0x1b, 0x5b, - 0xb7, 0x33, 0xda, 0x69, 0xa5, 0x82, 0x29, 0xea, 0xc1, 0x31, 0xc2, 0x9b, 0xba, 0x19, 0x86, 0xaf, - 0xc6, 0xca, 0xfc, 0xa1, 0x01, 0x33, 0x59, 0x6d, 0x3d, 0x21, 0x2d, 0x92, 0x99, 0x8a, 0x5b, 0x40, - 0xd7, 0x0b, 0x8f, 0x5b, 0x88, 0xa3, 0x15, 0x2a, 0x30, 0x74, 0xcf, 0x6b, 0xbb, 0x32, 0xae, 0x0e, - 0x97, 0xc3, 0x7d, 0x06, 0xb0, 0x38, 0x9c, 0x21, 0xe0, 0x1d, 0x0c, 0x5c, 0x2f, 0x87, 0x38, 0x02, - 0x5e, 0xd4, 0xb0, 0x38, 0x9c, 0x21, 0xb0, 0x65, 0x57, 0x2e, 0x13, 0x88, 0xc0, 0x56, 0xe3, 0xd0, - 0xe2, 0x70, 0x72, 0x05, 0x46, 0x56, 0xdb, 0xcb, 0xd4, 0x79, 0x40, 0xc5, 0xa1, 0x21, 0xba, 0x8a, - 0xfc, 0xb6, 0xdd, 0x64, 0x30, 0x4b, 0x16, 0x9a, 0xdf, 0x31, 0x60, 0xaa, 0xa7, 0x9b, 0x4e, 0xce, - 0xfc, 0x74, 0xfc, 0x09, 0xed, 0x20, 0xdf, 0xc7, 0x9b, 0x5f, 0xc8, 0x6e, 0xbe, 0xf9, 0xfb, 0x05, - 0x38, 0xdf, 0x67, 0xd5, 0x4a, 0xa2, 0x2b, 0x8c, 0x13, 0xa3, 0x2b, 0xbe, 0xca, 0x56, 0x09, 0xc7, - 0x6b, 0x85, 0xeb, 0x7e, 0xd2, 0xe2, 0xe4, 0x20, 0x0a, 0xcb, 0x64, 0x6a, 0x15, 0x99, 0x06, 0xe4, - 0x42, 0x03, 0x29, 0xec, 0xc8, 0xef, 0xf1, 0xc7, 0xeb, 0xcc, 0x7a, 0xe2, 0x1b, 0xf2, 0x7f, 0x43, - 0xe2, 0x1b, 0xf4, 0x53, 0xc5, 0xc2, 0x13, 0x3d, 0x55, 0xcc, 0x3e, 0x80, 0x18, 0x7a, 0x9c, 0xa3, - 0xb8, 0x79, 0x18, 0xaf, 0x53, 0x27, 0x68, 0xec, 0x55, 0x43, 0x3e, 0x48, 0xc3, 0xc8, 0x0d, 0x55, - 0x72, 0x88, 0x05, 0xb6, 0x13, 0xf6, 0x8e, 0x85, 0x46, 0x63, 0xfe, 0xa7, 0x54, 0x58, 0xc6, 0xdf, - 0x44, 0x79, 0x79, 0x05, 0x86, 0xb6, 0xf6, 0x68, 0x20, 0x8d, 0x64, 0x6c, 0xc8, 0x43, 0x06, 0x50, - 0x1b, 0x82, 0x18, 0xe6, 0x4f, 0x43, 0x49, 0xad, 0x0c, 0x15, 0x02, 0xfb, 0x2d, 0x66, 0x24, 0x57, - 0x08, 0x0c, 0x60, 0x71, 0xf8, 0x89, 0xd9, 0xd8, 0x92, 0x5e, 0xc8, 0x9f, 0xd4, 0x0b, 0xac, 0x72, - 0x94, 0x37, 0xa5, 0x72, 0xfc, 0xad, 0x56, 0x1e, 0x31, 0x80, 0xc5, 0xe1, 0x4f, 0xb4, 0xf2, 0xff, - 0x60, 0x40, 0x01, 0x33, 0x61, 0xbc, 0x01, 0xa3, 0xd2, 0x9f, 0xad, 0x66, 0x87, 0x98, 0x96, 0xee, - 0xee, 0x50, 0x0f, 0xaa, 0x11, 0x40, 0x56, 0xd5, 0x26, 0x0d, 0xb6, 0xb5, 0xd8, 0xab, 0x07, 0x0c, - 0xa0, 0x56, 0x85, 0x18, 0xa7, 0x18, 0x0f, 0x8c, 0x2f, 0x13, 0xdb, 0x51, 0xae, 0xb2, 0x78, 0x7c, - 0x59, 0xcf, 0xde, 0x53, 0x62, 0x99, 0xbf, 0x6e, 0xc0, 0xd9, 0x4c, 0x4b, 0x86, 0xd5, 0xca, 0x4d, - 0x26, 0x45, 0x1c, 0xd3, 0xf6, 0x12, 0xc7, 0x38, 0x4d, 0x1c, 0xd9, 0x29, 0x64, 0xeb, 0x79, 0x18, - 0x8d, 0x77, 0x98, 0x64, 0x46, 0x0e, 0x1d, 0x3a, 0x3d, 0xe5, 0x76, 0xec, 0xaf, 0x0d, 0x18, 0x66, - 0x4d, 0x78, 0x6a, 0xaf, 0x15, 0x65, 0xbb, 0xc0, 0xd9, 0x27, 0x0d, 0x74, 0x99, 0xe8, 0x77, 0x86, - 0x01, 0x12, 0x64, 0xb2, 0x0d, 0x13, 0xab, 0x4b, 0x0b, 0xf3, 0x4b, 0x2e, 0x6d, 0x47, 0x78, 0x06, - 0x9c, 0x4a, 0x2f, 0xc1, 0xb6, 0xc6, 0x41, 0xdb, 0x69, 0x0a, 0x84, 0x83, 0x44, 0x37, 0xf8, 0x9e, - 0xdb, 0xb0, 0xbd, 0x98, 0x4e, 0x35, 0x29, 0x75, 0x8e, 0xac, 0x8e, 0x7a, 0xf5, 0xfe, 0xb2, 0x52, - 0x47, 0x6e, 0xc0, 0x3a, 0x42, 0xa7, 0xd5, 0xec, 0x53, 0x87, 0xce, 0x91, 0xec, 0x41, 0xf9, 0x0e, - 0xae, 0x3e, 0x4a, 0x2d, 0xf9, 0xe3, 0x6b, 0x79, 0x41, 0xd4, 0xf2, 0x0c, 0x5f, 0xb6, 0xb2, 0xeb, - 0xe9, 0xe1, 0x9a, 0x48, 0x6e, 0xe1, 0x44, 0xc9, 0xfd, 0x3b, 0x06, 0x0c, 0xf3, 0xe5, 0x2d, 0x7e, - 0x43, 0x28, 0x73, 0x01, 0xdd, 0x7a, 0x32, 0x0b, 0x68, 0x19, 0x35, 0x97, 0xe6, 0x42, 0xe0, 0x65, - 0x64, 0x21, 0xf5, 0x20, 0x91, 0x3c, 0xe7, 0x40, 0xd3, 0x9a, 0x97, 0x24, 0xd1, 0x78, 0xfc, 0x2d, - 0x22, 0x95, 0x0b, 0xc7, 0x50, 0x9f, 0x47, 0x1d, 0x79, 0xcc, 0xe7, 0x51, 0x97, 0x61, 0x54, 0x84, - 0x97, 0xd5, 0x0e, 0xc4, 0x06, 0x5a, 0xba, 0x88, 0x62, 0xb8, 0x92, 0x75, 0x9d, 0x83, 0xec, 0x6d, - 0x2d, 0x67, 0x62, 0x8c, 0x48, 0x56, 0x61, 0x34, 0xb9, 0x13, 0x35, 0xaa, 0x1d, 0x56, 0xc7, 0x70, - 0x11, 0x7f, 0xcd, 0xaf, 0xdd, 0x66, 0x5e, 0x81, 0x4a, 0x78, 0x98, 0xdf, 0x34, 0xa0, 0x9c, 0x96, - 0x17, 0xf2, 0x0e, 0x8c, 0xc5, 0xd7, 0xd2, 0xe2, 0xe8, 0x13, 0xf4, 0x36, 0x27, 0xf7, 0xd8, 0xb4, - 0x38, 0x14, 0x15, 0x9d, 0xcc, 0x41, 0x91, 0x4d, 0x3b, 0x25, 0x69, 0x36, 0xea, 0x93, 0xae, 0x80, - 0xa9, 0x87, 0xaf, 0x12, 0x4f, 0x99, 0xb5, 0xff, 0x25, 0x0f, 0x63, 0xca, 0x60, 0x91, 0x57, 0xa0, - 0xb8, 0x14, 0x2e, 0xfb, 0x8d, 0x7d, 0xea, 0x8a, 0x33, 0x1d, 0x7c, 0xfd, 0xd6, 0x0b, 0xed, 0x26, - 0x02, 0xad, 0xb8, 0x98, 0xd4, 0x60, 0x9c, 0xff, 0x27, 0xaf, 0x1f, 0xe7, 0x12, 0x7f, 0x34, 0x47, - 0x96, 0x17, 0x8f, 0xd5, 0xe5, 0x5d, 0x23, 0x21, 0x5f, 0x03, 0xe0, 0x00, 0x36, 0xbe, 0x03, 0x44, - 0x97, 0xcb, 0x09, 0x7c, 0x56, 0x54, 0x10, 0x79, 0xea, 0x17, 0xa2, 0x28, 0x28, 0x0c, 0xf1, 0xe5, - 0x4d, 0xbf, 0xb1, 0x3f, 0xf8, 0xdb, 0xbb, 0xc9, 0xcb, 0x9b, 0x7e, 0x63, 0xdf, 0xce, 0x0e, 0x35, - 0x54, 0x59, 0x92, 0x6f, 0x19, 0x70, 0xd1, 0xa2, 0x0d, 0xff, 0x01, 0x0d, 0x0e, 0xaa, 0x11, 0x62, - 0xa9, 0x35, 0x9e, 0x1c, 0xd7, 0x78, 0x4b, 0xd4, 0xf8, 0x72, 0x20, 0xb8, 0xe0, 0x9d, 0xa8, 0x56, - 0x27, 0xb2, 0x8f, 0x69, 0xc2, 0x31, 0x55, 0x9a, 0x7f, 0x66, 0x28, 0x53, 0x80, 0xac, 0xc0, 0x68, - 0x2c, 0x2c, 0xc2, 0x65, 0x1a, 0x5b, 0x66, 0x12, 0x6e, 0xd1, 0x9d, 0xda, 0x33, 0xe2, 0xf8, 0x65, - 0x3a, 0x16, 0x39, 0x6d, 0x46, 0x48, 0x20, 0xf9, 0x00, 0x0a, 0x38, 0x54, 0x27, 0x67, 0x59, 0x93, - 0x4b, 0x4d, 0x81, 0x8d, 0x11, 0xb6, 0x1a, 0x29, 0xc9, 0xe7, 0x44, 0x0c, 0x50, 0x5e, 0xcb, 0x5f, - 0xcc, 0x40, 0xac, 0x1d, 0xf1, 0x1a, 0x93, 0x44, 0xb7, 0x2a, 0xd2, 0xfa, 0xf7, 0x72, 0x50, 0x4e, - 0x4f, 0x3c, 0xf2, 0x3e, 0x94, 0xe4, 0xfd, 0xb6, 0xbb, 0x4e, 0xb8, 0x27, 0x72, 0xa2, 0xe2, 0xae, - 0x55, 0x5e, 0x8a, 0xb3, 0xf7, 0x1c, 0x2d, 0x77, 0x9e, 0x46, 0xc0, 0x16, 0xe4, 0x75, 0x71, 0x69, - 0x42, 0x99, 0x40, 0x91, 0x1f, 0x75, 0x52, 0x39, 0x51, 0x25, 0x1a, 0x79, 0x03, 0xf2, 0xfc, 0xd2, - 0xa7, 0x9a, 0x50, 0xeb, 0xfe, 0xed, 0x2a, 0xbf, 0xb3, 0xc6, 0x4f, 0xfc, 0xf5, 0xa3, 0x13, 0x86, - 0x4f, 0x96, 0x95, 0x2b, 0x83, 0xc3, 0x5a, 0x62, 0x21, 0x09, 0x8e, 0x3f, 0xee, 0xe4, 0xbb, 0x83, - 0x1f, 0x16, 0x8a, 0xf9, 0x72, 0x41, 0x5c, 0x12, 0xfb, 0xbd, 0x3c, 0x8c, 0xc6, 0xf5, 0x13, 0x02, - 0x68, 0x6f, 0x88, 0xa3, 0x7b, 0xfc, 0x9f, 0x5c, 0x80, 0xa2, 0x34, 0x31, 0xc4, 0xf1, 0xfd, 0x48, - 0x28, 0xcc, 0x8b, 0x59, 0x90, 0xb6, 0x04, 0x37, 0x2f, 0x2c, 0xf9, 0x93, 0xdc, 0x84, 0xd8, 0x50, - 0xe8, 0x67, 0x51, 0x14, 0xd8, 0x80, 0x59, 0x31, 0x1a, 0x99, 0x80, 0x9c, 0xc7, 0x03, 0xe2, 0x47, - 0xad, 0x9c, 0xe7, 0x92, 0xf7, 0xa1, 0xe8, 0xb8, 0x2e, 0x75, 0x6d, 0x27, 0x1a, 0xe0, 0x1d, 0xe4, - 0x22, 0xe3, 0xc6, 0x35, 0x3a, 0x52, 0x55, 0x23, 0x52, 0x85, 0x51, 0x7c, 0x06, 0xb7, 0x1b, 0x0e, - 0xf4, 0x76, 0x6e, 0xc2, 0xa1, 0xc8, 0xc8, 0x36, 0x42, 0xea, 0x92, 0x97, 0xa1, 0xc0, 0x46, 0x53, - 0xac, 0x07, 0x71, 0x9a, 0xc4, 0xd5, 0xf5, 0x35, 0xde, 0x61, 0x77, 0xcf, 0x58, 0x88, 0x40, 0x5e, - 0x84, 0x7c, 0x77, 0x6e, 0x47, 0x68, 0xfa, 0x72, 0x72, 0x1f, 0x38, 0x46, 0x63, 0xc5, 0xe4, 0x16, - 0x14, 0x1f, 0xea, 0x37, 0x3f, 0xcf, 0xa6, 0x86, 0x31, 0xc6, 0x8f, 0x11, 0x6b, 0x45, 0x18, 0xe6, - 0x77, 0x1e, 0xcd, 0xe7, 0x00, 0x92, 0xaa, 0x7b, 0xa3, 0x2c, 0xcc, 0xaf, 0xc1, 0x68, 0x5c, 0x25, - 0x79, 0x16, 0x60, 0x9f, 0x1e, 0xd8, 0x7b, 0x4e, 0xdb, 0x15, 0x6f, 0xfa, 0x94, 0xac, 0xd1, 0x7d, - 0x7a, 0x70, 0x17, 0x01, 0xe4, 0x3c, 0x8c, 0x74, 0xd8, 0xa8, 0xca, 0x8c, 0xbe, 0xd6, 0x70, 0xa7, - 0xbb, 0xcd, 0x24, 0x74, 0x16, 0x46, 0xd0, 0xf9, 0x21, 0x26, 0xda, 0xb8, 0x25, 0x7f, 0x9a, 0xbf, - 0x95, 0xc3, 0x5c, 0x0f, 0x4a, 0x3b, 0xc9, 0x0b, 0x30, 0xde, 0x08, 0x28, 0x2e, 0x47, 0x0e, 0x33, - 0x8b, 0x44, 0x3d, 0xa5, 0x04, 0xb8, 0xe4, 0x92, 0x2b, 0x30, 0x99, 0xa4, 0x18, 0xb6, 0x1b, 0xdb, - 0xe2, 0xde, 0x77, 0xc9, 0x1a, 0xef, 0xc8, 0x1c, 0xc3, 0xf3, 0xdb, 0x78, 0x91, 0xa3, 0xac, 0xde, - 0x77, 0x8c, 0x64, 0xba, 0xe0, 0x51, 0x6b, 0x52, 0x81, 0xe3, 0xc1, 0xc9, 0x39, 0x18, 0x76, 0x9c, - 0xdd, 0xae, 0xc7, 0x83, 0xca, 0x4b, 0x96, 0xf8, 0x45, 0x5e, 0x85, 0xa9, 0xd0, 0xdb, 0x6d, 0x3b, - 0x51, 0x37, 0x10, 0xc9, 0x36, 0x68, 0x80, 0x22, 0x35, 0x6e, 0x95, 0xe3, 0x82, 0x79, 0x0e, 0x27, - 0xaf, 0x03, 0x51, 0xeb, 0xf3, 0xb7, 0x3f, 0xa6, 0x0d, 0x2e, 0x6a, 0x25, 0x6b, 0x4a, 0x29, 0x59, - 0xc5, 0x02, 0xf2, 0x3c, 0x94, 0x02, 0x1a, 0xa2, 0x49, 0x86, 0xdd, 0x86, 0x29, 0x84, 0xac, 0x31, - 0x09, 0xbb, 0x47, 0x0f, 0xcc, 0x1a, 0x4c, 0xf5, 0xcc, 0x47, 0xf2, 0x3a, 0xb7, 0xee, 0xc5, 0xfa, - 0x5c, 0xe2, 0x9b, 0x19, 0x7c, 0xfa, 0x4a, 0x7f, 0x39, 0x9d, 0x23, 0x99, 0x6d, 0x28, 0xa9, 0xfa, - 0xf5, 0x84, 0x1b, 0xf5, 0xe7, 0x30, 0xec, 0x94, 0x2b, 0x9f, 0xe1, 0xa3, 0xc3, 0x4a, 0xce, 0x73, - 0x31, 0xd8, 0xf4, 0x2a, 0x14, 0xa5, 0x95, 0xa0, 0xbe, 0x3f, 0x23, 0x0c, 0xca, 0x03, 0x2b, 0x2e, - 0x35, 0x5f, 0x86, 0x11, 0xa1, 0x42, 0x8f, 0x77, 0x44, 0x99, 0xdf, 0xc8, 0xc1, 0xa4, 0x45, 0xd9, - 0x04, 0x17, 0x2f, 0xbb, 0x7c, 0xc6, 0x92, 0x2d, 0x6b, 0xdf, 0x76, 0x4c, 0x02, 0x8b, 0xef, 0x1a, - 0x30, 0x9d, 0x81, 0xfb, 0x89, 0xb2, 0xb3, 0xbd, 0x09, 0xa3, 0x0b, 0x9e, 0xd3, 0xac, 0xba, 0x6e, - 0x1c, 0x3e, 0x8b, 0xd6, 0xa0, 0xcb, 0xa6, 0x93, 0xc3, 0xa0, 0xea, 0x62, 0x1a, 0xa3, 0x92, 0x6b, - 0x42, 0x28, 0x92, 0xfc, 0x91, 0x32, 0x9d, 0x33, 0xf0, 0x36, 0x25, 0xc9, 0x9c, 0xf1, 0x2e, 0x24, - 0x07, 0x26, 0xa7, 0xb3, 0x4f, 0xed, 0xd0, 0x65, 0xdf, 0x85, 0x4c, 0x7f, 0xde, 0x40, 0xdb, 0xce, - 0x6f, 0xe6, 0xe0, 0x5c, 0x36, 0xe1, 0x27, 0x4d, 0xb4, 0x87, 0xd9, 0x43, 0x94, 0x8c, 0xd9, 0x98, - 0x68, 0x8f, 0xa7, 0x1a, 0x41, 0xfc, 0x04, 0x81, 0xec, 0xc0, 0xf8, 0xb2, 0x13, 0x46, 0x77, 0xa9, - 0x13, 0x44, 0xdb, 0xd4, 0x89, 0x06, 0xb0, 0x60, 0xe3, 0xf7, 0xc9, 0x71, 0x51, 0xdb, 0x93, 0x94, - 0xe9, 0xf7, 0xc9, 0x35, 0xb6, 0xb1, 0xa0, 0x14, 0x06, 0x10, 0x94, 0xaf, 0xc3, 0x64, 0x9d, 0xb6, - 0x9c, 0xce, 0x9e, 0x1f, 0x50, 0xe1, 0x3b, 0xbf, 0x0e, 0xe3, 0x31, 0x28, 0x53, 0x5a, 0xf4, 0x62, - 0x0d, 0x5f, 0xe9, 0x88, 0x44, 0x95, 0xe8, 0xc5, 0xe6, 0x6f, 0xe4, 0xe0, 0x7c, 0xb5, 0x21, 0x0e, - 0x1a, 0x44, 0x81, 0x3c, 0x0f, 0xfd, 0x94, 0xeb, 0x26, 0x37, 0x60, 0xf4, 0xbe, 0xf3, 0x68, 0x99, - 0xe2, 0x0b, 0xc2, 0x3c, 0x5d, 0x13, 0x37, 0xbf, 0x9c, 0x47, 0x76, 0xec, 0xf6, 0xb2, 0x12, 0x1c, - 0x75, 0xb3, 0x59, 0x78, 0xcc, 0xcd, 0xa6, 0x09, 0xc3, 0x77, 0xfd, 0xa6, 0x2b, 0x16, 0x27, 0x71, - 0x6e, 0xb1, 0x87, 0x10, 0x4b, 0x94, 0x98, 0x3f, 0x34, 0x60, 0x22, 0x6e, 0x31, 0x36, 0xe1, 0x53, - 0xef, 0x92, 0x2b, 0x30, 0x82, 0x15, 0xc5, 0xaf, 0x23, 0xe1, 0xa2, 0xd1, 0x64, 0x20, 0xdb, 0x73, - 0x2d, 0x59, 0xa8, 0xf6, 0xc4, 0xd0, 0xe3, 0xf5, 0x84, 0xf9, 0xcf, 0xf0, 0x48, 0x44, 0xfd, 0x4a, - 0xb6, 0x12, 0x29, 0x0d, 0x31, 0x06, 0x6c, 0x48, 0xee, 0x89, 0x0d, 0x49, 0xbe, 0xef, 0x90, 0xfc, - 0x42, 0x0e, 0xc6, 0xe2, 0xc6, 0x7e, 0xc6, 0x92, 0x08, 0xc4, 0xdf, 0x35, 0x50, 0x08, 0x7d, 0x5d, - 0xd1, 0x15, 0x22, 0x52, 0xfd, 0x03, 0x18, 0x16, 0x93, 0xc9, 0x48, 0x9d, 0x0b, 0xa6, 0x46, 0x37, - 0x79, 0x63, 0x1a, 0x07, 0x34, 0xb4, 0x04, 0x1d, 0xde, 0x51, 0xd8, 0xa2, 0xdb, 0xe2, 0x84, 0xec, - 0xa9, 0x5d, 0xa3, 0xb2, 0xef, 0x28, 0x24, 0x1f, 0x36, 0xd0, 0xea, 0xf4, 0x8f, 0x0a, 0x50, 0x4e, - 0x93, 0x9c, 0x9c, 0xa6, 0x61, 0xad, 0xbb, 0x2d, 0x1e, 0xe8, 0xc0, 0x34, 0x0d, 0x9d, 0xee, 0xb6, - 0xc5, 0x60, 0xe4, 0x0a, 0x14, 0xd6, 0x02, 0xef, 0x01, 0x7e, 0xb5, 0x78, 0x9f, 0xa4, 0x13, 0x78, - 0x0f, 0xd4, 0x60, 0x5d, 0x56, 0x8e, 0x1b, 0xda, 0xe5, 0xba, 0xf2, 0xbc, 0x3f, 0xdf, 0xd0, 0x36, - 0xc3, 0x74, 0x3e, 0x20, 0x89, 0xc6, 0x96, 0xca, 0x1a, 0x75, 0x02, 0x91, 0x52, 0x40, 0xa8, 0x33, - 0x5c, 0x2a, 0xb7, 0x11, 0xcc, 0x93, 0xfd, 0x5a, 0x2a, 0x12, 0x69, 0x02, 0x51, 0x7e, 0xca, 0x09, - 0x7c, 0xf2, 0x1e, 0x4f, 0xbe, 0xab, 0x35, 0xa3, 0xb2, 0xb6, 0xd5, 0xd9, 0x9c, 0xc1, 0xf7, 0x49, - 0xfa, 0x08, 0xd7, 0x60, 0x14, 0x5d, 0x5e, 0xe8, 0xc8, 0x28, 0x9e, 0xc8, 0x4c, 0x06, 0x46, 0x03, - 0xc6, 0x13, 0xd8, 0xb1, 0x3b, 0x23, 0x61, 0x42, 0xde, 0x83, 0x31, 0x35, 0x9a, 0x97, 0xc7, 0x9c, - 0x5e, 0xe2, 0xf7, 0xc7, 0xfa, 0xe4, 0xcd, 0x53, 0x09, 0xcc, 0xcf, 0xa9, 0x52, 0x22, 0x16, 0xed, - 0x63, 0xa5, 0xc4, 0xfc, 0x35, 0x34, 0xe3, 0x5b, 0x7e, 0x44, 0x85, 0xf5, 0xf2, 0xd4, 0xea, 0xb1, - 0xc4, 0x85, 0x3c, 0xa4, 0xc5, 0xb4, 0x68, 0x5f, 0x77, 0x8a, 0x87, 0xed, 0x7f, 0xd7, 0x80, 0xb3, - 0x99, 0xb4, 0xe4, 0x3a, 0x40, 0x62, 0x23, 0x8a, 0x5e, 0xe2, 0x59, 0x94, 0x63, 0xa8, 0xa5, 0x60, - 0x90, 0xaf, 0xa6, 0xad, 0xbb, 0x93, 0x17, 0x27, 0xf9, 0xd6, 0xc8, 0x84, 0x6e, 0xdd, 0x65, 0xd8, - 0x74, 0xe6, 0x77, 0xf3, 0x30, 0xd5, 0xf3, 0x46, 0xe5, 0x09, 0x51, 0x04, 0xfb, 0xa9, 0x17, 0xd0, - 0xf8, 0x71, 0xc7, 0xb5, 0x7e, 0x2f, 0x64, 0x66, 0xbc, 0x87, 0x86, 0x6e, 0x31, 0x91, 0xc0, 0xfb, - 0x84, 0x67, 0xd1, 0xc2, 0xec, 0xb7, 0xf3, 0x5e, 0xed, 0x5b, 0xdb, 0x13, 0x78, 0x43, 0xef, 0x6f, - 0xf0, 0x13, 0x63, 0xbf, 0x96, 0x83, 0xe9, 0x9e, 0x6f, 0x7e, 0x6a, 0x67, 0xdd, 0x07, 0xda, 0xea, - 0xf6, 0x5c, 0xbf, 0x31, 0x1d, 0xc8, 0x8a, 0xf8, 0x5f, 0x06, 0x9c, 0xef, 0x43, 0x49, 0x0e, 0xd2, - 0x42, 0xc4, 0xad, 0x8a, 0x9b, 0xc7, 0x57, 0xf8, 0x44, 0x44, 0xe9, 0x53, 0x93, 0x84, 0x6f, 0xe4, - 0x00, 0xb6, 0xe8, 0xf6, 0xd3, 0x9d, 0x83, 0xea, 0x0b, 0x9a, 0x00, 0x28, 0x0e, 0xcc, 0xc1, 0x53, - 0x50, 0xad, 0xa2, 0x23, 0x71, 0xf0, 0x04, 0x54, 0xf1, 0x7b, 0x2a, 0xb9, 0xec, 0xf7, 0x54, 0xcc, - 0x6d, 0x98, 0xb9, 0x43, 0xa3, 0x64, 0x25, 0x94, 0x7b, 0xc8, 0xe3, 0xd9, 0xbe, 0x06, 0xa3, 0x02, - 0x5f, 0xcf, 0x8d, 0x2f, 0x43, 0xe2, 0x3c, 0xd7, 0x4a, 0x10, 0x4c, 0x0a, 0xe7, 0x17, 0x68, 0x93, - 0x46, 0xf4, 0xd3, 0xad, 0xa6, 0x0e, 0x84, 0x7f, 0x0a, 0x7f, 0x66, 0x63, 0xa0, 0x1a, 0x4e, 0xec, - 0x9f, 0x4d, 0x38, 0x1b, 0xb7, 0xfd, 0x49, 0xf2, 0xbd, 0xc1, 0x6c, 0x09, 0x71, 0x21, 0x32, 0xe1, - 0x78, 0x8c, 0x13, 0xf1, 0x11, 0x5c, 0x94, 0x04, 0x5b, 0x5e, 0x7c, 0x12, 0x33, 0x10, 0x2d, 0x79, - 0x07, 0xc6, 0x14, 0x1a, 0x71, 0xad, 0x1b, 0x4f, 0x3b, 0x1f, 0x7a, 0xd1, 0x9e, 0x1d, 0x72, 0xb8, - 0x7a, 0xda, 0xa9, 0xa0, 0x9b, 0x5f, 0x81, 0x67, 0xe2, 0xb8, 0x95, 0x8c, 0xaa, 0x53, 0xcc, 0x8d, - 0xd3, 0x31, 0x5f, 0x49, 0x3e, 0x6b, 0xa9, 0x1d, 0x47, 0xc0, 0x4b, 0xde, 0x44, 0xfd, 0x2c, 0xf1, - 0x31, 0x97, 0x94, 0xdc, 0x7c, 0x62, 0x2d, 0x4a, 0x00, 0xe6, 0xdb, 0x4a, 0x63, 0x33, 0x18, 0x6a, - 0xc4, 0x46, 0x9a, 0xf8, 0x1b, 0x39, 0x98, 0x5c, 0x5d, 0x5a, 0x98, 0x8f, 0xdd, 0xc8, 0x9f, 0xb1, - 0x04, 0x59, 0xda, 0xb7, 0xf5, 0xd7, 0x37, 0xe6, 0x06, 0x4c, 0xa7, 0xba, 0x01, 0x5f, 0x11, 0x7a, - 0x8f, 0xc7, 0x97, 0xc4, 0x60, 0xb9, 0xb2, 0x9c, 0xcb, 0x62, 0xbf, 0x79, 0xcb, 0x4a, 0x61, 0x9b, - 0xdf, 0x1d, 0x4e, 0xf1, 0x15, 0x2a, 0xec, 0x35, 0x18, 0x5d, 0x0a, 0xc3, 0x2e, 0x0d, 0x36, 0xac, - 0x65, 0xd5, 0x46, 0xf4, 0x10, 0x68, 0x77, 0x83, 0xa6, 0x95, 0x20, 0x90, 0x57, 0xa0, 0x28, 0x2e, - 0xe1, 0x49, 0x9d, 0x80, 0xc7, 0xe5, 0xf1, 0x1d, 0x3e, 0x2b, 0x2e, 0x26, 0x6f, 0x40, 0x89, 0xff, - 0xcf, 0xa5, 0x4d, 0x74, 0x38, 0xfa, 0xaa, 0x04, 0x3a, 0x97, 0x4e, 0x4b, 0x43, 0x63, 0x3b, 0x33, - 0xf9, 0x4c, 0x29, 0x6b, 0x51, 0x21, 0xd9, 0x99, 0xc9, 0x17, 0x4d, 0xb1, 0x4d, 0x2a, 0x12, 0xb9, - 0x06, 0xf9, 0xea, 0xbc, 0xa5, 0xa6, 0x03, 0x77, 0x1a, 0x01, 0x4f, 0xa7, 0xaf, 0xbd, 0x04, 0x56, - 0x9d, 0xb7, 0xc8, 0x1c, 0x14, 0xf1, 0xa5, 0x17, 0x97, 0x06, 0x22, 0xea, 0x15, 0xa5, 0xa6, 0x23, - 0x60, 0xea, 0xc9, 0xa3, 0xc4, 0x23, 0x37, 0x60, 0x64, 0xc1, 0x0b, 0x3b, 0x4d, 0xe7, 0x40, 0x64, - 0xc6, 0xc1, 0xc3, 0x10, 0x97, 0x83, 0x54, 0x39, 0x13, 0x58, 0xe4, 0x15, 0x18, 0xaa, 0x37, 0xfc, - 0x0e, 0xdb, 0x6d, 0xc5, 0xa1, 0x2d, 0x21, 0x03, 0x68, 0x79, 0x2f, 0x18, 0x00, 0xef, 0x85, 0xf3, - 0xeb, 0x6d, 0xa3, 0xca, 0xbd, 0xf0, 0xf4, 0xb5, 0x36, 0x81, 0xd3, 0x1b, 0x7c, 0x08, 0x4f, 0x32, - 0xf8, 0x70, 0x1b, 0xce, 0xdf, 0x41, 0x53, 0xbf, 0x4e, 0x03, 0x4c, 0x46, 0xca, 0x5f, 0x8d, 0xda, - 0xb0, 0x96, 0xc4, 0x95, 0x3e, 0xbc, 0x60, 0xc5, 0x77, 0x03, 0x76, 0xc8, 0x71, 0xe4, 0x83, 0x53, - 0xa9, 0xa7, 0x32, 0xfa, 0x31, 0x22, 0x5f, 0x82, 0x99, 0xac, 0x22, 0x71, 0xb9, 0x0f, 0xe3, 0xda, - 0xb3, 0x2b, 0x50, 0x03, 0xcb, 0xb3, 0x38, 0x90, 0x65, 0x28, 0x73, 0x78, 0xd5, 0x6d, 0x79, 0xed, - 0xc5, 0x96, 0xe3, 0x35, 0xf1, 0xaa, 0x9f, 0xb8, 0xaf, 0x29, 0xb8, 0x3a, 0xac, 0xd0, 0xa6, 0xac, - 0x54, 0x8b, 0x4e, 0x4a, 0x51, 0xa2, 0x3a, 0xaa, 0x57, 0xef, 0x2f, 0x27, 0x73, 0xea, 0xb3, 0x75, - 0x6e, 0xa4, 0x7d, 0xdb, 0x31, 0xe7, 0x46, 0x1b, 0x30, 0x9d, 0xea, 0x06, 0xa9, 0x8e, 0x34, 0x70, - 0x5a, 0x1d, 0xa5, 0x68, 0xac, 0x14, 0xb6, 0xf9, 0x5f, 0x87, 0x53, 0x7c, 0x85, 0xaf, 0xc8, 0x84, - 0x61, 0xae, 0x6d, 0xd4, 0xd4, 0x79, 0x5c, 0x17, 0x59, 0xa2, 0x84, 0x5c, 0x80, 0x7c, 0xbd, 0xbe, - 0xaa, 0x26, 0xf6, 0x0c, 0x43, 0xdf, 0x62, 0x30, 0x36, 0x42, 0xe8, 0x06, 0x52, 0xae, 0x98, 0x35, - 0x68, 0x10, 0x89, 0x77, 0x6c, 0x5f, 0x4a, 0xe6, 0x71, 0x21, 0xe9, 0x6f, 0x31, 0x8f, 0x93, 0xd9, - 0x3b, 0x0f, 0xb3, 0xd5, 0x30, 0xa4, 0x41, 0xc4, 0x5f, 0x23, 0x08, 0xbb, 0x2d, 0x1a, 0x08, 0x59, - 0x13, 0x3a, 0x86, 0xbf, 0x82, 0xdf, 0x08, 0xad, 0xbe, 0x88, 0xe4, 0x2a, 0x14, 0xab, 0x5d, 0xd7, - 0xa3, 0xed, 0x86, 0x16, 0x5d, 0xef, 0x08, 0x98, 0x15, 0x97, 0x92, 0x8f, 0xe0, 0xac, 0x20, 0x92, - 0x0a, 0x47, 0xf4, 0x00, 0xd7, 0x35, 0x7c, 0x07, 0x2b, 0xe6, 0x82, 0x54, 0x53, 0xb6, 0xe8, 0x92, - 0x6c, 0x4a, 0x52, 0x85, 0xf2, 0x22, 0x9e, 0x93, 0xca, 0xd7, 0xac, 0xfd, 0x40, 0x64, 0x9d, 0x46, - 0xcd, 0xc5, 0xcf, 0x50, 0x6d, 0x37, 0x2e, 0xb4, 0x7a, 0xd0, 0xc9, 0x3d, 0x98, 0x4e, 0xc3, 0x98, - 0x3e, 0x1e, 0x4d, 0x5e, 0x9b, 0xeb, 0xe1, 0x82, 0x8a, 0x39, 0x8b, 0x8a, 0x6c, 0xc3, 0x54, 0x35, - 0x8a, 0x02, 0x6f, 0xbb, 0x1b, 0xd1, 0x94, 0xea, 0x92, 0x8e, 0xc6, 0xb8, 0x5c, 0xaa, 0xaf, 0x67, - 0x84, 0x30, 0x4e, 0x3b, 0x31, 0x65, 0xac, 0xc2, 0xac, 0x5e, 0x76, 0xc4, 0x8d, 0x1f, 0xac, 0x14, - 0x8f, 0x3a, 0x8a, 0x2b, 0x51, 0xd2, 0xa1, 0x5b, 0x0d, 0x0f, 0x5a, 0x2d, 0x1a, 0x05, 0x78, 0x72, - 0x8f, 0x8f, 0x3e, 0x9a, 0x22, 0x06, 0xe8, 0xa2, 0xf2, 0x4e, 0x2b, 0x3e, 0xec, 0xa9, 0x85, 0x47, - 0x6a, 0x3c, 0xb5, 0xe5, 0xa3, 0x34, 0xe0, 0xf2, 0xd1, 0x84, 0xa9, 0xc5, 0x76, 0x23, 0x38, 0xc0, - 0xbb, 0x99, 0xb2, 0x71, 0xe3, 0x27, 0x34, 0x4e, 0xbe, 0xe8, 0x72, 0xc9, 0x91, 0x12, 0x96, 0xd5, - 0xbc, 0x5e, 0xc6, 0xe6, 0xdf, 0x82, 0x72, 0xba, 0x2f, 0x1f, 0xf3, 0x95, 0xee, 0xd3, 0x84, 0x66, - 0xb3, 0x91, 0x4e, 0x7f, 0x0b, 0xb9, 0xa1, 0x3d, 0xc5, 0x6c, 0x24, 0xa9, 0x03, 0x94, 0x47, 0x93, - 0xb5, 0x07, 0x98, 0xe5, 0x34, 0xce, 0x65, 0x4d, 0x63, 0xf3, 0x17, 0x73, 0x30, 0xc5, 0xa3, 0x49, - 0x9f, 0x7e, 0x5b, 0xf1, 0x3d, 0x4d, 0x39, 0x4b, 0x5f, 0x60, 0xea, 0xeb, 0x8e, 0xb1, 0x16, 0xbf, - 0x06, 0x67, 0x7b, 0xba, 0x02, 0x15, 0xf4, 0x82, 0x8c, 0xe3, 0xed, 0x51, 0xd1, 0xb3, 0xd9, 0x95, - 0x6c, 0xde, 0xb2, 0x7a, 0x28, 0xcc, 0x7f, 0x92, 0xeb, 0xe1, 0x2f, 0xec, 0x46, 0xd5, 0x12, 0x34, - 0x4e, 0x67, 0x09, 0xe6, 0x3e, 0x91, 0x25, 0x98, 0x1f, 0xc4, 0x12, 0xfc, 0x08, 0xc6, 0xd7, 0xa9, - 0xc3, 0x2c, 0x1a, 0x71, 0x5d, 0xae, 0xa0, 0x3d, 0x93, 0xcc, 0xca, 0xa4, 0x7e, 0x89, 0xaf, 0xda, - 0x46, 0x8c, 0x80, 0xa9, 0x16, 0x7e, 0x7f, 0xce, 0xd2, 0x39, 0xa8, 0x8b, 0xc6, 0x50, 0xff, 0x45, - 0xc3, 0x0c, 0x60, 0xac, 0x5e, 0x5f, 0xdd, 0x72, 0x02, 0xa6, 0x2d, 0x42, 0x66, 0x32, 0xca, 0x30, - 0x51, 0x23, 0x51, 0xbc, 0xbd, 0xf1, 0xa1, 0x12, 0x8b, 0x29, 0x16, 0x49, 0x2c, 0x42, 0x2a, 0x78, - 0x44, 0x9c, 0x80, 0x69, 0x11, 0x71, 0x02, 0x66, 0xfe, 0xe3, 0x02, 0x94, 0x79, 0xe8, 0x23, 0xdb, - 0xf7, 0x8a, 0xfc, 0x40, 0x3d, 0xef, 0x44, 0x18, 0xa7, 0x7f, 0x27, 0xe2, 0x13, 0xc4, 0xd8, 0x2a, - 0x77, 0xb1, 0xf3, 0x03, 0xdc, 0xc5, 0x7e, 0x4b, 0xbb, 0xc8, 0x5c, 0x48, 0x1e, 0x22, 0xdd, 0xef, - 0x6e, 0xd3, 0xe3, 0xaf, 0x30, 0xbf, 0xa9, 0xde, 0x38, 0x1e, 0x4a, 0xa2, 0x4f, 0x90, 0xf2, 0x98, - 0xbb, 0xc6, 0xb1, 0x16, 0x1b, 0x3e, 0x4d, 0xbc, 0xf9, 0xc8, 0xff, 0xd7, 0x78, 0xf3, 0x45, 0x00, - 0x25, 0x69, 0x4c, 0x31, 0x79, 0x8f, 0xf4, 0xe4, 0x84, 0x31, 0x0a, 0xa1, 0xf9, 0x9b, 0x13, 0x30, - 0x55, 0xaf, 0xaf, 0x2e, 0x78, 0xce, 0x6e, 0xdb, 0x0f, 0x23, 0xaf, 0xb1, 0xd4, 0xde, 0xf1, 0xd9, - 0x14, 0x5e, 0xa7, 0x61, 0x74, 0xbb, 0xe9, 0x3f, 0x54, 0x63, 0x9f, 0x23, 0x1a, 0x46, 0xf6, 0x4e, - 0xd3, 0x7f, 0x68, 0xc5, 0xc5, 0x6c, 0x89, 0x58, 0x0c, 0x82, 0xf8, 0xe9, 0x13, 0x5c, 0x22, 0x28, - 0x03, 0x58, 0x1c, 0xce, 0x66, 0x49, 0xbd, 0xcb, 0xb3, 0x7f, 0xf0, 0x4c, 0x73, 0x38, 0x4b, 0x42, - 0x0e, 0xb2, 0x64, 0x19, 0xa1, 0xbd, 0x02, 0x2b, 0xb4, 0xe6, 0x79, 0x2d, 0x6a, 0x3d, 0x29, 0x16, - 0x6f, 0xe8, 0x21, 0x14, 0x47, 0xd7, 0xee, 0x20, 0x5c, 0x35, 0xde, 0x7b, 0xe6, 0xc0, 0x01, 0x9c, - 0x65, 0xc6, 0xe5, 0xa9, 0x6d, 0x8e, 0x6b, 0x42, 0x27, 0x98, 0x78, 0x5f, 0x22, 0xc3, 0xf0, 0x50, - 0x9f, 0x47, 0xc8, 0xac, 0x81, 0xfc, 0xa2, 0x01, 0xcf, 0x66, 0x96, 0xc4, 0xb3, 0x7b, 0x4c, 0xbb, - 0x39, 0xa0, 0x28, 0x0d, 0xcc, 0x98, 0xf2, 0x6a, 0xbf, 0xaa, 0xed, 0x0c, 0x55, 0x70, 0x7c, 0x4d, - 0xe4, 0xdf, 0x1a, 0x70, 0x5e, 0xc3, 0xc0, 0x54, 0x8b, 0x2d, 0xda, 0x8e, 0xe4, 0xc3, 0xe1, 0x7d, - 0xe4, 0xfa, 0xe3, 0x27, 0x23, 0xd7, 0x2f, 0xe8, 0xdf, 0xc2, 0xd3, 0x51, 0x63, 0xf5, 0xea, 0x4e, - 0xb1, 0x4f, 0x0b, 0xc9, 0x4f, 0xc2, 0x14, 0x16, 0x49, 0xfb, 0x87, 0xc9, 0x2c, 0x9a, 0x4d, 0xa5, - 0xda, 0xdc, 0xf7, 0x0f, 0x2b, 0xe3, 0x5a, 0x01, 0x5e, 0x2b, 0xc4, 0xda, 0x62, 0x73, 0xc9, 0x6b, - 0xef, 0xf8, 0x5a, 0x6a, 0xd5, 0x34, 0x33, 0xf2, 0xef, 0x0d, 0x98, 0x65, 0x50, 0xde, 0xe0, 0xdb, - 0x81, 0xdf, 0x8a, 0xcb, 0x43, 0x71, 0xe3, 0xbc, 0x4f, 0x07, 0x35, 0x9f, 0x4c, 0x07, 0xbd, 0x84, - 0x4d, 0xe6, 0xb3, 0xdf, 0xde, 0x09, 0xfc, 0x56, 0xd2, 0x7c, 0x2d, 0x5b, 0x49, 0xbf, 0x46, 0x92, - 0x9f, 0x37, 0xe0, 0x82, 0xb6, 0x8d, 0x52, 0x2f, 0xe5, 0xcd, 0x4e, 0x6a, 0xce, 0x01, 0xb5, 0xa8, - 0x76, 0x5d, 0x48, 0xfa, 0x15, 0x6c, 0x41, 0xb2, 0x2e, 0x60, 0x5b, 0xec, 0x16, 0xc7, 0x52, 0x9a, - 0xd0, 0xbf, 0x16, 0xe2, 0xc1, 0x14, 0x3a, 0x96, 0x34, 0xbf, 0xc4, 0x4c, 0x7f, 0xbf, 0xc4, 0x15, - 0x51, 0xf5, 0x73, 0x78, 0xf1, 0xa9, 0xbf, 0x73, 0xa2, 0x97, 0x2b, 0xf9, 0x19, 0xb8, 0xd0, 0x03, - 0x8c, 0xe7, 0xd5, 0xd9, 0xbe, 0xf3, 0xea, 0xd5, 0xa3, 0xc3, 0xca, 0xcb, 0x59, 0xb5, 0x65, 0xcd, - 0xa9, 0xfe, 0x35, 0x90, 0x7b, 0x00, 0x49, 0xe1, 0xec, 0x39, 0x14, 0xc5, 0x57, 0x85, 0x24, 0x28, - 0x25, 0x4c, 0x3f, 0x2b, 0xb5, 0xa9, 0xcb, 0x58, 0x82, 0x44, 0x56, 0xa1, 0xa4, 0x5c, 0xef, 0x3a, - 0x98, 0x3d, 0xcf, 0xd9, 0x7d, 0xff, 0xb0, 0xa2, 0xc1, 0xd9, 0xee, 0x4f, 0xbd, 0x21, 0xa6, 0xfa, - 0x9b, 0x34, 0x44, 0xf2, 0x87, 0x06, 0xcc, 0x30, 0x40, 0x22, 0x28, 0xa2, 0xa1, 0xb3, 0xc7, 0x49, - 0xf2, 0xde, 0x93, 0x91, 0xe4, 0xe7, 0xb1, 0x8d, 0xaa, 0x24, 0xf7, 0x7c, 0x7c, 0x66, 0xe3, 0x50, - 0x82, 0x35, 0xbf, 0xa4, 0x26, 0xc1, 0x17, 0x06, 0x90, 0x60, 0xde, 0xd5, 0x27, 0x4b, 0x70, 0xdf, - 0x5a, 0xcc, 0x6f, 0xe6, 0x60, 0x4c, 0x31, 0x0d, 0xc9, 0xe7, 0xa1, 0xb4, 0x1a, 0xec, 0x3a, 0x6d, - 0xef, 0xa7, 0x1c, 0xe5, 0xe8, 0x1c, 0x4d, 0x4f, 0x5f, 0x81, 0x5b, 0x1a, 0x16, 0x86, 0x3c, 0x53, - 0xa7, 0xa5, 0x6e, 0x5a, 0x98, 0x69, 0x69, 0x21, 0xf4, 0x94, 0xe6, 0xd1, 0xfb, 0x19, 0xe6, 0xd1, - 0xa9, 0xf2, 0xbc, 0xbc, 0xd3, 0x6b, 0x24, 0x0d, 0x9e, 0x96, 0xc5, 0xfc, 0xe5, 0x1c, 0x94, 0xd7, - 0x83, 0x6e, 0x18, 0x51, 0x57, 0x1e, 0xfc, 0x7e, 0xb6, 0x1e, 0x8f, 0xd3, 0x3f, 0xee, 0x98, 0xd0, - 0xa6, 0xc2, 0xaf, 0xff, 0x76, 0x05, 0x9f, 0xf6, 0x4f, 0x77, 0x87, 0x7c, 0xda, 0x5f, 0x87, 0xa7, - 0x6f, 0x7d, 0xa6, 0xa9, 0xac, 0x34, 0xbe, 0xf9, 0xa7, 0xb9, 0x34, 0x6f, 0xe1, 0x09, 0x7b, 0x09, - 0x46, 0xf8, 0x5b, 0xbe, 0xf2, 0x62, 0x9a, 0x48, 0x8e, 0x8a, 0x20, 0x4b, 0x96, 0x9d, 0xe6, 0xfe, - 0x6f, 0x7c, 0x2e, 0x96, 0xcf, 0x3e, 0x17, 0x23, 0x6f, 0x42, 0x09, 0x63, 0x7d, 0xab, 0xae, 0x1b, - 0x30, 0x4b, 0xae, 0x90, 0xe4, 0x41, 0x7d, 0x48, 0xb7, 0x6d, 0x1e, 0x13, 0xec, 0xb8, 0x6e, 0x60, - 0x69, 0x78, 0x64, 0x1e, 0x66, 0xb4, 0xd0, 0x72, 0x49, 0x3f, 0x94, 0xec, 0xf4, 0x23, 0x2c, 0xe0, - 0xc4, 0x99, 0xc8, 0x98, 0x0a, 0xdc, 0x6f, 0x32, 0x53, 0x0c, 0x0d, 0x74, 0x3d, 0x87, 0xa4, 0x9c, - 0xf4, 0x32, 0xde, 0x84, 0x60, 0xfe, 0x94, 0x96, 0xd3, 0xd1, 0x52, 0x12, 0x71, 0x44, 0xf3, 0x2f, - 0x0d, 0x36, 0xd7, 0x1a, 0xfb, 0x9f, 0xb1, 0x9b, 0xc9, 0xec, 0x93, 0x8e, 0x71, 0xd4, 0xfe, 0x67, - 0x83, 0xdf, 0x2d, 0x14, 0xe2, 0xf3, 0x16, 0x0c, 0xf3, 0x97, 0x83, 0xc5, 0x2d, 0x38, 0x95, 0x0b, - 0x2f, 0x48, 0x62, 0x8b, 0xf8, 0xfb, 0xc3, 0x96, 0x20, 0x50, 0xf7, 0xae, 0xb9, 0x81, 0xf6, 0xae, - 0xca, 0xc3, 0x06, 0x83, 0x3d, 0x98, 0x63, 0x9c, 0xfc, 0xb0, 0x81, 0xf9, 0x7f, 0x73, 0xfc, 0x7b, - 0x44, 0xa3, 0x06, 0x4d, 0xa5, 0x7d, 0x05, 0x0a, 0x4c, 0x0e, 0xd4, 0x7c, 0xe5, 0x4c, 0x56, 0xb4, - 0x37, 0xd2, 0xfc, 0x26, 0xfa, 0xb4, 0x50, 0xd7, 0xaa, 0x97, 0xe1, 0x51, 0x1d, 0xab, 0xf3, 0x06, - 0x31, 0xf0, 0x39, 0x1a, 0xdf, 0xa5, 0xea, 0x74, 0x68, 0xeb, 0x2f, 0x07, 0x61, 0x39, 0xdb, 0x98, - 0xc6, 0x77, 0xd2, 0xd4, 0xc3, 0xa8, 0xd6, 0x8e, 0x63, 0xf3, 0xbb, 0x50, 0xaa, 0xb6, 0x4d, 0xae, - 0xaf, 0x2d, 0xc2, 0x84, 0x9e, 0x29, 0x47, 0x38, 0x8c, 0x31, 0xbb, 0x45, 0x2a, 0xcb, 0x8e, 0xea, - 0x9a, 0xd4, 0x89, 0xd8, 0xc6, 0x5f, 0x4b, 0x87, 0xa2, 0xbe, 0xe2, 0xc0, 0xd3, 0x2f, 0xda, 0xbd, - 0x79, 0xbc, 0x74, 0x12, 0x25, 0xd8, 0xe1, 0x73, 0x50, 0x16, 0x33, 0x33, 0xce, 0x4b, 0x80, 0x6e, - 0xb9, 0xa5, 0x05, 0x4b, 0x9d, 0x4d, 0x0d, 0xcf, 0x0d, 0x2c, 0x84, 0x9a, 0xdf, 0x31, 0xe0, 0x82, - 0x78, 0x11, 0xd9, 0xa2, 0x61, 0x14, 0x78, 0x3c, 0xcd, 0x01, 0xca, 0xe3, 0xe7, 0xc9, 0x3b, 0x32, - 0xb3, 0xab, 0xae, 0x20, 0xd3, 0x75, 0xd4, 0xc6, 0x85, 0x50, 0x0e, 0x61, 0x6e, 0x57, 0x99, 0xd1, - 0xf5, 0x2d, 0x91, 0xd1, 0x35, 0x77, 0x3c, 0x71, 0x3c, 0x2f, 0x5c, 0xda, 0x96, 0x99, 0x5c, 0xbf, - 0x9d, 0x83, 0xb3, 0x19, 0xcd, 0xda, 0xfc, 0xfc, 0x53, 0xaa, 0x1c, 0x6a, 0x9a, 0x72, 0x90, 0x29, - 0xbf, 0xfb, 0x76, 0x7c, 0xa6, 0xae, 0xf8, 0x4d, 0x03, 0xce, 0xeb, 0xd2, 0x23, 0xce, 0x11, 0x36, - 0x6f, 0x91, 0xb7, 0x61, 0xf8, 0x2e, 0x75, 0x5c, 0x2a, 0xaf, 0xcf, 0x9e, 0x4d, 0xbd, 0x73, 0xc0, - 0x0b, 0x39, 0xdb, 0x3f, 0xe5, 0x53, 0xf9, 0x8c, 0x25, 0x48, 0xc8, 0x82, 0x68, 0x1c, 0x0f, 0x2d, - 0x32, 0x65, 0x94, 0x4d, 0x56, 0x55, 0xc7, 0x38, 0x35, 0x7f, 0xd7, 0x80, 0x67, 0x8e, 0xa1, 0x61, - 0x03, 0xc7, 0x86, 0x5e, 0x1d, 0x38, 0x5c, 0x58, 0x10, 0x4a, 0xde, 0x83, 0xc9, 0x75, 0x61, 0xb2, - 0xca, 0xe1, 0x50, 0x9e, 0x87, 0x92, 0xd6, 0xac, 0x2d, 0xc7, 0x25, 0x8d, 0x4c, 0xae, 0x42, 0xf1, - 0xae, 0x1f, 0x46, 0xed, 0x24, 0x55, 0x21, 0x9e, 0xdc, 0xec, 0x09, 0x98, 0x15, 0x97, 0x32, 0xb3, - 0x40, 0x6f, 0xa6, 0x08, 0x65, 0x7d, 0x01, 0x86, 0x19, 0x4e, 0xec, 0x19, 0x45, 0x39, 0xc0, 0xf7, - 0x7a, 0x3d, 0xd7, 0x12, 0x45, 0xb1, 0x4f, 0x3e, 0x97, 0x19, 0x71, 0xf2, 0x4d, 0x03, 0xca, 0x3a, - 0xef, 0xc7, 0x1d, 0x9a, 0x77, 0xb5, 0xa1, 0x79, 0x26, 0x7b, 0x68, 0xfa, 0x8f, 0x49, 0x4f, 0xd6, - 0xb0, 0x81, 0xc6, 0xc2, 0x84, 0xe1, 0x05, 0xbf, 0xe5, 0x78, 0x6d, 0x35, 0xd3, 0x95, 0x8b, 0x10, - 0x4b, 0x94, 0x28, 0xbd, 0x95, 0xef, 0xdb, 0x5b, 0xe6, 0xaf, 0x14, 0xe0, 0x82, 0x45, 0x77, 0x3d, - 0x66, 0x20, 0x6d, 0x84, 0x5e, 0x7b, 0x57, 0x8b, 0x07, 0x32, 0x53, 0x1d, 0x2e, 0x6e, 0x41, 0x30, - 0x48, 0xdc, 0xdf, 0xaf, 0x40, 0x91, 0x69, 0x69, 0xa5, 0xcf, 0xd1, 0xdb, 0x85, 0xf9, 0x1a, 0xf9, - 0xb8, 0xca, 0x62, 0x72, 0x4d, 0xac, 0x21, 0xca, 0x3d, 0x35, 0xb6, 0x86, 0xfc, 0xe8, 0xb0, 0x02, - 0xfc, 0x7d, 0x16, 0x56, 0x2a, 0xd6, 0x91, 0xd8, 0xa8, 0x2a, 0xf4, 0x31, 0xaa, 0xee, 0xc3, 0x4c, - 0xd5, 0xe5, 0xfa, 0xc9, 0x69, 0xae, 0x05, 0x5e, 0xbb, 0xe1, 0x75, 0x9c, 0xa6, 0x34, 0xca, 0xd1, - 0xe7, 0xe9, 0xc4, 0xe5, 0x76, 0x27, 0x46, 0xb0, 0x32, 0xc9, 0xd8, 0x67, 0x2c, 0xac, 0xd4, 0x79, - 0x3a, 0x3e, 0xee, 0xc8, 0xc4, 0xcf, 0x70, 0xdb, 0x21, 0xcf, 0xc7, 0x67, 0xc5, 0xc5, 0x68, 0xce, - 0xe1, 0x55, 0xd5, 0xf5, 0xe5, 0xfa, 0x3d, 0x71, 0xf5, 0x53, 0x86, 0xd1, 0xf3, 0x9b, 0xad, 0x51, - 0x33, 0xc4, 0xb3, 0x17, 0x0d, 0x2f, 0xa1, 0xab, 0xd7, 0xef, 0x32, 0xba, 0x62, 0x0f, 0x5d, 0x18, - 0xee, 0xa9, 0x74, 0x1c, 0x8f, 0xdc, 0x00, 0xe0, 0x81, 0xc8, 0x28, 0x10, 0xa3, 0x89, 0xf1, 0x17, - 0x20, 0x94, 0x1b, 0x7f, 0x0a, 0x0a, 0x79, 0x07, 0xa6, 0x17, 0xe7, 0xe7, 0xe4, 0x06, 0x76, 0xc1, - 0x6f, 0x74, 0x5b, 0xb4, 0x1d, 0xe1, 0x1d, 0xe3, 0x12, 0x1f, 0x43, 0xda, 0x98, 0x63, 0x52, 0x90, - 0x85, 0x26, 0x6e, 0x76, 0xf2, 0xbc, 0x00, 0xf3, 0xbe, 0x4b, 0xc3, 0xcd, 0x9b, 0x9f, 0xb1, 0x9b, - 0x9d, 0xca, 0xb7, 0xe1, 0x6c, 0xbb, 0x99, 0x39, 0x33, 0xff, 0x3e, 0xde, 0xec, 0xec, 0xc1, 0x25, - 0x3f, 0x06, 0x43, 0xf8, 0x53, 0xac, 0xb8, 0xd3, 0x19, 0x6c, 0x93, 0xd5, 0xb6, 0xc1, 0x33, 0xab, - 0x21, 0x01, 0x59, 0x4a, 0x5e, 0xbf, 0x3a, 0xc5, 0xfd, 0x24, 0x91, 0x5c, 0x44, 0x7f, 0xf6, 0xd0, - 0x85, 0x92, 0x5a, 0x21, 0x93, 0x91, 0xbb, 0x4e, 0xb8, 0x47, 0xdd, 0x79, 0xf9, 0x58, 0x7a, 0x89, - 0xcb, 0xc8, 0x1e, 0x42, 0xf1, 0x49, 0x46, 0x4b, 0x41, 0x61, 0xda, 0x61, 0x29, 0xdc, 0x08, 0x45, - 0x53, 0xc4, 0x2e, 0xc8, 0xc3, 0xdd, 0xab, 0x6b, 0x89, 0x22, 0xd4, 0x96, 0xd2, 0xdd, 0x1d, 0x38, - 0x8d, 0x7d, 0x1a, 0x6c, 0xde, 0xfc, 0x34, 0xb4, 0xa5, 0x5e, 0xc7, 0x31, 0x63, 0xf2, 0x0d, 0x88, - 0x13, 0x03, 0x6a, 0xc8, 0xcc, 0x46, 0x4c, 0xa2, 0x2a, 0x8d, 0xc4, 0x46, 0x4c, 0xa2, 0x2a, 0x55, - 0x1b, 0x31, 0x46, 0x8d, 0x9f, 0xa6, 0xc8, 0x9d, 0xf0, 0x34, 0x45, 0x9f, 0x67, 0x78, 0xe4, 0x85, - 0x9c, 0xcf, 0xd0, 0xc3, 0x67, 0x5f, 0x84, 0x52, 0x35, 0x8a, 0x9c, 0xc6, 0x1e, 0x75, 0xf1, 0x09, - 0x14, 0x25, 0x98, 0xcb, 0x11, 0x70, 0xd5, 0x55, 0xa6, 0xe2, 0x2a, 0x0f, 0x1f, 0x8e, 0x0c, 0xf0, - 0xf0, 0xe1, 0x0d, 0x18, 0x59, 0x6a, 0x3f, 0xf0, 0x58, 0x9f, 0x14, 0x93, 0xc4, 0x5e, 0x1e, 0x07, - 0xe9, 0xaf, 0xe5, 0x21, 0x88, 0xbc, 0xa5, 0x58, 0x10, 0xa3, 0x89, 0x29, 0xcf, 0xb7, 0x59, 0xb6, - 0x34, 0x24, 0xd4, 0x53, 0x34, 0x89, 0x4e, 0xde, 0x84, 0x11, 0xb9, 0x7b, 0x86, 0xc4, 0x7c, 0x17, - 0x94, 0x0e, 0x2f, 0xd1, 0x72, 0x89, 0x89, 0xdd, 0xf3, 0x3b, 0xfa, 0xdd, 0xdf, 0x31, 0x25, 0xa7, - 0x8e, 0x72, 0xf7, 0x57, 0xcb, 0xa9, 0xa3, 0xdc, 0x02, 0x8e, 0x37, 0x43, 0xa5, 0x13, 0x37, 0x43, - 0x9b, 0x50, 0x5a, 0x73, 0x82, 0xc8, 0x63, 0xcb, 0x51, 0x3b, 0xe2, 0x49, 0x5d, 0x93, 0xbd, 0xba, - 0x52, 0x94, 0xbc, 0x86, 0xd5, 0x51, 0xf0, 0xf5, 0xa4, 0x24, 0x09, 0x9c, 0xac, 0x64, 0xdc, 0x0e, - 0x11, 0x59, 0xd6, 0xf1, 0x04, 0x48, 0x4d, 0xe9, 0xcd, 0x4b, 0x55, 0x57, 0x71, 0xef, 0xc5, 0x92, - 0x5b, 0x7c, 0x0c, 0x70, 0xcf, 0x38, 0x89, 0x6c, 0x30, 0x33, 0x1c, 0xda, 0x15, 0xa9, 0x8d, 0x63, - 0x8c, 0x48, 0xbe, 0x0a, 0x25, 0xf6, 0x3f, 0x66, 0xb8, 0xf4, 0x28, 0x4f, 0xda, 0x9a, 0xdc, 0x16, - 0xd0, 0x27, 0x34, 0x4f, 0x83, 0x59, 0xa7, 0x11, 0x9f, 0xc0, 0xc8, 0x38, 0xed, 0x78, 0xd1, 0xb8, - 0x91, 0xf7, 0xa1, 0xa4, 0x66, 0xc8, 0x9d, 0x9d, 0x4a, 0xe2, 0x7b, 0x5c, 0x01, 0x4f, 0x8f, 0x92, - 0x46, 0xc0, 0xd6, 0xaf, 0x6a, 0xa7, 0x83, 0xb4, 0x44, 0x91, 0xf6, 0x4e, 0x27, 0x4d, 0x26, 0xd1, - 0xc8, 0x07, 0x50, 0xaa, 0x76, 0x3a, 0x89, 0xc6, 0x99, 0x56, 0xb6, 0x84, 0x9d, 0x8e, 0x9d, 0xa9, - 0x75, 0x34, 0x0a, 0x26, 0x58, 0xc2, 0xe0, 0xc3, 0x7a, 0x67, 0x12, 0xc1, 0x92, 0x79, 0x5f, 0xd3, - 0x82, 0xa5, 0xa0, 0x9b, 0x3f, 0x34, 0xe0, 0x7c, 0x9f, 0x6e, 0x1b, 0xf8, 0x95, 0xd7, 0x1b, 0xc9, - 0x1a, 0xac, 0xb8, 0x23, 0xc4, 0x1a, 0xac, 0x7e, 0xb4, 0x5c, 0x8d, 0xb3, 0x33, 0xcc, 0xe6, 0x3f, - 0xb5, 0x0c, 0xb3, 0xe6, 0xa1, 0x01, 0x63, 0x8a, 0x30, 0x3f, 0xc1, 0x57, 0xd5, 0xae, 0x88, 0x54, - 0xeb, 0xf9, 0x04, 0xaf, 0x95, 0x72, 0x3d, 0x60, 0x6a, 0xf5, 0xaf, 0x01, 0x2c, 0x3b, 0x61, 0x54, - 0x6d, 0x44, 0xde, 0x03, 0x3a, 0x80, 0xe6, 0x4e, 0xf2, 0x4a, 0x39, 0xf8, 0x38, 0x03, 0x23, 0xeb, - 0xc9, 0x2b, 0x15, 0x33, 0x34, 0x57, 0x60, 0xb8, 0xee, 0x07, 0x51, 0xed, 0x80, 0x2f, 0xc7, 0x0b, - 0x34, 0x6c, 0xa8, 0x4e, 0x49, 0x0f, 0xdd, 0x13, 0x0d, 0x4b, 0x14, 0x31, 0x9b, 0xf8, 0xb6, 0x47, - 0x9b, 0xae, 0x7a, 0x5a, 0xbc, 0xc3, 0x00, 0x16, 0x87, 0x5f, 0x7b, 0x1f, 0x26, 0xa5, 0x60, 0xaf, - 0x2f, 0xd7, 0xf1, 0x0b, 0x26, 0x61, 0x6c, 0x73, 0xd1, 0x5a, 0xba, 0xfd, 0x65, 0xfb, 0xf6, 0xc6, - 0xf2, 0x72, 0xf9, 0x0c, 0x19, 0x87, 0x51, 0x01, 0x98, 0xaf, 0x96, 0x0d, 0x52, 0x82, 0xe2, 0xd2, - 0x4a, 0x7d, 0x71, 0x7e, 0xc3, 0x5a, 0x2c, 0xe7, 0xae, 0xbd, 0x04, 0x13, 0x49, 0xb8, 0x10, 0xa6, - 0x14, 0x19, 0x81, 0xbc, 0x55, 0xdd, 0x2a, 0x9f, 0x21, 0x00, 0xc3, 0x6b, 0xf7, 0xe6, 0xeb, 0x37, - 0x6f, 0x96, 0x8d, 0x6b, 0x9f, 0x83, 0x29, 0x74, 0x54, 0x2e, 0xb3, 0x7d, 0x43, 0x9b, 0x06, 0x58, - 0x53, 0x09, 0x8a, 0x75, 0xda, 0x71, 0x02, 0x27, 0xa2, 0xbc, 0x9a, 0xfb, 0xdd, 0x66, 0xe4, 0x75, - 0x9a, 0xf4, 0x51, 0xd9, 0xb8, 0xf6, 0x16, 0x4c, 0x5a, 0x7e, 0x37, 0xf2, 0xda, 0xbb, 0xf2, 0x59, - 0x0a, 0x72, 0x16, 0xa6, 0x36, 0x56, 0xaa, 0xf7, 0x6b, 0x4b, 0x77, 0x36, 0x56, 0x37, 0xea, 0xf6, - 0xfd, 0xea, 0xfa, 0xfc, 0xdd, 0xf2, 0x19, 0xd6, 0xe0, 0xfb, 0xab, 0xf5, 0x75, 0xdb, 0x5a, 0x9c, - 0x5f, 0x5c, 0x59, 0x2f, 0x1b, 0xd7, 0x7e, 0xc9, 0x80, 0x09, 0xfd, 0x05, 0x71, 0x72, 0x19, 0x2e, - 0x6d, 0xd4, 0x17, 0x2d, 0x7b, 0x7d, 0xf5, 0xde, 0xe2, 0x8a, 0xbd, 0x51, 0xaf, 0xde, 0x59, 0xb4, - 0x37, 0x56, 0xea, 0x6b, 0x8b, 0xf3, 0x4b, 0xb7, 0x97, 0x16, 0x17, 0xca, 0x67, 0x48, 0x05, 0x9e, - 0x51, 0x30, 0xac, 0xc5, 0xf9, 0xd5, 0xcd, 0x45, 0xcb, 0x5e, 0xab, 0xd6, 0xeb, 0x5b, 0xab, 0xd6, - 0x42, 0xd9, 0x20, 0x17, 0xe1, 0x5c, 0x06, 0xc2, 0xfd, 0xdb, 0xd5, 0x72, 0xae, 0xa7, 0x6c, 0x65, - 0x71, 0xab, 0xba, 0x6c, 0xd7, 0x56, 0xd7, 0xcb, 0xf9, 0x6b, 0xef, 0x33, 0xc3, 0x2b, 0x79, 0x7b, - 0x8f, 0x14, 0xa1, 0xb0, 0xb2, 0xba, 0xb2, 0x58, 0x3e, 0x43, 0xc6, 0x60, 0x64, 0x6d, 0x71, 0x65, - 0x61, 0x69, 0xe5, 0x0e, 0xef, 0xd6, 0xea, 0xda, 0x9a, 0xb5, 0xba, 0xb9, 0xb8, 0x50, 0xce, 0xb1, - 0xbe, 0x5b, 0x58, 0x5c, 0x61, 0x2d, 0xcb, 0x5f, 0x33, 0xf9, 0xb3, 0x2f, 0x5a, 0x4a, 0x7f, 0xd6, - 0x5b, 0x8b, 0x5f, 0x5a, 0x5f, 0x5c, 0xa9, 0x2f, 0xad, 0xae, 0x94, 0xcf, 0x5c, 0xbb, 0x94, 0xc2, - 0x91, 0x23, 0x51, 0xaf, 0xdf, 0x2d, 0x9f, 0xb9, 0xf6, 0x55, 0x28, 0xa9, 0x76, 0x07, 0x39, 0x0f, - 0xd3, 0xea, 0xef, 0x35, 0xda, 0x76, 0xbd, 0xf6, 0x6e, 0xf9, 0x4c, 0xba, 0xc0, 0xea, 0xb6, 0xdb, - 0xac, 0x00, 0x3f, 0x5e, 0x2d, 0x58, 0xa7, 0x41, 0xcb, 0x6b, 0x33, 0x93, 0xa2, 0x9c, 0xab, 0x95, - 0xbf, 0xf7, 0xe7, 0xcf, 0x9d, 0xf9, 0xde, 0x0f, 0x9e, 0x33, 0xfe, 0xf4, 0x07, 0xcf, 0x19, 0xff, - 0xf3, 0x07, 0xcf, 0x19, 0xdb, 0xc3, 0x28, 0xe8, 0xb7, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x8c, 0x17, 0x2b, 0x03, 0x96, 0xc5, 0x00, 0x00, + // 12841 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0xbd, 0x7f, 0x6c, 0x1c, 0x49, + 0x76, 0x18, 0xac, 0x9e, 0x19, 0x92, 0xc3, 0xc7, 0x21, 0x39, 0x2c, 0x52, 0x12, 0xa5, 0xd5, 0xee, + 0x68, 0x7b, 0x77, 0xb5, 0x5a, 0xed, 0xae, 0x74, 0xa2, 0x6e, 0x75, 0xde, 0xdb, 0x9f, 0x33, 0x24, + 0x25, 0x71, 0x45, 0x91, 0xdc, 0x1e, 0xfe, 0xb8, 0xf3, 0xdd, 0xb9, 0xdd, 0x9c, 0x2e, 0x92, 0xbd, + 0x9c, 0x99, 0x9e, 0xeb, 0xee, 0x91, 0x44, 0xfb, 0x33, 0x6c, 0xe3, 0xc3, 0x7d, 0x07, 0xc3, 0xf0, + 0x9d, 0xef, 0xc3, 0xf9, 0xb3, 0xfd, 0xc1, 0x81, 0x1d, 0x23, 0x4e, 0xe2, 0x04, 0x67, 0x04, 0x76, + 0x80, 0x24, 0x48, 0xe0, 0xc0, 0x40, 0x62, 0x1c, 0x82, 0x04, 0xf1, 0x7f, 0x81, 0x2f, 0x01, 0x13, + 0xdf, 0xf9, 0x2f, 0x02, 0x01, 0x02, 0xf8, 0x2f, 0x5f, 0x62, 0x20, 0xa8, 0x57, 0x55, 0xdd, 0x55, + 0x3d, 0x3d, 0xe4, 0x70, 0x57, 0x8b, 0x58, 0xfb, 0x17, 0x39, 0xaf, 0xde, 0x7b, 0x55, 0x5d, 0xf5, + 0xea, 0xd5, 0xab, 0x57, 0xaf, 0x5e, 0xc1, 0x58, 0x74, 0xd0, 0xa1, 0xe1, 0xf5, 0x4e, 0xe0, 0x47, + 0x3e, 0x19, 0xc2, 0x1f, 0x17, 0x67, 0x76, 0xfd, 0x5d, 0x1f, 0x21, 0x37, 0xd8, 0x7f, 0xbc, 0xf0, + 0x62, 0x65, 0xd7, 0xf7, 0x77, 0x9b, 0xf4, 0x06, 0xfe, 0xda, 0xee, 0xee, 0xdc, 0x88, 0xbc, 0x16, + 0x0d, 0x23, 0xa7, 0xd5, 0x11, 0x08, 0xf3, 0xbb, 0x5e, 0xb4, 0xd7, 0xdd, 0xbe, 0xde, 0xf0, 0x5b, + 0x37, 0x76, 0x03, 0xe7, 0xa1, 0x17, 0x39, 0x91, 0xe7, 0xb7, 0x9d, 0xe6, 0x8d, 0x88, 0x36, 0x69, + 0xc7, 0x0f, 0xa2, 0x1b, 0x4e, 0xc7, 0xbb, 0x81, 0x75, 0xdc, 0x78, 0x14, 0x38, 0x9d, 0x0e, 0x0d, + 0x92, 0x7f, 0x38, 0x13, 0xf3, 0xef, 0xe6, 0x61, 0xf4, 0x3e, 0xa5, 0x9d, 0x6a, 0xd3, 0x7b, 0x48, + 0xc9, 0x0b, 0x50, 0x58, 0x71, 0x5a, 0x74, 0xd6, 0xb8, 0x6c, 0x5c, 0x1d, 0xad, 0x4d, 0x1e, 0x1d, + 0x56, 0xc6, 0x42, 0x1a, 0x3c, 0xa4, 0x81, 0xdd, 0x76, 0x5a, 0xd4, 0xc2, 0x42, 0xf2, 0x2a, 0x8c, + 0xb2, 0xbf, 0x61, 0xc7, 0x69, 0xd0, 0xd9, 0x1c, 0x62, 0x8e, 0x1f, 0x1d, 0x56, 0x46, 0xdb, 0x12, + 0x68, 0x25, 0xe5, 0xe4, 0x0a, 0x8c, 0x2c, 0x53, 0x27, 0xa4, 0x4b, 0x0b, 0xb3, 0xf9, 0xcb, 0xc6, + 0xd5, 0x7c, 0xad, 0x74, 0x74, 0x58, 0x29, 0x36, 0x19, 0xc8, 0xf6, 0x5c, 0x4b, 0x16, 0x92, 0x25, + 0x18, 0x59, 0x7c, 0xdc, 0xf1, 0x02, 0x1a, 0xce, 0x16, 0x2e, 0x1b, 0x57, 0xc7, 0xe6, 0x2e, 0x5e, + 0xe7, 0xdf, 0x7f, 0x5d, 0x7e, 0xff, 0xf5, 0x75, 0xf9, 0xfd, 0xb5, 0xe9, 0xef, 0x1f, 0x56, 0xce, + 0x1c, 0x1d, 0x56, 0x46, 0x28, 0x27, 0xf9, 0xd5, 0xff, 0x5a, 0x31, 0x2c, 0x49, 0x4f, 0xde, 0x86, + 0xc2, 0xfa, 0x41, 0x87, 0xce, 0x8e, 0x5e, 0x36, 0xae, 0x4e, 0xcc, 0x3d, 0x77, 0x9d, 0xf7, 0x78, + 0xfc, 0x91, 0xc9, 0x7f, 0x0c, 0xab, 0x56, 0x3c, 0x3a, 0xac, 0x14, 0x18, 0x8a, 0x85, 0x54, 0xe4, + 0x75, 0x18, 0xbe, 0xe7, 0x87, 0xd1, 0xd2, 0xc2, 0x2c, 0xe0, 0xa7, 0x9d, 0x3d, 0x3a, 0xac, 0x4c, + 0xed, 0xf9, 0x61, 0x64, 0x7b, 0xee, 0x6b, 0x7e, 0xcb, 0x8b, 0x68, 0xab, 0x13, 0x1d, 0x58, 0x02, + 0xc9, 0xdc, 0x86, 0x71, 0x8d, 0x1f, 0x19, 0x83, 0x91, 0x8d, 0x95, 0xfb, 0x2b, 0xab, 0x5b, 0x2b, + 0xe5, 0x33, 0xa4, 0x08, 0x85, 0x95, 0xd5, 0x85, 0xc5, 0xb2, 0x41, 0x46, 0x20, 0x5f, 0x5d, 0x5b, + 0x2b, 0xe7, 0x48, 0x09, 0x8a, 0x0b, 0xd5, 0xf5, 0x6a, 0xad, 0x5a, 0x5f, 0x2c, 0xe7, 0xc9, 0x34, + 0x4c, 0x6e, 0x2d, 0xad, 0x2c, 0xac, 0x6e, 0xd5, 0xed, 0x85, 0xc5, 0xfa, 0xfd, 0xf5, 0xd5, 0xb5, + 0x72, 0x81, 0x4c, 0x00, 0xdc, 0xdf, 0xa8, 0x2d, 0x5a, 0x2b, 0x8b, 0xeb, 0x8b, 0xf5, 0xf2, 0x90, + 0xf9, 0xcd, 0x3c, 0x14, 0x1f, 0xd0, 0xc8, 0x71, 0x9d, 0xc8, 0x21, 0x97, 0xb4, 0x21, 0xc2, 0xd6, + 0x2b, 0x63, 0xf3, 0x42, 0xef, 0xd8, 0x0c, 0x1d, 0x1d, 0x56, 0x8c, 0xd7, 0xd5, 0x31, 0x79, 0x0b, + 0xc6, 0x16, 0x68, 0xd8, 0x08, 0xbc, 0x0e, 0x93, 0x17, 0x1c, 0x97, 0xd1, 0xda, 0x85, 0xa3, 0xc3, + 0xca, 0x59, 0x37, 0x01, 0x2b, 0xdf, 0xaa, 0x62, 0x93, 0x25, 0x18, 0x5e, 0x76, 0xb6, 0x69, 0x33, + 0x9c, 0x1d, 0xba, 0x9c, 0xbf, 0x3a, 0x36, 0xf7, 0x8c, 0xe8, 0x5f, 0xd9, 0xc0, 0xeb, 0xbc, 0x74, + 0xb1, 0x1d, 0x05, 0x07, 0xb5, 0x99, 0xa3, 0xc3, 0x4a, 0xb9, 0x89, 0x00, 0xb5, 0xef, 0x38, 0x0a, + 0xa9, 0x27, 0x63, 0x3e, 0x7c, 0xe2, 0x98, 0x3f, 0xfb, 0xfd, 0xc3, 0x8a, 0xc1, 0xc6, 0x42, 0x8c, + 0x79, 0xc2, 0x4f, 0x1f, 0xfd, 0xcb, 0x90, 0x5b, 0x5a, 0x98, 0x1d, 0x41, 0x59, 0x2b, 0x1f, 0x1d, + 0x56, 0x4a, 0xda, 0xb0, 0xe5, 0x96, 0x16, 0x2e, 0xbe, 0x09, 0x63, 0x4a, 0x1b, 0x49, 0x19, 0xf2, + 0xfb, 0xf4, 0x80, 0xf7, 0xa7, 0xc5, 0xfe, 0x25, 0x33, 0x30, 0xf4, 0xd0, 0x69, 0x76, 0x45, 0x07, + 0x5a, 0xfc, 0xc7, 0x17, 0x73, 0x3f, 0x61, 0x98, 0xff, 0x6f, 0x01, 0x8a, 0x96, 0xcf, 0xe7, 0x19, + 0x79, 0x05, 0x86, 0xea, 0x91, 0x13, 0xc9, 0xa1, 0x98, 0x3e, 0x3a, 0xac, 0x4c, 0x86, 0x0c, 0xa0, + 0xd4, 0xc7, 0x31, 0x18, 0xea, 0xda, 0x9e, 0x13, 0xca, 0x21, 0x41, 0xd4, 0x0e, 0x03, 0xa8, 0xa8, + 0x88, 0x41, 0xae, 0x40, 0xe1, 0x81, 0xef, 0x52, 0x31, 0x2a, 0xe4, 0xe8, 0xb0, 0x32, 0xd1, 0xf2, + 0x5d, 0x15, 0x11, 0xcb, 0xc9, 0x6b, 0x30, 0x3a, 0xdf, 0x0d, 0x02, 0xda, 0x66, 0xa2, 0x5a, 0x40, + 0xe4, 0x89, 0xa3, 0xc3, 0x0a, 0x34, 0x38, 0x90, 0x4d, 0xae, 0x04, 0x81, 0x75, 0x75, 0x3d, 0x72, + 0x82, 0x88, 0xba, 0xb3, 0x43, 0x03, 0x75, 0x35, 0x9b, 0x5e, 0x53, 0x21, 0x27, 0x49, 0x77, 0xb5, + 0xe0, 0x44, 0xee, 0xc1, 0xd8, 0xdd, 0xc0, 0x69, 0xd0, 0x35, 0x1a, 0x78, 0xbe, 0x8b, 0x63, 0x98, + 0xaf, 0x5d, 0x39, 0x3a, 0xac, 0x9c, 0xdb, 0x65, 0x60, 0xbb, 0x83, 0xf0, 0x84, 0xfa, 0xc7, 0x87, + 0x95, 0xe2, 0x42, 0x37, 0xc0, 0xde, 0xb3, 0x54, 0x52, 0xf2, 0xd3, 0x6c, 0x48, 0xc2, 0x08, 0xbb, + 0x96, 0xba, 0x38, 0x7a, 0xc7, 0x37, 0xd1, 0x14, 0x4d, 0x3c, 0xd7, 0x74, 0xc2, 0xc8, 0x0e, 0x38, + 0x5d, 0xaa, 0x9d, 0x2a, 0x4b, 0xb2, 0x0a, 0xc5, 0x7a, 0x63, 0x8f, 0xba, 0xdd, 0x26, 0x9d, 0x2d, + 0x22, 0xfb, 0xf3, 0x42, 0x70, 0xe5, 0x78, 0xca, 0xe2, 0xda, 0x45, 0xc1, 0x9b, 0x84, 0x02, 0xa2, + 0xf4, 0x7d, 0xcc, 0xe4, 0x8b, 0xc5, 0xdf, 0xf8, 0x9d, 0xca, 0x99, 0x5f, 0xf8, 0x2f, 0x97, 0xcf, + 0x98, 0xff, 0x2c, 0x07, 0xe5, 0x34, 0x13, 0xb2, 0x03, 0xe3, 0x1b, 0x1d, 0xd7, 0x89, 0xe8, 0x7c, + 0xd3, 0xa3, 0xed, 0x28, 0x44, 0x21, 0x39, 0xfe, 0x9b, 0x5e, 0x14, 0xf5, 0xce, 0x76, 0x91, 0xd0, + 0x6e, 0x70, 0xca, 0xd4, 0x57, 0xe9, 0x6c, 0x93, 0x7a, 0xea, 0xa8, 0xa7, 0x43, 0x94, 0xb0, 0xd3, + 0xd5, 0xc3, 0x35, 0x7c, 0x9f, 0x7a, 0x04, 0x5b, 0x21, 0x40, 0x6d, 0x77, 0xfb, 0x00, 0x25, 0x73, + 0x70, 0x01, 0x62, 0x24, 0x19, 0x02, 0xc4, 0xc0, 0xe6, 0x5f, 0x1a, 0x30, 0x61, 0xd1, 0xd0, 0xef, + 0x06, 0x0d, 0x7a, 0x8f, 0x3a, 0x2e, 0x0d, 0x98, 0xf8, 0xdf, 0xf7, 0xda, 0xae, 0x98, 0x53, 0x28, + 0xfe, 0xfb, 0x5e, 0x5b, 0x9d, 0xc2, 0x58, 0x4e, 0x3e, 0x07, 0x23, 0xf5, 0xee, 0x36, 0xa2, 0xf2, + 0x39, 0x75, 0x0e, 0x47, 0xac, 0xbb, 0x6d, 0xa7, 0xd0, 0x25, 0x1a, 0xb9, 0x01, 0x23, 0x9b, 0x34, + 0x08, 0x13, 0x8d, 0x87, 0x9a, 0xfd, 0x21, 0x07, 0xa9, 0x04, 0x02, 0x8b, 0xdc, 0x4d, 0xb4, 0xae, + 0x58, 0x93, 0x26, 0x53, 0xba, 0x2e, 0x11, 0x95, 0x96, 0x80, 0xa8, 0xa2, 0x22, 0xb1, 0xcc, 0xef, + 0xe4, 0xa0, 0xbc, 0xe0, 0x44, 0xce, 0xb6, 0x13, 0x8a, 0xfe, 0xdc, 0xbc, 0xc5, 0xf4, 0xb8, 0xf2, + 0xa1, 0xa8, 0xc7, 0x59, 0xcb, 0x3f, 0xf6, 0xe7, 0xbd, 0x94, 0xfe, 0xbc, 0x31, 0xb6, 0x40, 0x8a, + 0xcf, 0x4b, 0x3e, 0xea, 0x9d, 0x93, 0x3f, 0xaa, 0x2c, 0x3e, 0xaa, 0x28, 0x3f, 0x2a, 0xf9, 0x14, + 0xf2, 0x0e, 0x14, 0xea, 0x1d, 0xda, 0x10, 0x4a, 0x44, 0xea, 0x7e, 0xfd, 0xe3, 0x18, 0xc2, 0xe6, + 0xad, 0x5a, 0x49, 0xb0, 0x29, 0x84, 0x1d, 0xda, 0xb0, 0x90, 0x4c, 0x99, 0x34, 0xdf, 0x1d, 0x86, + 0x99, 0x2c, 0x32, 0xf2, 0x8e, 0xbe, 0x38, 0xf1, 0xee, 0x79, 0xa6, 0xef, 0xe2, 0x34, 0x6b, 0xe8, + 0xcb, 0xd3, 0x35, 0x28, 0xae, 0x31, 0x81, 0x6c, 0xf8, 0x4d, 0xd1, 0x73, 0x4c, 0x2b, 0x16, 0x3b, + 0x12, 0x66, 0x58, 0x71, 0x39, 0x79, 0x06, 0xf2, 0x1b, 0xd6, 0x92, 0xe8, 0xae, 0xd1, 0xa3, 0xc3, + 0x4a, 0xbe, 0x1b, 0x78, 0xb3, 0x86, 0xc5, 0xa0, 0xe4, 0x06, 0x0c, 0xcf, 0x57, 0xe7, 0x69, 0x10, + 0x61, 0x37, 0x95, 0x6a, 0xe7, 0x99, 0xb4, 0x34, 0x1c, 0xbb, 0x41, 0x83, 0x48, 0xab, 0x5e, 0xa0, + 0x91, 0x57, 0x21, 0x5f, 0xdd, 0xaa, 0x8b, 0x9e, 0x01, 0xd1, 0x33, 0xd5, 0xad, 0x7a, 0x6d, 0x5c, + 0x74, 0x44, 0xde, 0x79, 0x14, 0x32, 0xee, 0xd5, 0xad, 0xba, 0x3a, 0x5a, 0xc3, 0xc7, 0x8c, 0xd6, + 0x55, 0x28, 0x32, 0x3b, 0x83, 0x2d, 0xf0, 0xa8, 0x14, 0x47, 0xb9, 0xf9, 0xb4, 0x27, 0x60, 0x56, + 0x5c, 0x4a, 0x5e, 0x88, 0xcd, 0x96, 0x62, 0xc2, 0x4f, 0x98, 0x2d, 0xd2, 0x58, 0x21, 0x8f, 0x61, + 0x7c, 0xe1, 0xa0, 0xed, 0xb4, 0xbc, 0x86, 0x58, 0xc2, 0x47, 0x71, 0x09, 0xbf, 0x7e, 0xcc, 0x30, + 0x5e, 0xd7, 0x08, 0xf8, 0xaa, 0x2e, 0x95, 0xef, 0xac, 0xcb, 0xcb, 0xec, 0xf4, 0x0a, 0x3f, 0x6b, + 0x58, 0x7a, 0x45, 0x6c, 0x2e, 0x49, 0x15, 0x89, 0x76, 0x55, 0x22, 0x76, 0x12, 0x9c, 0xcc, 0xa5, + 0x40, 0x40, 0xd4, 0xb9, 0x14, 0x2f, 0xba, 0xef, 0x40, 0xfe, 0xee, 0xfc, 0xda, 0xec, 0x18, 0xf2, + 0x20, 0x82, 0xc7, 0xdd, 0xf9, 0xb5, 0xf9, 0xa6, 0xdf, 0x75, 0xeb, 0x1f, 0x2e, 0xd7, 0xce, 0x0b, + 0x36, 0xe3, 0xbb, 0x8d, 0x8e, 0xd6, 0x22, 0x46, 0x47, 0x16, 0xa1, 0x28, 0xbf, 0x72, 0xb6, 0x84, + 0x3c, 0xa6, 0x52, 0x1f, 0xbf, 0x79, 0x8b, 0xcf, 0x35, 0x57, 0xfc, 0x56, 0x5b, 0x21, 0x71, 0x2e, + 0x6e, 0x01, 0xe9, 0xed, 0x97, 0x0c, 0x4b, 0xe2, 0x55, 0xd5, 0x92, 0x18, 0x9b, 0x3b, 0x2b, 0xea, + 0x9a, 0xf7, 0x5b, 0x2d, 0xa7, 0xed, 0x22, 0xed, 0xe6, 0x9c, 0x6a, 0x60, 0x54, 0x61, 0x22, 0x69, + 0xc8, 0xb2, 0x17, 0x46, 0xe4, 0x06, 0x8c, 0x4a, 0x08, 0x5b, 0x44, 0xf2, 0x99, 0x4d, 0xb6, 0x12, + 0x1c, 0xf3, 0x4f, 0x73, 0x00, 0x49, 0xc9, 0x53, 0xaa, 0x67, 0xbe, 0xa0, 0xe9, 0x99, 0xb3, 0x69, + 0x01, 0xed, 0xab, 0x61, 0xc8, 0x7b, 0x30, 0xcc, 0x4c, 0xae, 0xae, 0x34, 0x29, 0xcf, 0xa7, 0x49, + 0xb1, 0x70, 0xf3, 0x56, 0x6d, 0x42, 0x10, 0x0f, 0x87, 0x08, 0xb1, 0x04, 0x99, 0xa2, 0xa2, 0xfe, + 0x70, 0x28, 0x19, 0x0c, 0xa1, 0x9c, 0xae, 0x2a, 0xda, 0xc5, 0x48, 0xe6, 0xa3, 0xd4, 0x2e, 0x8a, + 0x6e, 0xb9, 0xc0, 0x75, 0x0b, 0xef, 0xd4, 0x11, 0xa1, 0x5b, 0xd2, 0x9a, 0x85, 0x77, 0xe0, 0x89, + 0x9a, 0xa5, 0x93, 0x9e, 0xb6, 0x05, 0x14, 0x83, 0xab, 0x99, 0xbd, 0x92, 0x35, 0x61, 0x2f, 0x9f, + 0x34, 0x61, 0xd3, 0xd3, 0xf5, 0x56, 0x3f, 0x5d, 0x76, 0x56, 0xce, 0x2e, 0xe7, 0x91, 0x4a, 0x8e, + 0x3a, 0xed, 0x2d, 0x3e, 0x35, 0x87, 0xfb, 0x4e, 0xcd, 0xb3, 0x99, 0x53, 0x93, 0x4f, 0xcc, 0xb7, + 0x60, 0xa8, 0xfa, 0x33, 0xdd, 0x80, 0x0a, 0xdb, 0xaf, 0x24, 0xeb, 0x64, 0xb0, 0x78, 0x4e, 0x4f, + 0x3a, 0xec, 0xa7, 0x6a, 0x33, 0x63, 0x39, 0xab, 0x79, 0x7d, 0xb9, 0x2e, 0xec, 0x3a, 0x92, 0xea, + 0x96, 0xf5, 0x65, 0xa5, 0xd9, 0x91, 0xf6, 0xd5, 0x8c, 0x8a, 0xdc, 0x80, 0x5c, 0x75, 0x01, 0x37, + 0x8b, 0x63, 0x73, 0xa3, 0xb2, 0xda, 0x85, 0xda, 0x8c, 0x20, 0x29, 0x39, 0xda, 0xfe, 0xa1, 0xba, + 0x40, 0x6a, 0x30, 0xf4, 0xe0, 0xa0, 0xfe, 0xe1, 0xb2, 0x50, 0x64, 0xd3, 0x52, 0xae, 0x19, 0x6c, + 0x15, 0x57, 0xa1, 0x30, 0x69, 0x71, 0xeb, 0x20, 0xfc, 0x7a, 0x53, 0x6d, 0x31, 0xa2, 0x7d, 0x7a, + 0x0a, 0xe4, 0x9f, 0x18, 0x8a, 0xad, 0x21, 0x64, 0x9d, 0xed, 0x69, 0x85, 0xc4, 0x19, 0x89, 0xe5, + 0xd3, 0x23, 0x71, 0xb1, 0xbc, 0xbd, 0xc2, 0x47, 0x3f, 0xd7, 0x33, 0xfa, 0x63, 0xca, 0x4a, 0xc6, + 0xc7, 0x3c, 0xee, 0x8b, 0xfc, 0xc7, 0xee, 0x0b, 0xf3, 0x8f, 0x73, 0x58, 0x1f, 0x79, 0x0d, 0x86, + 0x2d, 0xba, 0x9b, 0x2c, 0xfa, 0xb8, 0x79, 0x0c, 0x10, 0xa2, 0x36, 0x92, 0xe3, 0xe0, 0x8a, 0x42, + 0xdd, 0x70, 0xcf, 0xdb, 0x89, 0x44, 0x4b, 0xe3, 0x15, 0x45, 0x80, 0x95, 0x15, 0x45, 0x40, 0xb4, + 0x15, 0x45, 0xc0, 0x98, 0xac, 0x5b, 0x0b, 0x75, 0xf1, 0x01, 0xf2, 0x6b, 0xad, 0x05, 0x45, 0x68, + 0x02, 0x57, 0x13, 0x1a, 0x6b, 0xa1, 0x4e, 0x6e, 0xc3, 0x68, 0xb5, 0xd1, 0xf0, 0xbb, 0xca, 0xee, + 0x6b, 0xf6, 0xe8, 0xb0, 0x32, 0xe3, 0x70, 0xa0, 0xee, 0x2b, 0x48, 0x50, 0x49, 0x1d, 0xc6, 0x16, + 0xd9, 0x96, 0xc5, 0x9b, 0x77, 0x1a, 0x7b, 0x54, 0x4c, 0x30, 0x29, 0xb1, 0x4a, 0x49, 0x6c, 0x42, + 0x9f, 0xa5, 0x08, 0x6c, 0x30, 0xa0, 0xba, 0x25, 0x57, 0x70, 0xcd, 0x5a, 0xd2, 0x15, 0xac, 0x61, + 0xf3, 0xcd, 0x6e, 0x18, 0xd1, 0x60, 0x69, 0x41, 0xf4, 0x23, 0x36, 0xac, 0xc1, 0x81, 0xa9, 0x86, + 0xc5, 0xa8, 0xe6, 0x7f, 0x36, 0xb0, 0x1b, 0xc8, 0x9b, 0x00, 0x4b, 0x6d, 0x66, 0xb6, 0x37, 0x68, + 0xcc, 0x00, 0x5d, 0x03, 0x9e, 0x80, 0xea, 0x1c, 0x14, 0x64, 0xbd, 0xea, 0xdc, 0xc0, 0x55, 0xb3, + 0x2a, 0xe5, 0x26, 0x40, 0x78, 0x89, 0x44, 0x95, 0x81, 0x80, 0xa6, 0xaa, 0x4c, 0x90, 0xc9, 0x15, + 0x18, 0x59, 0xaa, 0x3e, 0xa8, 0x76, 0xa3, 0x3d, 0x1c, 0x84, 0x22, 0x57, 0xc7, 0x9e, 0xd3, 0xb2, + 0x9d, 0x6e, 0xb4, 0x67, 0xc9, 0x42, 0xf3, 0xdf, 0xe5, 0xb4, 0x7e, 0x27, 0x16, 0x10, 0x8b, 0x76, + 0x9a, 0x5e, 0x03, 0x8d, 0x8a, 0xbb, 0x81, 0xdf, 0xed, 0xc4, 0x5f, 0x6b, 0x1e, 0x1d, 0x56, 0x9e, + 0x0b, 0x92, 0x52, 0x7b, 0x97, 0x15, 0xeb, 0x6d, 0xc8, 0xa0, 0x26, 0xef, 0x43, 0x69, 0x23, 0xa4, + 0x81, 0xf8, 0xc9, 0x36, 0x62, 0xf9, 0xab, 0xa3, 0xb5, 0x4b, 0xb8, 0xd1, 0x0a, 0x69, 0x10, 0xb3, + 0x51, 0x65, 0x49, 0xa3, 0x20, 0x2e, 0xcc, 0xae, 0x07, 0x4e, 0x3b, 0xf4, 0xa2, 0xc5, 0x76, 0x23, + 0x38, 0xc0, 0xe9, 0xb3, 0xd8, 0x76, 0xb6, 0x9b, 0xd4, 0xc5, 0x6e, 0x29, 0xd6, 0xae, 0x1e, 0x1d, + 0x56, 0x5e, 0x8c, 0x38, 0x8e, 0x4d, 0x63, 0x24, 0x9b, 0x72, 0x2c, 0x85, 0x73, 0x5f, 0x4e, 0xe4, + 0x3d, 0x28, 0x2d, 0xb6, 0xdd, 0x8e, 0xef, 0xb5, 0x23, 0x74, 0x93, 0x15, 0x62, 0x0b, 0xfb, 0x3c, + 0x15, 0x70, 0x9b, 0xc9, 0xa3, 0xda, 0x4c, 0x95, 0xc0, 0xfc, 0x05, 0x03, 0xc6, 0x14, 0xb5, 0xce, + 0xc6, 0x7d, 0x2d, 0xf0, 0x3f, 0xa2, 0x8d, 0x48, 0x17, 0xb9, 0x0e, 0x07, 0xa6, 0xc6, 0x3d, 0x46, + 0x4d, 0x89, 0x5a, 0xee, 0x14, 0xa2, 0x66, 0xde, 0x10, 0xab, 0x05, 0xdb, 0x2e, 0x2a, 0xde, 0x30, + 0xdc, 0x2e, 0x32, 0x73, 0x58, 0xdd, 0x2e, 0xb2, 0x72, 0xf3, 0xf7, 0x0d, 0xa6, 0xe5, 0xc9, 0x0d, + 0x80, 0xfb, 0xf4, 0x20, 0x72, 0xb6, 0xef, 0x78, 0x4d, 0xcd, 0xcb, 0xb9, 0x8f, 0x50, 0x7b, 0xc7, + 0x6b, 0x52, 0x4b, 0x41, 0x21, 0xb7, 0xa0, 0x78, 0x3f, 0xd8, 0x7e, 0x03, 0xd1, 0x73, 0xf1, 0x6a, + 0x3d, 0xbd, 0x1f, 0x6c, 0xbf, 0x81, 0xc8, 0xaa, 0x46, 0x91, 0x88, 0xc4, 0x84, 0xe1, 0x05, 0xbf, + 0xe5, 0x78, 0xd2, 0x42, 0x02, 0x66, 0x66, 0xb8, 0x08, 0xb1, 0x44, 0x09, 0xb3, 0x0f, 0xea, 0x6b, + 0x2b, 0xa2, 0xf3, 0xd1, 0x3e, 0x08, 0x3b, 0x6d, 0x8b, 0xc1, 0xcc, 0xef, 0x19, 0x30, 0xa6, 0x2c, + 0x5e, 0xe4, 0xf3, 0xc2, 0x23, 0x64, 0xa0, 0x3f, 0xf3, 0x5c, 0xef, 0xf2, 0xc6, 0x4a, 0xb9, 0x65, + 0xd7, 0xf2, 0x5d, 0x2a, 0xfc, 0x43, 0x89, 0xce, 0xcf, 0x0d, 0xa2, 0xf3, 0xdf, 0x04, 0xe0, 0x66, + 0x3f, 0x76, 0xa7, 0x32, 0x09, 0x15, 0xff, 0xaf, 0x3a, 0x18, 0x09, 0xb2, 0x69, 0x41, 0x49, 0xd5, + 0xf7, 0xa4, 0x06, 0xe3, 0x62, 0x97, 0x2b, 0xec, 0x44, 0xde, 0xcf, 0x38, 0x13, 0x04, 0xb7, 0xde, + 0x5d, 0xb7, 0x4e, 0x62, 0xfe, 0x62, 0x0e, 0x8a, 0x02, 0x32, 0xf7, 0x94, 0x9a, 0xb0, 0x6f, 0x68, + 0x26, 0xac, 0x5c, 0x19, 0x95, 0xbd, 0xd5, 0xdc, 0x09, 0x5b, 0xe4, 0x37, 0xa1, 0x24, 0xbb, 0x00, + 0x77, 0x02, 0xaf, 0xc0, 0x88, 0x74, 0xf2, 0xf0, 0x7d, 0xc0, 0xa4, 0xc6, 0x73, 0x73, 0xce, 0x92, + 0xe5, 0xe6, 0x77, 0x86, 0x24, 0x2d, 0xaf, 0x89, 0x75, 0x61, 0xd5, 0x75, 0x03, 0xb5, 0x0b, 0x1d, + 0xd7, 0x0d, 0x2c, 0x84, 0xb2, 0xc1, 0x5f, 0xeb, 0x6e, 0x37, 0xbd, 0x06, 0xe2, 0x28, 0x33, 0xb1, + 0x83, 0x50, 0x9b, 0xa1, 0xaa, 0x83, 0x9f, 0x20, 0x6b, 0x3b, 0xd4, 0xfc, 0xb1, 0x3b, 0xd4, 0x9f, + 0x82, 0xd1, 0xf9, 0x96, 0xab, 0x59, 0xb0, 0x66, 0x46, 0xa7, 0x5c, 0x8f, 0x91, 0xb8, 0xed, 0x7a, + 0x49, 0xf4, 0xd1, 0x4c, 0xa3, 0xe5, 0xf6, 0xda, 0xad, 0x09, 0x4b, 0x6d, 0x8b, 0x39, 0xf4, 0x49, + 0xb6, 0x98, 0xb7, 0x61, 0x74, 0x23, 0xa4, 0xeb, 0xdd, 0x76, 0x9b, 0x36, 0xd1, 0x9a, 0x2d, 0x72, + 0x7d, 0xd6, 0x0d, 0xa9, 0x1d, 0x21, 0x54, 0x6d, 0x40, 0x8c, 0xaa, 0x8a, 0xd5, 0xc8, 0x31, 0x62, + 0xf5, 0x79, 0x28, 0x54, 0x3b, 0x1d, 0xb9, 0xf7, 0x8e, 0xcd, 0xab, 0x4e, 0x07, 0x0d, 0x9e, 0x09, + 0xa7, 0xd3, 0xd1, 0x77, 0xd2, 0x88, 0x4d, 0x28, 0x90, 0xfb, 0xdd, 0x6d, 0x1a, 0xb4, 0x69, 0x44, + 0x43, 0xb1, 0x76, 0x86, 0xb3, 0x80, 0x3c, 0x66, 0xe5, 0x11, 0x47, 0x1a, 0x81, 0x6b, 0xf5, 0xfd, + 0xee, 0x36, 0xb5, 0xc5, 0x22, 0xac, 0xf6, 0x5d, 0x06, 0xc3, 0x8b, 0x75, 0x98, 0xd0, 0xfb, 0xff, + 0x09, 0xd8, 0xa4, 0x1f, 0x14, 0x8a, 0xc5, 0xf2, 0xa8, 0xf9, 0xcd, 0x1c, 0x8c, 0x55, 0x3b, 0x9d, + 0xa7, 0xdc, 0x01, 0xf6, 0x13, 0xda, 0xac, 0x3e, 0x97, 0x8c, 0xde, 0x29, 0x7c, 0x5f, 0x7f, 0x6d, + 0xc0, 0x64, 0x8a, 0x42, 0x6d, 0xbd, 0x31, 0xa0, 0x43, 0x28, 0x37, 0xa0, 0x43, 0x28, 0xdf, 0xdf, + 0x21, 0xa4, 0xce, 0x99, 0xc2, 0x27, 0x99, 0x33, 0x2f, 0x43, 0xbe, 0xda, 0xe9, 0x88, 0x5e, 0x29, + 0x25, 0xbd, 0xb2, 0x79, 0x8b, 0x2f, 0x6e, 0x4e, 0xa7, 0x63, 0x31, 0x0c, 0xf3, 0x75, 0x18, 0x45, + 0x30, 0x6a, 0xb4, 0xcb, 0x62, 0x2a, 0x70, 0x75, 0xa6, 0x91, 0x71, 0xb1, 0x37, 0xff, 0xa7, 0x01, + 0x43, 0xf8, 0xfb, 0x29, 0x15, 0x97, 0x39, 0x4d, 0x5c, 0xca, 0x8a, 0xb8, 0x0c, 0x22, 0x28, 0x7f, + 0x98, 0xc7, 0xde, 0x12, 0x22, 0x22, 0x5c, 0x0a, 0x46, 0x86, 0x4b, 0xe1, 0x13, 0x28, 0xf0, 0xfd, + 0xb4, 0x73, 0x21, 0x8f, 0x83, 0xf1, 0x42, 0xba, 0xa9, 0x4f, 0xc4, 0xaf, 0x70, 0x0f, 0xc8, 0x52, + 0x3b, 0xa4, 0x8d, 0x6e, 0x40, 0xeb, 0xfb, 0x5e, 0x67, 0x93, 0x06, 0xde, 0xce, 0x81, 0x30, 0xdd, + 0x51, 0xc7, 0x7a, 0xa2, 0xd4, 0x0e, 0xf7, 0xbd, 0x0e, 0x33, 0x13, 0xbc, 0x9d, 0x03, 0x2b, 0x83, + 0x86, 0xbc, 0x07, 0x23, 0x16, 0x7d, 0x14, 0x78, 0x91, 0xdc, 0x44, 0x4d, 0xc4, 0xbb, 0x3f, 0x84, + 0x72, 0x7b, 0x27, 0xe0, 0x3f, 0xd4, 0xf1, 0x17, 0xe5, 0x9f, 0xde, 0x0e, 0xfc, 0xbb, 0x43, 0x38, + 0x17, 0x4e, 0x38, 0xa8, 0x3d, 0xc6, 0x3f, 0xa4, 0x0f, 0x66, 0xfe, 0x34, 0x83, 0xb9, 0x09, 0x25, + 0xb6, 0xe9, 0x4f, 0x39, 0x8a, 0x2e, 0x25, 0x63, 0x79, 0x5d, 0x2d, 0x3e, 0xee, 0x8c, 0x56, 0xe3, + 0x43, 0xec, 0xb4, 0x90, 0xf0, 0xb3, 0xdf, 0x67, 0x15, 0xc6, 0x19, 0xe2, 0x11, 0xab, 0x8e, 0x06, + 0xef, 0xac, 0x53, 0x0b, 0xc6, 0xf0, 0x27, 0x13, 0x8c, 0x91, 0x8f, 0x23, 0x18, 0xe9, 0xd3, 0xf1, + 0xe2, 0x69, 0x4e, 0xc7, 0x2f, 0xbe, 0x07, 0x53, 0x3d, 0x3d, 0x7c, 0x9a, 0x13, 0xe6, 0x4f, 0x4f, + 0x2c, 0x7f, 0x2e, 0xee, 0x17, 0x32, 0x87, 0xfe, 0x02, 0x2f, 0xa0, 0x8d, 0x08, 0x55, 0xaf, 0xd0, + 0x96, 0x81, 0x80, 0xa5, 0xbc, 0x24, 0x08, 0x23, 0xef, 0xc2, 0x08, 0x3f, 0xa1, 0xe3, 0x1b, 0xdb, + 0xb1, 0xb9, 0x71, 0x51, 0x23, 0x87, 0x8a, 0x30, 0x09, 0x8e, 0xa1, 0xf6, 0xaa, 0x20, 0x32, 0xef, + 0xc2, 0xb0, 0x38, 0xe1, 0x3b, 0x7e, 0x5e, 0x54, 0x60, 0x68, 0x33, 0xe9, 0x19, 0x3c, 0x95, 0xe1, + 0x1f, 0x61, 0x71, 0xb8, 0xf9, 0xcb, 0x06, 0x4c, 0xe8, 0x5f, 0x49, 0xae, 0xc3, 0xb0, 0x38, 0x82, + 0x36, 0xf0, 0x08, 0x9a, 0x7d, 0xcd, 0x30, 0x3f, 0x7c, 0xd6, 0x8e, 0x9c, 0x05, 0x16, 0x53, 0xfd, + 0x82, 0x83, 0xd8, 0xa4, 0xa3, 0xea, 0x17, 0x42, 0x6a, 0xc9, 0x32, 0xb6, 0x8d, 0xb3, 0x68, 0xd8, + 0x6d, 0x46, 0xea, 0x36, 0x2e, 0x40, 0x88, 0x25, 0x4a, 0xcc, 0x43, 0x03, 0xa0, 0x5e, 0xbf, 0x77, + 0x9f, 0x1e, 0xac, 0x39, 0x5e, 0x80, 0x5b, 0x61, 0x9c, 0x8d, 0xf7, 0xc5, 0x68, 0x95, 0xc4, 0x56, + 0x98, 0xcf, 0xdc, 0x7d, 0x7a, 0xa0, 0x6d, 0x85, 0x25, 0x2a, 0x4e, 0xf9, 0xc0, 0x7b, 0xe8, 0x44, + 0x94, 0x11, 0xe6, 0x90, 0x90, 0x4f, 0x79, 0x0e, 0x4d, 0x51, 0x2a, 0xc8, 0xe4, 0x6b, 0x30, 0x91, + 0xfc, 0xc2, 0x0d, 0x7d, 0x1e, 0xf7, 0x89, 0x52, 0x22, 0xf4, 0xc2, 0xda, 0x73, 0x47, 0x87, 0x95, + 0x8b, 0x0a, 0xd7, 0xf4, 0x56, 0x3f, 0xc5, 0xcc, 0xfc, 0x5d, 0x03, 0x60, 0x7d, 0xb9, 0x2e, 0x3f, + 0xf0, 0x0a, 0x14, 0x62, 0x3f, 0x62, 0x89, 0xef, 0xb7, 0x53, 0x1b, 0x4a, 0x2c, 0x27, 0x2f, 0x40, + 0x3e, 0xf9, 0x92, 0xa9, 0xa3, 0xc3, 0xca, 0xb8, 0xfe, 0x05, 0xac, 0x94, 0xdc, 0x85, 0x91, 0x81, + 0xda, 0x8c, 0xd2, 0x99, 0xd1, 0x56, 0x49, 0x8d, 0xa3, 0xf0, 0xc1, 0xd6, 0xfa, 0x67, 0x77, 0x14, + 0xbe, 0x9d, 0x83, 0x49, 0xd6, 0xaf, 0xd5, 0x6e, 0xb4, 0xe7, 0x07, 0x5e, 0x74, 0xf0, 0xd4, 0xee, + 0x8a, 0xdf, 0xd6, 0x0c, 0xa2, 0x8b, 0x52, 0x6d, 0xa9, 0xdf, 0x36, 0xd0, 0xe6, 0xf8, 0x2f, 0x46, + 0x60, 0x3a, 0x83, 0x8a, 0xbc, 0x26, 0x82, 0xbf, 0x12, 0x3f, 0x14, 0x06, 0x77, 0xfd, 0xf8, 0xb0, + 0x52, 0x92, 0xe8, 0xeb, 0x49, 0xb0, 0xd7, 0x1c, 0x8c, 0x89, 0xad, 0xcf, 0x4a, 0x62, 0x51, 0x63, + 0xd4, 0x90, 0x74, 0x5a, 0xa2, 0x6a, 0x52, 0x91, 0x48, 0x15, 0x4a, 0xf3, 0x7b, 0xb4, 0xb1, 0xef, + 0xb5, 0x77, 0xef, 0xd3, 0x03, 0x6e, 0x2f, 0x95, 0x6a, 0xcf, 0xb2, 0x9d, 0x56, 0x43, 0xc0, 0xd9, + 0x90, 0xea, 0x9b, 0x38, 0x8d, 0x84, 0xbc, 0x0b, 0x63, 0x75, 0x6f, 0xb7, 0x2d, 0x39, 0x14, 0x90, + 0xc3, 0xa5, 0xa3, 0xc3, 0xca, 0xb9, 0x90, 0x83, 0x7b, 0x19, 0xa8, 0x04, 0xe4, 0x15, 0x18, 0xb2, + 0xfc, 0x26, 0xe5, 0xcb, 0xb0, 0x08, 0x27, 0x0a, 0x18, 0x40, 0x75, 0xae, 0x23, 0x06, 0xb9, 0x07, + 0x23, 0xec, 0x9f, 0x07, 0x4e, 0x67, 0x76, 0x18, 0xf5, 0x36, 0x89, 0x0d, 0x7c, 0x84, 0x76, 0xbc, + 0xf6, 0xae, 0x6a, 0xe3, 0x37, 0xa9, 0xdd, 0x72, 0x3a, 0xda, 0xba, 0xc8, 0x11, 0xc9, 0x26, 0x8c, + 0x25, 0x8a, 0x20, 0x9c, 0x1d, 0xd1, 0x8e, 0x22, 0x93, 0x92, 0xda, 0xf3, 0x82, 0xd9, 0xf9, 0xa8, + 0x19, 0xa2, 0x6c, 0x77, 0x18, 0xbe, 0xfe, 0x31, 0x0a, 0x23, 0x6d, 0x0f, 0x52, 0xec, 0xbf, 0x07, + 0x31, 0x4e, 0xdc, 0x83, 0xb8, 0x00, 0xa2, 0x93, 0xaa, 0xcd, 0x5d, 0x11, 0xfd, 0xf7, 0x4a, 0x7f, + 0x01, 0xbb, 0x9e, 0x20, 0xe3, 0x9c, 0xe4, 0xde, 0x2e, 0xd1, 0xff, 0x4e, 0x73, 0x57, 0xf3, 0x76, + 0xc5, 0xa8, 0xac, 0x1b, 0x12, 0x55, 0x23, 0x77, 0xe0, 0xb2, 0x1b, 0x92, 0x92, 0xa4, 0x1b, 0x3e, + 0x7a, 0x14, 0xf5, 0xeb, 0x06, 0x85, 0x11, 0x59, 0x01, 0xa8, 0x36, 0x22, 0xef, 0x21, 0x45, 0x91, + 0x18, 0xd3, 0x3a, 0x62, 0xbe, 0x7a, 0x9f, 0x1e, 0xd4, 0x69, 0x94, 0x9c, 0x0a, 0x38, 0x88, 0x9a, + 0x12, 0x13, 0x4b, 0xe1, 0x40, 0x3a, 0x70, 0xb6, 0xea, 0xba, 0x1e, 0x8f, 0x08, 0x5d, 0x0f, 0x98, + 0xfc, 0xba, 0xc8, 0xba, 0x94, 0xcd, 0xfa, 0x15, 0xc1, 0xfa, 0x79, 0x27, 0xa6, 0xb2, 0x23, 0x4e, + 0x96, 0xae, 0x26, 0x9b, 0xb1, 0xb9, 0x0a, 0x13, 0x7a, 0x97, 0xea, 0xb1, 0x90, 0x25, 0x28, 0x5a, + 0xf5, 0xaa, 0x5d, 0xbf, 0x57, 0xbd, 0x59, 0x36, 0x48, 0x19, 0x4a, 0xe2, 0xd7, 0x9c, 0x3d, 0xf7, + 0xc6, 0xed, 0x72, 0x4e, 0x83, 0xbc, 0x71, 0x73, 0xae, 0x9c, 0x37, 0xff, 0xd0, 0x80, 0xa2, 0x6c, + 0x1f, 0xb9, 0x0d, 0xf9, 0x7a, 0xfd, 0x5e, 0xea, 0x04, 0x3c, 0x59, 0x7a, 0xf9, 0x22, 0x13, 0x86, + 0x7b, 0xea, 0x22, 0x53, 0xaf, 0xdf, 0x63, 0x74, 0xeb, 0xcb, 0x75, 0x61, 0xb4, 0x64, 0x88, 0xeb, + 0x54, 0x9f, 0x63, 0xc1, 0xdb, 0x90, 0xff, 0x60, 0x6b, 0x5d, 0xec, 0x86, 0x32, 0xc6, 0x17, 0xe9, + 0x3e, 0x7a, 0xa4, 0x2e, 0x7d, 0x8c, 0xc0, 0xb4, 0x60, 0x4c, 0x99, 0x5a, 0xdc, 0x88, 0x68, 0xf9, + 0x71, 0x94, 0xa0, 0x30, 0x22, 0x18, 0xc4, 0x12, 0x25, 0xcc, 0xe6, 0x59, 0xf6, 0x1b, 0x4e, 0x53, + 0x58, 0x23, 0x68, 0xf3, 0x34, 0x19, 0xc0, 0xe2, 0x70, 0xf3, 0x4f, 0x0c, 0x28, 0xaf, 0x05, 0xfe, + 0x43, 0x8f, 0x69, 0xe0, 0x75, 0x7f, 0x9f, 0xb6, 0x37, 0x6f, 0x92, 0xd7, 0xa5, 0x12, 0xe0, 0x26, + 0xdc, 0x79, 0x46, 0x85, 0x4a, 0xe0, 0xc7, 0x87, 0x15, 0xa8, 0x1f, 0x84, 0x11, 0x6d, 0xb1, 0x72, + 0xa9, 0x08, 0x94, 0x60, 0xcb, 0xdc, 0xe0, 0x01, 0x5c, 0x27, 0x04, 0x5b, 0x56, 0x60, 0x08, 0x9b, + 0xa3, 0xc4, 0xd0, 0x0c, 0x45, 0x0c, 0x60, 0x71, 0xb8, 0xa2, 0xb0, 0xbf, 0x93, 0xeb, 0xf9, 0x86, + 0xb9, 0xcf, 0x54, 0x10, 0x94, 0xfe, 0x71, 0x03, 0x2d, 0x62, 0x5f, 0x86, 0x99, 0x74, 0x97, 0xa0, + 0x5f, 0xa4, 0x0a, 0x93, 0x3a, 0x5c, 0xba, 0x48, 0xce, 0x67, 0xd6, 0xb5, 0x39, 0x67, 0xa5, 0xf1, + 0xcd, 0x1f, 0x1a, 0x30, 0x8a, 0xff, 0x5a, 0xdd, 0x26, 0x65, 0x96, 0x4d, 0x75, 0xab, 0x2e, 0x8e, + 0x21, 0xd5, 0x53, 0x3d, 0xe7, 0x51, 0x68, 0x8b, 0x33, 0x4b, 0x4d, 0x8f, 0xc4, 0xc8, 0x82, 0x94, + 0x1f, 0xba, 0xca, 0x43, 0xad, 0x98, 0x94, 0x9f, 0xce, 0x86, 0x29, 0x52, 0x81, 0xcc, 0xc6, 0x8f, + 0xfd, 0xf2, 0x9b, 0xd2, 0x35, 0x8c, 0xe3, 0x87, 0x74, 0xbe, 0x76, 0x74, 0x22, 0xd1, 0xc8, 0xeb, + 0x30, 0xcc, 0xaa, 0xb6, 0xe4, 0xc1, 0x08, 0xee, 0x2a, 0xb0, 0x8d, 0x81, 0x76, 0x06, 0xcc, 0x91, + 0xcc, 0x7f, 0x9e, 0x4b, 0x77, 0xa0, 0xb0, 0x02, 0x4e, 0x39, 0x37, 0xde, 0x82, 0xa1, 0x6a, 0xb3, + 0xe9, 0x3f, 0x12, 0x5a, 0x42, 0xba, 0x69, 0xe2, 0xfe, 0xe3, 0x2b, 0xac, 0xc3, 0x50, 0xb4, 0xe0, + 0x03, 0x06, 0x20, 0xf3, 0x30, 0x5a, 0xdd, 0xaa, 0x2f, 0x2d, 0x2d, 0xac, 0xaf, 0x2f, 0x8b, 0x18, + 0xf7, 0x97, 0x64, 0xff, 0x78, 0x9e, 0x6b, 0x47, 0x51, 0xb3, 0x4f, 0x08, 0x6c, 0x42, 0x47, 0xde, + 0x01, 0xf8, 0xc0, 0xf7, 0xda, 0x0f, 0x68, 0xb4, 0xe7, 0xbb, 0xe2, 0xe3, 0x99, 0x49, 0x31, 0xf6, + 0x91, 0xef, 0xb5, 0xed, 0x16, 0x82, 0x59, 0xdb, 0x13, 0x24, 0x4b, 0xf9, 0x9f, 0xf5, 0x74, 0xcd, + 0x8f, 0xd0, 0x86, 0x19, 0x4a, 0x7a, 0x7a, 0xdb, 0x8f, 0xd2, 0xe7, 0x36, 0x12, 0xcd, 0xfc, 0x95, + 0x1c, 0x4c, 0xf0, 0x9d, 0x2a, 0x17, 0x98, 0xa7, 0x76, 0x32, 0xbe, 0xa5, 0x4d, 0xc6, 0x0b, 0x72, + 0x61, 0x50, 0x3e, 0x6d, 0xa0, 0xa9, 0xb8, 0x07, 0xa4, 0x97, 0x86, 0x58, 0xd2, 0x9f, 0x32, 0xc8, + 0x2c, 0xbc, 0x99, 0x44, 0x0c, 0x84, 0x48, 0x64, 0xa3, 0x2a, 0x0c, 0x2d, 0x8d, 0x87, 0xf9, 0xcb, + 0x39, 0x18, 0x57, 0xec, 0xc9, 0xa7, 0xb6, 0xe3, 0xbf, 0xa8, 0x75, 0xbc, 0x3c, 0x83, 0x50, 0xbe, + 0x6c, 0xa0, 0x7e, 0xef, 0xc2, 0x54, 0x0f, 0x49, 0xda, 0x2c, 0x37, 0x06, 0x31, 0xcb, 0x5f, 0xeb, + 0x8d, 0x3e, 0xe0, 0xf1, 0xf0, 0x71, 0xf4, 0x81, 0x1a, 0xee, 0xf0, 0xed, 0x1c, 0xcc, 0x88, 0x5f, + 0xd5, 0xae, 0xeb, 0x45, 0xf3, 0x7e, 0x7b, 0xc7, 0xdb, 0x7d, 0x6a, 0xc7, 0xa2, 0xaa, 0x8d, 0x45, + 0x45, 0x1f, 0x0b, 0xe5, 0x03, 0xfb, 0x0f, 0x89, 0xf9, 0xaf, 0x8a, 0x30, 0xdb, 0x8f, 0x80, 0x6d, + 0xfb, 0x95, 0x5d, 0x15, 0x6e, 0xfb, 0x53, 0x3b, 0x56, 0xbe, 0x9f, 0x4a, 0x42, 0x78, 0x72, 0x03, + 0x84, 0xf0, 0x2c, 0x43, 0x19, 0xab, 0xaa, 0xd3, 0x90, 0x75, 0x42, 0x98, 0x04, 0xe3, 0x5e, 0x3e, + 0x3a, 0xac, 0x5c, 0x72, 0x58, 0x99, 0x1d, 0x8a, 0x42, 0xbb, 0x1b, 0x78, 0x0a, 0x8f, 0x1e, 0x4a, + 0xf2, 0xbb, 0x06, 0x4c, 0x20, 0x70, 0xf1, 0x21, 0x6d, 0x47, 0xc8, 0xac, 0x20, 0x0e, 0x69, 0xe2, + 0x3b, 0x4f, 0xf5, 0x28, 0xf0, 0xda, 0xbb, 0xe8, 0x48, 0x0a, 0x6b, 0xdb, 0xac, 0x17, 0x7e, 0x70, + 0x58, 0x79, 0xfb, 0xe3, 0xdc, 0xa3, 0x12, 0xac, 0x42, 0xb6, 0x91, 0xe7, 0x0d, 0xa5, 0x58, 0x6d, + 0xaa, 0x99, 0xa9, 0x16, 0x91, 0x9f, 0x84, 0xf3, 0x3c, 0x0e, 0x63, 0xde, 0x6f, 0x47, 0x5e, 0xbb, + 0xeb, 0x77, 0xc3, 0x9a, 0xd3, 0xd8, 0xef, 0x76, 0x42, 0xe1, 0xec, 0xc4, 0x2f, 0x6f, 0xc4, 0x85, + 0xf6, 0x36, 0x2f, 0x55, 0x58, 0xf6, 0x63, 0x40, 0xee, 0xc1, 0x14, 0x2f, 0xaa, 0x76, 0x23, 0xbf, + 0xde, 0x70, 0x9a, 0x5e, 0x7b, 0x17, 0x7d, 0xa0, 0xc5, 0xda, 0x45, 0xb6, 0xb7, 0x74, 0xba, 0x91, + 0x6f, 0x87, 0x1c, 0xae, 0xf0, 0xeb, 0x25, 0x22, 0x4b, 0x30, 0x69, 0x51, 0xc7, 0x7d, 0xe0, 0x3c, + 0x9e, 0x77, 0x3a, 0x4e, 0xc3, 0x8b, 0x0e, 0x70, 0x67, 0x96, 0xaf, 0x55, 0x8e, 0x0e, 0x2b, 0xcf, + 0x04, 0xd4, 0x71, 0xed, 0x96, 0xf3, 0xd8, 0x6e, 0x88, 0x42, 0x85, 0x59, 0x9a, 0x2e, 0x66, 0xe5, + 0xb5, 0x63, 0x56, 0xa3, 0x69, 0x56, 0x5e, 0xbb, 0x3f, 0xab, 0x84, 0x4e, 0xb2, 0x5a, 0x77, 0x82, + 0x5d, 0x1a, 0x71, 0x27, 0x21, 0x5c, 0x36, 0xae, 0x1a, 0x0a, 0xab, 0x08, 0xcb, 0x6c, 0x74, 0x18, + 0xa6, 0x59, 0x29, 0x74, 0x4c, 0xf2, 0xb6, 0x02, 0x2f, 0xa2, 0xea, 0x17, 0x8e, 0x61, 0xb3, 0xb0, + 0xff, 0xd1, 0x4d, 0xda, 0xef, 0x13, 0x7b, 0x28, 0x13, 0x6e, 0xca, 0x47, 0x96, 0x7a, 0xb8, 0x65, + 0x7f, 0x65, 0x0f, 0x65, 0xcc, 0x4d, 0xfd, 0xce, 0x71, 0xfc, 0x4e, 0x85, 0x5b, 0x9f, 0x0f, 0xed, + 0xa1, 0x24, 0x2b, 0xac, 0xd3, 0x22, 0xda, 0x66, 0x12, 0x2d, 0x9c, 0xa4, 0x13, 0xd8, 0xb4, 0x17, + 0xc5, 0x9e, 0xba, 0x1c, 0xc8, 0x62, 0x3b, 0xc3, 0x65, 0x9a, 0x26, 0xfe, 0xa0, 0x50, 0x1c, 0x2a, + 0x0f, 0x5b, 0x65, 0x2e, 0xf2, 0x11, 0x13, 0x1c, 0xd4, 0xc5, 0xe6, 0x6f, 0xe6, 0xe0, 0x82, 0x54, + 0xc7, 0x34, 0x7a, 0xe4, 0x07, 0xfb, 0x5e, 0x7b, 0xf7, 0x29, 0xd7, 0xaa, 0x77, 0x34, 0xad, 0xfa, + 0x62, 0x6a, 0x85, 0x4b, 0x7d, 0xe5, 0x31, 0xaa, 0xf5, 0xcf, 0x87, 0xe0, 0xd9, 0x63, 0xa9, 0xc8, + 0x87, 0x6c, 0x15, 0xf4, 0x68, 0x3b, 0x5a, 0x72, 0x9b, 0x94, 0x6d, 0xc3, 0xfc, 0x6e, 0x24, 0x9c, + 0xd9, 0x2f, 0x1c, 0x1d, 0x56, 0xa6, 0xf9, 0x55, 0x20, 0xdb, 0x73, 0x9b, 0xd4, 0x8e, 0x78, 0xb1, + 0x36, 0x4c, 0xbd, 0xd4, 0x8c, 0x65, 0x7c, 0x31, 0x71, 0xa9, 0x1d, 0xd1, 0xe0, 0xa1, 0xc3, 0x6f, + 0x44, 0x08, 0x96, 0xfb, 0x94, 0x76, 0x6c, 0x87, 0x95, 0xda, 0x9e, 0x28, 0xd6, 0x59, 0xf6, 0x50, + 0x93, 0x3b, 0x0a, 0xcb, 0x79, 0xb6, 0x39, 0x78, 0xe0, 0x3c, 0x16, 0x16, 0x2f, 0xfa, 0x57, 0x15, + 0x96, 0x3c, 0x0a, 0xb2, 0xe5, 0x3c, 0xb6, 0x7a, 0x49, 0xc8, 0xd7, 0xe0, 0xac, 0x50, 0xdc, 0x4c, + 0x89, 0x05, 0x7e, 0x53, 0x7e, 0x71, 0x01, 0x79, 0xbd, 0x7c, 0x74, 0x58, 0x39, 0x2f, 0xd4, 0xbe, + 0xdd, 0xe0, 0x18, 0x99, 0x5f, 0x9d, 0xcd, 0x85, 0xac, 0xb3, 0x85, 0x2c, 0xd5, 0x1d, 0x0f, 0x68, + 0x18, 0x3a, 0xbb, 0xd2, 0x3a, 0xe6, 0x27, 0x4a, 0x4a, 0x67, 0xda, 0x2d, 0x5e, 0x6e, 0xf5, 0xa5, + 0x24, 0xf7, 0x60, 0x62, 0x8b, 0x6e, 0xab, 0xe3, 0x33, 0x1c, 0x4f, 0xf1, 0xf2, 0x23, 0xba, 0xdd, + 0x7f, 0x70, 0x52, 0x74, 0xc4, 0x83, 0xa9, 0xb5, 0xc0, 0x7f, 0x7c, 0xc0, 0xb6, 0x7a, 0xb4, 0x4d, + 0x03, 0x0c, 0xee, 0x1a, 0x41, 0x77, 0xd5, 0x6c, 0x62, 0x59, 0xea, 0xe5, 0xb5, 0xe7, 0x8f, 0x0e, + 0x2b, 0xcf, 0x76, 0x18, 0xd8, 0x6e, 0x0a, 0xb8, 0x9d, 0xba, 0x17, 0xd8, 0xcb, 0x95, 0xfc, 0x34, + 0x4c, 0x5a, 0x7e, 0x37, 0xf2, 0xda, 0xbb, 0xf5, 0x28, 0x70, 0x22, 0xba, 0xcb, 0x15, 0x79, 0x12, + 0x45, 0x96, 0x2a, 0xe5, 0x8e, 0xe9, 0x80, 0x03, 0xed, 0x50, 0x40, 0x35, 0x4d, 0xaa, 0x13, 0x98, + 0xbf, 0x9e, 0x83, 0x59, 0x31, 0x0c, 0x16, 0x6d, 0xf8, 0x81, 0xfb, 0xf4, 0x4f, 0xfb, 0x45, 0x6d, + 0xda, 0xbf, 0x10, 0xc7, 0x28, 0x65, 0x7d, 0xe4, 0x31, 0xb3, 0xfe, 0x0f, 0x0c, 0xb8, 0x74, 0x1c, + 0x11, 0xeb, 0x9d, 0x38, 0xae, 0x6f, 0xb4, 0x27, 0x7e, 0xaf, 0x03, 0xd3, 0x38, 0x9e, 0xe8, 0x38, + 0x0e, 0xef, 0xf9, 0x61, 0x84, 0xde, 0xbb, 0x9c, 0x16, 0x48, 0x50, 0xf3, 0xfd, 0x26, 0xea, 0xf9, + 0xda, 0x6b, 0x4c, 0x9d, 0xff, 0xe0, 0xb0, 0x02, 0x0c, 0xc4, 0x23, 0xf1, 0xd8, 0x9a, 0xcf, 0x25, + 0x06, 0xfd, 0xd2, 0xa1, 0x8d, 0xd1, 0x1f, 0xfb, 0xf4, 0x20, 0xb4, 0xb2, 0x58, 0xa3, 0x87, 0xa6, + 0xda, 0x8d, 0xf6, 0xd6, 0x02, 0xba, 0x43, 0x03, 0xda, 0x6e, 0xd0, 0xcf, 0x98, 0x87, 0x46, 0xff, + 0xb8, 0x81, 0xb6, 0x27, 0x7f, 0x35, 0x02, 0x33, 0x59, 0x64, 0xac, 0x5f, 0x14, 0x8b, 0x38, 0x7d, + 0x89, 0xfc, 0xff, 0x36, 0xa0, 0x54, 0xa7, 0x0d, 0xbf, 0xed, 0xde, 0x71, 0x1a, 0x91, 0x2f, 0x43, + 0x32, 0x6c, 0xae, 0xd9, 0x18, 0xdc, 0xde, 0xc1, 0x02, 0xcd, 0x33, 0xf0, 0xfe, 0x60, 0x86, 0x68, + 0xc3, 0xc7, 0x40, 0xd8, 0x88, 0xc9, 0x64, 0x52, 0x05, 0x9e, 0x6a, 0x68, 0x95, 0x92, 0x1a, 0x8c, + 0xcf, 0xfb, 0xed, 0x36, 0x65, 0x3f, 0x94, 0xb0, 0x4e, 0x0c, 0xc4, 0x6c, 0xc8, 0x82, 0xb4, 0x87, + 0x40, 0x27, 0x21, 0xb7, 0x20, 0xbf, 0x31, 0x77, 0x47, 0x8c, 0x81, 0x0c, 0x56, 0xdb, 0x98, 0xbb, + 0x83, 0x7b, 0x5d, 0x66, 0x3f, 0x8c, 0x77, 0xe7, 0x76, 0x54, 0x1f, 0xe8, 0xc6, 0xdc, 0x1d, 0xb2, + 0x0a, 0x53, 0x16, 0xfd, 0x7a, 0xd7, 0x0b, 0xa8, 0x98, 0x00, 0x0f, 0xee, 0x54, 0x71, 0x2c, 0x8a, + 0x5c, 0x8f, 0x05, 0xbc, 0x50, 0xda, 0xf6, 0x76, 0x6b, 0x47, 0xbd, 0x38, 0xd9, 0x4b, 0x4b, 0x7e, + 0x1e, 0xce, 0x2e, 0x78, 0xa1, 0x68, 0x33, 0x77, 0x3e, 0xba, 0x78, 0x0e, 0x39, 0xdc, 0x67, 0x3a, + 0x7c, 0x21, 0x73, 0x3a, 0x3c, 0xef, 0xc6, 0x4c, 0x6c, 0xee, 0xd9, 0x74, 0xd3, 0xf1, 0xb0, 0xd9, + 0xf5, 0x90, 0x8f, 0x60, 0x02, 0xbd, 0x3d, 0xe8, 0x8f, 0xc5, 0x78, 0xf3, 0x91, 0x3e, 0x35, 0x7f, + 0x2e, 0xb3, 0xe6, 0x8b, 0xe8, 0x3c, 0xb2, 0xd1, 0xab, 0x8b, 0xb1, 0xe9, 0xda, 0x1e, 0x41, 0xe3, + 0x4c, 0x3e, 0x80, 0x49, 0xb1, 0xe8, 0xac, 0xee, 0xac, 0xef, 0xd1, 0x05, 0xe7, 0x40, 0x04, 0x21, + 0xa0, 0xfd, 0x27, 0x56, 0x2a, 0xdb, 0xdf, 0xb1, 0xa3, 0x3d, 0x6a, 0xbb, 0x8e, 0xa6, 0x9e, 0x53, + 0x84, 0xe4, 0x67, 0x61, 0x6c, 0xd9, 0xc7, 0x83, 0x27, 0x54, 0x35, 0xa3, 0xc8, 0xe7, 0xcb, 0x78, + 0x71, 0x9a, 0x83, 0x53, 0x8b, 0xc8, 0x8f, 0x0f, 0x2b, 0x6f, 0x9d, 0x56, 0x0a, 0x95, 0x0a, 0x2c, + 0xb5, 0x36, 0x32, 0x0f, 0xc5, 0x2d, 0xba, 0xcd, 0xbe, 0x36, 0x7d, 0xe9, 0x4f, 0x82, 0xb9, 0xbe, + 0x78, 0x24, 0x7e, 0xa9, 0xa7, 0x3a, 0x12, 0x83, 0x04, 0x30, 0x85, 0xfd, 0xb3, 0xe6, 0x84, 0xe1, + 0x23, 0x3f, 0x70, 0x9b, 0x34, 0x94, 0xc7, 0x23, 0xbd, 0x9d, 0x3f, 0x97, 0xd9, 0xf9, 0x97, 0x78, + 0xe7, 0x77, 0x14, 0x0e, 0xaa, 0xb8, 0xf5, 0xb0, 0x37, 0xff, 0x85, 0x81, 0x52, 0x4f, 0xae, 0x61, + 0xf0, 0x59, 0x1c, 0xd5, 0x8e, 0xbb, 0x59, 0xa7, 0x93, 0xba, 0x0b, 0xc0, 0x51, 0xd8, 0xd6, 0xf7, + 0x8e, 0xd3, 0xa0, 0x91, 0xf4, 0x91, 0x22, 0xf2, 0x0e, 0x42, 0xd4, 0xad, 0x2f, 0xc7, 0x21, 0x5f, + 0x82, 0x99, 0x05, 0xfa, 0xd0, 0x6b, 0xd0, 0x6a, 0x14, 0xd1, 0x90, 0xf7, 0xf0, 0x7c, 0x95, 0x1f, + 0x26, 0x8e, 0xd6, 0x5e, 0x3c, 0x3a, 0xac, 0x5c, 0x76, 0xb1, 0xdc, 0x76, 0x12, 0x04, 0xbb, 0xe1, + 0xa8, 0xbc, 0x32, 0x39, 0x98, 0xff, 0xc3, 0x48, 0x7a, 0x9d, 0xbc, 0x0c, 0x05, 0x6b, 0x2d, 0x6e, + 0x3f, 0x3f, 0x27, 0x4c, 0x35, 0x1f, 0x11, 0xc8, 0x57, 0xe0, 0xac, 0xc2, 0x07, 0x7b, 0x84, 0xba, + 0xac, 0x41, 0xfc, 0x63, 0x5e, 0xc2, 0x83, 0x21, 0xa5, 0x25, 0x0e, 0xc7, 0x48, 0xb5, 0x28, 0x9b, + 0x07, 0xfb, 0x58, 0xa5, 0x60, 0x81, 0xb6, 0x3d, 0xce, 0x5b, 0xf9, 0x58, 0x95, 0xb7, 0x8b, 0x08, + 0xe9, 0x8f, 0xcd, 0xe2, 0xf0, 0x41, 0xa1, 0x58, 0x28, 0x0f, 0x99, 0x7f, 0x6d, 0x28, 0x59, 0x2f, + 0x9e, 0xd2, 0x15, 0xeb, 0xb6, 0xb6, 0x62, 0xcd, 0x08, 0xd2, 0xf8, 0xab, 0x58, 0x59, 0xa6, 0x95, + 0x31, 0x09, 0xe3, 0x1a, 0x12, 0x86, 0xd9, 0x6e, 0x84, 0x34, 0xe0, 0x3e, 0xc9, 0xcf, 0x56, 0x98, + 0x6d, 0xfc, 0x5d, 0x03, 0x45, 0x4f, 0xfe, 0x85, 0x01, 0x93, 0x29, 0x0a, 0xd6, 0x1b, 0x0c, 0xa4, + 0xf6, 0x46, 0x37, 0xa4, 0x81, 0x85, 0x50, 0x1e, 0x94, 0xb7, 0xac, 0x07, 0xe5, 0x35, 0x2d, 0x06, + 0x23, 0xef, 0xc3, 0xd0, 0x06, 0xee, 0x20, 0xf4, 0xb8, 0x8e, 0x98, 0x3f, 0x16, 0xf2, 0x19, 0xd6, + 0x65, 0xff, 0xaa, 0x0a, 0x02, 0xcb, 0x48, 0x1d, 0x46, 0xe6, 0x03, 0x8a, 0xf9, 0x2d, 0x0a, 0x83, + 0x1f, 0xc0, 0x35, 0x38, 0x49, 0xfa, 0x00, 0x4e, 0x70, 0x32, 0x7f, 0x2d, 0x07, 0x24, 0xf9, 0x46, + 0xda, 0x08, 0x68, 0x14, 0x3e, 0xb5, 0x83, 0xfe, 0x9e, 0x36, 0xe8, 0xcf, 0xf6, 0x0c, 0x3a, 0xff, + 0xbc, 0x81, 0xc6, 0xfe, 0x4f, 0x0c, 0x38, 0x97, 0x4d, 0x48, 0x5e, 0x80, 0xe1, 0xd5, 0xf5, 0x35, + 0x19, 0x1a, 0x24, 0x3e, 0xc5, 0xef, 0xa0, 0x65, 0x6c, 0x89, 0x22, 0xf2, 0x3a, 0x0c, 0x7f, 0x68, + 0xcd, 0xb3, 0x25, 0x53, 0xb9, 0x3d, 0xf3, 0xf5, 0xc0, 0x6e, 0xe8, 0x5b, 0x2e, 0x81, 0xa4, 0x8e, + 0x6d, 0xfe, 0x89, 0x8d, 0xed, 0xb7, 0x73, 0x30, 0x59, 0x6d, 0x34, 0x68, 0x18, 0x32, 0x83, 0x88, + 0x86, 0xd1, 0x53, 0x3b, 0xb0, 0xd9, 0x41, 0x3f, 0xda, 0xb7, 0x0d, 0x34, 0xaa, 0x7f, 0x6a, 0xc0, + 0x59, 0x49, 0xf5, 0xd0, 0xa3, 0x8f, 0xd6, 0xf7, 0x02, 0x1a, 0xee, 0xf9, 0x4d, 0x77, 0xd0, 0x7b, + 0x60, 0xb8, 0x4a, 0x7b, 0xcd, 0x88, 0x06, 0xaa, 0x83, 0x7a, 0x07, 0x21, 0xda, 0x2a, 0x8d, 0x10, + 0x72, 0x03, 0x46, 0xaa, 0x9d, 0x4e, 0xe0, 0x3f, 0xe4, 0xd3, 0x7e, 0x5c, 0x9c, 0x47, 0x72, 0x90, + 0x76, 0x7e, 0xc9, 0x41, 0xac, 0x19, 0x0b, 0xb4, 0xcd, 0x23, 0x9a, 0xc7, 0x79, 0x33, 0x5c, 0xda, + 0x56, 0x2d, 0x34, 0x2c, 0x37, 0xbf, 0x55, 0x80, 0x92, 0xfa, 0x21, 0xc4, 0x84, 0x61, 0x1e, 0x9e, + 0xa2, 0x86, 0x09, 0x38, 0x08, 0xb1, 0x44, 0x49, 0x12, 0xf5, 0x93, 0x3b, 0x31, 0xea, 0x67, 0x0b, + 0xc6, 0xd7, 0x02, 0xbf, 0xe3, 0x87, 0xd4, 0xe5, 0x29, 0x8a, 0xb8, 0xd6, 0x9a, 0x8e, 0x43, 0x61, + 0x79, 0x9f, 0xb3, 0x22, 0xbe, 0x1d, 0xe8, 0x08, 0x6c, 0x3b, 0x9d, 0xc0, 0x48, 0xe7, 0xc3, 0x1d, + 0xfc, 0x4e, 0x28, 0xae, 0x0b, 0xc4, 0x0e, 0x7e, 0x06, 0xd1, 0x1d, 0xfc, 0x0c, 0xa2, 0x4e, 0x8b, + 0xa1, 0x27, 0x35, 0x2d, 0xc8, 0xaf, 0x19, 0x30, 0x56, 0x6d, 0xb7, 0x45, 0xd4, 0x8f, 0xbc, 0xe7, + 0x7f, 0x36, 0x71, 0xf2, 0xf3, 0xb0, 0x50, 0xee, 0xe3, 0xff, 0xaa, 0xf0, 0xf1, 0xbf, 0xf5, 0xb1, + 0x7c, 0xfc, 0xeb, 0x81, 0xe3, 0x45, 0x21, 0x1e, 0xe6, 0x26, 0x15, 0xaa, 0xa1, 0xbf, 0x4a, 0x3b, + 0xc8, 0x5b, 0x50, 0x8e, 0xe5, 0x71, 0xa9, 0xed, 0xd2, 0xc7, 0x94, 0x07, 0x49, 0x8d, 0xf3, 0x1b, + 0x86, 0xda, 0xe1, 0x45, 0x1a, 0xd1, 0xfc, 0xb6, 0x01, 0xe7, 0x54, 0x81, 0xa8, 0x77, 0xb7, 0x5b, + 0x1e, 0x6e, 0x7f, 0xc8, 0x75, 0x18, 0x15, 0xe3, 0x15, 0x1b, 0x72, 0xbd, 0x79, 0xad, 0x12, 0x14, + 0xb2, 0xc8, 0x86, 0x88, 0xf1, 0x10, 0xbe, 0x82, 0xe9, 0xd4, 0x74, 0x63, 0x45, 0xb5, 0x59, 0xd1, + 0xd9, 0xe5, 0x00, 0x7f, 0xeb, 0x63, 0xc7, 0x20, 0xe6, 0xbb, 0x30, 0xa5, 0xb7, 0xb2, 0x4e, 0xf1, + 0x0a, 0x9a, 0xfc, 0x34, 0x23, 0xfb, 0xd3, 0x64, 0xb9, 0xb9, 0x05, 0xa4, 0x87, 0x3e, 0xc4, 0x83, + 0x2a, 0x1a, 0xc9, 0x83, 0x54, 0xe9, 0xee, 0xea, 0x41, 0x8c, 0x33, 0xbc, 0x8d, 0xa9, 0xdd, 0x8d, + 0xa4, 0xe6, 0x5f, 0x02, 0x4c, 0x67, 0xa8, 0x8e, 0x13, 0x96, 0xf6, 0x8a, 0x3e, 0x79, 0x46, 0xe3, + 0x88, 0x00, 0x39, 0x65, 0xde, 0x95, 0xd9, 0xbc, 0x8e, 0x99, 0x2a, 0xc7, 0xa5, 0xf8, 0xfa, 0x34, + 0x96, 0x77, 0x35, 0x68, 0x67, 0xe8, 0x89, 0x05, 0xed, 0xd4, 0x60, 0x5c, 0x7c, 0x95, 0x98, 0xca, + 0xc3, 0x89, 0x5b, 0x20, 0xe0, 0x05, 0x76, 0xcf, 0x94, 0xd6, 0x49, 0x38, 0x8f, 0xd0, 0x6f, 0x3e, + 0xa4, 0x82, 0xc7, 0x88, 0xca, 0x03, 0x0b, 0x32, 0x79, 0x28, 0x24, 0xe4, 0x1f, 0x1b, 0x40, 0x04, + 0x44, 0x9d, 0xcf, 0xc5, 0xe3, 0xe6, 0xb3, 0xfb, 0x64, 0xe6, 0xf3, 0xb3, 0xb2, 0x8d, 0xd9, 0xf3, + 0x3a, 0xa3, 0x59, 0xe4, 0x1f, 0x1a, 0x30, 0xc5, 0x23, 0x47, 0xd4, 0xc6, 0x8e, 0x1e, 0xd7, 0xd8, + 0xc6, 0x93, 0x69, 0xec, 0xa5, 0x10, 0xab, 0xed, 0xd3, 0xd6, 0xde, 0x46, 0x91, 0x9f, 0x04, 0x88, + 0x67, 0x94, 0x8c, 0x50, 0xbc, 0x94, 0xa1, 0x05, 0x62, 0xa4, 0xe4, 0x92, 0x65, 0x14, 0xd3, 0xa9, + 0x31, 0x3d, 0x09, 0x37, 0xf2, 0xf3, 0x30, 0xc3, 0xe6, 0x4b, 0x0c, 0x11, 0x71, 0x6e, 0xb3, 0x63, + 0x58, 0xcb, 0xe7, 0xfb, 0x2f, 0xed, 0xd7, 0xb3, 0xc8, 0xf8, 0x3d, 0x91, 0x24, 0xd1, 0x42, 0xd4, + 0x52, 0xb7, 0x7c, 0x59, 0x14, 0x18, 0xd0, 0x8a, 0xad, 0x0f, 0x67, 0x4b, 0x58, 0x67, 0xa6, 0x7e, + 0xbb, 0x20, 0xe7, 0x02, 0xd7, 0x6f, 0xa1, 0x7e, 0xd1, 0x03, 0x41, 0xe4, 0x43, 0x20, 0xf5, 0xee, + 0xee, 0x2e, 0x0d, 0x23, 0xea, 0x72, 0x18, 0x0d, 0xc2, 0xd9, 0x71, 0xd4, 0x0f, 0xe8, 0xa6, 0x0a, + 0x65, 0xa9, 0x1d, 0xc8, 0x62, 0x55, 0x48, 0x7a, 0x89, 0x09, 0x85, 0x19, 0xf1, 0xd1, 0x0c, 0x2a, + 0xd3, 0x14, 0x84, 0xb3, 0x13, 0x5a, 0x14, 0x61, 0x52, 0x52, 0x7b, 0x4e, 0xe6, 0xb1, 0x53, 0x72, + 0x1d, 0x68, 0xdb, 0xde, 0x2c, 0x76, 0x17, 0xb7, 0xe1, 0x42, 0xdf, 0xde, 0xcc, 0xb8, 0x2b, 0x72, + 0x43, 0xbf, 0x2b, 0x72, 0xa1, 0x9f, 0xd6, 0x0d, 0xd5, 0xfb, 0x22, 0xbf, 0x6d, 0xa4, 0xd4, 0xac, + 0xb0, 0x89, 0x78, 0x7e, 0xc5, 0x7e, 0xeb, 0x50, 0x0e, 0x93, 0x32, 0x70, 0x45, 0x9c, 0x4b, 0x6c, + 0x31, 0xa6, 0x88, 0x55, 0x45, 0x8e, 0x2a, 0xf9, 0x13, 0x6a, 0x5c, 0xf3, 0x9f, 0x1a, 0x40, 0x78, + 0x0b, 0xe7, 0x9d, 0x8e, 0xb3, 0xed, 0x35, 0xbd, 0xc8, 0xa3, 0x21, 0xb9, 0x0f, 0x65, 0xc1, 0xc2, + 0xd9, 0x6e, 0x52, 0x35, 0x0c, 0x4c, 0x9c, 0x13, 0xc7, 0x65, 0x76, 0xda, 0x7a, 0xea, 0x21, 0xec, + 0x23, 0x23, 0xb9, 0x4f, 0x20, 0x23, 0xe6, 0x8f, 0x0c, 0xb8, 0xd0, 0xdb, 0x6c, 0x51, 0x73, 0xdc, + 0x79, 0xc6, 0x09, 0x9d, 0x97, 0xf5, 0x95, 0x39, 0xf4, 0xb0, 0x3e, 0xb1, 0xaf, 0xcc, 0x27, 0x0e, + 0xdb, 0xd3, 0x7f, 0xe5, 0x23, 0x35, 0xa9, 0x07, 0x79, 0x3d, 0x2b, 0xa0, 0x87, 0xdf, 0xba, 0xe1, + 0x60, 0x3d, 0x96, 0x47, 0xee, 0x72, 0x72, 0x99, 0xbb, 0x1c, 0x79, 0x81, 0x28, 0x9f, 0x75, 0x81, + 0xc8, 0xfc, 0xa5, 0x1c, 0x94, 0xd6, 0x9a, 0xdd, 0x5d, 0xaf, 0xbd, 0xe0, 0x44, 0xce, 0x53, 0xbb, + 0x65, 0x7a, 0x53, 0xdb, 0x32, 0xc5, 0x11, 0x67, 0xf1, 0x87, 0x0d, 0x96, 0x64, 0xcf, 0x80, 0xc9, + 0x84, 0x84, 0xab, 0x87, 0x7b, 0x50, 0x60, 0x3f, 0x84, 0x05, 0x76, 0xb9, 0x87, 0x31, 0x62, 0x5d, + 0x8f, 0xff, 0x13, 0x9b, 0x18, 0x3d, 0xb5, 0x21, 0x72, 0xb8, 0xf8, 0x05, 0x9e, 0x99, 0xec, 0xf4, + 0x59, 0x54, 0xff, 0xc8, 0x80, 0x72, 0xfa, 0x4b, 0xc8, 0x7d, 0x18, 0x61, 0x9c, 0xbc, 0x38, 0xcb, + 0xd9, 0x8b, 0x7d, 0xbe, 0xf9, 0xba, 0x40, 0xe3, 0xcd, 0xc3, 0xce, 0xa7, 0x1c, 0x62, 0x49, 0x0e, + 0x17, 0x2d, 0x28, 0xa9, 0x58, 0x19, 0xad, 0x7b, 0x4d, 0xd7, 0x89, 0xe7, 0xb2, 0xfb, 0x41, 0x6d, + 0xf5, 0x6f, 0x69, 0xad, 0x16, 0xda, 0x70, 0xd0, 0x74, 0x95, 0x78, 0xe5, 0x8e, 0x4f, 0x07, 0x55, + 0xce, 0xa4, 0xd6, 0xd7, 0xaf, 0xdc, 0x71, 0x18, 0xdb, 0x6b, 0xf1, 0xfa, 0x84, 0x9c, 0xe1, 0x5e, + 0xab, 0x83, 0x10, 0xd5, 0x5e, 0xe7, 0x38, 0xe6, 0xdf, 0xc9, 0xc3, 0xb9, 0xa4, 0x79, 0x3c, 0x79, + 0xe7, 0x9a, 0x13, 0x38, 0xad, 0xf0, 0x84, 0x19, 0x70, 0xb5, 0xa7, 0x69, 0x78, 0xa5, 0x5c, 0x36, + 0x4d, 0x69, 0x90, 0x99, 0x6a, 0x10, 0x6e, 0x52, 0x79, 0x83, 0x64, 0x33, 0xc8, 0x7d, 0xc8, 0xd7, + 0x69, 0x24, 0x2e, 0x9e, 0x5e, 0xe9, 0xe9, 0x55, 0xb5, 0x5d, 0xd7, 0xeb, 0x34, 0xe2, 0x83, 0xc8, + 0x63, 0xf7, 0xa9, 0x16, 0x4b, 0xcf, 0xb6, 0x1b, 0x5b, 0x30, 0xbc, 0xf8, 0xb8, 0x43, 0x1b, 0x91, + 0xb8, 0x6f, 0xfa, 0xca, 0xf1, 0xfc, 0x38, 0xae, 0x72, 0xab, 0x95, 0x22, 0x40, 0xed, 0x2c, 0x8e, + 0x72, 0xf1, 0x36, 0x14, 0x65, 0xe5, 0xa7, 0xba, 0x9d, 0xf9, 0x26, 0x8c, 0x29, 0x95, 0x9c, 0x4a, + 0xe8, 0xff, 0xc6, 0x80, 0x61, 0xa6, 0x6d, 0x37, 0xdf, 0x78, 0x4a, 0x35, 0xd2, 0x2d, 0x4d, 0x23, + 0x4d, 0x29, 0xd7, 0x88, 0x70, 0x5e, 0xbe, 0x71, 0x82, 0x2e, 0x3a, 0x34, 0x00, 0x12, 0x64, 0x72, + 0x17, 0x46, 0x44, 0xbe, 0x18, 0x91, 0x19, 0x57, 0xbd, 0x97, 0x24, 0x33, 0x87, 0xc5, 0x56, 0x9c, + 0xdf, 0x49, 0x9b, 0xbd, 0x92, 0x9a, 0x2c, 0x24, 0xb1, 0xdb, 0xea, 0x45, 0x58, 0xc6, 0x66, 0xde, + 0x6f, 0xf3, 0x7b, 0x2a, 0x4a, 0x0e, 0xb2, 0x3e, 0x41, 0xdc, 0x55, 0xe1, 0xb8, 0xc9, 0x1f, 0xc7, + 0xe4, 0x9c, 0x60, 0x92, 0xed, 0xd3, 0xf9, 0xab, 0x12, 0xbf, 0xf9, 0x21, 0x1b, 0xf6, 0x0e, 0x94, + 0xee, 0xf8, 0xc1, 0x23, 0x27, 0x70, 0xab, 0xbb, 0x54, 0x44, 0xdd, 0x17, 0x31, 0x74, 0x7e, 0x7c, + 0x87, 0xc3, 0x6d, 0x87, 0x15, 0xfc, 0xf8, 0xb0, 0x52, 0xa8, 0xf9, 0x7e, 0xd3, 0xd2, 0xd0, 0xc9, + 0x2a, 0x8c, 0x3f, 0x70, 0x1e, 0x8b, 0x33, 0xd0, 0xf5, 0xf5, 0x65, 0x11, 0xbb, 0xf3, 0xca, 0xd1, + 0x61, 0xe5, 0x42, 0xcb, 0x79, 0x1c, 0x9f, 0x9d, 0xf6, 0x0f, 0x2f, 0xd7, 0xe9, 0x89, 0x07, 0x13, + 0x6b, 0x7e, 0x10, 0x89, 0x4a, 0x98, 0xcd, 0x9e, 0xef, 0x73, 0x8a, 0x76, 0x23, 0xf3, 0x14, 0xed, + 0x02, 0xdb, 0xa8, 0xd8, 0x3b, 0x31, 0xb9, 0x76, 0x5d, 0x51, 0x63, 0x4c, 0xde, 0x81, 0xa9, 0x79, + 0x1a, 0x44, 0xde, 0x8e, 0xd7, 0x70, 0x22, 0x7a, 0xc7, 0x0f, 0x5a, 0x4e, 0x24, 0x1c, 0x46, 0xe8, + 0x30, 0x68, 0x50, 0xce, 0xa9, 0xe5, 0x44, 0x56, 0x2f, 0x26, 0xf9, 0x4a, 0x56, 0x34, 0xd4, 0x10, + 0x7e, 0xfe, 0xeb, 0xcc, 0x1a, 0xc9, 0x88, 0x86, 0xea, 0xd3, 0x05, 0x19, 0x71, 0x51, 0xbb, 0xc7, + 0x1d, 0x25, 0x17, 0x6b, 0x37, 0xc5, 0xb1, 0xf6, 0xc9, 0x47, 0xc5, 0xf1, 0xb8, 0xf5, 0x39, 0x32, + 0x9e, 0x83, 0x7c, 0x6d, 0xed, 0x0e, 0xba, 0x80, 0xc4, 0xd1, 0x2d, 0x6d, 0xef, 0x39, 0xed, 0x06, + 0x1a, 0x51, 0x22, 0x1e, 0x44, 0x55, 0x78, 0xb5, 0xb5, 0x3b, 0xc4, 0x81, 0xe9, 0x35, 0x1a, 0xb4, + 0xbc, 0xe8, 0x4b, 0x37, 0x6f, 0x2a, 0x03, 0x55, 0xc4, 0xa6, 0xdd, 0x10, 0x4d, 0xab, 0x74, 0x10, + 0xc5, 0x7e, 0x7c, 0xf3, 0x66, 0xe6, 0x70, 0xc4, 0x0d, 0xcb, 0xe2, 0x45, 0x16, 0x61, 0xe2, 0x81, + 0xf3, 0x58, 0x1c, 0xf2, 0xc7, 0x7b, 0xd8, 0x3c, 0xde, 0x36, 0x40, 0xc1, 0x6a, 0x24, 0x45, 0xea, + 0x10, 0xeb, 0x44, 0xe4, 0x6d, 0x18, 0x4b, 0xc4, 0x2b, 0xc4, 0xe3, 0xdd, 0x3c, 0x0f, 0x33, 0x55, + 0x84, 0x53, 0xf3, 0x95, 0x29, 0xe8, 0x64, 0x23, 0x76, 0x41, 0x70, 0x4b, 0x18, 0x0f, 0x74, 0x47, + 0x6b, 0x37, 0x54, 0x17, 0x84, 0x83, 0x25, 0xda, 0x67, 0x4d, 0xc6, 0x7b, 0x03, 0x1e, 0x7d, 0x64, + 0xe9, 0x5c, 0x14, 0xcf, 0xc6, 0x5a, 0xe0, 0xb7, 0x3a, 0x11, 0x46, 0x61, 0xa6, 0x3c, 0x1b, 0x1d, + 0x2c, 0xc9, 0xf0, 0x6c, 0x70, 0x92, 0xec, 0xd8, 0x85, 0xf1, 0x4f, 0x10, 0xbb, 0x40, 0xa1, 0xb0, + 0xec, 0x37, 0xf6, 0x31, 0xec, 0x72, 0xb4, 0xf6, 0x21, 0xd3, 0x1f, 0x4d, 0xbf, 0xb1, 0xff, 0xe4, + 0xce, 0xdc, 0x91, 0x3d, 0x59, 0x61, 0xdf, 0xce, 0xc4, 0x4a, 0x54, 0x3d, 0x3b, 0xa9, 0x9d, 0x24, + 0x6a, 0x65, 0xdc, 0x50, 0xe1, 0x52, 0x28, 0x3f, 0xc4, 0xd2, 0xc9, 0x09, 0x85, 0xf2, 0x02, 0x0d, + 0xf7, 0x23, 0xbf, 0x33, 0xdf, 0xf4, 0x3a, 0xdb, 0xbe, 0x13, 0xb8, 0xb3, 0xe5, 0x3e, 0x0a, 0xe3, + 0xe5, 0x4c, 0x85, 0x31, 0xe5, 0x72, 0x7a, 0xbb, 0x21, 0x19, 0x58, 0x3d, 0x2c, 0xc9, 0x57, 0x60, + 0x82, 0xcd, 0x96, 0xc5, 0xc7, 0x11, 0x6d, 0x73, 0x51, 0x9a, 0xc2, 0xa5, 0x7e, 0x46, 0xb9, 0xb8, + 0x19, 0x17, 0x72, 0x21, 0x45, 0xed, 0x41, 0x63, 0x02, 0x55, 0x48, 0x75, 0x56, 0xc4, 0x85, 0xd9, + 0x07, 0xce, 0x63, 0x25, 0xcd, 0x91, 0x22, 0xf5, 0x04, 0x25, 0x16, 0x13, 0xea, 0x31, 0x89, 0xdd, + 0x8f, 0x91, 0xfa, 0x4c, 0x80, 0xbe, 0x9c, 0xc8, 0xcf, 0xc2, 0x79, 0xf1, 0x59, 0x0b, 0x98, 0x2b, + 0xc1, 0x0f, 0x0e, 0xea, 0x7b, 0x4e, 0xc0, 0x26, 0xee, 0xf4, 0xe9, 0x34, 0xac, 0xec, 0x30, 0x57, + 0xf2, 0xb1, 0x43, 0xce, 0xc8, 0xea, 0x57, 0x83, 0xf9, 0x93, 0xa9, 0x61, 0x27, 0x4b, 0x30, 0x22, + 0x70, 0xc5, 0xc2, 0xda, 0x5b, 0xfb, 0xb3, 0x99, 0xb5, 0x8f, 0x88, 0xda, 0x2d, 0x49, 0x6f, 0xfe, + 0xb1, 0x01, 0xe3, 0x5a, 0x8f, 0x92, 0xdb, 0x4a, 0xd4, 0x53, 0x12, 0xad, 0xa8, 0xe1, 0x64, 0x3e, + 0xaa, 0x71, 0x5b, 0x84, 0xba, 0xe5, 0xfa, 0xd3, 0x65, 0x26, 0xb1, 0x3b, 0x76, 0xab, 0x97, 0xe4, + 0x8a, 0x28, 0xf4, 0xc9, 0x15, 0xf1, 0xab, 0xe3, 0x30, 0xa1, 0xaf, 0xe1, 0xcc, 0xa8, 0x5e, 0xf6, + 0x77, 0xbd, 0xb6, 0xf4, 0x09, 0xf0, 0xec, 0x27, 0x08, 0xd1, 0x5e, 0xa8, 0x40, 0x08, 0x79, 0x09, + 0x20, 0x3e, 0x5d, 0x97, 0xdb, 0x7e, 0xf1, 0x9e, 0x86, 0x52, 0x40, 0x7e, 0x0a, 0x60, 0xc5, 0x77, + 0x69, 0x9c, 0x40, 0xe7, 0x18, 0x9f, 0xe0, 0xcb, 0xc2, 0x27, 0x28, 0xde, 0xc0, 0x38, 0x3a, 0xac, + 0x9c, 0x6d, 0xfb, 0x2e, 0xed, 0xcd, 0x9c, 0xa3, 0x70, 0x24, 0x5f, 0x84, 0x21, 0xab, 0xdb, 0xa4, + 0x32, 0x9f, 0xcb, 0x98, 0x9c, 0xd3, 0xdd, 0xa6, 0x92, 0x1b, 0x37, 0xe8, 0xa6, 0x8f, 0x82, 0x18, + 0x80, 0xbc, 0x07, 0xc0, 0xc4, 0x16, 0x93, 0x4c, 0xca, 0x0b, 0xe3, 0xe8, 0x22, 0x50, 0x24, 0x1e, + 0x53, 0x53, 0x6a, 0x95, 0x27, 0x24, 0x64, 0x15, 0x46, 0x84, 0x86, 0x14, 0x47, 0x2d, 0xcf, 0x65, + 0x39, 0xf9, 0x14, 0x33, 0x49, 0x24, 0x58, 0x41, 0xb0, 0xee, 0x77, 0xe3, 0x2e, 0x8e, 0xb7, 0x61, + 0x94, 0xb1, 0xdf, 0x08, 0xa9, 0xb8, 0x46, 0x3e, 0xca, 0xc3, 0x4e, 0x95, 0x06, 0x75, 0x43, 0xdd, + 0xc3, 0x90, 0x10, 0x90, 0xaf, 0x60, 0x4a, 0x24, 0xd1, 0xd5, 0xc7, 0xfa, 0x8a, 0xaf, 0xf4, 0x74, + 0xf5, 0x8c, 0xd3, 0xe9, 0x64, 0xe4, 0x90, 0x8b, 0xf9, 0x91, 0xdd, 0xf8, 0x6a, 0x56, 0x9c, 0x20, + 0xfd, 0x98, 0x0a, 0xae, 0xf5, 0x54, 0x30, 0x2b, 0x6f, 0x1b, 0xf5, 0x26, 0x42, 0xd2, 0xf8, 0x92, + 0x0e, 0x94, 0x13, 0x65, 0x22, 0xea, 0x82, 0xe3, 0xea, 0x7a, 0xbd, 0xa7, 0x2e, 0x75, 0x00, 0x7b, + 0xaa, 0xeb, 0xe1, 0x4e, 0xdc, 0x24, 0x99, 0xb5, 0xa8, 0x6f, 0xec, 0xb8, 0xfa, 0x5e, 0xea, 0xa9, + 0x6f, 0xda, 0xdd, 0xee, 0xad, 0x27, 0xc5, 0x93, 0xbc, 0x0d, 0xe3, 0x12, 0x82, 0xf3, 0x03, 0x7d, + 0xb4, 0x62, 0x0b, 0xe3, 0x6e, 0x63, 0xac, 0xa1, 0x9e, 0x05, 0x48, 0x45, 0x56, 0xa9, 0xb9, 0x74, + 0x8c, 0x6b, 0xd4, 0x69, 0xa9, 0xd0, 0x91, 0xc9, 0x97, 0x61, 0x6c, 0xa9, 0xc5, 0x3e, 0xc4, 0x6f, + 0x3b, 0x11, 0xc5, 0xf5, 0x36, 0xf1, 0x7b, 0x2b, 0x25, 0x8a, 0xa8, 0xf2, 0x74, 0xa3, 0x49, 0x91, + 0x6a, 0xaf, 0x28, 0x14, 0xac, 0xf3, 0xb8, 0x6b, 0x4b, 0xc8, 0x70, 0x28, 0x56, 0xd7, 0x67, 0x33, + 0x7c, 0xcf, 0x0a, 0x7b, 0x5c, 0xae, 0xb8, 0xc7, 0xcc, 0x16, 0x13, 0x42, 0xeb, 0x3c, 0x9d, 0x27, + 0x79, 0x07, 0xc6, 0xc4, 0x45, 0xd8, 0xaa, 0xb5, 0x12, 0xce, 0x96, 0xf1, 0xe3, 0x31, 0x85, 0x9f, + 0xbc, 0x33, 0x6b, 0x3b, 0x41, 0xea, 0x00, 0x32, 0xc1, 0x27, 0x5f, 0x82, 0x99, 0x2d, 0xaf, 0xed, + 0xfa, 0x8f, 0x42, 0xa1, 0xc0, 0x85, 0xa2, 0x9b, 0x4a, 0xc2, 0xac, 0x1e, 0xf1, 0x72, 0x5b, 0x2e, + 0x34, 0x3d, 0x8a, 0x2f, 0x93, 0x03, 0xf9, 0xb9, 0x1e, 0xce, 0x5c, 0x82, 0xc8, 0x71, 0x12, 0x34, + 0xd7, 0x23, 0x41, 0xbd, 0xd5, 0xa7, 0xc5, 0x29, 0xb3, 0x1a, 0xe2, 0x03, 0xd1, 0xcd, 0xaa, 0x0f, + 0x7c, 0xaf, 0x3d, 0x3b, 0xad, 0x3d, 0x3f, 0x14, 0x47, 0x5a, 0x23, 0xde, 0x9a, 0xdf, 0xf4, 0x1a, + 0x07, 0x32, 0x95, 0xaf, 0x6e, 0xb0, 0x7d, 0xe4, 0x6b, 0xfe, 0x93, 0x0c, 0xd6, 0xe4, 0xcb, 0x50, + 0x62, 0x7f, 0x63, 0xeb, 0x76, 0x46, 0x3b, 0xad, 0x54, 0x30, 0x45, 0x3d, 0x38, 0x46, 0x78, 0x53, + 0x37, 0xc3, 0xf0, 0xd5, 0x58, 0x99, 0x3f, 0x32, 0x60, 0x26, 0xab, 0xad, 0x27, 0xa4, 0x45, 0x32, + 0x53, 0x71, 0x0b, 0xe8, 0x7a, 0xe1, 0x71, 0x0b, 0x71, 0xb4, 0x42, 0x05, 0x86, 0xee, 0x7b, 0x6d, + 0x57, 0xc6, 0xd5, 0xe1, 0x72, 0xb8, 0xcf, 0x00, 0x16, 0x87, 0x33, 0x04, 0xbc, 0x83, 0x81, 0xeb, + 0xe5, 0x10, 0x47, 0xc0, 0x8b, 0x1a, 0x16, 0x87, 0x33, 0x04, 0xb6, 0xec, 0xca, 0x65, 0x02, 0x11, + 0xd8, 0x6a, 0x1c, 0x5a, 0x1c, 0x4e, 0xae, 0xc0, 0xc8, 0x6a, 0x7b, 0x99, 0x3a, 0x0f, 0xa9, 0x38, + 0x34, 0x44, 0x57, 0x91, 0xdf, 0xb6, 0x9b, 0x0c, 0x66, 0xc9, 0x42, 0xf3, 0xbb, 0x06, 0x4c, 0xf5, + 0x74, 0xd3, 0xc9, 0x99, 0x9f, 0x8e, 0x3f, 0xa1, 0x1d, 0xe4, 0xfb, 0x78, 0xf3, 0x0b, 0xd9, 0xcd, + 0x37, 0xff, 0xa0, 0x00, 0xe7, 0xfb, 0xac, 0x5a, 0x49, 0x74, 0x85, 0x71, 0x62, 0x74, 0xc5, 0x57, + 0xd9, 0x2a, 0xe1, 0x78, 0xad, 0x70, 0xdd, 0x4f, 0x5a, 0x9c, 0x1c, 0x44, 0x61, 0x99, 0x4c, 0xad, + 0x22, 0xd3, 0x80, 0x5c, 0x68, 0x20, 0x85, 0x1d, 0xf9, 0x3d, 0xfe, 0x78, 0x9d, 0x59, 0x4f, 0x7c, + 0x43, 0xfe, 0x6f, 0x49, 0x7c, 0x83, 0x7e, 0xaa, 0x58, 0x78, 0xa2, 0xa7, 0x8a, 0xd9, 0x07, 0x10, + 0x43, 0x9f, 0xe4, 0x28, 0x6e, 0x1e, 0xc6, 0xeb, 0xd4, 0x09, 0x1a, 0x7b, 0xd5, 0x90, 0x0f, 0xd2, + 0x30, 0x72, 0x43, 0x95, 0x1c, 0x62, 0x81, 0xed, 0x84, 0xbd, 0x63, 0xa1, 0xd1, 0x98, 0xff, 0x3e, + 0x15, 0x96, 0xf1, 0xb7, 0x51, 0x5e, 0x5e, 0x81, 0xa1, 0xad, 0x3d, 0x1a, 0x48, 0x23, 0x19, 0x1b, + 0xf2, 0x88, 0x01, 0xd4, 0x86, 0x20, 0x86, 0xf9, 0xb3, 0x50, 0x52, 0x2b, 0x43, 0x85, 0xc0, 0x7e, + 0x8b, 0x19, 0xc9, 0x15, 0x02, 0x03, 0x58, 0x1c, 0x7e, 0x62, 0x36, 0xb6, 0xa4, 0x17, 0xf2, 0x27, + 0xf5, 0x02, 0xab, 0x1c, 0xe5, 0x4d, 0xa9, 0x1c, 0x7f, 0xab, 0x95, 0x47, 0x0c, 0x60, 0x71, 0xf8, + 0x13, 0xad, 0xfc, 0xdf, 0x18, 0x50, 0xc0, 0x4c, 0x18, 0x6f, 0xc0, 0xa8, 0xf4, 0x67, 0xab, 0xd9, + 0x21, 0xa6, 0xa5, 0xbb, 0x3b, 0xd4, 0x83, 0x6a, 0x04, 0x90, 0x55, 0xb5, 0x49, 0x83, 0x6d, 0x2d, + 0xf6, 0xea, 0x21, 0x03, 0xa8, 0x55, 0x21, 0xc6, 0x29, 0xc6, 0x03, 0xe3, 0xcb, 0xc4, 0x76, 0x94, + 0xab, 0x2c, 0x1e, 0x5f, 0xd6, 0xb3, 0xf7, 0x94, 0x58, 0xe6, 0x6f, 0x18, 0x70, 0x36, 0xd3, 0x92, + 0x61, 0xb5, 0x72, 0x93, 0x49, 0x11, 0xc7, 0xb4, 0xbd, 0xc4, 0x31, 0x4e, 0x13, 0x47, 0x76, 0x0a, + 0xd9, 0x7a, 0x1e, 0x46, 0xe3, 0x1d, 0x26, 0x99, 0x91, 0x43, 0x87, 0x4e, 0x4f, 0xb9, 0x1d, 0xfb, + 0x1b, 0x03, 0x86, 0x59, 0x13, 0x9e, 0xda, 0x6b, 0x45, 0xd9, 0x2e, 0x70, 0xf6, 0x49, 0x03, 0x5d, + 0x26, 0xfa, 0xdd, 0x61, 0x80, 0x04, 0x99, 0x6c, 0xc3, 0xc4, 0xea, 0xd2, 0xc2, 0xfc, 0x92, 0x4b, + 0xdb, 0x11, 0x9e, 0x01, 0xa7, 0xd2, 0x4b, 0xb0, 0xad, 0x71, 0xd0, 0x76, 0x9a, 0x02, 0xe1, 0x20, + 0xd1, 0x0d, 0xbe, 0xe7, 0x36, 0x6c, 0x2f, 0xa6, 0x53, 0x4d, 0x4a, 0x9d, 0x23, 0xab, 0xa3, 0x5e, + 0x7d, 0xb0, 0xac, 0xd4, 0x91, 0x1b, 0xb0, 0x8e, 0xd0, 0x69, 0x35, 0xfb, 0xd4, 0xa1, 0x73, 0x24, + 0x7b, 0x50, 0xbe, 0x8b, 0xab, 0x8f, 0x52, 0x4b, 0xfe, 0xf8, 0x5a, 0x5e, 0x10, 0xb5, 0x3c, 0xc3, + 0x97, 0xad, 0xec, 0x7a, 0x7a, 0xb8, 0x26, 0x92, 0x5b, 0x38, 0x51, 0x72, 0xff, 0x1f, 0x03, 0x86, + 0xf9, 0xf2, 0x16, 0xbf, 0x21, 0x94, 0xb9, 0x80, 0x6e, 0x3d, 0x99, 0x05, 0xb4, 0x8c, 0x9a, 0x4b, + 0x73, 0x21, 0xf0, 0x32, 0xb2, 0x90, 0x7a, 0x90, 0x48, 0x9e, 0x73, 0xa0, 0x69, 0xcd, 0x4b, 0x92, + 0x68, 0x3c, 0xfe, 0x16, 0x91, 0xca, 0x85, 0x63, 0xa8, 0xcf, 0xa3, 0x8e, 0x7c, 0xc2, 0xe7, 0x51, + 0x97, 0x61, 0x54, 0x84, 0x97, 0xd5, 0x0e, 0xc4, 0x06, 0x5a, 0xba, 0x88, 0x62, 0xb8, 0x92, 0x75, + 0x9d, 0x83, 0xec, 0x6d, 0x2d, 0x67, 0x62, 0x8c, 0x48, 0x56, 0x61, 0x34, 0xb9, 0x13, 0x35, 0xaa, + 0x1d, 0x56, 0xc7, 0x70, 0x11, 0x7f, 0xcd, 0xaf, 0xdd, 0x66, 0x5e, 0x81, 0x4a, 0x78, 0x98, 0xdf, + 0x32, 0xa0, 0x9c, 0x96, 0x17, 0xf2, 0x36, 0x8c, 0xc5, 0xd7, 0xd2, 0xe2, 0xe8, 0x13, 0xf4, 0x36, + 0x27, 0xf7, 0xd8, 0xb4, 0x38, 0x14, 0x15, 0x9d, 0xcc, 0x41, 0x91, 0x4d, 0x3b, 0x25, 0x69, 0x36, + 0xea, 0x93, 0xae, 0x80, 0xa9, 0x87, 0xaf, 0x12, 0x4f, 0x99, 0xb5, 0xff, 0x31, 0x0f, 0x63, 0xca, + 0x60, 0x91, 0x57, 0xa0, 0xb8, 0x14, 0x2e, 0xfb, 0x8d, 0x7d, 0xea, 0x8a, 0x33, 0x1d, 0x7c, 0xfd, + 0xd6, 0x0b, 0xed, 0x26, 0x02, 0xad, 0xb8, 0x98, 0xd4, 0x60, 0x9c, 0xff, 0x27, 0xaf, 0x1f, 0xe7, + 0x12, 0x7f, 0x34, 0x47, 0x96, 0x17, 0x8f, 0xd5, 0xe5, 0x5d, 0x23, 0x21, 0x5f, 0x03, 0xe0, 0x00, + 0x36, 0xbe, 0x03, 0x44, 0x97, 0xcb, 0x09, 0x7c, 0x56, 0x54, 0x10, 0x79, 0xea, 0x17, 0xa2, 0x28, + 0x28, 0x0c, 0xf1, 0xe5, 0x4d, 0xbf, 0xb1, 0x3f, 0xf8, 0xdb, 0xbb, 0xc9, 0xcb, 0x9b, 0x7e, 0x63, + 0xdf, 0xce, 0x0e, 0x35, 0x54, 0x59, 0x92, 0x6f, 0x1b, 0x70, 0xd1, 0xa2, 0x0d, 0xff, 0x21, 0x0d, + 0x0e, 0xaa, 0x11, 0x62, 0xa9, 0x35, 0x9e, 0x1c, 0xd7, 0x78, 0x4b, 0xd4, 0xf8, 0x72, 0x20, 0xb8, + 0xe0, 0x9d, 0xa8, 0x56, 0x27, 0xb2, 0x8f, 0x69, 0xc2, 0x31, 0x55, 0x9a, 0x7f, 0x6e, 0x28, 0x53, + 0x80, 0xac, 0xc0, 0x68, 0x2c, 0x2c, 0xc2, 0x65, 0x1a, 0x5b, 0x66, 0x12, 0x6e, 0xd1, 0x9d, 0xda, + 0x33, 0xe2, 0xf8, 0x65, 0x3a, 0x16, 0x39, 0x6d, 0x46, 0x48, 0x20, 0x79, 0x1f, 0x0a, 0x38, 0x54, + 0x27, 0x67, 0x59, 0x93, 0x4b, 0x4d, 0x81, 0x8d, 0x11, 0xb6, 0x1a, 0x29, 0xc9, 0xe7, 0x44, 0x0c, + 0x50, 0x5e, 0xcb, 0x5f, 0xcc, 0x40, 0xac, 0x1d, 0xf1, 0x1a, 0x93, 0x44, 0xb7, 0x2a, 0xd2, 0xfa, + 0xff, 0xe5, 0xa0, 0x9c, 0x9e, 0x78, 0xe4, 0x3d, 0x28, 0xc9, 0xfb, 0x6d, 0xf7, 0x9c, 0x70, 0x4f, + 0xe4, 0x44, 0xc5, 0x5d, 0xab, 0xbc, 0x14, 0x67, 0xef, 0x39, 0x5a, 0xee, 0x3c, 0x8d, 0x80, 0x2d, + 0xc8, 0xeb, 0xe2, 0xd2, 0x84, 0x32, 0x81, 0x22, 0x3f, 0xea, 0xa4, 0x72, 0xa2, 0x4a, 0x34, 0xf2, + 0x06, 0xe4, 0xf9, 0xa5, 0x4f, 0x35, 0xa1, 0xd6, 0x83, 0x3b, 0x55, 0x7e, 0x67, 0x8d, 0x9f, 0xf8, + 0xeb, 0x47, 0x27, 0x0c, 0x9f, 0x2c, 0x2b, 0x57, 0x06, 0x87, 0xb5, 0xc4, 0x42, 0x12, 0x1c, 0x7f, + 0xdc, 0xc9, 0x77, 0x07, 0x3f, 0x28, 0x14, 0xf3, 0xe5, 0x82, 0xb8, 0x24, 0xf6, 0xfb, 0x79, 0x18, + 0x8d, 0xeb, 0x27, 0x04, 0xd0, 0xde, 0x10, 0x47, 0xf7, 0xf8, 0x3f, 0xb9, 0x00, 0x45, 0x69, 0x62, + 0x88, 0xe3, 0xfb, 0x91, 0x50, 0x98, 0x17, 0xb3, 0x20, 0x6d, 0x09, 0x6e, 0x5e, 0x58, 0xf2, 0x27, + 0xb9, 0x09, 0xb1, 0xa1, 0xd0, 0xcf, 0xa2, 0x28, 0xb0, 0x01, 0xb3, 0x62, 0x34, 0x32, 0x01, 0x39, + 0x8f, 0x07, 0xc4, 0x8f, 0x5a, 0x39, 0xcf, 0x25, 0xef, 0x41, 0xd1, 0x71, 0x5d, 0xea, 0xda, 0x4e, + 0x34, 0xc0, 0x3b, 0xc8, 0x45, 0xc6, 0x8d, 0x6b, 0x74, 0xa4, 0xaa, 0x46, 0xa4, 0x0a, 0xa3, 0xf8, + 0x0c, 0x6e, 0x37, 0x1c, 0xe8, 0xed, 0xdc, 0x84, 0x43, 0x91, 0x91, 0x6d, 0x84, 0xd4, 0x25, 0x2f, + 0x43, 0x81, 0x8d, 0xa6, 0x58, 0x0f, 0xe2, 0x34, 0x89, 0xab, 0xeb, 0x6b, 0xbc, 0xc3, 0xee, 0x9d, + 0xb1, 0x10, 0x81, 0xbc, 0x08, 0xf9, 0xee, 0xdc, 0x8e, 0xd0, 0xf4, 0xe5, 0xe4, 0x3e, 0x70, 0x8c, + 0xc6, 0x8a, 0xc9, 0x2d, 0x28, 0x3e, 0xd2, 0x6f, 0x7e, 0x9e, 0x4d, 0x0d, 0x63, 0x8c, 0x1f, 0x23, + 0xd6, 0x8a, 0x30, 0xcc, 0xef, 0x3c, 0x9a, 0xcf, 0x01, 0x24, 0x55, 0xf7, 0x46, 0x59, 0x98, 0x5f, + 0x83, 0xd1, 0xb8, 0x4a, 0xf2, 0x2c, 0xc0, 0x3e, 0x3d, 0xb0, 0xf7, 0x9c, 0xb6, 0x2b, 0xde, 0xf4, + 0x29, 0x59, 0xa3, 0xfb, 0xf4, 0xe0, 0x1e, 0x02, 0xc8, 0x79, 0x18, 0xe9, 0xb0, 0x51, 0x95, 0x19, + 0x7d, 0xad, 0xe1, 0x4e, 0x77, 0x9b, 0x49, 0xe8, 0x2c, 0x8c, 0xa0, 0xf3, 0x43, 0x4c, 0xb4, 0x71, + 0x4b, 0xfe, 0x34, 0x7f, 0x3b, 0x87, 0xb9, 0x1e, 0x94, 0x76, 0x92, 0x17, 0x60, 0xbc, 0x11, 0x50, + 0x5c, 0x8e, 0x1c, 0x66, 0x16, 0x89, 0x7a, 0x4a, 0x09, 0x70, 0xc9, 0x25, 0x57, 0x60, 0x32, 0x49, + 0x31, 0x6c, 0x37, 0xb6, 0xc5, 0xbd, 0xef, 0x92, 0x35, 0xde, 0x91, 0x39, 0x86, 0xe7, 0xb7, 0xf1, + 0x22, 0x47, 0x59, 0xbd, 0xef, 0x18, 0xc9, 0x74, 0xc1, 0xa3, 0xd6, 0xa4, 0x02, 0xc7, 0x83, 0x93, + 0x73, 0x30, 0xec, 0x38, 0xbb, 0x5d, 0x8f, 0x07, 0x95, 0x97, 0x2c, 0xf1, 0x8b, 0xbc, 0x0a, 0x53, + 0xa1, 0xb7, 0xdb, 0x76, 0xa2, 0x6e, 0x20, 0x92, 0x6d, 0xd0, 0x00, 0x45, 0x6a, 0xdc, 0x2a, 0xc7, + 0x05, 0xf3, 0x1c, 0x4e, 0x5e, 0x07, 0xa2, 0xd6, 0xe7, 0x6f, 0x7f, 0x44, 0x1b, 0x5c, 0xd4, 0x4a, + 0xd6, 0x94, 0x52, 0xb2, 0x8a, 0x05, 0xe4, 0x79, 0x28, 0x05, 0x34, 0x44, 0x93, 0x0c, 0xbb, 0x0d, + 0x53, 0x08, 0x59, 0x63, 0x12, 0x76, 0x9f, 0x1e, 0x98, 0x35, 0x98, 0xea, 0x99, 0x8f, 0xe4, 0x75, + 0x6e, 0xdd, 0x8b, 0xf5, 0xb9, 0xc4, 0x37, 0x33, 0xf8, 0xf4, 0x95, 0xfe, 0x72, 0x3a, 0x47, 0x32, + 0xdb, 0x50, 0x52, 0xf5, 0xeb, 0x09, 0x37, 0xea, 0xcf, 0x61, 0xd8, 0x29, 0x57, 0x3e, 0xc3, 0x47, + 0x87, 0x95, 0x9c, 0xe7, 0x62, 0xb0, 0xe9, 0x55, 0x28, 0x4a, 0x2b, 0x41, 0x7d, 0x7f, 0x46, 0x18, + 0x94, 0x07, 0x56, 0x5c, 0x6a, 0xbe, 0x0c, 0x23, 0x42, 0x85, 0x1e, 0xef, 0x88, 0x32, 0xbf, 0x91, + 0x83, 0x49, 0x8b, 0xb2, 0x09, 0x2e, 0x5e, 0x76, 0xf9, 0x8c, 0x25, 0x5b, 0xd6, 0xbe, 0xed, 0x98, + 0x04, 0x16, 0xdf, 0x33, 0x60, 0x3a, 0x03, 0xf7, 0x63, 0x65, 0x67, 0xbb, 0x0d, 0xa3, 0x0b, 0x9e, + 0xd3, 0xac, 0xba, 0x6e, 0x1c, 0x3e, 0x8b, 0xd6, 0xa0, 0xcb, 0xa6, 0x93, 0xc3, 0xa0, 0xea, 0x62, + 0x1a, 0xa3, 0x92, 0x6b, 0x42, 0x28, 0x92, 0xfc, 0x91, 0x32, 0x9d, 0x33, 0xf0, 0x36, 0x25, 0xc9, + 0x9c, 0xf1, 0x2e, 0x24, 0x07, 0x26, 0xa7, 0xb3, 0x4f, 0xed, 0xd0, 0x65, 0xdf, 0x85, 0x4c, 0x7f, + 0xde, 0x40, 0xdb, 0xce, 0x6f, 0xe5, 0xe0, 0x5c, 0x36, 0xe1, 0xc7, 0x4d, 0xb4, 0x87, 0xd9, 0x43, + 0x94, 0x8c, 0xd9, 0x98, 0x68, 0x8f, 0xa7, 0x1a, 0x41, 0xfc, 0x04, 0x81, 0xec, 0xc0, 0xf8, 0xb2, + 0x13, 0x46, 0xf7, 0xa8, 0x13, 0x44, 0xdb, 0xd4, 0x89, 0x06, 0xb0, 0x60, 0xe3, 0xf7, 0xc9, 0x71, + 0x51, 0xdb, 0x93, 0x94, 0xe9, 0xf7, 0xc9, 0x35, 0xb6, 0xb1, 0xa0, 0x14, 0x06, 0x10, 0x94, 0xaf, + 0xc3, 0x64, 0x9d, 0xb6, 0x9c, 0xce, 0x9e, 0x1f, 0x50, 0xe1, 0x3b, 0xbf, 0x0e, 0xe3, 0x31, 0x28, + 0x53, 0x5a, 0xf4, 0x62, 0x0d, 0x5f, 0xe9, 0x88, 0x44, 0x95, 0xe8, 0xc5, 0xe6, 0x6f, 0xe6, 0xe0, + 0x7c, 0xb5, 0x21, 0x0e, 0x1a, 0x44, 0x81, 0x3c, 0x0f, 0xfd, 0x94, 0xeb, 0x26, 0x37, 0x60, 0xf4, + 0x81, 0xf3, 0x78, 0x99, 0xe2, 0x0b, 0xc2, 0x3c, 0x5d, 0x13, 0x37, 0xbf, 0x9c, 0xc7, 0x76, 0xec, + 0xf6, 0xb2, 0x12, 0x1c, 0x75, 0xb3, 0x59, 0xf8, 0x84, 0x9b, 0x4d, 0x13, 0x86, 0xef, 0xf9, 0x4d, + 0x57, 0x2c, 0x4e, 0xe2, 0xdc, 0x62, 0x0f, 0x21, 0x96, 0x28, 0x31, 0x7f, 0x64, 0xc0, 0x44, 0xdc, + 0x62, 0x6c, 0xc2, 0xa7, 0xde, 0x25, 0x57, 0x60, 0x04, 0x2b, 0x8a, 0x5f, 0x47, 0xc2, 0x45, 0xa3, + 0xc9, 0x40, 0xb6, 0xe7, 0x5a, 0xb2, 0x50, 0xed, 0x89, 0xa1, 0x4f, 0xd6, 0x13, 0xe6, 0x3f, 0xc2, + 0x23, 0x11, 0xf5, 0x2b, 0xd9, 0x4a, 0xa4, 0x34, 0xc4, 0x18, 0xb0, 0x21, 0xb9, 0x27, 0x36, 0x24, + 0xf9, 0xbe, 0x43, 0xf2, 0xcd, 0x1c, 0x8c, 0xc5, 0x8d, 0xfd, 0x8c, 0x25, 0x11, 0x88, 0xbf, 0x6b, + 0xa0, 0x10, 0xfa, 0xba, 0xa2, 0x2b, 0x44, 0xa4, 0xfa, 0xfb, 0x30, 0x2c, 0x26, 0x93, 0x91, 0x3a, + 0x17, 0x4c, 0x8d, 0x6e, 0xf2, 0xc6, 0x34, 0x0e, 0x68, 0x68, 0x09, 0x3a, 0xbc, 0xa3, 0xb0, 0x45, + 0xb7, 0xc5, 0x09, 0xd9, 0x53, 0xbb, 0x46, 0x65, 0xdf, 0x51, 0x48, 0x3e, 0x6c, 0xa0, 0xd5, 0xe9, + 0xef, 0x15, 0xa0, 0x9c, 0x26, 0x39, 0x39, 0x4d, 0xc3, 0x5a, 0x77, 0x5b, 0x3c, 0xd0, 0x81, 0x69, + 0x1a, 0x3a, 0xdd, 0x6d, 0x8b, 0xc1, 0xc8, 0x15, 0x28, 0xac, 0x05, 0xde, 0x43, 0xfc, 0x6a, 0xf1, + 0x3e, 0x49, 0x27, 0xf0, 0x1e, 0xaa, 0xc1, 0xba, 0xac, 0x1c, 0x37, 0xb4, 0xcb, 0x75, 0xe5, 0x79, + 0x7f, 0xbe, 0xa1, 0x6d, 0x86, 0xe9, 0x7c, 0x40, 0x12, 0x8d, 0x2d, 0x95, 0x35, 0xea, 0x04, 0x22, + 0xa5, 0x80, 0x50, 0x67, 0xb8, 0x54, 0x6e, 0x23, 0x98, 0x27, 0xfb, 0xb5, 0x54, 0x24, 0xd2, 0x04, + 0xa2, 0xfc, 0x94, 0x13, 0xf8, 0xe4, 0x3d, 0x9e, 0x7c, 0x57, 0x6b, 0x46, 0x65, 0x6d, 0xab, 0xb3, + 0x39, 0x83, 0xef, 0x93, 0xf4, 0x11, 0xae, 0xc1, 0x28, 0xba, 0xbc, 0xd0, 0x91, 0x51, 0x3c, 0x91, + 0x99, 0x0c, 0x8c, 0x06, 0x8c, 0x27, 0xb0, 0x63, 0x77, 0x46, 0xc2, 0x84, 0xbc, 0x0b, 0x63, 0x6a, + 0x34, 0x2f, 0x8f, 0x39, 0xbd, 0xc4, 0xef, 0x8f, 0xf5, 0xc9, 0x9b, 0xa7, 0x12, 0x98, 0x9f, 0x53, + 0xa5, 0x44, 0x2c, 0xda, 0xc7, 0x4a, 0x89, 0xf9, 0xeb, 0x68, 0xc6, 0xb7, 0xfc, 0x88, 0x0a, 0xeb, + 0xe5, 0xa9, 0xd5, 0x63, 0x89, 0x0b, 0x79, 0x48, 0x8b, 0x69, 0xd1, 0xbe, 0xee, 0x14, 0x0f, 0xdb, + 0xff, 0x9e, 0x01, 0x67, 0x33, 0x69, 0xc9, 0x75, 0x80, 0xc4, 0x46, 0x14, 0xbd, 0xc4, 0xb3, 0x28, + 0xc7, 0x50, 0x4b, 0xc1, 0x20, 0x5f, 0x4d, 0x5b, 0x77, 0x27, 0x2f, 0x4e, 0xf2, 0xad, 0x91, 0x09, + 0xdd, 0xba, 0xcb, 0xb0, 0xe9, 0xcc, 0xef, 0xe5, 0x61, 0xaa, 0xe7, 0x8d, 0xca, 0x13, 0xa2, 0x08, + 0xf6, 0x53, 0x2f, 0xa0, 0xf1, 0xe3, 0x8e, 0x6b, 0xfd, 0x5e, 0xc8, 0xcc, 0x78, 0x0f, 0x0d, 0xdd, + 0x62, 0x22, 0x81, 0xf7, 0x09, 0xcf, 0xa2, 0x85, 0xd9, 0x6f, 0xe7, 0xbd, 0xda, 0xb7, 0xb6, 0x27, + 0xf0, 0x86, 0xde, 0xdf, 0xe2, 0x27, 0xc6, 0x7e, 0x3d, 0x07, 0xd3, 0x3d, 0xdf, 0xfc, 0xd4, 0xce, + 0xba, 0xf7, 0xb5, 0xd5, 0xed, 0xb9, 0x7e, 0x63, 0x3a, 0x90, 0x15, 0xf1, 0xdf, 0x0d, 0x38, 0xdf, + 0x87, 0x92, 0x1c, 0xa4, 0x85, 0x88, 0x5b, 0x15, 0x37, 0x8f, 0xaf, 0xf0, 0x89, 0x88, 0xd2, 0xa7, + 0x26, 0x09, 0xdf, 0xc8, 0x01, 0x6c, 0xd1, 0xed, 0xa7, 0x3b, 0x07, 0xd5, 0x17, 0x34, 0x01, 0x50, + 0x1c, 0x98, 0x83, 0xa7, 0xa0, 0x5a, 0x45, 0x47, 0xe2, 0xe0, 0x09, 0xa8, 0xe2, 0xf7, 0x54, 0x72, + 0xd9, 0xef, 0xa9, 0x98, 0xdb, 0x30, 0x73, 0x97, 0x46, 0xc9, 0x4a, 0x28, 0xf7, 0x90, 0xc7, 0xb3, + 0x7d, 0x0d, 0x46, 0x05, 0xbe, 0x9e, 0x1b, 0x5f, 0x86, 0xc4, 0x79, 0xae, 0x95, 0x20, 0x98, 0x14, + 0xce, 0x2f, 0xd0, 0x26, 0x8d, 0xe8, 0xa7, 0x5b, 0x4d, 0x1d, 0x08, 0xff, 0x14, 0xfe, 0xcc, 0xc6, + 0x40, 0x35, 0x9c, 0xd8, 0x3f, 0x9b, 0x70, 0x36, 0x6e, 0xfb, 0x93, 0xe4, 0x7b, 0x83, 0xd9, 0x12, + 0xe2, 0x42, 0x64, 0xc2, 0xf1, 0x18, 0x27, 0xe2, 0x63, 0xb8, 0x28, 0x09, 0xb6, 0xbc, 0xf8, 0x24, + 0x66, 0x20, 0x5a, 0xf2, 0x36, 0x8c, 0x29, 0x34, 0xe2, 0x5a, 0x37, 0x9e, 0x76, 0x3e, 0xf2, 0xa2, + 0x3d, 0x3b, 0xe4, 0x70, 0xf5, 0xb4, 0x53, 0x41, 0x37, 0xbf, 0x02, 0xcf, 0xc4, 0x71, 0x2b, 0x19, + 0x55, 0xa7, 0x98, 0x1b, 0xa7, 0x63, 0xbe, 0x92, 0x7c, 0xd6, 0x52, 0x3b, 0x8e, 0x80, 0x97, 0xbc, + 0x89, 0xfa, 0x59, 0xe2, 0x63, 0x2e, 0x29, 0xb9, 0xf9, 0xc4, 0x5a, 0x94, 0x00, 0xcc, 0xb7, 0x94, + 0xc6, 0x66, 0x30, 0xd4, 0x88, 0x8d, 0x34, 0xf1, 0x37, 0x72, 0x30, 0xb9, 0xba, 0xb4, 0x30, 0x1f, + 0xbb, 0x91, 0x3f, 0x63, 0x09, 0xb2, 0xb4, 0x6f, 0xeb, 0xaf, 0x6f, 0xcc, 0x0d, 0x98, 0x4e, 0x75, + 0x03, 0xbe, 0x22, 0xf4, 0x2e, 0x8f, 0x2f, 0x89, 0xc1, 0x72, 0x65, 0x39, 0x97, 0xc5, 0x7e, 0xf3, + 0x96, 0x95, 0xc2, 0x36, 0xbf, 0x37, 0x9c, 0xe2, 0x2b, 0x54, 0xd8, 0x6b, 0x30, 0xba, 0x14, 0x86, + 0x5d, 0x1a, 0x6c, 0x58, 0xcb, 0xaa, 0x8d, 0xe8, 0x21, 0xd0, 0xee, 0x06, 0x4d, 0x2b, 0x41, 0x20, + 0xaf, 0x40, 0x51, 0x5c, 0xc2, 0x93, 0x3a, 0x01, 0x8f, 0xcb, 0xe3, 0x3b, 0x7c, 0x56, 0x5c, 0x4c, + 0xde, 0x80, 0x12, 0xff, 0x9f, 0x4b, 0x9b, 0xe8, 0x70, 0xf4, 0x55, 0x09, 0x74, 0x2e, 0x9d, 0x96, + 0x86, 0xc6, 0x76, 0x66, 0xf2, 0x99, 0x52, 0xd6, 0xa2, 0x42, 0xb2, 0x33, 0x93, 0x2f, 0x9a, 0x62, + 0x9b, 0x54, 0x24, 0x72, 0x0d, 0xf2, 0xd5, 0x79, 0x4b, 0x4d, 0x07, 0xee, 0x34, 0x02, 0x9e, 0x4e, + 0x5f, 0x7b, 0x09, 0xac, 0x3a, 0x6f, 0x91, 0x39, 0x28, 0xe2, 0x4b, 0x2f, 0x2e, 0x0d, 0x44, 0xd4, + 0x2b, 0x4a, 0x4d, 0x47, 0xc0, 0xd4, 0x93, 0x47, 0x89, 0x47, 0x6e, 0xc0, 0xc8, 0x82, 0x17, 0x76, + 0x9a, 0xce, 0x81, 0xc8, 0x8c, 0x83, 0x87, 0x21, 0x2e, 0x07, 0xa9, 0x72, 0x26, 0xb0, 0xc8, 0x2b, + 0x30, 0x54, 0x6f, 0xf8, 0x1d, 0xb6, 0xdb, 0x8a, 0x43, 0x5b, 0x42, 0x06, 0xd0, 0xf2, 0x5e, 0x30, + 0x00, 0xde, 0x0b, 0xe7, 0xd7, 0xdb, 0x46, 0x95, 0x7b, 0xe1, 0xe9, 0x6b, 0x6d, 0x02, 0xa7, 0x37, + 0xf8, 0x10, 0x9e, 0x64, 0xf0, 0xe1, 0x36, 0x9c, 0xbf, 0x8b, 0xa6, 0x7e, 0x9d, 0x06, 0x98, 0x8c, + 0x94, 0xbf, 0x1a, 0xb5, 0x61, 0x2d, 0x89, 0x2b, 0x7d, 0x78, 0xc1, 0x8a, 0xef, 0x06, 0xec, 0x90, + 0xe3, 0xc8, 0x07, 0xa7, 0x52, 0x4f, 0x65, 0xf4, 0x63, 0x44, 0xbe, 0x04, 0x33, 0x59, 0x45, 0xe2, + 0x72, 0x1f, 0xc6, 0xb5, 0x67, 0x57, 0xa0, 0x06, 0x96, 0x67, 0x71, 0x20, 0xcb, 0x50, 0xe6, 0xf0, + 0xaa, 0xdb, 0xf2, 0xda, 0x8b, 0x2d, 0xc7, 0x6b, 0xe2, 0x55, 0x3f, 0x71, 0x5f, 0x53, 0x70, 0x75, + 0x58, 0xa1, 0x4d, 0x59, 0xa9, 0x16, 0x9d, 0x94, 0xa2, 0x44, 0x75, 0x54, 0xaf, 0x3e, 0x58, 0x4e, + 0xe6, 0xd4, 0x67, 0xeb, 0xdc, 0x48, 0xfb, 0xb6, 0x63, 0xce, 0x8d, 0x36, 0x60, 0x3a, 0xd5, 0x0d, + 0x52, 0x1d, 0x69, 0xe0, 0xb4, 0x3a, 0x4a, 0xd1, 0x58, 0x29, 0x6c, 0xf3, 0x3f, 0x0d, 0xa7, 0xf8, + 0x0a, 0x5f, 0x91, 0x09, 0xc3, 0x5c, 0xdb, 0xa8, 0xa9, 0xf3, 0xb8, 0x2e, 0xb2, 0x44, 0x09, 0xb9, + 0x00, 0xf9, 0x7a, 0x7d, 0x55, 0x4d, 0xec, 0x19, 0x86, 0xbe, 0xc5, 0x60, 0x6c, 0x84, 0xd0, 0x0d, + 0xa4, 0x5c, 0x31, 0x6b, 0xd0, 0x20, 0x12, 0xef, 0xd8, 0xbe, 0x94, 0xcc, 0xe3, 0x42, 0xd2, 0xdf, + 0x62, 0x1e, 0x27, 0xb3, 0x77, 0x1e, 0x66, 0xab, 0x61, 0x48, 0x83, 0x88, 0xbf, 0x46, 0x10, 0x76, + 0x5b, 0x34, 0x10, 0xb2, 0x26, 0x74, 0x0c, 0x7f, 0x05, 0xbf, 0x11, 0x5a, 0x7d, 0x11, 0xc9, 0x55, + 0x28, 0x56, 0xbb, 0xae, 0x47, 0xdb, 0x0d, 0x2d, 0xba, 0xde, 0x11, 0x30, 0x2b, 0x2e, 0x25, 0x1f, + 0xc2, 0x59, 0x41, 0x24, 0x15, 0x8e, 0xe8, 0x01, 0xae, 0x6b, 0xf8, 0x0e, 0x56, 0xcc, 0x05, 0xa9, + 0xa6, 0x6c, 0xd1, 0x25, 0xd9, 0x94, 0xa4, 0x0a, 0xe5, 0x45, 0x3c, 0x27, 0x95, 0xaf, 0x59, 0xfb, + 0x81, 0xc8, 0x3a, 0x8d, 0x9a, 0x8b, 0x9f, 0xa1, 0xda, 0x6e, 0x5c, 0x68, 0xf5, 0xa0, 0x93, 0xfb, + 0x30, 0x9d, 0x86, 0x31, 0x7d, 0x3c, 0x9a, 0xbc, 0x36, 0xd7, 0xc3, 0x05, 0x15, 0x73, 0x16, 0x15, + 0xd9, 0x86, 0xa9, 0x6a, 0x14, 0x05, 0xde, 0x76, 0x37, 0xa2, 0x29, 0xd5, 0x25, 0x1d, 0x8d, 0x71, + 0xb9, 0x54, 0x5f, 0xcf, 0x08, 0x61, 0x9c, 0x76, 0x62, 0xca, 0x58, 0x85, 0x59, 0xbd, 0xec, 0x88, + 0x1b, 0x3f, 0x58, 0x29, 0x1e, 0x75, 0x14, 0x57, 0xa2, 0xa4, 0x43, 0xb7, 0x1a, 0x1e, 0xb4, 0x5a, + 0x34, 0x0a, 0xf0, 0xe4, 0x1e, 0x1f, 0x7d, 0x34, 0x45, 0x0c, 0xd0, 0x45, 0xe5, 0x9d, 0x56, 0x7c, + 0xd8, 0x53, 0x0b, 0x8f, 0xd4, 0x78, 0x6a, 0xcb, 0x47, 0x69, 0xc0, 0xe5, 0xa3, 0x09, 0x53, 0x8b, + 0xed, 0x46, 0x70, 0x80, 0x77, 0x33, 0x65, 0xe3, 0xc6, 0x4f, 0x68, 0x9c, 0x7c, 0xd1, 0xe5, 0x92, + 0x23, 0x25, 0x2c, 0xab, 0x79, 0xbd, 0x8c, 0xcd, 0xff, 0x0b, 0xca, 0xe9, 0xbe, 0xfc, 0x84, 0xaf, + 0x74, 0x9f, 0x26, 0x34, 0x9b, 0x8d, 0x74, 0xfa, 0x5b, 0xc8, 0x0d, 0xed, 0x29, 0x66, 0x23, 0x49, + 0x1d, 0xa0, 0x3c, 0x9a, 0xac, 0x3d, 0xc0, 0x2c, 0xa7, 0x71, 0x2e, 0x6b, 0x1a, 0x9b, 0xbf, 0x94, + 0x83, 0x29, 0x1e, 0x4d, 0xfa, 0xf4, 0xdb, 0x8a, 0xef, 0x6a, 0xca, 0x59, 0xfa, 0x02, 0x53, 0x5f, + 0x77, 0x8c, 0xb5, 0xf8, 0x35, 0x38, 0xdb, 0xd3, 0x15, 0xa8, 0xa0, 0x17, 0x64, 0x1c, 0x6f, 0x8f, + 0x8a, 0x9e, 0xcd, 0xae, 0x64, 0xf3, 0x96, 0xd5, 0x43, 0x61, 0xfe, 0x83, 0x5c, 0x0f, 0x7f, 0x61, + 0x37, 0xaa, 0x96, 0xa0, 0x71, 0x3a, 0x4b, 0x30, 0xf7, 0xb1, 0x2c, 0xc1, 0xfc, 0x20, 0x96, 0xe0, + 0x87, 0x30, 0xbe, 0x4e, 0x1d, 0x66, 0xd1, 0x88, 0xeb, 0x72, 0x05, 0xed, 0x99, 0x64, 0x56, 0x26, + 0xf5, 0x4b, 0x7c, 0xd5, 0x36, 0x62, 0x04, 0x4c, 0xb5, 0xf0, 0xfb, 0x73, 0x96, 0xce, 0x41, 0x5d, + 0x34, 0x86, 0xfa, 0x2f, 0x1a, 0x66, 0x00, 0x63, 0xf5, 0xfa, 0xea, 0x96, 0x13, 0x30, 0x6d, 0x11, + 0x32, 0x93, 0x51, 0x86, 0x89, 0x1a, 0x89, 0xe2, 0xed, 0x8d, 0x0f, 0x95, 0x58, 0x4c, 0xb1, 0x48, + 0x62, 0x11, 0x52, 0xc1, 0x23, 0xe2, 0x04, 0x4c, 0x8b, 0x88, 0x13, 0x30, 0xf3, 0xef, 0x17, 0xa0, + 0xcc, 0x43, 0x1f, 0xd9, 0xbe, 0x57, 0xe4, 0x07, 0xea, 0x79, 0x27, 0xc2, 0x38, 0xfd, 0x3b, 0x11, + 0x1f, 0x23, 0xc6, 0x56, 0xb9, 0x8b, 0x9d, 0x1f, 0xe0, 0x2e, 0xf6, 0x9b, 0xda, 0x45, 0xe6, 0x42, + 0xf2, 0x10, 0xe9, 0x7e, 0x77, 0x9b, 0x1e, 0x7f, 0x85, 0xf9, 0xb6, 0x7a, 0xe3, 0x78, 0x28, 0x89, + 0x3e, 0x41, 0xca, 0x63, 0xee, 0x1a, 0xc7, 0x5a, 0x6c, 0xf8, 0x34, 0xf1, 0xe6, 0x23, 0xff, 0x47, + 0xe3, 0xcd, 0x17, 0x01, 0x94, 0xa4, 0x31, 0xc5, 0xe4, 0x3d, 0xd2, 0x93, 0x13, 0xc6, 0x28, 0x84, + 0xe6, 0xbf, 0x2d, 0xc3, 0x54, 0xbd, 0xbe, 0xba, 0xe0, 0x39, 0xbb, 0x6d, 0x3f, 0x8c, 0xbc, 0xc6, + 0x52, 0x7b, 0xc7, 0x67, 0x53, 0x78, 0x9d, 0x86, 0xd1, 0x9d, 0xa6, 0xff, 0x48, 0x8d, 0x7d, 0x8e, + 0x68, 0x18, 0xd9, 0x3b, 0x4d, 0xff, 0x91, 0x15, 0x17, 0xb3, 0x25, 0x62, 0x31, 0x08, 0xe2, 0xa7, + 0x4f, 0x70, 0x89, 0xa0, 0x0c, 0x60, 0x71, 0x38, 0x9b, 0x25, 0xf5, 0x2e, 0xcf, 0xfe, 0xc1, 0x33, + 0xcd, 0xe1, 0x2c, 0x09, 0x39, 0xc8, 0x92, 0x65, 0x84, 0xf6, 0x0a, 0xac, 0xd0, 0x9a, 0xe7, 0xb5, + 0xa8, 0xf5, 0xa4, 0x58, 0xbc, 0xa1, 0x87, 0x50, 0x1c, 0x5d, 0xbb, 0x83, 0x70, 0xd5, 0x78, 0xef, + 0x99, 0x03, 0x07, 0x70, 0x96, 0x19, 0x97, 0xa7, 0xb6, 0x39, 0xae, 0x09, 0x9d, 0x60, 0xe2, 0x7d, + 0x89, 0x0c, 0xc3, 0x43, 0x7d, 0x1e, 0x21, 0xb3, 0x06, 0xf2, 0x4b, 0x06, 0x3c, 0x9b, 0x59, 0x12, + 0xcf, 0xee, 0x31, 0xed, 0xe6, 0x80, 0xa2, 0x34, 0x30, 0x63, 0xca, 0xab, 0xfd, 0xaa, 0xb6, 0x33, + 0x54, 0xc1, 0xf1, 0x35, 0x91, 0x7f, 0x69, 0xc0, 0x79, 0x0d, 0x03, 0x53, 0x2d, 0xb6, 0x68, 0x3b, + 0x92, 0x0f, 0x87, 0xf7, 0x91, 0xeb, 0x8f, 0x9e, 0x8c, 0x5c, 0xbf, 0xa0, 0x7f, 0x0b, 0x4f, 0x47, + 0x8d, 0xd5, 0xab, 0x3b, 0xc5, 0x3e, 0x2d, 0x24, 0x3f, 0x0d, 0x53, 0x58, 0x24, 0xed, 0x1f, 0x26, + 0xb3, 0x68, 0x36, 0x95, 0x6a, 0x73, 0x3f, 0x38, 0xac, 0x8c, 0x6b, 0x05, 0x78, 0xad, 0x10, 0x6b, + 0x8b, 0xcd, 0x25, 0xaf, 0xbd, 0xe3, 0x6b, 0xa9, 0x55, 0xd3, 0xcc, 0xc8, 0xbf, 0x36, 0x60, 0x96, + 0x41, 0x79, 0x83, 0xef, 0x04, 0x7e, 0x2b, 0x2e, 0x0f, 0xc5, 0x8d, 0xf3, 0x3e, 0x1d, 0xd4, 0x7c, + 0x32, 0x1d, 0xf4, 0x12, 0x36, 0x99, 0xcf, 0x7e, 0x7b, 0x27, 0xf0, 0x5b, 0x49, 0xf3, 0xb5, 0x6c, + 0x25, 0xfd, 0x1a, 0x49, 0x7e, 0xd1, 0x80, 0x0b, 0xda, 0x36, 0x4a, 0xbd, 0x94, 0x37, 0x3b, 0xa9, + 0x39, 0x07, 0xd4, 0xa2, 0xda, 0x75, 0x21, 0xe9, 0x57, 0xb0, 0x05, 0xc9, 0xba, 0x80, 0x6d, 0xb1, + 0x5b, 0x1c, 0x4b, 0x69, 0x42, 0xff, 0x5a, 0x88, 0x07, 0x53, 0xe8, 0x58, 0xd2, 0xfc, 0x12, 0x33, + 0xfd, 0xfd, 0x12, 0x57, 0x44, 0xd5, 0xcf, 0xe1, 0xc5, 0xa7, 0xfe, 0xce, 0x89, 0x5e, 0xae, 0xe4, + 0xe7, 0xe0, 0x42, 0x0f, 0x30, 0x9e, 0x57, 0x67, 0xfb, 0xce, 0xab, 0x57, 0x8f, 0x0e, 0x2b, 0x2f, + 0x67, 0xd5, 0x96, 0x35, 0xa7, 0xfa, 0xd7, 0x40, 0xee, 0x03, 0x24, 0x85, 0xb3, 0xe7, 0x50, 0x14, + 0x5f, 0x15, 0x92, 0xa0, 0x94, 0x30, 0xfd, 0xac, 0xd4, 0xa6, 0x2e, 0x63, 0x09, 0x12, 0x59, 0x85, + 0x92, 0x72, 0xbd, 0xeb, 0x60, 0xf6, 0x3c, 0x67, 0xf7, 0x83, 0xc3, 0x8a, 0x06, 0x67, 0xbb, 0x3f, + 0xf5, 0x86, 0x98, 0xea, 0x6f, 0xd2, 0x10, 0xc9, 0x1f, 0x19, 0x30, 0xc3, 0x00, 0x89, 0xa0, 0x88, + 0x86, 0xce, 0x1e, 0x27, 0xc9, 0x7b, 0x4f, 0x46, 0x92, 0x9f, 0xc7, 0x36, 0xaa, 0x92, 0xdc, 0xf3, + 0xf1, 0x99, 0x8d, 0x43, 0x09, 0xd6, 0xfc, 0x92, 0x9a, 0x04, 0x5f, 0x18, 0x40, 0x82, 0x79, 0x57, + 0x9f, 0x2c, 0xc1, 0x7d, 0x6b, 0x21, 0xeb, 0x50, 0x12, 0x46, 0x2e, 0xef, 0xb0, 0xe7, 0xb4, 0x7b, + 0x23, 0x6a, 0x11, 0xdf, 0x8d, 0x8b, 0x7b, 0x6e, 0x3d, 0x5f, 0xa8, 0x71, 0x21, 0x6d, 0x98, 0xe6, + 0xbf, 0x75, 0x8b, 0xb4, 0xd2, 0xd7, 0x22, 0xbd, 0x2a, 0xbe, 0xe8, 0xb2, 0xe0, 0x9f, 0x32, 0x4c, + 0x95, 0x8a, 0xb2, 0x18, 0x13, 0x07, 0x26, 0x05, 0xd8, 0xdf, 0xa7, 0x5c, 0x5b, 0x5e, 0xd6, 0x62, + 0xa5, 0x52, 0xa5, 0x3c, 0x71, 0x8c, 0xac, 0x0b, 0x83, 0x52, 0x52, 0x2a, 0x33, 0xcd, 0xcf, 0xfc, + 0xa6, 0xd1, 0x53, 0x07, 0x79, 0x4d, 0x3c, 0x4d, 0xaf, 0x84, 0x7b, 0xa3, 0x03, 0x99, 0x73, 0xc4, + 0xa0, 0xef, 0x04, 0x81, 0xd9, 0x09, 0x6a, 0xe8, 0x5b, 0x5e, 0xa4, 0xfc, 0xe4, 0xa0, 0x24, 0x64, + 0xa5, 0x22, 0x1d, 0xa8, 0xf9, 0xc4, 0xde, 0x40, 0x07, 0xaa, 0x70, 0x9b, 0x9a, 0xbf, 0x98, 0xd3, + 0xc7, 0x8c, 0x5c, 0x55, 0x4c, 0x56, 0x25, 0xf8, 0x4e, 0x9a, 0xac, 0x8a, 0xa1, 0xfa, 0x7b, 0x06, + 0x4c, 0xaf, 0x06, 0xbb, 0x4e, 0xdb, 0xfb, 0x19, 0x1e, 0x9a, 0xef, 0x63, 0x3f, 0xc6, 0xc7, 0xa1, + 0x9f, 0xea, 0xd5, 0x7c, 0x5f, 0xa9, 0x98, 0x0d, 0x2d, 0x8e, 0xb1, 0x95, 0xd5, 0x1e, 0x3c, 0xc6, + 0xc2, 0x86, 0x29, 0x19, 0x12, 0x38, 0x3a, 0x87, 0x9b, 0xdf, 0xca, 0xc1, 0x98, 0x22, 0x3f, 0xe4, + 0xf3, 0x50, 0x52, 0xf9, 0xa8, 0x01, 0xc0, 0x6a, 0xb5, 0x96, 0x86, 0x85, 0x91, 0xfa, 0xd4, 0x69, + 0xa9, 0x7b, 0x6d, 0x56, 0x8b, 0x85, 0xd0, 0x53, 0x5a, 0xf5, 0xef, 0x65, 0x58, 0xf5, 0xa7, 0x4a, + 0x4f, 0xf4, 0x76, 0xaf, 0x6d, 0x3f, 0x78, 0x36, 0x21, 0xf3, 0x57, 0x72, 0x50, 0x5e, 0x0f, 0xba, + 0x61, 0x44, 0x5d, 0x19, 0xaf, 0xf0, 0xd9, 0x7a, 0xf3, 0x50, 0xff, 0xb8, 0x63, 0x22, 0xf2, 0x0a, + 0xbf, 0xf1, 0x3b, 0x95, 0x33, 0xe6, 0x97, 0x61, 0x26, 0xdd, 0x1d, 0xe8, 0x1b, 0xa8, 0xc2, 0xa4, + 0x0e, 0x4f, 0x5f, 0x56, 0x4e, 0x53, 0x59, 0x69, 0x7c, 0xf3, 0xcf, 0x72, 0x69, 0xde, 0xc2, 0x81, + 0xcb, 0x26, 0x38, 0x3e, 0x41, 0x2d, 0xef, 0x53, 0x8a, 0x9c, 0xbe, 0x08, 0xb2, 0x64, 0xd9, 0x69, + 0xae, 0xad, 0xc7, 0xc7, 0xb9, 0xf9, 0xec, 0xe3, 0x5c, 0x72, 0x1b, 0x4a, 0x18, 0xa2, 0x5e, 0x75, + 0xdd, 0x80, 0x6d, 0x40, 0x0a, 0x49, 0xfa, 0xde, 0x47, 0x74, 0xdb, 0xe6, 0xa1, 0xec, 0x8e, 0xeb, + 0x06, 0x96, 0x86, 0x47, 0xe6, 0x61, 0x46, 0xbb, 0x11, 0x21, 0xe9, 0x87, 0x12, 0x07, 0x55, 0x84, + 0x05, 0x9c, 0x38, 0x13, 0x19, 0x33, 0xd8, 0xfb, 0x4d, 0xb6, 0x83, 0xc0, 0x7d, 0xa5, 0x9e, 0xfa, + 0x54, 0x6a, 0x76, 0x19, 0x26, 0x45, 0x30, 0xed, 0x4f, 0xcb, 0xe9, 0x68, 0x99, 0xb4, 0x38, 0xa2, + 0xf9, 0x57, 0x06, 0x9b, 0x6b, 0x8d, 0xfd, 0xcf, 0xd8, 0x85, 0x7a, 0xf6, 0x49, 0xc7, 0x9c, 0x2f, + 0xfc, 0x07, 0x83, 0x5f, 0x89, 0x15, 0xe2, 0xf3, 0x26, 0x0c, 0xf3, 0x07, 0xaf, 0xc5, 0xe5, 0x4d, + 0x95, 0x0b, 0x2f, 0x48, 0x42, 0xe2, 0xf8, 0xb3, 0xd9, 0x96, 0x20, 0x50, 0x5d, 0x2e, 0xb9, 0x81, + 0x5c, 0x2e, 0xca, 0x7b, 0x1c, 0x83, 0xbd, 0xf3, 0x64, 0x9c, 0xfc, 0x1e, 0x87, 0xf9, 0xbf, 0x72, + 0xfc, 0x7b, 0x44, 0xa3, 0x06, 0xcd, 0x00, 0x7f, 0x05, 0x0a, 0x4c, 0x0e, 0xd4, 0x34, 0xfb, 0x4c, + 0x56, 0xb4, 0xa7, 0xfd, 0xfc, 0x26, 0xba, 0x62, 0x51, 0xd7, 0xaa, 0x39, 0x1c, 0x50, 0x1d, 0xab, + 0xf3, 0x06, 0x31, 0xf0, 0x15, 0x25, 0xdf, 0xa5, 0xea, 0x74, 0x68, 0xeb, 0x0f, 0x5e, 0x61, 0x39, + 0xb9, 0xad, 0x5c, 0xa5, 0x54, 0xcf, 0x50, 0x5b, 0x3b, 0x8e, 0xcd, 0xaf, 0xf0, 0xa9, 0xda, 0x36, + 0xb9, 0x75, 0xb9, 0x08, 0x13, 0x7a, 0x82, 0x27, 0x71, 0xce, 0x81, 0x49, 0x59, 0x52, 0xc9, 0xa1, + 0x54, 0x8f, 0xba, 0x4e, 0x44, 0x6a, 0x30, 0xae, 0x65, 0xf1, 0x51, 0x1f, 0x1f, 0xe1, 0x59, 0x43, + 0xed, 0xde, 0xf4, 0x73, 0x3a, 0x89, 0x12, 0xa3, 0xf3, 0x39, 0x28, 0x8b, 0x99, 0x19, 0xa7, 0xd3, + 0x40, 0x6f, 0xf2, 0xd2, 0x82, 0xa5, 0xce, 0xa6, 0x86, 0xe7, 0x06, 0x16, 0x42, 0xcd, 0xef, 0x1a, + 0x70, 0x41, 0x3c, 0xe4, 0x6d, 0xd1, 0x30, 0x0a, 0x3c, 0x9e, 0x9d, 0x03, 0xe5, 0xf1, 0xf3, 0xe4, + 0x6d, 0x99, 0x90, 0x58, 0x57, 0x90, 0xe9, 0x3a, 0x6a, 0xe3, 0x42, 0x28, 0x87, 0x30, 0x25, 0xb1, + 0x4c, 0x44, 0xfc, 0xa6, 0x48, 0x44, 0x9c, 0x3b, 0x9e, 0x38, 0x9e, 0x17, 0x2e, 0x6d, 0xcb, 0x04, + 0xc4, 0xdf, 0xc9, 0xc1, 0xd9, 0x8c, 0x66, 0x6d, 0x7e, 0xfe, 0x29, 0x55, 0x0e, 0x35, 0x4d, 0x39, + 0xc8, 0x4c, 0xf5, 0x7d, 0x3b, 0x3e, 0x53, 0x57, 0xfc, 0x96, 0x01, 0xe7, 0x75, 0xe9, 0x11, 0xc7, + 0x5f, 0x9b, 0xb7, 0xc8, 0x5b, 0x30, 0x7c, 0x8f, 0x3a, 0x2e, 0x95, 0xb7, 0xbe, 0xcf, 0xa6, 0x9e, + 0xe7, 0xe0, 0x85, 0x9c, 0xed, 0x9f, 0xf1, 0xa9, 0x7c, 0xc6, 0x12, 0x24, 0x64, 0x41, 0x34, 0x8e, + 0x9b, 0x80, 0xa6, 0x0c, 0x0e, 0xcb, 0xaa, 0xea, 0x18, 0x5f, 0xfc, 0xef, 0x19, 0xf0, 0xcc, 0x31, + 0x34, 0x6c, 0xe0, 0xd8, 0xd0, 0xab, 0x03, 0x87, 0x0b, 0x0b, 0x42, 0xc9, 0xbb, 0x30, 0xb9, 0x2e, + 0x4c, 0x48, 0x39, 0x1c, 0xca, 0xab, 0x66, 0xd2, 0xba, 0xb4, 0xe5, 0xb8, 0xa4, 0x91, 0x99, 0x01, + 0x7c, 0xcf, 0x0f, 0xa3, 0x76, 0x92, 0x61, 0x13, 0x0d, 0xe0, 0x3d, 0x01, 0xb3, 0xe2, 0x52, 0x66, + 0x16, 0xe8, 0xcd, 0x14, 0x11, 0xd8, 0x2f, 0xc0, 0x30, 0xc3, 0x89, 0x1d, 0xfa, 0x28, 0x07, 0xf8, + 0xcc, 0xb4, 0xe7, 0x5a, 0xa2, 0x28, 0x3e, 0x4a, 0xca, 0x65, 0x06, 0x4a, 0x7d, 0xcb, 0x80, 0xb2, + 0xce, 0xfb, 0x93, 0x0e, 0xcd, 0x3b, 0xda, 0xd0, 0x3c, 0x93, 0x3d, 0x34, 0xfd, 0xc7, 0xa4, 0x27, + 0xd9, 0xdd, 0x40, 0x63, 0x61, 0xc2, 0xf0, 0x82, 0xdf, 0x72, 0xbc, 0xb6, 0x9a, 0xa0, 0xcd, 0x45, + 0x88, 0x25, 0x4a, 0x94, 0xde, 0xca, 0xf7, 0xed, 0x2d, 0xf3, 0x57, 0x0b, 0x70, 0xc1, 0xa2, 0xbb, + 0x1e, 0x33, 0x90, 0x36, 0x42, 0xaf, 0xbd, 0xab, 0x85, 0xb1, 0x99, 0xa9, 0x0e, 0x17, 0x97, 0x77, + 0x18, 0x24, 0xee, 0xef, 0x57, 0xa0, 0xc8, 0xb4, 0xb4, 0xd2, 0xe7, 0xe8, 0xa4, 0xc5, 0x34, 0xa3, + 0x7c, 0x5c, 0x65, 0x31, 0xb9, 0x26, 0xd6, 0x10, 0xe5, 0x7a, 0x25, 0x5b, 0x43, 0x7e, 0x7c, 0x58, + 0x01, 0xfe, 0xac, 0x10, 0x2b, 0x15, 0xeb, 0x48, 0x6c, 0x54, 0x15, 0xfa, 0x18, 0x55, 0x0f, 0x60, + 0xa6, 0xea, 0x72, 0xfd, 0xe4, 0x34, 0xd7, 0x02, 0xaf, 0xdd, 0xf0, 0x3a, 0x4e, 0x53, 0x1a, 0xe5, + 0xe8, 0xaa, 0x77, 0xe2, 0x72, 0xbb, 0x13, 0x23, 0x58, 0x99, 0x64, 0xec, 0x33, 0x16, 0x56, 0xea, + 0x3c, 0x8b, 0x24, 0xf7, 0xbf, 0xe3, 0x67, 0xb8, 0xed, 0x90, 0xa7, 0x91, 0xb4, 0xe2, 0x62, 0x34, + 0xe7, 0xf0, 0x86, 0xf5, 0xfa, 0x72, 0xfd, 0xbe, 0xb8, 0xb1, 0x2c, 0x6f, 0x7f, 0xf0, 0x0b, 0xd9, + 0x51, 0x33, 0xc4, 0x23, 0x43, 0x0d, 0x2f, 0xa1, 0xab, 0xd7, 0xef, 0x31, 0xba, 0x62, 0x0f, 0x5d, + 0x18, 0xee, 0xa9, 0x74, 0x1c, 0x8f, 0xdc, 0x00, 0xe0, 0xf1, 0xf3, 0x28, 0x10, 0xa3, 0x89, 0xf1, + 0x17, 0x20, 0x94, 0x1b, 0x7f, 0x0a, 0x0a, 0x79, 0x1b, 0xa6, 0x17, 0xe7, 0xe7, 0xa4, 0xdf, 0x65, + 0xc1, 0x6f, 0x74, 0x5b, 0xb4, 0x1d, 0xe1, 0xd5, 0xf8, 0x12, 0x1f, 0x43, 0xda, 0x98, 0x63, 0x52, + 0x90, 0x85, 0x26, 0x2e, 0x24, 0xf3, 0x74, 0x16, 0xf3, 0xbe, 0x4b, 0xc3, 0xcd, 0x9b, 0x9f, 0xb1, + 0x0b, 0xc9, 0xca, 0xb7, 0xe1, 0x6c, 0xbb, 0x99, 0x39, 0x33, 0xff, 0x7f, 0xbc, 0x90, 0xdc, 0x83, + 0x4b, 0x7e, 0x02, 0x86, 0xf0, 0xa7, 0x58, 0x71, 0xa7, 0x33, 0xd8, 0x26, 0xab, 0x6d, 0x83, 0x27, + 0x04, 0x44, 0x02, 0xb2, 0x94, 0x3c, 0xda, 0x76, 0x8a, 0x6b, 0x75, 0x22, 0x27, 0x8e, 0xfe, 0x5a, + 0xa7, 0x0b, 0x25, 0xb5, 0x42, 0x26, 0x23, 0xf7, 0x9c, 0x70, 0x8f, 0xba, 0xf3, 0xf2, 0x8d, 0xff, + 0x12, 0x97, 0x91, 0x3d, 0x84, 0xe2, 0x4b, 0xa2, 0x96, 0x82, 0xc2, 0xb4, 0xc3, 0x52, 0xb8, 0x11, + 0x8a, 0xa6, 0x88, 0x5d, 0x90, 0x87, 0xbb, 0x57, 0xd7, 0x12, 0x45, 0xa8, 0x2d, 0xe5, 0x29, 0x4d, + 0xe0, 0x34, 0xf6, 0x69, 0xb0, 0x79, 0xf3, 0xd3, 0xd0, 0x96, 0x7a, 0x1d, 0xc7, 0x8c, 0xc9, 0x37, + 0x20, 0xce, 0x67, 0xa9, 0x21, 0x33, 0x1b, 0x31, 0x09, 0x06, 0x36, 0x12, 0x1b, 0x31, 0x09, 0x06, + 0x56, 0x6d, 0xc4, 0x18, 0x35, 0x7e, 0x51, 0x25, 0x77, 0xc2, 0x8b, 0x2a, 0x7d, 0x5e, 0x8f, 0x92, + 0xf7, 0xc8, 0x3e, 0x43, 0xef, 0xf5, 0x7d, 0x11, 0x4a, 0xd5, 0x28, 0x72, 0x1a, 0x7b, 0xd4, 0xc5, + 0x97, 0x7b, 0x94, 0x18, 0x44, 0x47, 0xc0, 0x55, 0x8f, 0xa2, 0x8a, 0xab, 0xbc, 0xd7, 0x39, 0x32, + 0xc0, 0x7b, 0x9d, 0x37, 0x60, 0x64, 0xa9, 0xfd, 0xd0, 0x63, 0x7d, 0x52, 0x4c, 0xf2, 0xd1, 0x79, + 0x1c, 0xa4, 0x3f, 0xf2, 0x88, 0x20, 0xf2, 0xa6, 0x62, 0x41, 0x8c, 0x26, 0xa6, 0x3c, 0xdf, 0x66, + 0xd9, 0xd2, 0x90, 0x50, 0x0f, 0x7f, 0x25, 0x3a, 0xb9, 0x0d, 0x23, 0x72, 0xf7, 0x0c, 0x89, 0xf9, + 0x2e, 0x28, 0x1d, 0x5e, 0xa2, 0xa5, 0xc0, 0x13, 0xbb, 0xe7, 0xb7, 0xf5, 0x2b, 0xeb, 0x63, 0x4a, + 0x2a, 0x28, 0xe5, 0xca, 0xba, 0x96, 0x0a, 0x4a, 0xb9, 0xbc, 0x1e, 0x6f, 0x86, 0x4a, 0x27, 0x6e, + 0x86, 0x36, 0xa1, 0xb4, 0xe6, 0x04, 0x91, 0xc7, 0x96, 0xa3, 0x76, 0xc4, 0x73, 0x11, 0x27, 0x7b, + 0x75, 0xa5, 0x28, 0x79, 0xc4, 0xad, 0xa3, 0xe0, 0xeb, 0xb9, 0x74, 0x12, 0x38, 0x59, 0xc9, 0xb8, + 0xd4, 0x24, 0x1e, 0x07, 0xc0, 0x83, 0x4b, 0x35, 0x13, 0x3d, 0x2f, 0x55, 0x4f, 0x38, 0x7a, 0xef, + 0x43, 0xdd, 0xe2, 0x63, 0x80, 0x7b, 0xc6, 0x49, 0x64, 0x83, 0x09, 0x0d, 0xd1, 0xae, 0x48, 0x6d, + 0x1c, 0x63, 0x44, 0xf2, 0x55, 0x28, 0xb1, 0xff, 0x31, 0x31, 0xab, 0x47, 0x79, 0xae, 0xe1, 0xe4, + 0x92, 0x8b, 0x3e, 0xa1, 0x79, 0xf6, 0xd6, 0x3a, 0x8d, 0xf8, 0x04, 0x46, 0xc6, 0x69, 0xc7, 0x8b, + 0xc6, 0x8d, 0xbc, 0x07, 0x25, 0x35, 0xb1, 0xf3, 0xec, 0x54, 0x12, 0x96, 0xe6, 0x0a, 0x78, 0x7a, + 0x94, 0x34, 0x02, 0xb6, 0x7e, 0x55, 0x3b, 0x1d, 0xa4, 0x25, 0x8a, 0xb4, 0x77, 0x3a, 0x69, 0x32, + 0x89, 0x46, 0xde, 0x87, 0x52, 0xb5, 0xd3, 0x49, 0x34, 0xce, 0xb4, 0xb2, 0x25, 0xec, 0x74, 0xec, + 0x4c, 0xad, 0xa3, 0x51, 0x30, 0xc1, 0x12, 0x06, 0x1f, 0xd6, 0x3b, 0x93, 0x08, 0x96, 0x4c, 0x57, + 0x9c, 0x16, 0x2c, 0x05, 0xdd, 0xfc, 0x91, 0x01, 0xe7, 0xfb, 0x74, 0xdb, 0xc0, 0x8f, 0x13, 0xdf, + 0x48, 0xd6, 0x60, 0xc5, 0x1d, 0x21, 0xd6, 0x60, 0xf5, 0xa3, 0xe5, 0x6a, 0x9c, 0x9d, 0x18, 0x39, + 0xff, 0xa9, 0x25, 0x46, 0x36, 0x0f, 0x0d, 0x18, 0x53, 0x84, 0xf9, 0x09, 0x3e, 0x06, 0x78, 0x45, + 0xbc, 0x10, 0x90, 0x4f, 0xf0, 0x5a, 0x29, 0xd7, 0x03, 0xbe, 0x08, 0xf0, 0x35, 0x80, 0x65, 0x27, + 0x8c, 0xaa, 0x8d, 0xc8, 0x7b, 0x48, 0x07, 0xd0, 0xdc, 0x49, 0x3a, 0x34, 0x07, 0xdf, 0x14, 0x61, + 0x64, 0x3d, 0xe9, 0xd0, 0x62, 0x86, 0xe6, 0x0a, 0x0c, 0xd7, 0xfd, 0x20, 0xaa, 0x1d, 0xf0, 0xe5, + 0x78, 0x81, 0x86, 0x0d, 0xd5, 0x29, 0xe9, 0xa1, 0x7b, 0xa2, 0x61, 0x89, 0x22, 0x66, 0x13, 0xdf, + 0xf1, 0x68, 0xd3, 0x55, 0x83, 0x1c, 0x76, 0x18, 0xc0, 0xe2, 0xf0, 0x6b, 0xef, 0xc1, 0xa4, 0x14, + 0xec, 0xf5, 0xe5, 0x3a, 0x7e, 0xc1, 0x24, 0x8c, 0x6d, 0x2e, 0x5a, 0x4b, 0x77, 0xbe, 0x6c, 0xdf, + 0xd9, 0x58, 0x5e, 0x2e, 0x9f, 0x21, 0xe3, 0x30, 0x2a, 0x00, 0xf3, 0xd5, 0xb2, 0x41, 0x4a, 0x50, + 0x5c, 0x5a, 0xa9, 0x2f, 0xce, 0x6f, 0x58, 0x8b, 0xe5, 0xdc, 0xb5, 0x97, 0x60, 0x22, 0x89, 0x72, + 0xc3, 0xf3, 0x90, 0x11, 0xc8, 0x5b, 0xd5, 0xad, 0xf2, 0x19, 0x02, 0x30, 0xbc, 0x76, 0x7f, 0xbe, + 0x7e, 0xf3, 0x66, 0xd9, 0xb8, 0xf6, 0x39, 0x98, 0x42, 0x47, 0xe5, 0x32, 0xdb, 0x37, 0xb4, 0x69, + 0x80, 0x35, 0x95, 0xa0, 0x58, 0xa7, 0x1d, 0x27, 0x70, 0x22, 0xca, 0xab, 0x79, 0xd0, 0x6d, 0x46, + 0x5e, 0xa7, 0x49, 0x1f, 0x97, 0x8d, 0x6b, 0x6f, 0xc2, 0xa4, 0xe5, 0x77, 0x23, 0xaf, 0xbd, 0x2b, + 0x5f, 0x53, 0x21, 0x67, 0x61, 0x6a, 0x63, 0xa5, 0xfa, 0xa0, 0xb6, 0x74, 0x77, 0x63, 0x75, 0xa3, + 0x6e, 0x3f, 0xa8, 0xae, 0xcf, 0xdf, 0x2b, 0x9f, 0x61, 0x0d, 0x7e, 0xb0, 0x5a, 0x5f, 0xb7, 0xad, + 0xc5, 0xf9, 0xc5, 0x95, 0xf5, 0xb2, 0x71, 0xed, 0x97, 0x0d, 0x98, 0xd0, 0x1f, 0xbe, 0x27, 0x97, + 0xe1, 0xd2, 0x46, 0x7d, 0xd1, 0xb2, 0xd7, 0x57, 0xef, 0x2f, 0xae, 0xd8, 0x1b, 0xf5, 0xea, 0xdd, + 0x45, 0x7b, 0x63, 0xa5, 0xbe, 0xb6, 0x38, 0xbf, 0x74, 0x67, 0x69, 0x71, 0xa1, 0x7c, 0x86, 0x54, + 0xe0, 0x19, 0x05, 0xc3, 0x5a, 0x9c, 0x5f, 0xdd, 0x5c, 0xb4, 0xec, 0xb5, 0x6a, 0xbd, 0xbe, 0xb5, + 0x6a, 0x2d, 0x94, 0x0d, 0x72, 0x11, 0xce, 0x65, 0x20, 0x3c, 0xb8, 0x53, 0x2d, 0xe7, 0x7a, 0xca, + 0x56, 0x16, 0xb7, 0xaa, 0xcb, 0x76, 0x6d, 0x75, 0xbd, 0x9c, 0xbf, 0xf6, 0x1e, 0x33, 0xbc, 0x92, + 0x27, 0x23, 0x49, 0x11, 0x0a, 0x2b, 0xab, 0x2b, 0x8b, 0xe5, 0x33, 0x64, 0x0c, 0x46, 0xd6, 0x16, + 0x57, 0x16, 0x96, 0x56, 0xee, 0xf2, 0x6e, 0xad, 0xae, 0xad, 0x59, 0xab, 0x9b, 0x8b, 0x0b, 0xe5, + 0x1c, 0xeb, 0xbb, 0x85, 0xc5, 0x15, 0xd6, 0xb2, 0xfc, 0x35, 0x93, 0xbf, 0x56, 0xa4, 0xbd, 0x44, + 0xc1, 0x7a, 0x6b, 0xf1, 0x4b, 0xeb, 0x8b, 0x2b, 0xf5, 0xa5, 0xd5, 0x95, 0xf2, 0x99, 0x6b, 0x97, + 0x52, 0x38, 0x72, 0x24, 0xea, 0xf5, 0x7b, 0xe5, 0x33, 0xd7, 0xbe, 0x0a, 0x25, 0xd5, 0xee, 0x20, + 0xe7, 0x61, 0x5a, 0xfd, 0xbd, 0x46, 0xdb, 0xae, 0xd7, 0xde, 0x2d, 0x9f, 0x49, 0x17, 0x58, 0xdd, + 0x76, 0x9b, 0x15, 0xe0, 0xc7, 0xab, 0x05, 0xeb, 0x34, 0x68, 0x79, 0x6d, 0x66, 0x52, 0x94, 0x73, + 0xb5, 0xf2, 0xf7, 0xff, 0xe2, 0xb9, 0x33, 0xdf, 0xff, 0xe1, 0x73, 0xc6, 0x9f, 0xfd, 0xf0, 0x39, + 0xe3, 0xbf, 0xfd, 0xf0, 0x39, 0x63, 0x7b, 0x18, 0x05, 0xfd, 0xd6, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xa2, 0x1a, 0x21, 0x4d, 0xc8, 0x00, 0x00, } func (m *KeepAlive) Marshal() (dAtA []byte, err error) { @@ -19840,6 +19949,50 @@ func (m *SSODiagnosticInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.GithubTokenInfo != nil { + { + size, err := m.GithubTokenInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x82 + } + if len(m.GithubTeamsToLogins) > 0 { + for iNdEx := len(m.GithubTeamsToLogins) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.GithubTeamsToLogins[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xfa + } + } + if m.GithubClaims != nil { + { + size, err := m.GithubClaims.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xf2 + } if len(m.OIDCConnectorTraitMapping) > 0 { for iNdEx := len(m.OIDCConnectorTraitMapping) - 1; iNdEx >= 0; iNdEx-- { { @@ -20038,6 +20191,105 @@ func (m *SSODiagnosticInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *GithubTokenInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GithubTokenInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GithubTokenInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Scope) > 0 { + i -= len(m.Scope) + copy(dAtA[i:], m.Scope) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Scope))) + i-- + dAtA[i] = 0x1a + } + if m.Expires != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Expires)) + i-- + dAtA[i] = 0x10 + } + if len(m.TokenType) > 0 { + i -= len(m.TokenType) + copy(dAtA[i:], m.TokenType) + i = encodeVarintTypes(dAtA, i, uint64(len(m.TokenType))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GithubClaims) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GithubClaims) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GithubClaims) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Teams) > 0 { + for iNdEx := len(m.Teams) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Teams[iNdEx]) + copy(dAtA[i:], m.Teams[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Teams[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + { + size := m.OrganizationToTeams.Size() + i -= size + if _, err := m.OrganizationToTeams.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Username) > 0 { + i -= len(m.Username) + copy(dAtA[i:], m.Username) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Username))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *TeamMapping) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -20389,12 +20641,12 @@ func (m *LockSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if m.Expires != nil { - n181, err181 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err181 != nil { - return 0, err181 + n184, err184 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err184 != nil { + return 0, err184 } - i -= n181 - i = encodeVarintTypes(dAtA, i, uint64(n181)) + i -= n184 + i = encodeVarintTypes(dAtA, i, uint64(n184)) i-- dAtA[i] = 0x1a } @@ -21075,12 +21327,12 @@ func (m *RecoveryCodesSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n191, err191 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err191 != nil { - return 0, err191 + n194, err194 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err194 != nil { + return 0, err194 } - i -= n191 - i = encodeVarintTypes(dAtA, i, uint64(n191)) + i -= n194 + i = encodeVarintTypes(dAtA, i, uint64(n194)) i-- dAtA[i] = 0x12 if len(m.Codes) > 0 { @@ -21346,20 +21598,20 @@ func (m *SessionTrackerSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n194, err194 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err194 != nil { - return 0, err194 + n197, err197 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err197 != nil { + return 0, err197 } - i -= n194 - i = encodeVarintTypes(dAtA, i, uint64(n194)) + i -= n197 + i = encodeVarintTypes(dAtA, i, uint64(n197)) i-- dAtA[i] = 0x2a - n195, err195 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err195 != nil { - return 0, err195 + n198, err198 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err198 != nil { + return 0, err198 } - i -= n195 - i = encodeVarintTypes(dAtA, i, uint64(n195)) + i -= n198 + i = encodeVarintTypes(dAtA, i, uint64(n198)) i-- dAtA[i] = 0x22 if m.State != 0 { @@ -21463,12 +21715,12 @@ func (m *Participant) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n196, err196 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) - if err196 != nil { - return 0, err196 + n199, err199 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) + if err199 != nil { + return 0, err199 } - i -= n196 - i = encodeVarintTypes(dAtA, i, uint64(n196)) + i -= n199 + i = encodeVarintTypes(dAtA, i, uint64(n199)) i-- dAtA[i] = 0x22 if len(m.Mode) > 0 { @@ -25931,6 +26183,67 @@ func (m *SSODiagnosticInfo) Size() (n int) { n += 2 + l + sovTypes(uint64(l)) } } + if m.GithubClaims != nil { + l = m.GithubClaims.Size() + n += 2 + l + sovTypes(uint64(l)) + } + if len(m.GithubTeamsToLogins) > 0 { + for _, e := range m.GithubTeamsToLogins { + l = e.Size() + n += 2 + l + sovTypes(uint64(l)) + } + } + if m.GithubTokenInfo != nil { + l = m.GithubTokenInfo.Size() + n += 2 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *GithubTokenInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TokenType) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Expires != 0 { + n += 1 + sovTypes(uint64(m.Expires)) + } + l = len(m.Scope) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *GithubClaims) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Username) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = m.OrganizationToTeams.Size() + n += 1 + l + sovTypes(uint64(l)) + if len(m.Teams) > 0 { + for _, s := range m.Teams { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -56271,6 +56584,394 @@ func (m *SSODiagnosticInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 30: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GithubClaims", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GithubClaims == nil { + m.GithubClaims = &GithubClaims{} + } + if err := m.GithubClaims.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 31: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GithubTeamsToLogins", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GithubTeamsToLogins = append(m.GithubTeamsToLogins, TeamMapping{}) + if err := m.GithubTeamsToLogins[len(m.GithubTeamsToLogins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 32: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GithubTokenInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GithubTokenInfo == nil { + m.GithubTokenInfo = &GithubTokenInfo{} + } + if err := m.GithubTokenInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GithubTokenInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GithubTokenInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GithubTokenInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TokenType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TokenType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + m.Expires = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Expires |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Scope = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GithubClaims) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GithubClaims: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GithubClaims: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Username = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OrganizationToTeams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.OrganizationToTeams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Teams", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Teams = append(m.Teams, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/api/types/types.proto b/api/types/types.proto index 8ffaf2721fef4..75bec33768f7f 100644 --- a/api/types/types.proto +++ b/api/types/types.proto @@ -2812,6 +2812,40 @@ message SSODiagnosticInfo { (gogoproto.nullable) = false, (gogoproto.jsontag) = "oidc_connector_trait_mapping,omitempty" ]; + + // GithubClaims represents Github user information obtained during OAuth2 flow. + GithubClaims GithubClaims = 30 [ (gogoproto.jsontag) = "github_claims,omitempty" ]; + + // GithubTeamsToLogins is TeamsToLogins mapping from Github connector used in the SSO flow. + repeated TeamMapping GithubTeamsToLogins = 31 + [ (gogoproto.nullable) = false, (gogoproto.jsontag) = "github_teams_to_logins,omitempty" ]; + + // GithubTokenInfo stores diagnostic info about Github OAuth2 token obtained during SSO flow. + GithubTokenInfo GithubTokenInfo = 32 [ (gogoproto.jsontag) = "github_token_info,omitempty" ]; +} + +// GithubTokenInfo stores diagnostic info about Github OAuth2 token obtained during SSO flow. +// The token itself is secret and therefore not included. +message GithubTokenInfo { + string TokenType = 1 [ (gogoproto.jsontag) = "token_type" ]; + int64 Expires = 2 [ (gogoproto.jsontag) = "expires" ]; + string Scope = 3 [ (gogoproto.jsontag) = "scope" ]; +} + +// GithubClaims represents Github user information obtained during OAuth2 flow +message GithubClaims { + // Username is the user's username + string Username = 1 [ (gogoproto.jsontag) = "username" ]; + + // OrganizationToTeams is the user's organization and team membership + wrappers.LabelValues OrganizationToTeams = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "organization_to_teams", + (gogoproto.customtype) = "github.com/gravitational/teleport/api/types/wrappers.Traits" + ]; + + // Teams is the users team membership + repeated string Teams = 3 [ (gogoproto.jsontag) = "teams" ]; } // TeamMapping represents a single team membership mapping. diff --git a/lib/auth/apiserver.go b/lib/auth/apiserver.go index 7d00ca1f273c8..7e7765c818fbf 100644 --- a/lib/auth/apiserver.go +++ b/lib/auth/apiserver.go @@ -215,6 +215,7 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) { srv.DELETE("/:version/github/connectors/:id", srv.withAuth(srv.deleteGithubConnector)) srv.POST("/:version/github/requests/create", srv.withAuth(srv.createGithubAuthRequest)) srv.POST("/:version/github/requests/validate", srv.withAuth(srv.validateGithubAuthCallback)) + srv.GET("/:version/github/requests/get/:id", srv.withAuth(srv.getGithubAuthRequest)) // SSO diag info srv.GET("/:version/sso/diag/:auth/:id", srv.withAuth(srv.getSSODiagnosticInfo)) @@ -1589,6 +1590,14 @@ func (s *APIServer) createGithubAuthRequest(auth ClientI, w http.ResponseWriter, return response, nil } +func (s *APIServer) getGithubAuthRequest(auth ClientI, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { + request, err := auth.GetGithubAuthRequest(r.Context(), p.ByName("id")) + if err != nil { + return nil, trace.Wrap(err) + } + return request, nil +} + // validateGithubAuthCallbackReq is a request to validate Github OAuth2 callback type validateGithubAuthCallbackReq struct { // Query is the callback query string @@ -1626,7 +1635,7 @@ func (s *APIServer) validateGithubAuthCallback(auth ClientI, w http.ResponseWrit if err := httplib.ReadJSON(r, &req); err != nil { return nil, trace.Wrap(err) } - response, err := auth.ValidateGithubAuthCallback(req.Query) + response, err := auth.ValidateGithubAuthCallback(r.Context(), req.Query) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index 6feda6bf01c36..edea65e88ec02 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -920,7 +920,15 @@ func TestGithubConnectorCRUDEventsEmitted(t *testing.T) { ctx := context.Background() // test github create event - github, err := types.NewGithubConnector("test", types.GithubConnectorSpecV3{}) + github, err := types.NewGithubConnector("test", types.GithubConnectorSpecV3{ + TeamsToLogins: []types.TeamMapping{ + { + Organization: "octocats", + Team: "dummy", + Logins: []string{"dummy"}, + }, + }, + }) require.NoError(t, err) err = s.a.upsertGithubConnector(ctx, github) require.NoError(t, err) diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index 2f30373a4f5c8..c3f30e5f10e97 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -2712,18 +2712,33 @@ func (a *ServerWithRoles) CreateGithubAuthRequest(req services.GithubAuthRequest return nil, trace.Wrap(err) } + // require additional permissions for executing SSO test flow. + if req.SSOTestFlow { + if err := a.authConnectorAction(apidefaults.Namespace, types.KindGithub, types.VerbCreate); err != nil { + return nil, trace.Wrap(err) + } + } + githubReq, err := a.authServer.CreateGithubAuthRequest(req) if err != nil { - // TODO(Tener): Update `testFlow` flag once GitHub SSO starts supporting test flows. - emitSSOLoginFailureEvent(a.authServer.closeCtx, a.authServer.emitter, events.LoginMethodGithub, err, false) + emitSSOLoginFailureEvent(a.authServer.closeCtx, a.authServer.emitter, events.LoginMethodGithub, err, req.SSOTestFlow) return nil, trace.Wrap(err) } return githubReq, nil } -func (a *ServerWithRoles) ValidateGithubAuthCallback(q url.Values) (*GithubAuthResponse, error) { - return a.authServer.ValidateGithubAuthCallback(q) +// GetGithubAuthRequest returns Github auth request if found. +func (a *ServerWithRoles) GetGithubAuthRequest(ctx context.Context, id string) (*services.GithubAuthRequest, error) { + if err := a.action(apidefaults.Namespace, types.KindGithubRequest, types.VerbRead); err != nil { + return nil, trace.Wrap(err) + } + + return a.authServer.GetGithubAuthRequest(ctx, id) +} + +func (a *ServerWithRoles) ValidateGithubAuthCallback(ctx context.Context, q url.Values) (*GithubAuthResponse, error) { + return a.authServer.ValidateGithubAuthCallback(ctx, q) } // EmitAuditEvent emits a single audit event diff --git a/lib/auth/auth_with_roles_test.go b/lib/auth/auth_with_roles_test.go index f0d8aaa8e9103..11de0814e6fc0 100644 --- a/lib/auth/auth_with_roles_test.go +++ b/lib/auth/auth_with_roles_test.go @@ -24,6 +24,8 @@ import ( "testing" "time" + "golang.org/x/crypto/ssh" + "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/constants" @@ -37,7 +39,6 @@ import ( "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" - "golang.org/x/crypto/ssh" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -629,6 +630,180 @@ func TestOIDCAuthRequest(t *testing.T) { } } +func TestGithubAuthRequest(t *testing.T) { + ctx := context.Background() + srv := newTestTLSServer(t) + + emptyRole, err := CreateRole(ctx, srv.Auth(), "test-empty", types.RoleSpecV5{}) + require.NoError(t, err) + + access1Role, err := CreateRole(ctx, srv.Auth(), "test-access-1", types.RoleSpecV5{ + Allow: types.RoleConditions{ + Rules: []types.Rule{ + { + Resources: []string{types.KindGithubRequest}, + Verbs: []string{types.VerbCreate}, + }, + }, + }, + }) + require.NoError(t, err) + + access2Role, err := CreateRole(ctx, srv.Auth(), "test-access-2", types.RoleSpecV5{ + Allow: types.RoleConditions{ + Rules: []types.Rule{ + { + Resources: []string{types.KindGithub}, + Verbs: []string{types.VerbCreate}, + }, + }, + }, + }) + require.NoError(t, err) + + access3Role, err := CreateRole(ctx, srv.Auth(), "test-access-3", types.RoleSpecV5{ + Allow: types.RoleConditions{ + Rules: []types.Rule{ + { + Resources: []string{types.KindGithub, types.KindGithubRequest}, + Verbs: []string{types.VerbCreate}, + }, + }, + }, + }) + require.NoError(t, err) + + readerRole, err := CreateRole(ctx, srv.Auth(), "test-access-4", types.RoleSpecV5{ + Allow: types.RoleConditions{ + Rules: []types.Rule{ + { + Resources: []string{types.KindGithubRequest}, + Verbs: []string{types.VerbRead}, + }, + }, + }, + }) + require.NoError(t, err) + + conn, err := types.NewGithubConnector("example", types.GithubConnectorSpecV3{ + ClientID: "example-client-id", + ClientSecret: "example-client-secret", + RedirectURL: "https://localhost:3080/v1/webapi/github/callback", + Display: "sign in with github", + TeamsToLogins: []types.TeamMapping{ + { + Organization: "octocats", + Team: "idp-admin", + Logins: []string{"access"}, + }, + }, + }) + require.NoError(t, err) + + err = srv.Auth().UpsertGithubConnector(context.Background(), conn) + require.NoError(t, err) + + reqNormal := services.GithubAuthRequest{ConnectorID: conn.GetName(), Type: constants.Github} + reqTest := services.GithubAuthRequest{ConnectorID: conn.GetName(), Type: constants.Github, SSOTestFlow: true, ConnectorSpec: &types.GithubConnectorSpecV3{ + ClientID: "example-client-id", + ClientSecret: "example-client-secret", + RedirectURL: "https://localhost:3080/v1/webapi/github/callback", + Display: "sign in with github", + TeamsToLogins: []types.TeamMapping{ + { + Organization: "octocats", + Team: "idp-admin", + Logins: []string{"access"}, + }, + }, + }} + + tests := []struct { + desc string + roles []string + request services.GithubAuthRequest + expectAccessDenied bool + }{ + { + desc: "empty role - no access", + roles: []string{emptyRole.GetName()}, + request: reqNormal, + expectAccessDenied: true, + }, + { + desc: "can create regular request with normal access", + roles: []string{access1Role.GetName()}, + request: reqNormal, + expectAccessDenied: false, + }, + { + desc: "cannot create sso test request with normal access", + roles: []string{access1Role.GetName()}, + request: reqTest, + expectAccessDenied: true, + }, + { + desc: "cannot create normal request with connector access", + roles: []string{access2Role.GetName()}, + request: reqNormal, + expectAccessDenied: true, + }, + { + desc: "cannot create sso test request with connector access", + roles: []string{access2Role.GetName()}, + request: reqTest, + expectAccessDenied: true, + }, + { + desc: "can create regular request with combined access", + roles: []string{access3Role.GetName()}, + request: reqNormal, + expectAccessDenied: false, + }, + { + desc: "can create sso test request with combined access", + roles: []string{access3Role.GetName()}, + request: reqTest, + expectAccessDenied: false, + }, + } + + user, err := CreateUser(srv.Auth(), "dummy") + require.NoError(t, err) + + userReader, err := CreateUser(srv.Auth(), "dummy-reader", readerRole) + require.NoError(t, err) + + clientReader, err := srv.NewClient(TestUser(userReader.GetName())) + require.NoError(t, err) + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + user.SetRoles(tt.roles) + err = srv.Auth().UpsertUser(user) + require.NoError(t, err) + + client, err := srv.NewClient(TestUser(user.GetName())) + require.NoError(t, err) + + request, err := client.CreateGithubAuthRequest(tt.request) + if tt.expectAccessDenied { + require.Error(t, err) + require.True(t, trace.IsAccessDenied(err), "expected access denied, got: %v", err) + return + } + + require.NoError(t, err) + require.NotEmpty(t, request.StateToken) + require.Equal(t, tt.request.ConnectorID, request.ConnectorID) + + requestCopy, err := clientReader.GetGithubAuthRequest(ctx, request.StateToken) + require.NoError(t, err) + require.Equal(t, request, requestCopy) + }) + } +} + func TestSSODiagnosticInfo(t *testing.T) { ctx := context.Background() srv := newTestTLSServer(t) diff --git a/lib/auth/clt.go b/lib/auth/clt.go index e4fc949afb55a..cc494f882212e 100644 --- a/lib/auth/clt.go +++ b/lib/auth/clt.go @@ -1219,9 +1219,22 @@ func (c *Client) CreateGithubAuthRequest(req services.GithubAuthRequest) (*servi return &response, nil } +// GetGithubAuthRequest gets Github AuthnRequest +func (c *Client) GetGithubAuthRequest(ctx context.Context, id string) (*services.GithubAuthRequest, error) { + out, err := c.Get(ctx, c.Endpoint("github", "requests", "get", id), url.Values{}) + if err != nil { + return nil, trace.Wrap(err) + } + var response services.GithubAuthRequest + if err := json.Unmarshal(out.Bytes(), &response); err != nil { + return nil, trace.Wrap(err) + } + return &response, nil +} + // ValidateGithubAuthCallback validates Github auth callback returned from redirect -func (c *Client) ValidateGithubAuthCallback(q url.Values) (*GithubAuthResponse, error) { - out, err := c.PostJSON(context.TODO(), c.Endpoint("github", "requests", "validate"), +func (c *Client) ValidateGithubAuthCallback(ctx context.Context, q url.Values) (*GithubAuthResponse, error) { + out, err := c.PostJSON(ctx, c.Endpoint("github", "requests", "validate"), validateGithubAuthCallbackReq{Query: q}) if err != nil { return nil, trace.Wrap(err) @@ -1706,8 +1719,10 @@ type IdentityService interface { DeleteGithubConnector(ctx context.Context, id string) error // CreateGithubAuthRequest creates a new request for Github OAuth2 flow CreateGithubAuthRequest(services.GithubAuthRequest) (*services.GithubAuthRequest, error) + // GetGithubAuthRequest returns Github auth request if found + GetGithubAuthRequest(ctx context.Context, id string) (*services.GithubAuthRequest, error) // ValidateGithubAuthCallback validates Github auth callback - ValidateGithubAuthCallback(q url.Values) (*GithubAuthResponse, error) + ValidateGithubAuthCallback(ctx context.Context, q url.Values) (*GithubAuthResponse, error) // GetUser returns user by name GetUser(name string, withSecrets bool) (types.User, error) diff --git a/lib/auth/github.go b/lib/auth/github.go index 2872aeee55bfb..989699195cff7 100644 --- a/lib/auth/github.go +++ b/lib/auth/github.go @@ -42,11 +42,7 @@ import ( // CreateGithubAuthRequest creates a new request for Github OAuth2 flow func (a *Server) CreateGithubAuthRequest(req services.GithubAuthRequest) (*services.GithubAuthRequest, error) { ctx := context.TODO() - connector, err := a.Identity.GetGithubConnector(ctx, req.ConnectorID, true) - if err != nil { - return nil, trace.Wrap(err) - } - client, err := a.getGithubOAuth2Client(connector) + _, client, err := a.getGithubConnectorAndClient(ctx, req) if err != nil { return nil, trace.Wrap(err) } @@ -128,12 +124,14 @@ type GithubAuthResponse struct { } type githubManager interface { - validateGithubAuthCallback(q url.Values) (*githubAuthResponse, error) + validateGithubAuthCallback(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) + newSSODiagContext(authKind string) *ssoDiagContext } // ValidateGithubAuthCallback validates Github auth callback redirect -func (a *Server) ValidateGithubAuthCallback(q url.Values) (*GithubAuthResponse, error) { - return validateGithubAuthCallbackHelper(a.closeCtx, a, q, a.emitter) +func (a *Server) ValidateGithubAuthCallback(ctx context.Context, q url.Values) (*GithubAuthResponse, error) { + + return validateGithubAuthCallbackHelper(ctx, a, q, a.emitter) } func validateGithubAuthCallbackHelper(ctx context.Context, m githubManager, q url.Values, emitter apievents.Emitter) (*GithubAuthResponse, error) { @@ -144,9 +142,16 @@ func validateGithubAuthCallbackHelper(ctx context.Context, m githubManager, q ur Method: events.LoginMethodGithub, } - re, err := m.validateGithubAuthCallback(q) - if re != nil && re.claims != nil { - attributes, err := apievents.EncodeMapStrings(re.claims) + diagCtx := m.newSSODiagContext(types.KindGithub) + + auth, err := m.validateGithubAuthCallback(ctx, diagCtx, q) + diagCtx.info.Error = trace.UserMessage(err) + + diagCtx.writeToBackend(ctx) + + claims := diagCtx.info.GithubClaims + if claims != nil { + attributes, err := apievents.EncodeMapStrings(claims.OrganizationToTeams) if err != nil { event.Status.UserMessage = fmt.Sprintf("Failed to encode identity attributes: %v", err.Error()) log.WithError(err).Debug("Failed to encode identity attributes.") @@ -157,6 +162,9 @@ func validateGithubAuthCallbackHelper(ctx context.Context, m githubManager, q ur if err != nil { event.Code = events.UserSSOLoginFailureCode + if diagCtx.info.TestFlow { + event.Code = events.UserSSOTestFlowLoginFailureCode + } event.Status.Success = false event.Status.Error = trace.Unwrap(err).Error() event.Status.UserMessage = err.Error() @@ -167,64 +175,163 @@ func validateGithubAuthCallbackHelper(ctx context.Context, m githubManager, q ur return nil, trace.Wrap(err) } event.Code = events.UserSSOLoginCode + if diagCtx.info.TestFlow { + event.Code = events.UserSSOTestFlowLoginCode + } event.Status.Success = true - event.User = re.auth.Username + event.User = auth.Username if err := emitter.EmitAuditEvent(ctx, event); err != nil { log.WithError(err).Warn("Failed to emit Github login event.") } - return &re.auth, nil + return auth, nil } -type githubAuthResponse struct { - auth GithubAuthResponse - claims map[string][]string +func (a *Server) getGithubConnectorAndClient(ctx context.Context, request services.GithubAuthRequest) (types.GithubConnector, *oauth2.Client, error) { + if request.SSOTestFlow { + if request.ConnectorSpec == nil { + return nil, nil, trace.BadParameter("ConnectorSpec cannot be nil when SSOTestFlow is true") + } + + if request.ConnectorID == "" { + return nil, nil, trace.BadParameter("ConnectorID cannot be empty") + } + + // stateless test flow + connector, err := types.NewGithubConnector(request.ConnectorID, *request.ConnectorSpec) + if err != nil { + return nil, nil, trace.Wrap(err) + } + + // construct client directly. + config := newGithubOAuth2Config(connector) + client, err := oauth2.NewClient(http.DefaultClient, config) + if err != nil { + return nil, nil, trace.Wrap(err) + } + + return connector, client, nil + } + + // regular execution flow + connector, err := a.Identity.GetGithubConnector(ctx, request.ConnectorID, true) + if err != nil { + return nil, nil, trace.Wrap(err) + } + + client, err := a.getGithubOAuth2Client(connector) + if err != nil { + return nil, nil, trace.Wrap(err) + } + + return connector, client, nil +} + +func newGithubOAuth2Config(connector types.GithubConnector) oauth2.Config { + return oauth2.Config{ + Credentials: oauth2.ClientCredentials{ + ID: connector.GetClientID(), + Secret: connector.GetClientSecret(), + }, + RedirectURL: connector.GetRedirectURL(), + Scope: GithubScopes, + AuthURL: GithubAuthURL, + TokenURL: GithubTokenURL, + } +} + +func (a *Server) getGithubOAuth2Client(connector types.GithubConnector) (*oauth2.Client, error) { + config := newGithubOAuth2Config(connector) + + a.lock.Lock() + defer a.lock.Unlock() + + cachedClient, ok := a.githubClients[connector.GetName()] + if ok && oauth2ConfigsEqual(cachedClient.config, config) { + return cachedClient.client, nil + } + + delete(a.githubClients, connector.GetName()) + client, err := oauth2.NewClient(http.DefaultClient, config) + if err != nil { + return nil, trace.Wrap(err) + } + a.githubClients[connector.GetName()] = &githubClient{ + client: client, + config: config, + } + return client, nil } // ValidateGithubAuthCallback validates Github auth callback redirect -func (a *Server) validateGithubAuthCallback(q url.Values) (*githubAuthResponse, error) { - ctx := context.TODO() +func (a *Server) validateGithubAuthCallback(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) { logger := log.WithFields(logrus.Fields{trace.Component: "github"}) - error := q.Get("error") - if error != "" { - return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, error, q) + + if errParam := q.Get("error"); errParam != "" { + // try to find request so the error gets logged against it. + state := q.Get("state") + if state != "" { + diagCtx.requestID = state + req, err := a.Identity.GetGithubAuthRequest(ctx, state) + if err == nil { + diagCtx.info.TestFlow = req.SSOTestFlow + } + } + + // optional parameter: error_description + errDesc := q.Get("error_description") + return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, errParam, q).AddUserMessage("Github returned error: %v [%v]", errDesc, errParam) } + code := q.Get("code") if code == "" { return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, - "code query param must be set", q) + "code query param must be set", q).AddUserMessage("Invalid parameters received from Github.") } + stateToken := q.Get("state") if stateToken == "" { return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, - "missing state query param", q) + "missing state query param", q).AddUserMessage("Invalid parameters received from Github.") } - req, err := a.Identity.GetGithubAuthRequest(stateToken) + diagCtx.requestID = stateToken + + req, err := a.Identity.GetGithubAuthRequest(ctx, stateToken) if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to get OIDC Auth Request.") } - connector, err := a.Identity.GetGithubConnector(ctx, req.ConnectorID, true) + diagCtx.info.TestFlow = req.SSOTestFlow + + connector, client, err := a.getGithubConnectorAndClient(ctx, *req) if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to get Github connector and client.") } + diagCtx.info.GithubTeamsToLogins = connector.GetTeamsToLogins() + logger.Debugf("Connector %q teams to logins: %v", connector.GetName(), connector.GetTeamsToLogins()) + if len(connector.GetTeamsToLogins()) == 0 { logger.Warnf("Github connector %q has empty teams_to_logins mapping, cannot populate claims.", connector.GetName()) return nil, trace.BadParameter( "connector %q has empty teams_to_logins mapping", connector.GetName()) } - client, err := a.getGithubOAuth2Client(connector) - if err != nil { - return nil, trace.Wrap(err) - } + // exchange the authorization code received by the callback for an access token token, err := client.RequestToken(oauth2.GrantTypeAuthCode, code) if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Requesting Github OAuth2 token failed.") + } + + diagCtx.info.GithubTokenInfo = &types.GithubTokenInfo{ + TokenType: token.TokenType, + Expires: int64(token.Expires), + Scope: token.Scope, } + logger.Debugf("Obtained OAuth2 token: Type=%v Expires=%v Scope=%v.", token.TokenType, token.Expires, token.Scope) + // Github does not support OIDC so user claims have to be populated // by making requests to Github API using the access token claims, err := populateGithubClaims(&githubAPIClient{ @@ -232,26 +339,35 @@ func (a *Server) validateGithubAuthCallback(q url.Values) (*githubAuthResponse, authServer: a, }) if err != nil { - return nil, trace.Wrap(err) - } - - re := &githubAuthResponse{ - claims: claims.OrganizationToTeams, + return nil, trace.Wrap(err, "Failed to query Github API for user claims.") } + diagCtx.info.GithubClaims = claims // Calculate (figure out name, roles, traits, session TTL) of user and // create the user in the backend. params, err := a.calculateGithubUser(connector, claims, req) if err != nil { - return re, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to calculate user attributes.") + } + + diagCtx.info.CreateUserParams = &types.CreateUserParams{ + ConnectorName: params.connectorName, + Username: params.username, + Logins: params.logins, + KubeGroups: params.kubeGroups, + KubeUsers: params.kubeUsers, + Roles: params.roles, + Traits: params.traits, + SessionTTL: types.Duration(params.sessionTTL), } - user, err := a.createGithubUser(params) + + user, err := a.createGithubUser(ctx, params, req.SSOTestFlow) if err != nil { - return re, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to create user from provided parameters.") } // Auth was successful, return session, certificate, etc. to caller. - re.auth = GithubAuthResponse{ + auth := GithubAuthResponse{ Req: *req, Identity: types.ExternalIdentity{ ConnectorID: params.connectorName, @@ -259,7 +375,12 @@ func (a *Server) validateGithubAuthCallback(q url.Values) (*githubAuthResponse, }, Username: user.GetName(), } - re.auth.Username = user.GetName() + + // In test flow skip signing and creating web sessions. + if req.SSOTestFlow { + diagCtx.info.Success = true + return &auth, nil + } // If the request is coming from a browser, create a web session. if req.CreateWebSession { @@ -271,26 +392,26 @@ func (a *Server) validateGithubAuthCallback(q url.Values) (*githubAuthResponse, LoginTime: a.clock.Now().UTC(), }) if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to create web session.") } - re.auth.Session = session + auth.Session = session } // If a public key was provided, sign it and return a certificate. if len(req.PublicKey) != 0 { sshCert, tlsCert, err := a.createSessionCert(user, params.sessionTTL, req.PublicKey, req.Compatibility, req.RouteToCluster, req.KubernetesCluster) if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to create session certificate.") } clusterName, err := a.GetClusterName() if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to obtain cluster name.") } - re.auth.Cert = sshCert - re.auth.TLSCert = tlsCert + auth.Cert = sshCert + auth.TLSCert = tlsCert // Return the host CA for this cluster only. authority, err := a.GetCertAuthority(ctx, types.CertAuthID{ @@ -298,12 +419,12 @@ func (a *Server) validateGithubAuthCallback(q url.Values) (*githubAuthResponse, DomainName: clusterName.GetClusterName(), }, false) if err != nil { - return nil, trace.Wrap(err) + return nil, trace.Wrap(err, "Failed to obtain cluster's host CA.") } - re.auth.HostSigners = append(re.auth.HostSigners, authority) + auth.HostSigners = append(auth.HostSigners, authority) } - return re, nil + return &auth, nil } // createUserParams is a set of parameters used to create a user for an @@ -344,12 +465,12 @@ func (a *Server) calculateGithubUser(connector types.GithubConnector, claims *ty p.logins, p.kubeGroups, p.kubeUsers = connector.MapClaims(*claims) if len(p.logins) == 0 { return nil, trace.BadParameter( - "user %q does not belong to any teams configured in %q connector", + "user %q does not belong to any teams configured in %q connector; the configuration may have typos.", claims.Username, connector.GetName()) } p.roles = p.logins p.traits = map[string][]string{ - teleport.TraitLogins: []string{p.username}, + teleport.TraitLogins: {p.username}, teleport.TraitKubeGroups: p.kubeGroups, teleport.TraitKubeUsers: p.kubeUsers, teleport.TraitTeams: claims.Teams, @@ -366,11 +487,10 @@ func (a *Server) calculateGithubUser(connector types.GithubConnector, claims *ty return &p, nil } -func (a *Server) createGithubUser(p *createUserParams) (types.User, error) { - +func (a *Server) createGithubUser(ctx context.Context, p *createUserParams, dryRun bool) (types.User, error) { log.WithFields(logrus.Fields{trace.Component: "github"}).Debugf( - "Generating dynamic identity %v/%v with logins: %v.", - p.connectorName, p.username, p.logins) + "Generating dynamic GitHub identity %v/%v with logins: %v. Dry run: %v.", + p.connectorName, p.username, p.logins, dryRun) expires := a.GetClock().Now().UTC().Add(p.sessionTTL) @@ -401,13 +521,15 @@ func (a *Server) createGithubUser(p *createUserParams) (types.User, error) { }, } + if dryRun { + return user, nil + } + existingUser, err := a.GetUser(p.username, false) if err != nil && !trace.IsNotFound(err) { return nil, trace.Wrap(err) } - ctx := context.TODO() - if existingUser != nil { ref := user.GetCreatedBy().Connector if !ref.IsSameProvider(existingUser.GetCreatedBy().Connector) { @@ -463,35 +585,6 @@ func populateGithubClaims(client githubAPIClientI) (*types.GithubClaims, error) return claims, nil } -func (a *Server) getGithubOAuth2Client(connector types.GithubConnector) (*oauth2.Client, error) { - a.lock.Lock() - defer a.lock.Unlock() - config := oauth2.Config{ - Credentials: oauth2.ClientCredentials{ - ID: connector.GetClientID(), - Secret: connector.GetClientSecret(), - }, - RedirectURL: connector.GetRedirectURL(), - Scope: GithubScopes, - AuthURL: GithubAuthURL, - TokenURL: GithubTokenURL, - } - cachedClient, ok := a.githubClients[connector.GetName()] - if ok && oauth2ConfigsEqual(cachedClient.config, config) { - return cachedClient.client, nil - } - delete(a.githubClients, connector.GetName()) - client, err := oauth2.NewClient(http.DefaultClient, config) - if err != nil { - return nil, trace.Wrap(err) - } - a.githubClients[connector.GetName()] = &githubClient{ - client: client, - config: config, - } - return client, nil -} - // githubAPIClientI defines an interface for Github API wrapper // so it can be substituted in tests type githubAPIClientI interface { diff --git a/lib/auth/github_test.go b/lib/auth/github_test.go index ab71e6db1de0f..a0e5b417b768d 100644 --- a/lib/auth/github_test.go +++ b/lib/auth/github_test.go @@ -29,8 +29,10 @@ import ( "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/events/eventstest" "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/trace" + "github.com/google/uuid" "github.com/jonboulle/clockwork" "gopkg.in/check.v1" ) @@ -89,14 +91,29 @@ func (s *GithubSuite) TestPopulateClaims(c *check.C) { } func (s *GithubSuite) TestCreateGithubUser(c *check.C) { + // Dry-run creation of Github user. + user, err := s.a.createGithubUser(context.Background(), &createUserParams{ + connectorName: "github", + username: "foo@example.com", + logins: []string{"foo"}, + roles: []string{"admin"}, + sessionTTL: 1 * time.Minute, + }, true) + c.Assert(err, check.IsNil) + c.Assert(user.GetName(), check.Equals, "foo@example.com") + + // Dry-run must not create a user. + _, err = s.a.GetUser("foo@example.com", false) + c.Assert(err, check.NotNil) + // Create GitHub user with 1 minute expiry. - _, err := s.a.createGithubUser(&createUserParams{ + _, err = s.a.createGithubUser(context.Background(), &createUserParams{ connectorName: "github", username: "foo", logins: []string{"foo"}, roles: []string{"admin"}, sessionTTL: 1 * time.Minute, - }) + }, false) c.Assert(err, check.IsNil) // Within that 1 minute period the user should still exist. @@ -136,41 +153,94 @@ func (c *testGithubAPIClient) getTeams() ([]teamResponse, error) { } func (s *GithubSuite) TestValidateGithubAuthCallbackEventsEmitted(c *check.C) { - auth := &githubAuthResponse{ - auth: GithubAuthResponse{ - Username: "test-name", - }, - claims: map[string][]string{ + auth := &GithubAuthResponse{ + Username: "test-name", + } + + claims := &types.GithubClaims{ + OrganizationToTeams: map[string][]string{ "test": {}, }, } + ssoDiagInfoCalls := 0 + m := &mockedGithubManager{} + m.createSSODiagnosticInfo = func(ctx context.Context, authKind string, authRequestID string, info types.SSODiagnosticInfo) error { + ssoDiagInfoCalls++ + return nil + } + + // TestFlow: false + m.testFlow = false // Test success event. - m.mockValidateGithubAuthCallback = func(q url.Values) (*githubAuthResponse, error) { + m.mockValidateGithubAuthCallback = func(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) { + diagCtx.info.GithubClaims = claims return auth, nil } _, _ = validateGithubAuthCallbackHelper(context.Background(), m, nil, s.a.emitter) c.Assert(s.mockEmitter.LastEvent().GetType(), check.Equals, events.UserLoginEvent) c.Assert(s.mockEmitter.LastEvent().GetCode(), check.Equals, events.UserSSOLoginCode) + c.Assert(ssoDiagInfoCalls, check.Equals, 0) s.mockEmitter.Reset() // Test failure event. - m.mockValidateGithubAuthCallback = func(q url.Values) (*githubAuthResponse, error) { + m.mockValidateGithubAuthCallback = func(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) { + diagCtx.info.GithubClaims = claims return auth, trace.BadParameter("") } _, _ = validateGithubAuthCallbackHelper(context.Background(), m, nil, s.a.emitter) c.Assert(s.mockEmitter.LastEvent().GetCode(), check.Equals, events.UserSSOLoginFailureCode) + c.Assert(ssoDiagInfoCalls, check.Equals, 0) + + // TestFlow: true + m.testFlow = true + + // Test success event. + m.mockValidateGithubAuthCallback = func(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) { + diagCtx.info.GithubClaims = claims + return auth, nil + } + _, _ = validateGithubAuthCallbackHelper(context.Background(), m, nil, s.a.emitter) + c.Assert(s.mockEmitter.LastEvent().GetType(), check.Equals, events.UserLoginEvent) + c.Assert(s.mockEmitter.LastEvent().GetCode(), check.Equals, events.UserSSOTestFlowLoginCode) + c.Assert(ssoDiagInfoCalls, check.Equals, 1) + s.mockEmitter.Reset() + + // Test failure event. + m.mockValidateGithubAuthCallback = func(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) { + diagCtx.info.GithubClaims = claims + return auth, trace.BadParameter("") + } + _, _ = validateGithubAuthCallbackHelper(context.Background(), m, nil, s.a.emitter) + c.Assert(s.mockEmitter.LastEvent().GetCode(), check.Equals, events.UserSSOTestFlowLoginFailureCode) + c.Assert(ssoDiagInfoCalls, check.Equals, 2) } type mockedGithubManager struct { - mockValidateGithubAuthCallback func(q url.Values) (*githubAuthResponse, error) + mockValidateGithubAuthCallback func(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) + createSSODiagnosticInfo func(ctx context.Context, authKind string, authRequestID string, info types.SSODiagnosticInfo) error + + testFlow bool +} + +func (m *mockedGithubManager) newSSODiagContext(authKind string) *ssoDiagContext { + if m.createSSODiagnosticInfo == nil { + panic("mockedGithubManager.createSSODiagnosticInfo is nil, newSSODiagContext cannot succeed.") + } + + return &ssoDiagContext{ + authKind: authKind, + createSSODiagnosticInfo: m.createSSODiagnosticInfo, + requestID: uuid.New().String(), + info: types.SSODiagnosticInfo{TestFlow: m.testFlow}, + } } -func (m *mockedGithubManager) validateGithubAuthCallback(q url.Values) (*githubAuthResponse, error) { +func (m *mockedGithubManager) validateGithubAuthCallback(ctx context.Context, diagCtx *ssoDiagContext, q url.Values) (*GithubAuthResponse, error) { if m.mockValidateGithubAuthCallback != nil { - return m.mockValidateGithubAuthCallback(q) + return m.mockValidateGithubAuthCallback(ctx, diagCtx, q) } return nil, trace.NotImplemented("mockValidateGithubAuthCallback not implemented") diff --git a/lib/auth/oidc.go b/lib/auth/oidc.go index 1ff07268b211f..227248fe3b4c5 100644 --- a/lib/auth/oidc.go +++ b/lib/auth/oidc.go @@ -277,9 +277,7 @@ func (a *Server) ValidateOIDCAuthCallback(ctx context.Context, q url.Values) (*O diagCtx := a.newSSODiagContext(types.KindOIDC) auth, err := a.validateOIDCAuthCallback(ctx, diagCtx, q) - if err != nil { - diagCtx.info.Error = trace.UserMessage(err) - } + diagCtx.info.Error = trace.UserMessage(err) diagCtx.writeToBackend(ctx) @@ -593,7 +591,7 @@ func (a *Server) calculateOIDCUser(diagCtx *ssoDiagContext, connector types.OIDC func (a *Server) createOIDCUser(p *createUserParams, dryRun bool) (types.User, error) { expires := a.GetClock().Now().UTC().Add(p.sessionTTL) - log.Debugf("Generating dynamic OIDC identity %v/%v with roles: %v.", p.connectorName, p.username, p.roles) + log.Debugf("Generating dynamic OIDC identity %v/%v with roles: %v. Dry run: %v.", p.connectorName, p.username, p.roles, dryRun) user := &types.UserV2{ Kind: types.KindUser, Version: types.V2, @@ -775,7 +773,7 @@ func (a *Server) getClaims(oidcClient *oidc.Client, connector types.OIDCConnecto return a.getClaimsFun(a.closeCtx, oidcClient, connector, code) } -// getClaimsFun implements Server.getClaims, but allows that code path to be overridden for testing. +// getClaims implements Server.getClaims, but allows that code path to be overridden for testing. func getClaims(closeCtx context.Context, oidcClient *oidc.Client, connector types.OIDCConnector, code string) (jose.Claims, error) { oac, err := getOAuthClient(oidcClient, connector) diff --git a/lib/auth/saml.go b/lib/auth/saml.go index 795d8e152e67c..0b03d452fc604 100644 --- a/lib/auth/saml.go +++ b/lib/auth/saml.go @@ -84,7 +84,7 @@ func (a *Server) DeleteSAMLConnector(ctx context.Context, connectorName string) func (a *Server) CreateSAMLAuthRequest(req services.SAMLAuthRequest) (*services.SAMLAuthRequest, error) { ctx := context.TODO() - connector, provider, err := a.getConnectorAndProvider(ctx, req) + connector, provider, err := a.getSAMLConnectorAndProvider(ctx, req) if err != nil { return nil, trace.Wrap(err) } @@ -123,7 +123,7 @@ func (a *Server) CreateSAMLAuthRequest(req services.SAMLAuthRequest) (*services. return &req, nil } -func (a *Server) getConnectorAndProvider(ctx context.Context, req services.SAMLAuthRequest) (types.SAMLConnector, *saml2.SAMLServiceProvider, error) { +func (a *Server) getSAMLConnectorAndProvider(ctx context.Context, req services.SAMLAuthRequest) (types.SAMLConnector, *saml2.SAMLServiceProvider, error) { if req.SSOTestFlow { if req.ConnectorSpec == nil { return nil, nil, trace.BadParameter("ConnectorSpec cannot be nil when SSOTestFlow is true") @@ -230,7 +230,7 @@ func (a *Server) calculateSAMLUser(diagCtx *ssoDiagContext, connector types.SAML func (a *Server) createSAMLUser(p *createUserParams, dryRun bool) (types.User, error) { expires := a.GetClock().Now().UTC().Add(p.sessionTTL) - log.Debugf("Generating dynamic SAML identity %v/%v with roles: %v.", p.connectorName, p.username, p.roles) + log.Debugf("Generating dynamic SAML identity %v/%v with roles: %v. Dry run: %v.", p.connectorName, p.username, p.roles, dryRun) user := &types.UserV2{ Kind: types.KindUser, @@ -372,9 +372,7 @@ func (a *Server) ValidateSAMLResponse(ctx context.Context, samlResponse string) diagCtx := a.newSSODiagContext(types.KindSAML) auth, err := a.validateSAMLResponse(ctx, diagCtx, samlResponse) - if err != nil { - diagCtx.info.Error = trace.UserMessage(err) - } + diagCtx.info.Error = trace.UserMessage(err) diagCtx.writeToBackend(ctx) @@ -430,7 +428,7 @@ func (a *Server) validateSAMLResponse(ctx context.Context, diagCtx *ssoDiagConte } diagCtx.info.TestFlow = request.SSOTestFlow - connector, provider, err := a.getConnectorAndProvider(ctx, *request) + connector, provider, err := a.getSAMLConnectorAndProvider(ctx, *request) if err != nil { return nil, trace.Wrap(err, "Failed to get SAML connector and provider") } diff --git a/lib/auth/saml_test.go b/lib/auth/saml_test.go index 60bd679e958ce..543577f182f7b 100644 --- a/lib/auth/saml_test.go +++ b/lib/auth/saml_test.go @@ -318,7 +318,7 @@ func TestServer_getConnectorAndProvider(t *testing.T) { }, } - connector, provider, err := a.getConnectorAndProvider(context.Background(), request) + connector, provider, err := a.getSAMLConnectorAndProvider(context.Background(), request) require.NoError(t, err) require.NotNil(t, connector) require.NotNil(t, provider) @@ -353,7 +353,7 @@ func TestServer_getConnectorAndProvider(t *testing.T) { SSOTestFlow: false, } - connector, provider, err = a.getConnectorAndProvider(context.Background(), request2) + connector, provider, err = a.getSAMLConnectorAndProvider(context.Background(), request2) require.NoError(t, err) require.NotNil(t, connector) require.NotNil(t, provider) diff --git a/lib/services/identity.go b/lib/services/identity.go index 81a9c4b4c7649..6bb34850bd504 100644 --- a/lib/services/identity.go +++ b/lib/services/identity.go @@ -231,7 +231,7 @@ type Identity interface { CreateGithubAuthRequest(req GithubAuthRequest) error // GetGithubAuthRequest retrieves Github auth request by the token - GetGithubAuthRequest(stateToken string) (*GithubAuthRequest, error) + GetGithubAuthRequest(ctx context.Context, stateToken string) (*GithubAuthRequest, error) // CreateUserToken creates a new user token. CreateUserToken(ctx context.Context, token types.UserToken) (types.UserToken, error) @@ -333,6 +333,10 @@ type GithubAuthRequest struct { RouteToCluster string `json:"route_to_cluster,omitempty"` // KubernetesCluster is the name of Kubernetes cluster to issue credentials for. KubernetesCluster string `json:"kubernetes_cluster,omitempty"` + // SSOTestFlow indicates if the request is part of the test flow. + SSOTestFlow bool `json:"sso_test_flow"` + // ConnectorSpec is embedded connector spec for use in test flow. + ConnectorSpec *types.GithubConnectorSpecV3 `json:"connector_spec,omitempty"` } // SetExpiry sets expiry time for the object @@ -365,6 +369,16 @@ func (r *GithubAuthRequest) Check() error { return trace.BadParameter("wrong CertTTL") } } + + // we could collapse these two checks into one, but the error message would become ambiguous. + if r.SSOTestFlow && r.ConnectorSpec == nil { + return trace.BadParameter("ConnectorSpec cannot be nil when SSOTestFlow is true") + } + + if !r.SSOTestFlow && r.ConnectorSpec != nil { + return trace.BadParameter("ConnectorSpec must be nil when SSOTestFlow is false") + } + return nil } diff --git a/lib/services/identity_test.go b/lib/services/identity_test.go index 89672000cb19e..1548ce10b2925 100644 --- a/lib/services/identity_test.go +++ b/lib/services/identity_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/trace" "github.com/stretchr/testify/require" ) @@ -218,3 +219,108 @@ func TestOIDCAuthRequest_Check(t *testing.T) { }) } } + +func TestGithubAuthRequest_Check(t *testing.T) { + const exampleSSHCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=` + + tests := []struct { + name string + req GithubAuthRequest + wantErr bool + }{ + { + name: "normal request", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + PublicKey: []byte(exampleSSHCert), + CertTTL: 60 * time.Minute, + }, + wantErr: false, + }, + { + name: "missing state token", + req: GithubAuthRequest{ + ConnectorID: "foo", + PublicKey: []byte(exampleSSHCert), + CertTTL: 60 * time.Minute, + }, + wantErr: true, + }, + { + name: "below min CertTTL", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + PublicKey: []byte(exampleSSHCert), + CertTTL: 1 * time.Second, + }, + wantErr: true, + }, + { + name: "above max CertTTL", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + PublicKey: []byte(exampleSSHCert), + CertTTL: 1000 * time.Hour, + }, + wantErr: true, + }, + { + name: "TTL ignored without cert", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + CertTTL: 60 * time.Minute, + }, + wantErr: false, + }, + { + name: "SSOTestFlow requires ConnectorSpec", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + PublicKey: []byte(exampleSSHCert), + CertTTL: 60 * time.Minute, + SSOTestFlow: true, + }, + wantErr: true, + }, + { + name: "ConnectorSpec requires SSOTestFlow", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + PublicKey: []byte(exampleSSHCert), + CertTTL: 60 * time.Minute, + ConnectorSpec: &types.GithubConnectorSpecV3{Display: "dummy"}, + }, + wantErr: true, + }, + { + name: "ConnectorSpec with SSOTestFlow works", + req: GithubAuthRequest{ + ConnectorID: "foo", + StateToken: "bar", + PublicKey: []byte(exampleSSHCert), + CertTTL: 60 * time.Minute, + SSOTestFlow: true, + ConnectorSpec: &types.GithubConnectorSpecV3{Display: "dummy"}, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.req.Check() + if tt.wantErr { + require.Error(t, err) + require.True(t, trace.IsBadParameter(err)) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/lib/services/local/users.go b/lib/services/local/users.go index b4023fb91279a..4718edca1a5d8 100644 --- a/lib/services/local/users.go +++ b/lib/services/local/users.go @@ -25,13 +25,14 @@ import ( "sync" "time" - "github.com/gokyle/hotp" - "github.com/google/go-cmp/cmp" - "github.com/google/uuid" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/services" + + "github.com/gokyle/hotp" + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/sirupsen/logrus" @@ -1388,11 +1389,11 @@ func (s *IdentityService) CreateGithubAuthRequest(req services.GithubAuthRequest } // GetGithubAuthRequest retrieves Github auth request by the token -func (s *IdentityService) GetGithubAuthRequest(stateToken string) (*services.GithubAuthRequest, error) { +func (s *IdentityService) GetGithubAuthRequest(ctx context.Context, stateToken string) (*services.GithubAuthRequest, error) { if stateToken == "" { return nil, trace.BadParameter("missing parameter stateToken") } - item, err := s.Get(context.TODO(), backend.Key(webPrefix, connectorsPrefix, githubPrefix, requestsPrefix, stateToken)) + item, err := s.Get(ctx, backend.Key(webPrefix, connectorsPrefix, githubPrefix, requestsPrefix, stateToken)) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index 26afe44e756a1..bc6d64b364647 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -1142,9 +1142,22 @@ func (h *Handler) githubCallback(w http.ResponseWriter, r *http.Request, p httpr logger := h.log.WithField("auth", "github") logger.Debugf("Callback start: %v.", r.URL.Query()) - response, err := h.cfg.ProxyClient.ValidateGithubAuthCallback(r.URL.Query()) + response, err := h.cfg.ProxyClient.ValidateGithubAuthCallback(r.Context(), r.URL.Query()) if err != nil { logger.WithError(err).Error("Error while processing callback.") + + // try to find the auth request, which bears the original client redirect URL. + // if found, use it to terminate the flow. + // + // this improves the UX by terminating the failed SSO flow immediately, rather than hoping for a timeout. + if requestID := r.URL.Query().Get("state"); requestID != "" { + if request, errGet := h.cfg.ProxyClient.GetGithubAuthRequest(r.Context(), requestID); errGet == nil && !request.CreateWebSession { + if redURL, errEnc := redirectURLWithError(request.ClientRedirectURL, err); errEnc == nil { + return redURL.String() + } + } + } + return client.LoginFailedBadCallbackRedirectURL } diff --git a/lib/web/apiserver_test.go b/lib/web/apiserver_test.go index 9c3c150b0bf48..4ae9b6f01f191 100644 --- a/lib/web/apiserver_test.go +++ b/lib/web/apiserver_test.go @@ -2468,7 +2468,15 @@ func TestGetWebConfig(t *testing.T) { require.NoError(t, err) // Add a test connector. - github, err := types.NewGithubConnector("test-github", types.GithubConnectorSpecV3{}) + github, err := types.NewGithubConnector("test-github", types.GithubConnectorSpecV3{ + TeamsToLogins: []types.TeamMapping{ + { + Organization: "octocats", + Team: "dummy", + Logins: []string{"dummy"}, + }, + }, + }) require.NoError(t, err) err = env.server.Auth().CreateGithubConnector(github) require.NoError(t, err) diff --git a/lib/web/resources_test.go b/lib/web/resources_test.go index 939722032ba64..5a9fc8e0541a1 100644 --- a/lib/web/resources_test.go +++ b/lib/web/resources_test.go @@ -80,19 +80,32 @@ spec: client_secret: "" display: "" redirect_url: "" - teams_to_logins: null + teams_to_logins: + - logins: + - dummy + organization: octocats + team: dummy version: v3 ` - githubConn, err := types.NewGithubConnector("githubName", types.GithubConnectorSpecV3{}) + githubConn, err := types.NewGithubConnector("githubName", types.GithubConnectorSpecV3{ + TeamsToLogins: []types.TeamMapping{ + { + Organization: "octocats", + Team: "dummy", + Logins: []string{"dummy"}, + }, + }, + }) require.NoError(t, err) item, err := ui.NewResourceItem(githubConn) - require.Nil(t, err) - require.Equal(t, item, &ui.ResourceItem{ + require.NoError(t, err) + + require.Equal(t, &ui.ResourceItem{ ID: "github:githubName", Kind: types.KindGithubConnector, Name: "githubName", Content: contents, - }) + }, item) } func TestNewResourceItemRole(t *testing.T) { @@ -232,7 +245,15 @@ func TestGetGithubConnectors(t *testing.T) { m := &mockedResourceAPIGetter{} m.mockGetGithubConnectors = func(ctx context.Context, withSecrets bool) ([]types.GithubConnector, error) { - connector, err := types.NewGithubConnector("test", types.GithubConnectorSpecV3{}) + connector, err := types.NewGithubConnector("test", types.GithubConnectorSpecV3{ + TeamsToLogins: []types.TeamMapping{ + { + Organization: "octocats", + Team: "dummy", + Logins: []string{"dummy"}, + }, + }, + }) require.NoError(t, err) return []types.GithubConnector{connector}, nil diff --git a/rfd/0070-tctl-sso-configure-command.md b/rfd/0070-tctl-sso-configure-command.md index 3a036449465ab..d445bbba46b74 100644 --- a/rfd/0070-tctl-sso-configure-command.md +++ b/rfd/0070-tctl-sso-configure-command.md @@ -1,6 +1,6 @@ --- authors: Krzysztof Skrzętnicki -state: draft +state: implemented --- # RFD 70 - `tctl sso configure` command @@ -55,8 +55,8 @@ For `SAML` the commonly used flags will be: -p, --preset Preset. One of: [okta onelogin ad adfs] -n, --name Connector name. Required, unless implied from preset. -e, --entity-descriptor Set the Entity Descriptor. Valid values: file, URL, XML content. Supplies configuration parameters as single XML instead of individual elements. --r, --attributes-to-roles Sets attribute-to-role mapping in the form 'attr_name,attr_value,role1,role2,...'. Repeatable. - --display Display controls how this connector is displayed. +-r, --attributes-to-roles Sets attribute-to-role mapping using format 'attr_name,attr_value,role1,role2,...'. Repeatable. + --display Sets the connector display name. ``` The `--attributes-to-roles/-a` flag is particularly important as it is used to provide a mapping between the @@ -96,7 +96,7 @@ Advanced features: Flags for ignoring warnings: ``` ---ignore-missing-roles Ignore non-existing roles referenced in --attributes-to-roles. +--ignore-missing-roles Ignore missing roles referenced in --attributes-to-roles. --ignore-missing-certs Ignore the lack of valid certificates from -e and --cert. ``` diff --git a/rfd/0071-tctl-sso-test-command.md b/rfd/0071-tctl-sso-test-command.md index d0a79b0f7bb94..2d908d54532ad 100644 --- a/rfd/0071-tctl-sso-test-command.md +++ b/rfd/0071-tctl-sso-test-command.md @@ -1,6 +1,6 @@ --- authors: Krzysztof Skrzętnicki -state: draft +state: implemented --- # RFD 71 - `tctl sso test` command diff --git a/tool/tctl/main.go b/tool/tctl/main.go index 1d5451e75851b..ec7c616dcc8c6 100644 --- a/tool/tctl/main.go +++ b/tool/tctl/main.go @@ -18,6 +18,8 @@ package main import ( "github.com/gravitational/teleport/tool/tctl/common" + "github.com/gravitational/teleport/tool/tctl/sso/configure" + "github.com/gravitational/teleport/tool/tctl/sso/tester" ) func main() { @@ -31,6 +33,8 @@ func main() { &common.StatusCommand{}, &common.TopCommand{}, &common.AccessRequestCommand{}, + &configure.SSOConfigureCommand{}, + &tester.SSOTestCommand{}, &common.AppsCommand{}, &common.DBCommand{}, &common.KubeCommand{}, diff --git a/tool/tctl/sso/configure/command.go b/tool/tctl/sso/configure/command.go new file mode 100644 index 0000000000000..dfdb591aec324 --- /dev/null +++ b/tool/tctl/sso/configure/command.go @@ -0,0 +1,74 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package configure + +import ( + "os" + + "github.com/gravitational/teleport" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/service" + "github.com/gravitational/teleport/lib/utils" + + "github.com/gravitational/kingpin" + "github.com/gravitational/trace" + + "github.com/sirupsen/logrus" +) + +// SSOConfigureCommand implements common.CLICommand interface +type SSOConfigureCommand struct { + config *service.Config + ConfigureCmd *kingpin.CmdClause + AuthCommands []*AuthKindCommand + Logger *logrus.Entry +} + +type AuthKindCommand struct { + Parsed bool + Run func(clt auth.ClientI) error +} + +// Initialize allows a caller-defined command to plug itself into CLI +// argument parsing +func (cmd *SSOConfigureCommand) Initialize(app *kingpin.Application, cfg *service.Config) { + cmd.config = cfg + cmd.Logger = cfg.Log.WithField(trace.Component, teleport.ComponentClient) + + sso := app.Command("sso", "A family of commands for configuring and testing auth connectors (SSO).") + cmd.ConfigureCmd = sso.Command("configure", "Create auth connector configuration.") + cmd.AuthCommands = []*AuthKindCommand{addGithubCommand(cmd)} +} + +// TryRun is executed after the CLI parsing is done. The command must +// determine if selectedCommand belongs to it and return match=true +func (cmd *SSOConfigureCommand) TryRun(selectedCommand string, clt auth.ClientI) (match bool, err error) { + for _, subCommand := range cmd.AuthCommands { + if subCommand.Parsed { + // the default tctl logging behaviour is to ignore all logs, unless --debug is present. + // we want different behaviour: log messages as normal, but with compact format (no time, no caller info). + if !cmd.config.Debug { + formatter := utils.NewDefaultTextFormatter(trace.IsTerminal(os.Stderr)) + formatter.FormatCaller = func() (caller string) { return "" } + cmd.Logger.Logger.SetFormatter(formatter) + cmd.Logger.Logger.SetOutput(os.Stderr) + } + + return true, trace.Wrap(subCommand.Run(clt)) + } + } + + return false, nil +} diff --git a/tool/tctl/sso/configure/github.go b/tool/tctl/sso/configure/github.go new file mode 100644 index 0000000000000..424e6b99827d1 --- /dev/null +++ b/tool/tctl/sso/configure/github.go @@ -0,0 +1,161 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package configure + +import ( + "context" + "fmt" + "os" + + "github.com/sirupsen/logrus" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/utils" + + "github.com/gravitational/kingpin" + "github.com/gravitational/trace" +) + +type ghExtraFlags struct { + connectorName string + ignoreMissingRoles bool +} + +func addGithubCommand(cmd *SSOConfigureCommand) *AuthKindCommand { + spec := types.GithubConnectorSpecV3{} + + gh := &ghExtraFlags{} + + sub := cmd.ConfigureCmd.Command("github", "Configure Github auth connector.") + // commonly used flags + sub.Flag("name", "Connector name.").Default("github").Short('n').StringVar(&gh.connectorName) + sub.Flag("teams-to-logins", "Sets teams-to-logins mapping using format 'organization,name,role1,role2,...'. Repeatable."). + Short('r'). + Required(). + PlaceHolder("org,team,role1,role2,..."). + SetValue(newTeamsToLoginsParser(&spec.TeamsToLogins)) + sub.Flag("display", "Sets the connector display name.").StringVar(&spec.Display) + sub.Flag("id", "Github app client ID.").PlaceHolder("ID").Required().StringVar(&spec.ClientID) + sub.Flag("secret", "Github app client secret.").Required().PlaceHolder("SECRET").StringVar(&spec.ClientSecret) + + // auto + sub.Flag("redirect-url", "Authorization callback URL.").PlaceHolder("URL").StringVar(&spec.RedirectURL) + + // ignores + sub.Flag("ignore-missing-roles", "Ignore missing roles referenced in --teams-to-logins.").BoolVar(&gh.ignoreMissingRoles) + + sub.Alias("gh") + + sub.Alias(` +Examples: + + > tctl sso configure gh -r octocats,admin,access,editor,auditor -r octocats,dev,access --secret GH_SECRET --id CLIENT_ID + + Generate Github auth connector. Two role mappings are defined: + - members of 'admin' team in 'octocats' org will receive 'access', 'editor' and 'auditor' roles. + - members of 'dev' team in 'octocats' org will receive 'access' role. + + The values for --secret and --id are provided by GitHub. + + > tctl sso configure gh ... | tctl sso test + + Generate the configuration and immediately test it using "tctl sso test" command.`) + + preset := &AuthKindCommand{ + Run: func(clt auth.ClientI) error { return ghRunFunc(cmd, &spec, gh, clt) }, + } + + sub.Action(func(ctx *kingpin.ParseContext) error { + preset.Parsed = true + return nil + }) + + return preset +} + +func ghRunFunc(cmd *SSOConfigureCommand, spec *types.GithubConnectorSpecV3, flags *ghExtraFlags, clt auth.ClientI) error { + if err := specCheckRoles(cmd.Logger, spec, flags.ignoreMissingRoles, clt); err != nil { + return trace.Wrap(err) + } + + if spec.RedirectURL == "" { + spec.RedirectURL = ResolveCallbackURL(cmd.Logger, clt, "RedirectURL", "https://%v/v1/webapi/github/callback") + } + + connector, err := types.NewGithubConnector(flags.connectorName, *spec) + if err != nil { + return trace.Wrap(err) + } + return trace.Wrap(utils.WriteYAML(os.Stdout, connector)) +} + +// ResolveCallbackURL deals with common pattern of resolving callback URL for IdP to use. +func ResolveCallbackURL(logger *logrus.Entry, clt auth.ClientI, fieldName string, callbackPattern string) string { + var callbackURL string + + logger.Infof("%v empty, resolving automatically.", fieldName) + proxies, err := clt.GetProxies() + if err != nil { + logger.WithError(err).Error("unable to get proxy list.") + } + + // find first proxy with public addr + for _, proxy := range proxies { + publicAddr := proxy.GetPublicAddr() + if publicAddr != "" { + callbackURL = fmt.Sprintf(callbackPattern, publicAddr) + break + } + } + + // check if successfully set. + if callbackURL == "" { + logger.Warnf("Unable to fill %v automatically, cluster's public address unknown.", fieldName) + } else { + logger.Infof("%v set to %q", fieldName, callbackURL) + } + return callbackURL +} + +func specCheckRoles(logger *logrus.Entry, spec *types.GithubConnectorSpecV3, ignoreMissingRoles bool, clt auth.ClientI) error { + allRoles, err := clt.GetRoles(context.TODO()) + if err != nil { + logger.WithError(err).Warn("unable to get roles list. Skipping teams-to-logins sanity checks.") + return nil + } + + roleMap := map[string]bool{} + var roleNames []string + for _, role := range allRoles { + roleMap[role.GetName()] = true + roleNames = append(roleNames, role.GetName()) + } + + for _, mapping := range spec.TeamsToLogins { + for _, role := range mapping.Logins { + _, found := roleMap[role] + if !found { + if ignoreMissingRoles { + logger.Warnf("teams-to-logins references non-existing role: %q. Available roles: %v.", role, roleNames) + } else { + return trace.BadParameter("teams-to-logins references non-existing role: %v. Correct the mapping, or add --ignore-missing-roles to ignore this error. Available roles: %v.", role, roleNames) + } + } + } + } + + return nil +} diff --git a/tool/tctl/sso/configure/teams_to_logins.go b/tool/tctl/sso/configure/teams_to_logins.go new file mode 100644 index 0000000000000..f8b3851aec937 --- /dev/null +++ b/tool/tctl/sso/configure/teams_to_logins.go @@ -0,0 +1,66 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package configure + +import ( + "fmt" + "strings" + + "github.com/gravitational/kingpin" + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/types" +) + +// teamsToLoginsParser parsers 'name,value,role1,role2,...' values into types.AttributeMapping entries. Cumulative, can handle multiple entries. +type teamsToLoginsParser struct { + mappings *[]types.TeamMapping +} + +func (p *teamsToLoginsParser) String() string { + return fmt.Sprintf("%q", p.mappings) +} + +func (p *teamsToLoginsParser) Set(s string) error { + splits := strings.Split(s, ",") + + if len(splits) < 3 { + return trace.BadParameter("Too few elements separated with comma. use syntax: 'name,value,role1,role2,...'.") + } + + name := splits[0] + value := splits[1] + roles := splits[2:] + + mapping := types.TeamMapping{ + Organization: name, + Team: value, + Logins: roles, // note: logins is legacy name, 'roles' is accurate now. + } + + *p.mappings = append(*p.mappings, mapping) + + return nil +} + +// IsCumulative returns true if flag is repeatable. This is checked by kingpin library. +func (p *teamsToLoginsParser) IsCumulative() bool { + return true +} + +// newTeamsToLoginsParser returns a cumulative flag parser for []types.TeamMapping. +func newTeamsToLoginsParser(field *[]types.TeamMapping) kingpin.Value { + return &teamsToLoginsParser{mappings: field} +} diff --git a/tool/tctl/sso/configure/teams_to_logins_test.go b/tool/tctl/sso/configure/teams_to_logins_test.go new file mode 100644 index 0000000000000..561d319ea870c --- /dev/null +++ b/tool/tctl/sso/configure/teams_to_logins_test.go @@ -0,0 +1,89 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package configure + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" +) + +func Test_teamsToLoginsParser_Set(t *testing.T) { + tests := []struct { + name string + parser teamsToLoginsParser + arg string + wantErr bool + wantParser teamsToLoginsParser + }{ + { + name: "one set of correct args", + parser: teamsToLoginsParser{mappings: new([]types.TeamMapping)}, + arg: "foo,bar,baz", + wantParser: teamsToLoginsParser{mappings: &[]types.TeamMapping{ + { + Organization: "foo", + Team: "bar", + Logins: []string{"baz"}, + }, + }}, + wantErr: false, + }, + { + name: "two sets of correct args", + parser: teamsToLoginsParser{mappings: &[]types.TeamMapping{ + { + Organization: "foo", + Team: "bar", + Logins: []string{"baz"}, + }, + }}, + arg: "aaa,bbb,ccc,ddd", + wantParser: teamsToLoginsParser{mappings: &[]types.TeamMapping{ + { + Organization: "foo", + Team: "bar", + Logins: []string{"baz"}, + }, + { + Organization: "aaa", + Team: "bbb", + Logins: []string{"ccc", "ddd"}, + }, + }}, + wantErr: false, + }, + { + name: "one set of incorrect args", + parser: teamsToLoginsParser{mappings: new([]types.TeamMapping)}, + arg: "abracadabra", + wantParser: teamsToLoginsParser{mappings: new([]types.TeamMapping)}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.parser.Set(tt.arg) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.parser, tt.wantParser) + } + }) + } +} diff --git a/tool/tctl/sso/tester/command.go b/tool/tctl/sso/tester/command.go new file mode 100644 index 0000000000000..c00fb60b8b548 --- /dev/null +++ b/tool/tctl/sso/tester/command.go @@ -0,0 +1,282 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tester + +import ( + "context" + "fmt" + "io" + "os" + "strings" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/service" + "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/utils" + + "github.com/gravitational/kingpin" + "github.com/gravitational/trace" + + kyaml "k8s.io/apimachinery/pkg/util/yaml" +) + +// SSOTestCommand implements common.CLICommand interface +type SSOTestCommand struct { + config *service.Config + + ssoTestCmd *kingpin.CmdClause + + // connectorFileName points at file name with sso connector definition + connectorFileName string + + // Handlers is a mapping between auth kind and appropriate handling function + Handlers map[string]func(c auth.ClientI, connBytes []byte) (*AuthRequestInfo, error) + // GetDiagInfoFields provides auth kind-specific diagnostic info fields. + GetDiagInfoFields map[string]func(diag *types.SSODiagnosticInfo, debug bool) []string +} + +// Initialize allows a caller-defined command to plug itself into CLI +// argument parsing +func (cmd *SSOTestCommand) Initialize(app *kingpin.Application, cfg *service.Config) { + cmd.config = cfg + + sso := app.GetCommand("sso") + cmd.ssoTestCmd = sso.Command("test", "Perform end-to-end test of SSO flow using provided auth connector definition.") + cmd.ssoTestCmd.Arg("filename", "Connector resource definition filename. Empty for stdin.").StringVar(&cmd.connectorFileName) + cmd.ssoTestCmd.Alias(` +Examples: + + Test the auth connector from connector.yaml: + + > tctl sso test connector.yaml + + The command is designed to be used in conjunction with "tctl sso configure" family of commands: + + > tctl sso configure github ... | tctl sso test + + The pipeline may also utilise "tee" to capture the connector generated with "tctl sso configure". + + > tctl sso configure github ... | tee connector.yaml | tctl sso test`) + + cmd.Handlers = map[string]func(c auth.ClientI, connBytes []byte) (*AuthRequestInfo, error){ + types.KindGithubConnector: handleGithubConnector, + } + + cmd.GetDiagInfoFields = map[string]func(diag *types.SSODiagnosticInfo, debug bool) []string{ + types.KindGithubConnector: getGithubDiagInfoFields, + } +} + +func (cmd *SSOTestCommand) getSupportedKinds() []string { + var kinds []string + + for kind := range cmd.Handlers { + kinds = append(kinds, kind) + } + + return kinds +} + +func (cmd *SSOTestCommand) ssoTestCommand(c auth.ClientI) error { + reader := os.Stdin + if cmd.connectorFileName != "" { + f, err := utils.OpenFile(cmd.connectorFileName) + if err != nil { + return trace.Wrap(err, "could not open connector spec file %v", cmd.connectorFileName) + } + defer f.Close() + reader = f + } + + decoder := kyaml.NewYAMLOrJSONDecoder(reader, defaults.LookaheadBufSize) + for { + var raw services.UnknownResource + err := decoder.Decode(&raw) + if err != nil { + if err == io.EOF { + return nil + } + return trace.Wrap(err, "Unable to load resource. Make sure the file is in correct format.") + } + + handler, ok := cmd.Handlers[raw.Kind] + if !ok { + return trace.BadParameter("Resources of type %q are not supported. Supported kinds: %v", raw.Kind, cmd.getSupportedKinds()) + } + + requestInfo, err := handler(c, raw.Raw) + if err != nil { + return trace.Wrap(err) + } + + // note: loginErr is processed further down. + loginResponse, loginErr := cmd.runSSOLoginFlow(context.TODO(), raw.Kind, c, requestInfo.Config) + + if requestInfo.RequestCreateErr != nil { + return trace.BadParameter("Failed to create auth request. Check the auth connector definition for errors. Error: %v", requestInfo.RequestCreateErr) + } + + info, infoErr := c.GetSSODiagnosticInfo(context.TODO(), raw.Kind, requestInfo.RequestID) + + err = cmd.reportLoginResult(raw.Kind, info, infoErr, loginResponse, loginErr) + if err != nil { + return trace.Wrap(err) + } + } +} + +// TryRun is executed after the CLI parsing is done. The command must +// determine if selectedCommand belongs to it and return match=true +func (cmd *SSOTestCommand) TryRun(selectedCommand string, c auth.ClientI) (match bool, err error) { + if selectedCommand == cmd.ssoTestCmd.FullCommand() { + return true, cmd.ssoTestCommand(c) + } + return false, nil +} + +// AuthRequestInfo is helper type, useful for tying together test handlers of different auth types. +type AuthRequestInfo struct { + // Config holds *client.RedirectorConfig used for SSO redirect. + Config *client.RedirectorConfig + // RequestID is ID of auth request created for SSO test. + RequestID string + // RequestCreateErr holds an error in case auth request creation failed. + RequestCreateErr error +} + +func (cmd *SSOTestCommand) runSSOLoginFlow(ctx context.Context, protocol string, c auth.ClientI, config *client.RedirectorConfig) (*auth.SSHLoginResponse, error) { + key, err := client.NewKey() + if err != nil { + return nil, trace.Wrap(err) + } + + proxies, err := c.GetProxies() + if err != nil { + return nil, trace.Wrap(err) + } + + if len(proxies) == 0 { + return nil, trace.BadParameter("cluster has no proxies.") + } + + cfg := client.MakeDefaultConfig() + cfg.WebProxyAddr = proxies[0].GetPublicAddr() + + tc, err := client.NewClient(cfg) + if err != nil { + return nil, trace.Wrap(err) + } + + return client.SSHAgentSSOLogin(ctx, client.SSHLoginSSO{ + SSHLogin: client.SSHLogin{ + ProxyAddr: tc.WebProxyAddr, + PubKey: key.Pub, + TTL: tc.KeyTTL, + Insecure: tc.InsecureSkipVerify, + Pool: nil, + Compatibility: tc.CertificateFormat, + RouteToCluster: tc.SiteName, + KubernetesCluster: tc.KubernetesCluster, + }, + ConnectorID: "-sso-test", + Protocol: protocol, + BindAddr: tc.BindAddr, + Browser: tc.Browser, + }, config) +} + +// GetDiagMessage is helper function for preparing message set to be shown to user. +func GetDiagMessage(present bool, show bool, msg string) string { + if present && show { + return msg + } + return "" +} + +func (cmd *SSOTestCommand) reportLoginResult(authKind string, diag *types.SSODiagnosticInfo, infoErr error, loginResponse *auth.SSHLoginResponse, loginErr error) (errResult error) { + success := diag != nil && diag.Success + + // check for errors + if loginErr != nil || infoErr != nil { + success = false + } + + if success { + fmt.Printf("Success! Logged in as: %v\n", loginResponse.Username) + } else { + fmt.Printf("Failure!\n") + errResult = trace.Errorf("SSO flow failed.") + + if infoErr != nil { + fmt.Printf("No diagnostic info found. Most likely cause: the request timed out or callback configuration is incorrect. Ensure that user logs within alloted time and IdP configuration is correct.\n Error details: %v\n", trace.UserMessage(infoErr)) + errResult = trace.Wrap(infoErr, "SSO flow failed.") + } + + if loginErr != nil { + fmt.Printf("Login error: %v\n", trace.UserMessage(loginErr)) + errResult = trace.Wrap(loginErr, "SSO flow failed.") + } + } + + // finish early if there is no diag info to show. + if diag == nil { + return errResult + } + + cmd.printDiagnosticInfo(authKind, diag, loginErr) + + return errResult +} + +func (cmd *SSOTestCommand) printDiagnosticInfo(authKind string, diag *types.SSODiagnosticInfo, loginErr error) { + fields := []string{ + // common fields across auth connector types. + GetDiagMessage( + diag.Error != "", + cmd.config.Debug || loginErr == nil, + FormatString("Original error", diag.Error)), + GetDiagMessage( + diag.CreateUserParams != nil, + true, + formatUserDetails("Authentication details", diag.CreateUserParams)), + } + + // enrich the fields with auth-specific fields + if getFields, ok := cmd.GetDiagInfoFields[authKind]; ok { + fields = append(fields, getFields(diag, cmd.config.Debug)...) + } + + // raw data - debug. we want this field last. + fields = append(fields, GetDiagMessage(true, cmd.config.Debug, FormatJSON("Raw data", diag))) + + const termWidth = 80 + + for _, msg := range fields { + if msg != "" { + fmt.Println(strings.Repeat("-", termWidth)) + fmt.Println(msg) + } + } + + if !cmd.config.Debug { + fmt.Println(strings.Repeat("-", termWidth)) + fmt.Println("For more details repeat the command with --debug flag.") + } + + fmt.Println() +} diff --git a/tool/tctl/sso/tester/format.go b/tool/tctl/sso/tester/format.go new file mode 100644 index 0000000000000..92d532bc125c9 --- /dev/null +++ b/tool/tctl/sso/tester/format.go @@ -0,0 +1,64 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tester + +import ( + "encoding/json" + "fmt" + + "github.com/gravitational/teleport/api/types" + + "github.com/ghodss/yaml" +) + +func FormatString(description string, msg string) string { + return fmt.Sprintf("%v:\n%v\n", description, msg) +} + +func FormatYAML(description string, object interface{}) string { + output, err := yaml.Marshal(object) + if err != nil { + return formatError(description, err) + } + return fmt.Sprintf("%v:\n%v", description, string(output)) +} + +func FormatJSON(description string, object interface{}) string { + output, err := json.MarshalIndent(object, "", " ") + if err != nil { + return formatError(description, err) + } + return fmt.Sprintf("%v:\n%v\n", description, string(output)) +} + +func formatUserDetails(description string, info *types.CreateUserParams) string { + if info == nil { + return "" + } + + // Skip fields: connector_name, session_ttl + info.ConnectorName = "" + info.SessionTTL = 0 + + output, err := yaml.Marshal(info) + if err != nil { + return formatError(description, err) + } + return fmt.Sprintf("%v:\n%v", description, Indent(string(output), 3)) +} + +func formatError(fieldDesc string, err error) string { + return fmt.Sprintf("%v: error rendering field: %v\n", fieldDesc, err) +} diff --git a/tool/tctl/sso/tester/format_test.go b/tool/tctl/sso/tester/format_test.go new file mode 100644 index 0000000000000..b30d1a5fdf5d9 --- /dev/null +++ b/tool/tctl/sso/tester/format_test.go @@ -0,0 +1,250 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tester + +import ( + "fmt" + "testing" + + "github.com/gravitational/teleport/api/types" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" +) + +func Test_formatString(t *testing.T) { + tests := []struct { + name string + description string + msg string + want string + }{ + { + name: "empty", + description: "", + msg: "", + want: ":\n\n", + }, + { + name: "something", + description: "a field", + msg: "foo baz bar blah", + want: `a field: +foo baz bar blah +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := FormatString(tt.description, tt.msg) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_formatYAML(t *testing.T) { + tests := []struct { + name string + description string + object interface{} + want string + }{ + { + name: "empty", + description: "", + object: nil, + want: ":\nnull\n", + }, + { + name: "simple object", + description: "my field", + object: types.RoleSpecV5{ + Allow: types.RoleConditions{ + Logins: []string{"username"}, + ClusterLabels: types.Labels{"access": []string{"ops"}}, + }, + }, + want: `my field: +allow: + cluster_labels: + access: ops + logins: + - username +deny: {} +options: + cert_format: "" + desktop_clipboard: null + desktop_directory_sharing: null + forward_agent: false + record_session: null +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := FormatYAML(tt.description, tt.object) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_formatJSON(t *testing.T) { + tests := []struct { + name string + description string + object interface{} + want string + }{ + { + name: "empty", + description: "empty field", + object: struct{}{}, + want: `empty field: +{} +`, + }, + { + name: "simple object", + description: "my field", + object: types.RoleSpecV5{ + Allow: types.RoleConditions{ + Logins: []string{"username"}, + ClusterLabels: types.Labels{"access": []string{"ops"}}, + }, + }, + want: `my field: +{ + "options": { + "forward_agent": false, + "cert_format": "", + "record_session": null, + "desktop_clipboard": null, + "desktop_directory_sharing": null + }, + "allow": { + "logins": [ + "username" + ], + "cluster_labels": { + "access": "ops" + } + }, + "deny": {} +} +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := FormatJSON(tt.description, tt.object) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_formatUserDetails(t *testing.T) { + tests := []struct { + name string + description string + info *types.CreateUserParams + want string + }{ + { + name: "empty", + description: "", + info: nil, + want: "", + }, + { + name: "some details", + description: "user details", + info: &types.CreateUserParams{ + ConnectorName: "foo", + Username: "bar", + Logins: []string{"laa", "lbb", "lcc"}, + KubeGroups: []string{"kgaa", "kgbb", "kgcc"}, + KubeUsers: []string{"kuaa", "kubb", "kucc"}, + Roles: []string{"raa", "rbb", "rcc"}, + Traits: map[string][]string{ + "groups": {"gfoo", "gbar", "gbaz"}, + }, + SessionTTL: 1230, + }, + want: `user details: + kube_groups: + - kgaa + - kgbb + - kgcc + kube_users: + - kuaa + - kubb + - kucc + logins: + - laa + - lbb + - lcc + roles: + - raa + - rbb + - rcc + traits: + groups: + - gfoo + - gbar + - gbaz + username: bar`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formatUserDetails(tt.description, tt.info) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_formatError(t *testing.T) { + tests := []struct { + name string + fieldDesc string + err error + want string + }{ + { + name: "empty", + fieldDesc: "my field", + err: nil, + want: "my field: error rendering field: \n", + }, + { + name: "plain error", + fieldDesc: "my field", + err: fmt.Errorf("foo: %v", 123), + want: "my field: error rendering field: foo: 123\n", + }, + { + name: "trace error", + fieldDesc: "my field", + err: trace.Errorf("bar: %v", 321), + want: "my field: error rendering field: bar: 321\n", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formatError(tt.fieldDesc, tt.err) + require.Equal(t, tt.want, got) + }) + } +} diff --git a/tool/tctl/sso/tester/github.go b/tool/tctl/sso/tester/github.go new file mode 100644 index 0000000000000..5709ab8765892 --- /dev/null +++ b/tool/tctl/sso/tester/github.go @@ -0,0 +1,102 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tester + +import ( + "github.com/gravitational/teleport/api/constants" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/services" + + "github.com/gravitational/trace" +) + +func githubTest(c auth.ClientI, connector types.GithubConnector) (*AuthRequestInfo, error) { + // get connector spec + var spec types.GithubConnectorSpecV3 + switch ghConnector := connector.(type) { + case *types.GithubConnectorV3: + spec = ghConnector.Spec + default: + return nil, trace.BadParameter("Unrecognized GitHub connector version: %T. Provide supported connector version.", ghConnector) + } + + requestInfo := &AuthRequestInfo{} + + makeRequest := func(req client.SSOLoginConsoleReq) (*client.SSOLoginConsoleResponse, error) { + ghRequest := services.GithubAuthRequest{ + ConnectorID: req.ConnectorID + "-" + connector.GetName(), + Type: constants.Github, + PublicKey: req.PublicKey, + CertTTL: defaults.GithubAuthRequestTTL, + CreateWebSession: false, + ClientRedirectURL: req.RedirectURL, + RouteToCluster: req.RouteToCluster, + SSOTestFlow: true, + ConnectorSpec: &spec, + } + + request, err := c.CreateGithubAuthRequest(ghRequest) + + if request != nil { + requestInfo.RequestID = request.StateToken + } + requestInfo.RequestCreateErr = err + + if err != nil { + return nil, trace.Wrap(err) + } + + return &client.SSOLoginConsoleResponse{RedirectURL: request.RedirectURL}, nil + } + + requestInfo.Config = &client.RedirectorConfig{SSOLoginConsoleRequestFn: makeRequest} + return requestInfo, nil +} + +func handleGithubConnector(c auth.ClientI, connBytes []byte) (*AuthRequestInfo, error) { + conn, err := services.UnmarshalGithubConnector(connBytes) + if err != nil { + return nil, trace.Wrap(err, "Unable to load GitHub connector. Correct the definition and try again.") + } + requestInfo, err := githubTest(c, conn) + if err != nil { + return nil, trace.Wrap(err) + } + + return requestInfo, nil +} + +func getGithubDiagInfoFields(diag *types.SSODiagnosticInfo, debug bool) []string { + return []string{ + GetDiagMessage( + diag.GithubTokenInfo != nil, + debug, + FormatJSON("[GitHub] OAuth2 token info", diag.GithubTokenInfo), + ), + GetDiagMessage( + diag.GithubClaims != nil, + true, + FormatYAML("[GitHub] Received claims", diag.GithubClaims), + ), + GetDiagMessage( + diag.GithubTeamsToLogins != nil, + true, + FormatYAML("[GitHub] Connector team to logins mapping", diag.GithubTeamsToLogins), + ), + } +} diff --git a/tool/tctl/sso/tester/utils.go b/tool/tctl/sso/tester/utils.go new file mode 100644 index 0000000000000..bcff6b2a406d6 --- /dev/null +++ b/tool/tctl/sso/tester/utils.go @@ -0,0 +1,32 @@ +// Copyright 2022 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tester + +import ( + "bufio" + "fmt" + "strings" +) + +// Indent returns the string where each line is indented by the specified +// number of spaces. +func Indent(s string, padding int) string { + var lines []string + scanner := bufio.NewScanner(strings.NewReader(s)) + for scanner.Scan() { + lines = append(lines, fmt.Sprintf("%v%v", strings.Repeat(" ", padding), scanner.Text())) + } + return strings.Join(lines, "\n") +}