diff --git a/.github/workflows/update-docs-webhook.yaml b/.github/workflows/update-docs-webhook.yaml index 47ff3f4bfb042..6ff9e5703107d 100644 --- a/.github/workflows/update-docs-webhook.yaml +++ b/.github/workflows/update-docs-webhook.yaml @@ -1,6 +1,8 @@ name: Update docs webhook on: push: + paths: + - 'docs/**' branches: - master - branch/v* @@ -11,11 +13,19 @@ jobs: name: Update docs webhook runs-on: ubuntu-latest environment: update-docs + strategy: + fail-fast: false + matrix: + webhooks: + - url_secret_name: DOCS_DEPLOY_HOOK + http_method: GET + - url_secret_name: AMPLIFY_DOCS_DEPLOY_HOOK + http_method: POST steps: - name: Call deployment webhook env: - WEBHOOK_URL: ${{ secrets.DOCS_DEPLOY_HOOK }} + WEBHOOK_URL: ${{ secrets[matrix.webhooks.url_secret_name] }} run: | - if curl --silent --fail --show-error "$WEBHOOK_URL" > /dev/null; then + if curl -X ${{ matrix.webhooks.http_method }} --silent --fail --show-error "$WEBHOOK_URL" > /dev/null; then echo "Triggered successfully" fi diff --git a/Makefile b/Makefile index 82e210bbad320..cf8a84ff571a9 100644 --- a/Makefile +++ b/Makefile @@ -364,7 +364,7 @@ $(BUILDDIR)/tctl: @if [[ "$(OS)" != "windows" && -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \ echo 'Warning: Building tctl without libfido2. Install libfido2 to have access to MFA.' >&2; \ fi - GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) ./tool/tctl + GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(TOUCHID_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) ./tool/tctl .PHONY: $(BUILDDIR)/teleport # Appending new conditional settings for community build type diff --git a/api/client/webclient/webclient.go b/api/client/webclient/webclient.go index b5c684ebfb628..8b5bf3eed4d93 100644 --- a/api/client/webclient/webclient.go +++ b/api/client/webclient/webclient.go @@ -359,8 +359,8 @@ type ProxySettings struct { type AutoUpdateSettings struct { // ToolsVersion defines the version of {tsh, tctl} for client auto update. ToolsVersion string `json:"tools_version"` - // ToolsMode defines mode client auto update feature `enabled|disabled`. - ToolsMode string `json:"tools_mode"` + // ToolsAutoUpdate indicates if the requesting tools client should be updated. + ToolsAutoUpdate bool `json:"tools_auto_update"` // AgentVersion defines the version of teleport that agents enrolled into autoupdates should run. AgentVersion string `json:"agent_version"` // AgentAutoUpdate indicates if the requesting agent should attempt to update now. diff --git a/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go b/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go index 55ec345396c34..4634ef46f0f91 100644 --- a/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go +++ b/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go @@ -147,6 +147,60 @@ func (ReviewDayOfMonth) EnumDescriptor() ([]byte, []int) { return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{1} } +// MembershipKind represents the different kinds of list membership +type MembershipKind int32 + +const ( + // MEMBERSHIP_KIND_UNSPECIFIED represents list members that are of + // unknown membership kind, defaulting to being treated as type USER + MembershipKind_MEMBERSHIP_KIND_UNSPECIFIED MembershipKind = 0 + // MEMBERSHIP_KIND_USER represents list members that are normal users + MembershipKind_MEMBERSHIP_KIND_USER MembershipKind = 1 + // MEMBERSHIP_KIND_LIST represents list members that are nested Access Lists + MembershipKind_MEMBERSHIP_KIND_LIST MembershipKind = 2 +) + +// Enum value maps for MembershipKind. +var ( + MembershipKind_name = map[int32]string{ + 0: "MEMBERSHIP_KIND_UNSPECIFIED", + 1: "MEMBERSHIP_KIND_USER", + 2: "MEMBERSHIP_KIND_LIST", + } + MembershipKind_value = map[string]int32{ + "MEMBERSHIP_KIND_UNSPECIFIED": 0, + "MEMBERSHIP_KIND_USER": 1, + "MEMBERSHIP_KIND_LIST": 2, + } +) + +func (x MembershipKind) Enum() *MembershipKind { + p := new(MembershipKind) + *p = x + return p +} + +func (x MembershipKind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MembershipKind) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_accesslist_v1_accesslist_proto_enumTypes[2].Descriptor() +} + +func (MembershipKind) Type() protoreflect.EnumType { + return &file_teleport_accesslist_v1_accesslist_proto_enumTypes[2] +} + +func (x MembershipKind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MembershipKind.Descriptor instead. +func (MembershipKind) EnumDescriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{2} +} + // IneligibleStatus describes how the user is ineligible. type IneligibleStatus int32 @@ -196,11 +250,11 @@ func (x IneligibleStatus) String() string { } func (IneligibleStatus) Descriptor() protoreflect.EnumDescriptor { - return file_teleport_accesslist_v1_accesslist_proto_enumTypes[2].Descriptor() + return file_teleport_accesslist_v1_accesslist_proto_enumTypes[3].Descriptor() } func (IneligibleStatus) Type() protoreflect.EnumType { - return &file_teleport_accesslist_v1_accesslist_proto_enumTypes[2] + return &file_teleport_accesslist_v1_accesslist_proto_enumTypes[3] } func (x IneligibleStatus) Number() protoreflect.EnumNumber { @@ -209,7 +263,7 @@ func (x IneligibleStatus) Number() protoreflect.EnumNumber { // Deprecated: Use IneligibleStatus.Descriptor instead. func (IneligibleStatus) EnumDescriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{2} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{3} } // AccessList describes the basic building block of access grants, which are @@ -409,6 +463,9 @@ type AccessListOwner struct { // ineligible_status describes if this owner is eligible or not // and if not, describes how they're lacking eligibility. IneligibleStatus IneligibleStatus `protobuf:"varint,3,opt,name=ineligible_status,json=ineligibleStatus,proto3,enum=teleport.accesslist.v1.IneligibleStatus" json:"ineligible_status,omitempty"` + // membership_kind describes the type of membership, either + // `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + MembershipKind MembershipKind `protobuf:"varint,4,opt,name=membership_kind,json=membershipKind,proto3,enum=teleport.accesslist.v1.MembershipKind" json:"membership_kind,omitempty"` } func (x *AccessListOwner) Reset() { @@ -462,6 +519,13 @@ func (x *AccessListOwner) GetIneligibleStatus() IneligibleStatus { return IneligibleStatus_INELIGIBLE_STATUS_UNSPECIFIED } +func (x *AccessListOwner) GetMembershipKind() MembershipKind { + if x != nil { + return x.MembershipKind + } + return MembershipKind_MEMBERSHIP_KIND_UNSPECIFIED +} + // AccessListAudit describes the audit configuration for an Access List. type AccessListAudit struct { state protoimpl.MessageState @@ -829,6 +893,9 @@ type MemberSpec struct { // ineligible_status describes if this member is eligible or not // and if not, describes how they're lacking eligibility. IneligibleStatus IneligibleStatus `protobuf:"varint,7,opt,name=ineligible_status,json=ineligibleStatus,proto3,enum=teleport.accesslist.v1.IneligibleStatus" json:"ineligible_status,omitempty"` + // membership_kind describes the type of membership, either + // `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + MembershipKind MembershipKind `protobuf:"varint,9,opt,name=membership_kind,json=membershipKind,proto3,enum=teleport.accesslist.v1.MembershipKind" json:"membership_kind,omitempty"` } func (x *MemberSpec) Reset() { @@ -910,6 +977,13 @@ func (x *MemberSpec) GetIneligibleStatus() IneligibleStatus { return IneligibleStatus_INELIGIBLE_STATUS_UNSPECIFIED } +func (x *MemberSpec) GetMembershipKind() MembershipKind { + if x != nil { + return x.MembershipKind + } + return MembershipKind_MEMBERSHIP_KIND_UNSPECIFIED +} + // Review is a review of an Access List. type Review struct { state protoimpl.MessageState @@ -1133,8 +1207,14 @@ type AccessListStatus struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // member_count is the number of members in the in the Access List. + // member_count is the number of members in the Access List. MemberCount *uint32 `protobuf:"varint,1,opt,name=member_count,json=memberCount,proto3,oneof" json:"member_count,omitempty"` + // member_list_count is the number of nested list members in the Access List. + MemberListCount *uint32 `protobuf:"varint,2,opt,name=member_list_count,json=memberListCount,proto3,oneof" json:"member_list_count,omitempty"` + // owner_of describes Access Lists where this Access List is an explicit owner. + OwnerOf []string `protobuf:"bytes,3,rep,name=owner_of,json=ownerOf,proto3" json:"owner_of,omitempty"` + // member_of describes Access Lists where this Access List is an explicit member. + MemberOf []string `protobuf:"bytes,4,rep,name=member_of,json=memberOf,proto3" json:"member_of,omitempty"` } func (x *AccessListStatus) Reset() { @@ -1174,6 +1254,27 @@ func (x *AccessListStatus) GetMemberCount() uint32 { return 0 } +func (x *AccessListStatus) GetMemberListCount() uint32 { + if x != nil && x.MemberListCount != nil { + return *x.MemberListCount + } + return 0 +} + +func (x *AccessListStatus) GetOwnerOf() []string { + if x != nil { + return x.OwnerOf + } + return nil +} + +func (x *AccessListStatus) GetMemberOf() []string { + if x != nil { + return x.MemberOf + } + return nil +} + var File_teleport_accesslist_v1_accesslist_proto protoreflect.FileDescriptor var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ @@ -1238,7 +1339,7 @@ var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ 0x72, 0x61, 0x6e, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x09, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x22, 0x9e, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, + 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x22, 0xef, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, @@ -1248,169 +1349,193 @@ var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, - 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x0f, - 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, - 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x79, 0x22, 0x9f, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x09, 0x66, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x64, 0x61, 0x79, 0x5f, - 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, - 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x52, 0x0a, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x4d, - 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x40, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x5c, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, - 0x65, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, - 0x61, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, 0x72, - 0x61, 0x69, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x30, - 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, - 0x22, 0x7c, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, - 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xc7, - 0x02, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, - 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, - 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x42, 0x79, 0x12, - 0x55, 0x0a, 0x11, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x52, 0x0a, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x22, 0x7c, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x36, - 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, + 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4f, 0x0a, 0x0f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x68, 0x69, 0x70, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x68, 0x69, 0x70, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xf7, 0x01, 0x0a, 0x0f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x42, 0x0a, + 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x44, 0x61, 0x74, + 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, - 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xdf, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, - 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x74, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x90, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x72, 0x0a, 0x1f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, - 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x27, - 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x61, 0x0a, 0x18, 0x72, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x79, 0x52, 0x16, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x66, 0x0a, 0x1b, 0x72, 0x65, - 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, - 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x79, 0x22, 0x9f, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x09, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x64, 0x61, 0x79, + 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, - 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x52, 0x17, 0x72, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x4b, 0x0a, 0x10, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x26, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2a, 0xb6, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x20, 0x0a, 0x1c, - 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, - 0x0a, 0x1a, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, - 0x43, 0x59, 0x5f, 0x4f, 0x4e, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x01, 0x12, 0x21, - 0x0a, 0x1d, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, - 0x43, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x53, 0x10, - 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, - 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x53, 0x49, 0x58, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x53, - 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, - 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4f, 0x4e, 0x45, 0x5f, 0x59, 0x45, 0x41, 0x52, 0x10, - 0x0c, 0x2a, 0x97, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, - 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, - 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, - 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, - 0x54, 0x48, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, - 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, - 0x48, 0x5f, 0x46, 0x49, 0x46, 0x54, 0x45, 0x45, 0x4e, 0x54, 0x48, 0x10, 0x0f, 0x12, 0x1c, 0x0a, - 0x18, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, - 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x4c, 0x41, 0x53, 0x54, 0x10, 0x1f, 0x2a, 0xc6, 0x01, 0x0a, 0x10, - 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, - 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, - 0x45, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, - 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x02, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x45, - 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, - 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x4d, 0x45, - 0x4e, 0x54, 0x53, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, - 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, - 0x45, 0x44, 0x10, 0x04, 0x42, 0x58, 0x5a, 0x56, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x76, - 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x52, 0x0a, 0x64, 0x61, 0x79, 0x4f, 0x66, + 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x40, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x5c, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, + 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, + 0x72, 0x61, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, + 0x72, 0x61, 0x69, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, + 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, + 0x73, 0x22, 0x7c, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x06, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, + 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, + 0x98, 0x03, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x62, + 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x42, 0x79, + 0x12, 0x55, 0x0a, 0x11, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4f, 0x0a, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x4b, 0x69, 0x6e, 0x64, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x52, 0x0a, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x22, 0x7c, 0x0a, 0x06, 0x52, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x12, 0x36, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xdf, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, + 0x65, 0x77, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, + 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x90, 0x03, 0x0a, 0x0d, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x72, 0x0a, 0x1f, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x73, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x61, 0x0a, 0x18, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x79, 0x52, 0x16, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x66, 0x0a, 0x1b, + 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, + 0x6e, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x52, 0x17, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x11, 0x66, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0xca, 0x01, + 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x08, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x4f, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x5f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x4f, 0x66, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2a, 0xb6, 0x01, 0x0a, 0x0f, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x20, + 0x0a, 0x1c, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, + 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, + 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4f, 0x4e, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x01, + 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, + 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, + 0x53, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, + 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x53, 0x49, 0x58, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, + 0x48, 0x53, 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, + 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4f, 0x4e, 0x45, 0x5f, 0x59, 0x45, 0x41, + 0x52, 0x10, 0x0c, 0x2a, 0x97, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, + 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x56, 0x49, + 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, + 0x19, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, + 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, + 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, + 0x4e, 0x54, 0x48, 0x5f, 0x46, 0x49, 0x46, 0x54, 0x45, 0x45, 0x4e, 0x54, 0x48, 0x10, 0x0f, 0x12, + 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, + 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x4c, 0x41, 0x53, 0x54, 0x10, 0x1f, 0x2a, 0x65, 0x0a, + 0x0e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x4b, 0x69, 0x6e, 0x64, 0x12, + 0x1f, 0x0a, 0x1b, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x4b, 0x49, + 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x4b, + 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, + 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4c, 0x49, + 0x53, 0x54, 0x10, 0x02, 0x2a, 0xc6, 0x01, 0x0a, 0x10, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x45, + 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, + 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, + 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, + 0x10, 0x02, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, + 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x03, 0x12, 0x1d, + 0x0a, 0x19, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x42, 0x58, 0x5a, + 0x56, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x6c, 0x69, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1425,67 +1550,70 @@ func file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP() []byte { return file_teleport_accesslist_v1_accesslist_proto_rawDescData } -var file_teleport_accesslist_v1_accesslist_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_teleport_accesslist_v1_accesslist_proto_enumTypes = make([]protoimpl.EnumInfo, 4) var file_teleport_accesslist_v1_accesslist_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_teleport_accesslist_v1_accesslist_proto_goTypes = []any{ (ReviewFrequency)(0), // 0: teleport.accesslist.v1.ReviewFrequency (ReviewDayOfMonth)(0), // 1: teleport.accesslist.v1.ReviewDayOfMonth - (IneligibleStatus)(0), // 2: teleport.accesslist.v1.IneligibleStatus - (*AccessList)(nil), // 3: teleport.accesslist.v1.AccessList - (*AccessListSpec)(nil), // 4: teleport.accesslist.v1.AccessListSpec - (*AccessListOwner)(nil), // 5: teleport.accesslist.v1.AccessListOwner - (*AccessListAudit)(nil), // 6: teleport.accesslist.v1.AccessListAudit - (*Recurrence)(nil), // 7: teleport.accesslist.v1.Recurrence - (*Notifications)(nil), // 8: teleport.accesslist.v1.Notifications - (*AccessListRequires)(nil), // 9: teleport.accesslist.v1.AccessListRequires - (*AccessListGrants)(nil), // 10: teleport.accesslist.v1.AccessListGrants - (*Member)(nil), // 11: teleport.accesslist.v1.Member - (*MemberSpec)(nil), // 12: teleport.accesslist.v1.MemberSpec - (*Review)(nil), // 13: teleport.accesslist.v1.Review - (*ReviewSpec)(nil), // 14: teleport.accesslist.v1.ReviewSpec - (*ReviewChanges)(nil), // 15: teleport.accesslist.v1.ReviewChanges - (*AccessListStatus)(nil), // 16: teleport.accesslist.v1.AccessListStatus - (*v1.ResourceHeader)(nil), // 17: teleport.header.v1.ResourceHeader - (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 19: google.protobuf.Duration - (*v11.Trait)(nil), // 20: teleport.trait.v1.Trait + (MembershipKind)(0), // 2: teleport.accesslist.v1.MembershipKind + (IneligibleStatus)(0), // 3: teleport.accesslist.v1.IneligibleStatus + (*AccessList)(nil), // 4: teleport.accesslist.v1.AccessList + (*AccessListSpec)(nil), // 5: teleport.accesslist.v1.AccessListSpec + (*AccessListOwner)(nil), // 6: teleport.accesslist.v1.AccessListOwner + (*AccessListAudit)(nil), // 7: teleport.accesslist.v1.AccessListAudit + (*Recurrence)(nil), // 8: teleport.accesslist.v1.Recurrence + (*Notifications)(nil), // 9: teleport.accesslist.v1.Notifications + (*AccessListRequires)(nil), // 10: teleport.accesslist.v1.AccessListRequires + (*AccessListGrants)(nil), // 11: teleport.accesslist.v1.AccessListGrants + (*Member)(nil), // 12: teleport.accesslist.v1.Member + (*MemberSpec)(nil), // 13: teleport.accesslist.v1.MemberSpec + (*Review)(nil), // 14: teleport.accesslist.v1.Review + (*ReviewSpec)(nil), // 15: teleport.accesslist.v1.ReviewSpec + (*ReviewChanges)(nil), // 16: teleport.accesslist.v1.ReviewChanges + (*AccessListStatus)(nil), // 17: teleport.accesslist.v1.AccessListStatus + (*v1.ResourceHeader)(nil), // 18: teleport.header.v1.ResourceHeader + (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 20: google.protobuf.Duration + (*v11.Trait)(nil), // 21: teleport.trait.v1.Trait } var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{ - 17, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader - 4, // 1: teleport.accesslist.v1.AccessList.spec:type_name -> teleport.accesslist.v1.AccessListSpec - 16, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus - 5, // 3: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner - 6, // 4: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit - 9, // 5: teleport.accesslist.v1.AccessListSpec.membership_requires:type_name -> teleport.accesslist.v1.AccessListRequires - 9, // 6: teleport.accesslist.v1.AccessListSpec.ownership_requires:type_name -> teleport.accesslist.v1.AccessListRequires - 10, // 7: teleport.accesslist.v1.AccessListSpec.grants:type_name -> teleport.accesslist.v1.AccessListGrants - 10, // 8: teleport.accesslist.v1.AccessListSpec.owner_grants:type_name -> teleport.accesslist.v1.AccessListGrants - 2, // 9: teleport.accesslist.v1.AccessListOwner.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus - 18, // 10: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp - 7, // 11: teleport.accesslist.v1.AccessListAudit.recurrence:type_name -> teleport.accesslist.v1.Recurrence - 8, // 12: teleport.accesslist.v1.AccessListAudit.notifications:type_name -> teleport.accesslist.v1.Notifications - 0, // 13: teleport.accesslist.v1.Recurrence.frequency:type_name -> teleport.accesslist.v1.ReviewFrequency - 1, // 14: teleport.accesslist.v1.Recurrence.day_of_month:type_name -> teleport.accesslist.v1.ReviewDayOfMonth - 19, // 15: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration - 20, // 16: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait - 20, // 17: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait - 17, // 18: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader - 12, // 19: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec - 18, // 20: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp - 18, // 21: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp - 2, // 22: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus - 17, // 23: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader - 14, // 24: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec - 18, // 25: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp - 15, // 26: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges - 9, // 27: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires - 0, // 28: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency - 1, // 29: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth - 30, // [30:30] is the sub-list for method output_type - 30, // [30:30] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 18, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader + 5, // 1: teleport.accesslist.v1.AccessList.spec:type_name -> teleport.accesslist.v1.AccessListSpec + 17, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus + 6, // 3: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner + 7, // 4: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit + 10, // 5: teleport.accesslist.v1.AccessListSpec.membership_requires:type_name -> teleport.accesslist.v1.AccessListRequires + 10, // 6: teleport.accesslist.v1.AccessListSpec.ownership_requires:type_name -> teleport.accesslist.v1.AccessListRequires + 11, // 7: teleport.accesslist.v1.AccessListSpec.grants:type_name -> teleport.accesslist.v1.AccessListGrants + 11, // 8: teleport.accesslist.v1.AccessListSpec.owner_grants:type_name -> teleport.accesslist.v1.AccessListGrants + 3, // 9: teleport.accesslist.v1.AccessListOwner.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus + 2, // 10: teleport.accesslist.v1.AccessListOwner.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind + 19, // 11: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp + 8, // 12: teleport.accesslist.v1.AccessListAudit.recurrence:type_name -> teleport.accesslist.v1.Recurrence + 9, // 13: teleport.accesslist.v1.AccessListAudit.notifications:type_name -> teleport.accesslist.v1.Notifications + 0, // 14: teleport.accesslist.v1.Recurrence.frequency:type_name -> teleport.accesslist.v1.ReviewFrequency + 1, // 15: teleport.accesslist.v1.Recurrence.day_of_month:type_name -> teleport.accesslist.v1.ReviewDayOfMonth + 20, // 16: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration + 21, // 17: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait + 21, // 18: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait + 18, // 19: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader + 13, // 20: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec + 19, // 21: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp + 19, // 22: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp + 3, // 23: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus + 2, // 24: teleport.accesslist.v1.MemberSpec.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind + 18, // 25: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader + 15, // 26: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec + 19, // 27: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp + 16, // 28: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges + 10, // 29: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires + 0, // 30: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency + 1, // 31: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth + 32, // [32:32] is the sub-list for method output_type + 32, // [32:32] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name } func init() { file_teleport_accesslist_v1_accesslist_proto_init() } @@ -1499,7 +1627,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_accesslist_v1_accesslist_proto_rawDesc, - NumEnums: 3, + NumEnums: 4, NumMessages: 14, NumExtensions: 0, NumServices: 0, diff --git a/api/proto/teleport/accesslist/v1/accesslist.proto b/api/proto/teleport/accesslist/v1/accesslist.proto index b83034160a9e7..373c325027d39 100644 --- a/api/proto/teleport/accesslist/v1/accesslist.proto +++ b/api/proto/teleport/accesslist/v1/accesslist.proto @@ -85,6 +85,10 @@ message AccessListOwner { // ineligible_status describes if this owner is eligible or not // and if not, describes how they're lacking eligibility. IneligibleStatus ineligible_status = 3; + + // membership_kind describes the type of membership, either + // `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + MembershipKind membership_kind = 4; } // AccessListAudit describes the audit configuration for an Access List. @@ -197,6 +201,21 @@ message MemberSpec { // ineligible_status describes if this member is eligible or not // and if not, describes how they're lacking eligibility. IneligibleStatus ineligible_status = 7; + + // membership_kind describes the type of membership, either + // `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + MembershipKind membership_kind = 9; +} + +// MembershipKind represents the different kinds of list membership +enum MembershipKind { + // MEMBERSHIP_KIND_UNSPECIFIED represents list members that are of + // unknown membership kind, defaulting to being treated as type USER + MEMBERSHIP_KIND_UNSPECIFIED = 0; + // MEMBERSHIP_KIND_USER represents list members that are normal users + MEMBERSHIP_KIND_USER = 1; + // MEMBERSHIP_KIND_LIST represents list members that are nested Access Lists + MEMBERSHIP_KIND_LIST = 2; } // IneligibleStatus describes how the user is ineligible. @@ -268,6 +287,12 @@ message ReviewChanges { // AccessListStatus contains dynamic fields calculated during retrieval. message AccessListStatus { - // member_count is the number of members in the in the Access List. + // member_count is the number of members in the Access List. optional uint32 member_count = 1; + // member_list_count is the number of nested list members in the Access List. + optional uint32 member_list_count = 2; + // owner_of describes Access Lists where this Access List is an explicit owner. + repeated string owner_of = 3; + // member_of describes Access Lists where this Access List is an explicit member. + repeated string member_of = 4; } diff --git a/api/proto/teleport/legacy/types/events/events.proto b/api/proto/teleport/legacy/types/events/events.proto index d984ba5881dc6..279c3ad5c40f4 100644 --- a/api/proto/teleport/legacy/types/events/events.proto +++ b/api/proto/teleport/legacy/types/events/events.proto @@ -1892,6 +1892,54 @@ message SFTP { string Error = 12 [(gogoproto.jsontag) = "error,omitempty"]; } +// SFTPSummary is emitted at the end of an SFTP transfer +message SFTPSummary { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // SessionMetadata is a common event session metadata + SessionMetadata Session = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ServerMetadata is a common server metadata + ServerMetadata Server = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // FileTransferStats contains statistics about transferred files + repeated FileTransferStat FileTransferStats = 6 [(gogoproto.jsontag) = "file_transfer_stats"]; +} + +// FileTransferStat is statistics about a transferred file +message FileTransferStat { + string Path = 1 [(gogoproto.jsontag) = "path"]; + uint64 BytesRead = 2 [(gogoproto.jsontag) = "bytes_read"]; + uint64 BytesWritten = 3 [(gogoproto.jsontag) = "bytes_written"]; +} + // Subsystem is emitted when a user requests a new subsystem. message Subsystem { // Metadata is a common event metadata @@ -4615,6 +4663,7 @@ message OneOf { events.UserTaskCreate UserTaskCreate = 188; events.UserTaskUpdate UserTaskUpdate = 189; events.UserTaskDelete UserTaskDelete = 190; + events.SFTPSummary SFTPSummary = 191; } } @@ -6923,6 +6972,13 @@ message AutoUpdateConfigCreate { (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + + // Status indicates whether the creation was successful. + Status Status = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // AutoUpdateConfigUpdate is emitted when an auto update config is updated. @@ -6954,6 +7010,13 @@ message AutoUpdateConfigUpdate { (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // AutoUpdateConfigDelete is emitted when an auto update config is deleted. @@ -6985,6 +7048,13 @@ message AutoUpdateConfigDelete { (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + + // Status indicates whether the deletion was successful. + Status Status = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // AutoUpdateVersionCreate is emitted when an auto update version is created. @@ -7016,6 +7086,13 @@ message AutoUpdateVersionCreate { (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + + // Status indicates whether the creation was successful. + Status Status = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // AutoUpdateVersionUpdate is emitted when an auto update version is updated. @@ -7047,6 +7124,13 @@ message AutoUpdateVersionUpdate { (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // AutoUpdateVersionDelete is emitted when an auto update version is deleted. @@ -7078,6 +7162,13 @@ message AutoUpdateVersionDelete { (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + + // Status indicates whether the deletion was successful. + Status Status = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // StaticHostUserCreate is emitted when a static host user is created. diff --git a/api/types/accesslist/accesslist.go b/api/types/accesslist/accesslist.go index b9f42f553e1e4..72ad2b43a329e 100644 --- a/api/types/accesslist/accesslist.go +++ b/api/types/accesslist/accesslist.go @@ -24,6 +24,7 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" + accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/header" "github.com/gravitational/teleport/api/types/header/convert/legacy" @@ -75,6 +76,20 @@ func parseReviewFrequency(input string) ReviewFrequency { return 0 } +// MaxAllowedDepth is the maximum allowed depth for nested access lists. +const MaxAllowedDepth = 10 + +var ( + // MembershipKindUnspecified is the default membership kind (treated as 'user'). + MembershipKindUnspecified = accesslistv1.MembershipKind_MEMBERSHIP_KIND_UNSPECIFIED.String() + + // MembershipKindUser is the user membership kind. + MembershipKindUser = accesslistv1.MembershipKind_MEMBERSHIP_KIND_USER.String() + + // MembershipKindList is the list membership kind. + MembershipKindList = accesslistv1.MembershipKind_MEMBERSHIP_KIND_LIST.String() +) + // ReviewDayOfMonth is the day of month the review should be repeated on. type ReviewDayOfMonth int @@ -123,7 +138,7 @@ type AccessList struct { Spec Spec `json:"spec" yaml:"spec"` // Status contains dynamically calculated fields. - Status Status `json:"-" yaml:"-"` + Status Status `json:"status" yaml:"status"` } // Spec is the specification for an access list. @@ -167,6 +182,10 @@ type Owner struct { // IneligibleStatus describes the reason why this owner is not eligible. IneligibleStatus string `json:"ineligible_status" yaml:"ineligible_status"` + + // MembershipKind describes the kind of ownership, + // either "MEMBERSHIP_KIND_USER" or "MEMBERSHIP_KIND_LIST". + MembershipKind string `json:"membership_kind" yaml:"membership_kind"` } // Audit describes the audit configuration for an access list. @@ -224,7 +243,14 @@ type Grants struct { // Status contains dynamic fields calculated during retrieval. type Status struct { // MemberCount is the number of members in the access list. - MemberCount *uint32 + MemberCount *uint32 `json:"-" yaml:"-"` + // MemberListCount is the number of members in the access list that are lists themselves. + MemberListCount *uint32 `json:"-" yaml:"-"` + + // OwnerOf is a list of Access List UUIDs where this access list is an explicit owner. + OwnerOf []string `json:"owner_of" yaml:"owner_of"` + // MemberOf is a list of Access List UUIDs where this access list is an explicit member. + MemberOf []string `json:"member_of" yaml:"member_of"` } // NewAccessList will create a new access list. @@ -286,10 +312,6 @@ func (a *AccessList) CheckAndSetDefaults() error { a.Spec.Audit.Notifications.Start = twoWeeks } - if len(a.Spec.Grants.Roles) == 0 && len(a.Spec.Grants.Traits) == 0 { - return trace.BadParameter("grants must specify at least one role or trait") - } - // Deduplicate owners. The backend will currently prevent this, but it's possible that access lists // were created with duplicated owners before the backend checked for duplicate owners. In order to // ensure that these access lists are backwards compatible, we'll deduplicate them here. @@ -299,6 +321,9 @@ func (a *AccessList) CheckAndSetDefaults() error { if owner.Name == "" { return trace.BadParameter("owner name is missing") } + if owner.MembershipKind == "" { + owner.MembershipKind = MembershipKindUser + } if _, ok := ownerMap[owner.Name]; ok { continue @@ -317,7 +342,7 @@ func (a *AccessList) GetOwners() []Owner { return a.Spec.Owners } -// GetOwners returns the list of owners from the access list. +// SetOwners sets the owners of the access list. func (a *AccessList) SetOwners(owners []Owner) { a.Spec.Owners = owners } @@ -337,6 +362,11 @@ func (a *AccessList) GetGrants() Grants { return a.Spec.Grants } +// GetOwnerGrants returns the owner grants from the access list. +func (a *AccessList) GetOwnerGrants() Grants { + return a.Spec.OwnerGrants +} + // GetMetadata returns metadata. This is specifically for conforming to the Resource interface, // and should be removed when possible. func (a *AccessList) GetMetadata() types.Metadata { diff --git a/api/types/accesslist/convert/v1/accesslist.go b/api/types/accesslist/convert/v1/accesslist.go index fb0d00c8a090f..9ff3aa0e36b48 100644 --- a/api/types/accesslist/convert/v1/accesslist.go +++ b/api/types/accesslist/convert/v1/accesslist.go @@ -68,13 +68,10 @@ func FromProto(msg *accesslistv1.AccessList, opts ...AccessListOption) (*accessl owners := make([]accesslist.Owner, len(msg.Spec.Owners)) for i, owner := range msg.Spec.Owners { - owners[i] = accesslist.Owner{ - Name: owner.Name, - Description: owner.Description, - // Set it to empty as default. - // Must provide as options to set it with the provided value. - IneligibleStatus: "", - } + owners[i] = FromOwnerProto(owner) + // Set IneligibleStatus to empty as default. + // Must provide as options to set it with the provided value. + owners[i].IneligibleStatus = "" } var ownerGrants accesslist.Grants @@ -94,10 +91,24 @@ func FromProto(msg *accesslistv1.AccessList, opts ...AccessListOption) (*accessl } var memberCount *uint32 + var memberListCount *uint32 if msg.Status != nil && msg.Status.MemberCount != nil { memberCount = new(uint32) *memberCount = *msg.Status.MemberCount } + if msg.Status != nil && msg.Status.MemberListCount != nil { + memberListCount = new(uint32) + *memberListCount = *msg.Status.MemberListCount + } + + var ownerOf []string + var memberOf []string + if msg.Status != nil && msg.Status.OwnerOf != nil { + ownerOf = msg.Status.OwnerOf + } + if msg.Status != nil && msg.Status.MemberOf != nil { + memberOf = msg.Status.MemberOf + } accessList, err := accesslist.NewAccessList(headerv1.FromMetadataProto(msg.Header.Metadata), accesslist.Spec{ Title: msg.Spec.Title, @@ -126,7 +137,10 @@ func FromProto(msg *accesslistv1.AccessList, opts ...AccessListOption) (*accessl return nil, trace.Wrap(err) } accessList.Status = accesslist.Status{ - MemberCount: memberCount, + MemberCount: memberCount, + MemberListCount: memberListCount, + OwnerOf: ownerOf, + MemberOf: memberOf, } for _, opt := range opts { @@ -140,15 +154,7 @@ func FromProto(msg *accesslistv1.AccessList, opts ...AccessListOption) (*accessl func ToProto(accessList *accesslist.AccessList) *accesslistv1.AccessList { owners := make([]*accesslistv1.AccessListOwner, len(accessList.Spec.Owners)) for i, owner := range accessList.Spec.Owners { - var ineligibleStatus accesslistv1.IneligibleStatus - if enumVal, ok := accesslistv1.IneligibleStatus_value[owner.IneligibleStatus]; ok { - ineligibleStatus = accesslistv1.IneligibleStatus(enumVal) - } - owners[i] = &accesslistv1.AccessListOwner{ - Name: owner.Name, - Description: owner.Description, - IneligibleStatus: ineligibleStatus, - } + owners[i] = ToOwnerProto(owner) } var ownerGrants *accesslistv1.AccessListGrants @@ -173,10 +179,24 @@ func ToProto(accessList *accesslist.AccessList) *accesslistv1.AccessList { } var memberCount *uint32 + var memberListCount *uint32 if accessList.Status.MemberCount != nil { memberCount = new(uint32) *memberCount = *accessList.Status.MemberCount } + if accessList.Status.MemberListCount != nil { + memberListCount = new(uint32) + *memberListCount = *accessList.Status.MemberListCount + } + + var ownerOf []string + var memberOf []string + if accessList.Status.OwnerOf != nil { + ownerOf = accessList.Status.OwnerOf + } + if accessList.Status.MemberOf != nil { + memberOf = accessList.Status.MemberOf + } return &accesslistv1.AccessList{ Header: headerv1.ToResourceHeaderProto(accessList.ResourceHeader), @@ -209,11 +229,53 @@ func ToProto(accessList *accesslist.AccessList) *accesslistv1.AccessList { OwnerGrants: ownerGrants, }, Status: &accesslistv1.AccessListStatus{ - MemberCount: memberCount, + MemberCount: memberCount, + MemberListCount: memberListCount, + OwnerOf: ownerOf, + MemberOf: memberOf, }, } } +// ToOwnerProto converts an internal access list owner into a v1 access list owner object. +func ToOwnerProto(owner accesslist.Owner) *accesslistv1.AccessListOwner { + var ineligibleStatus accesslistv1.IneligibleStatus + if owner.IneligibleStatus != "" { + if enumVal, ok := accesslistv1.IneligibleStatus_value[owner.IneligibleStatus]; ok { + ineligibleStatus = accesslistv1.IneligibleStatus(enumVal) + } + } else { + ineligibleStatus = accesslistv1.IneligibleStatus_INELIGIBLE_STATUS_UNSPECIFIED + } + + var kind accesslistv1.MembershipKind + if enumVal, ok := accesslistv1.MembershipKind_value[owner.MembershipKind]; ok { + kind = accesslistv1.MembershipKind(enumVal) + } + + return &accesslistv1.AccessListOwner{ + Name: owner.Name, + Description: owner.Description, + IneligibleStatus: ineligibleStatus, + MembershipKind: kind, + } +} + +// FromOwnerProto converts a v1 access list owner into an internal access list owner object. +func FromOwnerProto(protoOwner *accesslistv1.AccessListOwner) accesslist.Owner { + ineligibleStatus := "" + if protoOwner.IneligibleStatus != accesslistv1.IneligibleStatus_INELIGIBLE_STATUS_UNSPECIFIED { + ineligibleStatus = protoOwner.IneligibleStatus.String() + } + + return accesslist.Owner{ + Name: protoOwner.Name, + Description: protoOwner.Description, + IneligibleStatus: ineligibleStatus, + MembershipKind: protoOwner.MembershipKind.String(), + } +} + // WithOwnersIneligibleStatusField sets the "ineligibleStatus" field to the provided proto value. func WithOwnersIneligibleStatusField(protoOwners []*accesslistv1.AccessListOwner) AccessListOption { return func(a *accesslist.AccessList) { diff --git a/api/types/accesslist/member.go b/api/types/accesslist/member.go index 1ffeeccca8342..28a71ac1bcf5e 100644 --- a/api/types/accesslist/member.go +++ b/api/types/accesslist/member.go @@ -61,6 +61,10 @@ type AccessListMemberSpec struct { // IneligibleStatus describes the reason why this member is not eligible. IneligibleStatus string `json:"ineligible_status" yaml:"ineligible_status"` + + // MembershipKind describes the kind of membership, + // either "MEMBERSHIP_KIND_USER" or "MEMBERSHIP_KIND_LIST". + MembershipKind string `json:"membership_kind" yaml:"membership_kind"` } // NewAccessListMember will create a new access listm member. @@ -86,6 +90,10 @@ func (a *AccessListMember) CheckAndSetDefaults() error { return trace.Wrap(err) } + if a.Spec.MembershipKind == "" { + a.Spec.MembershipKind = MembershipKindUser + } + if a.Spec.AccessList == "" { return trace.BadParameter("access list is missing") } diff --git a/api/types/events/events.go b/api/types/events/events.go index 4c1e561c7e2f1..19cc44b5e8981 100644 --- a/api/types/events/events.go +++ b/api/types/events/events.go @@ -2302,3 +2302,53 @@ func (m *UserTaskUpdate) TrimToMaxSize(_ int) AuditEvent { func (m *UserTaskDelete) TrimToMaxSize(_ int) AuditEvent { return m } + +func (m *SFTPSummary) TrimToMaxSize(maxSize int) AuditEvent { + size := m.Size() + if size <= maxSize { + return m + } + + out := utils.CloneProtoMsg(m) + + var customFieldsCount int + for i := range out.FileTransferStats { + if out.FileTransferStats[i].Path != "" { + customFieldsCount++ + out.FileTransferStats[i].Path = "" + } + } + + maxSize = adjustedMaxSize(out, maxSize) + maxFieldsSize := maxSizePerField(maxSize, customFieldsCount) + + for i := range out.FileTransferStats { + out.FileTransferStats[i].Path = trimStr(out.FileTransferStats[i].Path, maxFieldsSize) + } + + return out +} + +func (m *AutoUpdateConfigCreate) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *AutoUpdateConfigUpdate) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *AutoUpdateConfigDelete) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *AutoUpdateVersionCreate) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *AutoUpdateVersionUpdate) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *AutoUpdateVersionDelete) TrimToMaxSize(_ int) AuditEvent { + return m +} diff --git a/api/types/events/events.pb.go b/api/types/events/events.pb.go index d992e716e5201..660ffdc998fb1 100644 --- a/api/types/events/events.pb.go +++ b/api/types/events/events.pb.go @@ -3337,6 +3337,101 @@ func (m *SFTP) XXX_DiscardUnknown() { var xxx_messageInfo_SFTP proto.InternalMessageInfo +// SFTPSummary is emitted at the end of an SFTP transfer +type SFTPSummary struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,2,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,3,opt,name=Connection,proto3,embedded=Connection" json:""` + // SessionMetadata is a common event session metadata + SessionMetadata `protobuf:"bytes,4,opt,name=Session,proto3,embedded=Session" json:""` + // ServerMetadata is a common server metadata + ServerMetadata `protobuf:"bytes,5,opt,name=Server,proto3,embedded=Server" json:""` + // FileTransferStats contains statistics about transferred files + FileTransferStats []*FileTransferStat `protobuf:"bytes,6,rep,name=FileTransferStats,proto3" json:"file_transfer_stats"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SFTPSummary) Reset() { *m = SFTPSummary{} } +func (m *SFTPSummary) String() string { return proto.CompactTextString(m) } +func (*SFTPSummary) ProtoMessage() {} +func (*SFTPSummary) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{56} +} +func (m *SFTPSummary) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SFTPSummary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SFTPSummary.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 *SFTPSummary) XXX_Merge(src proto.Message) { + xxx_messageInfo_SFTPSummary.Merge(m, src) +} +func (m *SFTPSummary) XXX_Size() int { + return m.Size() +} +func (m *SFTPSummary) XXX_DiscardUnknown() { + xxx_messageInfo_SFTPSummary.DiscardUnknown(m) +} + +var xxx_messageInfo_SFTPSummary proto.InternalMessageInfo + +// FileTransferStat is statistics about a transferred file +type FileTransferStat struct { + Path string `protobuf:"bytes,1,opt,name=Path,proto3" json:"path"` + BytesRead uint64 `protobuf:"varint,2,opt,name=BytesRead,proto3" json:"bytes_read"` + BytesWritten uint64 `protobuf:"varint,3,opt,name=BytesWritten,proto3" json:"bytes_written"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileTransferStat) Reset() { *m = FileTransferStat{} } +func (m *FileTransferStat) String() string { return proto.CompactTextString(m) } +func (*FileTransferStat) ProtoMessage() {} +func (*FileTransferStat) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{57} +} +func (m *FileTransferStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FileTransferStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FileTransferStat.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 *FileTransferStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileTransferStat.Merge(m, src) +} +func (m *FileTransferStat) XXX_Size() int { + return m.Size() +} +func (m *FileTransferStat) XXX_DiscardUnknown() { + xxx_messageInfo_FileTransferStat.DiscardUnknown(m) +} + +var xxx_messageInfo_FileTransferStat proto.InternalMessageInfo + // Subsystem is emitted when a user requests a new subsystem. type Subsystem struct { // Metadata is a common event metadata @@ -3358,7 +3453,7 @@ func (m *Subsystem) Reset() { *m = Subsystem{} } func (m *Subsystem) String() string { return proto.CompactTextString(m) } func (*Subsystem) ProtoMessage() {} func (*Subsystem) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{56} + return fileDescriptor_007ba1c3d6266d56, []int{58} } func (m *Subsystem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3410,7 +3505,7 @@ func (m *ClientDisconnect) Reset() { *m = ClientDisconnect{} } func (m *ClientDisconnect) String() string { return proto.CompactTextString(m) } func (*ClientDisconnect) ProtoMessage() {} func (*ClientDisconnect) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{57} + return fileDescriptor_007ba1c3d6266d56, []int{59} } func (m *ClientDisconnect) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3458,7 +3553,7 @@ func (m *AuthAttempt) Reset() { *m = AuthAttempt{} } func (m *AuthAttempt) String() string { return proto.CompactTextString(m) } func (*AuthAttempt) ProtoMessage() {} func (*AuthAttempt) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{58} + return fileDescriptor_007ba1c3d6266d56, []int{60} } func (m *AuthAttempt) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3504,7 +3599,7 @@ func (m *UserTokenCreate) Reset() { *m = UserTokenCreate{} } func (m *UserTokenCreate) String() string { return proto.CompactTextString(m) } func (*UserTokenCreate) ProtoMessage() {} func (*UserTokenCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{59} + return fileDescriptor_007ba1c3d6266d56, []int{61} } func (m *UserTokenCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3552,7 +3647,7 @@ func (m *RoleCreate) Reset() { *m = RoleCreate{} } func (m *RoleCreate) String() string { return proto.CompactTextString(m) } func (*RoleCreate) ProtoMessage() {} func (*RoleCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{60} + return fileDescriptor_007ba1c3d6266d56, []int{62} } func (m *RoleCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3600,7 +3695,7 @@ func (m *RoleUpdate) Reset() { *m = RoleUpdate{} } func (m *RoleUpdate) String() string { return proto.CompactTextString(m) } func (*RoleUpdate) ProtoMessage() {} func (*RoleUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{61} + return fileDescriptor_007ba1c3d6266d56, []int{63} } func (m *RoleUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3648,7 +3743,7 @@ func (m *RoleDelete) Reset() { *m = RoleDelete{} } func (m *RoleDelete) String() string { return proto.CompactTextString(m) } func (*RoleDelete) ProtoMessage() {} func (*RoleDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{62} + return fileDescriptor_007ba1c3d6266d56, []int{64} } func (m *RoleDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3694,7 +3789,7 @@ func (m *BotCreate) Reset() { *m = BotCreate{} } func (m *BotCreate) String() string { return proto.CompactTextString(m) } func (*BotCreate) ProtoMessage() {} func (*BotCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{63} + return fileDescriptor_007ba1c3d6266d56, []int{65} } func (m *BotCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3740,7 +3835,7 @@ func (m *BotUpdate) Reset() { *m = BotUpdate{} } func (m *BotUpdate) String() string { return proto.CompactTextString(m) } func (*BotUpdate) ProtoMessage() {} func (*BotUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{64} + return fileDescriptor_007ba1c3d6266d56, []int{66} } func (m *BotUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3786,7 +3881,7 @@ func (m *BotDelete) Reset() { *m = BotDelete{} } func (m *BotDelete) String() string { return proto.CompactTextString(m) } func (*BotDelete) ProtoMessage() {} func (*BotDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{65} + return fileDescriptor_007ba1c3d6266d56, []int{67} } func (m *BotDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3834,7 +3929,7 @@ func (m *TrustedClusterCreate) Reset() { *m = TrustedClusterCreate{} } func (m *TrustedClusterCreate) String() string { return proto.CompactTextString(m) } func (*TrustedClusterCreate) ProtoMessage() {} func (*TrustedClusterCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{66} + return fileDescriptor_007ba1c3d6266d56, []int{68} } func (m *TrustedClusterCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3882,7 +3977,7 @@ func (m *TrustedClusterDelete) Reset() { *m = TrustedClusterDelete{} } func (m *TrustedClusterDelete) String() string { return proto.CompactTextString(m) } func (*TrustedClusterDelete) ProtoMessage() {} func (*TrustedClusterDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{67} + return fileDescriptor_007ba1c3d6266d56, []int{69} } func (m *TrustedClusterDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3928,7 +4023,7 @@ func (m *ProvisionTokenCreate) Reset() { *m = ProvisionTokenCreate{} } func (m *ProvisionTokenCreate) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenCreate) ProtoMessage() {} func (*ProvisionTokenCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{68} + return fileDescriptor_007ba1c3d6266d56, []int{70} } func (m *ProvisionTokenCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3977,7 +4072,7 @@ func (m *TrustedClusterTokenCreate) Reset() { *m = TrustedClusterTokenCr func (m *TrustedClusterTokenCreate) String() string { return proto.CompactTextString(m) } func (*TrustedClusterTokenCreate) ProtoMessage() {} func (*TrustedClusterTokenCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{69} + return fileDescriptor_007ba1c3d6266d56, []int{71} } func (m *TrustedClusterTokenCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4025,7 +4120,7 @@ func (m *GithubConnectorCreate) Reset() { *m = GithubConnectorCreate{} } func (m *GithubConnectorCreate) String() string { return proto.CompactTextString(m) } func (*GithubConnectorCreate) ProtoMessage() {} func (*GithubConnectorCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{70} + return fileDescriptor_007ba1c3d6266d56, []int{72} } func (m *GithubConnectorCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4073,7 +4168,7 @@ func (m *GithubConnectorUpdate) Reset() { *m = GithubConnectorUpdate{} } func (m *GithubConnectorUpdate) String() string { return proto.CompactTextString(m) } func (*GithubConnectorUpdate) ProtoMessage() {} func (*GithubConnectorUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{71} + return fileDescriptor_007ba1c3d6266d56, []int{73} } func (m *GithubConnectorUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4121,7 +4216,7 @@ func (m *GithubConnectorDelete) Reset() { *m = GithubConnectorDelete{} } func (m *GithubConnectorDelete) String() string { return proto.CompactTextString(m) } func (*GithubConnectorDelete) ProtoMessage() {} func (*GithubConnectorDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{72} + return fileDescriptor_007ba1c3d6266d56, []int{74} } func (m *GithubConnectorDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4167,7 +4262,7 @@ func (m *OIDCConnectorCreate) Reset() { *m = OIDCConnectorCreate{} } func (m *OIDCConnectorCreate) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorCreate) ProtoMessage() {} func (*OIDCConnectorCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{73} + return fileDescriptor_007ba1c3d6266d56, []int{75} } func (m *OIDCConnectorCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4213,7 +4308,7 @@ func (m *OIDCConnectorUpdate) Reset() { *m = OIDCConnectorUpdate{} } func (m *OIDCConnectorUpdate) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorUpdate) ProtoMessage() {} func (*OIDCConnectorUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{74} + return fileDescriptor_007ba1c3d6266d56, []int{76} } func (m *OIDCConnectorUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4259,7 +4354,7 @@ func (m *OIDCConnectorDelete) Reset() { *m = OIDCConnectorDelete{} } func (m *OIDCConnectorDelete) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorDelete) ProtoMessage() {} func (*OIDCConnectorDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{75} + return fileDescriptor_007ba1c3d6266d56, []int{77} } func (m *OIDCConnectorDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4307,7 +4402,7 @@ func (m *SAMLConnectorCreate) Reset() { *m = SAMLConnectorCreate{} } func (m *SAMLConnectorCreate) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorCreate) ProtoMessage() {} func (*SAMLConnectorCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{76} + return fileDescriptor_007ba1c3d6266d56, []int{78} } func (m *SAMLConnectorCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4355,7 +4450,7 @@ func (m *SAMLConnectorUpdate) Reset() { *m = SAMLConnectorUpdate{} } func (m *SAMLConnectorUpdate) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorUpdate) ProtoMessage() {} func (*SAMLConnectorUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{77} + return fileDescriptor_007ba1c3d6266d56, []int{79} } func (m *SAMLConnectorUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4401,7 +4496,7 @@ func (m *SAMLConnectorDelete) Reset() { *m = SAMLConnectorDelete{} } func (m *SAMLConnectorDelete) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorDelete) ProtoMessage() {} func (*SAMLConnectorDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{78} + return fileDescriptor_007ba1c3d6266d56, []int{80} } func (m *SAMLConnectorDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4467,7 +4562,7 @@ func (m *KubeRequest) Reset() { *m = KubeRequest{} } func (m *KubeRequest) String() string { return proto.CompactTextString(m) } func (*KubeRequest) ProtoMessage() {} func (*KubeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{79} + return fileDescriptor_007ba1c3d6266d56, []int{81} } func (m *KubeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4515,7 +4610,7 @@ func (m *AppMetadata) Reset() { *m = AppMetadata{} } func (m *AppMetadata) String() string { return proto.CompactTextString(m) } func (*AppMetadata) ProtoMessage() {} func (*AppMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{80} + return fileDescriptor_007ba1c3d6266d56, []int{82} } func (m *AppMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4563,7 +4658,7 @@ func (m *AppCreate) Reset() { *m = AppCreate{} } func (m *AppCreate) String() string { return proto.CompactTextString(m) } func (*AppCreate) ProtoMessage() {} func (*AppCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{81} + return fileDescriptor_007ba1c3d6266d56, []int{83} } func (m *AppCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4611,7 +4706,7 @@ func (m *AppUpdate) Reset() { *m = AppUpdate{} } func (m *AppUpdate) String() string { return proto.CompactTextString(m) } func (*AppUpdate) ProtoMessage() {} func (*AppUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{82} + return fileDescriptor_007ba1c3d6266d56, []int{84} } func (m *AppUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4657,7 +4752,7 @@ func (m *AppDelete) Reset() { *m = AppDelete{} } func (m *AppDelete) String() string { return proto.CompactTextString(m) } func (*AppDelete) ProtoMessage() {} func (*AppDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{83} + return fileDescriptor_007ba1c3d6266d56, []int{85} } func (m *AppDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4712,7 +4807,7 @@ func (m *AppSessionStart) Reset() { *m = AppSessionStart{} } func (m *AppSessionStart) String() string { return proto.CompactTextString(m) } func (*AppSessionStart) ProtoMessage() {} func (*AppSessionStart) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{84} + return fileDescriptor_007ba1c3d6266d56, []int{86} } func (m *AppSessionStart) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4764,7 +4859,7 @@ func (m *AppSessionEnd) Reset() { *m = AppSessionEnd{} } func (m *AppSessionEnd) String() string { return proto.CompactTextString(m) } func (*AppSessionEnd) ProtoMessage() {} func (*AppSessionEnd) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{85} + return fileDescriptor_007ba1c3d6266d56, []int{87} } func (m *AppSessionEnd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4821,7 +4916,7 @@ func (m *AppSessionChunk) Reset() { *m = AppSessionChunk{} } func (m *AppSessionChunk) String() string { return proto.CompactTextString(m) } func (*AppSessionChunk) ProtoMessage() {} func (*AppSessionChunk) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{86} + return fileDescriptor_007ba1c3d6266d56, []int{88} } func (m *AppSessionChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4875,7 +4970,7 @@ func (m *AppSessionRequest) Reset() { *m = AppSessionRequest{} } func (m *AppSessionRequest) String() string { return proto.CompactTextString(m) } func (*AppSessionRequest) ProtoMessage() {} func (*AppSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{87} + return fileDescriptor_007ba1c3d6266d56, []int{89} } func (m *AppSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4923,7 +5018,7 @@ func (m *AWSRequestMetadata) Reset() { *m = AWSRequestMetadata{} } func (m *AWSRequestMetadata) String() string { return proto.CompactTextString(m) } func (*AWSRequestMetadata) ProtoMessage() {} func (*AWSRequestMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{88} + return fileDescriptor_007ba1c3d6266d56, []int{90} } func (m *AWSRequestMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4989,7 +5084,7 @@ func (m *DatabaseMetadata) Reset() { *m = DatabaseMetadata{} } func (m *DatabaseMetadata) String() string { return proto.CompactTextString(m) } func (*DatabaseMetadata) ProtoMessage() {} func (*DatabaseMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{89} + return fileDescriptor_007ba1c3d6266d56, []int{91} } func (m *DatabaseMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5037,7 +5132,7 @@ func (m *DatabaseCreate) Reset() { *m = DatabaseCreate{} } func (m *DatabaseCreate) String() string { return proto.CompactTextString(m) } func (*DatabaseCreate) ProtoMessage() {} func (*DatabaseCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{90} + return fileDescriptor_007ba1c3d6266d56, []int{92} } func (m *DatabaseCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5085,7 +5180,7 @@ func (m *DatabaseUpdate) Reset() { *m = DatabaseUpdate{} } func (m *DatabaseUpdate) String() string { return proto.CompactTextString(m) } func (*DatabaseUpdate) ProtoMessage() {} func (*DatabaseUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{91} + return fileDescriptor_007ba1c3d6266d56, []int{93} } func (m *DatabaseUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5131,7 +5226,7 @@ func (m *DatabaseDelete) Reset() { *m = DatabaseDelete{} } func (m *DatabaseDelete) String() string { return proto.CompactTextString(m) } func (*DatabaseDelete) ProtoMessage() {} func (*DatabaseDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{92} + return fileDescriptor_007ba1c3d6266d56, []int{94} } func (m *DatabaseDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5189,7 +5284,7 @@ func (m *DatabaseSessionStart) Reset() { *m = DatabaseSessionStart{} } func (m *DatabaseSessionStart) String() string { return proto.CompactTextString(m) } func (*DatabaseSessionStart) ProtoMessage() {} func (*DatabaseSessionStart) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{93} + return fileDescriptor_007ba1c3d6266d56, []int{95} } func (m *DatabaseSessionStart) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5243,7 +5338,7 @@ func (m *DatabaseSessionQuery) Reset() { *m = DatabaseSessionQuery{} } func (m *DatabaseSessionQuery) String() string { return proto.CompactTextString(m) } func (*DatabaseSessionQuery) ProtoMessage() {} func (*DatabaseSessionQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{94} + return fileDescriptor_007ba1c3d6266d56, []int{96} } func (m *DatabaseSessionQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5298,7 +5393,7 @@ func (m *DatabaseSessionCommandResult) Reset() { *m = DatabaseSessionCom func (m *DatabaseSessionCommandResult) String() string { return proto.CompactTextString(m) } func (*DatabaseSessionCommandResult) ProtoMessage() {} func (*DatabaseSessionCommandResult) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{95} + return fileDescriptor_007ba1c3d6266d56, []int{97} } func (m *DatabaseSessionCommandResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5350,7 +5445,7 @@ func (m *DatabasePermissionUpdate) Reset() { *m = DatabasePermissionUpda func (m *DatabasePermissionUpdate) String() string { return proto.CompactTextString(m) } func (*DatabasePermissionUpdate) ProtoMessage() {} func (*DatabasePermissionUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{96} + return fileDescriptor_007ba1c3d6266d56, []int{98} } func (m *DatabasePermissionUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5394,7 +5489,7 @@ func (m *DatabasePermissionEntry) Reset() { *m = DatabasePermissionEntry func (m *DatabasePermissionEntry) String() string { return proto.CompactTextString(m) } func (*DatabasePermissionEntry) ProtoMessage() {} func (*DatabasePermissionEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{97} + return fileDescriptor_007ba1c3d6266d56, []int{99} } func (m *DatabasePermissionEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5449,7 +5544,7 @@ func (m *DatabaseUserCreate) Reset() { *m = DatabaseUserCreate{} } func (m *DatabaseUserCreate) String() string { return proto.CompactTextString(m) } func (*DatabaseUserCreate) ProtoMessage() {} func (*DatabaseUserCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{98} + return fileDescriptor_007ba1c3d6266d56, []int{100} } func (m *DatabaseUserCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5504,7 +5599,7 @@ func (m *DatabaseUserDeactivate) Reset() { *m = DatabaseUserDeactivate{} func (m *DatabaseUserDeactivate) String() string { return proto.CompactTextString(m) } func (*DatabaseUserDeactivate) ProtoMessage() {} func (*DatabaseUserDeactivate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{99} + return fileDescriptor_007ba1c3d6266d56, []int{101} } func (m *DatabaseUserDeactivate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5557,7 +5652,7 @@ func (m *PostgresParse) Reset() { *m = PostgresParse{} } func (m *PostgresParse) String() string { return proto.CompactTextString(m) } func (*PostgresParse) ProtoMessage() {} func (*PostgresParse) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{100} + return fileDescriptor_007ba1c3d6266d56, []int{102} } func (m *PostgresParse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5612,7 +5707,7 @@ func (m *PostgresBind) Reset() { *m = PostgresBind{} } func (m *PostgresBind) String() string { return proto.CompactTextString(m) } func (*PostgresBind) ProtoMessage() {} func (*PostgresBind) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{101} + return fileDescriptor_007ba1c3d6266d56, []int{103} } func (m *PostgresBind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5663,7 +5758,7 @@ func (m *PostgresExecute) Reset() { *m = PostgresExecute{} } func (m *PostgresExecute) String() string { return proto.CompactTextString(m) } func (*PostgresExecute) ProtoMessage() {} func (*PostgresExecute) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{102} + return fileDescriptor_007ba1c3d6266d56, []int{104} } func (m *PostgresExecute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5716,7 +5811,7 @@ func (m *PostgresClose) Reset() { *m = PostgresClose{} } func (m *PostgresClose) String() string { return proto.CompactTextString(m) } func (*PostgresClose) ProtoMessage() {} func (*PostgresClose) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{103} + return fileDescriptor_007ba1c3d6266d56, []int{105} } func (m *PostgresClose) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5769,7 +5864,7 @@ func (m *PostgresFunctionCall) Reset() { *m = PostgresFunctionCall{} } func (m *PostgresFunctionCall) String() string { return proto.CompactTextString(m) } func (*PostgresFunctionCall) ProtoMessage() {} func (*PostgresFunctionCall) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{104} + return fileDescriptor_007ba1c3d6266d56, []int{106} } func (m *PostgresFunctionCall) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5837,7 +5932,7 @@ func (m *WindowsDesktopSessionStart) Reset() { *m = WindowsDesktopSessio func (m *WindowsDesktopSessionStart) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopSessionStart) ProtoMessage() {} func (*WindowsDesktopSessionStart) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{105} + return fileDescriptor_007ba1c3d6266d56, []int{107} } func (m *WindowsDesktopSessionStart) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5889,7 +5984,7 @@ func (m *DatabaseSessionEnd) Reset() { *m = DatabaseSessionEnd{} } func (m *DatabaseSessionEnd) String() string { return proto.CompactTextString(m) } func (*DatabaseSessionEnd) ProtoMessage() {} func (*DatabaseSessionEnd) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{106} + return fileDescriptor_007ba1c3d6266d56, []int{108} } func (m *DatabaseSessionEnd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5935,7 +6030,7 @@ func (m *MFADeviceMetadata) Reset() { *m = MFADeviceMetadata{} } func (m *MFADeviceMetadata) String() string { return proto.CompactTextString(m) } func (*MFADeviceMetadata) ProtoMessage() {} func (*MFADeviceMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{107} + return fileDescriptor_007ba1c3d6266d56, []int{109} } func (m *MFADeviceMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5983,7 +6078,7 @@ func (m *MFADeviceAdd) Reset() { *m = MFADeviceAdd{} } func (m *MFADeviceAdd) String() string { return proto.CompactTextString(m) } func (*MFADeviceAdd) ProtoMessage() {} func (*MFADeviceAdd) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{108} + return fileDescriptor_007ba1c3d6266d56, []int{110} } func (m *MFADeviceAdd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6031,7 +6126,7 @@ func (m *MFADeviceDelete) Reset() { *m = MFADeviceDelete{} } func (m *MFADeviceDelete) String() string { return proto.CompactTextString(m) } func (*MFADeviceDelete) ProtoMessage() {} func (*MFADeviceDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{109} + return fileDescriptor_007ba1c3d6266d56, []int{111} } func (m *MFADeviceDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6075,7 +6170,7 @@ func (m *BillingInformationUpdate) Reset() { *m = BillingInformationUpda func (m *BillingInformationUpdate) String() string { return proto.CompactTextString(m) } func (*BillingInformationUpdate) ProtoMessage() {} func (*BillingInformationUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{110} + return fileDescriptor_007ba1c3d6266d56, []int{112} } func (m *BillingInformationUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6119,7 +6214,7 @@ func (m *BillingCardCreate) Reset() { *m = BillingCardCreate{} } func (m *BillingCardCreate) String() string { return proto.CompactTextString(m) } func (*BillingCardCreate) ProtoMessage() {} func (*BillingCardCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{111} + return fileDescriptor_007ba1c3d6266d56, []int{113} } func (m *BillingCardCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6163,7 +6258,7 @@ func (m *BillingCardDelete) Reset() { *m = BillingCardDelete{} } func (m *BillingCardDelete) String() string { return proto.CompactTextString(m) } func (*BillingCardDelete) ProtoMessage() {} func (*BillingCardDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{112} + return fileDescriptor_007ba1c3d6266d56, []int{114} } func (m *BillingCardDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6217,7 +6312,7 @@ func (m *LockCreate) Reset() { *m = LockCreate{} } func (m *LockCreate) String() string { return proto.CompactTextString(m) } func (*LockCreate) ProtoMessage() {} func (*LockCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{113} + return fileDescriptor_007ba1c3d6266d56, []int{115} } func (m *LockCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6265,7 +6360,7 @@ func (m *LockDelete) Reset() { *m = LockDelete{} } func (m *LockDelete) String() string { return proto.CompactTextString(m) } func (*LockDelete) ProtoMessage() {} func (*LockDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{114} + return fileDescriptor_007ba1c3d6266d56, []int{116} } func (m *LockDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6309,7 +6404,7 @@ func (m *RecoveryCodeGenerate) Reset() { *m = RecoveryCodeGenerate{} } func (m *RecoveryCodeGenerate) String() string { return proto.CompactTextString(m) } func (*RecoveryCodeGenerate) ProtoMessage() {} func (*RecoveryCodeGenerate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{115} + return fileDescriptor_007ba1c3d6266d56, []int{117} } func (m *RecoveryCodeGenerate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6356,7 +6451,7 @@ func (m *RecoveryCodeUsed) Reset() { *m = RecoveryCodeUsed{} } func (m *RecoveryCodeUsed) String() string { return proto.CompactTextString(m) } func (*RecoveryCodeUsed) ProtoMessage() {} func (*RecoveryCodeUsed) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{116} + return fileDescriptor_007ba1c3d6266d56, []int{118} } func (m *RecoveryCodeUsed) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6422,7 +6517,7 @@ func (m *WindowsDesktopSessionEnd) Reset() { *m = WindowsDesktopSessionE func (m *WindowsDesktopSessionEnd) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopSessionEnd) ProtoMessage() {} func (*WindowsDesktopSessionEnd) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{117} + return fileDescriptor_007ba1c3d6266d56, []int{119} } func (m *WindowsDesktopSessionEnd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6470,7 +6565,7 @@ func (m *CertificateCreate) Reset() { *m = CertificateCreate{} } func (m *CertificateCreate) String() string { return proto.CompactTextString(m) } func (*CertificateCreate) ProtoMessage() {} func (*CertificateCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{118} + return fileDescriptor_007ba1c3d6266d56, []int{120} } func (m *CertificateCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6518,7 +6613,7 @@ func (m *RenewableCertificateGenerationMismatch) Reset() { func (m *RenewableCertificateGenerationMismatch) String() string { return proto.CompactTextString(m) } func (*RenewableCertificateGenerationMismatch) ProtoMessage() {} func (*RenewableCertificateGenerationMismatch) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{119} + return fileDescriptor_007ba1c3d6266d56, []int{121} } func (m *RenewableCertificateGenerationMismatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6576,7 +6671,7 @@ func (m *BotJoin) Reset() { *m = BotJoin{} } func (m *BotJoin) String() string { return proto.CompactTextString(m) } func (*BotJoin) ProtoMessage() {} func (*BotJoin) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{120} + return fileDescriptor_007ba1c3d6266d56, []int{122} } func (m *BotJoin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6638,7 +6733,7 @@ func (m *InstanceJoin) Reset() { *m = InstanceJoin{} } func (m *InstanceJoin) String() string { return proto.CompactTextString(m) } func (*InstanceJoin) ProtoMessage() {} func (*InstanceJoin) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{121} + return fileDescriptor_007ba1c3d6266d56, []int{123} } func (m *InstanceJoin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6686,7 +6781,7 @@ func (m *Unknown) Reset() { *m = Unknown{} } func (m *Unknown) String() string { return proto.CompactTextString(m) } func (*Unknown) ProtoMessage() {} func (*Unknown) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{122} + return fileDescriptor_007ba1c3d6266d56, []int{124} } func (m *Unknown) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6743,7 +6838,7 @@ func (m *DeviceMetadata) Reset() { *m = DeviceMetadata{} } func (m *DeviceMetadata) String() string { return proto.CompactTextString(m) } func (*DeviceMetadata) ProtoMessage() {} func (*DeviceMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{123} + return fileDescriptor_007ba1c3d6266d56, []int{125} } func (m *DeviceMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6794,7 +6889,7 @@ func (m *DeviceEvent) Reset() { *m = DeviceEvent{} } func (m *DeviceEvent) String() string { return proto.CompactTextString(m) } func (*DeviceEvent) ProtoMessage() {} func (*DeviceEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{124} + return fileDescriptor_007ba1c3d6266d56, []int{126} } func (m *DeviceEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6846,7 +6941,7 @@ func (m *DeviceEvent2) Reset() { *m = DeviceEvent2{} } func (m *DeviceEvent2) String() string { return proto.CompactTextString(m) } func (*DeviceEvent2) ProtoMessage() {} func (*DeviceEvent2) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{125} + return fileDescriptor_007ba1c3d6266d56, []int{127} } func (m *DeviceEvent2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6894,7 +6989,7 @@ func (m *DiscoveryConfigCreate) Reset() { *m = DiscoveryConfigCreate{} } func (m *DiscoveryConfigCreate) String() string { return proto.CompactTextString(m) } func (*DiscoveryConfigCreate) ProtoMessage() {} func (*DiscoveryConfigCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{126} + return fileDescriptor_007ba1c3d6266d56, []int{128} } func (m *DiscoveryConfigCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6942,7 +7037,7 @@ func (m *DiscoveryConfigUpdate) Reset() { *m = DiscoveryConfigUpdate{} } func (m *DiscoveryConfigUpdate) String() string { return proto.CompactTextString(m) } func (*DiscoveryConfigUpdate) ProtoMessage() {} func (*DiscoveryConfigUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{127} + return fileDescriptor_007ba1c3d6266d56, []int{129} } func (m *DiscoveryConfigUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6990,7 +7085,7 @@ func (m *DiscoveryConfigDelete) Reset() { *m = DiscoveryConfigDelete{} } func (m *DiscoveryConfigDelete) String() string { return proto.CompactTextString(m) } func (*DiscoveryConfigDelete) ProtoMessage() {} func (*DiscoveryConfigDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{128} + return fileDescriptor_007ba1c3d6266d56, []int{130} } func (m *DiscoveryConfigDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7036,7 +7131,7 @@ func (m *DiscoveryConfigDeleteAll) Reset() { *m = DiscoveryConfigDeleteA func (m *DiscoveryConfigDeleteAll) String() string { return proto.CompactTextString(m) } func (*DiscoveryConfigDeleteAll) ProtoMessage() {} func (*DiscoveryConfigDeleteAll) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{129} + return fileDescriptor_007ba1c3d6266d56, []int{131} } func (m *DiscoveryConfigDeleteAll) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7085,7 +7180,7 @@ func (m *IntegrationCreate) Reset() { *m = IntegrationCreate{} } func (m *IntegrationCreate) String() string { return proto.CompactTextString(m) } func (*IntegrationCreate) ProtoMessage() {} func (*IntegrationCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{130} + return fileDescriptor_007ba1c3d6266d56, []int{132} } func (m *IntegrationCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7134,7 +7229,7 @@ func (m *IntegrationUpdate) Reset() { *m = IntegrationUpdate{} } func (m *IntegrationUpdate) String() string { return proto.CompactTextString(m) } func (*IntegrationUpdate) ProtoMessage() {} func (*IntegrationUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{131} + return fileDescriptor_007ba1c3d6266d56, []int{133} } func (m *IntegrationUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7183,7 +7278,7 @@ func (m *IntegrationDelete) Reset() { *m = IntegrationDelete{} } func (m *IntegrationDelete) String() string { return proto.CompactTextString(m) } func (*IntegrationDelete) ProtoMessage() {} func (*IntegrationDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{132} + return fileDescriptor_007ba1c3d6266d56, []int{134} } func (m *IntegrationDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7229,7 +7324,7 @@ func (m *IntegrationMetadata) Reset() { *m = IntegrationMetadata{} } func (m *IntegrationMetadata) String() string { return proto.CompactTextString(m) } func (*IntegrationMetadata) ProtoMessage() {} func (*IntegrationMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{133} + return fileDescriptor_007ba1c3d6266d56, []int{135} } func (m *IntegrationMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7274,7 +7369,7 @@ func (m *AWSOIDCIntegrationMetadata) Reset() { *m = AWSOIDCIntegrationMe func (m *AWSOIDCIntegrationMetadata) String() string { return proto.CompactTextString(m) } func (*AWSOIDCIntegrationMetadata) ProtoMessage() {} func (*AWSOIDCIntegrationMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{134} + return fileDescriptor_007ba1c3d6266d56, []int{136} } func (m *AWSOIDCIntegrationMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7318,7 +7413,7 @@ func (m *AzureOIDCIntegrationMetadata) Reset() { *m = AzureOIDCIntegrati func (m *AzureOIDCIntegrationMetadata) String() string { return proto.CompactTextString(m) } func (*AzureOIDCIntegrationMetadata) ProtoMessage() {} func (*AzureOIDCIntegrationMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{135} + return fileDescriptor_007ba1c3d6266d56, []int{137} } func (m *AzureOIDCIntegrationMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7367,7 +7462,7 @@ func (m *PluginCreate) Reset() { *m = PluginCreate{} } func (m *PluginCreate) String() string { return proto.CompactTextString(m) } func (*PluginCreate) ProtoMessage() {} func (*PluginCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{136} + return fileDescriptor_007ba1c3d6266d56, []int{138} } func (m *PluginCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7416,7 +7511,7 @@ func (m *PluginUpdate) Reset() { *m = PluginUpdate{} } func (m *PluginUpdate) String() string { return proto.CompactTextString(m) } func (*PluginUpdate) ProtoMessage() {} func (*PluginUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{137} + return fileDescriptor_007ba1c3d6266d56, []int{139} } func (m *PluginUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7465,7 +7560,7 @@ func (m *PluginDelete) Reset() { *m = PluginDelete{} } func (m *PluginDelete) String() string { return proto.CompactTextString(m) } func (*PluginDelete) ProtoMessage() {} func (*PluginDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{138} + return fileDescriptor_007ba1c3d6266d56, []int{140} } func (m *PluginDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7514,7 +7609,7 @@ func (m *PluginMetadata) Reset() { *m = PluginMetadata{} } func (m *PluginMetadata) String() string { return proto.CompactTextString(m) } func (*PluginMetadata) ProtoMessage() {} func (*PluginMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{139} + return fileDescriptor_007ba1c3d6266d56, []int{141} } func (m *PluginMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7732,6 +7827,7 @@ type OneOf struct { // *OneOf_UserTaskCreate // *OneOf_UserTaskUpdate // *OneOf_UserTaskDelete + // *OneOf_SFTPSummary Event isOneOf_Event `protobuf_oneof:"Event"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -7742,7 +7838,7 @@ func (m *OneOf) Reset() { *m = OneOf{} } func (m *OneOf) String() string { return proto.CompactTextString(m) } func (*OneOf) ProtoMessage() {} func (*OneOf) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{140} + return fileDescriptor_007ba1c3d6266d56, []int{142} } func (m *OneOf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8335,6 +8431,9 @@ type OneOf_UserTaskUpdate struct { type OneOf_UserTaskDelete struct { UserTaskDelete *UserTaskDelete `protobuf:"bytes,190,opt,name=UserTaskDelete,proto3,oneof" json:"UserTaskDelete,omitempty"` } +type OneOf_SFTPSummary struct { + SFTPSummary *SFTPSummary `protobuf:"bytes,191,opt,name=SFTPSummary,proto3,oneof" json:"SFTPSummary,omitempty"` +} func (*OneOf_UserLogin) isOneOf_Event() {} func (*OneOf_UserCreate) isOneOf_Event() {} @@ -8522,6 +8621,7 @@ func (*OneOf_CrownJewelDelete) isOneOf_Event() {} func (*OneOf_UserTaskCreate) isOneOf_Event() {} func (*OneOf_UserTaskUpdate) isOneOf_Event() {} func (*OneOf_UserTaskDelete) isOneOf_Event() {} +func (*OneOf_SFTPSummary) isOneOf_Event() {} func (m *OneOf) GetEvent() isOneOf_Event { if m != nil { @@ -9832,6 +9932,13 @@ func (m *OneOf) GetUserTaskDelete() *UserTaskDelete { return nil } +func (m *OneOf) GetSFTPSummary() *SFTPSummary { + if x, ok := m.GetEvent().(*OneOf_SFTPSummary); ok { + return x.SFTPSummary + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*OneOf) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -10021,6 +10128,7 @@ func (*OneOf) XXX_OneofWrappers() []interface{} { (*OneOf_UserTaskCreate)(nil), (*OneOf_UserTaskUpdate)(nil), (*OneOf_UserTaskDelete)(nil), + (*OneOf_SFTPSummary)(nil), } } @@ -10041,7 +10149,7 @@ func (m *StreamStatus) Reset() { *m = StreamStatus{} } func (m *StreamStatus) String() string { return proto.CompactTextString(m) } func (*StreamStatus) ProtoMessage() {} func (*StreamStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{141} + return fileDescriptor_007ba1c3d6266d56, []int{143} } func (m *StreamStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10087,7 +10195,7 @@ func (m *SessionUpload) Reset() { *m = SessionUpload{} } func (m *SessionUpload) String() string { return proto.CompactTextString(m) } func (*SessionUpload) ProtoMessage() {} func (*SessionUpload) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{142} + return fileDescriptor_007ba1c3d6266d56, []int{144} } func (m *SessionUpload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10206,7 +10314,7 @@ func (m *Identity) Reset() { *m = Identity{} } func (m *Identity) String() string { return proto.CompactTextString(m) } func (*Identity) ProtoMessage() {} func (*Identity) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{143} + return fileDescriptor_007ba1c3d6266d56, []int{145} } func (m *Identity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10262,7 +10370,7 @@ func (m *RouteToApp) Reset() { *m = RouteToApp{} } func (m *RouteToApp) String() string { return proto.CompactTextString(m) } func (*RouteToApp) ProtoMessage() {} func (*RouteToApp) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{144} + return fileDescriptor_007ba1c3d6266d56, []int{146} } func (m *RouteToApp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10312,7 +10420,7 @@ func (m *RouteToDatabase) Reset() { *m = RouteToDatabase{} } func (m *RouteToDatabase) String() string { return proto.CompactTextString(m) } func (*RouteToDatabase) ProtoMessage() {} func (*RouteToDatabase) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{145} + return fileDescriptor_007ba1c3d6266d56, []int{147} } func (m *RouteToDatabase) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10362,7 +10470,7 @@ func (m *DeviceExtensions) Reset() { *m = DeviceExtensions{} } func (m *DeviceExtensions) String() string { return proto.CompactTextString(m) } func (*DeviceExtensions) ProtoMessage() {} func (*DeviceExtensions) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{146} + return fileDescriptor_007ba1c3d6266d56, []int{148} } func (m *DeviceExtensions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10419,7 +10527,7 @@ func (m *AccessRequestResourceSearch) Reset() { *m = AccessRequestResour func (m *AccessRequestResourceSearch) String() string { return proto.CompactTextString(m) } func (*AccessRequestResourceSearch) ProtoMessage() {} func (*AccessRequestResourceSearch) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{147} + return fileDescriptor_007ba1c3d6266d56, []int{149} } func (m *AccessRequestResourceSearch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10470,7 +10578,7 @@ func (m *MySQLStatementPrepare) Reset() { *m = MySQLStatementPrepare{} } func (m *MySQLStatementPrepare) String() string { return proto.CompactTextString(m) } func (*MySQLStatementPrepare) ProtoMessage() {} func (*MySQLStatementPrepare) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{148} + return fileDescriptor_007ba1c3d6266d56, []int{150} } func (m *MySQLStatementPrepare) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10523,7 +10631,7 @@ func (m *MySQLStatementExecute) Reset() { *m = MySQLStatementExecute{} } func (m *MySQLStatementExecute) String() string { return proto.CompactTextString(m) } func (*MySQLStatementExecute) ProtoMessage() {} func (*MySQLStatementExecute) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{149} + return fileDescriptor_007ba1c3d6266d56, []int{151} } func (m *MySQLStatementExecute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10578,7 +10686,7 @@ func (m *MySQLStatementSendLongData) Reset() { *m = MySQLStatementSendLo func (m *MySQLStatementSendLongData) String() string { return proto.CompactTextString(m) } func (*MySQLStatementSendLongData) ProtoMessage() {} func (*MySQLStatementSendLongData) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{150} + return fileDescriptor_007ba1c3d6266d56, []int{152} } func (m *MySQLStatementSendLongData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10629,7 +10737,7 @@ func (m *MySQLStatementClose) Reset() { *m = MySQLStatementClose{} } func (m *MySQLStatementClose) String() string { return proto.CompactTextString(m) } func (*MySQLStatementClose) ProtoMessage() {} func (*MySQLStatementClose) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{151} + return fileDescriptor_007ba1c3d6266d56, []int{153} } func (m *MySQLStatementClose) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10680,7 +10788,7 @@ func (m *MySQLStatementReset) Reset() { *m = MySQLStatementReset{} } func (m *MySQLStatementReset) String() string { return proto.CompactTextString(m) } func (*MySQLStatementReset) ProtoMessage() {} func (*MySQLStatementReset) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{152} + return fileDescriptor_007ba1c3d6266d56, []int{154} } func (m *MySQLStatementReset) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10733,7 +10841,7 @@ func (m *MySQLStatementFetch) Reset() { *m = MySQLStatementFetch{} } func (m *MySQLStatementFetch) String() string { return proto.CompactTextString(m) } func (*MySQLStatementFetch) ProtoMessage() {} func (*MySQLStatementFetch) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{153} + return fileDescriptor_007ba1c3d6266d56, []int{155} } func (m *MySQLStatementFetch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10786,7 +10894,7 @@ func (m *MySQLStatementBulkExecute) Reset() { *m = MySQLStatementBulkExe func (m *MySQLStatementBulkExecute) String() string { return proto.CompactTextString(m) } func (*MySQLStatementBulkExecute) ProtoMessage() {} func (*MySQLStatementBulkExecute) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{154} + return fileDescriptor_007ba1c3d6266d56, []int{156} } func (m *MySQLStatementBulkExecute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10837,7 +10945,7 @@ func (m *MySQLInitDB) Reset() { *m = MySQLInitDB{} } func (m *MySQLInitDB) String() string { return proto.CompactTextString(m) } func (*MySQLInitDB) ProtoMessage() {} func (*MySQLInitDB) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{155} + return fileDescriptor_007ba1c3d6266d56, []int{157} } func (m *MySQLInitDB) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10887,7 +10995,7 @@ func (m *MySQLCreateDB) Reset() { *m = MySQLCreateDB{} } func (m *MySQLCreateDB) String() string { return proto.CompactTextString(m) } func (*MySQLCreateDB) ProtoMessage() {} func (*MySQLCreateDB) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{156} + return fileDescriptor_007ba1c3d6266d56, []int{158} } func (m *MySQLCreateDB) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10937,7 +11045,7 @@ func (m *MySQLDropDB) Reset() { *m = MySQLDropDB{} } func (m *MySQLDropDB) String() string { return proto.CompactTextString(m) } func (*MySQLDropDB) ProtoMessage() {} func (*MySQLDropDB) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{157} + return fileDescriptor_007ba1c3d6266d56, []int{159} } func (m *MySQLDropDB) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10985,7 +11093,7 @@ func (m *MySQLShutDown) Reset() { *m = MySQLShutDown{} } func (m *MySQLShutDown) String() string { return proto.CompactTextString(m) } func (*MySQLShutDown) ProtoMessage() {} func (*MySQLShutDown) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{158} + return fileDescriptor_007ba1c3d6266d56, []int{160} } func (m *MySQLShutDown) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11036,7 +11144,7 @@ func (m *MySQLProcessKill) Reset() { *m = MySQLProcessKill{} } func (m *MySQLProcessKill) String() string { return proto.CompactTextString(m) } func (*MySQLProcessKill) ProtoMessage() {} func (*MySQLProcessKill) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{159} + return fileDescriptor_007ba1c3d6266d56, []int{161} } func (m *MySQLProcessKill) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11085,7 +11193,7 @@ func (m *MySQLDebug) Reset() { *m = MySQLDebug{} } func (m *MySQLDebug) String() string { return proto.CompactTextString(m) } func (*MySQLDebug) ProtoMessage() {} func (*MySQLDebug) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{160} + return fileDescriptor_007ba1c3d6266d56, []int{162} } func (m *MySQLDebug) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11135,7 +11243,7 @@ func (m *MySQLRefresh) Reset() { *m = MySQLRefresh{} } func (m *MySQLRefresh) String() string { return proto.CompactTextString(m) } func (*MySQLRefresh) ProtoMessage() {} func (*MySQLRefresh) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{161} + return fileDescriptor_007ba1c3d6266d56, []int{163} } func (m *MySQLRefresh) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11187,7 +11295,7 @@ func (m *SQLServerRPCRequest) Reset() { *m = SQLServerRPCRequest{} } func (m *SQLServerRPCRequest) String() string { return proto.CompactTextString(m) } func (*SQLServerRPCRequest) ProtoMessage() {} func (*SQLServerRPCRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{162} + return fileDescriptor_007ba1c3d6266d56, []int{164} } func (m *SQLServerRPCRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11237,7 +11345,7 @@ func (m *DatabaseSessionMalformedPacket) Reset() { *m = DatabaseSessionM func (m *DatabaseSessionMalformedPacket) String() string { return proto.CompactTextString(m) } func (*DatabaseSessionMalformedPacket) ProtoMessage() {} func (*DatabaseSessionMalformedPacket) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{163} + return fileDescriptor_007ba1c3d6266d56, []int{165} } func (m *DatabaseSessionMalformedPacket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11304,7 +11412,7 @@ func (m *ElasticsearchRequest) Reset() { *m = ElasticsearchRequest{} } func (m *ElasticsearchRequest) String() string { return proto.CompactTextString(m) } func (*ElasticsearchRequest) ProtoMessage() {} func (*ElasticsearchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{164} + return fileDescriptor_007ba1c3d6266d56, []int{166} } func (m *ElasticsearchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11370,7 +11478,7 @@ func (m *OpenSearchRequest) Reset() { *m = OpenSearchRequest{} } func (m *OpenSearchRequest) String() string { return proto.CompactTextString(m) } func (*OpenSearchRequest) ProtoMessage() {} func (*OpenSearchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{165} + return fileDescriptor_007ba1c3d6266d56, []int{167} } func (m *OpenSearchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11430,7 +11538,7 @@ func (m *DynamoDBRequest) Reset() { *m = DynamoDBRequest{} } func (m *DynamoDBRequest) String() string { return proto.CompactTextString(m) } func (*DynamoDBRequest) ProtoMessage() {} func (*DynamoDBRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{166} + return fileDescriptor_007ba1c3d6266d56, []int{168} } func (m *DynamoDBRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11496,7 +11604,7 @@ func (m *AppSessionDynamoDBRequest) Reset() { *m = AppSessionDynamoDBReq func (m *AppSessionDynamoDBRequest) String() string { return proto.CompactTextString(m) } func (*AppSessionDynamoDBRequest) ProtoMessage() {} func (*AppSessionDynamoDBRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{167} + return fileDescriptor_007ba1c3d6266d56, []int{169} } func (m *AppSessionDynamoDBRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11538,7 +11646,7 @@ func (m *UpgradeWindowStartMetadata) Reset() { *m = UpgradeWindowStartMe func (m *UpgradeWindowStartMetadata) String() string { return proto.CompactTextString(m) } func (*UpgradeWindowStartMetadata) ProtoMessage() {} func (*UpgradeWindowStartMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{168} + return fileDescriptor_007ba1c3d6266d56, []int{170} } func (m *UpgradeWindowStartMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11586,7 +11694,7 @@ func (m *UpgradeWindowStartUpdate) Reset() { *m = UpgradeWindowStartUpda func (m *UpgradeWindowStartUpdate) String() string { return proto.CompactTextString(m) } func (*UpgradeWindowStartUpdate) ProtoMessage() {} func (*UpgradeWindowStartUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{169} + return fileDescriptor_007ba1c3d6266d56, []int{171} } func (m *UpgradeWindowStartUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11633,7 +11741,7 @@ func (m *SessionRecordingAccess) Reset() { *m = SessionRecordingAccess{} func (m *SessionRecordingAccess) String() string { return proto.CompactTextString(m) } func (*SessionRecordingAccess) ProtoMessage() {} func (*SessionRecordingAccess) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{170} + return fileDescriptor_007ba1c3d6266d56, []int{172} } func (m *SessionRecordingAccess) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11675,7 +11783,7 @@ func (m *KubeClusterMetadata) Reset() { *m = KubeClusterMetadata{} } func (m *KubeClusterMetadata) String() string { return proto.CompactTextString(m) } func (*KubeClusterMetadata) ProtoMessage() {} func (*KubeClusterMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{171} + return fileDescriptor_007ba1c3d6266d56, []int{173} } func (m *KubeClusterMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11723,7 +11831,7 @@ func (m *KubernetesClusterCreate) Reset() { *m = KubernetesClusterCreate func (m *KubernetesClusterCreate) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterCreate) ProtoMessage() {} func (*KubernetesClusterCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{172} + return fileDescriptor_007ba1c3d6266d56, []int{174} } func (m *KubernetesClusterCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11771,7 +11879,7 @@ func (m *KubernetesClusterUpdate) Reset() { *m = KubernetesClusterUpdate func (m *KubernetesClusterUpdate) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterUpdate) ProtoMessage() {} func (*KubernetesClusterUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{173} + return fileDescriptor_007ba1c3d6266d56, []int{175} } func (m *KubernetesClusterUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11817,7 +11925,7 @@ func (m *KubernetesClusterDelete) Reset() { *m = KubernetesClusterDelete func (m *KubernetesClusterDelete) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterDelete) ProtoMessage() {} func (*KubernetesClusterDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{174} + return fileDescriptor_007ba1c3d6266d56, []int{176} } func (m *KubernetesClusterDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11880,7 +11988,7 @@ func (m *SSMRun) Reset() { *m = SSMRun{} } func (m *SSMRun) String() string { return proto.CompactTextString(m) } func (*SSMRun) ProtoMessage() {} func (*SSMRun) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{175} + return fileDescriptor_007ba1c3d6266d56, []int{177} } func (m *SSMRun) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11933,7 +12041,7 @@ func (m *CassandraPrepare) Reset() { *m = CassandraPrepare{} } func (m *CassandraPrepare) String() string { return proto.CompactTextString(m) } func (*CassandraPrepare) ProtoMessage() {} func (*CassandraPrepare) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{176} + return fileDescriptor_007ba1c3d6266d56, []int{178} } func (m *CassandraPrepare) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11983,7 +12091,7 @@ func (m *CassandraExecute) Reset() { *m = CassandraExecute{} } func (m *CassandraExecute) String() string { return proto.CompactTextString(m) } func (*CassandraExecute) ProtoMessage() {} func (*CassandraExecute) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{177} + return fileDescriptor_007ba1c3d6266d56, []int{179} } func (m *CassandraExecute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12039,7 +12147,7 @@ func (m *CassandraBatch) Reset() { *m = CassandraBatch{} } func (m *CassandraBatch) String() string { return proto.CompactTextString(m) } func (*CassandraBatch) ProtoMessage() {} func (*CassandraBatch) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{178} + return fileDescriptor_007ba1c3d6266d56, []int{180} } func (m *CassandraBatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12085,7 +12193,7 @@ func (m *CassandraBatch_BatchChild) Reset() { *m = CassandraBatch_BatchC func (m *CassandraBatch_BatchChild) String() string { return proto.CompactTextString(m) } func (*CassandraBatch_BatchChild) ProtoMessage() {} func (*CassandraBatch_BatchChild) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{178, 0} + return fileDescriptor_007ba1c3d6266d56, []int{180, 0} } func (m *CassandraBatch_BatchChild) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12129,7 +12237,7 @@ func (m *CassandraBatch_BatchChild_Value) Reset() { *m = CassandraBatch_ func (m *CassandraBatch_BatchChild_Value) String() string { return proto.CompactTextString(m) } func (*CassandraBatch_BatchChild_Value) ProtoMessage() {} func (*CassandraBatch_BatchChild_Value) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{178, 0, 0} + return fileDescriptor_007ba1c3d6266d56, []int{180, 0, 0} } func (m *CassandraBatch_BatchChild_Value) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12180,7 +12288,7 @@ func (m *CassandraRegister) Reset() { *m = CassandraRegister{} } func (m *CassandraRegister) String() string { return proto.CompactTextString(m) } func (*CassandraRegister) ProtoMessage() {} func (*CassandraRegister) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{179} + return fileDescriptor_007ba1c3d6266d56, []int{181} } func (m *CassandraRegister) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12226,7 +12334,7 @@ func (m *LoginRuleCreate) Reset() { *m = LoginRuleCreate{} } func (m *LoginRuleCreate) String() string { return proto.CompactTextString(m) } func (*LoginRuleCreate) ProtoMessage() {} func (*LoginRuleCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{180} + return fileDescriptor_007ba1c3d6266d56, []int{182} } func (m *LoginRuleCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12272,7 +12380,7 @@ func (m *LoginRuleDelete) Reset() { *m = LoginRuleDelete{} } func (m *LoginRuleDelete) String() string { return proto.CompactTextString(m) } func (*LoginRuleDelete) ProtoMessage() {} func (*LoginRuleDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{181} + return fileDescriptor_007ba1c3d6266d56, []int{183} } func (m *LoginRuleDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12322,7 +12430,7 @@ func (m *SAMLIdPAuthAttempt) Reset() { *m = SAMLIdPAuthAttempt{} } func (m *SAMLIdPAuthAttempt) String() string { return proto.CompactTextString(m) } func (*SAMLIdPAuthAttempt) ProtoMessage() {} func (*SAMLIdPAuthAttempt) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{182} + return fileDescriptor_007ba1c3d6266d56, []int{184} } func (m *SAMLIdPAuthAttempt) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12368,7 +12476,7 @@ func (m *SAMLIdPServiceProviderCreate) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderCreate) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderCreate) ProtoMessage() {} func (*SAMLIdPServiceProviderCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{183} + return fileDescriptor_007ba1c3d6266d56, []int{185} } func (m *SAMLIdPServiceProviderCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12414,7 +12522,7 @@ func (m *SAMLIdPServiceProviderUpdate) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderUpdate) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderUpdate) ProtoMessage() {} func (*SAMLIdPServiceProviderUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{184} + return fileDescriptor_007ba1c3d6266d56, []int{186} } func (m *SAMLIdPServiceProviderUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12460,7 +12568,7 @@ func (m *SAMLIdPServiceProviderDelete) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderDelete) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderDelete) ProtoMessage() {} func (*SAMLIdPServiceProviderDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{185} + return fileDescriptor_007ba1c3d6266d56, []int{187} } func (m *SAMLIdPServiceProviderDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12504,7 +12612,7 @@ func (m *SAMLIdPServiceProviderDeleteAll) Reset() { *m = SAMLIdPServiceP func (m *SAMLIdPServiceProviderDeleteAll) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderDeleteAll) ProtoMessage() {} func (*SAMLIdPServiceProviderDeleteAll) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{186} + return fileDescriptor_007ba1c3d6266d56, []int{188} } func (m *SAMLIdPServiceProviderDeleteAll) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12550,7 +12658,7 @@ func (m *OktaResourcesUpdate) Reset() { *m = OktaResourcesUpdate{} } func (m *OktaResourcesUpdate) String() string { return proto.CompactTextString(m) } func (*OktaResourcesUpdate) ProtoMessage() {} func (*OktaResourcesUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{187} + return fileDescriptor_007ba1c3d6266d56, []int{189} } func (m *OktaResourcesUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12596,7 +12704,7 @@ func (m *OktaSyncFailure) Reset() { *m = OktaSyncFailure{} } func (m *OktaSyncFailure) String() string { return proto.CompactTextString(m) } func (*OktaSyncFailure) ProtoMessage() {} func (*OktaSyncFailure) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{188} + return fileDescriptor_007ba1c3d6266d56, []int{190} } func (m *OktaSyncFailure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12646,7 +12754,7 @@ func (m *OktaAssignmentResult) Reset() { *m = OktaAssignmentResult{} } func (m *OktaAssignmentResult) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentResult) ProtoMessage() {} func (*OktaAssignmentResult) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{189} + return fileDescriptor_007ba1c3d6266d56, []int{191} } func (m *OktaAssignmentResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12692,7 +12800,7 @@ func (m *AccessListCreate) Reset() { *m = AccessListCreate{} } func (m *AccessListCreate) String() string { return proto.CompactTextString(m) } func (*AccessListCreate) ProtoMessage() {} func (*AccessListCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{190} + return fileDescriptor_007ba1c3d6266d56, []int{192} } func (m *AccessListCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12738,7 +12846,7 @@ func (m *AccessListUpdate) Reset() { *m = AccessListUpdate{} } func (m *AccessListUpdate) String() string { return proto.CompactTextString(m) } func (*AccessListUpdate) ProtoMessage() {} func (*AccessListUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{191} + return fileDescriptor_007ba1c3d6266d56, []int{193} } func (m *AccessListUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12784,7 +12892,7 @@ func (m *AccessListDelete) Reset() { *m = AccessListDelete{} } func (m *AccessListDelete) String() string { return proto.CompactTextString(m) } func (*AccessListDelete) ProtoMessage() {} func (*AccessListDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{192} + return fileDescriptor_007ba1c3d6266d56, []int{194} } func (m *AccessListDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12832,7 +12940,7 @@ func (m *AccessListMemberCreate) Reset() { *m = AccessListMemberCreate{} func (m *AccessListMemberCreate) String() string { return proto.CompactTextString(m) } func (*AccessListMemberCreate) ProtoMessage() {} func (*AccessListMemberCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{193} + return fileDescriptor_007ba1c3d6266d56, []int{195} } func (m *AccessListMemberCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12880,7 +12988,7 @@ func (m *AccessListMemberUpdate) Reset() { *m = AccessListMemberUpdate{} func (m *AccessListMemberUpdate) String() string { return proto.CompactTextString(m) } func (*AccessListMemberUpdate) ProtoMessage() {} func (*AccessListMemberUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{194} + return fileDescriptor_007ba1c3d6266d56, []int{196} } func (m *AccessListMemberUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12928,7 +13036,7 @@ func (m *AccessListMemberDelete) Reset() { *m = AccessListMemberDelete{} func (m *AccessListMemberDelete) String() string { return proto.CompactTextString(m) } func (*AccessListMemberDelete) ProtoMessage() {} func (*AccessListMemberDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{195} + return fileDescriptor_007ba1c3d6266d56, []int{197} } func (m *AccessListMemberDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12978,7 +13086,7 @@ func (m *AccessListMemberDeleteAllForAccessList) Reset() { func (m *AccessListMemberDeleteAllForAccessList) String() string { return proto.CompactTextString(m) } func (*AccessListMemberDeleteAllForAccessList) ProtoMessage() {} func (*AccessListMemberDeleteAllForAccessList) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{196} + return fileDescriptor_007ba1c3d6266d56, []int{198} } func (m *AccessListMemberDeleteAllForAccessList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13026,7 +13134,7 @@ func (m *AccessListReview) Reset() { *m = AccessListReview{} } func (m *AccessListReview) String() string { return proto.CompactTextString(m) } func (*AccessListReview) ProtoMessage() {} func (*AccessListReview) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{197} + return fileDescriptor_007ba1c3d6266d56, []int{199} } func (m *AccessListReview) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13074,7 +13182,7 @@ func (m *AuditQueryRun) Reset() { *m = AuditQueryRun{} } func (m *AuditQueryRun) String() string { return proto.CompactTextString(m) } func (*AuditQueryRun) ProtoMessage() {} func (*AuditQueryRun) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{198} + return fileDescriptor_007ba1c3d6266d56, []int{200} } func (m *AuditQueryRun) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13124,7 +13232,7 @@ func (m *AuditQueryDetails) Reset() { *m = AuditQueryDetails{} } func (m *AuditQueryDetails) String() string { return proto.CompactTextString(m) } func (*AuditQueryDetails) ProtoMessage() {} func (*AuditQueryDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{199} + return fileDescriptor_007ba1c3d6266d56, []int{201} } func (m *AuditQueryDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13180,7 +13288,7 @@ func (m *SecurityReportRun) Reset() { *m = SecurityReportRun{} } func (m *SecurityReportRun) String() string { return proto.CompactTextString(m) } func (*SecurityReportRun) ProtoMessage() {} func (*SecurityReportRun) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{200} + return fileDescriptor_007ba1c3d6266d56, []int{202} } func (m *SecurityReportRun) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13228,7 +13336,7 @@ func (m *ExternalAuditStorageEnable) Reset() { *m = ExternalAuditStorage func (m *ExternalAuditStorageEnable) String() string { return proto.CompactTextString(m) } func (*ExternalAuditStorageEnable) ProtoMessage() {} func (*ExternalAuditStorageEnable) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{201} + return fileDescriptor_007ba1c3d6266d56, []int{203} } func (m *ExternalAuditStorageEnable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13276,7 +13384,7 @@ func (m *ExternalAuditStorageDisable) Reset() { *m = ExternalAuditStorag func (m *ExternalAuditStorageDisable) String() string { return proto.CompactTextString(m) } func (*ExternalAuditStorageDisable) ProtoMessage() {} func (*ExternalAuditStorageDisable) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{202} + return fileDescriptor_007ba1c3d6266d56, []int{204} } func (m *ExternalAuditStorageDisable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13337,7 +13445,7 @@ func (m *ExternalAuditStorageDetails) Reset() { *m = ExternalAuditStorag func (m *ExternalAuditStorageDetails) String() string { return proto.CompactTextString(m) } func (*ExternalAuditStorageDetails) ProtoMessage() {} func (*ExternalAuditStorageDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{203} + return fileDescriptor_007ba1c3d6266d56, []int{205} } func (m *ExternalAuditStorageDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13395,7 +13503,7 @@ func (m *OktaAccessListSync) Reset() { *m = OktaAccessListSync{} } func (m *OktaAccessListSync) String() string { return proto.CompactTextString(m) } func (*OktaAccessListSync) ProtoMessage() {} func (*OktaAccessListSync) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{204} + return fileDescriptor_007ba1c3d6266d56, []int{206} } func (m *OktaAccessListSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13459,7 +13567,7 @@ func (m *OktaUserSync) Reset() { *m = OktaUserSync{} } func (m *OktaUserSync) String() string { return proto.CompactTextString(m) } func (*OktaUserSync) ProtoMessage() {} func (*OktaUserSync) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{205} + return fileDescriptor_007ba1c3d6266d56, []int{207} } func (m *OktaUserSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13523,7 +13631,7 @@ func (m *SPIFFESVIDIssued) Reset() { *m = SPIFFESVIDIssued{} } func (m *SPIFFESVIDIssued) String() string { return proto.CompactTextString(m) } func (*SPIFFESVIDIssued) ProtoMessage() {} func (*SPIFFESVIDIssued) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{206} + return fileDescriptor_007ba1c3d6266d56, []int{208} } func (m *SPIFFESVIDIssued) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13574,7 +13682,7 @@ func (m *AuthPreferenceUpdate) Reset() { *m = AuthPreferenceUpdate{} } func (m *AuthPreferenceUpdate) String() string { return proto.CompactTextString(m) } func (*AuthPreferenceUpdate) ProtoMessage() {} func (*AuthPreferenceUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{207} + return fileDescriptor_007ba1c3d6266d56, []int{209} } func (m *AuthPreferenceUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13622,7 +13730,7 @@ func (m *ClusterNetworkingConfigUpdate) Reset() { *m = ClusterNetworking func (m *ClusterNetworkingConfigUpdate) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigUpdate) ProtoMessage() {} func (*ClusterNetworkingConfigUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{208} + return fileDescriptor_007ba1c3d6266d56, []int{210} } func (m *ClusterNetworkingConfigUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13670,7 +13778,7 @@ func (m *SessionRecordingConfigUpdate) Reset() { *m = SessionRecordingCo func (m *SessionRecordingConfigUpdate) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigUpdate) ProtoMessage() {} func (*SessionRecordingConfigUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{209} + return fileDescriptor_007ba1c3d6266d56, []int{211} } func (m *SessionRecordingConfigUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13720,7 +13828,7 @@ func (m *AccessPathChanged) Reset() { *m = AccessPathChanged{} } func (m *AccessPathChanged) String() string { return proto.CompactTextString(m) } func (*AccessPathChanged) ProtoMessage() {} func (*AccessPathChanged) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{210} + return fileDescriptor_007ba1c3d6266d56, []int{212} } func (m *AccessPathChanged) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13774,7 +13882,7 @@ func (m *SpannerRPC) Reset() { *m = SpannerRPC{} } func (m *SpannerRPC) String() string { return proto.CompactTextString(m) } func (*SpannerRPC) ProtoMessage() {} func (*SpannerRPC) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{211} + return fileDescriptor_007ba1c3d6266d56, []int{213} } func (m *SpannerRPC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13822,7 +13930,7 @@ func (m *AccessGraphSettingsUpdate) Reset() { *m = AccessGraphSettingsUp func (m *AccessGraphSettingsUpdate) String() string { return proto.CompactTextString(m) } func (*AccessGraphSettingsUpdate) ProtoMessage() {} func (*AccessGraphSettingsUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{212} + return fileDescriptor_007ba1c3d6266d56, []int{214} } func (m *AccessGraphSettingsUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13870,7 +13978,7 @@ func (m *SPIFFEFederationCreate) Reset() { *m = SPIFFEFederationCreate{} func (m *SPIFFEFederationCreate) String() string { return proto.CompactTextString(m) } func (*SPIFFEFederationCreate) ProtoMessage() {} func (*SPIFFEFederationCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{213} + return fileDescriptor_007ba1c3d6266d56, []int{215} } func (m *SPIFFEFederationCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13918,7 +14026,7 @@ func (m *SPIFFEFederationDelete) Reset() { *m = SPIFFEFederationDelete{} func (m *SPIFFEFederationDelete) String() string { return proto.CompactTextString(m) } func (*SPIFFEFederationDelete) ProtoMessage() {} func (*SPIFFEFederationDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{214} + return fileDescriptor_007ba1c3d6266d56, []int{216} } func (m *SPIFFEFederationDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13956,7 +14064,9 @@ type AutoUpdateConfigCreate struct { // User is a common user event metadata UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` // ConnectionMetadata holds information about the connection - ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // Status indicates whether the creation was successful. + Status `protobuf:"bytes,5,opt,name=Status,proto3,embedded=Status" json:""` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -13966,7 +14076,7 @@ func (m *AutoUpdateConfigCreate) Reset() { *m = AutoUpdateConfigCreate{} func (m *AutoUpdateConfigCreate) String() string { return proto.CompactTextString(m) } func (*AutoUpdateConfigCreate) ProtoMessage() {} func (*AutoUpdateConfigCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{215} + return fileDescriptor_007ba1c3d6266d56, []int{217} } func (m *AutoUpdateConfigCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14004,7 +14114,9 @@ type AutoUpdateConfigUpdate struct { // User is a common user event metadata UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` // ConnectionMetadata holds information about the connection - ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,5,opt,name=Resource,proto3,embedded=Resource" json:""` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -14014,7 +14126,7 @@ func (m *AutoUpdateConfigUpdate) Reset() { *m = AutoUpdateConfigUpdate{} func (m *AutoUpdateConfigUpdate) String() string { return proto.CompactTextString(m) } func (*AutoUpdateConfigUpdate) ProtoMessage() {} func (*AutoUpdateConfigUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{216} + return fileDescriptor_007ba1c3d6266d56, []int{218} } func (m *AutoUpdateConfigUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14052,7 +14164,9 @@ type AutoUpdateConfigDelete struct { // User is a common user event metadata UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` // ConnectionMetadata holds information about the connection - ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // Status indicates whether the deletion was successful. + Status `protobuf:"bytes,5,opt,name=Status,proto3,embedded=Status" json:""` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -14062,7 +14176,7 @@ func (m *AutoUpdateConfigDelete) Reset() { *m = AutoUpdateConfigDelete{} func (m *AutoUpdateConfigDelete) String() string { return proto.CompactTextString(m) } func (*AutoUpdateConfigDelete) ProtoMessage() {} func (*AutoUpdateConfigDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{217} + return fileDescriptor_007ba1c3d6266d56, []int{219} } func (m *AutoUpdateConfigDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14100,7 +14214,9 @@ type AutoUpdateVersionCreate struct { // User is a common user event metadata UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` // ConnectionMetadata holds information about the connection - ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // Status indicates whether the creation was successful. + Status `protobuf:"bytes,5,opt,name=Status,proto3,embedded=Status" json:""` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -14110,7 +14226,7 @@ func (m *AutoUpdateVersionCreate) Reset() { *m = AutoUpdateVersionCreate func (m *AutoUpdateVersionCreate) String() string { return proto.CompactTextString(m) } func (*AutoUpdateVersionCreate) ProtoMessage() {} func (*AutoUpdateVersionCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{218} + return fileDescriptor_007ba1c3d6266d56, []int{220} } func (m *AutoUpdateVersionCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14148,7 +14264,9 @@ type AutoUpdateVersionUpdate struct { // User is a common user event metadata UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` // ConnectionMetadata holds information about the connection - ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,5,opt,name=Resource,proto3,embedded=Resource" json:""` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -14158,7 +14276,7 @@ func (m *AutoUpdateVersionUpdate) Reset() { *m = AutoUpdateVersionUpdate func (m *AutoUpdateVersionUpdate) String() string { return proto.CompactTextString(m) } func (*AutoUpdateVersionUpdate) ProtoMessage() {} func (*AutoUpdateVersionUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{219} + return fileDescriptor_007ba1c3d6266d56, []int{221} } func (m *AutoUpdateVersionUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14196,7 +14314,9 @@ type AutoUpdateVersionDelete struct { // User is a common user event metadata UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` // ConnectionMetadata holds information about the connection - ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // Status indicates whether the deletion was successful. + Status `protobuf:"bytes,5,opt,name=Status,proto3,embedded=Status" json:""` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -14206,7 +14326,7 @@ func (m *AutoUpdateVersionDelete) Reset() { *m = AutoUpdateVersionDelete func (m *AutoUpdateVersionDelete) String() string { return proto.CompactTextString(m) } func (*AutoUpdateVersionDelete) ProtoMessage() {} func (*AutoUpdateVersionDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{220} + return fileDescriptor_007ba1c3d6266d56, []int{222} } func (m *AutoUpdateVersionDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14256,7 +14376,7 @@ func (m *StaticHostUserCreate) Reset() { *m = StaticHostUserCreate{} } func (m *StaticHostUserCreate) String() string { return proto.CompactTextString(m) } func (*StaticHostUserCreate) ProtoMessage() {} func (*StaticHostUserCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{221} + return fileDescriptor_007ba1c3d6266d56, []int{223} } func (m *StaticHostUserCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14306,7 +14426,7 @@ func (m *StaticHostUserUpdate) Reset() { *m = StaticHostUserUpdate{} } func (m *StaticHostUserUpdate) String() string { return proto.CompactTextString(m) } func (*StaticHostUserUpdate) ProtoMessage() {} func (*StaticHostUserUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{222} + return fileDescriptor_007ba1c3d6266d56, []int{224} } func (m *StaticHostUserUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14356,7 +14476,7 @@ func (m *StaticHostUserDelete) Reset() { *m = StaticHostUserDelete{} } func (m *StaticHostUserDelete) String() string { return proto.CompactTextString(m) } func (*StaticHostUserDelete) ProtoMessage() {} func (*StaticHostUserDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{223} + return fileDescriptor_007ba1c3d6266d56, []int{225} } func (m *StaticHostUserDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14408,7 +14528,7 @@ func (m *CrownJewelCreate) Reset() { *m = CrownJewelCreate{} } func (m *CrownJewelCreate) String() string { return proto.CompactTextString(m) } func (*CrownJewelCreate) ProtoMessage() {} func (*CrownJewelCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{224} + return fileDescriptor_007ba1c3d6266d56, []int{226} } func (m *CrownJewelCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14462,7 +14582,7 @@ func (m *CrownJewelUpdate) Reset() { *m = CrownJewelUpdate{} } func (m *CrownJewelUpdate) String() string { return proto.CompactTextString(m) } func (*CrownJewelUpdate) ProtoMessage() {} func (*CrownJewelUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{225} + return fileDescriptor_007ba1c3d6266d56, []int{227} } func (m *CrownJewelUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14512,7 +14632,7 @@ func (m *CrownJewelDelete) Reset() { *m = CrownJewelDelete{} } func (m *CrownJewelDelete) String() string { return proto.CompactTextString(m) } func (*CrownJewelDelete) ProtoMessage() {} func (*CrownJewelDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{226} + return fileDescriptor_007ba1c3d6266d56, []int{228} } func (m *CrownJewelDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14564,7 +14684,7 @@ func (m *UserTaskCreate) Reset() { *m = UserTaskCreate{} } func (m *UserTaskCreate) String() string { return proto.CompactTextString(m) } func (*UserTaskCreate) ProtoMessage() {} func (*UserTaskCreate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{227} + return fileDescriptor_007ba1c3d6266d56, []int{229} } func (m *UserTaskCreate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14620,7 +14740,7 @@ func (m *UserTaskUpdate) Reset() { *m = UserTaskUpdate{} } func (m *UserTaskUpdate) String() string { return proto.CompactTextString(m) } func (*UserTaskUpdate) ProtoMessage() {} func (*UserTaskUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{228} + return fileDescriptor_007ba1c3d6266d56, []int{230} } func (m *UserTaskUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14666,7 +14786,7 @@ func (m *UserTaskMetadata) Reset() { *m = UserTaskMetadata{} } func (m *UserTaskMetadata) String() string { return proto.CompactTextString(m) } func (*UserTaskMetadata) ProtoMessage() {} func (*UserTaskMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{229} + return fileDescriptor_007ba1c3d6266d56, []int{231} } func (m *UserTaskMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14716,7 +14836,7 @@ func (m *UserTaskDelete) Reset() { *m = UserTaskDelete{} } func (m *UserTaskDelete) String() string { return proto.CompactTextString(m) } func (*UserTaskDelete) ProtoMessage() {} func (*UserTaskDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_007ba1c3d6266d56, []int{230} + return fileDescriptor_007ba1c3d6266d56, []int{232} } func (m *UserTaskDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14815,6 +14935,8 @@ func init() { proto.RegisterType((*SCP)(nil), "events.SCP") proto.RegisterType((*SFTPAttributes)(nil), "events.SFTPAttributes") proto.RegisterType((*SFTP)(nil), "events.SFTP") + proto.RegisterType((*SFTPSummary)(nil), "events.SFTPSummary") + proto.RegisterType((*FileTransferStat)(nil), "events.FileTransferStat") proto.RegisterType((*Subsystem)(nil), "events.Subsystem") proto.RegisterType((*ClientDisconnect)(nil), "events.ClientDisconnect") proto.RegisterType((*AuthAttempt)(nil), "events.AuthAttempt") @@ -15007,1048 +15129,1057 @@ func init() { } var fileDescriptor_007ba1c3d6266d56 = []byte{ - // 16650 bytes of a gzipped FileDescriptorProto + // 16794 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x78, 0x24, 0x49, - 0x72, 0x18, 0x86, 0x7e, 0xa0, 0xd1, 0x08, 0x3c, 0x06, 0x93, 0xf3, 0xaa, 0x99, 0x9d, 0x5d, 0xec, - 0xd6, 0xde, 0xcd, 0xcd, 0xec, 0xed, 0xce, 0xdc, 0xce, 0xce, 0xee, 0xde, 0xbe, 0x6e, 0xaf, 0x81, - 0x06, 0x06, 0x3d, 0x83, 0xd7, 0x56, 0x63, 0x66, 0x6e, 0x8f, 0xbc, 0x6b, 0x16, 0xba, 0x12, 0x40, - 0xed, 0x74, 0x57, 0x35, 0xab, 0xaa, 0x07, 0x83, 0xf5, 0x8b, 0x27, 0x53, 0x14, 0x29, 0xee, 0x9d, - 0xce, 0x47, 0x53, 0xa4, 0x44, 0xd9, 0x22, 0xf5, 0xb0, 0x29, 0x9a, 0x22, 0x45, 0x89, 0x26, 0x79, - 0x24, 0xcf, 0x96, 0x7c, 0x7e, 0xac, 0xc4, 0xcf, 0xfc, 0x24, 0xd9, 0xd6, 0xa7, 0xcf, 0x96, 0x71, - 0x32, 0x6d, 0xfd, 0xc1, 0x67, 0x7f, 0x1f, 0x6d, 0xdf, 0x67, 0x9d, 0x65, 0xd9, 0x9f, 0xbf, 0x8c, - 0xcc, 0xaa, 0xca, 0x7a, 0x35, 0x9e, 0x2b, 0x2c, 0x16, 0xf8, 0x33, 0x83, 0x8e, 0x88, 0x8c, 0xcc, - 0x8a, 0x8c, 0xcc, 0x8c, 0xcc, 0x8c, 0x8c, 0x80, 0x6b, 0x1e, 0x6d, 0xd1, 0x8e, 0xed, 0x78, 0x37, - 0x5a, 0x74, 0x55, 0x6f, 0x6e, 0xdc, 0xf0, 0x36, 0x3a, 0xd4, 0xbd, 0x41, 0x1f, 0x51, 0xcb, 0xf3, - 0xff, 0xbb, 0xde, 0x71, 0x6c, 0xcf, 0x26, 0x25, 0xfe, 0xeb, 0xd2, 0xd9, 0x55, 0x7b, 0xd5, 0x46, - 0xd0, 0x0d, 0xf6, 0x17, 0xc7, 0x5e, 0xba, 0xbc, 0x6a, 0xdb, 0xab, 0x2d, 0x7a, 0x03, 0x7f, 0x2d, - 0x77, 0x57, 0x6e, 0xb8, 0x9e, 0xd3, 0x6d, 0x7a, 0x02, 0x3b, 0x1e, 0xc7, 0x7a, 0x66, 0x9b, 0xba, - 0x9e, 0xde, 0xee, 0x08, 0x82, 0xa7, 0xe2, 0x04, 0xeb, 0x8e, 0xde, 0xe9, 0x50, 0x47, 0x54, 0x7e, - 0xe9, 0x99, 0xf4, 0x76, 0xe2, 0xbf, 0x82, 0xe4, 0x85, 0x74, 0x12, 0x9f, 0x51, 0x8c, 0xa3, 0xfa, - 0xad, 0x3c, 0x94, 0xe7, 0xa8, 0xa7, 0x1b, 0xba, 0xa7, 0x93, 0xcb, 0xd0, 0x5f, 0xb3, 0x0c, 0xfa, - 0x58, 0xc9, 0x3d, 0x9d, 0xbb, 0x5a, 0x98, 0x28, 0x6d, 0x6d, 0x8e, 0xe7, 0xa9, 0xa9, 0x71, 0x20, - 0x79, 0x12, 0x8a, 0x4b, 0x1b, 0x1d, 0xaa, 0xe4, 0x9f, 0xce, 0x5d, 0x1d, 0x9c, 0x18, 0xdc, 0xda, - 0x1c, 0xef, 0x47, 0x59, 0x68, 0x08, 0x26, 0xcf, 0x40, 0xbe, 0x56, 0x55, 0x0a, 0x88, 0x3c, 0xbd, - 0xb5, 0x39, 0x3e, 0xd2, 0x35, 0x8d, 0xe7, 0xed, 0xb6, 0xe9, 0xd1, 0x76, 0xc7, 0xdb, 0xd0, 0xf2, - 0xb5, 0x2a, 0xb9, 0x02, 0xc5, 0x49, 0xdb, 0xa0, 0x4a, 0x11, 0x89, 0xc8, 0xd6, 0xe6, 0xf8, 0x68, - 0xd3, 0x36, 0xa8, 0x44, 0x85, 0x78, 0xf2, 0x45, 0x28, 0x2e, 0x99, 0x6d, 0xaa, 0xf4, 0x3f, 0x9d, - 0xbb, 0x3a, 0x74, 0xf3, 0xd2, 0x75, 0x2e, 0x95, 0xeb, 0xbe, 0x54, 0xae, 0x2f, 0xf9, 0x62, 0x9b, - 0x18, 0xfb, 0x70, 0x73, 0xbc, 0x6f, 0x6b, 0x73, 0xbc, 0xc8, 0x24, 0xf9, 0xcd, 0xef, 0x8d, 0xe7, - 0x34, 0x2c, 0x49, 0xde, 0x84, 0xa1, 0xc9, 0x56, 0xd7, 0xf5, 0xa8, 0x33, 0xaf, 0xb7, 0xa9, 0x52, - 0xc2, 0x0a, 0x2f, 0x6d, 0x6d, 0x8e, 0x9f, 0x6f, 0x72, 0x70, 0xc3, 0xd2, 0xdb, 0x72, 0xc5, 0x32, - 0xb9, 0xfa, 0x3b, 0x39, 0x38, 0x55, 0xa7, 0xae, 0x6b, 0xda, 0x56, 0x20, 0x9b, 0x4f, 0xc3, 0xa0, - 0x00, 0xd5, 0xaa, 0x28, 0x9f, 0xc1, 0x89, 0x81, 0xad, 0xcd, 0xf1, 0x82, 0x6b, 0x1a, 0x5a, 0x88, - 0x21, 0x9f, 0x83, 0x81, 0x07, 0xa6, 0xb7, 0x36, 0x37, 0x5d, 0x11, 0x72, 0x3a, 0xbf, 0xb5, 0x39, - 0x4e, 0xd6, 0x4d, 0x6f, 0xad, 0xd1, 0x5e, 0xd1, 0xa5, 0x0a, 0x7d, 0x32, 0x32, 0x0b, 0x63, 0x8b, - 0x8e, 0xf9, 0x48, 0xf7, 0xe8, 0x5d, 0xba, 0xb1, 0x68, 0xb7, 0xcc, 0xe6, 0x86, 0x90, 0xe2, 0xd3, - 0x5b, 0x9b, 0xe3, 0x97, 0x3b, 0x1c, 0xd7, 0x78, 0x48, 0x37, 0x1a, 0x1d, 0xc4, 0x4a, 0x4c, 0x12, - 0x25, 0xd5, 0xdf, 0x2d, 0xc1, 0xf0, 0x3d, 0x97, 0x3a, 0x41, 0xbb, 0xaf, 0x40, 0x91, 0xfd, 0x16, - 0x4d, 0x46, 0x99, 0x77, 0x5d, 0xea, 0xc8, 0x32, 0x67, 0x78, 0x72, 0x0d, 0xfa, 0x67, 0xed, 0x55, - 0xd3, 0x12, 0xcd, 0x3e, 0xb3, 0xb5, 0x39, 0x7e, 0xaa, 0xc5, 0x00, 0x12, 0x25, 0xa7, 0x20, 0x5f, - 0x80, 0xe1, 0x5a, 0x9b, 0xe9, 0x90, 0x6d, 0xe9, 0x9e, 0xed, 0x88, 0xd6, 0xa2, 0x74, 0x4d, 0x09, - 0x2e, 0x15, 0x8c, 0xd0, 0x93, 0xd7, 0x01, 0x2a, 0x0f, 0xea, 0x9a, 0xdd, 0xa2, 0x15, 0x6d, 0x5e, - 0x28, 0x03, 0x96, 0xd6, 0xd7, 0xdd, 0x86, 0x63, 0xb7, 0x68, 0x43, 0x77, 0xe4, 0x6a, 0x25, 0x6a, - 0x32, 0x05, 0xa3, 0x95, 0x66, 0x93, 0xba, 0xae, 0x46, 0x7f, 0xb4, 0x4b, 0x5d, 0xcf, 0x55, 0xfa, - 0x9f, 0x2e, 0x5c, 0x1d, 0x9c, 0x78, 0x72, 0x6b, 0x73, 0xfc, 0xa2, 0x8e, 0x98, 0x86, 0x23, 0x50, - 0x12, 0x8b, 0x58, 0x21, 0x32, 0x01, 0x23, 0x95, 0xf7, 0xbb, 0x0e, 0xad, 0x19, 0xd4, 0xf2, 0x4c, - 0x6f, 0x43, 0x68, 0xc8, 0xe5, 0xad, 0xcd, 0x71, 0x45, 0x67, 0x88, 0x86, 0x29, 0x30, 0x12, 0x93, - 0x68, 0x11, 0xb2, 0x00, 0xa7, 0x6f, 0x4f, 0x2e, 0xd6, 0xa9, 0xf3, 0xc8, 0x6c, 0xd2, 0x4a, 0xb3, - 0x69, 0x77, 0x2d, 0x4f, 0x19, 0x40, 0x3e, 0xcf, 0x6c, 0x6d, 0x8e, 0x3f, 0xb9, 0xda, 0xec, 0x34, - 0x5c, 0x8e, 0x6d, 0xe8, 0x1c, 0x2d, 0x31, 0x4b, 0x96, 0x25, 0x5f, 0x86, 0x91, 0x25, 0x87, 0x69, - 0xa1, 0x51, 0xa5, 0x0c, 0xae, 0x94, 0x51, 0xff, 0xcf, 0x5f, 0x17, 0x13, 0x10, 0x87, 0xfa, 0x3d, - 0xcb, 0x1b, 0xeb, 0xf1, 0x02, 0x0d, 0x03, 0x71, 0x72, 0x63, 0x23, 0xac, 0x08, 0x05, 0x85, 0x7d, - 0xbc, 0xe9, 0x50, 0x23, 0xa1, 0x6d, 0x83, 0xd8, 0xe6, 0x6b, 0x5b, 0x9b, 0xe3, 0x9f, 0x76, 0x04, - 0x4d, 0xa3, 0xa7, 0xda, 0x65, 0xb2, 0x22, 0x53, 0x50, 0x66, 0xda, 0x74, 0xd7, 0xb4, 0x0c, 0x05, - 0x9e, 0xce, 0x5d, 0x1d, 0xbd, 0x39, 0xe6, 0xb7, 0xde, 0x87, 0x4f, 0x5c, 0xd8, 0xda, 0x1c, 0x3f, - 0xc3, 0x74, 0xb0, 0xf1, 0xd0, 0xb4, 0xe4, 0x29, 0x22, 0x28, 0xca, 0x46, 0xd1, 0x84, 0xed, 0xe1, - 0xd0, 0x1d, 0x0a, 0x47, 0xd1, 0xb2, 0xed, 0xc5, 0x87, 0xad, 0x4f, 0x46, 0x26, 0x61, 0x64, 0xc2, - 0xf6, 0x6a, 0x96, 0xeb, 0xe9, 0x56, 0x93, 0xd6, 0xaa, 0xca, 0x30, 0x96, 0x43, 0xb5, 0x60, 0xe5, - 0x4c, 0x81, 0x69, 0x44, 0x26, 0xa5, 0x68, 0x19, 0xf5, 0x9f, 0x17, 0x61, 0x94, 0xf5, 0x89, 0x34, - 0x7c, 0x2a, 0x6c, 0x26, 0x60, 0x10, 0x56, 0x8b, 0xdb, 0xd1, 0x9b, 0x54, 0x8c, 0x24, 0xfc, 0x0a, - 0xcb, 0x07, 0x4a, 0x3c, 0xe3, 0xf4, 0xe4, 0x1a, 0x94, 0x39, 0xa8, 0x56, 0x15, 0x83, 0x6b, 0x64, - 0x6b, 0x73, 0x7c, 0xd0, 0x45, 0x58, 0xc3, 0x34, 0xb4, 0x00, 0xcd, 0xb4, 0x9b, 0xff, 0x3d, 0x63, - 0xbb, 0x1e, 0x63, 0x2e, 0xc6, 0x16, 0x7e, 0x86, 0x28, 0xb0, 0x26, 0x50, 0xb2, 0x76, 0x47, 0x0b, - 0x91, 0xd7, 0x00, 0x38, 0xa4, 0x62, 0x18, 0x8e, 0x18, 0x60, 0x17, 0xb7, 0x36, 0xc7, 0xcf, 0x09, - 0x16, 0xba, 0x61, 0xc8, 0xa3, 0x53, 0x22, 0x26, 0x6d, 0x18, 0xe6, 0xbf, 0x66, 0xf5, 0x65, 0xda, - 0xe2, 0xa3, 0x6b, 0xe8, 0xe6, 0x55, 0xbf, 0x13, 0xa3, 0xd2, 0xb9, 0x2e, 0x93, 0x4e, 0x59, 0x9e, - 0xb3, 0x31, 0x31, 0x2e, 0x26, 0xe4, 0x0b, 0xa2, 0xaa, 0x16, 0xe2, 0xe4, 0xa9, 0x40, 0x2e, 0xc3, - 0xe6, 0xe9, 0x69, 0xdb, 0x59, 0xd7, 0x1d, 0x83, 0x1a, 0x13, 0x1b, 0xf2, 0x3c, 0xbd, 0xe2, 0x83, - 0x1b, 0xcb, 0xb2, 0xea, 0xc9, 0xe4, 0xac, 0xd3, 0x39, 0xb7, 0x7a, 0x77, 0x19, 0x55, 0x6e, 0x20, - 0x21, 0x2d, 0xb7, 0xbb, 0x1c, 0x57, 0xb3, 0x68, 0x19, 0x36, 0x15, 0x70, 0xc0, 0x7d, 0xea, 0xb0, - 0x49, 0x1c, 0x47, 0x9d, 0x98, 0x0a, 0x04, 0x93, 0x47, 0x1c, 0x93, 0xe4, 0x21, 0x8a, 0x5c, 0x7a, - 0x1b, 0x4e, 0x27, 0x44, 0x41, 0xc6, 0xa0, 0xf0, 0x90, 0x6e, 0x70, 0x75, 0xd1, 0xd8, 0x9f, 0xe4, - 0x2c, 0xf4, 0x3f, 0xd2, 0x5b, 0x5d, 0xb1, 0x84, 0x6a, 0xfc, 0xc7, 0xeb, 0xf9, 0xcf, 0xe7, 0xd8, - 0x8a, 0x43, 0x26, 0x6d, 0xcb, 0xa2, 0x4d, 0x4f, 0x5e, 0x74, 0x5e, 0x81, 0xc1, 0x59, 0xbb, 0xa9, - 0xb7, 0xb0, 0x1f, 0xb9, 0xde, 0x29, 0x5b, 0x9b, 0xe3, 0x67, 0x59, 0x07, 0x5e, 0x6f, 0x31, 0x8c, - 0xd4, 0xa6, 0x90, 0x94, 0x29, 0x80, 0x46, 0xdb, 0xb6, 0x47, 0xb1, 0x60, 0x3e, 0x54, 0x00, 0x2c, - 0xe8, 0x20, 0x4a, 0x56, 0x80, 0x90, 0x98, 0xdc, 0x80, 0xf2, 0x22, 0x5b, 0x67, 0x9b, 0x76, 0x4b, - 0x28, 0x1f, 0x2e, 0x05, 0xb8, 0xf6, 0xca, 0x63, 0xd5, 0x27, 0x52, 0x67, 0x60, 0x74, 0xb2, 0x65, - 0x52, 0xcb, 0x93, 0x5b, 0xcd, 0x46, 0x72, 0x65, 0x95, 0x5a, 0x9e, 0xdc, 0x6a, 0x1c, 0xf3, 0x3a, - 0x83, 0xca, 0xad, 0x0e, 0x48, 0xd5, 0x3f, 0x2c, 0xc0, 0xc5, 0xbb, 0xdd, 0x65, 0xea, 0x58, 0xd4, - 0xa3, 0xae, 0x58, 0x90, 0x03, 0xae, 0xf3, 0x70, 0x3a, 0x81, 0x14, 0xdc, 0x71, 0xa1, 0x7c, 0x18, - 0x20, 0x1b, 0x62, 0x8d, 0x97, 0x67, 0xdb, 0x44, 0x51, 0x32, 0x03, 0xa7, 0x42, 0x20, 0x6b, 0x84, - 0xab, 0xe4, 0x71, 0x29, 0x79, 0x6a, 0x6b, 0x73, 0xfc, 0x92, 0xc4, 0x8d, 0x35, 0x5b, 0xd6, 0xe0, - 0x78, 0x31, 0x72, 0x17, 0xc6, 0x42, 0xd0, 0x6d, 0xc7, 0xee, 0x76, 0x5c, 0xa5, 0x80, 0xac, 0xc6, - 0xb7, 0x36, 0xc7, 0x9f, 0x90, 0x58, 0xad, 0x22, 0x52, 0x5e, 0xc0, 0xe3, 0x05, 0xc9, 0x8f, 0xe7, - 0x64, 0x6e, 0x62, 0x14, 0x16, 0x71, 0x14, 0xbe, 0xea, 0x8f, 0xc2, 0x4c, 0x21, 0x5d, 0x8f, 0x97, - 0x14, 0x83, 0x32, 0xd6, 0x8c, 0xc4, 0xa0, 0x4c, 0xd4, 0x78, 0x69, 0x12, 0xce, 0xa5, 0xf2, 0xda, - 0x95, 0x56, 0xff, 0xb3, 0x82, 0xcc, 0x65, 0xd1, 0x36, 0x82, 0xce, 0x5c, 0x90, 0x3b, 0x73, 0xd1, - 0x36, 0x70, 0xaa, 0xcf, 0x85, 0x6b, 0xa7, 0xd4, 0xd8, 0x8e, 0x6d, 0xc4, 0x67, 0xfd, 0x64, 0x59, - 0xf2, 0x55, 0x38, 0x9f, 0x00, 0xf2, 0xe9, 0x9a, 0x6b, 0xff, 0x95, 0xad, 0xcd, 0x71, 0x35, 0x85, - 0x6b, 0x7c, 0xf6, 0xce, 0xe0, 0x42, 0x74, 0xb8, 0x20, 0x49, 0xdd, 0xb6, 0x3c, 0xdd, 0xb4, 0x84, - 0x71, 0xc9, 0x47, 0xc9, 0x67, 0xb6, 0x36, 0xc7, 0x9f, 0x95, 0x75, 0xd0, 0xa7, 0x89, 0x37, 0x3e, - 0x8b, 0x0f, 0x31, 0x40, 0x49, 0x41, 0xd5, 0xda, 0xfa, 0xaa, 0x6f, 0x31, 0x5f, 0xdd, 0xda, 0x1c, - 0xff, 0x54, 0x6a, 0x1d, 0x26, 0xa3, 0x92, 0x57, 0xe8, 0x2c, 0x4e, 0x44, 0x03, 0x12, 0xe2, 0xe6, - 0x6d, 0x83, 0xe2, 0x37, 0xf4, 0x23, 0x7f, 0x75, 0x6b, 0x73, 0xfc, 0x29, 0x89, 0xbf, 0x65, 0x1b, - 0x34, 0xde, 0xfc, 0x94, 0xd2, 0xea, 0xef, 0x14, 0xe0, 0xa9, 0x7a, 0x65, 0x6e, 0xb6, 0x66, 0xf8, - 0x26, 0xcd, 0xa2, 0x63, 0x3f, 0x32, 0x0d, 0x69, 0xf4, 0x2e, 0xc3, 0x85, 0x18, 0x6a, 0x0a, 0xad, - 0xa8, 0xc0, 0x98, 0xc6, 0x6f, 0xf3, 0xcd, 0xa5, 0x8e, 0xa0, 0x69, 0x70, 0x53, 0x2b, 0xba, 0x68, - 0x67, 0x31, 0x62, 0x7d, 0x14, 0x43, 0xd5, 0xd7, 0x6c, 0xc7, 0x6b, 0x76, 0x3d, 0xa1, 0x04, 0xd8, - 0x47, 0x89, 0x3a, 0x5c, 0x41, 0xd4, 0xa3, 0x0a, 0x9f, 0x0f, 0xf9, 0xa9, 0x1c, 0x8c, 0x55, 0x3c, - 0xcf, 0x31, 0x97, 0xbb, 0x1e, 0x9d, 0xd3, 0x3b, 0x1d, 0xd3, 0x5a, 0xc5, 0xb1, 0x3e, 0x74, 0xf3, - 0xcd, 0x60, 0x8d, 0xec, 0x29, 0x89, 0xeb, 0xf1, 0xe2, 0xd2, 0x10, 0xd5, 0x7d, 0x54, 0xa3, 0xcd, - 0x71, 0xf2, 0x10, 0x8d, 0x97, 0x63, 0x43, 0x34, 0x95, 0xd7, 0xae, 0x86, 0xe8, 0xb7, 0x0a, 0x70, - 0x79, 0xe1, 0xa1, 0xa7, 0x6b, 0xd4, 0xb5, 0xbb, 0x4e, 0x93, 0xba, 0xf7, 0x3a, 0x86, 0xee, 0xd1, - 0x70, 0xa4, 0x8e, 0x43, 0x7f, 0xc5, 0x30, 0xa8, 0x81, 0xec, 0xfa, 0xf9, 0xb6, 0x4f, 0x67, 0x00, - 0x8d, 0xc3, 0xc9, 0xa7, 0x61, 0x40, 0x94, 0x41, 0xee, 0xfd, 0x13, 0x43, 0x5b, 0x9b, 0xe3, 0x03, - 0x5d, 0x0e, 0xd2, 0x7c, 0x1c, 0x23, 0xab, 0xd2, 0x16, 0x65, 0x64, 0x85, 0x90, 0xcc, 0xe0, 0x20, - 0xcd, 0xc7, 0x91, 0x77, 0x60, 0x14, 0xd9, 0x06, 0xed, 0x11, 0x73, 0xdf, 0x59, 0x5f, 0xba, 0x72, - 0x63, 0xf9, 0xd2, 0x84, 0xad, 0x69, 0x38, 0x7e, 0x01, 0x2d, 0xc6, 0x80, 0x3c, 0x80, 0x31, 0xd1, - 0x88, 0x90, 0x69, 0x7f, 0x0f, 0xa6, 0xe7, 0xb6, 0x36, 0xc7, 0x4f, 0x8b, 0xf6, 0x4b, 0x6c, 0x13, - 0x4c, 0x18, 0x63, 0xd1, 0xec, 0x90, 0x71, 0x69, 0x3b, 0xc6, 0xe2, 0x8b, 0x65, 0xc6, 0x71, 0x26, - 0xea, 0xbb, 0x30, 0x2c, 0x17, 0x24, 0xe7, 0x71, 0x6b, 0xcd, 0xc7, 0x09, 0x6e, 0xca, 0x4d, 0x03, - 0xf7, 0xd3, 0x2f, 0xc2, 0x50, 0x95, 0xba, 0x4d, 0xc7, 0xec, 0x30, 0xab, 0x41, 0x28, 0xf9, 0xa9, - 0xad, 0xcd, 0xf1, 0x21, 0x23, 0x04, 0x6b, 0x32, 0x8d, 0xfa, 0x7f, 0xe5, 0xe0, 0x3c, 0xe3, 0x5d, - 0x71, 0x5d, 0x73, 0xd5, 0x6a, 0xcb, 0xcb, 0xf6, 0xf3, 0x50, 0xaa, 0x63, 0x7d, 0xa2, 0xa6, 0xb3, - 0x5b, 0x9b, 0xe3, 0x63, 0xbc, 0x05, 0x92, 0x1e, 0x0a, 0x9a, 0x60, 0x5f, 0x99, 0xdf, 0x66, 0x5f, - 0xc9, 0x4c, 0x5a, 0x4f, 0x77, 0x3c, 0xd3, 0x5a, 0xad, 0x7b, 0xba, 0xd7, 0x75, 0x23, 0x26, 0xad, - 0xc0, 0x34, 0x5c, 0x44, 0x45, 0x4c, 0xda, 0x48, 0x21, 0xf2, 0x36, 0x0c, 0x4f, 0x59, 0x46, 0xc8, - 0x84, 0x4f, 0x88, 0x4f, 0x30, 0x4b, 0x93, 0x22, 0x3c, 0xc9, 0x22, 0x52, 0x40, 0xfd, 0xeb, 0x39, - 0x50, 0xf8, 0x26, 0x70, 0xd6, 0x74, 0xbd, 0x39, 0xda, 0x5e, 0x96, 0x66, 0xa7, 0x69, 0x7f, 0x57, - 0xc9, 0x70, 0xd2, 0x5a, 0x84, 0xa6, 0x80, 0xd8, 0x55, 0xb6, 0x4c, 0x37, 0xb1, 0xfd, 0x88, 0x95, - 0x22, 0x35, 0x18, 0xe0, 0x9c, 0xb9, 0x2d, 0x31, 0x74, 0x53, 0xf1, 0x15, 0x21, 0x5e, 0x35, 0x57, - 0x86, 0x36, 0x27, 0x96, 0x37, 0x34, 0xa2, 0xbc, 0xfa, 0x37, 0xf2, 0x30, 0x16, 0x2f, 0x44, 0x1e, - 0x40, 0xf9, 0x8e, 0x6d, 0x5a, 0xd4, 0x58, 0xb0, 0xb0, 0x85, 0xbd, 0x0f, 0x47, 0x7c, 0x5b, 0xfc, - 0xcc, 0x7b, 0x58, 0xa6, 0x21, 0x5b, 0xb0, 0x78, 0x56, 0x12, 0x30, 0x23, 0x5f, 0x86, 0x41, 0x66, - 0x03, 0x3e, 0x42, 0xce, 0xf9, 0x6d, 0x39, 0x3f, 0x2d, 0x38, 0x9f, 0x75, 0x78, 0xa1, 0x24, 0xeb, - 0x90, 0x1d, 0xd3, 0x2b, 0x8d, 0xea, 0xae, 0x6d, 0x89, 0x9e, 0x47, 0xbd, 0x72, 0x10, 0x22, 0xeb, - 0x15, 0xa7, 0x61, 0xa6, 0x2b, 0xff, 0x58, 0xec, 0x06, 0x69, 0xef, 0xc2, 0x65, 0x15, 0xef, 0x01, - 0x89, 0x58, 0xfd, 0x89, 0x3c, 0xbc, 0x10, 0x8a, 0x4c, 0xa3, 0x8f, 0x4c, 0xba, 0x2e, 0xc4, 0xb9, - 0x66, 0x76, 0xc4, 0x9e, 0x95, 0xa9, 0xbc, 0x3b, 0xb9, 0xa6, 0x5b, 0xab, 0xd4, 0x20, 0xd7, 0xa0, - 0x5f, 0xb3, 0x5b, 0xd4, 0x55, 0x72, 0x68, 0xae, 0xe1, 0x74, 0xe2, 0x30, 0x80, 0x7c, 0xe8, 0x81, - 0x14, 0xc4, 0x86, 0xd2, 0x92, 0xa3, 0x9b, 0x9e, 0xdf, 0xb3, 0x95, 0x64, 0xcf, 0xee, 0xa0, 0xc6, - 0xeb, 0x9c, 0x07, 0x9f, 0xf3, 0x51, 0x10, 0x1e, 0x02, 0x64, 0x41, 0x70, 0x92, 0x4b, 0xaf, 0xc1, - 0x90, 0x44, 0xbc, 0xab, 0x49, 0xfd, 0xdb, 0x45, 0x59, 0xd7, 0xfd, 0x66, 0x09, 0x5d, 0xbf, 0xc1, - 0x74, 0xd4, 0x75, 0x99, 0x55, 0xc1, 0x95, 0x5c, 0x68, 0x22, 0x82, 0xa2, 0x9a, 0x88, 0x20, 0xf2, - 0x12, 0x94, 0x39, 0x8b, 0x60, 0xff, 0x8a, 0x7b, 0x5f, 0x07, 0x61, 0xd1, 0xa5, 0x39, 0x20, 0x24, - 0xbf, 0x92, 0x83, 0x27, 0x7b, 0x4a, 0x02, 0x95, 0x61, 0xe8, 0xe6, 0xcb, 0x7b, 0x12, 0xe3, 0xc4, - 0x0b, 0x5b, 0x9b, 0xe3, 0xd7, 0xda, 0x01, 0x49, 0xc3, 0x91, 0x68, 0x1a, 0x4d, 0x4e, 0x24, 0xb5, - 0xab, 0x77, 0x53, 0x98, 0xf1, 0xc8, 0x2b, 0x9d, 0xc6, 0xa3, 0x23, 0xab, 0xb9, 0xe1, 0x37, 0xb2, - 0x18, 0x1a, 0x8f, 0xe2, 0x7b, 0x57, 0x7c, 0x92, 0x94, 0x6a, 0x32, 0xb8, 0x90, 0x26, 0x5c, 0xe0, - 0x98, 0xaa, 0xbe, 0xb1, 0xb0, 0x32, 0x67, 0x5b, 0xde, 0x9a, 0x5f, 0x41, 0xbf, 0x7c, 0xf6, 0x82, - 0x15, 0x18, 0xfa, 0x46, 0xc3, 0x5e, 0x69, 0xb4, 0x19, 0x55, 0x4a, 0x1d, 0x59, 0x9c, 0xd8, 0x44, - 0x2b, 0xc6, 0x9c, 0x3f, 0x05, 0x95, 0xc2, 0x93, 0x31, 0x7f, 0x9c, 0x26, 0x27, 0x9c, 0x58, 0x21, - 0xb5, 0x06, 0xc3, 0xb3, 0x76, 0xf3, 0x61, 0xa0, 0x2e, 0xaf, 0x41, 0x69, 0x49, 0x77, 0x56, 0xa9, - 0x87, 0xb2, 0x18, 0xba, 0x79, 0xfa, 0x3a, 0x3f, 0x6d, 0x66, 0x44, 0x1c, 0x31, 0x31, 0x2a, 0x66, - 0x83, 0x92, 0x87, 0xbf, 0x35, 0x51, 0x40, 0xfd, 0x5e, 0x3f, 0x0c, 0x8b, 0x93, 0x51, 0x9c, 0xcd, - 0xc9, 0xeb, 0xe1, 0x59, 0xb3, 0x98, 0xbe, 0x82, 0xd3, 0xa1, 0xe0, 0x54, 0x6b, 0x98, 0x31, 0xfb, - 0xfb, 0x9b, 0xe3, 0xb9, 0xad, 0xcd, 0xf1, 0x3e, 0xad, 0x2c, 0x6d, 0x2a, 0xc3, 0xf5, 0x46, 0x5a, - 0x60, 0xe5, 0xb3, 0xce, 0x58, 0x59, 0xbe, 0xfe, 0xbc, 0x0d, 0x03, 0xa2, 0x0d, 0x42, 0xe3, 0x2e, - 0x84, 0x67, 0x19, 0x91, 0x13, 0xde, 0x58, 0x69, 0xbf, 0x14, 0x79, 0x13, 0x4a, 0x7c, 0x6f, 0x2f, - 0x04, 0x70, 0x3e, 0xfd, 0x2c, 0x24, 0x56, 0x5c, 0x94, 0x21, 0x33, 0x00, 0xe1, 0xbe, 0x3e, 0x38, - 0xd0, 0x16, 0x1c, 0x92, 0x3b, 0xfe, 0x18, 0x17, 0xa9, 0x2c, 0x79, 0x05, 0x86, 0x97, 0xa8, 0xd3, - 0x36, 0x2d, 0xbd, 0x55, 0x37, 0xdf, 0xf7, 0xcf, 0xb4, 0x71, 0xe1, 0x75, 0xcd, 0xf7, 0xe5, 0x91, - 0x1b, 0xa1, 0x23, 0x5f, 0x49, 0xdb, 0x37, 0x0f, 0x60, 0x43, 0x9e, 0xd9, 0x76, 0x43, 0x19, 0x6b, - 0x4f, 0xca, 0x36, 0xfa, 0x1d, 0x18, 0x89, 0x6c, 0x99, 0xc4, 0xa1, 0xe5, 0x93, 0x49, 0xd6, 0xd2, - 0xfe, 0x2f, 0xc6, 0x36, 0xca, 0x81, 0x69, 0x72, 0xcd, 0x32, 0x3d, 0x53, 0x6f, 0x4d, 0xda, 0xed, - 0xb6, 0x6e, 0x19, 0xca, 0x60, 0xa8, 0xc9, 0x26, 0xc7, 0x34, 0x9a, 0x1c, 0x25, 0x6b, 0x72, 0xb4, - 0x10, 0xdb, 0x96, 0x8b, 0x3e, 0xd4, 0x68, 0xd3, 0x76, 0x98, 0x2d, 0x80, 0x67, 0x92, 0x62, 0x5b, - 0xee, 0x72, 0x5c, 0xc3, 0xf1, 0x91, 0xb2, 0xb1, 0x1d, 0x2f, 0x78, 0xa7, 0x58, 0x1e, 0x1a, 0x1b, - 0x8e, 0x1f, 0x23, 0xab, 0x7f, 0xad, 0x00, 0x43, 0x82, 0x94, 0x2d, 0xa5, 0x27, 0x0a, 0xbe, 0x1f, - 0x05, 0x4f, 0x55, 0xd4, 0xd2, 0x41, 0x29, 0xaa, 0xfa, 0x41, 0x3e, 0x98, 0x8d, 0x16, 0x1d, 0xd3, - 0xda, 0xdf, 0x6c, 0x74, 0x05, 0x60, 0x72, 0xad, 0x6b, 0x3d, 0xe4, 0xd7, 0x65, 0xf9, 0xf0, 0xba, - 0xac, 0x69, 0x6a, 0x12, 0x86, 0x3c, 0x09, 0xc5, 0x2a, 0xe3, 0xcf, 0x7a, 0x66, 0x78, 0x62, 0xf0, - 0x43, 0xce, 0x29, 0xf7, 0x82, 0x86, 0x60, 0xb6, 0xb9, 0x9a, 0xd8, 0xf0, 0x28, 0x37, 0x67, 0x0b, - 0x7c, 0x73, 0xb5, 0xcc, 0x00, 0x1a, 0x87, 0x93, 0x5b, 0x70, 0xba, 0x4a, 0x5b, 0xfa, 0xc6, 0x9c, - 0xd9, 0x6a, 0x99, 0x2e, 0x6d, 0xda, 0x96, 0xe1, 0xa2, 0x90, 0x45, 0x75, 0x6d, 0x57, 0x4b, 0x12, - 0x10, 0x15, 0x4a, 0x0b, 0x2b, 0x2b, 0x2e, 0xf5, 0x50, 0x7c, 0x85, 0x09, 0x60, 0x93, 0xb3, 0x8d, - 0x10, 0x4d, 0x60, 0xd4, 0x5f, 0xcf, 0xb1, 0xdd, 0x8b, 0xfb, 0xd0, 0xb3, 0x3b, 0x81, 0x96, 0xef, - 0x4b, 0x24, 0xd7, 0x42, 0xbb, 0x22, 0x8f, 0x5f, 0x7b, 0x4a, 0x7c, 0xed, 0x80, 0xb0, 0x2d, 0x42, - 0x8b, 0x22, 0xf5, 0xab, 0x0a, 0xdb, 0x7c, 0x95, 0xfa, 0xc7, 0x79, 0xb8, 0x20, 0x5a, 0x3c, 0xd9, - 0x32, 0x3b, 0xcb, 0xb6, 0xee, 0x18, 0x1a, 0x6d, 0x52, 0xf3, 0x11, 0x3d, 0x9a, 0x03, 0x2f, 0x3a, - 0x74, 0x8a, 0xfb, 0x18, 0x3a, 0x37, 0x71, 0x23, 0xc8, 0x24, 0x83, 0x07, 0xbe, 0xdc, 0xa8, 0x18, - 0xdb, 0xda, 0x1c, 0x1f, 0x36, 0x38, 0x18, 0x8f, 0xfc, 0x35, 0x99, 0x88, 0x29, 0xc9, 0x2c, 0xb5, - 0x56, 0xbd, 0x35, 0x54, 0x92, 0x7e, 0xae, 0x24, 0x2d, 0x84, 0x68, 0x02, 0xa3, 0xfe, 0x6f, 0x79, - 0x38, 0x1b, 0x17, 0x79, 0x9d, 0x5a, 0xc6, 0x89, 0xbc, 0x3f, 0x1a, 0x79, 0x7f, 0xbf, 0x00, 0x4f, - 0x88, 0x32, 0xf5, 0x35, 0xdd, 0xa1, 0x46, 0xd5, 0x74, 0x68, 0xd3, 0xb3, 0x9d, 0x8d, 0x23, 0x6c, - 0x40, 0x1d, 0x9c, 0xd8, 0x6f, 0x41, 0x49, 0x6c, 0xff, 0xf9, 0x3a, 0x33, 0x1a, 0xb4, 0x04, 0xa1, - 0x89, 0x15, 0x8a, 0x1f, 0x1d, 0xc4, 0x3a, 0xab, 0xb4, 0x93, 0xce, 0xfa, 0x3c, 0x8c, 0x04, 0xa2, - 0xc7, 0x8d, 0xe8, 0x40, 0x68, 0x6d, 0x19, 0x3e, 0x02, 0xf7, 0xa2, 0x5a, 0x94, 0x10, 0x6b, 0xf3, - 0x01, 0xb5, 0x2a, 0x5a, 0x43, 0x23, 0xa2, 0xb6, 0xa0, 0x9c, 0x69, 0x68, 0x32, 0x91, 0xba, 0x59, - 0x84, 0x4b, 0xe9, 0xdd, 0xae, 0x51, 0xdd, 0x38, 0xe9, 0xf5, 0x4f, 0x64, 0xaf, 0x93, 0x67, 0xa0, - 0xb8, 0xa8, 0x7b, 0x6b, 0xe2, 0xfa, 0x1d, 0xef, 0x84, 0x57, 0xcc, 0x16, 0x6d, 0x74, 0x74, 0x6f, - 0x4d, 0x43, 0x94, 0x34, 0x67, 0x00, 0x72, 0x4c, 0x99, 0x33, 0xa4, 0xc5, 0x7e, 0xe8, 0xe9, 0xdc, - 0xd5, 0x62, 0xea, 0x62, 0xff, 0xbd, 0x62, 0xd6, 0xbc, 0xf2, 0xc0, 0x31, 0x3d, 0x7a, 0xa2, 0x61, - 0x27, 0x1a, 0xb6, 0x4f, 0x0d, 0xfb, 0x87, 0x79, 0x18, 0x09, 0x36, 0x4d, 0xef, 0xd1, 0xe6, 0xe1, - 0xac, 0x55, 0xe1, 0x56, 0xa6, 0xb0, 0xef, 0xad, 0xcc, 0x7e, 0x14, 0x4a, 0x0d, 0x8e, 0x3c, 0xb9, - 0x69, 0x80, 0x12, 0xe3, 0x47, 0x9e, 0xc1, 0x41, 0xe7, 0x33, 0x30, 0x30, 0xa7, 0x3f, 0x36, 0xdb, - 0xdd, 0xb6, 0xb0, 0xd2, 0xd1, 0x9d, 0xac, 0xad, 0x3f, 0xd6, 0x7c, 0xb8, 0xfa, 0xdf, 0xe6, 0x60, - 0x54, 0x08, 0x55, 0x30, 0xdf, 0x97, 0x54, 0x43, 0xe9, 0xe4, 0xf7, 0x2d, 0x9d, 0xc2, 0xde, 0xa5, - 0xa3, 0xfe, 0x85, 0x02, 0x28, 0xd3, 0x66, 0x8b, 0x2e, 0x39, 0xba, 0xe5, 0xae, 0x50, 0x47, 0x6c, - 0xa7, 0xa7, 0x18, 0xab, 0x7d, 0x7d, 0xa0, 0x34, 0xa5, 0xe4, 0xf7, 0x34, 0xa5, 0x7c, 0x16, 0x06, - 0x45, 0x63, 0x02, 0x57, 0x46, 0x1c, 0x35, 0x8e, 0x0f, 0xd4, 0x42, 0x3c, 0x23, 0xae, 0x74, 0x3a, - 0x8e, 0xfd, 0x88, 0x3a, 0xfc, 0x96, 0x4a, 0x10, 0xeb, 0x3e, 0x50, 0x0b, 0xf1, 0x12, 0x67, 0xea, - 0xdb, 0x8b, 0x32, 0x67, 0xea, 0x68, 0x21, 0x9e, 0x5c, 0x85, 0xf2, 0xac, 0xdd, 0xd4, 0x51, 0xd0, - 0x7c, 0x5a, 0x19, 0xde, 0xda, 0x1c, 0x2f, 0xb7, 0x04, 0x4c, 0x0b, 0xb0, 0x8c, 0xb2, 0x6a, 0xaf, - 0x5b, 0x2d, 0x5b, 0xe7, 0xce, 0x2f, 0x65, 0x4e, 0x69, 0x08, 0x98, 0x16, 0x60, 0x19, 0x25, 0x93, - 0x39, 0x3a, 0x15, 0x95, 0x43, 0x9e, 0x2b, 0x02, 0xa6, 0x05, 0x58, 0xf5, 0xd7, 0x8b, 0x4c, 0x7b, - 0x5d, 0xf3, 0xfd, 0x63, 0xbf, 0x2e, 0x84, 0x03, 0xa6, 0x7f, 0x0f, 0x03, 0xe6, 0xd8, 0x1c, 0xd8, - 0xa9, 0xff, 0x7c, 0x00, 0x40, 0x48, 0x7f, 0xea, 0x64, 0x73, 0xb8, 0x3f, 0xad, 0xa9, 0xc2, 0xe9, - 0x29, 0x6b, 0x4d, 0xb7, 0x9a, 0xd4, 0x08, 0x8f, 0x2d, 0x4b, 0x38, 0xb4, 0xd1, 0x09, 0x92, 0x0a, - 0x64, 0x78, 0x6e, 0xa9, 0x25, 0x0b, 0x90, 0x17, 0x61, 0xa8, 0x66, 0x79, 0xd4, 0xd1, 0x9b, 0x9e, - 0xf9, 0x88, 0x8a, 0xa9, 0x01, 0x6f, 0x86, 0xcd, 0x10, 0xac, 0xc9, 0x34, 0xe4, 0x16, 0x0c, 0x2f, - 0xea, 0x8e, 0x67, 0x36, 0xcd, 0x8e, 0x6e, 0x79, 0xae, 0x52, 0xc6, 0x19, 0x0d, 0x2d, 0x8c, 0x8e, - 0x04, 0xd7, 0x22, 0x54, 0xe4, 0x2b, 0x30, 0x88, 0x5b, 0x53, 0xf4, 0xd7, 0x1e, 0xdc, 0xf6, 0xe2, - 0xf0, 0xd9, 0xd0, 0x3d, 0x90, 0x9f, 0xbe, 0xe2, 0x0d, 0x70, 0xfc, 0xee, 0x30, 0xe0, 0x48, 0xbe, - 0x04, 0x03, 0x53, 0x96, 0x81, 0xcc, 0x61, 0x5b, 0xe6, 0xaa, 0x60, 0x7e, 0x3e, 0x64, 0x6e, 0x77, - 0x62, 0xbc, 0x7d, 0x76, 0xe9, 0xa3, 0x6c, 0xe8, 0xa3, 0x1b, 0x65, 0xc3, 0x1f, 0xc1, 0xb1, 0xf8, - 0xc8, 0x41, 0x1d, 0x8b, 0x8f, 0xee, 0xf1, 0x58, 0x5c, 0x7d, 0x1f, 0x86, 0x26, 0x16, 0xa7, 0x83, - 0xd1, 0x7b, 0x11, 0x0a, 0x8b, 0xc2, 0x53, 0xa1, 0xc8, 0xed, 0x99, 0x8e, 0x69, 0x68, 0x0c, 0x46, - 0xae, 0x41, 0x79, 0x12, 0xdd, 0xdf, 0xc4, 0x2d, 0x62, 0x91, 0xaf, 0x7f, 0x4d, 0x84, 0xa1, 0x17, - 0xac, 0x8f, 0x26, 0x9f, 0x86, 0x81, 0x45, 0xc7, 0x5e, 0x75, 0xf4, 0xb6, 0x58, 0x83, 0xd1, 0x55, - 0xa4, 0xc3, 0x41, 0x9a, 0x8f, 0x53, 0x7f, 0x26, 0xe7, 0x9b, 0xed, 0xac, 0x44, 0xbd, 0x8b, 0x47, - 0xf3, 0x58, 0x77, 0x99, 0x97, 0x70, 0x39, 0x48, 0xf3, 0x71, 0xe4, 0x1a, 0xf4, 0x4f, 0x39, 0x8e, - 0xed, 0xc8, 0x3e, 0xee, 0x94, 0x01, 0xe4, 0xeb, 0x5e, 0xa4, 0x20, 0xaf, 0xc2, 0x10, 0x9f, 0x73, - 0xf8, 0x89, 0x66, 0xa1, 0xd7, 0x4d, 0xa9, 0x4c, 0xa9, 0x7e, 0xb7, 0x20, 0xd9, 0x6c, 0x5c, 0xe2, - 0xc7, 0xf0, 0x56, 0xe0, 0x25, 0x28, 0x4c, 0x2c, 0x4e, 0x8b, 0x09, 0xf0, 0x8c, 0x5f, 0x54, 0x52, - 0x95, 0x58, 0x39, 0x46, 0x4d, 0x2e, 0x43, 0x71, 0x91, 0xa9, 0x4f, 0x09, 0xd5, 0xa3, 0xbc, 0xb5, - 0x39, 0x5e, 0xec, 0x30, 0xfd, 0x41, 0x28, 0x62, 0xd9, 0x66, 0x86, 0xef, 0x98, 0x38, 0x36, 0xdc, - 0xc7, 0x5c, 0x86, 0x62, 0xc5, 0x59, 0x7d, 0x24, 0x66, 0x2d, 0xc4, 0xea, 0xce, 0xea, 0x23, 0x0d, - 0xa1, 0xe4, 0x06, 0x80, 0x46, 0xbd, 0xae, 0x63, 0xe1, 0xf3, 0x93, 0x41, 0x3c, 0x7f, 0xc3, 0xd9, - 0xd0, 0x41, 0x68, 0xa3, 0x69, 0x1b, 0x54, 0x93, 0x48, 0xd4, 0xbf, 0x1a, 0x5e, 0xec, 0x54, 0x4d, - 0xf7, 0xe1, 0x49, 0x17, 0xee, 0xa2, 0x0b, 0x75, 0x71, 0xc4, 0x99, 0xec, 0xa4, 0x71, 0xe8, 0x9f, - 0x6e, 0xe9, 0xab, 0x2e, 0xf6, 0xa1, 0xf0, 0x25, 0x5b, 0x61, 0x00, 0x8d, 0xc3, 0x63, 0xfd, 0x54, - 0xde, 0xbe, 0x9f, 0x7e, 0xae, 0x3f, 0x18, 0x6d, 0xf3, 0xd4, 0x5b, 0xb7, 0x9d, 0x93, 0xae, 0xda, - 0x69, 0x57, 0x5d, 0x81, 0x81, 0xba, 0xd3, 0x94, 0x8e, 0x2e, 0x70, 0x3f, 0xe0, 0x3a, 0x4d, 0x7e, - 0x6c, 0xe1, 0x23, 0x19, 0x5d, 0xd5, 0xf5, 0x90, 0x6e, 0x20, 0xa4, 0x33, 0x5c, 0x4f, 0xd0, 0x09, - 0xa4, 0xa0, 0x5b, 0xb4, 0x1d, 0x4f, 0x74, 0x5c, 0x40, 0xd7, 0xb1, 0x1d, 0x4f, 0xf3, 0x91, 0xe4, - 0xb3, 0x00, 0x4b, 0x93, 0x8b, 0xbe, 0xb3, 0xfd, 0x60, 0xe8, 0x0b, 0x28, 0xbc, 0xec, 0x35, 0x09, - 0x4d, 0x96, 0x60, 0x70, 0xa1, 0x43, 0x1d, 0xbe, 0x15, 0xe2, 0x0f, 0x4a, 0x3e, 0x13, 0x13, 0xad, - 0xe8, 0xf7, 0xeb, 0xe2, 0xff, 0x80, 0x9c, 0xaf, 0x2f, 0xb6, 0xff, 0x53, 0x0b, 0x19, 0x91, 0x57, - 0xa1, 0x54, 0xe1, 0x76, 0xde, 0x10, 0xb2, 0x0c, 0x44, 0x86, 0x5b, 0x50, 0x8e, 0xe2, 0x7b, 0x76, - 0x1d, 0xff, 0xd6, 0x04, 0xb9, 0x7a, 0x0d, 0xc6, 0xe2, 0xd5, 0x90, 0x21, 0x18, 0x98, 0x5c, 0x98, - 0x9f, 0x9f, 0x9a, 0x5c, 0x1a, 0xeb, 0x23, 0x65, 0x28, 0xd6, 0xa7, 0xe6, 0xab, 0x63, 0x39, 0xf5, - 0x57, 0xa5, 0x19, 0x84, 0xa9, 0xd6, 0xc9, 0xd5, 0xf0, 0xbe, 0xee, 0x5b, 0xc6, 0xf0, 0x3e, 0x14, - 0x4f, 0x0c, 0xda, 0xa6, 0xe7, 0x51, 0x43, 0xac, 0x12, 0x78, 0x5f, 0xe8, 0x3d, 0xd6, 0x12, 0x78, - 0xf2, 0x3c, 0x8c, 0x20, 0x4c, 0x5c, 0x11, 0xf2, 0xfd, 0xb1, 0x28, 0xe0, 0x3c, 0xd6, 0xa2, 0x48, - 0xf5, 0x0f, 0xc2, 0xdb, 0xe1, 0x59, 0xaa, 0x1f, 0xd5, 0x1b, 0xc5, 0x8f, 0x49, 0x7f, 0xa9, 0xff, - 0xb2, 0xc8, 0x9f, 0x80, 0xf0, 0xf7, 0x82, 0x87, 0x21, 0xca, 0xf0, 0x48, 0xb7, 0xb0, 0x8b, 0x23, - 0xdd, 0xe7, 0xa1, 0x34, 0x47, 0xbd, 0x35, 0xdb, 0x77, 0xfc, 0x42, 0x0f, 0xbd, 0x36, 0x42, 0x64, - 0x0f, 0x3d, 0x4e, 0x43, 0x1e, 0x02, 0xf1, 0x1f, 0x03, 0x06, 0x8e, 0xd8, 0xfe, 0x11, 0xf2, 0x85, - 0xc4, 0x3e, 0xa5, 0x8e, 0x2f, 0x81, 0xd1, 0xc7, 0xfe, 0x6c, 0xe0, 0xe8, 0x2d, 0x79, 0x62, 0xfd, - 0x8b, 0xcd, 0xf1, 0x12, 0xa7, 0xd1, 0x52, 0xd8, 0x92, 0x77, 0x60, 0x70, 0x6e, 0xba, 0x22, 0x1e, - 0x06, 0x72, 0xaf, 0x88, 0x8b, 0x81, 0x14, 0x7d, 0x44, 0x20, 0x12, 0x7c, 0x6f, 0xd3, 0x5e, 0xd1, - 0x93, 0xef, 0x02, 0x43, 0x2e, 0x4c, 0x5b, 0xf8, 0xcb, 0x1d, 0x71, 0xba, 0x10, 0x68, 0x4b, 0xf4, - 0x3d, 0x4f, 0x5c, 0x56, 0x1c, 0x1b, 0xd3, 0x96, 0xf2, 0x3e, 0x46, 0xf7, 0x02, 0x9c, 0xae, 0x74, - 0x3a, 0x2d, 0x93, 0x1a, 0xa8, 0x2f, 0x5a, 0xb7, 0x45, 0x5d, 0xe1, 0xf2, 0x83, 0x8f, 0x41, 0x74, - 0x8e, 0x6c, 0xe0, 0x73, 0xd4, 0x86, 0xd3, 0x8d, 0xfa, 0x67, 0x26, 0xcb, 0xaa, 0x7f, 0x36, 0x0f, - 0xe7, 0x27, 0x1d, 0xaa, 0x7b, 0x74, 0x6e, 0xba, 0x52, 0xe9, 0xa2, 0x8f, 0x5c, 0xab, 0x45, 0xad, - 0xd5, 0xc3, 0x19, 0xd6, 0x6f, 0xc0, 0x68, 0xd0, 0x80, 0x7a, 0xd3, 0xee, 0x50, 0xf9, 0x61, 0x55, - 0xd3, 0xc7, 0x34, 0x5c, 0x86, 0xd2, 0x62, 0xa4, 0xe4, 0x2e, 0x9c, 0x09, 0x20, 0x95, 0x56, 0xcb, - 0x5e, 0xd7, 0x68, 0xd7, 0xe5, 0x8e, 0xb1, 0x65, 0xee, 0x18, 0x1b, 0x72, 0xd0, 0x19, 0xbe, 0xe1, - 0x30, 0x02, 0x2d, 0xad, 0x94, 0xfa, 0x8b, 0x05, 0xb8, 0x70, 0x5f, 0x6f, 0x99, 0x46, 0x28, 0x1a, - 0x8d, 0xba, 0x1d, 0xdb, 0x72, 0xe9, 0x11, 0x1a, 0xa5, 0x91, 0xa1, 0x50, 0x3c, 0x90, 0xa1, 0x90, - 0xec, 0xa2, 0xfe, 0x7d, 0x77, 0x51, 0x69, 0x4f, 0x5d, 0xf4, 0xbf, 0xe6, 0x60, 0xcc, 0x77, 0xfc, - 0x97, 0x1f, 0x71, 0x4b, 0x5e, 0xe9, 0x78, 0x84, 0x18, 0xf3, 0x83, 0x46, 0x3c, 0xa9, 0xc3, 0xc0, - 0xd4, 0xe3, 0x8e, 0xe9, 0x50, 0x77, 0x07, 0x4e, 0xdc, 0x4f, 0x8a, 0xe3, 0x92, 0xd3, 0x94, 0x17, - 0x49, 0x9c, 0x94, 0x70, 0x30, 0x3e, 0xe7, 0xe3, 0x4f, 0x1f, 0x26, 0xfc, 0x97, 0xe9, 0xfc, 0x39, - 0x9f, 0x78, 0x22, 0x11, 0x79, 0x9f, 0x19, 0x92, 0x92, 0x67, 0xa1, 0xb0, 0xb4, 0x34, 0x2b, 0x66, - 0x52, 0x8c, 0x08, 0xe0, 0x79, 0xf2, 0x7b, 0x45, 0x86, 0x55, 0xff, 0x49, 0x1e, 0x80, 0xa9, 0x02, - 0x1f, 0xae, 0x87, 0xa2, 0x84, 0x13, 0x50, 0xf6, 0x05, 0x2e, 0xd4, 0x30, 0xf0, 0xda, 0x8f, 0x77, - 0x44, 0xbc, 0xee, 0xe0, 0x85, 0xc6, 0xb8, 0xef, 0x48, 0xce, 0xef, 0x01, 0x70, 0x67, 0x83, 0x8e, - 0xe4, 0xbe, 0xfb, 0xf8, 0x67, 0x61, 0x50, 0xcc, 0x78, 0x76, 0xe4, 0xfc, 0xbf, 0xe9, 0x03, 0xb5, - 0x10, 0x1f, 0x9b, 0x5a, 0x4b, 0xfb, 0x58, 0x88, 0x7d, 0xf1, 0xf2, 0x5e, 0x39, 0x11, 0xef, 0x01, - 0x8b, 0xf7, 0x1b, 0x42, 0xbc, 0xfc, 0x05, 0xcf, 0x91, 0x15, 0xef, 0x81, 0x9d, 0x7d, 0xab, 0xff, - 0x30, 0x07, 0x84, 0x35, 0x6b, 0x51, 0x77, 0xdd, 0x75, 0xdb, 0x31, 0xb8, 0x73, 0xfa, 0xa1, 0x08, - 0xe6, 0xe0, 0xee, 0x2b, 0xbf, 0x5b, 0x86, 0x33, 0x11, 0xc7, 0xdf, 0x23, 0x3e, 0x59, 0x5d, 0x8b, - 0x8e, 0xa6, 0x5e, 0xaf, 0x5e, 0x3e, 0x25, 0x5f, 0x88, 0xf6, 0x47, 0x1e, 0xa0, 0x49, 0x37, 0xa1, - 0x2f, 0xc0, 0xb0, 0xf8, 0xc1, 0x56, 0x68, 0xff, 0xa6, 0x0b, 0x47, 0xa9, 0xcb, 0x00, 0x5a, 0x04, - 0x4d, 0x5e, 0x86, 0x41, 0x36, 0x60, 0x56, 0x31, 0x78, 0xc8, 0x40, 0xf8, 0xa2, 0xc4, 0xf0, 0x81, - 0xf2, 0x7a, 0x12, 0x50, 0x4a, 0xef, 0x88, 0xca, 0x3b, 0x78, 0x47, 0xf4, 0x55, 0x18, 0xaa, 0x58, - 0x96, 0xed, 0xe1, 0x26, 0xdd, 0x15, 0x57, 0x13, 0x99, 0x56, 0xf9, 0xb3, 0xf8, 0x38, 0x3e, 0xa4, - 0x4f, 0x35, 0xcb, 0x65, 0x86, 0xe4, 0xa6, 0xff, 0x2a, 0x86, 0x3a, 0xc2, 0xab, 0x1c, 0xaf, 0x67, - 0x1c, 0x01, 0x4b, 0x3e, 0x8a, 0xc1, 0xce, 0x1b, 0x59, 0x74, 0xec, 0x8e, 0xed, 0x52, 0x83, 0x0b, - 0x6a, 0x28, 0x0c, 0x35, 0xd0, 0x11, 0x08, 0x7c, 0xc7, 0x16, 0x09, 0xe4, 0x11, 0x29, 0x42, 0x56, - 0xe0, 0xac, 0x7f, 0x51, 0x1c, 0xbc, 0x18, 0xac, 0x55, 0x5d, 0x65, 0x18, 0x5f, 0x25, 0x91, 0xb8, - 0x32, 0xd4, 0xaa, 0x13, 0x4f, 0xf9, 0xd7, 0x22, 0xfe, 0x93, 0xc3, 0x86, 0x69, 0xc8, 0x5d, 0x9d, - 0xca, 0x8f, 0xfc, 0x08, 0x0c, 0xcd, 0xe9, 0x8f, 0xab, 0x5d, 0x71, 0xf6, 0x32, 0xb2, 0xf3, 0xdb, - 0x97, 0xb6, 0xfe, 0xb8, 0x61, 0x88, 0x72, 0x31, 0x9b, 0x42, 0x66, 0x49, 0x1a, 0x70, 0x7e, 0xd1, - 0xb1, 0xdb, 0xb6, 0x47, 0x8d, 0xd8, 0xe3, 0xbb, 0x53, 0xe1, 0x6b, 0xdd, 0x8e, 0xa0, 0x68, 0xf4, - 0x78, 0x85, 0x97, 0xc1, 0x86, 0xb4, 0xe1, 0x54, 0xc5, 0x75, 0xbb, 0x6d, 0x1a, 0xde, 0x50, 0x8d, - 0x6d, 0xfb, 0x19, 0x9f, 0x11, 0x5e, 0xcb, 0x4f, 0xe8, 0x58, 0x94, 0x5f, 0x50, 0x35, 0x3c, 0x53, - 0xae, 0x11, 0xbf, 0x25, 0xce, 0xfb, 0x4e, 0xb1, 0x3c, 0x3a, 0x76, 0x4a, 0xbb, 0x90, 0x6c, 0xcc, - 0x92, 0xe9, 0xb5, 0xa8, 0xfa, 0x9d, 0x1c, 0x40, 0x28, 0x60, 0xf2, 0x42, 0x34, 0x42, 0x51, 0x2e, - 0xbc, 0xe8, 0x10, 0xd1, 0x0b, 0x22, 0x21, 0x89, 0xc8, 0x65, 0x28, 0x62, 0x84, 0x8b, 0x7c, 0x78, - 0xb0, 0xfa, 0xd0, 0xb4, 0x0c, 0x0d, 0xa1, 0x0c, 0x2b, 0x3d, 0x45, 0x47, 0x2c, 0x5e, 0xea, 0x73, - 0xab, 0xb0, 0x0a, 0xa7, 0xea, 0xdd, 0x65, 0xbf, 0x6e, 0xe9, 0x5d, 0x1d, 0x06, 0xda, 0x70, 0xbb, - 0xcb, 0xc1, 0x63, 0xd4, 0x48, 0x18, 0x93, 0x68, 0x11, 0xf5, 0xd7, 0x73, 0xb1, 0x59, 0xf0, 0x10, - 0x17, 0xbd, 0x4f, 0x25, 0xfd, 0x34, 0x92, 0xd3, 0x92, 0xfa, 0x17, 0xf3, 0x30, 0xb4, 0x68, 0x3b, - 0x9e, 0x08, 0x19, 0x72, 0xb4, 0x57, 0x21, 0x69, 0xaf, 0x54, 0xdc, 0xc5, 0x5e, 0xe9, 0x32, 0x14, - 0x25, 0x17, 0x65, 0x7e, 0x2f, 0x62, 0x18, 0x8e, 0x86, 0x50, 0xf5, 0xc7, 0xf2, 0x00, 0x5f, 0x7a, - 0xf1, 0xc5, 0x63, 0x2c, 0x20, 0xf5, 0x17, 0x72, 0x70, 0x4a, 0x5c, 0xd4, 0x49, 0xb1, 0xbe, 0x06, - 0xfc, 0x2b, 0x56, 0x79, 0x5c, 0x72, 0x90, 0xe6, 0xe3, 0xd8, 0x12, 0x30, 0xf5, 0xd8, 0xf4, 0xf0, - 0xae, 0x42, 0x0a, 0xf6, 0x45, 0x05, 0x4c, 0x5e, 0x02, 0x7c, 0x3a, 0xf2, 0x82, 0x7f, 0x05, 0x59, - 0x08, 0xd7, 0x3d, 0x56, 0x60, 0x2a, 0xf5, 0x1a, 0x52, 0xfd, 0xad, 0x22, 0x14, 0xa7, 0x1e, 0xd3, - 0xe6, 0x11, 0xef, 0x1a, 0xe9, 0x60, 0xb3, 0xb8, 0xcf, 0x83, 0xcd, 0xbd, 0xf8, 0x54, 0xbc, 0x1d, - 0xf6, 0x67, 0x29, 0x5a, 0x7d, 0xac, 0xe7, 0xe3, 0xd5, 0xfb, 0x3d, 0x7d, 0xf4, 0x5c, 0x72, 0xfe, - 0x8b, 0x02, 0x14, 0xea, 0x93, 0x8b, 0x27, 0x7a, 0x73, 0xa8, 0x7a, 0xd3, 0xfb, 0xce, 0x5a, 0x0d, - 0xae, 0xa1, 0xca, 0xa1, 0x97, 0x68, 0xec, 0xc6, 0xe9, 0xfb, 0x05, 0x18, 0xad, 0x4f, 0x2f, 0x2d, - 0x4a, 0x27, 0xc1, 0x77, 0xb9, 0x27, 0x1f, 0xfa, 0x94, 0xf1, 0x2e, 0xbd, 0x9c, 0xb0, 0x67, 0xee, - 0xd5, 0x2c, 0xef, 0x95, 0x5b, 0xf7, 0xf5, 0x56, 0x97, 0xe2, 0xd1, 0x0b, 0xf7, 0xfb, 0x75, 0xcd, - 0xf7, 0xe9, 0x2f, 0xe2, 0xc3, 0x7f, 0x9f, 0x01, 0x79, 0x03, 0x0a, 0xf7, 0x84, 0x47, 0x46, 0x16, - 0x9f, 0x97, 0x6e, 0x72, 0x3e, 0x6c, 0x12, 0x2c, 0x74, 0x4d, 0x03, 0x39, 0xb0, 0x52, 0xac, 0xf0, - 0x6d, 0xb1, 0x00, 0xef, 0xa8, 0xf0, 0xaa, 0x5f, 0xf8, 0x76, 0xad, 0x4a, 0xea, 0x30, 0xb4, 0x48, - 0x9d, 0xb6, 0x89, 0x1d, 0xe5, 0xcf, 0xd9, 0xbd, 0x99, 0xb0, 0x9d, 0xca, 0x50, 0x27, 0x2c, 0x84, - 0xcc, 0x64, 0x2e, 0xe4, 0x5d, 0x00, 0x6e, 0xa3, 0xec, 0x30, 0x7e, 0xe4, 0x93, 0x68, 0xf7, 0x73, - 0xd3, 0x32, 0xc5, 0xc6, 0x93, 0x98, 0x91, 0x87, 0x30, 0x36, 0x67, 0x1b, 0xe6, 0x8a, 0xc9, 0x5d, - 0x2f, 0xb1, 0x82, 0xd2, 0xf6, 0x0e, 0x4f, 0xcc, 0x94, 0x6c, 0x4b, 0xe5, 0xd2, 0xaa, 0x49, 0x30, - 0x56, 0xff, 0xd3, 0x7e, 0x28, 0xb2, 0x6e, 0x3f, 0x19, 0xbf, 0xfb, 0x19, 0xbf, 0x15, 0x18, 0x7b, - 0x60, 0x3b, 0x0f, 0x4d, 0x6b, 0x35, 0xf0, 0x8a, 0x17, 0x7b, 0x53, 0xf4, 0xe4, 0x59, 0xe7, 0xb8, - 0x46, 0xe0, 0x40, 0xaf, 0x25, 0xc8, 0xb7, 0x19, 0xc1, 0xaf, 0x01, 0xf0, 0xb7, 0xee, 0x48, 0x53, - 0x0e, 0x83, 0x55, 0xf0, 0x97, 0xf0, 0xe8, 0x68, 0x2f, 0x07, 0xab, 0x08, 0x89, 0xd9, 0x26, 0x9c, - 0xfb, 0x42, 0x0c, 0xa2, 0xdf, 0x3d, 0x6e, 0xc2, 0xd1, 0x17, 0x42, 0x36, 0x02, 0xb8, 0x57, 0xc4, - 0x22, 0x80, 0x74, 0xbf, 0x04, 0x31, 0x41, 0x44, 0x26, 0x07, 0x11, 0x1e, 0x2e, 0xe5, 0x7a, 0x49, - 0x93, 0x78, 0x90, 0x57, 0x62, 0x17, 0xe0, 0x24, 0xc2, 0x2d, 0xf3, 0xfe, 0x3b, 0x74, 0xa0, 0x1a, - 0xde, 0xce, 0x81, 0x4a, 0xfd, 0x20, 0x0f, 0x83, 0xf5, 0xee, 0xb2, 0xbb, 0xe1, 0x7a, 0xb4, 0x7d, - 0xc4, 0xd5, 0xd8, 0xdf, 0x5e, 0x15, 0x53, 0xb7, 0x57, 0xcf, 0xfa, 0x42, 0x91, 0xce, 0x1d, 0x03, - 0x93, 0xce, 0x17, 0xc7, 0xdf, 0xcc, 0xc3, 0x18, 0xbf, 0x38, 0xab, 0x9a, 0x6e, 0xf3, 0x00, 0x9c, - 0xf9, 0x0f, 0x5f, 0x2a, 0xfb, 0xbb, 0x6c, 0xde, 0xc1, 0x13, 0x09, 0xf5, 0x6b, 0x79, 0x18, 0xaa, - 0x74, 0xbd, 0xb5, 0x8a, 0x87, 0xba, 0x75, 0x2c, 0xf7, 0x27, 0x7f, 0x37, 0x07, 0xa7, 0x58, 0x43, - 0x96, 0xec, 0x87, 0xd4, 0x3a, 0x80, 0x83, 0x47, 0xf9, 0x00, 0x31, 0xbf, 0xc7, 0x03, 0x44, 0x5f, - 0x96, 0x85, 0xdd, 0xc9, 0x12, 0x8f, 0xcb, 0x35, 0xbb, 0x45, 0x8f, 0xf6, 0x67, 0x1c, 0xe0, 0x71, - 0xb9, 0x2f, 0x90, 0x03, 0xb8, 0x9e, 0xf9, 0x64, 0x09, 0xe4, 0x00, 0xce, 0x96, 0x3e, 0x19, 0x02, - 0xf9, 0x6e, 0x0e, 0x06, 0x27, 0x6c, 0xef, 0x88, 0x0f, 0x7c, 0xf1, 0x15, 0x47, 0x5b, 0xcd, 0xfd, - 0xaf, 0x38, 0xda, 0xba, 0xa9, 0xfe, 0x7c, 0x1e, 0xce, 0x8a, 0xd8, 0xe0, 0xe2, 0xfc, 0xe1, 0x64, - 0x3a, 0x16, 0x83, 0x2d, 0x29, 0x9a, 0x93, 0x79, 0x48, 0x88, 0xe6, 0x97, 0x0b, 0x70, 0x16, 0x43, - 0x99, 0xb2, 0x6d, 0xd9, 0x27, 0xc0, 0x16, 0x21, 0xcd, 0xe8, 0x25, 0xe8, 0x5c, 0xca, 0x25, 0xe8, - 0xbf, 0xd8, 0x1c, 0x7f, 0x65, 0xd5, 0xf4, 0xd6, 0xba, 0xcb, 0xd7, 0x9b, 0x76, 0xfb, 0xc6, 0xaa, - 0xa3, 0x3f, 0x32, 0xf9, 0xf5, 0x9f, 0xde, 0xba, 0x11, 0xa4, 0xd9, 0xd0, 0x3b, 0xa6, 0x48, 0xc0, - 0x51, 0xc7, 0xbd, 0x0e, 0xe3, 0xea, 0x5f, 0x9f, 0xba, 0x00, 0x77, 0x6c, 0xd3, 0x12, 0x3e, 0x85, - 0xdc, 0xd0, 0xad, 0xb3, 0xfd, 0xe1, 0x7b, 0xb6, 0x69, 0x35, 0xe2, 0x8e, 0x85, 0xbb, 0xad, 0x2f, - 0x64, 0xad, 0x49, 0xd5, 0xa8, 0xff, 0x4d, 0x0e, 0x2e, 0x46, 0xb5, 0xf8, 0x93, 0x60, 0x3b, 0xfe, - 0xb9, 0x3c, 0x9c, 0xbb, 0x8d, 0xc2, 0x09, 0x1c, 0x39, 0x4e, 0xe6, 0x2d, 0x31, 0x38, 0x53, 0x64, - 0x73, 0x62, 0x51, 0x66, 0xcb, 0xe6, 0x64, 0x52, 0x17, 0xb2, 0xf9, 0xaf, 0x73, 0x70, 0x66, 0xa1, - 0x56, 0x9d, 0xfc, 0x84, 0x8c, 0xa8, 0xe4, 0xf7, 0x1c, 0x71, 0x83, 0x33, 0xf1, 0x3d, 0x47, 0xdc, - 0xf4, 0xfc, 0x56, 0x1e, 0xce, 0xd4, 0x2b, 0x73, 0xb3, 0x9f, 0x94, 0x19, 0x7c, 0x52, 0xf6, 0x3a, - 0xf4, 0x0f, 0xc1, 0x84, 0x2d, 0x20, 0x7f, 0xe6, 0xfd, 0x9b, 0xd9, 0xde, 0x88, 0x49, 0xa1, 0x1c, - 0xf1, 0xa9, 0xfb, 0x40, 0x84, 0xc2, 0x34, 0x3f, 0x42, 0x7d, 0xc4, 0x35, 0xff, 0x3f, 0x2f, 0xc1, - 0xd0, 0xdd, 0xee, 0x32, 0x15, 0xce, 0x29, 0xc7, 0xfa, 0xe4, 0xf7, 0x26, 0x0c, 0x09, 0x31, 0xe0, - 0xad, 0x89, 0x14, 0x3c, 0x4f, 0x04, 0x43, 0xe1, 0xf1, 0x89, 0x64, 0x22, 0x72, 0x19, 0x8a, 0xf7, - 0xa9, 0xb3, 0x2c, 0xbf, 0x2b, 0x7d, 0x44, 0x9d, 0x65, 0x0d, 0xa1, 0x64, 0x36, 0x74, 0x99, 0xaf, - 0x2c, 0xd6, 0x30, 0x91, 0x8a, 0xb8, 0xb0, 0xc1, 0xcc, 0x30, 0x81, 0xdf, 0x9b, 0xde, 0x31, 0x79, - 0x0a, 0x16, 0xf9, 0x4d, 0x7b, 0xbc, 0x24, 0x99, 0x87, 0xd3, 0xb2, 0xe3, 0x13, 0xcf, 0x22, 0x52, - 0x4e, 0x61, 0x97, 0x96, 0x3f, 0x24, 0x59, 0x94, 0xbc, 0x0d, 0xc3, 0x3e, 0x10, 0x5d, 0xb8, 0x06, - 0xc3, 0xd0, 0xf5, 0x01, 0xab, 0x58, 0x8a, 0xa2, 0x48, 0x01, 0x99, 0x01, 0x5e, 0x43, 0x40, 0x0a, - 0x83, 0x98, 0x4b, 0x5c, 0xa4, 0x00, 0x79, 0x19, 0x19, 0xe0, 0x33, 0x0f, 0x74, 0x56, 0x19, 0xc2, - 0x47, 0x97, 0xe8, 0x92, 0xef, 0x08, 0x38, 0x7f, 0x5a, 0x1b, 0x21, 0x23, 0x0b, 0x00, 0xa1, 0x53, - 0x81, 0x08, 0x60, 0xb0, 0x6b, 0x77, 0x07, 0x89, 0x85, 0x7c, 0x1d, 0x38, 0xb2, 0x97, 0xeb, 0x40, - 0xf5, 0x1f, 0xe4, 0x61, 0xa8, 0xd2, 0xe9, 0x04, 0x43, 0xe1, 0x05, 0x28, 0x55, 0x3a, 0x9d, 0x7b, - 0x5a, 0x4d, 0x0e, 0x65, 0xae, 0x77, 0x3a, 0x8d, 0xae, 0x63, 0xca, 0x3e, 0xa1, 0x9c, 0x88, 0x4c, - 0xc2, 0x48, 0xa5, 0xd3, 0x59, 0xec, 0x2e, 0xb7, 0xcc, 0xa6, 0x94, 0x19, 0x89, 0xe7, 0x8e, 0xeb, - 0x74, 0x1a, 0x1d, 0xc4, 0xc4, 0xd3, 0x63, 0x45, 0xcb, 0x90, 0xaf, 0x62, 0xd8, 0x1f, 0x91, 0x98, - 0x87, 0xa7, 0xfe, 0x50, 0x83, 0x20, 0xe6, 0x61, 0xdb, 0xae, 0x07, 0x44, 0x3c, 0xd8, 0xfb, 0x65, - 0x3f, 0x64, 0x3e, 0xab, 0x28, 0x91, 0x80, 0x27, 0x64, 0x49, 0x3e, 0x07, 0x03, 0x95, 0x4e, 0x47, - 0xba, 0x6f, 0x42, 0xa7, 0x22, 0x56, 0x2a, 0x9e, 0xfb, 0x4c, 0x90, 0x5d, 0x7a, 0x13, 0x46, 0xa3, - 0x95, 0xed, 0x2a, 0x58, 0xfc, 0x0f, 0x72, 0xf8, 0x41, 0x47, 0xdc, 0xa7, 0xf9, 0x25, 0x28, 0x54, - 0x3a, 0x1d, 0x31, 0x1f, 0x9d, 0x49, 0xe9, 0x8f, 0xf8, 0x13, 0xe8, 0x4a, 0xa7, 0xe3, 0x7f, 0xfa, - 0x11, 0x7f, 0x1c, 0xb1, 0xa7, 0x4f, 0xff, 0x2e, 0xff, 0xf4, 0xa3, 0xfd, 0x70, 0x41, 0xfd, 0xad, - 0x02, 0x9c, 0xaa, 0x74, 0x3a, 0x27, 0x41, 0xe6, 0x0f, 0xea, 0xa1, 0xf5, 0x8b, 0x00, 0xd2, 0xf4, - 0x38, 0x10, 0x3c, 0xdd, 0x1a, 0x92, 0xa6, 0x46, 0x25, 0xa7, 0x49, 0x44, 0xbe, 0xfa, 0x95, 0x77, - 0xa5, 0x7e, 0x5f, 0x2b, 0xe0, 0x54, 0x7c, 0xd4, 0x83, 0x46, 0x7d, 0x5c, 0xba, 0x4d, 0xf4, 0x41, - 0x69, 0x57, 0x7d, 0xf0, 0x77, 0x22, 0x83, 0x07, 0x83, 0x96, 0x9f, 0xf4, 0x42, 0xff, 0xbe, 0xcc, - 0xe2, 0x51, 0x59, 0x98, 0x22, 0x92, 0x8d, 0x9f, 0x48, 0x49, 0xc4, 0x55, 0x6a, 0x32, 0x54, 0xc3, - 0x34, 0xb4, 0x18, 0xad, 0xdf, 0x87, 0x03, 0xbb, 0xea, 0xc3, 0xcd, 0x3c, 0xbe, 0x9d, 0x0e, 0xe2, - 0x32, 0xed, 0x7f, 0x77, 0x71, 0x03, 0x80, 0x7b, 0x1e, 0x04, 0x6e, 0xcd, 0x23, 0x3c, 0x04, 0x0b, - 0xcf, 0xaf, 0x24, 0x42, 0xb0, 0x84, 0x24, 0x81, 0x87, 0x54, 0x21, 0xd5, 0x43, 0xea, 0x1a, 0x94, - 0x35, 0x7d, 0xfd, 0x9d, 0x2e, 0x75, 0x36, 0x84, 0x39, 0xc3, 0xc3, 0x1e, 0xea, 0xeb, 0x8d, 0x1f, - 0x65, 0x40, 0x2d, 0x40, 0x13, 0x35, 0x78, 0x7c, 0x2f, 0x79, 0x84, 0xf0, 0x33, 0xf2, 0xe0, 0xc9, - 0xfd, 0x5e, 0x14, 0x9d, 0xbc, 0x0e, 0x85, 0xca, 0x83, 0xba, 0x90, 0x6c, 0xd0, 0xb5, 0x95, 0x07, - 0x75, 0x21, 0xaf, 0xcc, 0xb2, 0x0f, 0xea, 0xea, 0xd7, 0xf2, 0x40, 0x92, 0x94, 0xe4, 0x15, 0x18, - 0x44, 0xe8, 0x2a, 0xd3, 0x19, 0x39, 0x31, 0xe7, 0xba, 0xdb, 0x70, 0x10, 0x1a, 0x31, 0xee, 0x7c, - 0x52, 0xf2, 0x1a, 0xa6, 0x3e, 0x16, 0xa9, 0xe1, 0x22, 0x89, 0x39, 0xd7, 0x5d, 0x3f, 0x59, 0x70, - 0x2c, 0xf3, 0xb1, 0x20, 0x46, 0xbb, 0xf0, 0x41, 0x7d, 0xc6, 0x76, 0x3d, 0x21, 0x6a, 0x6e, 0x17, - 0xae, 0xbb, 0x98, 0x11, 0x36, 0x62, 0x17, 0x72, 0x32, 0xcc, 0x6a, 0xf5, 0xa0, 0xce, 0x9f, 0xa9, - 0x18, 0x9a, 0xdd, 0xf2, 0x0d, 0x4a, 0x9e, 0xd5, 0x6a, 0xdd, 0x6d, 0xf0, 0x27, 0x2e, 0x06, 0xe6, - 0x5c, 0x8e, 0x64, 0xb5, 0x8a, 0x94, 0x52, 0xbf, 0x5e, 0x86, 0xb1, 0xaa, 0xee, 0xe9, 0xcb, 0xba, - 0x4b, 0xa5, 0xdd, 0xf4, 0x29, 0x1f, 0xe6, 0x7f, 0x8e, 0x24, 0x07, 0x63, 0x39, 0xe5, 0x6b, 0xe2, - 0x05, 0xc8, 0x1b, 0x21, 0xdf, 0x20, 0xe7, 0xa8, 0x9c, 0xc4, 0x6c, 0xb9, 0xd1, 0x11, 0x60, 0x2d, - 0x41, 0x48, 0x9e, 0x87, 0x21, 0x1f, 0xc6, 0x36, 0x00, 0x85, 0x50, 0x67, 0x8c, 0x65, 0x66, 0xff, - 0x6b, 0x32, 0x9a, 0xbc, 0x06, 0xc3, 0xfe, 0x4f, 0xc9, 0xb4, 0xe6, 0x19, 0xd9, 0x96, 0x13, 0xbb, - 0x27, 0x99, 0x54, 0x2e, 0x8a, 0xf3, 0x5b, 0x7f, 0xa4, 0x68, 0x2c, 0xe9, 0x59, 0x84, 0x94, 0xfc, - 0x28, 0x8c, 0xfa, 0xbf, 0xc5, 0x86, 0x81, 0xe7, 0x87, 0x7b, 0x3e, 0x48, 0xe9, 0x1c, 0x13, 0xeb, - 0xf5, 0x28, 0x39, 0xdf, 0x3a, 0x3c, 0xe1, 0xe7, 0xf1, 0x32, 0x96, 0x93, 0x3b, 0x87, 0x58, 0x05, - 0xa4, 0x06, 0xa7, 0x7d, 0x48, 0xa8, 0xa1, 0x03, 0xe1, 0x8e, 0xd1, 0x58, 0x6e, 0xa4, 0x2a, 0x69, - 0xb2, 0x14, 0x69, 0xc1, 0xe5, 0x08, 0xd0, 0x70, 0xd7, 0xcc, 0x15, 0x4f, 0x6c, 0xf7, 0x44, 0x0c, - 0x62, 0x91, 0xb8, 0x31, 0xe0, 0xca, 0x69, 0xfc, 0x0c, 0xac, 0xd1, 0xec, 0x50, 0x3d, 0xb9, 0x91, - 0x3a, 0x9c, 0xf5, 0xf1, 0xb7, 0x27, 0x17, 0x17, 0x1d, 0xfb, 0x3d, 0xda, 0xf4, 0x6a, 0x55, 0xb1, - 0x5d, 0xc6, 0xd8, 0x74, 0xc6, 0x72, 0x63, 0xb5, 0xd9, 0x61, 0x4a, 0xc1, 0x70, 0x51, 0xe6, 0xa9, - 0x85, 0xc9, 0x7d, 0x38, 0x27, 0xc1, 0xa5, 0xf4, 0xd0, 0x10, 0xee, 0xe7, 0x05, 0xd7, 0xf4, 0x0c, - 0xd1, 0xe9, 0xc5, 0xc9, 0x9b, 0x30, 0xe2, 0x23, 0xf8, 0x2d, 0xe2, 0x10, 0xde, 0x22, 0xe2, 0x90, - 0x34, 0x96, 0x1b, 0xf1, 0xd7, 0x94, 0x51, 0x62, 0x59, 0xa3, 0x30, 0xa3, 0xfe, 0x70, 0x44, 0xa3, - 0xbc, 0x8d, 0x4e, 0xaa, 0x32, 0x62, 0x96, 0xfd, 0xb7, 0x43, 0x8d, 0x5a, 0x70, 0xcc, 0x55, 0x93, - 0xef, 0xa4, 0xfd, 0x07, 0x94, 0xcb, 0x0d, 0x1b, 0x81, 0x69, 0xfa, 0xc1, 0xc9, 0x2f, 0x55, 0xe0, - 0x4c, 0x8a, 0x8e, 0xed, 0x6a, 0xc7, 0xf8, 0x41, 0x3e, 0x6c, 0xc4, 0x11, 0xdf, 0x36, 0x4e, 0x40, - 0xd9, 0xff, 0x12, 0x61, 0x3c, 0x28, 0x59, 0x43, 0x33, 0xce, 0xc3, 0xc7, 0x47, 0xc4, 0x71, 0xc4, - 0xb7, 0x92, 0x07, 0x21, 0x8e, 0x0f, 0x73, 0xa1, 0x38, 0x8e, 0xf8, 0xf6, 0xf2, 0xa7, 0x8b, 0xe1, - 0x9c, 0x74, 0xb2, 0xc7, 0x3c, 0x28, 0x33, 0x39, 0xf4, 0x83, 0x2d, 0xed, 0xe2, 0x21, 0xa3, 0xac, - 0x9a, 0x03, 0x7b, 0x53, 0x4d, 0xf2, 0x26, 0x0c, 0x2d, 0xda, 0xae, 0xb7, 0xea, 0x50, 0x77, 0x31, - 0x88, 0xa1, 0x8f, 0x8f, 0x60, 0x3b, 0x02, 0xdc, 0xe8, 0x44, 0x66, 0x7f, 0x99, 0x5c, 0xfd, 0x47, - 0x85, 0x84, 0x36, 0x70, 0xc3, 0xf5, 0x48, 0x6a, 0xc3, 0x01, 0x0c, 0x75, 0x72, 0x33, 0x5c, 0x05, - 0xb9, 0x85, 0xdf, 0x2f, 0x05, 0x08, 0x5c, 0x16, 0x06, 0x7e, 0x94, 0x84, 0xfc, 0x10, 0x5c, 0x88, - 0x00, 0x16, 0x75, 0x47, 0x6f, 0x53, 0x2f, 0xcc, 0x57, 0x88, 0x21, 0x9f, 0xfc, 0xd2, 0x8d, 0x4e, - 0x80, 0x96, 0x73, 0x20, 0x66, 0x70, 0x90, 0x54, 0x6b, 0x60, 0x17, 0x2e, 0xd6, 0x3f, 0x57, 0x08, - 0x0d, 0x9d, 0x68, 0xe8, 0x56, 0x8d, 0xba, 0xdd, 0x96, 0x77, 0x7c, 0x3b, 0x78, 0x6f, 0x89, 0x31, - 0x66, 0xe0, 0x54, 0x65, 0x65, 0x85, 0x36, 0x3d, 0x3f, 0x22, 0xb5, 0x2b, 0x82, 0xf5, 0xf1, 0x8d, - 0x87, 0x40, 0x89, 0x08, 0xc3, 0x91, 0xcc, 0xfa, 0xb1, 0x62, 0xea, 0x3f, 0x2e, 0x82, 0x12, 0x18, - 0xfe, 0xc1, 0x33, 0xaf, 0x43, 0x5c, 0x64, 0x3f, 0x16, 0xbd, 0x62, 0xc2, 0xe9, 0x50, 0x18, 0xf5, - 0x6e, 0xbb, 0xad, 0xe3, 0xd0, 0x63, 0x1b, 0x8b, 0xf1, 0x38, 0xb3, 0x90, 0x90, 0xef, 0x25, 0x2e, - 0x89, 0xbd, 0x04, 0x09, 0x9f, 0xd1, 0x35, 0x5c, 0xce, 0x42, 0x4b, 0x72, 0x25, 0xdf, 0xc8, 0xc1, - 0x59, 0xbf, 0x53, 0x16, 0x96, 0x99, 0x51, 0x3d, 0x69, 0x77, 0x2d, 0xcf, 0xdf, 0xc7, 0xbc, 0x9e, - 0x5d, 0x1d, 0xef, 0xa4, 0xeb, 0x69, 0x85, 0x79, 0x4b, 0x82, 0xb0, 0x14, 0x81, 0x42, 0xd8, 0x48, - 0xd3, 0x68, 0x22, 0x91, 0x96, 0x5a, 0xef, 0xa5, 0xdb, 0x70, 0x31, 0x93, 0xe5, 0x76, 0x46, 0x6c, - 0xbf, 0x6c, 0xc4, 0xfe, 0x77, 0xb9, 0x70, 0x22, 0x8a, 0x09, 0x89, 0x5c, 0x07, 0x08, 0x41, 0x62, - 0x5b, 0x3b, 0xba, 0xb5, 0x39, 0x0e, 0xa1, 0xd0, 0x34, 0x89, 0x82, 0x2c, 0x40, 0x49, 0x88, 0x85, - 0xe7, 0x06, 0xfe, 0xec, 0x36, 0xbd, 0x70, 0x5d, 0x96, 0x03, 0x6e, 0x59, 0xc5, 0x37, 0x0b, 0x36, - 0x97, 0x5e, 0x83, 0xa1, 0xbd, 0x7e, 0xd7, 0x37, 0x0a, 0x40, 0xe4, 0x3d, 0xe8, 0x21, 0x1a, 0xe8, - 0x47, 0x78, 0x0a, 0xbb, 0x0a, 0x65, 0xf6, 0x09, 0x98, 0x2d, 0x43, 0x8a, 0x8e, 0xdb, 0x15, 0x30, - 0x2d, 0xc0, 0x86, 0xa1, 0xa9, 0x06, 0xd2, 0x43, 0x53, 0xa9, 0x3f, 0x5b, 0x80, 0xf3, 0x72, 0x87, - 0x54, 0x29, 0x06, 0xdc, 0x3f, 0xe9, 0x94, 0x8f, 0xb0, 0x53, 0x54, 0x28, 0xf1, 0xad, 0x87, 0xc8, - 0x7c, 0xc0, 0x8f, 0x85, 0x10, 0xa2, 0x09, 0x8c, 0xfa, 0x3f, 0xe7, 0x61, 0x24, 0x30, 0xef, 0x74, - 0xc7, 0x3d, 0xc6, 0xdd, 0xf1, 0x79, 0x18, 0xc1, 0xe0, 0x42, 0x6d, 0x6a, 0xf1, 0x00, 0x3c, 0xfd, - 0x52, 0xaa, 0x12, 0x1f, 0x21, 0xb2, 0x52, 0x45, 0x08, 0x99, 0xf6, 0x73, 0xcb, 0x4f, 0x0a, 0xf9, - 0xc4, 0xcd, 0x3e, 0x0e, 0x57, 0xff, 0x52, 0x01, 0x86, 0x7d, 0x29, 0x4f, 0x98, 0x47, 0xf5, 0x9e, - 0xe7, 0x70, 0x85, 0x7c, 0x03, 0x60, 0xd1, 0x76, 0x3c, 0xbd, 0x35, 0x1f, 0x6a, 0x3e, 0x1e, 0x90, - 0x76, 0x10, 0xca, 0xcb, 0x48, 0x24, 0xb8, 0x7e, 0x85, 0x66, 0x35, 0x9f, 0x98, 0xf8, 0xfa, 0x15, - 0x40, 0x35, 0x89, 0x42, 0xfd, 0xbd, 0x3c, 0x9c, 0xf2, 0x3b, 0x69, 0xea, 0x31, 0x6d, 0x76, 0x8f, - 0xf3, 0xdc, 0x14, 0x95, 0x76, 0xff, 0xb6, 0xd2, 0x56, 0xff, 0x4f, 0x69, 0x22, 0x99, 0x6c, 0xd9, - 0x27, 0x13, 0xc9, 0xbf, 0x0a, 0x1d, 0x57, 0x7f, 0xbc, 0x00, 0x67, 0x7d, 0xa9, 0x4f, 0x77, 0x2d, - 0x3c, 0x5a, 0x98, 0xd4, 0x5b, 0xad, 0xe3, 0xbc, 0x1b, 0x1f, 0xf2, 0x05, 0xb1, 0x20, 0xa2, 0xf5, - 0x89, 0x0c, 0x81, 0x2b, 0x02, 0xdc, 0xb0, 0x4d, 0x43, 0x93, 0x89, 0xc8, 0xdb, 0x30, 0xec, 0xff, - 0xac, 0x38, 0xab, 0xfe, 0x16, 0x1c, 0x2f, 0x0a, 0x82, 0x42, 0xba, 0x13, 0x09, 0x4a, 0x10, 0x29, - 0xa0, 0x7e, 0x6d, 0x00, 0x2e, 0x3d, 0x30, 0x2d, 0xc3, 0x5e, 0x77, 0xfd, 0x04, 0x93, 0x47, 0xfe, - 0xa0, 0xec, 0xb0, 0x13, 0x4b, 0xbe, 0x03, 0xe7, 0xe2, 0x22, 0x75, 0x82, 0xb0, 0xdf, 0xa2, 0x77, - 0xd6, 0x39, 0x41, 0xc3, 0x4f, 0x35, 0x29, 0x6e, 0xdb, 0xb4, 0xf4, 0x92, 0xf1, 0x5c, 0x95, 0x03, - 0x3b, 0xc9, 0x55, 0xf9, 0x1c, 0x94, 0xaa, 0x76, 0x5b, 0x37, 0xfd, 0xf0, 0x34, 0x38, 0x8a, 0x83, - 0x7a, 0x11, 0xa3, 0x09, 0x0a, 0xc6, 0x5f, 0x54, 0x8c, 0x5d, 0x36, 0x18, 0xf2, 0xf7, 0x0b, 0x30, - 0x2b, 0x4d, 0x93, 0x89, 0x88, 0x0d, 0x23, 0xa2, 0x3a, 0x71, 0x37, 0x06, 0xb8, 0x79, 0x7a, 0xd9, - 0x97, 0x51, 0xb6, 0x5a, 0x5d, 0x8f, 0x94, 0xe3, 0xdb, 0x28, 0x9e, 0x42, 0x53, 0x7c, 0x0c, 0xbf, - 0x25, 0xd3, 0xa2, 0xfc, 0x25, 0x21, 0xe0, 0x24, 0x33, 0x94, 0x14, 0x02, 0xce, 0x32, 0x32, 0x11, - 0x99, 0x82, 0xd3, 0x18, 0x9c, 0x39, 0xd8, 0x4a, 0x31, 0x95, 0x18, 0x46, 0xa3, 0x12, 0xaf, 0x5c, - 0x78, 0x3c, 0x67, 0xf6, 0x71, 0x8d, 0xa6, 0x40, 0x6b, 0xc9, 0x12, 0xe4, 0x22, 0x14, 0xe6, 0x67, - 0x2b, 0x78, 0x57, 0x53, 0xe6, 0x89, 0x91, 0xac, 0x96, 0xae, 0x31, 0xd8, 0xa5, 0x2f, 0x02, 0x49, - 0x7e, 0xce, 0xae, 0xee, 0x63, 0xfe, 0x4b, 0x69, 0xcb, 0x77, 0xd4, 0x3d, 0x6a, 0x0e, 0x62, 0x22, - 0x8c, 0xe4, 0x24, 0xeb, 0xff, 0x28, 0x73, 0x92, 0x95, 0x0e, 0x34, 0x27, 0x99, 0xfa, 0x6b, 0x39, - 0x38, 0x9d, 0x08, 0x60, 0x4e, 0x5e, 0x02, 0xe0, 0x10, 0x29, 0x50, 0x24, 0x46, 0x5e, 0x09, 0x83, - 0x9a, 0x8b, 0xe5, 0x31, 0x24, 0x23, 0x37, 0xa0, 0xcc, 0x7f, 0x89, 0xe0, 0x4e, 0xc9, 0x22, 0xdd, - 0xae, 0x69, 0x68, 0x01, 0x51, 0x58, 0x0b, 0xde, 0x48, 0x16, 0x52, 0x8b, 0x78, 0x1b, 0x9d, 0xa0, - 0x16, 0x46, 0xa6, 0x7e, 0x3d, 0x0f, 0xc3, 0x41, 0x83, 0x2b, 0xc6, 0x61, 0xe9, 0x5c, 0x49, 0xc4, - 0x82, 0x2f, 0x6c, 0x17, 0x0b, 0x3e, 0x36, 0xdf, 0x8a, 0xe0, 0xef, 0x07, 0xf7, 0xa0, 0xea, 0x9b, - 0x79, 0x38, 0x15, 0xd4, 0x7a, 0x88, 0x97, 0x5f, 0x1f, 0x23, 0x91, 0x7c, 0x23, 0x07, 0xca, 0x84, - 0xd9, 0x6a, 0x99, 0xd6, 0x6a, 0xcd, 0x5a, 0xb1, 0x9d, 0x36, 0x4e, 0x88, 0x87, 0x77, 0x84, 0xab, - 0xfe, 0xa9, 0x1c, 0x9c, 0x16, 0x0d, 0x9a, 0xd4, 0x1d, 0xe3, 0xf0, 0xce, 0xc7, 0xe2, 0x2d, 0x39, - 0x3c, 0x7d, 0x51, 0xbf, 0x9d, 0x07, 0x98, 0xb5, 0x9b, 0x0f, 0x8f, 0xf8, 0x7b, 0xac, 0x37, 0xa0, - 0xc4, 0x23, 0x6c, 0x09, 0x8d, 0x3d, 0x2d, 0xde, 0x1d, 0xb1, 0x4f, 0xe3, 0x88, 0x89, 0x31, 0x31, - 0x1f, 0x97, 0x78, 0x84, 0x2e, 0x25, 0xa7, 0x89, 0x22, 0xac, 0x52, 0x46, 0x27, 0x16, 0x8c, 0xa0, - 0x52, 0x06, 0x8b, 0x56, 0xba, 0xb5, 0x39, 0x5e, 0x6c, 0xd9, 0xcd, 0x87, 0x1a, 0xd2, 0xab, 0xff, - 0x32, 0xc7, 0x65, 0x77, 0xc4, 0x5f, 0x95, 0xfa, 0x9f, 0x5f, 0xdc, 0xe5, 0xe7, 0xff, 0xe9, 0x1c, - 0x9c, 0xd5, 0x68, 0xd3, 0x7e, 0x44, 0x9d, 0x8d, 0x49, 0xdb, 0xa0, 0xb7, 0xa9, 0x45, 0x9d, 0xc3, - 0x1a, 0x51, 0xbf, 0x8f, 0xc9, 0x33, 0xc2, 0xc6, 0xdc, 0x73, 0xa9, 0x71, 0x74, 0x12, 0x9b, 0xa8, - 0xbf, 0x39, 0x00, 0x4a, 0xaa, 0xd5, 0x7b, 0x64, 0xcd, 0xb9, 0xcc, 0xad, 0x4c, 0xf1, 0xa0, 0xb6, - 0x32, 0xfd, 0xbb, 0xdb, 0xca, 0x94, 0x76, 0xbb, 0x95, 0x19, 0xd8, 0xc9, 0x56, 0xa6, 0x1d, 0xdf, - 0xca, 0x94, 0x71, 0x2b, 0xf3, 0x52, 0xcf, 0xad, 0xcc, 0x94, 0x65, 0xec, 0x71, 0x23, 0x73, 0x64, - 0x93, 0xee, 0xee, 0x65, 0x07, 0x76, 0x95, 0x4d, 0x8a, 0x4d, 0xdb, 0x31, 0xa8, 0x21, 0x36, 0x5e, - 0x78, 0xea, 0xef, 0x08, 0x98, 0x16, 0x60, 0x13, 0x19, 0x8c, 0x47, 0x76, 0x92, 0xc1, 0xf8, 0x00, - 0xf6, 0x5f, 0x1f, 0xe4, 0xe1, 0xf4, 0x24, 0x75, 0x3c, 0x1e, 0xc2, 0xf3, 0x20, 0x5c, 0xe2, 0x2a, - 0x70, 0x4a, 0x62, 0x88, 0x16, 0x79, 0x3e, 0x74, 0xf3, 0x6b, 0x52, 0xc7, 0x8b, 0x7b, 0x09, 0xc6, - 0xe9, 0x59, 0xf5, 0x7e, 0x16, 0x31, 0x31, 0x76, 0x83, 0xea, 0x7d, 0x38, 0x17, 0xa4, 0x29, 0x7e, - 0x69, 0x01, 0xbd, 0x94, 0x18, 0xac, 0xb8, 0xfb, 0xc4, 0x60, 0xea, 0xaf, 0xe6, 0xe0, 0x8a, 0x46, - 0x2d, 0xba, 0xae, 0x2f, 0xb7, 0xa8, 0xd4, 0x2c, 0xb1, 0x32, 0xb0, 0x59, 0xc3, 0x74, 0xdb, 0xba, - 0xd7, 0x5c, 0xdb, 0x97, 0x8c, 0xa6, 0x61, 0x58, 0x9e, 0xbf, 0x76, 0x31, 0xb7, 0x45, 0xca, 0xa9, - 0xbf, 0x59, 0x84, 0x81, 0x09, 0xdb, 0xbb, 0x63, 0xef, 0x33, 0x53, 0x5d, 0x38, 0xe5, 0xe7, 0x77, - 0x71, 0xd6, 0xf3, 0x39, 0xac, 0x5c, 0x0a, 0xde, 0x8f, 0x2e, 0xa4, 0xcb, 0x76, 0x22, 0xc9, 0x81, - 0x4f, 0xb6, 0xcb, 0x1c, 0x75, 0xaf, 0xc0, 0x20, 0x46, 0x7f, 0x91, 0x4e, 0x63, 0xd1, 0x41, 0xdb, - 0x63, 0xc0, 0x78, 0x1d, 0x21, 0x29, 0xf9, 0xa1, 0x48, 0xcc, 0xd1, 0xd2, 0xfe, 0x73, 0xda, 0xc9, - 0xe1, 0x47, 0x5f, 0xe2, 0x17, 0x79, 0xd8, 0x26, 0x29, 0xff, 0x07, 0x9e, 0xa2, 0xc4, 0x9a, 0x14, - 0x10, 0x1e, 0x60, 0xbe, 0xb9, 0x49, 0x18, 0x99, 0xb0, 0x3d, 0xc9, 0x19, 0x78, 0x30, 0x7c, 0x06, - 0xca, 0x24, 0x9f, 0xee, 0x09, 0x1c, 0x2d, 0xa3, 0x7e, 0xbf, 0x08, 0xc3, 0xfe, 0xcf, 0x43, 0xd2, - 0x9d, 0x17, 0xa0, 0x34, 0x63, 0x4b, 0x29, 0x10, 0xd0, 0x81, 0x78, 0xcd, 0x76, 0x63, 0x9e, 0xd1, - 0x82, 0x88, 0x49, 0x7d, 0xde, 0x36, 0x64, 0xf7, 0x77, 0x94, 0xba, 0x65, 0x1b, 0x89, 0xe7, 0xc3, - 0x01, 0x21, 0xb9, 0x02, 0x45, 0x7c, 0x39, 0x20, 0x1d, 0xe4, 0xc7, 0x5e, 0x0b, 0x20, 0x5e, 0xd2, - 0xca, 0xd2, 0x6e, 0xb5, 0x72, 0x60, 0xaf, 0x5a, 0x59, 0x3e, 0x58, 0xad, 0x7c, 0x17, 0x86, 0xb1, - 0x26, 0x3f, 0x83, 0xda, 0xf6, 0x0b, 0xeb, 0x45, 0xb1, 0xf6, 0x8d, 0xf0, 0x76, 0x8b, 0x3c, 0x6a, - 0xb8, 0xe4, 0x45, 0x58, 0xc5, 0x74, 0x17, 0xf6, 0xb1, 0x9d, 0xfe, 0x47, 0x39, 0x18, 0xb8, 0x67, - 0x3d, 0xb4, 0xec, 0xf5, 0xfd, 0x69, 0xdc, 0x4b, 0x30, 0x24, 0xd8, 0x48, 0xab, 0x0b, 0xbe, 0x08, - 0xef, 0x72, 0x70, 0x03, 0x39, 0x69, 0x32, 0x15, 0x79, 0x33, 0x28, 0x84, 0x8f, 0x83, 0x0a, 0x61, - 0x12, 0x11, 0xbf, 0x50, 0x33, 0x9a, 0xf7, 0x40, 0x26, 0x27, 0x97, 0xa1, 0x58, 0x65, 0x4d, 0x95, - 0xa2, 0xe8, 0xb2, 0xa6, 0x68, 0x08, 0x55, 0x3f, 0x28, 0xc2, 0x68, 0xec, 0xe0, 0xeb, 0x39, 0x18, - 0x14, 0x07, 0x4f, 0xa6, 0x9f, 0x88, 0x01, 0x1f, 0x0f, 0x05, 0x40, 0xad, 0xcc, 0xff, 0xac, 0x19, - 0xe4, 0x0b, 0x30, 0x60, 0xbb, 0xb8, 0x28, 0xe2, 0xb7, 0x8c, 0x86, 0x43, 0x68, 0xa1, 0xce, 0xda, - 0xce, 0x07, 0x87, 0x20, 0x91, 0x35, 0xd2, 0x76, 0xf1, 0xd3, 0x6e, 0xc1, 0xa0, 0xee, 0xba, 0xd4, - 0x6b, 0x78, 0xfa, 0xaa, 0x9c, 0x9b, 0x21, 0x00, 0xca, 0xa3, 0x03, 0x81, 0x4b, 0xfa, 0x2a, 0xf9, - 0x22, 0x8c, 0x34, 0x1d, 0x8a, 0xcb, 0xa6, 0xde, 0x62, 0xad, 0x94, 0xcc, 0xda, 0x08, 0x42, 0xbe, - 0x3f, 0x09, 0x11, 0x35, 0x83, 0xdc, 0x87, 0x11, 0xf1, 0x39, 0xdc, 0x73, 0x1f, 0x07, 0xda, 0x68, - 0xb8, 0x8c, 0x71, 0x91, 0x70, 0xdf, 0x7d, 0xf1, 0x80, 0x43, 0x26, 0x97, 0xf9, 0x1a, 0x12, 0x29, - 0x59, 0x00, 0xb2, 0x4e, 0x97, 0x1b, 0x7a, 0xd7, 0x5b, 0x63, 0x75, 0xf1, 0xd0, 0xe2, 0x22, 0x25, - 0x21, 0xbe, 0x7a, 0x48, 0x62, 0xe5, 0xc7, 0x20, 0xeb, 0x74, 0xb9, 0x12, 0x41, 0x92, 0x07, 0x70, - 0x2e, 0x59, 0x84, 0x7d, 0x32, 0xbf, 0x1c, 0x78, 0x76, 0x6b, 0x73, 0x7c, 0x3c, 0x95, 0x40, 0x62, - 0x7b, 0x26, 0xc1, 0xb6, 0x66, 0xdc, 0x29, 0x96, 0x07, 0xc6, 0xca, 0xda, 0x28, 0x2b, 0xeb, 0x9b, - 0x90, 0xa6, 0xa1, 0xfe, 0x41, 0x8e, 0x99, 0x8a, 0xec, 0x83, 0x30, 0x27, 0x33, 0xd3, 0xf5, 0xf6, - 0x2e, 0x75, 0xbd, 0x1d, 0x66, 0x4f, 0x2c, 0xb9, 0x3d, 0x66, 0x57, 0x4d, 0x60, 0xc9, 0x75, 0x28, - 0x19, 0xf2, 0xa9, 0xd9, 0xf9, 0x68, 0x27, 0xf8, 0xf5, 0x68, 0x82, 0x8a, 0x5c, 0x85, 0x22, 0x5b, - 0xb2, 0xe2, 0x5b, 0x66, 0xd9, 0xba, 0xd0, 0x90, 0x42, 0xfd, 0xb1, 0x3c, 0x0c, 0x4b, 0x5f, 0x73, - 0x73, 0x5f, 0x9f, 0xf3, 0xfa, 0xce, 0x9a, 0xe9, 0x3b, 0xbd, 0xe0, 0x5e, 0xca, 0x6f, 0xf2, 0xad, - 0x40, 0x14, 0x3b, 0xba, 0x90, 0x12, 0x82, 0x79, 0x45, 0x7c, 0x68, 0x69, 0xe7, 0xdb, 0x47, 0x46, - 0x7f, 0xa7, 0x58, 0xce, 0x8f, 0x15, 0xee, 0x14, 0xcb, 0xc5, 0xb1, 0x7e, 0x8c, 0xc3, 0x85, 0xa1, - 0xaf, 0xf9, 0xde, 0xdc, 0x5a, 0x31, 0x57, 0x8f, 0xf8, 0xdb, 0x91, 0x83, 0x8d, 0x51, 0x16, 0x93, - 0xcd, 0x11, 0x7f, 0x48, 0xf2, 0x91, 0xca, 0xe6, 0x24, 0xdb, 0xa2, 0x90, 0xcd, 0x3f, 0xce, 0x81, - 0x92, 0x2a, 0x9b, 0xca, 0x21, 0xf9, 0x41, 0x1c, 0x5c, 0xce, 0xc5, 0x3f, 0xca, 0xc3, 0xe9, 0x9a, - 0xe5, 0xd1, 0x55, 0xbe, 0x63, 0x3c, 0xe2, 0x53, 0xc5, 0x5d, 0x18, 0x92, 0x3e, 0x46, 0xf4, 0xf9, - 0x13, 0xc1, 0x7e, 0x3c, 0x44, 0x65, 0x70, 0x92, 0x4b, 0x1f, 0x60, 0x9a, 0xf6, 0x98, 0x90, 0x8f, - 0xf8, 0x9c, 0x73, 0x34, 0x84, 0x7c, 0xc4, 0x27, 0xaf, 0x8f, 0xa9, 0x90, 0xff, 0xf7, 0x1c, 0x9c, - 0x49, 0xa9, 0x9c, 0x5c, 0x81, 0x81, 0x7a, 0x77, 0x19, 0xc3, 0x6e, 0xe5, 0x42, 0x8f, 0x61, 0xb7, - 0xbb, 0x8c, 0x11, 0xb7, 0x34, 0x1f, 0x49, 0x96, 0xf0, 0x71, 0xfd, 0x42, 0xad, 0x3a, 0x29, 0xa4, - 0xaa, 0x4a, 0x61, 0x02, 0x18, 0x38, 0xed, 0xcb, 0x82, 0x07, 0xf8, 0xb6, 0x69, 0x34, 0x63, 0x0f, - 0xf0, 0x59, 0x19, 0xf2, 0xc3, 0x30, 0x58, 0x79, 0xbf, 0xeb, 0x50, 0xe4, 0xcb, 0x25, 0xfe, 0xa9, - 0x80, 0xaf, 0x8f, 0x48, 0xe3, 0xcc, 0x63, 0x09, 0x30, 0x8a, 0x38, 0xef, 0x90, 0xa1, 0xfa, 0xf5, - 0x1c, 0x5c, 0xca, 0x6e, 0x1d, 0xf9, 0x1c, 0x0c, 0xb0, 0x9d, 0x79, 0x45, 0x9b, 0x17, 0x9f, 0xce, - 0xf3, 0x93, 0xda, 0x2d, 0xda, 0xd0, 0x1d, 0xd9, 0xd8, 0xf7, 0xc9, 0xc8, 0x5b, 0x30, 0x54, 0x73, - 0xdd, 0x2e, 0x75, 0xea, 0x2f, 0xdd, 0xd3, 0x6a, 0x62, 0x4f, 0x88, 0x7b, 0x0e, 0x13, 0xc1, 0x0d, - 0xf7, 0xa5, 0x58, 0x60, 0x2d, 0x99, 0x5e, 0xfd, 0xc9, 0x1c, 0x5c, 0xee, 0xf5, 0x55, 0xe4, 0x25, - 0x28, 0x2f, 0x51, 0x4b, 0xb7, 0xbc, 0x5a, 0x55, 0x34, 0x09, 0xb7, 0x58, 0x1e, 0xc2, 0xa2, 0x3b, - 0x85, 0x80, 0x90, 0x15, 0xe2, 0xe7, 0x8a, 0x81, 0x23, 0x03, 0x3f, 0x03, 0x45, 0x58, 0xac, 0x90, - 0x4f, 0xa8, 0xfe, 0x61, 0x1e, 0x86, 0x17, 0x5b, 0xdd, 0x55, 0x53, 0x5a, 0x38, 0xf6, 0x6c, 0x6f, - 0xfb, 0xd6, 0x6f, 0x7e, 0x77, 0xd6, 0x2f, 0x1b, 0x6e, 0xce, 0x1e, 0x87, 0x9b, 0x5f, 0x8e, 0xbc, - 0x09, 0xa5, 0x0e, 0x7e, 0x47, 0xfc, 0x24, 0x96, 0x7f, 0x5d, 0xd6, 0x49, 0x2c, 0x2f, 0xc3, 0xc6, - 0x57, 0x73, 0x1f, 0xe3, 0x2b, 0x2c, 0x2b, 0x09, 0x34, 0x5c, 0x24, 0x4e, 0x04, 0x7a, 0x20, 0x02, - 0x0d, 0x17, 0x84, 0x13, 0x81, 0xee, 0x43, 0xa0, 0xbf, 0x99, 0x87, 0xd1, 0x68, 0x95, 0xe4, 0x73, - 0x30, 0xc4, 0xab, 0xe1, 0xe7, 0x42, 0x39, 0xc9, 0xa9, 0x38, 0x04, 0x6b, 0xc0, 0x7f, 0x88, 0x03, - 0xae, 0x53, 0x6b, 0xba, 0xdb, 0x08, 0x4f, 0x68, 0xf8, 0xfd, 0x6d, 0x99, 0x7b, 0x42, 0xc5, 0x50, - 0xda, 0xe8, 0x9a, 0xee, 0x4e, 0x86, 0xbf, 0xc9, 0x14, 0x10, 0x87, 0x76, 0x5d, 0x1a, 0x65, 0x50, - 0x44, 0x06, 0x22, 0x39, 0x74, 0x1c, 0xab, 0x9d, 0xe6, 0x30, 0x99, 0xcd, 0x57, 0x82, 0x66, 0xa3, - 0x32, 0xf4, 0xef, 0x20, 0x73, 0xb5, 0x44, 0x9f, 0x7e, 0xcc, 0xc9, 0x09, 0xaa, 0xba, 0xa7, 0xf3, - 0x4d, 0xb9, 0xdf, 0x01, 0xea, 0x87, 0x36, 0xf4, 0x2f, 0x58, 0x74, 0x61, 0x85, 0xbc, 0x08, 0x83, - 0x4c, 0x61, 0x66, 0x6d, 0xd6, 0x97, 0x39, 0xe1, 0x3f, 0x21, 0x69, 0x12, 0x22, 0x66, 0xfa, 0xb4, - 0x90, 0x8a, 0xdc, 0xe2, 0xd9, 0xef, 0xf9, 0x1c, 0x2b, 0xb4, 0x8f, 0xc8, 0x65, 0x38, 0x66, 0xa6, - 0x4f, 0x93, 0xe8, 0xfc, 0x52, 0xe2, 0x81, 0x4e, 0x21, 0x59, 0x8a, 0x63, 0xfc, 0x52, 0x62, 0x7c, - 0xcc, 0xa6, 0x25, 0x96, 0x8f, 0xef, 0x9e, 0x92, 0x14, 0x33, 0x7d, 0x5a, 0x7a, 0x42, 0xfa, 0x61, - 0xd9, 0xa1, 0x34, 0xee, 0xf4, 0x21, 0xe3, 0x66, 0xfa, 0xb4, 0x08, 0x2d, 0x79, 0x15, 0x86, 0xc4, - 0xef, 0x3b, 0xb6, 0xb8, 0x51, 0x96, 0x62, 0x11, 0x49, 0xa8, 0x99, 0x3e, 0x4d, 0xa6, 0x94, 0x2a, - 0x5d, 0x74, 0x4c, 0xcb, 0x13, 0x6f, 0x94, 0xe3, 0x95, 0x22, 0x4e, 0xaa, 0x14, 0x7f, 0x93, 0xb7, - 0x60, 0x24, 0x08, 0xf2, 0xf4, 0x1e, 0x6d, 0x7a, 0xe2, 0xf0, 0xfb, 0x5c, 0xac, 0x30, 0x47, 0xce, - 0xf4, 0x69, 0x51, 0x6a, 0x72, 0x15, 0x4a, 0x1a, 0x75, 0xcd, 0xf7, 0xfd, 0xeb, 0xe2, 0x51, 0x69, - 0x9c, 0x9b, 0xef, 0x33, 0x29, 0x09, 0x3c, 0xeb, 0x9d, 0xf0, 0x7e, 0x5a, 0x1c, 0x55, 0x93, 0x58, - 0x2d, 0x53, 0x96, 0xc1, 0x7a, 0x47, 0x72, 0x4e, 0xf8, 0x62, 0x18, 0xfa, 0x4a, 0x24, 0xcc, 0x1c, - 0x8a, 0xc7, 0x18, 0x90, 0xb1, 0x33, 0x7d, 0x5a, 0x8c, 0x5e, 0x92, 0x6a, 0xd5, 0x74, 0x1f, 0x8a, - 0x68, 0xa3, 0x71, 0xa9, 0x32, 0x94, 0x24, 0x55, 0xf6, 0x53, 0xaa, 0x7a, 0x9e, 0x7a, 0xeb, 0xb6, - 0xf3, 0x50, 0xc4, 0x16, 0x8d, 0x57, 0x2d, 0xb0, 0x52, 0xd5, 0x02, 0x22, 0x57, 0xcd, 0x06, 0xdc, - 0x68, 0x7a, 0xd5, 0xba, 0xa7, 0xcb, 0x55, 0xf3, 0x93, 0x38, 0xbf, 0x93, 0x66, 0xa9, 0xfe, 0x88, - 0xe7, 0x2d, 0x4f, 0x76, 0x28, 0xe2, 0xa4, 0x0e, 0xc5, 0xdf, 0xac, 0x52, 0x29, 0x37, 0xb5, 0x48, - 0x4c, 0x1e, 0x54, 0x2a, 0xa1, 0x58, 0xa5, 0x72, 0x16, 0xeb, 0x5b, 0x72, 0xca, 0x66, 0xe5, 0x74, - 0xb4, 0x83, 0x42, 0x0c, 0xeb, 0x20, 0x29, 0xb5, 0xf3, 0x38, 0xa6, 0x83, 0x55, 0x08, 0x92, 0x0f, - 0x05, 0x2d, 0x9c, 0x5c, 0x9c, 0xe9, 0xd3, 0x30, 0x51, 0xac, 0xca, 0x13, 0x0d, 0x2b, 0x67, 0x90, - 0x62, 0xd8, 0xa7, 0x60, 0xb0, 0x99, 0x3e, 0x8d, 0x27, 0x21, 0x7e, 0x51, 0x4a, 0xe9, 0xa7, 0x9c, - 0x8d, 0x4e, 0x11, 0x01, 0x82, 0x4d, 0x11, 0x61, 0xe2, 0xbf, 0xe9, 0x64, 0xda, 0x3b, 0xe5, 0x5c, - 0x74, 0xa9, 0x89, 0xe3, 0x67, 0xfa, 0xb4, 0x64, 0xaa, 0xbc, 0x57, 0x23, 0x99, 0xe0, 0x94, 0xf3, - 0xb1, 0x00, 0x60, 0x21, 0x8a, 0x89, 0x4b, 0xce, 0x19, 0xb7, 0x10, 0xcb, 0x5a, 0x2e, 0x26, 0xab, - 0x0b, 0xd1, 0x8d, 0x4b, 0x0a, 0xc9, 0x4c, 0x9f, 0x96, 0x56, 0x92, 0x4c, 0x26, 0xf2, 0xb1, 0x29, - 0x4a, 0xd4, 0x37, 0x26, 0x86, 0x9e, 0xe9, 0xd3, 0x12, 0x19, 0xdc, 0x6e, 0xc9, 0x89, 0xd0, 0x94, - 0x8b, 0xd1, 0x4e, 0x0c, 0x31, 0xac, 0x13, 0xa5, 0x84, 0x69, 0xb7, 0xe4, 0xe4, 0x58, 0xca, 0xa5, - 0x64, 0xa9, 0x70, 0xe6, 0x94, 0x92, 0x68, 0x69, 0xe9, 0xf9, 0x7e, 0x94, 0x27, 0x44, 0xc6, 0x55, - 0x51, 0x3e, 0x8d, 0x66, 0xa6, 0x4f, 0x4b, 0xcf, 0x15, 0xa4, 0xa5, 0x27, 0xca, 0x51, 0x2e, 0xf7, - 0xe2, 0x19, 0xb4, 0x2e, 0x3d, 0xc9, 0x8e, 0xde, 0x23, 0x6d, 0x89, 0xf2, 0x64, 0x34, 0xfa, 0x70, - 0x26, 0xe1, 0x4c, 0x9f, 0xd6, 0x23, 0xf9, 0xc9, 0xbd, 0x8c, 0x1c, 0x22, 0xca, 0x53, 0xd1, 0x84, - 0xcb, 0xa9, 0x44, 0x33, 0x7d, 0x5a, 0x46, 0x06, 0x92, 0x7b, 0x19, 0x29, 0x26, 0x94, 0xf1, 0x9e, - 0x6c, 0x03, 0x79, 0x64, 0x24, 0xa8, 0x58, 0x48, 0xcd, 0xce, 0xa0, 0x3c, 0x1d, 0x55, 0xdd, 0x14, - 0x12, 0xa6, 0xba, 0x69, 0x79, 0x1d, 0x16, 0x52, 0xd3, 0x09, 0x28, 0xcf, 0xf4, 0x60, 0x18, 0xb4, - 0x31, 0x35, 0x11, 0xc1, 0x42, 0x6a, 0x3c, 0x7f, 0x45, 0x8d, 0x32, 0x4c, 0x21, 0x61, 0x0c, 0xd3, - 0x32, 0x01, 0x2c, 0xa4, 0x86, 0x7d, 0x57, 0x9e, 0xed, 0xc1, 0x30, 0x6c, 0x61, 0x5a, 0xc0, 0xf8, - 0x57, 0x23, 0x71, 0xd7, 0x95, 0x4f, 0x45, 0xe7, 0x0d, 0x09, 0xc5, 0xe6, 0x0d, 0x39, 0x42, 0xfb, - 0x64, 0x22, 0xb2, 0xac, 0xf2, 0xe9, 0xe8, 0x30, 0x8f, 0xa1, 0xd9, 0x30, 0x8f, 0xc7, 0xa2, 0x9d, - 0x4c, 0x44, 0xd8, 0x54, 0xae, 0x64, 0x31, 0x41, 0x74, 0x94, 0x09, 0x8f, 0xc9, 0x59, 0x4b, 0x09, - 0xf1, 0xa8, 0x7c, 0x26, 0xea, 0xd7, 0x9d, 0x20, 0x98, 0xe9, 0xd3, 0x52, 0x02, 0x43, 0x6a, 0xe9, - 0xf1, 0x8c, 0x94, 0xab, 0xd1, 0x61, 0x9b, 0x46, 0xc3, 0x86, 0x6d, 0x6a, 0x2c, 0xa4, 0xd9, 0xb4, - 0xc7, 0x27, 0xca, 0xb5, 0xa8, 0x61, 0x96, 0xa4, 0x60, 0x86, 0x59, 0xca, 0xa3, 0x15, 0x2d, 0x3d, - 0xc6, 0x8e, 0xf2, 0x5c, 0xcf, 0x16, 0x22, 0x4d, 0x4a, 0x0b, 0x79, 0xc8, 0x99, 0xd0, 0x76, 0xba, - 0xd7, 0x69, 0xd9, 0xba, 0xa1, 0x7c, 0x36, 0xd5, 0x76, 0xe2, 0x48, 0xc9, 0x76, 0xe2, 0x00, 0xb6, - 0xca, 0xcb, 0x6f, 0x1c, 0x94, 0xe7, 0xa3, 0xab, 0xbc, 0x8c, 0x63, 0xab, 0x7c, 0xe4, 0x3d, 0xc4, - 0x64, 0xe2, 0x3d, 0x80, 0xf2, 0x42, 0x54, 0x01, 0x62, 0x68, 0xa6, 0x00, 0xf1, 0x17, 0x04, 0x5f, - 0xcd, 0xf6, 0xa0, 0x57, 0xae, 0x23, 0xb7, 0xa7, 0x7d, 0x6e, 0x59, 0x74, 0x33, 0x7d, 0x5a, 0xb6, - 0x17, 0x7e, 0x2d, 0xc5, 0x21, 0x5e, 0xb9, 0x11, 0x55, 0xb0, 0x04, 0x01, 0x53, 0xb0, 0xa4, 0x1b, - 0x7d, 0x2d, 0xc5, 0xa3, 0x5d, 0xf9, 0x5c, 0x26, 0xab, 0xe0, 0x9b, 0x53, 0xfc, 0xe0, 0x6f, 0xc9, - 0x2e, 0xe9, 0xca, 0x8b, 0xd1, 0xc5, 0x2e, 0xc4, 0xb0, 0xc5, 0x4e, 0x72, 0x5d, 0xbf, 0x25, 0x3b, - 0x63, 0x2b, 0x37, 0x93, 0xa5, 0xc2, 0x25, 0x52, 0x72, 0xda, 0xd6, 0xd2, 0x7d, 0x98, 0x95, 0x97, - 0xa2, 0x5a, 0x97, 0x46, 0xc3, 0xb4, 0x2e, 0xd5, 0xff, 0x79, 0x3a, 0xe9, 0x8a, 0xac, 0xdc, 0x8a, - 0x6f, 0xb2, 0xa3, 0x78, 0x66, 0xf9, 0x24, 0xdc, 0x97, 0xbf, 0x18, 0x0f, 0xb6, 0xa7, 0xbc, 0x1c, - 0xbb, 0xf6, 0x8d, 0x60, 0x99, 0x7d, 0x1b, 0x0b, 0xce, 0xf7, 0xc5, 0x78, 0x7c, 0x3a, 0xe5, 0x95, - 0x74, 0x0e, 0x81, 0xae, 0xc4, 0xe3, 0xd9, 0x7d, 0x31, 0x1e, 0xd2, 0x4d, 0x79, 0x35, 0x9d, 0x43, - 0x20, 0xdd, 0x78, 0x08, 0xb8, 0x17, 0xa5, 0x20, 0xf3, 0xca, 0xe7, 0xa3, 0xa6, 0x63, 0x80, 0x60, - 0xa6, 0x63, 0x18, 0x8a, 0xfe, 0x45, 0x29, 0x38, 0xbb, 0xf2, 0x5a, 0xa2, 0x48, 0xd0, 0x58, 0x29, - 0x84, 0xfb, 0x8b, 0x52, 0x50, 0x73, 0xe5, 0xf5, 0x44, 0x91, 0xa0, 0x75, 0x52, 0xe8, 0x73, 0xa3, - 0xd7, 0xfb, 0x55, 0xe5, 0x8d, 0xe8, 0x61, 0x70, 0x36, 0xe5, 0x4c, 0x9f, 0xd6, 0xeb, 0x1d, 0xec, - 0x57, 0xb3, 0x1d, 0xbb, 0x95, 0x37, 0xa3, 0x43, 0x38, 0x8b, 0x8e, 0x0d, 0xe1, 0x4c, 0xe7, 0xf0, - 0xb7, 0x62, 0xb1, 0x2c, 0x94, 0xb7, 0xa2, 0x53, 0x5c, 0x04, 0xc9, 0xa6, 0xb8, 0x78, 0xe4, 0x8b, - 0x48, 0x90, 0x06, 0xe5, 0x0b, 0xd1, 0x29, 0x4e, 0xc6, 0xb1, 0x29, 0x2e, 0x12, 0xd0, 0x61, 0x32, - 0x11, 0x3b, 0x40, 0x79, 0x3b, 0x3a, 0xc5, 0xc5, 0xd0, 0x6c, 0x8a, 0x8b, 0x47, 0x1b, 0x78, 0x2b, - 0xf6, 0x84, 0x5e, 0xf9, 0x62, 0x7a, 0xfb, 0x11, 0x29, 0xb7, 0x9f, 0x3f, 0xb8, 0xd7, 0xd2, 0xdf, - 0x82, 0x2b, 0x95, 0xe8, 0xf8, 0x4d, 0xa3, 0x61, 0xe3, 0x37, 0xf5, 0x1d, 0x79, 0x7c, 0xe3, 0x20, - 0xb4, 0x6a, 0xa2, 0xc7, 0xc6, 0x21, 0x34, 0x45, 0x52, 0xc0, 0x91, 0x3d, 0x32, 0xdf, 0x08, 0x4d, - 0x66, 0xec, 0x91, 0xfd, 0x6d, 0x50, 0x8c, 0x9e, 0xcd, 0xae, 0x09, 0x3f, 0x63, 0xa5, 0x1a, 0x9d, - 0x5d, 0x13, 0x04, 0x6c, 0x76, 0x4d, 0x7a, 0x27, 0x4f, 0xc3, 0x98, 0xd0, 0x22, 0xee, 0x3e, 0x6d, - 0x5a, 0xab, 0xca, 0x54, 0xec, 0xbd, 0x65, 0x0c, 0xcf, 0x66, 0xa7, 0x38, 0x0c, 0xd7, 0x6b, 0x0e, - 0x9b, 0x6c, 0x99, 0x9d, 0x65, 0x5b, 0x77, 0x8c, 0x3a, 0xb5, 0x0c, 0x65, 0x3a, 0xb6, 0x5e, 0xa7, - 0xd0, 0xe0, 0x7a, 0x9d, 0x02, 0xc7, 0x10, 0x71, 0x31, 0xb8, 0x46, 0x9b, 0xd4, 0x7c, 0x44, 0x95, - 0xdb, 0xc8, 0x76, 0x3c, 0x8b, 0xad, 0x20, 0x9b, 0xe9, 0xd3, 0xb2, 0x38, 0x30, 0x5b, 0x7d, 0x6e, - 0xa3, 0xfe, 0xce, 0x6c, 0x10, 0x7e, 0x60, 0xd1, 0xa1, 0x1d, 0xdd, 0xa1, 0xca, 0x4c, 0xd4, 0x56, - 0x4f, 0x25, 0x62, 0xb6, 0x7a, 0x2a, 0x22, 0xc9, 0xd6, 0x1f, 0x0b, 0xb5, 0x5e, 0x6c, 0xc3, 0x11, - 0x91, 0x5e, 0x9a, 0xcd, 0x4e, 0x51, 0x04, 0x13, 0xd0, 0xac, 0x6d, 0xad, 0xe2, 0x49, 0xc5, 0x9d, - 0xe8, 0xec, 0x94, 0x4d, 0xc9, 0x66, 0xa7, 0x6c, 0x2c, 0x53, 0xf5, 0x28, 0x96, 0x8f, 0xc1, 0xbb, - 0x51, 0x55, 0x4f, 0x21, 0x61, 0xaa, 0x9e, 0x02, 0x4e, 0x32, 0xd4, 0xa8, 0x4b, 0x3d, 0x65, 0xb6, - 0x17, 0x43, 0x24, 0x49, 0x32, 0x44, 0x70, 0x92, 0xe1, 0x34, 0xf5, 0x9a, 0x6b, 0xca, 0x5c, 0x2f, - 0x86, 0x48, 0x92, 0x64, 0x88, 0x60, 0xb6, 0xd9, 0x8c, 0x82, 0x27, 0xba, 0xad, 0x87, 0x7e, 0x9f, - 0xcd, 0x47, 0x37, 0x9b, 0x99, 0x84, 0x6c, 0xb3, 0x99, 0x89, 0x24, 0x3f, 0xb9, 0x63, 0x3f, 0x78, - 0x65, 0x01, 0x2b, 0xbc, 0x1e, 0xda, 0x05, 0x3b, 0x29, 0x35, 0xd3, 0xa7, 0xed, 0xd4, 0xcf, 0xfe, - 0xb3, 0x81, 0xd3, 0xa8, 0xb2, 0x88, 0x55, 0x9d, 0x0a, 0xce, 0x2a, 0x38, 0x78, 0xa6, 0x4f, 0x0b, - 0xdc, 0x4a, 0x5f, 0x85, 0x21, 0xfc, 0xa8, 0x9a, 0x65, 0x7a, 0xd5, 0x09, 0xe5, 0x9d, 0xe8, 0x96, - 0x49, 0x42, 0xb1, 0x2d, 0x93, 0xf4, 0x93, 0x4d, 0xe2, 0xf8, 0x93, 0x4f, 0x31, 0xd5, 0x09, 0x45, - 0x8b, 0x4e, 0xe2, 0x11, 0x24, 0x9b, 0xc4, 0x23, 0x80, 0xa0, 0xde, 0xaa, 0x63, 0x77, 0xaa, 0x13, - 0x4a, 0x3d, 0xa5, 0x5e, 0x8e, 0x0a, 0xea, 0xe5, 0x3f, 0x83, 0x7a, 0xeb, 0x6b, 0x5d, 0xaf, 0xca, - 0xbe, 0x71, 0x29, 0xa5, 0x5e, 0x1f, 0x19, 0xd4, 0xeb, 0x03, 0xd8, 0x54, 0x88, 0x80, 0x45, 0xc7, - 0x66, 0x93, 0xf6, 0x5d, 0xb3, 0xd5, 0x52, 0xee, 0x45, 0xa7, 0xc2, 0x38, 0x9e, 0x4d, 0x85, 0x71, - 0x18, 0x33, 0x3d, 0x79, 0xab, 0xe8, 0x72, 0x77, 0x55, 0xb9, 0x1f, 0x35, 0x3d, 0x43, 0x0c, 0x33, - 0x3d, 0xc3, 0x5f, 0xb8, 0xbb, 0x60, 0xbf, 0x34, 0xba, 0xe2, 0x50, 0x77, 0x4d, 0x79, 0x10, 0xdb, - 0x5d, 0x48, 0x38, 0xdc, 0x5d, 0x48, 0xbf, 0xc9, 0x2a, 0x3c, 0x11, 0x59, 0x68, 0xfc, 0x4b, 0x9b, - 0x3a, 0xd5, 0x9d, 0xe6, 0x9a, 0xf2, 0x25, 0x64, 0xf5, 0x6c, 0xea, 0x52, 0x15, 0x25, 0x9d, 0xe9, - 0xd3, 0x7a, 0x71, 0xc2, 0x6d, 0xf9, 0x3b, 0xb3, 0x3c, 0x12, 0xac, 0xb6, 0x38, 0xe9, 0x6f, 0x42, - 0xdf, 0x8d, 0x6d, 0xcb, 0x93, 0x24, 0xb8, 0x2d, 0x4f, 0x82, 0x49, 0x07, 0x9e, 0x8a, 0x6d, 0xd5, - 0xe6, 0xf4, 0x16, 0xdb, 0x97, 0x50, 0x63, 0x51, 0x6f, 0x3e, 0xa4, 0x9e, 0xf2, 0x65, 0xe4, 0x7d, - 0x25, 0x63, 0xc3, 0x17, 0xa3, 0x9e, 0xe9, 0xd3, 0xb6, 0xe1, 0x47, 0x54, 0x28, 0xd6, 0xa7, 0x97, - 0x16, 0x95, 0x1f, 0x8a, 0x9e, 0x6f, 0x32, 0xd8, 0x4c, 0x9f, 0x86, 0x38, 0x66, 0xa5, 0xdd, 0xeb, - 0xac, 0x3a, 0xba, 0x41, 0xb9, 0xa1, 0x85, 0xb6, 0x9b, 0x30, 0x40, 0x7f, 0x38, 0x6a, 0xa5, 0x65, - 0xd1, 0x31, 0x2b, 0x2d, 0x0b, 0xc7, 0x14, 0x35, 0x92, 0xf4, 0x44, 0xf9, 0x4a, 0x54, 0x51, 0x23, - 0x48, 0xa6, 0xa8, 0xd1, 0x14, 0x29, 0x5f, 0x82, 0xf3, 0xc1, 0x7e, 0x5e, 0xac, 0xbf, 0xbc, 0xd3, - 0x94, 0xaf, 0x22, 0x9f, 0xa7, 0x12, 0x97, 0x01, 0x11, 0xaa, 0x99, 0x3e, 0x2d, 0xa3, 0x3c, 0x5b, - 0x71, 0x13, 0xf9, 0xbc, 0x84, 0x79, 0xf1, 0x23, 0xd1, 0x15, 0x37, 0x83, 0x8c, 0xad, 0xb8, 0x19, - 0xa8, 0x54, 0xe6, 0x42, 0xa8, 0xfa, 0x36, 0xcc, 0x03, 0x99, 0x66, 0x71, 0x48, 0x65, 0x2e, 0x2c, - 0xb5, 0xe5, 0x6d, 0x98, 0x07, 0xd6, 0x5a, 0x16, 0x07, 0x72, 0x15, 0x4a, 0xf5, 0xfa, 0x9c, 0xd6, - 0xb5, 0x94, 0x66, 0xcc, 0x5b, 0x16, 0xa1, 0x33, 0x7d, 0x9a, 0xc0, 0x33, 0x33, 0x68, 0xaa, 0xa5, - 0xbb, 0x9e, 0xd9, 0x74, 0x71, 0xc4, 0xf8, 0x23, 0xc4, 0x88, 0x9a, 0x41, 0x69, 0x34, 0xcc, 0x0c, - 0x4a, 0x83, 0x33, 0x7b, 0x71, 0x52, 0x77, 0x5d, 0xdd, 0x32, 0x1c, 0x7d, 0x02, 0x97, 0x09, 0x1a, - 0x7b, 0x8d, 0x15, 0xc1, 0x32, 0x7b, 0x31, 0x0a, 0xc1, 0xc3, 0x77, 0x1f, 0xe2, 0x9b, 0x39, 0x2b, - 0xb1, 0xc3, 0xf7, 0x18, 0x1e, 0x0f, 0xdf, 0x63, 0x30, 0xb4, 0x3b, 0x7d, 0x98, 0x46, 0x57, 0x4d, - 0x26, 0x22, 0x65, 0x35, 0x66, 0x77, 0xc6, 0x09, 0xd0, 0xee, 0x8c, 0x03, 0x23, 0x4d, 0xf2, 0x97, - 0xdb, 0xb5, 0x8c, 0x26, 0x85, 0xab, 0x6c, 0xa2, 0x0c, 0x5b, 0xbf, 0xc3, 0xc1, 0x51, 0xdd, 0xb0, - 0xf4, 0xb6, 0x5d, 0x9d, 0xf0, 0xa5, 0x6e, 0x46, 0xd7, 0xef, 0x4c, 0x42, 0xb6, 0x7e, 0x67, 0x22, - 0xd9, 0xec, 0xea, 0x6f, 0xb4, 0xd6, 0x74, 0x87, 0x1a, 0x55, 0xd3, 0xc1, 0x93, 0xc5, 0x0d, 0xbe, - 0x35, 0x7c, 0x2f, 0x3a, 0xbb, 0xf6, 0x20, 0x65, 0xb3, 0x6b, 0x0f, 0x34, 0x33, 0xf2, 0xd2, 0xd1, - 0x1a, 0xd5, 0x0d, 0xe5, 0x61, 0xd4, 0xc8, 0xcb, 0xa6, 0x64, 0x46, 0x5e, 0x36, 0x36, 0xfb, 0x73, - 0x1e, 0x38, 0xa6, 0x47, 0x95, 0xd6, 0x4e, 0x3e, 0x07, 0x49, 0xb3, 0x3f, 0x07, 0xd1, 0x6c, 0x43, - 0x18, 0xef, 0x90, 0x76, 0x74, 0x43, 0x98, 0xec, 0x86, 0x78, 0x09, 0x66, 0xb1, 0x88, 0x47, 0x79, - 0x8a, 0x15, 0xb5, 0x58, 0x04, 0x98, 0x59, 0x2c, 0xe1, 0xb3, 0xbd, 0xc8, 0x53, 0x2c, 0xc5, 0x8e, - 0xae, 0xa1, 0x32, 0x8e, 0xad, 0xa1, 0x91, 0x67, 0x5b, 0xaf, 0x46, 0xde, 0x19, 0x28, 0x9d, 0xa8, - 0xd5, 0x21, 0xa1, 0x98, 0xd5, 0x21, 0xbf, 0x48, 0x98, 0x84, 0x53, 0x78, 0x0b, 0xae, 0x75, 0x83, - 0x7b, 0x9c, 0x1f, 0x8d, 0x7e, 0x66, 0x0c, 0xcd, 0x3e, 0x33, 0x06, 0x8a, 0x30, 0x11, 0xd3, 0x96, - 0x93, 0xc1, 0x24, 0x3c, 0x1f, 0x8c, 0x81, 0xc8, 0x2c, 0x90, 0x7a, 0x65, 0x6e, 0xb6, 0x66, 0x2c, - 0xca, 0x57, 0x64, 0x6e, 0xf4, 0x04, 0x36, 0x49, 0x31, 0xd3, 0xa7, 0xa5, 0x94, 0x23, 0xef, 0xc1, - 0x65, 0x01, 0x15, 0x2f, 0xae, 0x31, 0xed, 0xbf, 0x11, 0x2c, 0x08, 0x5e, 0xd4, 0x8f, 0xad, 0x17, - 0xed, 0x4c, 0x9f, 0xd6, 0x93, 0x57, 0x76, 0x5d, 0x62, 0x7d, 0xe8, 0xee, 0xa4, 0xae, 0x60, 0x91, - 0xe8, 0xc9, 0x2b, 0xbb, 0x2e, 0x21, 0xf7, 0x47, 0x3b, 0xa9, 0x2b, 0xe8, 0x84, 0x9e, 0xbc, 0x88, - 0x0b, 0xe3, 0xbd, 0xf0, 0x95, 0x56, 0x4b, 0x59, 0xc7, 0xea, 0x3e, 0xb3, 0x93, 0xea, 0x2a, 0x68, - 0x70, 0x6e, 0xc7, 0x91, 0xcd, 0xd2, 0x0b, 0x1d, 0x6a, 0xd5, 0x23, 0x0b, 0xd0, 0xe3, 0xe8, 0x2c, - 0x9d, 0x20, 0x60, 0xb3, 0x74, 0x02, 0xc8, 0x06, 0x94, 0xfc, 0x5c, 0x45, 0xd9, 0x88, 0x0e, 0x28, - 0x19, 0xc7, 0x06, 0x54, 0xe4, 0x69, 0xcb, 0x02, 0x9c, 0x59, 0x78, 0xe8, 0xe9, 0xbe, 0x05, 0xe9, - 0x8a, 0xae, 0x7c, 0x3f, 0x76, 0xc9, 0x94, 0x24, 0xc1, 0x4b, 0xa6, 0x24, 0x98, 0x8d, 0x11, 0x06, - 0xae, 0x6f, 0x58, 0xcd, 0x69, 0xdd, 0x6c, 0x75, 0x1d, 0xaa, 0xfc, 0x6b, 0xd1, 0x31, 0x12, 0x43, - 0xb3, 0x31, 0x12, 0x03, 0xb1, 0x05, 0x9a, 0x81, 0x2a, 0xae, 0x6b, 0xae, 0x5a, 0x62, 0x5f, 0xd9, - 0x6d, 0x79, 0xca, 0xbf, 0x1e, 0x5d, 0xa0, 0xd3, 0x68, 0xd8, 0x02, 0x9d, 0x06, 0xc7, 0x53, 0x27, - 0xd6, 0x0b, 0x6c, 0xf1, 0x90, 0xef, 0x2a, 0xff, 0x8d, 0xd8, 0xa9, 0x53, 0x0a, 0x0d, 0x9e, 0x3a, - 0xa5, 0xc0, 0xd9, 0xfa, 0xc8, 0x6d, 0xb2, 0x59, 0x33, 0xb8, 0xab, 0xfe, 0x37, 0xa3, 0xeb, 0x63, - 0x1c, 0xcf, 0xd6, 0xc7, 0x38, 0x2c, 0xca, 0x47, 0x74, 0xc1, 0xbf, 0x95, 0xc5, 0x27, 0x90, 0x7f, - 0xa2, 0x0c, 0xb9, 0x2d, 0xf3, 0x11, 0x23, 0xe5, 0xc7, 0x72, 0x59, 0x8c, 0x82, 0xe1, 0x91, 0x28, - 0x14, 0x65, 0xa4, 0xd1, 0x47, 0x26, 0x5d, 0x57, 0xbe, 0x96, 0xc9, 0x88, 0x13, 0x44, 0x19, 0x71, - 0x18, 0x79, 0x17, 0xce, 0x87, 0xb0, 0x39, 0xda, 0x5e, 0x0e, 0x66, 0xa6, 0x3f, 0x91, 0x8b, 0x9a, - 0xc1, 0xe9, 0x64, 0xcc, 0x0c, 0x4e, 0xc7, 0xa4, 0xb1, 0x16, 0xa2, 0xfb, 0xb7, 0xb7, 0x61, 0x1d, - 0x48, 0x30, 0x83, 0x41, 0x1a, 0x6b, 0x21, 0xcd, 0x1f, 0xdf, 0x86, 0x75, 0x20, 0xd3, 0x0c, 0x06, - 0xe4, 0xa7, 0x72, 0x70, 0x25, 0x1d, 0x55, 0x69, 0xb5, 0xa6, 0x6d, 0x27, 0xc4, 0x29, 0x7f, 0x32, - 0x17, 0x3d, 0x68, 0xd8, 0x59, 0xb1, 0x99, 0x3e, 0x6d, 0x87, 0x15, 0x90, 0x2f, 0xc0, 0x48, 0xa5, - 0x6b, 0x98, 0x1e, 0x5e, 0xbc, 0x31, 0xc3, 0xf9, 0x27, 0x72, 0xb1, 0x2d, 0x8e, 0x8c, 0xc5, 0x2d, - 0x8e, 0x0c, 0x20, 0x77, 0xe0, 0x74, 0x9d, 0x36, 0xbb, 0x8e, 0xe9, 0x6d, 0x68, 0xb4, 0x63, 0x3b, - 0x1e, 0xe3, 0xf1, 0xa7, 0x72, 0xd1, 0x49, 0x2c, 0x41, 0xc1, 0x26, 0xb1, 0x04, 0x90, 0xdc, 0x4f, - 0xdc, 0xca, 0x8b, 0xce, 0xfc, 0xc9, 0x5c, 0xcf, 0x6b, 0xf9, 0xa0, 0x2f, 0xd3, 0x8b, 0x93, 0xc5, - 0xd8, 0x2d, 0xba, 0xe0, 0xfa, 0x53, 0xb9, 0x1e, 0xd7, 0xe8, 0xd2, 0x0c, 0x97, 0x04, 0x33, 0x8e, - 0x29, 0x19, 0xe0, 0x95, 0x3f, 0x9d, 0xeb, 0x71, 0xed, 0x1d, 0x72, 0x4c, 0x4b, 0x1e, 0xff, 0x32, - 0xf7, 0x14, 0x11, 0x8c, 0x7e, 0x3a, 0x97, 0x74, 0x15, 0x09, 0xca, 0x4b, 0x84, 0xac, 0xd8, 0x3d, - 0x37, 0x50, 0xfa, 0x0f, 0x72, 0x49, 0xdf, 0xbc, 0xb0, 0x58, 0xf8, 0x8b, 0x50, 0xb8, 0x34, 0xf5, - 0xd8, 0xa3, 0x8e, 0xa5, 0xb7, 0xb0, 0x3b, 0xeb, 0x9e, 0xed, 0xe8, 0xab, 0x74, 0xca, 0xd2, 0x97, - 0x5b, 0x54, 0xf9, 0x7a, 0x2e, 0x6a, 0xc1, 0x66, 0x93, 0x32, 0x0b, 0x36, 0x1b, 0x4b, 0xd6, 0xe0, - 0x89, 0x34, 0x6c, 0xd5, 0x74, 0xb1, 0x9e, 0x6f, 0xe4, 0xa2, 0x26, 0x6c, 0x0f, 0x5a, 0x66, 0xc2, - 0xf6, 0x40, 0x93, 0x9b, 0x30, 0x38, 0x61, 0xfb, 0xd3, 0xef, 0x9f, 0x89, 0x39, 0x43, 0x06, 0x98, - 0x99, 0x3e, 0x2d, 0x24, 0x13, 0x65, 0xc4, 0xa0, 0xfe, 0x66, 0xb2, 0x4c, 0x78, 0xf9, 0x14, 0xfc, - 0x10, 0x65, 0x84, 0xb8, 0xff, 0x9d, 0x64, 0x99, 0xf0, 0x8e, 0x2b, 0xf8, 0xc1, 0x66, 0x12, 0x5e, - 0xe3, 0xdc, 0x74, 0x85, 0xd9, 0x6d, 0x93, 0x6b, 0x7a, 0xab, 0x45, 0xad, 0x55, 0xaa, 0x7c, 0x2b, - 0x36, 0x93, 0xa4, 0x93, 0xb1, 0x99, 0x24, 0x1d, 0x43, 0x7e, 0x18, 0x2e, 0xdc, 0xd7, 0x5b, 0xa6, - 0x11, 0xe2, 0xfc, 0x7c, 0xe0, 0xca, 0xcf, 0xe4, 0xa2, 0xbb, 0xe9, 0x0c, 0x3a, 0xb6, 0x9b, 0xce, - 0x40, 0x91, 0x39, 0x20, 0xb8, 0x8c, 0x06, 0xb3, 0x05, 0x5b, 0x9f, 0x95, 0x7f, 0x37, 0x17, 0xb5, - 0x53, 0x93, 0x24, 0xcc, 0x4e, 0x4d, 0x42, 0x49, 0x23, 0x3b, 0x35, 0x88, 0xf2, 0xb3, 0xb9, 0xe8, - 0x69, 0x4d, 0x16, 0xe1, 0x4c, 0x9f, 0x96, 0x9d, 0x5f, 0xe4, 0x36, 0x8c, 0xd5, 0x17, 0x6b, 0xd3, - 0xd3, 0x53, 0xf5, 0xfb, 0xb5, 0x2a, 0x3e, 0x74, 0x30, 0x94, 0x3f, 0x1b, 0x5b, 0xb1, 0xe2, 0x04, - 0x6c, 0xc5, 0x8a, 0xc3, 0xc8, 0x1b, 0x30, 0xcc, 0xda, 0xcf, 0x06, 0x0c, 0x7e, 0xf2, 0xcf, 0xe5, - 0xa2, 0xe6, 0x94, 0x8c, 0x64, 0xe6, 0x94, 0xfc, 0x9b, 0xd4, 0xe1, 0x2c, 0x93, 0xe2, 0xa2, 0x43, - 0x57, 0xa8, 0x43, 0xad, 0xa6, 0x3f, 0xa6, 0x7f, 0x3e, 0x17, 0xb5, 0x32, 0xd2, 0x88, 0x98, 0x95, - 0x91, 0x06, 0x27, 0x0f, 0xe1, 0x72, 0xfc, 0x24, 0x48, 0x7e, 0x76, 0xaa, 0xfc, 0xb9, 0x5c, 0xcc, - 0x18, 0xee, 0x41, 0x8c, 0xc6, 0x70, 0x0f, 0x3c, 0xb1, 0xe0, 0x49, 0x71, 0xac, 0x22, 0x1c, 0x2e, - 0xe3, 0xb5, 0xfd, 0x79, 0x5e, 0xdb, 0xa7, 0x43, 0x87, 0xc0, 0x1e, 0xd4, 0x33, 0x7d, 0x5a, 0x6f, - 0x76, 0x4c, 0xcf, 0x92, 0x09, 0x30, 0x94, 0x5f, 0xc8, 0xa5, 0x7b, 0xa4, 0x44, 0xdc, 0x94, 0xd3, - 0x32, 0x67, 0xbc, 0x9b, 0x95, 0xbe, 0x41, 0xf9, 0x0b, 0xb1, 0xf1, 0x96, 0x4e, 0xc6, 0xc6, 0x5b, - 0x46, 0xfe, 0x87, 0x3b, 0x70, 0x9a, 0x2b, 0xf5, 0xa2, 0x8e, 0xc3, 0xd0, 0x5a, 0xa5, 0x86, 0xf2, - 0xef, 0xc5, 0x56, 0xbb, 0x04, 0x05, 0xba, 0xf6, 0xc4, 0x81, 0x6c, 0xea, 0xae, 0x77, 0x74, 0xcb, - 0xc2, 0x63, 0x56, 0xe5, 0xdf, 0x8f, 0x4d, 0xdd, 0x21, 0x0a, 0x1d, 0x77, 0x83, 0x5f, 0x4c, 0x13, - 0x7a, 0xa5, 0x3e, 0x52, 0xfe, 0x62, 0x4c, 0x13, 0x7a, 0x11, 0x33, 0x4d, 0xe8, 0x99, 0x47, 0xe9, - 0x7e, 0xc6, 0x13, 0x70, 0xe5, 0x17, 0x63, 0x2b, 0x72, 0x2a, 0x15, 0x5b, 0x91, 0xd3, 0x5f, 0x90, - 0xdf, 0xcf, 0x78, 0x3e, 0xad, 0xfc, 0x52, 0x6f, 0xbe, 0xe1, 0x4a, 0x9f, 0xfe, 0xfa, 0xfa, 0x7e, - 0xc6, 0xd3, 0x63, 0xe5, 0x2f, 0xf5, 0xe6, 0x1b, 0x3a, 0xf6, 0xa5, 0xbf, 0x5c, 0x6e, 0x64, 0x3f, - 0xdb, 0x55, 0xfe, 0x72, 0x7c, 0xea, 0xca, 0x20, 0xc4, 0xa9, 0x2b, 0xeb, 0xed, 0xef, 0x32, 0x5c, - 0xe4, 0x1a, 0x72, 0xdb, 0xd1, 0x3b, 0x6b, 0x75, 0xea, 0x79, 0xa6, 0xb5, 0xea, 0xef, 0xc4, 0xfe, - 0x4a, 0x2e, 0x76, 0x3c, 0x96, 0x45, 0x89, 0xc7, 0x63, 0x59, 0x48, 0xa6, 0xbc, 0x89, 0x07, 0xba, - 0xca, 0x5f, 0x8d, 0x29, 0x6f, 0x82, 0x82, 0x29, 0x6f, 0xf2, 0x5d, 0xef, 0x9d, 0x94, 0x77, 0xa8, - 0xca, 0x7f, 0x90, 0xcd, 0x2b, 0x68, 0x5f, 0xca, 0xf3, 0xd5, 0x3b, 0x29, 0xcf, 0x2d, 0x95, 0xff, - 0x30, 0x9b, 0x57, 0xe8, 0x83, 0x94, 0x7c, 0xa5, 0xf9, 0x2e, 0x9c, 0xe7, 0xb3, 0xf9, 0x34, 0x35, - 0x68, 0xe4, 0x43, 0x7f, 0x39, 0x36, 0xf6, 0xd3, 0xc9, 0xf0, 0xc8, 0x3d, 0x15, 0x93, 0xc6, 0x5a, - 0xb4, 0xf5, 0xaf, 0x6d, 0xc3, 0x3a, 0xdc, 0x10, 0xa4, 0x63, 0xd8, 0x7a, 0x23, 0x3f, 0x7e, 0x53, - 0x7e, 0x25, 0xb6, 0xde, 0xc8, 0x48, 0x74, 0xe7, 0x90, 0x5f, 0xca, 0xbd, 0x11, 0x7d, 0xe8, 0xa5, - 0xfc, 0x47, 0xa9, 0x85, 0x83, 0x0e, 0x88, 0xbe, 0x0a, 0x7b, 0x23, 0xfa, 0xa8, 0x49, 0xf9, 0xd5, - 0xd4, 0xc2, 0xc1, 0x07, 0x44, 0x5f, 0x40, 0xb1, 0x2d, 0x52, 0xd7, 0xb3, 0x39, 0xab, 0xc8, 0xf4, - 0xf0, 0xd7, 0xe3, 0x5b, 0xa4, 0x54, 0x32, 0xdc, 0x22, 0xa5, 0x62, 0xd2, 0x58, 0x8b, 0xcf, 0xfb, - 0xb5, 0x6d, 0x58, 0x4b, 0x1b, 0xbb, 0x54, 0x4c, 0x1a, 0x6b, 0xf1, 0xf1, 0xbf, 0xbe, 0x0d, 0x6b, - 0x69, 0x63, 0x97, 0x8a, 0x61, 0xe6, 0x58, 0x88, 0xb9, 0x4f, 0x1d, 0x37, 0x54, 0xbf, 0xbf, 0x11, - 0x33, 0xc7, 0x32, 0xe8, 0x98, 0x39, 0x96, 0x81, 0x4a, 0xe5, 0x2e, 0x84, 0xf2, 0x1b, 0xdb, 0x71, - 0x0f, 0xef, 0x65, 0x32, 0x50, 0xa9, 0xdc, 0x85, 0x5c, 0xfe, 0xe6, 0x76, 0xdc, 0xc3, 0x8b, 0x99, - 0x0c, 0x14, 0x33, 0x8a, 0xea, 0x9e, 0xee, 0x99, 0xcd, 0x19, 0xdb, 0xf5, 0xa4, 0x45, 0xfe, 0x6f, - 0xc5, 0x8c, 0xa2, 0x34, 0x22, 0x66, 0x14, 0xa5, 0xc1, 0x93, 0x4c, 0x85, 0x34, 0x7e, 0xb3, 0x27, - 0xd3, 0xd0, 0xd2, 0x4a, 0x83, 0x27, 0x99, 0x0a, 0x21, 0xfc, 0xc7, 0x3d, 0x99, 0x86, 0x9e, 0xf2, - 0x69, 0x70, 0x66, 0x99, 0x4e, 0x3a, 0xf6, 0xba, 0x75, 0x87, 0xae, 0xd3, 0x96, 0xf8, 0xf4, 0xdf, - 0x8a, 0x59, 0xa6, 0x71, 0x02, 0xbc, 0x45, 0x89, 0xc1, 0xa2, 0x8c, 0xc4, 0xe7, 0xfe, 0x76, 0x26, - 0xa3, 0xf0, 0x98, 0x28, 0x0e, 0x8b, 0x32, 0x12, 0x9f, 0xf8, 0x3b, 0x99, 0x8c, 0xc2, 0x63, 0xa2, - 0x38, 0x8c, 0x54, 0x60, 0x14, 0xdf, 0x4a, 0xe8, 0xae, 0xef, 0xf9, 0xf9, 0xfb, 0xb9, 0xe8, 0xad, - 0x57, 0x14, 0x3d, 0xd3, 0xa7, 0xc5, 0x0a, 0xc8, 0x2c, 0xc4, 0x27, 0x7d, 0x27, 0x83, 0x45, 0xe8, - 0xef, 0x18, 0x85, 0xc8, 0x2c, 0xc4, 0xc7, 0xfc, 0x27, 0x19, 0x2c, 0x42, 0x87, 0xc7, 0x28, 0x64, - 0x62, 0x00, 0xfa, 0xf1, 0x40, 0xf4, 0x4e, 0xa9, 0xfc, 0xed, 0xdc, 0xd8, 0xef, 0xe6, 0xee, 0x94, - 0xca, 0xbf, 0x9b, 0x1b, 0xfb, 0x3d, 0xf6, 0xff, 0xef, 0xe5, 0xc6, 0x7e, 0x3f, 0xa7, 0x5d, 0x0c, - 0x95, 0xbb, 0xb2, 0x4a, 0x2d, 0x6f, 0xb1, 0xa5, 0x8b, 0xa1, 0x99, 0x8a, 0xe2, 0x3f, 0x53, 0x51, - 0x22, 0xa1, 0xd5, 0x2f, 0xe6, 0x60, 0xb8, 0xee, 0x39, 0x54, 0x6f, 0x8b, 0xf8, 0x70, 0x97, 0xa0, - 0xcc, 0x5d, 0x98, 0xfd, 0xf7, 0xd6, 0x5a, 0xf0, 0x9b, 0x5c, 0x81, 0xd1, 0x59, 0xdd, 0xf5, 0xb0, - 0x89, 0x35, 0xcb, 0xa0, 0x8f, 0xf1, 0xf9, 0x5e, 0x41, 0x8b, 0x41, 0xc9, 0x2c, 0xa7, 0xe3, 0xe5, - 0x30, 0x24, 0x68, 0x61, 0xdb, 0xb0, 0x68, 0xe5, 0x0f, 0x37, 0xc7, 0xfb, 0x30, 0x0a, 0x5a, 0xac, - 0xac, 0xfa, 0x07, 0x39, 0x48, 0x38, 0x57, 0xef, 0x3d, 0x0e, 0xc2, 0x02, 0x9c, 0x8a, 0x85, 0xa1, - 0x15, 0x6f, 0x10, 0x77, 0x18, 0xa5, 0x36, 0x5e, 0x9a, 0x7c, 0x26, 0x78, 0xfb, 0x76, 0x4f, 0x9b, - 0x15, 0x21, 0xef, 0x30, 0x59, 0x43, 0xd7, 0x69, 0x69, 0x12, 0x4a, 0x84, 0x34, 0xfa, 0xc1, 0x58, - 0x18, 0x63, 0x93, 0x5c, 0x11, 0x41, 0x19, 0x72, 0x61, 0xa0, 0xbc, 0x58, 0x6a, 0x78, 0x1e, 0x84, - 0xe1, 0x0b, 0x30, 0x5c, 0x6b, 0x77, 0xa8, 0xe3, 0xda, 0x96, 0xee, 0xd9, 0x8e, 0x78, 0xd3, 0x8e, - 0x41, 0xd4, 0x4c, 0x09, 0x2e, 0x07, 0xf6, 0x92, 0xe9, 0xc9, 0x35, 0x3f, 0xdf, 0x5c, 0x01, 0xa3, - 0x9b, 0xe2, 0xc3, 0xd4, 0x78, 0xba, 0x71, 0x4e, 0xc1, 0x48, 0xef, 0xb9, 0x3a, 0xbe, 0x92, 0x0c, - 0x48, 0xbb, 0x0c, 0x20, 0x93, 0x22, 0x05, 0x79, 0x1e, 0x4a, 0x78, 0xab, 0xe4, 0x62, 0x1e, 0x49, - 0x11, 0xbe, 0xaf, 0x85, 0x10, 0x39, 0x58, 0x1a, 0xa7, 0x21, 0x77, 0x61, 0x2c, 0xbc, 0x32, 0xbf, - 0xed, 0xd8, 0xdd, 0x8e, 0x9f, 0x39, 0x06, 0xd3, 0xb4, 0x3f, 0x0c, 0x70, 0x8d, 0x55, 0x44, 0x4a, - 0x2c, 0x12, 0x05, 0xc9, 0x0c, 0x9c, 0x0a, 0x61, 0x4c, 0x44, 0x7e, 0xc6, 0x2a, 0xcc, 0x16, 0x2a, - 0xf1, 0x62, 0xe2, 0x8c, 0x64, 0x0b, 0x8d, 0x15, 0x23, 0x35, 0x18, 0xf0, 0x63, 0xf7, 0x95, 0xb7, - 0x55, 0xd2, 0x33, 0x22, 0x76, 0xdf, 0x80, 0x1c, 0xb5, 0xcf, 0x2f, 0x4f, 0xa6, 0x61, 0x54, 0xb3, - 0xbb, 0x1e, 0x5d, 0xb2, 0xc5, 0x5e, 0x53, 0xc4, 0x88, 0xc4, 0x36, 0x39, 0x0c, 0xd3, 0xf0, 0x6c, - 0x3f, 0xcb, 0xbd, 0x9c, 0x6d, 0x3d, 0x5a, 0x8a, 0xcc, 0xc3, 0xe9, 0x84, 0x73, 0x81, 0x9c, 0x7b, - 0x5e, 0xfa, 0xbc, 0x24, 0xb3, 0x64, 0x51, 0xf2, 0x13, 0x39, 0x28, 0x2d, 0x39, 0xba, 0xe9, 0xb9, - 0xe2, 0x81, 0xe5, 0xb9, 0xeb, 0xeb, 0x8e, 0xde, 0x61, 0xfa, 0x71, 0x1d, 0xc3, 0xd7, 0xde, 0xd7, - 0x5b, 0x5d, 0xea, 0x4e, 0x3c, 0x60, 0x5f, 0xf7, 0xdf, 0x6f, 0x8e, 0xbf, 0xb1, 0x8a, 0x47, 0x98, - 0xd7, 0x9b, 0x76, 0xfb, 0xc6, 0xaa, 0xa3, 0x3f, 0x32, 0x3d, 0x34, 0x14, 0xf5, 0xd6, 0x0d, 0x8f, - 0xb6, 0xf0, 0xa4, 0xf4, 0x86, 0xde, 0x31, 0x6f, 0x60, 0x98, 0xf4, 0x1b, 0x01, 0x27, 0x5e, 0x03, - 0x53, 0x01, 0x0f, 0xff, 0x92, 0x55, 0x80, 0xe3, 0xc8, 0x3c, 0x80, 0xf8, 0xd4, 0x4a, 0xa7, 0x23, - 0x5e, 0x6b, 0x4a, 0xe7, 0x8b, 0x3e, 0x86, 0x2b, 0x76, 0x20, 0x30, 0xbd, 0x23, 0x85, 0x06, 0xd6, - 0x24, 0x0e, 0x4c, 0x0b, 0x96, 0x44, 0x8b, 0x7c, 0x31, 0x8d, 0x84, 0x12, 0xf7, 0x1b, 0x9b, 0x22, - 0xa4, 0x78, 0x31, 0xb2, 0x0c, 0xa7, 0x04, 0xdf, 0x20, 0x91, 0xc8, 0x68, 0x74, 0x56, 0x88, 0xa1, - 0xb9, 0xd2, 0x06, 0x6d, 0x34, 0x04, 0x58, 0xae, 0x23, 0x56, 0x82, 0x4c, 0x84, 0x89, 0x8f, 0xe7, - 0xf5, 0x36, 0x75, 0x95, 0x53, 0xa8, 0xb1, 0x97, 0xb7, 0x36, 0xc7, 0x15, 0xbf, 0x3c, 0x86, 0xb1, - 0x94, 0x45, 0x17, 0x2d, 0x22, 0xf3, 0xe0, 0x5a, 0x3f, 0x96, 0xc2, 0x23, 0xae, 0xf3, 0xd1, 0x22, - 0x64, 0x12, 0x46, 0x82, 0xc7, 0x22, 0xf7, 0xee, 0xd5, 0xaa, 0xf8, 0x1c, 0x54, 0x44, 0x32, 0x8d, - 0xa5, 0xfa, 0x90, 0x99, 0x44, 0xca, 0x48, 0x11, 0x36, 0xf8, 0xfb, 0xd0, 0x58, 0x84, 0x8d, 0x4e, - 0x4a, 0x84, 0x8d, 0x45, 0xf2, 0x16, 0x0c, 0x55, 0x1e, 0xd4, 0x45, 0xe4, 0x10, 0x57, 0x39, 0x13, - 0xe6, 0x8d, 0xd2, 0xd7, 0xdd, 0x86, 0x1f, 0x65, 0x44, 0x6e, 0xba, 0x4c, 0x4f, 0xa6, 0x60, 0x34, - 0xe2, 0x6f, 0xe6, 0x2a, 0x67, 0x91, 0x03, 0xb6, 0x5c, 0x47, 0x4c, 0xc3, 0x11, 0x28, 0x79, 0x78, - 0x45, 0x0b, 0x31, 0xad, 0xa9, 0x9a, 0x2e, 0xe6, 0xe0, 0xd1, 0x28, 0x06, 0x29, 0xc1, 0xc7, 0xa5, - 0x65, 0xae, 0x35, 0x86, 0x40, 0x35, 0x1c, 0x8e, 0x93, 0x7b, 0x34, 0x56, 0x8c, 0xbc, 0x07, 0x04, - 0xb3, 0xf6, 0x50, 0xc3, 0xbf, 0x7e, 0xac, 0x55, 0x5d, 0xe5, 0x3c, 0x86, 0xf1, 0x26, 0xf1, 0xa0, - 0x08, 0xb5, 0xea, 0xc4, 0x15, 0x31, 0x7d, 0x3c, 0xa5, 0xf3, 0x52, 0x0d, 0x3f, 0x20, 0x42, 0xc3, - 0x8c, 0xa4, 0x34, 0x4e, 0xe1, 0x4a, 0xd6, 0xe1, 0xc2, 0xa2, 0x43, 0x1f, 0x99, 0x76, 0xd7, 0xf5, - 0x97, 0x0f, 0x7f, 0xde, 0xba, 0xb0, 0xed, 0xbc, 0xf5, 0x8c, 0xa8, 0xf8, 0x5c, 0xc7, 0xa1, 0x8f, - 0x1a, 0x7e, 0xf0, 0xe6, 0x48, 0xec, 0xd1, 0x2c, 0xee, 0x98, 0x98, 0xf9, 0xfd, 0xae, 0x43, 0x05, - 0xdc, 0xa4, 0xae, 0xa2, 0x84, 0x53, 0x2d, 0x8f, 0x37, 0x63, 0x06, 0xb8, 0x48, 0x62, 0xe6, 0x68, - 0x31, 0xa2, 0x01, 0xb9, 0x3d, 0xe9, 0x5f, 0x45, 0x57, 0x9a, 0x3c, 0x7d, 0xad, 0x72, 0x11, 0x99, - 0xa9, 0x4c, 0x2c, 0xab, 0xcd, 0x20, 0x90, 0x7b, 0x43, 0x17, 0x78, 0x59, 0x2c, 0xc9, 0xd2, 0x64, - 0x16, 0xc6, 0x16, 0x1d, 0x3c, 0x18, 0xbb, 0x4b, 0x37, 0x16, 0xed, 0x96, 0xd9, 0xdc, 0xc0, 0x37, - 0xae, 0x62, 0xaa, 0xec, 0x70, 0x5c, 0xe3, 0x21, 0xdd, 0x68, 0x74, 0x10, 0x2b, 0x2f, 0x2b, 0xf1, - 0x92, 0x72, 0x60, 0xe5, 0x27, 0x76, 0x16, 0x58, 0x99, 0xc2, 0x98, 0xb8, 0xc8, 0x7e, 0xec, 0x51, - 0x8b, 0x2d, 0xf5, 0xae, 0x78, 0xcf, 0xaa, 0xc4, 0x2e, 0xbe, 0x03, 0x3c, 0x9f, 0x3a, 0xc4, 0x28, - 0xa3, 0x01, 0x58, 0x6e, 0x58, 0xbc, 0x48, 0x32, 0xfa, 0xf0, 0x93, 0x7b, 0x88, 0x3e, 0xfc, 0xb7, - 0x0a, 0xf2, 0xfc, 0x4b, 0x2e, 0x43, 0x51, 0x4a, 0x0e, 0x84, 0xa1, 0x55, 0x31, 0x90, 0x7a, 0x51, - 0x44, 0x8c, 0x1e, 0x14, 0xb6, 0x4b, 0x10, 0x43, 0x07, 0xb3, 0x41, 0x86, 0xe1, 0x36, 0xb5, 0x90, - 0x00, 0x33, 0xf1, 0x75, 0x97, 0x5b, 0x66, 0x13, 0xc3, 0xeb, 0x17, 0xa4, 0xa0, 0x19, 0x08, 0xe5, - 0xd1, 0xf5, 0x25, 0x12, 0x72, 0x13, 0x86, 0xfc, 0x03, 0xd9, 0x30, 0xb4, 0x30, 0x46, 0x5d, 0x17, - 0xb3, 0xb5, 0x08, 0xea, 0x2e, 0x11, 0x91, 0xd7, 0x01, 0xc2, 0xe9, 0x40, 0x58, 0x5a, 0xb8, 0x54, - 0xc8, 0xb3, 0x87, 0xbc, 0x54, 0x84, 0xd4, 0x6c, 0xe2, 0x94, 0xd5, 0xd1, 0xcf, 0x3d, 0x8a, 0x13, - 0x67, 0x44, 0x87, 0x65, 0x05, 0x89, 0x16, 0x21, 0x0b, 0x70, 0x3a, 0xa1, 0x81, 0x22, 0x10, 0x31, - 0xe6, 0x9f, 0x4f, 0x51, 0x5f, 0x79, 0x61, 0x4e, 0x94, 0x25, 0xcf, 0x42, 0xe1, 0x9e, 0x56, 0x13, - 0xc1, 0x50, 0x79, 0x1c, 0xdd, 0x48, 0xa4, 0x24, 0x86, 0x55, 0xff, 0x44, 0x3e, 0xb1, 0x36, 0x31, - 0xe9, 0x09, 0x56, 0x52, 0x0f, 0xa2, 0xf4, 0xfc, 0xfa, 0xb9, 0xf4, 0x24, 0x22, 0x72, 0x15, 0xca, - 0x8b, 0x6c, 0x66, 0x68, 0xda, 0x2d, 0xd1, 0x9f, 0x18, 0xd6, 0xaa, 0x23, 0x60, 0x5a, 0x80, 0x25, - 0x37, 0xa5, 0x94, 0xb9, 0x52, 0x7c, 0x71, 0x3f, 0x65, 0x6e, 0x3c, 0xd0, 0x36, 0x26, 0xcf, 0xbd, - 0x19, 0x4b, 0xc1, 0x25, 0xca, 0xa4, 0xac, 0x8b, 0x61, 0xca, 0xad, 0xc0, 0x2a, 0xed, 0xdf, 0xce, - 0x2a, 0x55, 0xff, 0x76, 0x2e, 0x39, 0xce, 0xc8, 0xad, 0x64, 0xa8, 0x5f, 0x5c, 0x84, 0x02, 0xa0, - 0x5c, 0x6b, 0x10, 0xf4, 0x37, 0x12, 0xb4, 0x37, 0xbf, 0xe7, 0xa0, 0xbd, 0x85, 0x5d, 0x06, 0xed, - 0x55, 0xff, 0x9f, 0x62, 0x4f, 0xc7, 0xeb, 0x43, 0x09, 0xee, 0xf6, 0x1a, 0xdb, 0x59, 0xb1, 0xda, - 0x2b, 0x6e, 0x62, 0x7f, 0xc0, 0xfd, 0x4a, 0x1b, 0x3a, 0x1f, 0x5a, 0xae, 0x16, 0xa5, 0x24, 0x6f, - 0xc3, 0xb0, 0xff, 0x01, 0x18, 0x0c, 0x5a, 0x0a, 0x62, 0x1c, 0xac, 0x6a, 0xb1, 0xb0, 0xc9, 0x91, - 0x02, 0xe4, 0x65, 0x18, 0x44, 0x9b, 0xa6, 0xa3, 0x37, 0xfd, 0x48, 0xe1, 0x3c, 0xb4, 0xb8, 0x0f, - 0x94, 0x03, 0x98, 0x05, 0x94, 0xe4, 0x2b, 0x50, 0x12, 0xe9, 0x32, 0x78, 0x36, 0xf9, 0x1b, 0x3b, - 0xf0, 0x54, 0xbf, 0x2e, 0xa7, 0xca, 0xe0, 0xbb, 0x14, 0x04, 0x44, 0x76, 0x29, 0x3c, 0x4b, 0xc6, - 0x12, 0x9c, 0x59, 0x74, 0xa8, 0x81, 0x6f, 0x22, 0xa6, 0x1e, 0x77, 0x1c, 0x91, 0xc8, 0x84, 0x8f, - 0x72, 0x5c, 0xa4, 0x3a, 0x3e, 0x9a, 0x2d, 0x9f, 0x02, 0x2f, 0x87, 0x2b, 0x4e, 0x29, 0xce, 0x2c, - 0x17, 0xde, 0x92, 0xbb, 0x74, 0x63, 0xdd, 0x76, 0x0c, 0x9e, 0xeb, 0x43, 0xcc, 0xdf, 0x42, 0xd0, - 0x0f, 0x05, 0x4a, 0xb6, 0x5c, 0xa2, 0x85, 0x2e, 0xbd, 0x06, 0x43, 0x7b, 0x4d, 0x37, 0xf1, 0x1b, - 0xf9, 0x8c, 0x27, 0x4c, 0xc7, 0x37, 0xe3, 0x5f, 0x90, 0x86, 0xba, 0x3f, 0x23, 0x0d, 0xf5, 0xf7, - 0xf3, 0x19, 0xef, 0xb3, 0x8e, 0x75, 0xba, 0xd8, 0x40, 0x18, 0xd1, 0x74, 0xb1, 0x61, 0xa6, 0x5e, - 0xd3, 0xd0, 0x64, 0xa2, 0x58, 0x62, 0xe9, 0xd2, 0xb6, 0x89, 0xa5, 0x7f, 0xb9, 0xd0, 0xeb, 0xfd, - 0xda, 0x89, 0xec, 0x77, 0x23, 0xfb, 0x9b, 0x30, 0x14, 0x48, 0xb6, 0x56, 0x45, 0xa3, 0x67, 0x24, - 0x48, 0x6e, 0xc3, 0xc1, 0x58, 0x46, 0x22, 0x22, 0xd7, 0x78, 0x5b, 0xeb, 0xe6, 0xfb, 0x3c, 0xcd, - 0xc2, 0x88, 0x08, 0xa0, 0xaf, 0x7b, 0x7a, 0xc3, 0x35, 0xdf, 0xa7, 0x5a, 0x80, 0x56, 0xff, 0xb3, - 0x7c, 0xea, 0x23, 0xc0, 0x93, 0x3e, 0xda, 0x45, 0x1f, 0xa5, 0x08, 0x91, 0x3f, 0x5f, 0x3c, 0x11, - 0xe2, 0x2e, 0x84, 0xf8, 0xc7, 0xf9, 0xd4, 0xc7, 0x9e, 0x27, 0x42, 0xdc, 0xcd, 0x6c, 0xf1, 0x3c, - 0x0c, 0x6a, 0xf6, 0xba, 0x3b, 0x89, 0x1b, 0x1b, 0x3e, 0x57, 0xe0, 0x44, 0xed, 0xd8, 0xeb, 0x6e, - 0x03, 0xb7, 0x2c, 0x5a, 0x48, 0xa0, 0xfe, 0x20, 0xdf, 0xe3, 0x39, 0xec, 0x89, 0xe0, 0x3f, 0xca, - 0x25, 0xf2, 0xb7, 0xf3, 0x91, 0xe7, 0xb6, 0xc7, 0x57, 0xd8, 0x37, 0x00, 0xea, 0xcd, 0x35, 0xda, - 0xd6, 0xa5, 0x54, 0x55, 0x78, 0xee, 0xe0, 0x22, 0x54, 0xa4, 0x38, 0x0e, 0x49, 0xd4, 0x6f, 0xe7, - 0x63, 0xef, 0x8d, 0x4f, 0x64, 0xb7, 0x63, 0xd9, 0x05, 0x5a, 0x27, 0x9e, 0x50, 0x9f, 0x48, 0x6e, - 0xa7, 0x92, 0xfb, 0xc9, 0x7c, 0xec, 0xb5, 0xf9, 0xb1, 0x95, 0x1d, 0x1b, 0x80, 0xc9, 0x57, 0xf0, - 0xc7, 0x56, 0x93, 0x9e, 0x87, 0x41, 0x21, 0x87, 0x60, 0xa9, 0xe0, 0xf3, 0x3e, 0x07, 0xe2, 0x29, - 0x6b, 0x40, 0xa0, 0xfe, 0xc9, 0x3c, 0x44, 0xa3, 0x00, 0x1c, 0x53, 0x1d, 0xfa, 0xed, 0x7c, 0x34, - 0xfe, 0xc1, 0xf1, 0xd5, 0x9f, 0xeb, 0x00, 0xf5, 0xee, 0x72, 0x53, 0x84, 0xcf, 0xed, 0x97, 0x8e, - 0xe9, 0x03, 0xa8, 0x26, 0x51, 0xa8, 0xff, 0x6f, 0x3e, 0x35, 0x28, 0xc3, 0xf1, 0x15, 0xe0, 0x4b, - 0x78, 0x2a, 0xde, 0xb4, 0xc2, 0x89, 0x1c, 0x0f, 0x21, 0xd9, 0xf8, 0x4b, 0xe4, 0x37, 0xf4, 0x09, - 0xc9, 0xe7, 0x53, 0xcc, 0x35, 0xcc, 0xbe, 0x10, 0x9a, 0x6b, 0xf2, 0x35, 0x84, 0x64, 0xb8, 0xfd, - 0xbd, 0xfc, 0x76, 0x31, 0x2c, 0x8e, 0xf3, 0xaa, 0x3a, 0xb0, 0xa8, 0x6f, 0x60, 0xac, 0x45, 0xd6, - 0x13, 0xc3, 0x3c, 0xfb, 0x5e, 0x87, 0x83, 0xe4, 0xbb, 0x37, 0x41, 0xa5, 0xfe, 0xb3, 0xfe, 0xf4, - 0x00, 0x0a, 0xc7, 0x57, 0x84, 0x97, 0xa1, 0xb8, 0xa8, 0x7b, 0x6b, 0x42, 0x93, 0xf1, 0x4a, 0xaf, - 0xa3, 0x7b, 0x6b, 0x1a, 0x42, 0xc9, 0x35, 0x28, 0x6b, 0xfa, 0x3a, 0x3f, 0xf3, 0x2c, 0x85, 0x99, - 0x11, 0x1d, 0x7d, 0xbd, 0xc1, 0xcf, 0x3d, 0x03, 0x34, 0x51, 0x83, 0xcc, 0x9c, 0xfc, 0xe4, 0x1b, - 0xd3, 0xc2, 0xf1, 0xcc, 0x9c, 0x41, 0x3e, 0xce, 0xcb, 0x50, 0x9c, 0xb0, 0x8d, 0x0d, 0xbc, 0xbe, - 0x1a, 0xe6, 0x95, 0x2d, 0xdb, 0xc6, 0x86, 0x86, 0x50, 0xf2, 0x53, 0x39, 0x18, 0x98, 0xa1, 0xba, - 0xc1, 0x46, 0xc8, 0x60, 0x2f, 0xaf, 0x93, 0x2f, 0x1d, 0x8c, 0xd7, 0xc9, 0xe9, 0x35, 0x5e, 0x99, - 0xac, 0x28, 0xa2, 0x7e, 0x72, 0x1b, 0xca, 0x93, 0xba, 0x47, 0x57, 0x6d, 0x67, 0x03, 0xfd, 0x68, - 0x46, 0x43, 0x27, 0xfc, 0x88, 0xfe, 0xf8, 0x44, 0xfc, 0x66, 0xac, 0x29, 0x7e, 0x69, 0x41, 0x61, - 0x26, 0x16, 0x9e, 0xf8, 0x5f, 0x64, 0xa1, 0x46, 0xb1, 0x78, 0x08, 0xd1, 0x04, 0x26, 0x3c, 0x56, - 0x1e, 0x4e, 0x3f, 0x56, 0x46, 0xeb, 0x11, 0x7d, 0xed, 0x30, 0x1f, 0xe6, 0x08, 0x2e, 0xfa, 0xdc, - 0x7a, 0x44, 0x28, 0xa6, 0xc3, 0xd4, 0x24, 0x12, 0xf5, 0x7b, 0xfd, 0x90, 0xfa, 0xdc, 0xfa, 0x44, - 0xc9, 0x4f, 0x94, 0x3c, 0x54, 0xf2, 0x6a, 0x42, 0xc9, 0x2f, 0x25, 0x1f, 0xf0, 0x7f, 0x4c, 0x35, - 0xfc, 0xe7, 0x8a, 0x89, 0xf0, 0x1f, 0xc7, 0x7b, 0x77, 0x19, 0x4a, 0xaf, 0x7f, 0x5b, 0xe9, 0x05, - 0x03, 0xa2, 0xb4, 0xed, 0x80, 0x18, 0xd8, 0xe9, 0x80, 0x28, 0x67, 0x0e, 0x88, 0x50, 0x41, 0x06, - 0x33, 0x15, 0xa4, 0x26, 0x06, 0x0d, 0xf4, 0xce, 0x42, 0x72, 0x79, 0x6b, 0x73, 0x7c, 0x94, 0x8d, - 0xa6, 0xd4, 0xf4, 0x23, 0xc8, 0x42, 0xfd, 0x83, 0x62, 0x8f, 0x98, 0x3d, 0x87, 0xa2, 0x23, 0x2f, - 0x41, 0xa1, 0xd2, 0xe9, 0x08, 0xfd, 0x38, 0x23, 0x85, 0x0b, 0xca, 0x28, 0xc5, 0xa8, 0xc9, 0xeb, - 0x50, 0xa8, 0x3c, 0xa8, 0xc7, 0x33, 0x8f, 0x54, 0x1e, 0xd4, 0xc5, 0x97, 0x64, 0x96, 0x7d, 0x50, - 0x27, 0x6f, 0x86, 0x21, 0x40, 0xd7, 0xba, 0xd6, 0x43, 0xb1, 0x51, 0x14, 0xee, 0xb6, 0xbe, 0x3b, - 0x4e, 0x93, 0xa1, 0xd8, 0x76, 0x31, 0x46, 0x1b, 0xd3, 0xa6, 0xd2, 0xce, 0xb5, 0x69, 0x60, 0x5b, - 0x6d, 0x2a, 0xef, 0x54, 0x9b, 0x06, 0x77, 0xa0, 0x4d, 0xb0, 0xad, 0x36, 0x0d, 0xed, 0x5f, 0x9b, - 0x3a, 0x70, 0x29, 0x19, 0x67, 0x2d, 0xd0, 0x08, 0x0d, 0x48, 0x12, 0x2b, 0x1c, 0x4b, 0xf0, 0xea, - 0xbf, 0xcb, 0xb1, 0x8d, 0x75, 0x44, 0x37, 0x5c, 0x86, 0x97, 0xfd, 0xd3, 0x92, 0xa5, 0xd5, 0xdf, - 0xc8, 0x67, 0x87, 0x87, 0x3b, 0x9a, 0x53, 0xdc, 0x8f, 0xa4, 0x4a, 0xa9, 0x18, 0x7d, 0xae, 0x9f, - 0x2d, 0xe5, 0x18, 0xdb, 0x34, 0x99, 0x7d, 0x37, 0x97, 0x15, 0xb3, 0x6e, 0x5f, 0x12, 0xfb, 0x74, - 0xd2, 0xa3, 0x0d, 0xfd, 0xf4, 0xdd, 0xa8, 0x2b, 0xdb, 0x34, 0x0c, 0xcb, 0x42, 0x14, 0x52, 0xda, - 0x89, 0x80, 0x23, 0xe5, 0xd4, 0xbf, 0x9d, 0x83, 0x33, 0x77, 0xbb, 0xcb, 0x54, 0x78, 0xb0, 0x05, - 0xcd, 0x78, 0x0f, 0x80, 0x81, 0x85, 0x13, 0x4b, 0x0e, 0x9d, 0x58, 0x3e, 0x2b, 0xc7, 0x9b, 0x8b, - 0x15, 0xb8, 0x1e, 0x52, 0x73, 0x07, 0x96, 0x27, 0x7d, 0x67, 0xce, 0x87, 0xdd, 0x65, 0xda, 0x48, - 0x78, 0xb2, 0x48, 0xdc, 0x2f, 0xbd, 0xc5, 0xdd, 0xe4, 0xf7, 0xea, 0x34, 0xf2, 0x6b, 0xf9, 0xcc, - 0x10, 0x7f, 0x47, 0x36, 0x17, 0xe5, 0x0f, 0xa5, 0xf6, 0x4a, 0x3c, 0x27, 0x65, 0x0a, 0x49, 0x8c, - 0x63, 0x1a, 0x97, 0x74, 0x81, 0x1d, 0xf1, 0x0c, 0xa9, 0x1f, 0xa9, 0xc0, 0xfe, 0x41, 0x2e, 0x33, - 0x14, 0xe3, 0x51, 0x15, 0x98, 0xfa, 0xbf, 0x14, 0xfc, 0x08, 0x90, 0xfb, 0xfa, 0x84, 0xe7, 0x61, - 0x50, 0x3c, 0x84, 0x8f, 0x3a, 0xe0, 0x8a, 0xa3, 0x3c, 0x3c, 0x1a, 0x0e, 0x08, 0xd8, 0x32, 0x2f, - 0x79, 0x07, 0x4b, 0x0e, 0xb8, 0x92, 0x67, 0xb0, 0x26, 0x91, 0xb0, 0x85, 0x7c, 0xea, 0xb1, 0xe9, - 0xa1, 0x55, 0xc0, 0xfa, 0xb2, 0xc0, 0x17, 0x72, 0xfa, 0xd8, 0xf4, 0xb8, 0x4d, 0x10, 0xa0, 0xd9, - 0x22, 0x5d, 0x0f, 0xf3, 0xbf, 0x8b, 0x45, 0xda, 0x15, 0x69, 0xf0, 0xc5, 0xb3, 0xb1, 0xe7, 0x61, - 0x50, 0x78, 0xb5, 0x0a, 0x37, 0x13, 0xd1, 0x5a, 0xe1, 0x07, 0x8b, 0xad, 0x0d, 0x08, 0x18, 0x47, - 0x8d, 0xae, 0x86, 0x8e, 0x75, 0xc8, 0xd1, 0x41, 0x88, 0x26, 0x30, 0xe4, 0x26, 0x8c, 0xd6, 0x3d, - 0xdd, 0x32, 0x74, 0xc7, 0x58, 0xe8, 0x7a, 0x9d, 0xae, 0x27, 0x1b, 0xa5, 0xae, 0x67, 0xd8, 0x5d, - 0x4f, 0x8b, 0x51, 0x90, 0xcf, 0xc1, 0x88, 0x0f, 0x99, 0x72, 0x1c, 0xdb, 0x91, 0x2d, 0x0f, 0xd7, - 0x33, 0xa8, 0xe3, 0x68, 0x51, 0x02, 0xf2, 0x79, 0x18, 0xa9, 0x59, 0x8f, 0xec, 0x26, 0x7f, 0x0c, - 0xae, 0xcd, 0x0a, 0x3b, 0x04, 0x9f, 0x62, 0x99, 0x01, 0xa2, 0xd1, 0x75, 0x5a, 0x5a, 0x94, 0x50, - 0xdd, 0xca, 0x27, 0x03, 0x65, 0x1e, 0xdf, 0x4d, 0xcb, 0xb5, 0xa8, 0x33, 0x1d, 0x7a, 0x90, 0xa2, - 0x41, 0x28, 0xfb, 0xf2, 0x72, 0xbb, 0xf0, 0x26, 0x94, 0xef, 0xd2, 0x0d, 0xee, 0xf7, 0x59, 0x0a, - 0x5d, 0x85, 0x1f, 0x0a, 0x98, 0x7c, 0xe2, 0xea, 0xd3, 0xa9, 0xdf, 0xc9, 0x27, 0x43, 0x80, 0x1e, - 0x5f, 0x61, 0x7f, 0x0e, 0x06, 0x50, 0x94, 0x35, 0xff, 0xc8, 0x1f, 0x05, 0x88, 0xe2, 0x8e, 0x7a, - 0x20, 0xfb, 0x64, 0xea, 0x2f, 0x95, 0xe2, 0x71, 0x61, 0x8f, 0xaf, 0xf4, 0xde, 0x80, 0xa1, 0x49, - 0xdb, 0x72, 0x4d, 0xd7, 0xa3, 0x56, 0xd3, 0x57, 0xd8, 0x8b, 0xcc, 0xa0, 0x6a, 0x86, 0x60, 0xf9, - 0x0d, 0x92, 0x44, 0xbd, 0x17, 0xe5, 0x25, 0xaf, 0xc0, 0x20, 0x8a, 0x1c, 0xfd, 0xa4, 0xf9, 0x84, - 0x87, 0xb7, 0x05, 0xcb, 0x0c, 0x18, 0x77, 0x92, 0x0e, 0x49, 0xc9, 0x3d, 0x28, 0x4f, 0xae, 0x99, - 0x2d, 0xc3, 0xa1, 0x16, 0xfa, 0x0b, 0x4b, 0xe1, 0x37, 0xa2, 0x7d, 0x79, 0x1d, 0xff, 0x45, 0x5a, - 0xde, 0x9c, 0xa6, 0x28, 0x16, 0x79, 0x85, 0x25, 0x60, 0x97, 0x7e, 0x36, 0x0f, 0x10, 0x16, 0x20, - 0x4f, 0x43, 0x3e, 0x48, 0xad, 0x8c, 0x6e, 0x2a, 0x11, 0x0d, 0xca, 0xe3, 0x52, 0x21, 0xc6, 0x76, - 0x7e, 0xdb, 0xb1, 0x7d, 0x0f, 0x4a, 0xfc, 0xc4, 0x0b, 0x3d, 0xc9, 0xa5, 0x50, 0x95, 0x99, 0x0d, - 0xbe, 0x8e, 0xf4, 0x7c, 0x33, 0x8b, 0x96, 0x67, 0xc4, 0x2b, 0x9b, 0x33, 0xbb, 0xd4, 0x84, 0x7e, - 0xfc, 0x8b, 0x5c, 0x81, 0xe2, 0x92, 0x9f, 0x96, 0x75, 0x84, 0xcf, 0xd2, 0x31, 0xf9, 0x21, 0x9e, - 0x75, 0xd3, 0xa4, 0x6d, 0x79, 0xac, 0x6a, 0x6c, 0xf5, 0xb0, 0x90, 0x8b, 0x80, 0x45, 0xe4, 0x22, - 0x60, 0xea, 0x7f, 0x95, 0x4f, 0x89, 0x58, 0x7c, 0x7c, 0x87, 0xc9, 0x6b, 0x00, 0xf8, 0xa4, 0x9b, - 0xc9, 0xd3, 0x7f, 0xa2, 0x81, 0xa3, 0x04, 0x19, 0xa1, 0xda, 0x46, 0xb6, 0x1d, 0x21, 0xb1, 0xfa, - 0x77, 0x73, 0x89, 0x30, 0xb7, 0xfb, 0x92, 0xa3, 0x6c, 0x95, 0xe5, 0xf7, 0x68, 0xc6, 0xfa, 0x7d, - 0x51, 0xd8, 0x5d, 0x5f, 0x44, 0xbf, 0xe5, 0x00, 0x2c, 0xd3, 0xc3, 0xfc, 0x96, 0xef, 0xe5, 0xd3, - 0x82, 0xfe, 0x1e, 0x4d, 0x15, 0xbf, 0x15, 0x18, 0xa5, 0xc5, 0x58, 0x98, 0x75, 0x84, 0xc6, 0x53, - 0x47, 0x0b, 0x33, 0xf5, 0xab, 0x70, 0x2a, 0x16, 0x0a, 0x57, 0x64, 0xf1, 0xbd, 0xd2, 0x3b, 0xa6, - 0x6e, 0x76, 0x30, 0x80, 0x08, 0x99, 0xfa, 0xff, 0xe5, 0x7a, 0x07, 0x42, 0x3e, 0x74, 0xd5, 0x49, - 0x11, 0x40, 0xe1, 0x5f, 0x8d, 0x00, 0x0e, 0x60, 0x1b, 0x7c, 0xb4, 0x05, 0xf0, 0x31, 0x99, 0x3c, - 0x3e, 0x6a, 0x01, 0xfc, 0x52, 0x6e, 0xdb, 0x38, 0xd6, 0x87, 0x2d, 0x03, 0xf5, 0x7f, 0xcc, 0xa5, - 0xc6, 0x9b, 0xde, 0x57, 0xbb, 0xde, 0x84, 0x12, 0x77, 0xab, 0x11, 0xad, 0x92, 0x32, 0x74, 0x31, - 0x68, 0x56, 0x4e, 0x7b, 0x8e, 0x25, 0xb3, 0x30, 0xc0, 0xdb, 0x60, 0x88, 0xde, 0xf8, 0x54, 0x8f, - 0xa0, 0xd7, 0x46, 0xd6, 0xe4, 0x28, 0xd0, 0xea, 0xdf, 0xc9, 0x25, 0xc2, 0x5f, 0x1f, 0xe2, 0xb7, - 0x85, 0x53, 0x75, 0x61, 0xe7, 0x53, 0xb5, 0xfa, 0x4f, 0xf3, 0xe9, 0xd1, 0xb7, 0x0f, 0xf1, 0x43, - 0x0e, 0xe2, 0x38, 0x6d, 0x6f, 0xeb, 0xd6, 0x12, 0x8c, 0x46, 0x65, 0x21, 0x96, 0xad, 0xa7, 0xd2, - 0x63, 0x90, 0x67, 0xb4, 0x22, 0xc6, 0x43, 0xfd, 0x30, 0x97, 0x0c, 0x1c, 0x7e, 0xe8, 0xf3, 0xd3, - 0xde, 0xb4, 0x25, 0xfa, 0x29, 0x1f, 0x93, 0xb5, 0xe6, 0x20, 0x3e, 0xe5, 0x63, 0xb2, 0x6a, 0xec, - 0xed, 0x53, 0x7e, 0x25, 0x9f, 0x15, 0x77, 0xfd, 0xd0, 0x3f, 0xe8, 0xcb, 0xb2, 0x90, 0x79, 0xcb, - 0xc4, 0xa7, 0x3d, 0x9d, 0x15, 0xe8, 0x3c, 0x83, 0x67, 0x82, 0xcf, 0xde, 0xc6, 0x78, 0xaa, 0xb0, - 0x3e, 0x26, 0x8a, 0x7c, 0x34, 0x84, 0xf5, 0x31, 0x19, 0x2a, 0x1f, 0x3f, 0x61, 0xfd, 0x6e, 0x7e, - 0xa7, 0xc1, 0xfe, 0x4f, 0x84, 0x97, 0x10, 0xde, 0x37, 0xf3, 0xc9, 0x24, 0x14, 0x87, 0x2e, 0xa6, - 0x69, 0x28, 0x89, 0x74, 0x18, 0x99, 0xc2, 0xe1, 0xf8, 0x2c, 0x8b, 0x46, 0x7c, 0xc7, 0x2d, 0x10, - 0x17, 0x39, 0x3b, 0x13, 0x09, 0xa7, 0x55, 0x7f, 0x90, 0x8b, 0x65, 0x6c, 0x38, 0x94, 0x23, 0x84, - 0x3d, 0x2d, 0x49, 0xe4, 0x2d, 0xff, 0x30, 0xb3, 0x18, 0x8b, 0x98, 0x1d, 0x7c, 0x4f, 0x95, 0x7a, - 0xba, 0xd9, 0x8a, 0x97, 0x17, 0x31, 0x01, 0xbe, 0x93, 0x87, 0xd3, 0x09, 0x52, 0x72, 0x25, 0x12, - 0x4a, 0x07, 0x8f, 0x25, 0x63, 0xce, 0xe3, 0x3c, 0xa8, 0xce, 0x2e, 0x4e, 0x52, 0xaf, 0x40, 0xb1, - 0xaa, 0x6f, 0xf0, 0x6f, 0xeb, 0xe7, 0x2c, 0x0d, 0x7d, 0x43, 0x3e, 0x71, 0x43, 0x3c, 0x59, 0x86, - 0x73, 0xfc, 0x3e, 0xc4, 0xb4, 0xad, 0x25, 0xb3, 0x4d, 0x6b, 0xd6, 0x9c, 0xd9, 0x6a, 0x99, 0xae, - 0xb8, 0xd4, 0x7b, 0x7e, 0x6b, 0x73, 0xfc, 0xaa, 0x67, 0x7b, 0x7a, 0xab, 0x41, 0x7d, 0xb2, 0x86, - 0x67, 0xb6, 0x69, 0xc3, 0xb4, 0x1a, 0x6d, 0xa4, 0x94, 0x58, 0xa6, 0xb3, 0x22, 0x35, 0x1e, 0x1c, - 0xbd, 0xde, 0xd4, 0x2d, 0x8b, 0x1a, 0x35, 0x6b, 0x62, 0xc3, 0xa3, 0xfc, 0x32, 0xb0, 0xc0, 0x8f, - 0x04, 0xf9, 0xdb, 0x70, 0x8e, 0x66, 0x8c, 0x97, 0x19, 0x81, 0x96, 0x52, 0x48, 0xfd, 0xbd, 0x62, - 0x4a, 0xb2, 0x8e, 0x23, 0xa4, 0x3e, 0x7e, 0x4f, 0x17, 0xb7, 0xe9, 0xe9, 0x1b, 0x30, 0x20, 0xa2, - 0xcf, 0x8a, 0x0b, 0x06, 0x74, 0x66, 0x7f, 0xc4, 0x41, 0xf2, 0x0d, 0x8d, 0xa0, 0x22, 0x2d, 0xb8, - 0xb4, 0xc4, 0xba, 0x29, 0xbd, 0x33, 0x4b, 0x7b, 0xe8, 0xcc, 0x1e, 0xfc, 0xc8, 0xbb, 0x70, 0x01, - 0xb1, 0x29, 0xdd, 0x3a, 0x80, 0x55, 0x61, 0x8c, 0x2a, 0x5e, 0x55, 0x7a, 0xe7, 0x66, 0x95, 0x27, - 0x5f, 0x86, 0xe1, 0x60, 0x80, 0x98, 0xd4, 0x15, 0x37, 0x17, 0x3d, 0xc6, 0x19, 0x0f, 0x00, 0xc7, - 0xc0, 0xe8, 0x42, 0x16, 0x0d, 0x22, 0x16, 0xe1, 0xa5, 0xfe, 0x0f, 0xb9, 0x5e, 0x49, 0x43, 0x0e, - 0x7d, 0x56, 0x7e, 0x0b, 0x06, 0x0c, 0xfe, 0x51, 0x42, 0xa7, 0x7a, 0xa7, 0x15, 0xe1, 0xa4, 0x9a, - 0x5f, 0x46, 0xfd, 0x27, 0xb9, 0x9e, 0xb9, 0x4a, 0x8e, 0xfa, 0xe7, 0x7d, 0xb3, 0x90, 0xf1, 0x79, - 0x62, 0x12, 0xbd, 0x06, 0x63, 0x66, 0x18, 0x4c, 0xbd, 0x11, 0x86, 0x9f, 0xd2, 0x4e, 0x49, 0x70, - 0x1c, 0x5d, 0xb7, 0xe0, 0xbc, 0xef, 0xf8, 0xe8, 0xf8, 0x1e, 0x62, 0x6e, 0xa3, 0xeb, 0x98, 0x7c, - 0x5c, 0x6a, 0x67, 0xdd, 0x98, 0xfb, 0x98, 0x7b, 0xcf, 0x31, 0x59, 0x05, 0xba, 0xb7, 0x46, 0x2d, - 0xbd, 0xb1, 0x6e, 0x3b, 0x0f, 0x31, 0xca, 0x28, 0x1f, 0x9c, 0xda, 0x29, 0x0e, 0x7f, 0xe0, 0x83, - 0xc9, 0xb3, 0x30, 0xb2, 0xda, 0xea, 0xd2, 0x20, 0xae, 0x23, 0xbf, 0xeb, 0xd3, 0x86, 0x19, 0x30, - 0xb8, 0x21, 0x79, 0x12, 0x00, 0x89, 0x3c, 0xcc, 0x24, 0x83, 0x17, 0x7b, 0xda, 0x20, 0x83, 0x2c, - 0x89, 0xee, 0xba, 0xc4, 0xb5, 0x9a, 0x0b, 0xa9, 0xd1, 0xb2, 0xad, 0xd5, 0x86, 0x47, 0x9d, 0x36, - 0x36, 0x14, 0x9d, 0x19, 0xb4, 0xf3, 0x48, 0x81, 0x57, 0x27, 0xee, 0xac, 0x6d, 0xad, 0x2e, 0x51, - 0xa7, 0xcd, 0x9a, 0xfa, 0x3c, 0x10, 0xd1, 0x54, 0x07, 0x0f, 0x3d, 0xf8, 0xc7, 0xa1, 0x37, 0x83, - 0x26, 0x3e, 0x82, 0x9f, 0x86, 0xe0, 0x87, 0x8d, 0xc3, 0x10, 0x0f, 0x6e, 0xc7, 0x85, 0x86, 0x2e, - 0x0c, 0x1a, 0x70, 0x10, 0xca, 0xeb, 0x3c, 0x08, 0xef, 0x0a, 0xee, 0xd5, 0xad, 0x89, 0x5f, 0xea, - 0x07, 0x85, 0xb4, 0xf4, 0x2a, 0xfb, 0x52, 0xb4, 0x70, 0x5a, 0xcd, 0xef, 0x6a, 0x5a, 0x3d, 0x65, - 0x75, 0xdb, 0x0d, 0xbd, 0xd3, 0x69, 0xac, 0x98, 0x2d, 0x7c, 0x56, 0x85, 0x0b, 0x9f, 0x36, 0x62, - 0x75, 0xdb, 0x95, 0x4e, 0x67, 0x9a, 0x03, 0xc9, 0x73, 0x70, 0x9a, 0xd1, 0x61, 0x27, 0x05, 0x94, - 0x45, 0xa4, 0x64, 0x0c, 0x30, 0x3a, 0xac, 0x4f, 0x7b, 0x11, 0xca, 0x82, 0x27, 0x5f, 0xab, 0xfa, - 0xb5, 0x01, 0xce, 0xcc, 0x65, 0x3d, 0x17, 0xb0, 0xe1, 0x93, 0x6b, 0xbf, 0x36, 0xe8, 0x97, 0xc7, - 0x18, 0xc8, 0x56, 0xb7, 0xcd, 0x23, 0x62, 0x0d, 0x20, 0x32, 0xf8, 0x4d, 0xae, 0xc0, 0x28, 0xe3, - 0x12, 0x08, 0x8c, 0x87, 0x8d, 0xed, 0xd7, 0x62, 0x50, 0x72, 0x13, 0xce, 0x46, 0x20, 0xdc, 0x06, - 0xe5, 0xcf, 0x04, 0xfa, 0xb5, 0x54, 0x9c, 0xfa, 0xed, 0x42, 0x34, 0xe9, 0xcb, 0x21, 0x74, 0xc4, - 0x05, 0x18, 0xb0, 0x9d, 0xd5, 0x46, 0xd7, 0x69, 0x89, 0xb1, 0x57, 0xb2, 0x9d, 0xd5, 0x7b, 0x4e, - 0x8b, 0x9c, 0x83, 0x12, 0xeb, 0x1d, 0xd3, 0x10, 0x43, 0xac, 0x5f, 0xef, 0x74, 0x6a, 0x06, 0xa9, - 0xf0, 0x0e, 0xc1, 0x90, 0xa3, 0x8d, 0x26, 0x6e, 0xed, 0xb9, 0x53, 0x42, 0x3f, 0x5f, 0xf1, 0x12, - 0x48, 0xec, 0x27, 0x0c, 0x44, 0xca, 0x0f, 0x02, 0x62, 0x2c, 0x0c, 0xdc, 0x96, 0x18, 0xbc, 0x4f, - 0xe2, 0x2c, 0x04, 0x32, 0x64, 0xc1, 0x37, 0x31, 0x06, 0xa9, 0x02, 0x09, 0xa9, 0xda, 0xb6, 0x61, - 0xae, 0x98, 0x94, 0xbf, 0xea, 0xe8, 0xe7, 0x17, 0xbf, 0x49, 0xac, 0x36, 0xe6, 0x33, 0x99, 0x13, - 0x10, 0xf2, 0x06, 0x57, 0x42, 0x4e, 0x87, 0x6b, 0x1f, 0xef, 0x5b, 0x6e, 0xa7, 0xc5, 0x50, 0xa8, - 0x99, 0x58, 0x1e, 0x17, 0x42, 0xf5, 0xaf, 0x14, 0x93, 0x99, 0x7f, 0x0e, 0xc5, 0xae, 0x99, 0x01, - 0x10, 0x89, 0xbd, 0xc2, 0xcb, 0xb5, 0xc0, 0xe3, 0x3c, 0xc4, 0x64, 0xf0, 0x90, 0xca, 0x92, 0x6b, - 0x50, 0xe6, 0x5f, 0x54, 0xab, 0x0a, 0x7b, 0x07, 0x5d, 0xc4, 0xdc, 0x8e, 0xb9, 0xb2, 0x82, 0xfe, - 0x64, 0x01, 0x9a, 0x5c, 0x81, 0x81, 0xea, 0x7c, 0xbd, 0x5e, 0x99, 0xf7, 0x6f, 0x8a, 0xf1, 0x7d, - 0x89, 0x61, 0xb9, 0x0d, 0x57, 0xb7, 0x5c, 0xcd, 0x47, 0x92, 0x67, 0xa1, 0x54, 0x5b, 0x44, 0x32, - 0xfe, 0x6a, 0x72, 0x68, 0x6b, 0x73, 0x7c, 0xc0, 0xec, 0x70, 0x2a, 0x81, 0xc2, 0x7a, 0xef, 0xd7, - 0xaa, 0x92, 0xbb, 0x04, 0xaf, 0xf7, 0x91, 0x69, 0xe0, 0xb5, 0xb3, 0x16, 0xa0, 0xc9, 0xcb, 0x30, - 0x5c, 0xa7, 0x8e, 0xa9, 0xb7, 0xe6, 0xbb, 0xb8, 0x55, 0x94, 0x42, 0x29, 0xba, 0x08, 0x6f, 0x58, - 0x88, 0xd0, 0x22, 0x64, 0xe4, 0x32, 0x14, 0x67, 0x4c, 0xcb, 0x7f, 0xc2, 0x80, 0x3e, 0xee, 0x6b, - 0xa6, 0xe5, 0x69, 0x08, 0x25, 0xcf, 0x42, 0xe1, 0xce, 0x52, 0x4d, 0x78, 0x82, 0x21, 0xaf, 0xf7, - 0xbc, 0x48, 0x58, 0xc6, 0x3b, 0x4b, 0x35, 0xf2, 0x32, 0x0c, 0xb2, 0x45, 0x8c, 0x5a, 0x4d, 0xea, - 0x2a, 0x43, 0xf8, 0x31, 0x3c, 0x8c, 0xa0, 0x0f, 0x94, 0x7d, 0x3a, 0x02, 0x4a, 0xf5, 0xff, 0xc8, - 0xa7, 0xa7, 0x66, 0x3a, 0x84, 0xa1, 0xbe, 0xc7, 0x5b, 0xe4, 0x98, 0x82, 0x15, 0xf7, 0xa1, 0x60, - 0x2b, 0x70, 0xaa, 0x62, 0xb4, 0x4d, 0xab, 0x82, 0x3f, 0xdd, 0xb9, 0xe9, 0x0a, 0x4e, 0x1d, 0xd2, - 0xf3, 0xbc, 0x18, 0x5a, 0x7c, 0x0f, 0x0f, 0xf8, 0xcb, 0x50, 0x0d, 0x9d, 0xe3, 0x1a, 0xed, 0x15, - 0xbd, 0xd1, 0xe4, 0x59, 0x8d, 0xb4, 0x38, 0x53, 0xf5, 0x67, 0xf2, 0xdb, 0x64, 0x93, 0x3a, 0x8e, - 0xd2, 0x57, 0xbf, 0x95, 0xef, 0x9d, 0xd0, 0xeb, 0x58, 0x0a, 0xe5, 0x8f, 0xf3, 0x29, 0xe9, 0xb5, - 0xf6, 0x25, 0x89, 0x6b, 0x50, 0xe6, 0x6c, 0x02, 0x37, 0x5e, 0x9c, 0xcd, 0xb8, 0xb2, 0xe2, 0x2c, - 0xea, 0xa3, 0xc9, 0x3c, 0x9c, 0xad, 0xac, 0xac, 0xd0, 0xa6, 0x17, 0x86, 0x7e, 0x9e, 0x0f, 0x83, - 0xb0, 0xf2, 0x50, 0xb7, 0x02, 0x1f, 0x86, 0x8e, 0xc6, 0x60, 0x23, 0xa9, 0xe5, 0xc8, 0x12, 0x9c, - 0x8f, 0xc3, 0xeb, 0x7c, 0x0b, 0x50, 0x94, 0xa2, 0xdf, 0x26, 0x38, 0xf2, 0xff, 0xb4, 0x8c, 0xb2, - 0x69, 0xad, 0xc4, 0xa9, 0xba, 0xbf, 0x57, 0x2b, 0x71, 0xde, 0x4e, 0x2d, 0xa7, 0x7e, 0xa7, 0x20, - 0x67, 0x21, 0x3b, 0xbe, 0x0e, 0x57, 0xb7, 0x22, 0x6e, 0xd6, 0x3b, 0x1d, 0x32, 0x2f, 0x8b, 0x08, - 0x22, 0x46, 0xd7, 0xf1, 0x3d, 0x12, 0x83, 0x08, 0x06, 0x08, 0x94, 0xd7, 0xa1, 0x80, 0x92, 0xd4, - 0xa0, 0x58, 0x71, 0x56, 0xb9, 0x79, 0xbb, 0xdd, 0xa3, 0x2a, 0xdd, 0x59, 0x75, 0xd3, 0x1f, 0x55, - 0x31, 0x16, 0xea, 0x9f, 0xc9, 0xf7, 0x48, 0x1c, 0x76, 0x2c, 0x27, 0x91, 0x3f, 0x9f, 0xcf, 0x4a, - 0x01, 0x76, 0x54, 0x5d, 0xc7, 0x3e, 0x62, 0xe1, 0x1c, 0x6d, 0xbf, 0xba, 0x03, 0x16, 0x4e, 0x46, - 0x3a, 0xb2, 0x13, 0xe1, 0x7c, 0x90, 0xcf, 0xca, 0xc8, 0x76, 0x6c, 0x67, 0x99, 0x8c, 0x24, 0x70, - 0x27, 0xba, 0xf2, 0x0b, 0xf9, 0xcc, 0x3c, 0x78, 0x27, 0xd2, 0x51, 0xbf, 0x9e, 0xcf, 0xcc, 0xe3, - 0x77, 0x2c, 0x87, 0x52, 0xaa, 0xb6, 0x9c, 0x8c, 0x25, 0x21, 0x9d, 0x3f, 0xcc, 0xa7, 0x67, 0x4e, - 0x3c, 0x04, 0x55, 0x39, 0x08, 0x0f, 0x3c, 0x5f, 0xa0, 0xc5, 0x7d, 0x09, 0xb4, 0xff, 0x40, 0x05, - 0x7a, 0x68, 0x63, 0xef, 0x93, 0x2a, 0xd0, 0x03, 0x18, 0xbc, 0xc7, 0x59, 0xa0, 0x3f, 0x5d, 0x48, - 0x66, 0x0b, 0x3d, 0x96, 0x47, 0x94, 0x13, 0x50, 0xf6, 0xcf, 0x30, 0x84, 0x40, 0x77, 0xdc, 0x9d, - 0x7e, 0x39, 0xf2, 0x36, 0x9c, 0x0a, 0x65, 0x29, 0x47, 0xa6, 0xc2, 0xeb, 0x8d, 0x26, 0x43, 0x35, - 0xde, 0x63, 0x38, 0x11, 0x42, 0x25, 0x4e, 0xad, 0xfe, 0xa0, 0x90, 0x4c, 0xb9, 0x7a, 0xd2, 0x1b, - 0x7b, 0xec, 0x8d, 0x7b, 0x70, 0x7e, 0xb2, 0xeb, 0x38, 0xd4, 0xf2, 0xd2, 0x3b, 0x05, 0x0f, 0x97, - 0x9b, 0x9c, 0xa2, 0x91, 0xec, 0x9c, 0x8c, 0xc2, 0x8c, 0xad, 0xf0, 0xbe, 0x8f, 0xb3, 0x1d, 0x08, - 0xd9, 0x76, 0x39, 0x45, 0x1a, 0xdb, 0xf4, 0xc2, 0xea, 0xdf, 0xcb, 0x27, 0x93, 0xe4, 0x9e, 0x74, - 0xfd, 0xde, 0xba, 0x5e, 0xfd, 0xa0, 0x10, 0x4f, 0x14, 0x7c, 0xb2, 0x40, 0xec, 0xbd, 0x3b, 0x7c, - 0x49, 0xe2, 0xb8, 0x91, 0xbe, 0xc2, 0x87, 0x67, 0x7d, 0x85, 0x8f, 0x57, 0x7f, 0xad, 0x18, 0x4f, - 0xba, 0x7c, 0xd2, 0x1d, 0x87, 0xd7, 0x1d, 0x64, 0x01, 0xce, 0x8a, 0xb9, 0xcd, 0x07, 0x61, 0x8a, - 0x02, 0x31, 0x7f, 0xf1, 0x4c, 0x67, 0x62, 0x5a, 0xec, 0xba, 0xd4, 0x69, 0x78, 0xba, 0xfb, 0xb0, - 0x81, 0x39, 0x0d, 0xb4, 0xd4, 0x82, 0x8c, 0xa1, 0x98, 0xd5, 0xa2, 0x0c, 0xcb, 0x21, 0x43, 0x7f, - 0x42, 0x4c, 0x30, 0x4c, 0x2b, 0xa8, 0xfe, 0x76, 0x0e, 0xc6, 0xe2, 0x9f, 0x43, 0xae, 0x43, 0x99, - 0xfd, 0x0e, 0x9e, 0x85, 0x4b, 0x79, 0x94, 0x39, 0x47, 0x7e, 0x65, 0xec, 0xd3, 0x90, 0x57, 0x60, - 0x10, 0x6f, 0xe7, 0xb1, 0x40, 0x3e, 0x7c, 0x8d, 0x1f, 0x16, 0xc0, 0xe4, 0x9e, 0xbc, 0x58, 0x48, - 0x4a, 0xde, 0x80, 0xa1, 0x5a, 0xe8, 0x86, 0x24, 0xee, 0x64, 0xd0, 0xfb, 0x51, 0x2a, 0x19, 0x12, - 0x68, 0x32, 0xb5, 0xfa, 0x61, 0x3e, 0x9e, 0x1c, 0xfc, 0x44, 0xd5, 0xf7, 0xa6, 0xea, 0xcf, 0xcd, - 0x71, 0x55, 0xbf, 0x6b, 0x5a, 0x06, 0xb9, 0x08, 0xe7, 0xee, 0xd5, 0xa7, 0xb4, 0xc6, 0xdd, 0xda, - 0x7c, 0xb5, 0x71, 0x6f, 0xbe, 0xbe, 0x38, 0x35, 0x59, 0x9b, 0xae, 0x4d, 0x55, 0xc7, 0xfa, 0xc8, - 0x19, 0x38, 0x15, 0xa2, 0x66, 0xee, 0xcd, 0x55, 0xe6, 0xc7, 0x72, 0xe4, 0x34, 0x8c, 0x84, 0xc0, - 0x89, 0x85, 0xa5, 0xb1, 0xfc, 0x73, 0x9f, 0x81, 0x21, 0x74, 0xbf, 0xe2, 0xd7, 0xc5, 0x64, 0x18, - 0xca, 0x0b, 0x13, 0xf5, 0x29, 0xed, 0x3e, 0x32, 0x01, 0x28, 0x55, 0xa7, 0xe6, 0x19, 0xc3, 0xdc, - 0x73, 0xff, 0x77, 0x0e, 0xa0, 0x3e, 0xbd, 0xb4, 0x28, 0x08, 0x87, 0x60, 0xa0, 0x36, 0x7f, 0xbf, - 0x32, 0x5b, 0x63, 0x74, 0x65, 0x28, 0x2e, 0x2c, 0x4e, 0xb1, 0x1a, 0x06, 0xa1, 0x7f, 0x72, 0x76, - 0xa1, 0x3e, 0x35, 0x96, 0x67, 0x40, 0x6d, 0xaa, 0x52, 0x1d, 0x2b, 0x30, 0xe0, 0x03, 0xad, 0xb6, - 0x34, 0x35, 0x56, 0x64, 0x7f, 0xce, 0xd6, 0x97, 0x2a, 0x4b, 0x63, 0xfd, 0xec, 0xcf, 0x69, 0xfc, - 0xb3, 0xc4, 0x98, 0xd5, 0xa7, 0x96, 0xf0, 0xc7, 0x00, 0x6b, 0xc2, 0xb4, 0xff, 0xab, 0xcc, 0x50, - 0x8c, 0x75, 0xb5, 0xa6, 0x8d, 0x0d, 0xb2, 0x1f, 0x8c, 0x25, 0xfb, 0x01, 0xac, 0x71, 0xda, 0xd4, - 0xdc, 0xc2, 0xfd, 0xa9, 0xb1, 0x21, 0xc6, 0x6b, 0xee, 0x2e, 0x03, 0x0f, 0xb3, 0x3f, 0xb5, 0x39, - 0xf6, 0xe7, 0x08, 0xe3, 0xa4, 0x4d, 0x55, 0x66, 0x17, 0x2b, 0x4b, 0x33, 0x63, 0xa3, 0xac, 0x3d, - 0xc8, 0xf3, 0x14, 0x2f, 0x39, 0x5f, 0x99, 0x9b, 0x1a, 0x1b, 0x13, 0x34, 0xd5, 0xd9, 0xda, 0xfc, - 0xdd, 0xb1, 0xd3, 0xd8, 0x90, 0x77, 0xe7, 0xf0, 0x07, 0x61, 0x05, 0xf0, 0xaf, 0x33, 0xcf, 0xfd, - 0x30, 0x94, 0x16, 0xea, 0x38, 0x0a, 0x2e, 0xc0, 0x99, 0x85, 0x7a, 0x63, 0xe9, 0xdd, 0xc5, 0xa9, - 0x98, 0xbc, 0x4f, 0xc3, 0x88, 0x8f, 0x98, 0xad, 0xcd, 0xdf, 0xfb, 0x12, 0x97, 0xb6, 0x0f, 0x9a, - 0xab, 0x4c, 0x2e, 0xd4, 0xc7, 0xf2, 0xac, 0x57, 0x7c, 0xd0, 0x83, 0xda, 0x7c, 0x75, 0xe1, 0x41, - 0x7d, 0xac, 0xf0, 0xdc, 0x23, 0x18, 0xe6, 0xb9, 0x1d, 0x17, 0x1c, 0x73, 0xd5, 0xb4, 0xc8, 0x93, - 0x70, 0xb1, 0x3a, 0x75, 0xbf, 0x36, 0x39, 0xd5, 0x58, 0xd0, 0x6a, 0xb7, 0x6b, 0xf3, 0xb1, 0x9a, - 0xce, 0xc1, 0xe9, 0x28, 0xba, 0xb2, 0x58, 0x1b, 0xcb, 0x91, 0xf3, 0x40, 0xa2, 0xe0, 0x3b, 0x95, - 0xb9, 0xe9, 0xb1, 0x3c, 0x51, 0xe0, 0x6c, 0x14, 0x5e, 0x9b, 0x5f, 0xba, 0x37, 0x3f, 0x35, 0x56, - 0x78, 0xee, 0x2f, 0xe7, 0xe0, 0x5c, 0x6a, 0xfc, 0x5f, 0xa2, 0xc2, 0x53, 0x53, 0xb3, 0x95, 0xfa, - 0x52, 0x6d, 0xb2, 0x3e, 0x55, 0xd1, 0x26, 0x67, 0x1a, 0x93, 0x95, 0xa5, 0xa9, 0xdb, 0x0b, 0xda, - 0xbb, 0x8d, 0xdb, 0x53, 0xf3, 0x53, 0x5a, 0x65, 0x76, 0xac, 0x8f, 0x3c, 0x0b, 0xe3, 0x19, 0x34, - 0xf5, 0xa9, 0xc9, 0x7b, 0x5a, 0x6d, 0xe9, 0xdd, 0xb1, 0x1c, 0x79, 0x06, 0x9e, 0xcc, 0x24, 0x62, - 0xbf, 0xc7, 0xf2, 0xe4, 0x29, 0xb8, 0x94, 0x45, 0xf2, 0xce, 0xec, 0x58, 0xe1, 0xb9, 0x9f, 0xcf, - 0x01, 0x49, 0x06, 0x70, 0x25, 0x4f, 0xc3, 0x65, 0xa6, 0x17, 0x8d, 0xec, 0x06, 0x3e, 0x03, 0x4f, - 0xa6, 0x52, 0x48, 0xcd, 0x1b, 0x87, 0x27, 0x32, 0x48, 0x44, 0xe3, 0x2e, 0x83, 0x92, 0x4e, 0x80, - 0x4d, 0xfb, 0xad, 0x1c, 0x9c, 0x4b, 0xf5, 0xd0, 0x20, 0x57, 0xe1, 0x53, 0x95, 0xea, 0x1c, 0xeb, - 0x9b, 0xc9, 0xa5, 0xda, 0xc2, 0x7c, 0xbd, 0x31, 0x37, 0x5d, 0x69, 0x30, 0xed, 0xbb, 0x57, 0x8f, - 0xf5, 0xe6, 0x15, 0x50, 0x7b, 0x50, 0x4e, 0xce, 0x54, 0xe6, 0x6f, 0xb3, 0xe1, 0x47, 0x3e, 0x05, - 0x4f, 0x67, 0xd2, 0x4d, 0xcd, 0x57, 0x26, 0x66, 0xa7, 0xaa, 0x63, 0x79, 0xf2, 0x69, 0x78, 0x26, - 0x93, 0xaa, 0x5a, 0xab, 0x73, 0xb2, 0xc2, 0x44, 0xf5, 0xc3, 0xff, 0xe9, 0xa9, 0xbe, 0x0f, 0xff, - 0xe8, 0xa9, 0xdc, 0xdf, 0xff, 0xa3, 0xa7, 0x72, 0xff, 0xf4, 0x8f, 0x9e, 0xca, 0x7d, 0xf9, 0xe6, - 0x6e, 0x02, 0xf3, 0xf2, 0x69, 0x6b, 0xb9, 0x84, 0xb7, 0xa5, 0x2f, 0xfd, 0xff, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xf3, 0xef, 0xd0, 0xdb, 0x09, 0x7c, 0x01, 0x00, + 0x72, 0x18, 0x86, 0x7e, 0xa0, 0x01, 0x04, 0x1e, 0x03, 0xe4, 0xbc, 0x6a, 0x66, 0x67, 0x07, 0xbb, + 0xb5, 0x77, 0x73, 0x33, 0x7b, 0xbb, 0x33, 0xb7, 0xb3, 0xb3, 0xbb, 0xb7, 0xaf, 0xdb, 0x6b, 0xa0, + 0x81, 0x41, 0xcf, 0xe0, 0xb5, 0xd5, 0x98, 0x99, 0xdb, 0x23, 0xef, 0x9a, 0x85, 0xae, 0x44, 0xa3, + 0x76, 0xba, 0xab, 0x9a, 0x55, 0xd5, 0x83, 0xc1, 0xfa, 0xc5, 0xa3, 0x29, 0x8a, 0x14, 0x8f, 0xa7, + 0xf3, 0xd1, 0x14, 0xa9, 0x87, 0x2d, 0x52, 0x0f, 0x9b, 0xa2, 0x28, 0x52, 0x94, 0x68, 0x92, 0x47, + 0xf2, 0x2c, 0xc9, 0xe7, 0xc7, 0x49, 0xfc, 0xcc, 0x8f, 0x94, 0x6d, 0x7d, 0xfa, 0x6c, 0x19, 0x27, + 0xd3, 0xd6, 0x1f, 0x7c, 0xf6, 0xf7, 0xd1, 0x36, 0x3f, 0xeb, 0x2c, 0xcb, 0xfe, 0xfc, 0x65, 0x64, + 0x56, 0x55, 0xd6, 0xab, 0xf1, 0x5c, 0x62, 0xb1, 0x83, 0x3f, 0x33, 0xe8, 0x88, 0xc8, 0xc8, 0xac, + 0xc8, 0xc8, 0xcc, 0xc8, 0xcc, 0xc8, 0x08, 0xb8, 0xe6, 0xd1, 0x16, 0xed, 0xd8, 0x8e, 0x77, 0xa3, + 0x45, 0x9b, 0x7a, 0x63, 0xf3, 0x86, 0xb7, 0xd9, 0xa1, 0xee, 0x0d, 0xfa, 0x88, 0x5a, 0x9e, 0xff, + 0xdf, 0xf5, 0x8e, 0x63, 0x7b, 0x36, 0x29, 0xf1, 0x5f, 0x17, 0xcf, 0x34, 0xed, 0xa6, 0x8d, 0xa0, + 0x1b, 0xec, 0x2f, 0x8e, 0xbd, 0x78, 0xa9, 0x69, 0xdb, 0xcd, 0x16, 0xbd, 0x81, 0xbf, 0x56, 0xbb, + 0x6b, 0x37, 0x5c, 0xcf, 0xe9, 0x36, 0x3c, 0x81, 0x9d, 0x8c, 0x63, 0x3d, 0xb3, 0x4d, 0x5d, 0x4f, + 0x6f, 0x77, 0x04, 0xc1, 0xe5, 0x38, 0xc1, 0x86, 0xa3, 0x77, 0x3a, 0xd4, 0x11, 0x95, 0x5f, 0x7c, + 0x36, 0xbd, 0x9d, 0xf8, 0xaf, 0x20, 0x79, 0x31, 0x9d, 0xc4, 0x67, 0x14, 0xe3, 0xa8, 0x7e, 0x23, + 0x0f, 0x83, 0x0b, 0xd4, 0xd3, 0x0d, 0xdd, 0xd3, 0xc9, 0x25, 0xe8, 0xaf, 0x5a, 0x06, 0x7d, 0xac, + 0xe4, 0x9e, 0xc9, 0x5d, 0x2d, 0x4c, 0x95, 0xb6, 0xb7, 0x26, 0xf3, 0xd4, 0xd4, 0x38, 0x90, 0x3c, + 0x0d, 0xc5, 0x95, 0xcd, 0x0e, 0x55, 0xf2, 0xcf, 0xe4, 0xae, 0x0e, 0x4d, 0x0d, 0x6d, 0x6f, 0x4d, + 0xf6, 0xa3, 0x2c, 0x34, 0x04, 0x93, 0x67, 0x21, 0x5f, 0xad, 0x28, 0x05, 0x44, 0x4e, 0x6c, 0x6f, + 0x4d, 0x8e, 0x76, 0x4d, 0xe3, 0x05, 0xbb, 0x6d, 0x7a, 0xb4, 0xdd, 0xf1, 0x36, 0xb5, 0x7c, 0xb5, + 0x42, 0xae, 0x40, 0x71, 0xda, 0x36, 0xa8, 0x52, 0x44, 0x22, 0xb2, 0xbd, 0x35, 0x39, 0xd6, 0xb0, + 0x0d, 0x2a, 0x51, 0x21, 0x9e, 0x7c, 0x1e, 0x8a, 0x2b, 0x66, 0x9b, 0x2a, 0xfd, 0xcf, 0xe4, 0xae, + 0x0e, 0xdf, 0xbc, 0x78, 0x9d, 0x4b, 0xe5, 0xba, 0x2f, 0x95, 0xeb, 0x2b, 0xbe, 0xd8, 0xa6, 0xc6, + 0xbf, 0xb3, 0x35, 0xd9, 0xb7, 0xbd, 0x35, 0x59, 0x64, 0x92, 0xfc, 0xfa, 0x77, 0x27, 0x73, 0x1a, + 0x96, 0x24, 0x6f, 0xc1, 0xf0, 0x74, 0xab, 0xeb, 0x7a, 0xd4, 0x59, 0xd4, 0xdb, 0x54, 0x29, 0x61, + 0x85, 0x17, 0xb7, 0xb7, 0x26, 0xcf, 0x35, 0x38, 0xb8, 0x6e, 0xe9, 0x6d, 0xb9, 0x62, 0x99, 0x5c, + 0xfd, 0xcd, 0x1c, 0x9c, 0xaa, 0x51, 0xd7, 0x35, 0x6d, 0x2b, 0x90, 0xcd, 0x27, 0x61, 0x48, 0x80, + 0xaa, 0x15, 0x94, 0xcf, 0xd0, 0xd4, 0xc0, 0xf6, 0xd6, 0x64, 0xc1, 0x35, 0x0d, 0x2d, 0xc4, 0x90, + 0xcf, 0xc0, 0xc0, 0x03, 0xd3, 0x5b, 0x5f, 0x98, 0x2d, 0x0b, 0x39, 0x9d, 0xdb, 0xde, 0x9a, 0x24, + 0x1b, 0xa6, 0xb7, 0x5e, 0x6f, 0xaf, 0xe9, 0x52, 0x85, 0x3e, 0x19, 0x99, 0x87, 0xf1, 0x65, 0xc7, + 0x7c, 0xa4, 0x7b, 0xf4, 0x2e, 0xdd, 0x5c, 0xb6, 0x5b, 0x66, 0x63, 0x53, 0x48, 0xf1, 0x99, 0xed, + 0xad, 0xc9, 0x4b, 0x1d, 0x8e, 0xab, 0x3f, 0xa4, 0x9b, 0xf5, 0x0e, 0x62, 0x25, 0x26, 0x89, 0x92, + 0xea, 0x6f, 0x95, 0x60, 0xe4, 0x9e, 0x4b, 0x9d, 0xa0, 0xdd, 0x57, 0xa0, 0xc8, 0x7e, 0x8b, 0x26, + 0xa3, 0xcc, 0xbb, 0x2e, 0x75, 0x64, 0x99, 0x33, 0x3c, 0xb9, 0x06, 0xfd, 0xf3, 0x76, 0xd3, 0xb4, + 0x44, 0xb3, 0x4f, 0x6f, 0x6f, 0x4d, 0x9e, 0x6a, 0x31, 0x80, 0x44, 0xc9, 0x29, 0xc8, 0xe7, 0x60, + 0xa4, 0xda, 0x66, 0x3a, 0x64, 0x5b, 0xba, 0x67, 0x3b, 0xa2, 0xb5, 0x28, 0x5d, 0x53, 0x82, 0x4b, + 0x05, 0x23, 0xf4, 0xe4, 0x0d, 0x80, 0xf2, 0x83, 0x9a, 0x66, 0xb7, 0x68, 0x59, 0x5b, 0x14, 0xca, + 0x80, 0xa5, 0xf5, 0x0d, 0xb7, 0xee, 0xd8, 0x2d, 0x5a, 0xd7, 0x1d, 0xb9, 0x5a, 0x89, 0x9a, 0xcc, + 0xc0, 0x58, 0xb9, 0xd1, 0xa0, 0xae, 0xab, 0xd1, 0x1f, 0xec, 0x52, 0xd7, 0x73, 0x95, 0xfe, 0x67, + 0x0a, 0x57, 0x87, 0xa6, 0x9e, 0xde, 0xde, 0x9a, 0xbc, 0xa0, 0x23, 0xa6, 0xee, 0x08, 0x94, 0xc4, + 0x22, 0x56, 0x88, 0x4c, 0xc1, 0x68, 0xf9, 0x83, 0xae, 0x43, 0xab, 0x06, 0xb5, 0x3c, 0xd3, 0xdb, + 0x14, 0x1a, 0x72, 0x69, 0x7b, 0x6b, 0x52, 0xd1, 0x19, 0xa2, 0x6e, 0x0a, 0x8c, 0xc4, 0x24, 0x5a, + 0x84, 0x2c, 0xc1, 0xc4, 0xed, 0xe9, 0xe5, 0x1a, 0x75, 0x1e, 0x99, 0x0d, 0x5a, 0x6e, 0x34, 0xec, + 0xae, 0xe5, 0x29, 0x03, 0xc8, 0xe7, 0xd9, 0xed, 0xad, 0xc9, 0xa7, 0x9b, 0x8d, 0x4e, 0xdd, 0xe5, + 0xd8, 0xba, 0xce, 0xd1, 0x12, 0xb3, 0x64, 0x59, 0xf2, 0x45, 0x18, 0x5d, 0x71, 0x98, 0x16, 0x1a, + 0x15, 0xca, 0xe0, 0xca, 0x20, 0xea, 0xff, 0xb9, 0xeb, 0x62, 0x02, 0xe2, 0x50, 0xbf, 0x67, 0x79, + 0x63, 0x3d, 0x5e, 0xa0, 0x6e, 0x20, 0x4e, 0x6e, 0x6c, 0x84, 0x15, 0xa1, 0xa0, 0xb0, 0x8f, 0x37, + 0x1d, 0x6a, 0x24, 0xb4, 0x6d, 0x08, 0xdb, 0x7c, 0x6d, 0x7b, 0x6b, 0xf2, 0x93, 0x8e, 0xa0, 0xa9, + 0xf7, 0x54, 0xbb, 0x4c, 0x56, 0x64, 0x06, 0x06, 0x99, 0x36, 0xdd, 0x35, 0x2d, 0x43, 0x81, 0x67, + 0x72, 0x57, 0xc7, 0x6e, 0x8e, 0xfb, 0xad, 0xf7, 0xe1, 0x53, 0xe7, 0xb7, 0xb7, 0x26, 0x4f, 0x33, + 0x1d, 0xac, 0x3f, 0x34, 0x2d, 0x79, 0x8a, 0x08, 0x8a, 0xb2, 0x51, 0x34, 0x65, 0x7b, 0x38, 0x74, + 0x87, 0xc3, 0x51, 0xb4, 0x6a, 0x7b, 0xf1, 0x61, 0xeb, 0x93, 0x91, 0x69, 0x18, 0x9d, 0xb2, 0xbd, + 0xaa, 0xe5, 0x7a, 0xba, 0xd5, 0xa0, 0xd5, 0x8a, 0x32, 0x82, 0xe5, 0x50, 0x2d, 0x58, 0x39, 0x53, + 0x60, 0xea, 0x91, 0x49, 0x29, 0x5a, 0x46, 0xfd, 0x97, 0x45, 0x18, 0x63, 0x7d, 0x22, 0x0d, 0x9f, + 0x32, 0x9b, 0x09, 0x18, 0x84, 0xd5, 0xe2, 0x76, 0xf4, 0x06, 0x15, 0x23, 0x09, 0xbf, 0xc2, 0xf2, + 0x81, 0x12, 0xcf, 0x38, 0x3d, 0xb9, 0x06, 0x83, 0x1c, 0x54, 0xad, 0x88, 0xc1, 0x35, 0xba, 0xbd, + 0x35, 0x39, 0xe4, 0x22, 0xac, 0x6e, 0x1a, 0x5a, 0x80, 0x66, 0xda, 0xcd, 0xff, 0x9e, 0xb3, 0x5d, + 0x8f, 0x31, 0x17, 0x63, 0x0b, 0x3f, 0x43, 0x14, 0x58, 0x17, 0x28, 0x59, 0xbb, 0xa3, 0x85, 0xc8, + 0xeb, 0x00, 0x1c, 0x52, 0x36, 0x0c, 0x47, 0x0c, 0xb0, 0x0b, 0xdb, 0x5b, 0x93, 0x67, 0x05, 0x0b, + 0xdd, 0x30, 0xe4, 0xd1, 0x29, 0x11, 0x93, 0x36, 0x8c, 0xf0, 0x5f, 0xf3, 0xfa, 0x2a, 0x6d, 0xf1, + 0xd1, 0x35, 0x7c, 0xf3, 0xaa, 0xdf, 0x89, 0x51, 0xe9, 0x5c, 0x97, 0x49, 0x67, 0x2c, 0xcf, 0xd9, + 0x9c, 0x9a, 0x14, 0x13, 0xf2, 0x79, 0x51, 0x55, 0x0b, 0x71, 0xf2, 0x54, 0x20, 0x97, 0x61, 0xf3, + 0xf4, 0xac, 0xed, 0x6c, 0xe8, 0x8e, 0x41, 0x8d, 0xa9, 0x4d, 0x79, 0x9e, 0x5e, 0xf3, 0xc1, 0xf5, + 0x55, 0x59, 0xf5, 0x64, 0x72, 0xd6, 0xe9, 0x9c, 0x5b, 0xad, 0xbb, 0x8a, 0x2a, 0x37, 0x90, 0x90, + 0x96, 0xdb, 0x5d, 0x8d, 0xab, 0x59, 0xb4, 0x0c, 0x9b, 0x0a, 0x38, 0xe0, 0x3e, 0x75, 0xd8, 0x24, + 0x8e, 0xa3, 0x4e, 0x4c, 0x05, 0x82, 0xc9, 0x23, 0x8e, 0x49, 0xf2, 0x10, 0x45, 0x2e, 0xbe, 0x03, + 0x13, 0x09, 0x51, 0x90, 0x71, 0x28, 0x3c, 0xa4, 0x9b, 0x5c, 0x5d, 0x34, 0xf6, 0x27, 0x39, 0x03, + 0xfd, 0x8f, 0xf4, 0x56, 0x57, 0x2c, 0xa1, 0x1a, 0xff, 0xf1, 0x46, 0xfe, 0xb3, 0x39, 0xb6, 0xe2, + 0x90, 0x69, 0xdb, 0xb2, 0x68, 0xc3, 0x93, 0x17, 0x9d, 0x57, 0x61, 0x68, 0xde, 0x6e, 0xe8, 0x2d, + 0xec, 0x47, 0xae, 0x77, 0xca, 0xf6, 0xd6, 0xe4, 0x19, 0xd6, 0x81, 0xd7, 0x5b, 0x0c, 0x23, 0xb5, + 0x29, 0x24, 0x65, 0x0a, 0xa0, 0xd1, 0xb6, 0xed, 0x51, 0x2c, 0x98, 0x0f, 0x15, 0x00, 0x0b, 0x3a, + 0x88, 0x92, 0x15, 0x20, 0x24, 0x26, 0x37, 0x60, 0x70, 0x99, 0xad, 0xb3, 0x0d, 0xbb, 0x25, 0x94, + 0x0f, 0x97, 0x02, 0x5c, 0x7b, 0xe5, 0xb1, 0xea, 0x13, 0xa9, 0x73, 0x30, 0x36, 0xdd, 0x32, 0xa9, + 0xe5, 0xc9, 0xad, 0x66, 0x23, 0xb9, 0xdc, 0xa4, 0x96, 0x27, 0xb7, 0x1a, 0xc7, 0xbc, 0xce, 0xa0, + 0x72, 0xab, 0x03, 0x52, 0xf5, 0xf7, 0x0a, 0x70, 0xe1, 0x6e, 0x77, 0x95, 0x3a, 0x16, 0xf5, 0xa8, + 0x2b, 0x16, 0xe4, 0x80, 0xeb, 0x22, 0x4c, 0x24, 0x90, 0x82, 0x3b, 0x2e, 0x94, 0x0f, 0x03, 0x64, + 0x5d, 0xac, 0xf1, 0xf2, 0x6c, 0x9b, 0x28, 0x4a, 0xe6, 0xe0, 0x54, 0x08, 0x64, 0x8d, 0x70, 0x95, + 0x3c, 0x2e, 0x25, 0x97, 0xb7, 0xb7, 0x26, 0x2f, 0x4a, 0xdc, 0x58, 0xb3, 0x65, 0x0d, 0x8e, 0x17, + 0x23, 0x77, 0x61, 0x3c, 0x04, 0xdd, 0x76, 0xec, 0x6e, 0xc7, 0x55, 0x0a, 0xc8, 0x6a, 0x72, 0x7b, + 0x6b, 0xf2, 0x29, 0x89, 0x55, 0x13, 0x91, 0xf2, 0x02, 0x1e, 0x2f, 0x48, 0x7e, 0x24, 0x27, 0x73, + 0x13, 0xa3, 0xb0, 0x88, 0xa3, 0xf0, 0x35, 0x7f, 0x14, 0x66, 0x0a, 0xe9, 0x7a, 0xbc, 0xa4, 0x18, + 0x94, 0xb1, 0x66, 0x24, 0x06, 0x65, 0xa2, 0xc6, 0x8b, 0xd3, 0x70, 0x36, 0x95, 0xd7, 0x9e, 0xb4, + 0xfa, 0x5f, 0x14, 0x64, 0x2e, 0xcb, 0xb6, 0x11, 0x74, 0xe6, 0x92, 0xdc, 0x99, 0xcb, 0xb6, 0x81, + 0x53, 0x7d, 0x2e, 0x5c, 0x3b, 0xa5, 0xc6, 0x76, 0x6c, 0x23, 0x3e, 0xeb, 0x27, 0xcb, 0x92, 0x2f, + 0xc3, 0xb9, 0x04, 0x90, 0x4f, 0xd7, 0x5c, 0xfb, 0xaf, 0x6c, 0x6f, 0x4d, 0xaa, 0x29, 0x5c, 0xe3, + 0xb3, 0x77, 0x06, 0x17, 0xa2, 0xc3, 0x79, 0x49, 0xea, 0xb6, 0xe5, 0xe9, 0xa6, 0x25, 0x8c, 0x4b, + 0x3e, 0x4a, 0x3e, 0xb5, 0xbd, 0x35, 0xf9, 0x9c, 0xac, 0x83, 0x3e, 0x4d, 0xbc, 0xf1, 0x59, 0x7c, + 0x88, 0x01, 0x4a, 0x0a, 0xaa, 0xda, 0xd6, 0x9b, 0xbe, 0xc5, 0x7c, 0x75, 0x7b, 0x6b, 0xf2, 0x13, + 0xa9, 0x75, 0x98, 0x8c, 0x4a, 0x5e, 0xa1, 0xb3, 0x38, 0x11, 0x0d, 0x48, 0x88, 0x5b, 0xb4, 0x0d, + 0x8a, 0xdf, 0xd0, 0x8f, 0xfc, 0xd5, 0xed, 0xad, 0xc9, 0xcb, 0x12, 0x7f, 0xcb, 0x36, 0x68, 0xbc, + 0xf9, 0x29, 0xa5, 0xd5, 0xdf, 0x2c, 0xc0, 0xe5, 0x5a, 0x79, 0x61, 0xbe, 0x6a, 0xf8, 0x26, 0xcd, + 0xb2, 0x63, 0x3f, 0x32, 0x0d, 0x69, 0xf4, 0xae, 0xc2, 0xf9, 0x18, 0x6a, 0x06, 0xad, 0xa8, 0xc0, + 0x98, 0xc6, 0x6f, 0xf3, 0xcd, 0xa5, 0x8e, 0xa0, 0xa9, 0x73, 0x53, 0x2b, 0xba, 0x68, 0x67, 0x31, + 0x62, 0x7d, 0x14, 0x43, 0xd5, 0xd6, 0x6d, 0xc7, 0x6b, 0x74, 0x3d, 0xa1, 0x04, 0xd8, 0x47, 0x89, + 0x3a, 0x5c, 0x41, 0xd4, 0xa3, 0x0a, 0x9f, 0x0f, 0xf9, 0xf1, 0x1c, 0x8c, 0x97, 0x3d, 0xcf, 0x31, + 0x57, 0xbb, 0x1e, 0x5d, 0xd0, 0x3b, 0x1d, 0xd3, 0x6a, 0xe2, 0x58, 0x1f, 0xbe, 0xf9, 0x56, 0xb0, + 0x46, 0xf6, 0x94, 0xc4, 0xf5, 0x78, 0x71, 0x69, 0x88, 0xea, 0x3e, 0xaa, 0xde, 0xe6, 0x38, 0x79, + 0x88, 0xc6, 0xcb, 0xb1, 0x21, 0x9a, 0xca, 0x6b, 0x4f, 0x43, 0xf4, 0x1b, 0x05, 0xb8, 0xb4, 0xf4, + 0xd0, 0xd3, 0x35, 0xea, 0xda, 0x5d, 0xa7, 0x41, 0xdd, 0x7b, 0x1d, 0x43, 0xf7, 0x68, 0x38, 0x52, + 0x27, 0xa1, 0xbf, 0x6c, 0x18, 0xd4, 0x40, 0x76, 0xfd, 0x7c, 0xdb, 0xa7, 0x33, 0x80, 0xc6, 0xe1, + 0xe4, 0x93, 0x30, 0x20, 0xca, 0x20, 0xf7, 0xfe, 0xa9, 0xe1, 0xed, 0xad, 0xc9, 0x81, 0x2e, 0x07, + 0x69, 0x3e, 0x8e, 0x91, 0x55, 0x68, 0x8b, 0x32, 0xb2, 0x42, 0x48, 0x66, 0x70, 0x90, 0xe6, 0xe3, + 0xc8, 0xbb, 0x30, 0x86, 0x6c, 0x83, 0xf6, 0x88, 0xb9, 0xef, 0x8c, 0x2f, 0x5d, 0xb9, 0xb1, 0x7c, + 0x69, 0xc2, 0xd6, 0xd4, 0x1d, 0xbf, 0x80, 0x16, 0x63, 0x40, 0x1e, 0xc0, 0xb8, 0x68, 0x44, 0xc8, + 0xb4, 0xbf, 0x07, 0xd3, 0xb3, 0xdb, 0x5b, 0x93, 0x13, 0xa2, 0xfd, 0x12, 0xdb, 0x04, 0x13, 0xc6, + 0x58, 0x34, 0x3b, 0x64, 0x5c, 0xda, 0x89, 0xb1, 0xf8, 0x62, 0x99, 0x71, 0x9c, 0x89, 0xfa, 0x1e, + 0x8c, 0xc8, 0x05, 0xc9, 0x39, 0xdc, 0x5a, 0xf3, 0x71, 0x82, 0x9b, 0x72, 0xd3, 0xc0, 0xfd, 0xf4, + 0x4b, 0x30, 0x5c, 0xa1, 0x6e, 0xc3, 0x31, 0x3b, 0xcc, 0x6a, 0x10, 0x4a, 0x7e, 0x6a, 0x7b, 0x6b, + 0x72, 0xd8, 0x08, 0xc1, 0x9a, 0x4c, 0xa3, 0xfe, 0x5f, 0x39, 0x38, 0xc7, 0x78, 0x97, 0x5d, 0xd7, + 0x6c, 0x5a, 0x6d, 0x79, 0xd9, 0x7e, 0x01, 0x4a, 0x35, 0xac, 0x4f, 0xd4, 0x74, 0x66, 0x7b, 0x6b, + 0x72, 0x9c, 0xb7, 0x40, 0xd2, 0x43, 0x41, 0x13, 0xec, 0x2b, 0xf3, 0x3b, 0xec, 0x2b, 0x99, 0x49, + 0xeb, 0xe9, 0x8e, 0x67, 0x5a, 0xcd, 0x9a, 0xa7, 0x7b, 0x5d, 0x37, 0x62, 0xd2, 0x0a, 0x4c, 0xdd, + 0x45, 0x54, 0xc4, 0xa4, 0x8d, 0x14, 0x22, 0xef, 0xc0, 0xc8, 0x8c, 0x65, 0x84, 0x4c, 0xf8, 0x84, + 0xf8, 0x14, 0xb3, 0x34, 0x29, 0xc2, 0x93, 0x2c, 0x22, 0x05, 0xd4, 0xbf, 0x95, 0x03, 0x85, 0x6f, + 0x02, 0xe7, 0x4d, 0xd7, 0x5b, 0xa0, 0xed, 0x55, 0x69, 0x76, 0x9a, 0xf5, 0x77, 0x95, 0x0c, 0x27, + 0xad, 0x45, 0x68, 0x0a, 0x88, 0x5d, 0x65, 0xcb, 0x74, 0x13, 0xdb, 0x8f, 0x58, 0x29, 0x52, 0x85, + 0x01, 0xce, 0x99, 0xdb, 0x12, 0xc3, 0x37, 0x15, 0x5f, 0x11, 0xe2, 0x55, 0x73, 0x65, 0x68, 0x73, + 0x62, 0x79, 0x43, 0x23, 0xca, 0xab, 0x7f, 0x3b, 0x0f, 0xe3, 0xf1, 0x42, 0xe4, 0x01, 0x0c, 0xde, + 0xb1, 0x4d, 0x8b, 0x1a, 0x4b, 0x16, 0xb6, 0xb0, 0xf7, 0xe1, 0x88, 0x6f, 0x8b, 0x9f, 0x7e, 0x1f, + 0xcb, 0xd4, 0x65, 0x0b, 0x16, 0xcf, 0x4a, 0x02, 0x66, 0xe4, 0x8b, 0x30, 0xc4, 0x6c, 0xc0, 0x47, + 0xc8, 0x39, 0xbf, 0x23, 0xe7, 0x67, 0x04, 0xe7, 0x33, 0x0e, 0x2f, 0x94, 0x64, 0x1d, 0xb2, 0x63, + 0x7a, 0xa5, 0x51, 0xdd, 0xb5, 0x2d, 0xd1, 0xf3, 0xa8, 0x57, 0x0e, 0x42, 0x64, 0xbd, 0xe2, 0x34, + 0xcc, 0x74, 0xe5, 0x1f, 0x8b, 0xdd, 0x20, 0xed, 0x5d, 0xb8, 0xac, 0xe2, 0x3d, 0x20, 0x11, 0xab, + 0x3f, 0x9a, 0x87, 0x17, 0x43, 0x91, 0x69, 0xf4, 0x91, 0x49, 0x37, 0x84, 0x38, 0xd7, 0xcd, 0x8e, + 0xd8, 0xb3, 0x32, 0x95, 0x77, 0xa7, 0xd7, 0x75, 0xab, 0x49, 0x0d, 0x72, 0x0d, 0xfa, 0x35, 0xbb, + 0x45, 0x5d, 0x25, 0x87, 0xe6, 0x1a, 0x4e, 0x27, 0x0e, 0x03, 0xc8, 0x87, 0x1e, 0x48, 0x41, 0x6c, + 0x28, 0xad, 0x38, 0xba, 0xe9, 0xf9, 0x3d, 0x5b, 0x4e, 0xf6, 0xec, 0x2e, 0x6a, 0xbc, 0xce, 0x79, + 0xf0, 0x39, 0x1f, 0x05, 0xe1, 0x21, 0x40, 0x16, 0x04, 0x27, 0xb9, 0xf8, 0x3a, 0x0c, 0x4b, 0xc4, + 0x7b, 0x9a, 0xd4, 0xbf, 0x59, 0x94, 0x75, 0xdd, 0x6f, 0x96, 0xd0, 0xf5, 0x1b, 0x4c, 0x47, 0x5d, + 0x97, 0x59, 0x15, 0x5c, 0xc9, 0x85, 0x26, 0x22, 0x28, 0xaa, 0x89, 0x08, 0x22, 0x2f, 0xc3, 0x20, + 0x67, 0x11, 0xec, 0x5f, 0x71, 0xef, 0xeb, 0x20, 0x2c, 0xba, 0x34, 0x07, 0x84, 0xe4, 0x17, 0x73, + 0xf0, 0x74, 0x4f, 0x49, 0xa0, 0x32, 0x0c, 0xdf, 0x7c, 0x65, 0x5f, 0x62, 0x9c, 0x7a, 0x71, 0x7b, + 0x6b, 0xf2, 0x5a, 0x3b, 0x20, 0xa9, 0x3b, 0x12, 0x4d, 0xbd, 0xc1, 0x89, 0xa4, 0x76, 0xf5, 0x6e, + 0x0a, 0x33, 0x1e, 0x79, 0xa5, 0xb3, 0x78, 0x74, 0x64, 0x35, 0x36, 0xfd, 0x46, 0x16, 0x43, 0xe3, + 0x51, 0x7c, 0xef, 0x9a, 0x4f, 0x92, 0x52, 0x4d, 0x06, 0x17, 0xd2, 0x80, 0xf3, 0x1c, 0x53, 0xd1, + 0x37, 0x97, 0xd6, 0x16, 0x6c, 0xcb, 0x5b, 0xf7, 0x2b, 0xe8, 0x97, 0xcf, 0x5e, 0xb0, 0x02, 0x43, + 0xdf, 0xac, 0xdb, 0x6b, 0xf5, 0x36, 0xa3, 0x4a, 0xa9, 0x23, 0x8b, 0x13, 0x9b, 0x68, 0xc5, 0x98, + 0xf3, 0xa7, 0xa0, 0x52, 0x78, 0x32, 0xe6, 0x8f, 0xd3, 0xe4, 0x84, 0x13, 0x2b, 0xa4, 0x56, 0x61, + 0x64, 0xde, 0x6e, 0x3c, 0x0c, 0xd4, 0xe5, 0x75, 0x28, 0xad, 0xe8, 0x4e, 0x93, 0x7a, 0x28, 0x8b, + 0xe1, 0x9b, 0x13, 0xd7, 0xf9, 0x69, 0x33, 0x23, 0xe2, 0x88, 0xa9, 0x31, 0x31, 0x1b, 0x94, 0x3c, + 0xfc, 0xad, 0x89, 0x02, 0xea, 0x77, 0xfb, 0x61, 0x44, 0x9c, 0x8c, 0xe2, 0x6c, 0x4e, 0xde, 0x08, + 0xcf, 0x9a, 0xc5, 0xf4, 0x15, 0x9c, 0x0e, 0x05, 0xa7, 0x5a, 0x23, 0x8c, 0xd9, 0xef, 0x6f, 0x4d, + 0xe6, 0xb6, 0xb7, 0x26, 0xfb, 0xb4, 0x41, 0x69, 0x53, 0x19, 0xae, 0x37, 0xd2, 0x02, 0x2b, 0x9f, + 0x75, 0xc6, 0xca, 0xf2, 0xf5, 0xe7, 0x1d, 0x18, 0x10, 0x6d, 0x10, 0x1a, 0x77, 0x3e, 0x3c, 0xcb, + 0x88, 0x9c, 0xf0, 0xc6, 0x4a, 0xfb, 0xa5, 0xc8, 0x5b, 0x50, 0xe2, 0x7b, 0x7b, 0x21, 0x80, 0x73, + 0xe9, 0x67, 0x21, 0xb1, 0xe2, 0xa2, 0x0c, 0x99, 0x03, 0x08, 0xf7, 0xf5, 0xc1, 0x81, 0xb6, 0xe0, + 0x90, 0xdc, 0xf1, 0xc7, 0xb8, 0x48, 0x65, 0xc9, 0xab, 0x30, 0xb2, 0x42, 0x9d, 0xb6, 0x69, 0xe9, + 0xad, 0x9a, 0xf9, 0x81, 0x7f, 0xa6, 0x8d, 0x0b, 0xaf, 0x6b, 0x7e, 0x20, 0x8f, 0xdc, 0x08, 0x1d, + 0xf9, 0x52, 0xda, 0xbe, 0x79, 0x00, 0x1b, 0xf2, 0xec, 0x8e, 0x1b, 0xca, 0x58, 0x7b, 0x52, 0xb6, + 0xd1, 0xef, 0xc2, 0x68, 0x64, 0xcb, 0x24, 0x0e, 0x2d, 0x9f, 0x4e, 0xb2, 0x96, 0xf6, 0x7f, 0x31, + 0xb6, 0x51, 0x0e, 0x4c, 0x93, 0xab, 0x96, 0xe9, 0x99, 0x7a, 0x6b, 0xda, 0x6e, 0xb7, 0x75, 0xcb, + 0x50, 0x86, 0x42, 0x4d, 0x36, 0x39, 0xa6, 0xde, 0xe0, 0x28, 0x59, 0x93, 0xa3, 0x85, 0xd8, 0xb6, + 0x5c, 0xf4, 0xa1, 0x46, 0x1b, 0xb6, 0xc3, 0x6c, 0x01, 0x3c, 0x93, 0x14, 0xdb, 0x72, 0x97, 0xe3, + 0xea, 0x8e, 0x8f, 0x94, 0x8d, 0xed, 0x78, 0xc1, 0x3b, 0xc5, 0xc1, 0xe1, 0xf1, 0x91, 0xf8, 0x31, + 0xb2, 0xfa, 0x37, 0x0a, 0x30, 0x2c, 0x48, 0xd9, 0x52, 0x7a, 0xa2, 0xe0, 0x07, 0x51, 0xf0, 0x54, + 0x45, 0x2d, 0x1d, 0x96, 0xa2, 0xaa, 0x5f, 0xcd, 0x07, 0xb3, 0xd1, 0xb2, 0x63, 0x5a, 0x07, 0x9b, + 0x8d, 0xae, 0x00, 0x4c, 0xaf, 0x77, 0xad, 0x87, 0xfc, 0xba, 0x2c, 0x1f, 0x5e, 0x97, 0x35, 0x4c, + 0x4d, 0xc2, 0x90, 0xa7, 0xa1, 0x58, 0x61, 0xfc, 0x59, 0xcf, 0x8c, 0x4c, 0x0d, 0x7d, 0x87, 0x73, + 0xca, 0xbd, 0xa8, 0x21, 0x98, 0x6d, 0xae, 0xa6, 0x36, 0x3d, 0xca, 0xcd, 0xd9, 0x02, 0xdf, 0x5c, + 0xad, 0x32, 0x80, 0xc6, 0xe1, 0xe4, 0x16, 0x4c, 0x54, 0x68, 0x4b, 0xdf, 0x5c, 0x30, 0x5b, 0x2d, + 0xd3, 0xa5, 0x0d, 0xdb, 0x32, 0x5c, 0x14, 0xb2, 0xa8, 0xae, 0xed, 0x6a, 0x49, 0x02, 0xa2, 0x42, + 0x69, 0x69, 0x6d, 0xcd, 0xa5, 0x1e, 0x8a, 0xaf, 0x30, 0x05, 0x6c, 0x72, 0xb6, 0x11, 0xa2, 0x09, + 0x8c, 0xfa, 0x2b, 0x39, 0xb6, 0x7b, 0x71, 0x1f, 0x7a, 0x76, 0x27, 0xd0, 0xf2, 0x03, 0x89, 0xe4, + 0x5a, 0x68, 0x57, 0xe4, 0xf1, 0x6b, 0x4f, 0x89, 0xaf, 0x1d, 0x10, 0xb6, 0x45, 0x68, 0x51, 0xa4, + 0x7e, 0x55, 0x61, 0x87, 0xaf, 0x52, 0xff, 0x28, 0x0f, 0xe7, 0x45, 0x8b, 0xa7, 0x5b, 0x66, 0x67, + 0xd5, 0xd6, 0x1d, 0x43, 0xa3, 0x0d, 0x6a, 0x3e, 0xa2, 0xc7, 0x73, 0xe0, 0x45, 0x87, 0x4e, 0xf1, + 0x00, 0x43, 0xe7, 0x26, 0x6e, 0x04, 0x99, 0x64, 0xf0, 0xc0, 0x97, 0x1b, 0x15, 0xe3, 0xdb, 0x5b, + 0x93, 0x23, 0x06, 0x07, 0xe3, 0x91, 0xbf, 0x26, 0x13, 0x31, 0x25, 0x99, 0xa7, 0x56, 0xd3, 0x5b, + 0x47, 0x25, 0xe9, 0xe7, 0x4a, 0xd2, 0x42, 0x88, 0x26, 0x30, 0xea, 0xff, 0x96, 0x87, 0x33, 0x71, + 0x91, 0xd7, 0xa8, 0x65, 0x9c, 0xc8, 0xfb, 0xc3, 0x91, 0xf7, 0x1f, 0x17, 0xe0, 0x29, 0x51, 0xa6, + 0xb6, 0xae, 0x3b, 0xd4, 0xa8, 0x98, 0x0e, 0x6d, 0x78, 0xb6, 0xb3, 0x79, 0x8c, 0x0d, 0xa8, 0xc3, + 0x13, 0xfb, 0x2d, 0x28, 0x89, 0xed, 0x3f, 0x5f, 0x67, 0xc6, 0x82, 0x96, 0x20, 0x34, 0xb1, 0x42, + 0xf1, 0xa3, 0x83, 0x58, 0x67, 0x95, 0x76, 0xd3, 0x59, 0x9f, 0x85, 0xd1, 0x40, 0xf4, 0xb8, 0x11, + 0x1d, 0x08, 0xad, 0x2d, 0xc3, 0x47, 0xe0, 0x5e, 0x54, 0x8b, 0x12, 0x62, 0x6d, 0x3e, 0xa0, 0x5a, + 0x41, 0x6b, 0x68, 0x54, 0xd4, 0x16, 0x94, 0x33, 0x0d, 0x4d, 0x26, 0x52, 0xb7, 0x8a, 0x70, 0x31, + 0xbd, 0xdb, 0x35, 0xaa, 0x1b, 0x27, 0xbd, 0xfe, 0xb1, 0xec, 0x75, 0xf2, 0x2c, 0x14, 0x97, 0x75, + 0x6f, 0x5d, 0x5c, 0xbf, 0xe3, 0x9d, 0xf0, 0x9a, 0xd9, 0xa2, 0xf5, 0x8e, 0xee, 0xad, 0x6b, 0x88, + 0x92, 0xe6, 0x0c, 0x40, 0x8e, 0x29, 0x73, 0x86, 0xb4, 0xd8, 0x0f, 0x3f, 0x93, 0xbb, 0x5a, 0x4c, + 0x5d, 0xec, 0xbf, 0x5b, 0xcc, 0x9a, 0x57, 0x1e, 0x38, 0xa6, 0x47, 0x4f, 0x34, 0xec, 0x44, 0xc3, + 0x0e, 0xa8, 0x61, 0xff, 0x38, 0x0f, 0xa3, 0xc1, 0xa6, 0xe9, 0x7d, 0xda, 0x38, 0x9a, 0xb5, 0x2a, + 0xdc, 0xca, 0x14, 0x0e, 0xbc, 0x95, 0x39, 0x88, 0x42, 0xa9, 0xc1, 0x91, 0x27, 0x37, 0x0d, 0x50, + 0x62, 0xfc, 0xc8, 0x33, 0x38, 0xe8, 0x7c, 0x16, 0x06, 0x16, 0xf4, 0xc7, 0x66, 0xbb, 0xdb, 0x16, + 0x56, 0x3a, 0xba, 0x93, 0xb5, 0xf5, 0xc7, 0x9a, 0x0f, 0x57, 0xff, 0xdb, 0x1c, 0x8c, 0x09, 0xa1, + 0x0a, 0xe6, 0x07, 0x92, 0x6a, 0x28, 0x9d, 0xfc, 0x81, 0xa5, 0x53, 0xd8, 0xbf, 0x74, 0xd4, 0xbf, + 0x54, 0x00, 0x65, 0xd6, 0x6c, 0xd1, 0x15, 0x47, 0xb7, 0xdc, 0x35, 0xea, 0x88, 0xed, 0xf4, 0x0c, + 0x63, 0x75, 0xa0, 0x0f, 0x94, 0xa6, 0x94, 0xfc, 0xbe, 0xa6, 0x94, 0x4f, 0xc3, 0x90, 0x68, 0x4c, + 0xe0, 0xca, 0x88, 0xa3, 0xc6, 0xf1, 0x81, 0x5a, 0x88, 0x67, 0xc4, 0xe5, 0x4e, 0xc7, 0xb1, 0x1f, + 0x51, 0x87, 0xdf, 0x52, 0x09, 0x62, 0xdd, 0x07, 0x6a, 0x21, 0x5e, 0xe2, 0x4c, 0x7d, 0x7b, 0x51, + 0xe6, 0x4c, 0x1d, 0x2d, 0xc4, 0x93, 0xab, 0x30, 0x38, 0x6f, 0x37, 0x74, 0x14, 0x34, 0x9f, 0x56, + 0x46, 0xb6, 0xb7, 0x26, 0x07, 0x5b, 0x02, 0xa6, 0x05, 0x58, 0x46, 0x59, 0xb1, 0x37, 0xac, 0x96, + 0xad, 0x73, 0xe7, 0x97, 0x41, 0x4e, 0x69, 0x08, 0x98, 0x16, 0x60, 0x19, 0x25, 0x93, 0x39, 0x3a, + 0x15, 0x0d, 0x86, 0x3c, 0xd7, 0x04, 0x4c, 0x0b, 0xb0, 0xea, 0xaf, 0x14, 0x99, 0xf6, 0xba, 0xe6, + 0x07, 0x4f, 0xfc, 0xba, 0x10, 0x0e, 0x98, 0xfe, 0x7d, 0x0c, 0x98, 0x27, 0xe6, 0xc0, 0x4e, 0xfd, + 0x97, 0x03, 0x00, 0x42, 0xfa, 0x33, 0x27, 0x9b, 0xc3, 0x83, 0x69, 0x4d, 0x05, 0x26, 0x66, 0xac, + 0x75, 0xdd, 0x6a, 0x50, 0x23, 0x3c, 0xb6, 0x2c, 0xe1, 0xd0, 0x46, 0x27, 0x48, 0x2a, 0x90, 0xe1, + 0xb9, 0xa5, 0x96, 0x2c, 0x40, 0x5e, 0x82, 0xe1, 0xaa, 0xe5, 0x51, 0x47, 0x6f, 0x78, 0xe6, 0x23, + 0x2a, 0xa6, 0x06, 0xbc, 0x19, 0x36, 0x43, 0xb0, 0x26, 0xd3, 0x90, 0x5b, 0x30, 0xb2, 0xac, 0x3b, + 0x9e, 0xd9, 0x30, 0x3b, 0xba, 0xe5, 0xb9, 0xca, 0x20, 0xce, 0x68, 0x68, 0x61, 0x74, 0x24, 0xb8, + 0x16, 0xa1, 0x22, 0x5f, 0x82, 0x21, 0xdc, 0x9a, 0xa2, 0xbf, 0xf6, 0xd0, 0x8e, 0x17, 0x87, 0xcf, + 0x85, 0xee, 0x81, 0xfc, 0xf4, 0x15, 0x6f, 0x80, 0xe3, 0x77, 0x87, 0x01, 0x47, 0xf2, 0x05, 0x18, + 0x98, 0xb1, 0x0c, 0x64, 0x0e, 0x3b, 0x32, 0x57, 0x05, 0xf3, 0x73, 0x21, 0x73, 0xbb, 0x13, 0xe3, + 0xed, 0xb3, 0x4b, 0x1f, 0x65, 0xc3, 0x1f, 0xde, 0x28, 0x1b, 0xf9, 0x10, 0x8e, 0xc5, 0x47, 0x0f, + 0xeb, 0x58, 0x7c, 0x6c, 0x9f, 0xc7, 0xe2, 0xea, 0x07, 0x30, 0x3c, 0xb5, 0x3c, 0x1b, 0x8c, 0xde, + 0x0b, 0x50, 0x58, 0x16, 0x9e, 0x0a, 0x45, 0x6e, 0xcf, 0x74, 0x4c, 0x43, 0x63, 0x30, 0x72, 0x0d, + 0x06, 0xa7, 0xd1, 0xfd, 0x4d, 0xdc, 0x22, 0x16, 0xf9, 0xfa, 0xd7, 0x40, 0x18, 0x7a, 0xc1, 0xfa, + 0x68, 0xf2, 0x49, 0x18, 0x58, 0x76, 0xec, 0xa6, 0xa3, 0xb7, 0xc5, 0x1a, 0x8c, 0xae, 0x22, 0x1d, + 0x0e, 0xd2, 0x7c, 0x9c, 0xfa, 0x53, 0x39, 0xdf, 0x6c, 0x67, 0x25, 0x6a, 0x5d, 0x3c, 0x9a, 0xc7, + 0xba, 0x07, 0x79, 0x09, 0x97, 0x83, 0x34, 0x1f, 0x47, 0xae, 0x41, 0xff, 0x8c, 0xe3, 0xd8, 0x8e, + 0xec, 0xe3, 0x4e, 0x19, 0x40, 0xbe, 0xee, 0x45, 0x0a, 0xf2, 0x1a, 0x0c, 0xf3, 0x39, 0x87, 0x9f, + 0x68, 0x16, 0x7a, 0xdd, 0x94, 0xca, 0x94, 0xea, 0xb7, 0x0b, 0x92, 0xcd, 0xc6, 0x25, 0xfe, 0x04, + 0xde, 0x0a, 0xbc, 0x0c, 0x85, 0xa9, 0xe5, 0x59, 0x31, 0x01, 0x9e, 0xf6, 0x8b, 0x4a, 0xaa, 0x12, + 0x2b, 0xc7, 0xa8, 0xc9, 0x25, 0x28, 0x2e, 0x33, 0xf5, 0x29, 0xa1, 0x7a, 0x0c, 0x6e, 0x6f, 0x4d, + 0x16, 0x3b, 0x4c, 0x7f, 0x10, 0x8a, 0x58, 0xb6, 0x99, 0xe1, 0x3b, 0x26, 0x8e, 0x0d, 0xf7, 0x31, + 0x97, 0xa0, 0x58, 0x76, 0x9a, 0x8f, 0xc4, 0xac, 0x85, 0x58, 0xdd, 0x69, 0x3e, 0xd2, 0x10, 0x4a, + 0x6e, 0x00, 0x68, 0xd4, 0xeb, 0x3a, 0x16, 0x3e, 0x3f, 0x19, 0xc2, 0xf3, 0x37, 0x9c, 0x0d, 0x1d, + 0x84, 0xd6, 0x1b, 0xb6, 0x41, 0x35, 0x89, 0x44, 0xfd, 0xeb, 0xe1, 0xc5, 0x4e, 0xc5, 0x74, 0x1f, + 0x9e, 0x74, 0xe1, 0x1e, 0xba, 0x50, 0x17, 0x47, 0x9c, 0xc9, 0x4e, 0x9a, 0x84, 0xfe, 0xd9, 0x96, + 0xde, 0x74, 0xb1, 0x0f, 0x85, 0x2f, 0xd9, 0x1a, 0x03, 0x68, 0x1c, 0x1e, 0xeb, 0xa7, 0xc1, 0x9d, + 0xfb, 0xe9, 0x67, 0xfa, 0x83, 0xd1, 0xb6, 0x48, 0xbd, 0x0d, 0xdb, 0x39, 0xe9, 0xaa, 0xdd, 0x76, + 0xd5, 0x15, 0x18, 0xa8, 0x39, 0x0d, 0xe9, 0xe8, 0x02, 0xf7, 0x03, 0xae, 0xd3, 0xe0, 0xc7, 0x16, + 0x3e, 0x92, 0xd1, 0x55, 0x5c, 0x0f, 0xe9, 0x06, 0x42, 0x3a, 0xc3, 0xf5, 0x04, 0x9d, 0x40, 0x0a, + 0xba, 0x65, 0xdb, 0xf1, 0x44, 0xc7, 0x05, 0x74, 0x1d, 0xdb, 0xf1, 0x34, 0x1f, 0x49, 0x3e, 0x0d, + 0xb0, 0x32, 0xbd, 0xec, 0x3b, 0xdb, 0x0f, 0x85, 0xbe, 0x80, 0xc2, 0xcb, 0x5e, 0x93, 0xd0, 0x64, + 0x05, 0x86, 0x96, 0x3a, 0xd4, 0xe1, 0x5b, 0x21, 0xfe, 0xa0, 0xe4, 0x53, 0x31, 0xd1, 0x8a, 0x7e, + 0xbf, 0x2e, 0xfe, 0x0f, 0xc8, 0xf9, 0xfa, 0x62, 0xfb, 0x3f, 0xb5, 0x90, 0x11, 0x79, 0x0d, 0x4a, + 0x65, 0x6e, 0xe7, 0x0d, 0x23, 0xcb, 0x40, 0x64, 0xb8, 0x05, 0xe5, 0x28, 0xbe, 0x67, 0xd7, 0xf1, + 0x6f, 0x4d, 0x90, 0xab, 0xd7, 0x60, 0x3c, 0x5e, 0x0d, 0x19, 0x86, 0x81, 0xe9, 0xa5, 0xc5, 0xc5, + 0x99, 0xe9, 0x95, 0xf1, 0x3e, 0x32, 0x08, 0xc5, 0xda, 0xcc, 0x62, 0x65, 0x3c, 0xa7, 0xfe, 0x92, + 0x34, 0x83, 0x30, 0xd5, 0x3a, 0xb9, 0x1a, 0x3e, 0xd0, 0x7d, 0xcb, 0x38, 0xde, 0x87, 0xe2, 0x89, + 0x41, 0xdb, 0xf4, 0x3c, 0x6a, 0x88, 0x55, 0x02, 0xef, 0x0b, 0xbd, 0xc7, 0x5a, 0x02, 0x4f, 0x5e, + 0x80, 0x51, 0x84, 0x89, 0x2b, 0x42, 0xbe, 0x3f, 0x16, 0x05, 0x9c, 0xc7, 0x5a, 0x14, 0xa9, 0xfe, + 0x6e, 0x78, 0x3b, 0x3c, 0x4f, 0xf5, 0xe3, 0x7a, 0xa3, 0xf8, 0x11, 0xe9, 0x2f, 0xf5, 0x5f, 0x17, + 0xf9, 0x13, 0x10, 0xfe, 0x5e, 0xf0, 0x28, 0x44, 0x19, 0x1e, 0xe9, 0x16, 0xf6, 0x70, 0xa4, 0xfb, + 0x02, 0x94, 0x16, 0xa8, 0xb7, 0x6e, 0xfb, 0x8e, 0x5f, 0xe8, 0xa1, 0xd7, 0x46, 0x88, 0xec, 0xa1, + 0xc7, 0x69, 0xc8, 0x43, 0x20, 0xfe, 0x63, 0xc0, 0xc0, 0x11, 0xdb, 0x3f, 0x42, 0x3e, 0x9f, 0xd8, + 0xa7, 0xd4, 0xf0, 0x25, 0x30, 0xfa, 0xd8, 0x9f, 0x09, 0x1c, 0xbd, 0x25, 0x4f, 0xac, 0x7f, 0xb5, + 0x35, 0x59, 0xe2, 0x34, 0x5a, 0x0a, 0x5b, 0xf2, 0x2e, 0x0c, 0x2d, 0xcc, 0x96, 0xc5, 0xc3, 0x40, + 0xee, 0x15, 0x71, 0x21, 0x90, 0xa2, 0x8f, 0x08, 0x44, 0x82, 0xef, 0x6d, 0xda, 0x6b, 0x7a, 0xf2, + 0x5d, 0x60, 0xc8, 0x85, 0x69, 0x0b, 0x7f, 0xb9, 0x23, 0x4e, 0x17, 0x02, 0x6d, 0x89, 0xbe, 0xe7, + 0x89, 0xcb, 0x8a, 0x63, 0x63, 0xda, 0x32, 0x78, 0x80, 0xd1, 0xbd, 0x04, 0x13, 0xe5, 0x4e, 0xa7, + 0x65, 0x52, 0x03, 0xf5, 0x45, 0xeb, 0xb6, 0xa8, 0x2b, 0x5c, 0x7e, 0xf0, 0x31, 0x88, 0xce, 0x91, + 0x75, 0x7c, 0x8e, 0x5a, 0x77, 0xba, 0x51, 0xff, 0xcc, 0x64, 0x59, 0xf5, 0xcf, 0xe5, 0xe1, 0xdc, + 0xb4, 0x43, 0x75, 0x8f, 0x2e, 0xcc, 0x96, 0xcb, 0x5d, 0xf4, 0x91, 0x6b, 0xb5, 0xa8, 0xd5, 0x3c, + 0x9a, 0x61, 0xfd, 0x26, 0x8c, 0x05, 0x0d, 0xa8, 0x35, 0xec, 0x0e, 0x95, 0x1f, 0x56, 0x35, 0x7c, + 0x4c, 0xdd, 0x65, 0x28, 0x2d, 0x46, 0x4a, 0xee, 0xc2, 0xe9, 0x00, 0x52, 0x6e, 0xb5, 0xec, 0x0d, + 0x8d, 0x76, 0x5d, 0xee, 0x18, 0x3b, 0xc8, 0x1d, 0x63, 0x43, 0x0e, 0x3a, 0xc3, 0xd7, 0x1d, 0x46, + 0xa0, 0xa5, 0x95, 0x52, 0x7f, 0xae, 0x00, 0xe7, 0xef, 0xeb, 0x2d, 0xd3, 0x08, 0x45, 0xa3, 0x51, + 0xb7, 0x63, 0x5b, 0x2e, 0x3d, 0x46, 0xa3, 0x34, 0x32, 0x14, 0x8a, 0x87, 0x32, 0x14, 0x92, 0x5d, + 0xd4, 0x7f, 0xe0, 0x2e, 0x2a, 0xed, 0xab, 0x8b, 0xfe, 0xd7, 0x1c, 0x8c, 0xfb, 0x8e, 0xff, 0xf2, + 0x23, 0x6e, 0xc9, 0x2b, 0x1d, 0x8f, 0x10, 0x63, 0x7e, 0xd0, 0x88, 0x27, 0x35, 0x18, 0x98, 0x79, + 0xdc, 0x31, 0x1d, 0xea, 0xee, 0xc2, 0x89, 0xfb, 0x69, 0x71, 0x5c, 0x32, 0x41, 0x79, 0x91, 0xc4, + 0x49, 0x09, 0x07, 0xe3, 0x73, 0x3e, 0xfe, 0xf4, 0x61, 0xca, 0x7f, 0x99, 0xce, 0x9f, 0xf3, 0x89, + 0x27, 0x12, 0x91, 0xf7, 0x99, 0x21, 0x29, 0x79, 0x0e, 0x0a, 0x2b, 0x2b, 0xf3, 0x62, 0x26, 0xc5, + 0x88, 0x00, 0x9e, 0x27, 0xbf, 0x57, 0x64, 0x58, 0xf5, 0x9f, 0xe5, 0x01, 0x98, 0x2a, 0xf0, 0xe1, + 0x7a, 0x24, 0x4a, 0x38, 0x05, 0x83, 0xbe, 0xc0, 0x85, 0x1a, 0x06, 0x5e, 0xfb, 0xf1, 0x8e, 0x88, + 0xd7, 0x1d, 0xbc, 0xd0, 0x98, 0xf4, 0x1d, 0xc9, 0xf9, 0x3d, 0x00, 0xee, 0x6c, 0xd0, 0x91, 0xdc, + 0x77, 0x1f, 0xff, 0x34, 0x0c, 0x89, 0x19, 0xcf, 0x8e, 0x9c, 0xff, 0x37, 0x7c, 0xa0, 0x16, 0xe2, + 0x63, 0x53, 0x6b, 0xe9, 0x00, 0x0b, 0xb1, 0x2f, 0x5e, 0xde, 0x2b, 0x27, 0xe2, 0x3d, 0x64, 0xf1, + 0x7e, 0x4d, 0x88, 0x97, 0xbf, 0xe0, 0x39, 0xb6, 0xe2, 0x3d, 0xb4, 0xb3, 0x6f, 0xf5, 0x1f, 0xe7, + 0x80, 0xb0, 0x66, 0x2d, 0xeb, 0xae, 0xbb, 0x61, 0x3b, 0x06, 0x77, 0x4e, 0x3f, 0x12, 0xc1, 0x1c, + 0xde, 0x7d, 0xe5, 0xb7, 0x07, 0xe1, 0x74, 0xc4, 0xf1, 0xf7, 0x98, 0x4f, 0x56, 0xd7, 0xa2, 0xa3, + 0xa9, 0xd7, 0xab, 0x97, 0x4f, 0xc8, 0x17, 0xa2, 0xfd, 0x91, 0x07, 0x68, 0xd2, 0x4d, 0xe8, 0x8b, + 0x30, 0x22, 0x7e, 0xb0, 0x15, 0xda, 0xbf, 0xe9, 0xc2, 0x51, 0xea, 0x32, 0x80, 0x16, 0x41, 0x93, + 0x57, 0x60, 0x88, 0x0d, 0x98, 0x26, 0x06, 0x0f, 0x19, 0x08, 0x5f, 0x94, 0x18, 0x3e, 0x50, 0x5e, + 0x4f, 0x02, 0x4a, 0xe9, 0x1d, 0xd1, 0xe0, 0x2e, 0xde, 0x11, 0x7d, 0x19, 0x86, 0xcb, 0x96, 0x65, + 0x7b, 0xb8, 0x49, 0x77, 0xc5, 0xd5, 0x44, 0xa6, 0x55, 0xfe, 0x1c, 0x3e, 0x8e, 0x0f, 0xe9, 0x53, + 0xcd, 0x72, 0x99, 0x21, 0xb9, 0xe9, 0xbf, 0x8a, 0xa1, 0x8e, 0xf0, 0x2a, 0xc7, 0xeb, 0x19, 0x47, + 0xc0, 0x92, 0x8f, 0x62, 0xb0, 0xf3, 0x46, 0x97, 0x1d, 0xbb, 0x63, 0xbb, 0xd4, 0xe0, 0x82, 0x1a, + 0x0e, 0x43, 0x0d, 0x74, 0x04, 0x02, 0xdf, 0xb1, 0x45, 0x02, 0x79, 0x44, 0x8a, 0x90, 0x35, 0x38, + 0xe3, 0x5f, 0x14, 0x07, 0x2f, 0x06, 0xab, 0x15, 0x57, 0x19, 0xc1, 0x57, 0x49, 0x24, 0xae, 0x0c, + 0xd5, 0xca, 0xd4, 0x65, 0xff, 0x5a, 0xc4, 0x7f, 0x72, 0x58, 0x37, 0x0d, 0xb9, 0xab, 0x53, 0xf9, + 0x91, 0x1f, 0x80, 0xe1, 0x05, 0xfd, 0x71, 0xa5, 0x2b, 0xce, 0x5e, 0x46, 0x77, 0x7f, 0xfb, 0xd2, + 0xd6, 0x1f, 0xd7, 0x0d, 0x51, 0x2e, 0x66, 0x53, 0xc8, 0x2c, 0x49, 0x1d, 0xce, 0x2d, 0x3b, 0x76, + 0xdb, 0xf6, 0xa8, 0x11, 0x7b, 0x7c, 0x77, 0x2a, 0x7c, 0xad, 0xdb, 0x11, 0x14, 0xf5, 0x1e, 0xaf, + 0xf0, 0x32, 0xd8, 0x90, 0x36, 0x9c, 0x2a, 0xbb, 0x6e, 0xb7, 0x4d, 0xc3, 0x1b, 0xaa, 0xf1, 0x1d, + 0x3f, 0xe3, 0x53, 0xc2, 0x6b, 0xf9, 0x29, 0x1d, 0x8b, 0xf2, 0x0b, 0xaa, 0xba, 0x67, 0xca, 0x35, + 0xe2, 0xb7, 0xc4, 0x79, 0xdf, 0x29, 0x0e, 0x8e, 0x8d, 0x9f, 0xd2, 0xce, 0x27, 0x1b, 0xb3, 0x62, + 0x7a, 0x2d, 0xaa, 0x7e, 0x2b, 0x07, 0x10, 0x0a, 0x98, 0xbc, 0x18, 0x8d, 0x50, 0x94, 0x0b, 0x2f, + 0x3a, 0x44, 0xf4, 0x82, 0x48, 0x48, 0x22, 0x72, 0x09, 0x8a, 0x18, 0xe1, 0x22, 0x1f, 0x1e, 0xac, + 0x3e, 0x34, 0x2d, 0x43, 0x43, 0x28, 0xc3, 0x4a, 0x4f, 0xd1, 0x11, 0x8b, 0x97, 0xfa, 0xdc, 0x2a, + 0xac, 0xc0, 0xa9, 0x5a, 0x77, 0xd5, 0xaf, 0x5b, 0x7a, 0x57, 0x87, 0x81, 0x36, 0xdc, 0xee, 0x6a, + 0xf0, 0x18, 0x35, 0x12, 0xc6, 0x24, 0x5a, 0x44, 0xfd, 0x95, 0x5c, 0x6c, 0x16, 0x3c, 0xc2, 0x45, + 0xef, 0x13, 0x49, 0x3f, 0x8d, 0xe4, 0xb4, 0xa4, 0xfe, 0xe5, 0x3c, 0x0c, 0x2f, 0xdb, 0x8e, 0x27, + 0x42, 0x86, 0x1c, 0xef, 0x55, 0x48, 0xda, 0x2b, 0x15, 0xf7, 0xb0, 0x57, 0xba, 0x04, 0x45, 0xc9, + 0x45, 0x99, 0xdf, 0x8b, 0x18, 0x86, 0xa3, 0x21, 0x54, 0xfd, 0xa1, 0x3c, 0xc0, 0x17, 0x5e, 0x7a, + 0xe9, 0x09, 0x16, 0x90, 0xfa, 0x17, 0x73, 0x70, 0x4a, 0x5c, 0xd4, 0x49, 0xb1, 0xbe, 0x06, 0xfc, + 0x2b, 0x56, 0x79, 0x5c, 0x72, 0x90, 0xe6, 0xe3, 0xd8, 0x12, 0x30, 0xf3, 0xd8, 0xf4, 0xf0, 0xae, + 0x42, 0x0a, 0xf6, 0x45, 0x05, 0x4c, 0x5e, 0x02, 0x7c, 0x3a, 0xf2, 0xa2, 0x7f, 0x05, 0x59, 0x08, + 0xd7, 0x3d, 0x56, 0x60, 0x26, 0xf5, 0x1a, 0x52, 0xfd, 0xf5, 0x22, 0x14, 0x67, 0x1e, 0xd3, 0xc6, + 0x31, 0xef, 0x1a, 0xe9, 0x60, 0xb3, 0x78, 0xc0, 0x83, 0xcd, 0xfd, 0xf8, 0x54, 0xbc, 0x13, 0xf6, + 0x67, 0x29, 0x5a, 0x7d, 0xac, 0xe7, 0xe3, 0xd5, 0xfb, 0x3d, 0x7d, 0xfc, 0x5c, 0x72, 0xfe, 0x8b, + 0x02, 0x14, 0x6a, 0xd3, 0xcb, 0x27, 0x7a, 0x73, 0xa4, 0x7a, 0xd3, 0xfb, 0xce, 0x5a, 0x0d, 0xae, + 0xa1, 0x06, 0x43, 0x2f, 0xd1, 0xd8, 0x8d, 0xd3, 0x1f, 0x17, 0x60, 0xac, 0x36, 0xbb, 0xb2, 0x2c, + 0x9d, 0x04, 0xdf, 0xe5, 0x9e, 0x7c, 0xe8, 0x53, 0xc6, 0xbb, 0xf4, 0x52, 0xc2, 0x9e, 0xb9, 0x57, + 0xb5, 0xbc, 0x57, 0x6f, 0xdd, 0xd7, 0x5b, 0x5d, 0x8a, 0x47, 0x2f, 0xdc, 0xef, 0xd7, 0x35, 0x3f, + 0xa0, 0x3f, 0x87, 0x0f, 0xff, 0x7d, 0x06, 0xe4, 0x4d, 0x28, 0xdc, 0x13, 0x1e, 0x19, 0x59, 0x7c, + 0x5e, 0xbe, 0xc9, 0xf9, 0xb0, 0x49, 0xb0, 0xd0, 0x35, 0x0d, 0xe4, 0xc0, 0x4a, 0xb1, 0xc2, 0xb7, + 0xc5, 0x02, 0xbc, 0xab, 0xc2, 0x4d, 0xbf, 0xf0, 0xed, 0x6a, 0x85, 0xd4, 0x60, 0x78, 0x99, 0x3a, + 0x6d, 0x13, 0x3b, 0xca, 0x9f, 0xb3, 0x7b, 0x33, 0x61, 0x3b, 0x95, 0xe1, 0x4e, 0x58, 0x08, 0x99, + 0xc9, 0x5c, 0xc8, 0x7b, 0x00, 0xdc, 0x46, 0xd9, 0x65, 0xfc, 0xc8, 0xa7, 0xd1, 0xee, 0xe7, 0xa6, + 0x65, 0x8a, 0x8d, 0x27, 0x31, 0x23, 0x0f, 0x61, 0x7c, 0xc1, 0x36, 0xcc, 0x35, 0x93, 0xbb, 0x5e, + 0x62, 0x05, 0xa5, 0x9d, 0x1d, 0x9e, 0x98, 0x29, 0xd9, 0x96, 0xca, 0xa5, 0x55, 0x93, 0x60, 0xac, + 0xfe, 0xbd, 0x7e, 0x28, 0xb2, 0x6e, 0x3f, 0x19, 0xbf, 0x07, 0x19, 0xbf, 0x65, 0x18, 0x7f, 0x60, + 0x3b, 0x0f, 0x4d, 0xab, 0x19, 0x78, 0xc5, 0x8b, 0xbd, 0x29, 0x7a, 0xf2, 0x6c, 0x70, 0x5c, 0x3d, + 0x70, 0xa0, 0xd7, 0x12, 0xe4, 0x3b, 0x8c, 0xe0, 0xd7, 0x01, 0xf8, 0x5b, 0x77, 0xa4, 0x19, 0x0c, + 0x83, 0x55, 0xf0, 0x97, 0xf0, 0xe8, 0x68, 0x2f, 0x07, 0xab, 0x08, 0x89, 0xd9, 0x26, 0x9c, 0xfb, + 0x42, 0x0c, 0xa1, 0xdf, 0x3d, 0x6e, 0xc2, 0xd1, 0x17, 0x42, 0x36, 0x02, 0xb8, 0x57, 0xc4, 0x32, + 0x80, 0x74, 0xbf, 0x04, 0x31, 0x41, 0x44, 0x26, 0x07, 0x11, 0x1e, 0x2e, 0xe5, 0x7a, 0x49, 0x93, + 0x78, 0x90, 0x57, 0x63, 0x17, 0xe0, 0x24, 0xc2, 0x2d, 0xf3, 0xfe, 0x3b, 0x74, 0xa0, 0x1a, 0xd9, + 0xc9, 0x81, 0x4a, 0xfd, 0x9b, 0x05, 0x18, 0x66, 0xdc, 0x6a, 0xdd, 0x76, 0x5b, 0x77, 0x36, 0x4f, + 0x14, 0xf9, 0x20, 0x8a, 0x5c, 0x87, 0x09, 0xd9, 0x61, 0x9e, 0x99, 0xae, 0x7e, 0xa8, 0xa1, 0xe0, + 0xf8, 0x27, 0x4e, 0xc0, 0x6d, 0x4b, 0x9c, 0xf7, 0x3d, 0x01, 0xc6, 0xb3, 0x05, 0x57, 0x4b, 0xf2, + 0x52, 0x7f, 0x3a, 0x07, 0xe3, 0x71, 0x68, 0xa0, 0xfb, 0xb9, 0x54, 0xdd, 0x7f, 0x01, 0x86, 0xc4, + 0x15, 0xba, 0x6e, 0x08, 0x8f, 0xbe, 0xb1, 0xed, 0xad, 0x49, 0xc0, 0xf7, 0xcb, 0x75, 0x87, 0xea, + 0x86, 0x16, 0x12, 0x90, 0x57, 0x60, 0x04, 0x7f, 0x3c, 0x70, 0x4c, 0xcf, 0xa3, 0xbc, 0x33, 0x8a, + 0xfc, 0x56, 0x80, 0x17, 0xd8, 0xe0, 0x08, 0x2d, 0x42, 0xa6, 0x7e, 0x35, 0x0f, 0x43, 0xb5, 0xee, + 0xaa, 0xbb, 0xe9, 0x7a, 0xb4, 0x7d, 0xcc, 0x75, 0xc8, 0xdf, 0xa4, 0x17, 0x53, 0x37, 0xe9, 0xcf, + 0xf9, 0x43, 0x4b, 0x3a, 0xbd, 0x0e, 0x36, 0x06, 0xfe, 0xa0, 0xfa, 0x3b, 0x79, 0x18, 0xe7, 0xd7, + 0xaf, 0x15, 0xd3, 0x6d, 0x1c, 0xc2, 0x93, 0x90, 0xa3, 0x97, 0xca, 0xc1, 0x5c, 0x16, 0x76, 0xf1, + 0xd0, 0x46, 0xfd, 0x4a, 0x1e, 0x86, 0xcb, 0x5d, 0x6f, 0xbd, 0xec, 0xe1, 0x0c, 0xf5, 0x44, 0xee, + 0x72, 0xff, 0x61, 0x0e, 0x4e, 0xb1, 0x86, 0xac, 0xd8, 0x0f, 0xa9, 0x75, 0x08, 0xc7, 0xd7, 0xf2, + 0x31, 0x74, 0x7e, 0x9f, 0xc7, 0xd0, 0xbe, 0x2c, 0x0b, 0x7b, 0x93, 0x25, 0x5e, 0xba, 0x68, 0x76, + 0x8b, 0x1e, 0xef, 0xcf, 0x38, 0xc4, 0x4b, 0x17, 0x5f, 0x20, 0x87, 0x70, 0xc9, 0xf7, 0xf1, 0x12, + 0xc8, 0x21, 0x9c, 0x50, 0x7e, 0x3c, 0x04, 0xf2, 0xed, 0x1c, 0x0c, 0x4d, 0xd9, 0xde, 0x31, 0x1f, + 0xf8, 0xe2, 0x2b, 0x8e, 0xb7, 0x9a, 0xfb, 0x5f, 0x71, 0xbc, 0x75, 0x53, 0xfd, 0xd9, 0x3c, 0x9c, + 0x11, 0x11, 0xe6, 0xc5, 0x29, 0xd6, 0xc9, 0x74, 0x2c, 0x06, 0x5b, 0x52, 0x34, 0x27, 0xf3, 0x90, + 0x10, 0xcd, 0x2f, 0x14, 0xe0, 0x0c, 0x06, 0xc4, 0x65, 0x7b, 0xa2, 0x8f, 0x81, 0x2d, 0x42, 0x1a, + 0xd1, 0xab, 0xf4, 0x85, 0x94, 0xab, 0xf4, 0x7f, 0xb5, 0x35, 0xf9, 0x6a, 0xd3, 0xf4, 0xd6, 0xbb, + 0xab, 0xd7, 0x1b, 0x76, 0xfb, 0x46, 0xd3, 0xd1, 0x1f, 0x99, 0xfc, 0x12, 0x59, 0x6f, 0xdd, 0x08, + 0x92, 0xb5, 0xe8, 0x1d, 0x53, 0xa4, 0x71, 0xa9, 0xe1, 0x5e, 0x87, 0x71, 0xf5, 0x2f, 0xe1, 0x5d, + 0x80, 0x3b, 0xb6, 0x69, 0x09, 0xcf, 0x54, 0x6e, 0xe8, 0xd6, 0xb6, 0xb7, 0x26, 0xcf, 0xbe, 0x6f, + 0x9b, 0x56, 0x3d, 0xee, 0x9e, 0xba, 0xd7, 0xfa, 0x42, 0xd6, 0x9a, 0x54, 0x8d, 0xfa, 0xdf, 0xe4, + 0xe0, 0x42, 0x54, 0x8b, 0x3f, 0x0e, 0xb6, 0xe3, 0x9f, 0xcf, 0xc3, 0xd9, 0xdb, 0x28, 0x9c, 0xc0, + 0x1d, 0xe8, 0x64, 0xde, 0x12, 0x83, 0x33, 0x45, 0x36, 0x27, 0x16, 0x65, 0xb6, 0x6c, 0x4e, 0x26, + 0x75, 0x21, 0x9b, 0xff, 0x3a, 0x07, 0xa7, 0x97, 0xaa, 0x95, 0xe9, 0x8f, 0xc9, 0x88, 0x4a, 0x7e, + 0xcf, 0x31, 0x37, 0x38, 0x13, 0xdf, 0x73, 0xcc, 0x4d, 0xcf, 0x6f, 0xe4, 0xe1, 0x74, 0xad, 0xbc, + 0x30, 0xff, 0x71, 0x99, 0xc1, 0xa7, 0x65, 0xdf, 0x55, 0xff, 0x10, 0x4c, 0xd8, 0x02, 0xf2, 0x67, + 0xde, 0xbf, 0x99, 0xed, 0xd3, 0x9a, 0x14, 0xca, 0x31, 0x9f, 0xba, 0x0f, 0x45, 0x28, 0x4c, 0xf3, + 0x23, 0xd4, 0xc7, 0x5c, 0xf3, 0xff, 0xf3, 0x12, 0x0c, 0xdf, 0xed, 0xae, 0x52, 0xe1, 0xe2, 0xf4, + 0x44, 0x9f, 0xfc, 0xde, 0x84, 0x61, 0x21, 0x06, 0xbc, 0xa3, 0x90, 0x42, 0x30, 0x8a, 0x90, 0x3a, + 0x3c, 0xca, 0x95, 0x4c, 0x44, 0x2e, 0x41, 0xf1, 0x3e, 0x75, 0x56, 0xe5, 0xd7, 0xc9, 0x8f, 0xa8, + 0xb3, 0xaa, 0x21, 0x94, 0xcc, 0x87, 0x0f, 0x2f, 0xca, 0xcb, 0x55, 0x4c, 0xc7, 0x23, 0xae, 0xfd, + 0x30, 0xbf, 0x50, 0xe0, 0x3d, 0xa9, 0x77, 0x4c, 0x9e, 0xc8, 0x47, 0x8e, 0x8c, 0x10, 0x2f, 0x49, + 0x16, 0x61, 0x42, 0x76, 0x9f, 0xe3, 0xb9, 0x68, 0x06, 0x53, 0xd8, 0xa5, 0x65, 0xa1, 0x49, 0x16, + 0x25, 0xef, 0xc0, 0x88, 0x0f, 0x44, 0x47, 0xc0, 0xa1, 0x30, 0x01, 0x42, 0xc0, 0x2a, 0x96, 0xe8, + 0x2a, 0x52, 0x40, 0x66, 0x80, 0xd7, 0x10, 0x90, 0xc2, 0x20, 0xe6, 0x58, 0x19, 0x29, 0x40, 0x5e, + 0x41, 0x06, 0xf8, 0x58, 0x08, 0x5d, 0x9e, 0x86, 0xf1, 0xe9, 0x2e, 0x5e, 0xe1, 0x38, 0x02, 0xce, + 0x1f, 0x68, 0x47, 0xc8, 0xc8, 0x12, 0x40, 0xe8, 0x9a, 0x22, 0xc2, 0x60, 0xec, 0xd9, 0x69, 0x46, + 0x62, 0x21, 0xdf, 0xc5, 0x8d, 0xee, 0xe7, 0x2e, 0x4e, 0xfd, 0x83, 0x3c, 0x0c, 0x97, 0x3b, 0x9d, + 0x60, 0x28, 0xbc, 0x08, 0xa5, 0x72, 0xa7, 0x73, 0x4f, 0xab, 0xca, 0x01, 0xf1, 0xf5, 0x4e, 0xa7, + 0xde, 0x75, 0x4c, 0xd9, 0xb3, 0x98, 0x13, 0x91, 0x69, 0x18, 0x2d, 0x77, 0x3a, 0xcb, 0xdd, 0xd5, + 0x96, 0xd9, 0x90, 0xf2, 0x6b, 0xf1, 0x0c, 0x84, 0x9d, 0x4e, 0xbd, 0x83, 0x98, 0x78, 0x92, 0xb5, + 0x68, 0x19, 0xf2, 0x65, 0x0c, 0x1e, 0x25, 0xd2, 0x3b, 0xf1, 0x04, 0x32, 0x6a, 0x10, 0x0a, 0x3f, + 0x6c, 0xdb, 0xf5, 0x80, 0x88, 0xa7, 0x0c, 0xb8, 0xe4, 0x27, 0x5e, 0x60, 0x15, 0x25, 0xd2, 0x38, + 0x85, 0x2c, 0xc9, 0x67, 0x60, 0xa0, 0xdc, 0xe9, 0x48, 0xf7, 0x4d, 0xe8, 0x9a, 0xc6, 0x4a, 0xc5, + 0x33, 0xe8, 0x09, 0xb2, 0x8b, 0x6f, 0xc1, 0x58, 0xb4, 0xb2, 0x3d, 0xa5, 0x1c, 0xf8, 0x5e, 0x0e, + 0x3f, 0xe8, 0x98, 0x7b, 0xc6, 0xbf, 0x0c, 0x85, 0x72, 0xa7, 0x23, 0xe6, 0xa3, 0xd3, 0x29, 0xfd, + 0x11, 0x7f, 0x48, 0x5f, 0xee, 0x74, 0xfc, 0x4f, 0x3f, 0xe6, 0x4f, 0x6c, 0xf6, 0xf5, 0xe9, 0xdf, + 0xe6, 0x9f, 0x7e, 0xbc, 0x9f, 0xbf, 0xa8, 0xbf, 0x5e, 0x80, 0x53, 0xe5, 0x4e, 0xe7, 0x24, 0x55, + 0xc1, 0x61, 0x3d, 0xd7, 0x7f, 0x09, 0x40, 0x9a, 0x1e, 0x07, 0x82, 0x07, 0x80, 0xc3, 0xd2, 0xd4, + 0xa8, 0xe4, 0x34, 0x89, 0xc8, 0x57, 0xbf, 0xc1, 0x3d, 0xa9, 0xdf, 0x57, 0x0a, 0x38, 0x15, 0x1f, + 0xf7, 0xd0, 0x63, 0x1f, 0x95, 0x6e, 0x13, 0x7d, 0x50, 0xda, 0x53, 0x1f, 0xfc, 0x83, 0xc8, 0xe0, + 0xc1, 0xd0, 0xf7, 0x27, 0xbd, 0xd0, 0x7f, 0x20, 0xb3, 0x78, 0x4c, 0x16, 0xa6, 0x88, 0x87, 0xe4, + 0xa7, 0xe3, 0x12, 0xd1, 0xb9, 0x1a, 0x0c, 0x55, 0x37, 0x0d, 0x2d, 0x46, 0xeb, 0xf7, 0xe1, 0xc0, + 0x9e, 0xfa, 0x70, 0x2b, 0x8f, 0x2f, 0xf0, 0x83, 0xe8, 0x5e, 0x07, 0xdf, 0x5d, 0xdc, 0x00, 0xe0, + 0x9e, 0x07, 0x81, 0x73, 0xfc, 0x28, 0x0f, 0xe4, 0xc3, 0xb3, 0x74, 0x89, 0x40, 0x3e, 0x21, 0x49, + 0xe0, 0x6b, 0x54, 0x48, 0xf5, 0x35, 0xba, 0x06, 0x83, 0x9a, 0xbe, 0xf1, 0x6e, 0x97, 0x3a, 0x9b, + 0xc2, 0x9c, 0xe1, 0xc1, 0x33, 0xf5, 0x8d, 0xfa, 0x0f, 0x32, 0xa0, 0x16, 0xa0, 0x89, 0x1a, 0x84, + 0x70, 0x90, 0x3c, 0x42, 0xf8, 0x19, 0x79, 0x10, 0xb8, 0x61, 0x3f, 0x8a, 0x4e, 0xde, 0x80, 0x42, + 0xf9, 0x41, 0x4d, 0x48, 0x36, 0xe8, 0xda, 0xf2, 0x83, 0x9a, 0x90, 0x57, 0x66, 0xd9, 0x07, 0x35, + 0xf5, 0x2b, 0x79, 0x20, 0x49, 0x4a, 0xf2, 0x2a, 0x0c, 0x21, 0xb4, 0xc9, 0x74, 0x46, 0x4e, 0xef, + 0xba, 0xe1, 0xd6, 0x1d, 0x84, 0x46, 0x8c, 0x3b, 0x9f, 0x94, 0xbc, 0x8e, 0x09, 0xb4, 0x45, 0x82, + 0xc1, 0x48, 0x7a, 0xd7, 0x0d, 0xd7, 0x4f, 0x39, 0x1d, 0xcb, 0x9f, 0x2d, 0x88, 0xd1, 0x2e, 0x7c, + 0x50, 0x9b, 0xb3, 0x5d, 0x4f, 0x88, 0x9a, 0xdb, 0x85, 0x1b, 0x2e, 0xe6, 0x15, 0x8e, 0xd8, 0x85, + 0x9c, 0x0c, 0x73, 0xa3, 0x3d, 0xa8, 0xf1, 0xc7, 0x4e, 0x86, 0x66, 0xb7, 0x7c, 0x83, 0x92, 0xe7, + 0x46, 0xdb, 0x70, 0xeb, 0xfc, 0xa1, 0x94, 0x81, 0x99, 0xbb, 0x23, 0xb9, 0xd1, 0x22, 0xa5, 0xd4, + 0x9f, 0x1c, 0x84, 0xf1, 0x8a, 0xee, 0xe9, 0xab, 0xba, 0x4b, 0xa5, 0xdd, 0xf4, 0x29, 0x1f, 0xe6, + 0x7f, 0x8e, 0x24, 0x07, 0x63, 0x35, 0xe5, 0x6b, 0xe2, 0x05, 0xc8, 0x9b, 0x21, 0xdf, 0x20, 0x73, + 0xad, 0x9c, 0x0a, 0x6f, 0xb5, 0xde, 0x11, 0x60, 0x2d, 0x41, 0x48, 0x5e, 0x80, 0x61, 0x1f, 0xc6, + 0x36, 0x00, 0x85, 0x50, 0x67, 0x8c, 0x55, 0x66, 0xff, 0x6b, 0x32, 0x9a, 0xbc, 0x0e, 0x23, 0xfe, + 0x4f, 0xc9, 0xb4, 0xe6, 0x79, 0xfd, 0x56, 0x13, 0xbb, 0x27, 0x99, 0x54, 0x2e, 0x8a, 0xf3, 0x5b, + 0x7f, 0xa4, 0x68, 0x2c, 0x75, 0x5e, 0x84, 0x94, 0xfc, 0x20, 0x8c, 0xf9, 0xbf, 0xc5, 0x86, 0x81, + 0xbb, 0xfe, 0xbd, 0x10, 0x24, 0x06, 0x8f, 0x89, 0xf5, 0x7a, 0x94, 0x9c, 0x6f, 0x1d, 0x9e, 0xf2, + 0xb3, 0xc1, 0x19, 0xab, 0xc9, 0x9d, 0x43, 0xac, 0x02, 0x52, 0x85, 0x09, 0x1f, 0x12, 0x6a, 0xe8, + 0x40, 0xb8, 0x63, 0x34, 0x56, 0xeb, 0xa9, 0x4a, 0x9a, 0x2c, 0x45, 0x5a, 0x70, 0x29, 0x02, 0x34, + 0xdc, 0x75, 0x73, 0xcd, 0x13, 0xdb, 0x3d, 0x11, 0xc9, 0x5a, 0xa4, 0xff, 0x0c, 0xb8, 0x72, 0x1a, + 0x3f, 0x8f, 0x6f, 0x34, 0xc7, 0x58, 0x4f, 0x6e, 0xa4, 0x06, 0x67, 0x7c, 0xfc, 0xed, 0xe9, 0xe5, + 0x65, 0xc7, 0x7e, 0x9f, 0x36, 0xbc, 0x6a, 0x45, 0x6c, 0x97, 0x31, 0xc2, 0xa1, 0xb1, 0x5a, 0x6f, + 0x36, 0x3a, 0x4c, 0x29, 0x18, 0x2e, 0xca, 0x3c, 0xb5, 0x30, 0xb9, 0x0f, 0x67, 0x25, 0xb8, 0x94, + 0x64, 0x1c, 0xc2, 0xfd, 0xbc, 0xe0, 0x9a, 0x9e, 0x67, 0x3c, 0xbd, 0x38, 0x79, 0x0b, 0x46, 0x7d, + 0x04, 0xbf, 0x45, 0x1c, 0xc6, 0x5b, 0x44, 0x1c, 0x92, 0xc6, 0x6a, 0x3d, 0xfe, 0x26, 0x37, 0x4a, + 0x2c, 0x6b, 0xd4, 0xca, 0x66, 0x87, 0x0a, 0x9f, 0x5c, 0x5f, 0xa3, 0xbc, 0xcd, 0x4e, 0xaa, 0x32, + 0x32, 0x52, 0xf2, 0x4e, 0xa8, 0x51, 0x4b, 0x8e, 0xd9, 0x34, 0xf9, 0x4e, 0xda, 0x7f, 0x86, 0xbb, + 0x5a, 0xb7, 0x11, 0x98, 0xa6, 0x1f, 0x9c, 0xfc, 0x62, 0x19, 0x4e, 0xa7, 0xe8, 0xd8, 0x9e, 0x76, + 0x8c, 0x5f, 0xcd, 0x87, 0x8d, 0x38, 0xe6, 0xdb, 0xc6, 0x29, 0x18, 0xf4, 0xbf, 0x44, 0x18, 0x0f, + 0x4a, 0xd6, 0xd0, 0x8c, 0xf3, 0xf0, 0xf1, 0x11, 0x71, 0x1c, 0xf3, 0xad, 0xe4, 0x61, 0x88, 0xe3, + 0x3b, 0xb9, 0x50, 0x1c, 0xc7, 0x7c, 0x7b, 0xf9, 0x13, 0xc5, 0x70, 0x4e, 0x3a, 0xd9, 0x63, 0x1e, + 0x96, 0x99, 0x1c, 0xfa, 0xc1, 0x96, 0xf6, 0xf0, 0x1c, 0x56, 0x56, 0xcd, 0x81, 0xfd, 0xa9, 0x26, + 0x79, 0x0b, 0x86, 0x97, 0x6d, 0xd7, 0x6b, 0x3a, 0xd4, 0x5d, 0x0e, 0x32, 0x31, 0xe0, 0x53, 0xea, + 0x8e, 0x00, 0xd7, 0x3b, 0x91, 0xd9, 0x5f, 0x26, 0x57, 0xff, 0x49, 0x21, 0xa1, 0x0d, 0xdc, 0x70, + 0x3d, 0x96, 0xda, 0x70, 0x08, 0x43, 0x9d, 0xdc, 0x0c, 0x57, 0x41, 0x6e, 0xe1, 0xf7, 0x4b, 0x61, + 0x26, 0x57, 0x85, 0x81, 0x1f, 0x25, 0x21, 0xdf, 0x07, 0xe7, 0x23, 0x80, 0x65, 0xdd, 0xd1, 0xdb, + 0xd4, 0x0b, 0xb3, 0x5e, 0x62, 0xe0, 0x30, 0xbf, 0x74, 0xbd, 0x13, 0xa0, 0xe5, 0x4c, 0x9a, 0x19, + 0x1c, 0x24, 0xd5, 0x1a, 0xd8, 0x83, 0x8b, 0xf5, 0xcf, 0x14, 0x42, 0x43, 0x27, 0x1a, 0x00, 0x58, + 0xa3, 0x6e, 0xb7, 0xe5, 0x3d, 0xb9, 0x1d, 0xbc, 0xbf, 0xf4, 0x2a, 0x73, 0x70, 0xaa, 0xbc, 0xb6, + 0x46, 0x1b, 0x9e, 0x1f, 0xd7, 0xdc, 0x15, 0x21, 0x1f, 0xf9, 0xc6, 0x43, 0xa0, 0x44, 0x9c, 0x6a, + 0xb9, 0x5f, 0xe3, 0xc5, 0xd4, 0x7f, 0x5a, 0x04, 0x25, 0x30, 0xfc, 0x83, 0xc7, 0x82, 0x47, 0xb8, + 0xc8, 0x7e, 0x24, 0x7a, 0xc5, 0x84, 0x89, 0x50, 0x18, 0xe2, 0x95, 0x96, 0xc8, 0x8b, 0x3e, 0x19, + 0x67, 0x16, 0x12, 0xf2, 0xbd, 0xc4, 0x45, 0xb1, 0x97, 0x20, 0xe1, 0x63, 0xcc, 0xba, 0xcb, 0x59, + 0x68, 0x49, 0xae, 0xe4, 0x6b, 0x39, 0x38, 0xe3, 0x77, 0xca, 0xd2, 0x2a, 0x33, 0xaa, 0xa7, 0xed, + 0xae, 0x15, 0x3c, 0x61, 0x7a, 0x23, 0xbb, 0x3a, 0xde, 0x49, 0xd7, 0xd3, 0x0a, 0xf3, 0x96, 0x04, + 0xc1, 0x4d, 0x02, 0x85, 0xb0, 0x91, 0xa6, 0xde, 0x40, 0x22, 0x2d, 0xb5, 0xde, 0x8b, 0xb7, 0xe1, + 0x42, 0x26, 0xcb, 0x9d, 0x8c, 0xd8, 0x7e, 0xd9, 0x88, 0xfd, 0xef, 0x72, 0xe1, 0x44, 0x14, 0x13, + 0x12, 0xb9, 0x0e, 0x10, 0x82, 0xc4, 0xb6, 0x16, 0x5f, 0x48, 0x85, 0x42, 0xd3, 0x24, 0x0a, 0xb2, + 0x04, 0x25, 0x21, 0x16, 0x9e, 0x61, 0xfa, 0xd3, 0x3b, 0xf4, 0xc2, 0x75, 0x59, 0x0e, 0xb8, 0x65, + 0x15, 0xdf, 0x2c, 0xd8, 0x5c, 0x7c, 0x1d, 0x86, 0xf7, 0xfb, 0x5d, 0x5f, 0x2b, 0x00, 0x91, 0xf7, + 0xa0, 0x47, 0x68, 0xa0, 0x1f, 0xe3, 0x29, 0xec, 0x2a, 0x0c, 0xb2, 0x4f, 0xc0, 0x9c, 0x2b, 0x52, + 0x8c, 0xe5, 0xae, 0x80, 0x69, 0x01, 0x36, 0x0c, 0x70, 0x36, 0x90, 0x1e, 0xe0, 0x4c, 0xfd, 0xe9, + 0x02, 0x9c, 0x93, 0x3b, 0xa4, 0x42, 0x31, 0x6d, 0xc3, 0x49, 0xa7, 0x7c, 0x88, 0x9d, 0xa2, 0x42, + 0x89, 0x6f, 0x3d, 0x44, 0xfe, 0x0c, 0x7e, 0x2c, 0x84, 0x10, 0x4d, 0x60, 0xd4, 0xff, 0x39, 0x0f, + 0xa3, 0x81, 0x79, 0xa7, 0x3b, 0xee, 0x13, 0xdc, 0x1d, 0x9f, 0x85, 0x51, 0x0c, 0x51, 0xd5, 0xa6, + 0x16, 0x0f, 0xe3, 0xd4, 0x2f, 0x25, 0xbc, 0xf1, 0x11, 0x22, 0xb7, 0x59, 0x84, 0x90, 0x69, 0x3f, + 0xb7, 0xfc, 0xa4, 0xc0, 0x61, 0xdc, 0xec, 0xe3, 0x70, 0xf5, 0xaf, 0x14, 0x60, 0xc4, 0x97, 0xf2, + 0x94, 0x79, 0x5c, 0xef, 0x79, 0x8e, 0x56, 0xc8, 0x37, 0x00, 0x96, 0x6d, 0xc7, 0xd3, 0x5b, 0x8b, + 0xa1, 0xe6, 0xe3, 0x01, 0x69, 0x07, 0xa1, 0xbc, 0x8c, 0x44, 0x82, 0xeb, 0x57, 0x68, 0x56, 0xf3, + 0x89, 0x89, 0xaf, 0x5f, 0x01, 0x54, 0x93, 0x28, 0xd4, 0xdf, 0xce, 0xc3, 0x29, 0xbf, 0x93, 0x66, + 0x1e, 0xd3, 0x46, 0xf7, 0x49, 0x9e, 0x9b, 0xa2, 0xd2, 0xee, 0xdf, 0x51, 0xda, 0xea, 0xff, 0x29, + 0x4d, 0x24, 0xd3, 0x2d, 0xfb, 0x64, 0x22, 0xf9, 0x93, 0xd0, 0x71, 0xf5, 0x47, 0x0a, 0x70, 0xc6, + 0x97, 0xfa, 0x6c, 0xd7, 0xc2, 0xa3, 0x85, 0x69, 0xbd, 0xd5, 0x7a, 0x92, 0x77, 0xe3, 0xc3, 0xbe, + 0x20, 0x96, 0x44, 0xcc, 0x47, 0x91, 0x67, 0x72, 0x4d, 0x80, 0xeb, 0xb6, 0x69, 0x68, 0x32, 0x11, + 0x79, 0x07, 0x46, 0xfc, 0x9f, 0x65, 0xa7, 0xe9, 0x6f, 0xc1, 0xf1, 0xa2, 0x20, 0x28, 0xa4, 0x3b, + 0x91, 0xd0, 0x16, 0x91, 0x02, 0xea, 0x57, 0x06, 0xe0, 0xe2, 0x03, 0xd3, 0x32, 0xec, 0x0d, 0xd7, + 0x4f, 0x53, 0x7a, 0xec, 0x0f, 0xca, 0x8e, 0x3a, 0x3d, 0xe9, 0xbb, 0x70, 0x36, 0x2e, 0x52, 0x27, + 0x08, 0x1e, 0x2f, 0x7a, 0x67, 0x83, 0x13, 0xd4, 0xfd, 0x84, 0xa5, 0xe2, 0xb6, 0x4d, 0x4b, 0x2f, + 0x19, 0xcf, 0x78, 0x3a, 0xb0, 0x9b, 0x8c, 0xa7, 0xcf, 0x43, 0xa9, 0x62, 0xb7, 0x75, 0xd3, 0x0f, + 0x72, 0x84, 0xa3, 0x38, 0xa8, 0x17, 0x31, 0x9a, 0xa0, 0x60, 0xfc, 0x45, 0xc5, 0xd8, 0x65, 0x43, + 0x21, 0x7f, 0xbf, 0x00, 0xb3, 0xd2, 0x34, 0x99, 0x88, 0xd8, 0x30, 0x2a, 0xaa, 0x13, 0x77, 0x63, + 0x80, 0x9b, 0xa7, 0x57, 0x7c, 0x19, 0x65, 0xab, 0xd5, 0xf5, 0x48, 0x39, 0xbe, 0x8d, 0xe2, 0x89, + 0x58, 0xc5, 0xc7, 0xf0, 0x5b, 0x32, 0x2d, 0xca, 0x5f, 0x12, 0x02, 0x4e, 0x32, 0xc3, 0x49, 0x21, + 0xe0, 0x2c, 0x23, 0x13, 0x91, 0x19, 0x98, 0xc0, 0x10, 0xdf, 0xc1, 0x56, 0x8a, 0xa9, 0xc4, 0x08, + 0x1a, 0x95, 0x78, 0xe5, 0xc2, 0xa3, 0x82, 0xb3, 0x8f, 0xab, 0x37, 0x04, 0x5a, 0x4b, 0x96, 0x20, + 0x17, 0xa0, 0xb0, 0x38, 0x5f, 0xc6, 0xbb, 0x9a, 0x41, 0x9e, 0x5e, 0xcb, 0x6a, 0xe9, 0x1a, 0x83, + 0x5d, 0xfc, 0x3c, 0x90, 0xe4, 0xe7, 0xec, 0xe9, 0x3e, 0xe6, 0xbf, 0x94, 0xb6, 0x7c, 0xc7, 0xdd, + 0xa3, 0xe6, 0x30, 0x26, 0xc2, 0x48, 0x66, 0xbb, 0xfe, 0x0f, 0x33, 0xb3, 0x5d, 0xe9, 0x50, 0x33, + 0xdb, 0xa9, 0xbf, 0x9c, 0x83, 0x89, 0x44, 0x18, 0x7c, 0xf2, 0x32, 0x00, 0x87, 0x48, 0xe1, 0x46, + 0x31, 0x7e, 0x4f, 0x18, 0x1a, 0x5f, 0x2c, 0x8f, 0x21, 0x19, 0xb9, 0x01, 0x83, 0xfc, 0x97, 0x08, + 0x11, 0x96, 0x2c, 0xd2, 0xed, 0x9a, 0x86, 0x16, 0x10, 0x85, 0xb5, 0xe0, 0x8d, 0x64, 0x21, 0xb5, + 0x88, 0xb7, 0xd9, 0x09, 0x6a, 0x61, 0x64, 0xea, 0x4f, 0xe6, 0x61, 0x24, 0x68, 0x70, 0xd9, 0x38, + 0x2a, 0x9d, 0x2b, 0x89, 0x8c, 0x02, 0x85, 0x9d, 0x32, 0x0a, 0xc4, 0xe6, 0x5b, 0x91, 0x42, 0xe0, + 0xf0, 0x1e, 0x54, 0x7d, 0x3d, 0x0f, 0xa7, 0x82, 0x5a, 0x8f, 0xf0, 0xf2, 0xeb, 0x23, 0x24, 0x92, + 0xaf, 0xe5, 0x40, 0x99, 0x32, 0x5b, 0x2d, 0xd3, 0x6a, 0x56, 0xad, 0x35, 0xdb, 0x69, 0xe3, 0x84, + 0x78, 0x74, 0x47, 0xb8, 0xea, 0x9f, 0xce, 0xc1, 0x84, 0x68, 0xd0, 0xb4, 0xee, 0x18, 0x47, 0x77, + 0x3e, 0x16, 0x6f, 0xc9, 0xd1, 0xe9, 0x8b, 0xfa, 0xcd, 0x3c, 0xc0, 0xbc, 0xdd, 0x78, 0x78, 0xcc, + 0xdf, 0x63, 0xbd, 0x09, 0x25, 0x1e, 0xa7, 0x4d, 0x68, 0xec, 0x84, 0x78, 0x77, 0xc4, 0x3e, 0x8d, + 0x23, 0xa6, 0xc6, 0xc5, 0x7c, 0x5c, 0xe2, 0x71, 0xde, 0x94, 0x9c, 0x26, 0x8a, 0xb0, 0x4a, 0x19, + 0x9d, 0x58, 0x30, 0x82, 0x4a, 0x19, 0x2c, 0x5a, 0xe9, 0xf6, 0xd6, 0x64, 0xb1, 0x65, 0x37, 0x1e, + 0x6a, 0x48, 0xaf, 0xfe, 0xeb, 0x1c, 0x97, 0xdd, 0x31, 0x7f, 0x55, 0xea, 0x7f, 0x7e, 0x71, 0x8f, + 0x9f, 0xff, 0x67, 0x72, 0x70, 0x46, 0xa3, 0x0d, 0xfb, 0x11, 0x75, 0x36, 0xa7, 0x6d, 0x83, 0xde, + 0xa6, 0x16, 0x75, 0x8e, 0x6a, 0x44, 0xfd, 0x0e, 0xa6, 0x60, 0x09, 0x1b, 0x73, 0xcf, 0xa5, 0xc6, + 0xf1, 0x49, 0x8f, 0xa3, 0xfe, 0xda, 0x00, 0x28, 0xa9, 0x56, 0xef, 0xb1, 0x35, 0xe7, 0x32, 0xb7, + 0x32, 0xc5, 0xc3, 0xda, 0xca, 0xf4, 0xef, 0x6d, 0x2b, 0x53, 0xda, 0xeb, 0x56, 0x66, 0x60, 0x37, + 0x5b, 0x99, 0x76, 0x7c, 0x2b, 0x33, 0x88, 0x5b, 0x99, 0x97, 0x7b, 0x6e, 0x65, 0x66, 0x2c, 0x63, + 0x9f, 0x1b, 0x99, 0x63, 0x9b, 0xba, 0x79, 0x3f, 0x3b, 0xb0, 0xab, 0x6c, 0x52, 0x6c, 0xd8, 0x8e, + 0x41, 0x0d, 0xb1, 0xf1, 0xc2, 0x53, 0x7f, 0x47, 0xc0, 0xb4, 0x00, 0x9b, 0xc8, 0x83, 0x3d, 0xba, + 0x9b, 0x3c, 0xd8, 0x87, 0xb0, 0xff, 0xfa, 0x6a, 0x1e, 0x26, 0xa6, 0xa9, 0xe3, 0xf1, 0x40, 0xb0, + 0x87, 0xe1, 0x12, 0x57, 0x86, 0x53, 0x12, 0x43, 0xb4, 0xc8, 0xf3, 0xa1, 0x9b, 0x5f, 0x83, 0x3a, + 0x5e, 0xdc, 0x4b, 0x30, 0x4e, 0xcf, 0xaa, 0xf7, 0x73, 0xd1, 0x89, 0xb1, 0x1b, 0x54, 0xef, 0xc3, + 0xb9, 0x20, 0x4d, 0xf1, 0x4b, 0x0b, 0xe8, 0xa5, 0xf4, 0x72, 0xc5, 0xbd, 0xa7, 0x97, 0x53, 0x7f, + 0x29, 0x07, 0x57, 0x34, 0x6a, 0xd1, 0x0d, 0x7d, 0xb5, 0x45, 0xa5, 0x66, 0x89, 0x95, 0x81, 0xcd, + 0x1a, 0xa6, 0xdb, 0xd6, 0xbd, 0xc6, 0xfa, 0x81, 0x64, 0x34, 0x0b, 0x23, 0xf2, 0xfc, 0xb5, 0x87, + 0xb9, 0x2d, 0x52, 0x4e, 0xfd, 0xb5, 0x22, 0x0c, 0x4c, 0xd9, 0xde, 0x1d, 0xfb, 0x80, 0xf9, 0x0e, + 0xc3, 0x29, 0x3f, 0xbf, 0x87, 0xb3, 0x9e, 0xcf, 0x60, 0xe5, 0x52, 0x0a, 0x08, 0x74, 0x21, 0x5d, + 0xb5, 0x13, 0xa9, 0x32, 0x7c, 0xb2, 0x3d, 0x66, 0x3a, 0x7c, 0x15, 0x86, 0x30, 0xfa, 0x8b, 0x74, + 0x1a, 0x8b, 0x0e, 0xda, 0x1e, 0x03, 0xc6, 0xeb, 0x08, 0x49, 0xc9, 0xf7, 0x45, 0x22, 0xd7, 0x96, + 0x0e, 0x9e, 0x19, 0x51, 0x0e, 0x62, 0xfb, 0x32, 0xbf, 0xc8, 0xc3, 0x36, 0x49, 0x59, 0x64, 0xf0, + 0x14, 0x25, 0xd6, 0xa4, 0x80, 0xf0, 0x10, 0xb3, 0x16, 0x4e, 0xc3, 0xe8, 0x94, 0xed, 0x49, 0xce, + 0xc0, 0x43, 0xe1, 0x33, 0x50, 0x26, 0xf9, 0x74, 0x4f, 0xe0, 0x68, 0x19, 0xf5, 0x8f, 0x8b, 0x30, + 0xe2, 0xff, 0x3c, 0x22, 0xdd, 0x79, 0x11, 0x4a, 0x73, 0xb6, 0x94, 0x48, 0x03, 0x1d, 0x88, 0xd7, + 0x6d, 0x37, 0xe6, 0x19, 0x2d, 0x88, 0x98, 0xd4, 0x17, 0x6d, 0x43, 0x76, 0x7f, 0x47, 0xa9, 0x5b, + 0xb6, 0x91, 0x78, 0x3e, 0x1c, 0x10, 0x92, 0x2b, 0x50, 0xc4, 0x97, 0x03, 0xd2, 0x41, 0x7e, 0xec, + 0xb5, 0x00, 0xe2, 0x25, 0xad, 0x2c, 0xed, 0x55, 0x2b, 0x07, 0xf6, 0xab, 0x95, 0x83, 0x87, 0xab, + 0x95, 0xef, 0xc1, 0x08, 0xd6, 0xe4, 0xe7, 0xe1, 0xdb, 0x79, 0x61, 0xbd, 0x20, 0xd6, 0xbe, 0x51, + 0xde, 0x6e, 0x91, 0x8d, 0x0f, 0x97, 0xbc, 0x08, 0xab, 0x98, 0xee, 0xc2, 0x01, 0xb6, 0xd3, 0xff, + 0x24, 0x07, 0x03, 0xf7, 0xac, 0x87, 0x96, 0xbd, 0x71, 0x30, 0x8d, 0x7b, 0x19, 0x86, 0x05, 0x1b, + 0x69, 0x75, 0xc1, 0x17, 0xe1, 0x5d, 0x0e, 0xae, 0x23, 0x27, 0x4d, 0xa6, 0x22, 0x6f, 0x05, 0x85, + 0xf0, 0x71, 0x50, 0x21, 0x4c, 0x45, 0xe3, 0x17, 0x6a, 0x44, 0xb3, 0x67, 0xc8, 0xe4, 0xe4, 0x12, + 0x14, 0x2b, 0xac, 0xa9, 0x52, 0x14, 0x5d, 0xd6, 0x14, 0x0d, 0xa1, 0xea, 0x57, 0x8b, 0x30, 0x16, + 0x3b, 0xf8, 0x7a, 0x1e, 0x86, 0xc4, 0xc1, 0x93, 0xe9, 0xa7, 0xf3, 0xc0, 0xc7, 0x43, 0x01, 0x50, + 0x1b, 0xe4, 0x7f, 0x56, 0x0d, 0xf2, 0x39, 0x18, 0xb0, 0x5d, 0x5c, 0x14, 0xf1, 0x5b, 0xc6, 0xc2, + 0x21, 0xb4, 0x54, 0x63, 0x6d, 0xe7, 0x83, 0x43, 0x90, 0xc8, 0x1a, 0x69, 0xbb, 0xf8, 0x69, 0xb7, + 0x60, 0x48, 0x77, 0x5d, 0xea, 0xd5, 0x3d, 0xbd, 0x29, 0x67, 0xf8, 0x08, 0x80, 0xf2, 0xe8, 0x40, + 0xe0, 0x8a, 0xde, 0x24, 0x9f, 0x87, 0xd1, 0x86, 0x43, 0x71, 0xd9, 0xd4, 0x5b, 0xac, 0x95, 0x92, + 0x59, 0x1b, 0x41, 0xc8, 0xf7, 0x27, 0x21, 0xa2, 0x6a, 0x90, 0xfb, 0x30, 0x2a, 0x3e, 0x87, 0x7b, + 0xee, 0xe3, 0x40, 0x1b, 0x0b, 0x97, 0x31, 0x2e, 0x12, 0xee, 0xbb, 0x2f, 0x1e, 0x70, 0xc8, 0xe4, + 0x32, 0x5f, 0x43, 0x22, 0x25, 0x4b, 0x40, 0x36, 0xe8, 0x6a, 0x5d, 0xef, 0x7a, 0xeb, 0xac, 0x2e, + 0x1e, 0xa0, 0x5e, 0x24, 0xb6, 0xc4, 0x57, 0x0f, 0x49, 0xac, 0xfc, 0x18, 0x64, 0x83, 0xae, 0x96, + 0x23, 0x48, 0xf2, 0x00, 0xce, 0x26, 0x8b, 0xb0, 0x4f, 0xe6, 0x97, 0x03, 0xcf, 0x6d, 0x6f, 0x4d, + 0x4e, 0xa6, 0x12, 0x48, 0x6c, 0x4f, 0x27, 0xd8, 0x56, 0x8d, 0x3b, 0xc5, 0xc1, 0x81, 0xf1, 0x41, + 0x6d, 0x8c, 0x95, 0xf5, 0x4d, 0x48, 0xd3, 0x50, 0x7f, 0x37, 0xc7, 0x4c, 0x45, 0xf6, 0x41, 0x98, + 0xd9, 0x9b, 0xe9, 0x7a, 0x7b, 0x8f, 0xba, 0xde, 0x0e, 0x73, 0x70, 0x96, 0xdc, 0x1e, 0xb3, 0xab, + 0x26, 0xb0, 0xe4, 0x3a, 0x94, 0x0c, 0xf9, 0xd4, 0xec, 0x5c, 0xb4, 0x13, 0xfc, 0x7a, 0x34, 0x41, + 0x45, 0xae, 0x42, 0x91, 0x2d, 0x59, 0xf1, 0x2d, 0xb3, 0x6c, 0x5d, 0x68, 0x48, 0xa1, 0xfe, 0x50, + 0x1e, 0x46, 0xa4, 0xaf, 0xb9, 0x79, 0xa0, 0xcf, 0x79, 0x63, 0x77, 0xcd, 0xf4, 0x9d, 0x5e, 0x70, + 0x2f, 0xe5, 0x37, 0xf9, 0x56, 0x20, 0x8a, 0x5d, 0x5d, 0x48, 0x09, 0xc1, 0xbc, 0x2a, 0x3e, 0xb4, + 0xb4, 0xfb, 0xed, 0x23, 0xa3, 0xbf, 0x53, 0x1c, 0xcc, 0x8f, 0x17, 0xee, 0x14, 0x07, 0x8b, 0xe3, + 0xfd, 0x18, 0x87, 0x0b, 0x43, 0x5f, 0xf3, 0xbd, 0xb9, 0xb5, 0x66, 0x36, 0x8f, 0xf9, 0xdb, 0x91, + 0xc3, 0x8d, 0x51, 0x16, 0x93, 0xcd, 0x31, 0x7f, 0x48, 0xf2, 0xa1, 0xca, 0xe6, 0x24, 0x67, 0xa7, + 0x90, 0xcd, 0x3f, 0xcd, 0x81, 0x92, 0x2a, 0x9b, 0xf2, 0x11, 0xf9, 0x41, 0x1c, 0x5e, 0xe6, 0xce, + 0x3f, 0xcc, 0xc3, 0x44, 0xd5, 0xf2, 0x68, 0x93, 0xef, 0x18, 0x8f, 0xf9, 0x54, 0x71, 0x17, 0x86, + 0xa5, 0x8f, 0x11, 0x7d, 0xfe, 0x54, 0xb0, 0x1f, 0x0f, 0x51, 0x19, 0x9c, 0xe4, 0xd2, 0x87, 0x98, + 0xec, 0x3f, 0x26, 0xe4, 0x63, 0x3e, 0xe7, 0x1c, 0x0f, 0x21, 0x1f, 0xf3, 0xc9, 0xeb, 0x23, 0x2a, + 0xe4, 0xff, 0x3d, 0x07, 0xa7, 0x53, 0x2a, 0x27, 0x57, 0x60, 0xa0, 0xd6, 0x5d, 0xc5, 0xb0, 0x5b, + 0xb9, 0xd0, 0x63, 0xd8, 0xed, 0xae, 0x62, 0xc4, 0x2d, 0xcd, 0x47, 0x92, 0x15, 0x7c, 0x5c, 0xbf, + 0x54, 0xad, 0x4c, 0x0b, 0xa9, 0xaa, 0x52, 0x98, 0x00, 0x06, 0x4e, 0xfb, 0xb2, 0xe0, 0x01, 0xbe, + 0x6d, 0x1a, 0x8d, 0xd8, 0x03, 0x7c, 0x56, 0x86, 0x7c, 0x3f, 0x0c, 0x95, 0x3f, 0xe8, 0x3a, 0x14, + 0xf9, 0x72, 0x89, 0x7f, 0x22, 0xe0, 0xeb, 0x23, 0xd2, 0x38, 0xf3, 0x58, 0x02, 0x8c, 0x22, 0xce, + 0x3b, 0x64, 0xa8, 0xfe, 0x64, 0x0e, 0x2e, 0x66, 0xb7, 0x8e, 0x7c, 0x06, 0x06, 0xd8, 0xce, 0xbc, + 0xac, 0x2d, 0x8a, 0x4f, 0xe7, 0x59, 0x6e, 0xed, 0x16, 0xad, 0xeb, 0x8e, 0x6c, 0xec, 0xfb, 0x64, + 0xe4, 0x6d, 0x18, 0xae, 0xba, 0x6e, 0x97, 0x3a, 0xb5, 0x97, 0xef, 0x69, 0x55, 0xb1, 0x27, 0xc4, + 0x3d, 0x87, 0x89, 0xe0, 0xba, 0xfb, 0x72, 0x2c, 0xb0, 0x96, 0x4c, 0xaf, 0xfe, 0x58, 0x0e, 0x2e, + 0xf5, 0xfa, 0x2a, 0xf2, 0x32, 0x0c, 0xae, 0x50, 0x4b, 0xb7, 0xbc, 0x6a, 0x45, 0x34, 0x09, 0xb7, + 0x58, 0x1e, 0xc2, 0xa2, 0x3b, 0x85, 0x80, 0x90, 0x15, 0xe2, 0xe7, 0x8a, 0x81, 0x23, 0x03, 0x3f, + 0x03, 0x45, 0x58, 0xac, 0x90, 0x4f, 0xa8, 0xfe, 0x5e, 0x1e, 0x46, 0x96, 0x5b, 0xdd, 0xa6, 0x29, + 0x2d, 0x1c, 0xfb, 0xb6, 0xb7, 0x7d, 0xeb, 0x37, 0xbf, 0x37, 0xeb, 0x97, 0x0d, 0x37, 0x67, 0x9f, + 0xc3, 0xcd, 0x2f, 0x47, 0xde, 0x82, 0x52, 0x07, 0xbf, 0x23, 0x7e, 0x12, 0xcb, 0xbf, 0x2e, 0xeb, + 0x24, 0x96, 0x97, 0x61, 0xe3, 0xab, 0x71, 0x80, 0xf1, 0x15, 0x96, 0x95, 0x04, 0x1a, 0x2e, 0x12, + 0x27, 0x02, 0x3d, 0x14, 0x81, 0x86, 0x0b, 0xc2, 0x89, 0x40, 0x0f, 0x20, 0xd0, 0x5f, 0xcb, 0xc3, + 0x58, 0xb4, 0x4a, 0xf2, 0x19, 0x18, 0xe6, 0xd5, 0xf0, 0x73, 0xa1, 0x9c, 0xe4, 0x54, 0x1c, 0x82, + 0x35, 0xe0, 0x3f, 0xc4, 0x01, 0xd7, 0xa9, 0x75, 0xdd, 0xad, 0x87, 0x27, 0x34, 0xfc, 0xfe, 0x76, + 0x90, 0x7b, 0x42, 0xc5, 0x50, 0xda, 0xd8, 0xba, 0xee, 0x4e, 0x87, 0xbf, 0xc9, 0x0c, 0x10, 0x87, + 0x76, 0x5d, 0x1a, 0x65, 0x50, 0x44, 0x06, 0x22, 0xc5, 0x78, 0x1c, 0xab, 0x4d, 0x70, 0x98, 0xcc, + 0xe6, 0x4b, 0x41, 0xb3, 0x51, 0x19, 0xfa, 0x77, 0x91, 0xff, 0x5c, 0xa2, 0x4f, 0x3f, 0xe6, 0xe4, + 0x04, 0x15, 0xdd, 0xd3, 0xf9, 0xa6, 0xdc, 0xef, 0x00, 0xf5, 0x87, 0x3b, 0xd0, 0xbf, 0x64, 0xd1, + 0xa5, 0x35, 0xf2, 0x12, 0x0c, 0x31, 0x85, 0x99, 0xb7, 0x59, 0x5f, 0xe6, 0x84, 0xff, 0x84, 0xa4, + 0x49, 0x88, 0x98, 0xeb, 0xd3, 0x42, 0x2a, 0x72, 0x0b, 0x20, 0x7c, 0x62, 0x26, 0xb4, 0x8f, 0xc8, + 0x65, 0x38, 0x66, 0xae, 0x4f, 0x93, 0xe8, 0xfc, 0x52, 0xe2, 0x81, 0x4e, 0x21, 0x59, 0x8a, 0x63, + 0xfc, 0x52, 0x62, 0x7c, 0xcc, 0x03, 0x61, 0xbf, 0x96, 0x75, 0xd7, 0xdd, 0xb0, 0x1d, 0x63, 0x7a, + 0x5d, 0xb7, 0x9a, 0x34, 0xbe, 0x7b, 0x4a, 0x52, 0xcc, 0xf5, 0x69, 0x29, 0xe5, 0xc8, 0x1b, 0x30, + 0x22, 0x3b, 0x94, 0xc6, 0x9d, 0x3e, 0x64, 0xdc, 0x5c, 0x9f, 0x16, 0xa1, 0x25, 0xaf, 0xc1, 0xb0, + 0xf8, 0x7d, 0xc7, 0x16, 0x37, 0xca, 0x52, 0x2c, 0x22, 0x09, 0x35, 0xd7, 0xa7, 0xc9, 0x94, 0x52, + 0xa5, 0xcb, 0x8e, 0x69, 0x79, 0xe2, 0x8d, 0x72, 0xbc, 0x52, 0xc4, 0x49, 0x95, 0xe2, 0x6f, 0xf2, + 0x36, 0x8c, 0x06, 0x41, 0x9e, 0xde, 0xa7, 0x0d, 0x4f, 0x1c, 0x7e, 0x9f, 0x8d, 0x15, 0xe6, 0xc8, + 0xb9, 0x3e, 0x2d, 0x4a, 0x4d, 0xae, 0x42, 0x49, 0xa3, 0xae, 0xf9, 0x81, 0x7f, 0x5d, 0x3c, 0x26, + 0x8d, 0x73, 0xf3, 0x03, 0x26, 0x25, 0x81, 0x67, 0xbd, 0x13, 0xde, 0x4f, 0x8b, 0xa3, 0x6a, 0x12, + 0xab, 0x65, 0xc6, 0x32, 0x58, 0xef, 0x48, 0xce, 0x09, 0x9f, 0x0f, 0x43, 0x5f, 0x89, 0xb4, 0xab, + 0xc3, 0xf1, 0x18, 0x03, 0x32, 0x76, 0xae, 0x4f, 0x8b, 0xd1, 0x4b, 0x52, 0xad, 0x98, 0xee, 0x43, + 0x11, 0x6d, 0x34, 0x2e, 0x55, 0x86, 0x92, 0xa4, 0xca, 0x7e, 0x4a, 0x55, 0x2f, 0x52, 0x6f, 0xc3, + 0x76, 0x1e, 0x8a, 0xd8, 0xa2, 0xf1, 0xaa, 0x05, 0x56, 0xaa, 0x5a, 0x40, 0xe4, 0xaa, 0xd9, 0x80, + 0x1b, 0x4b, 0xaf, 0x5a, 0xf7, 0x74, 0xb9, 0x6a, 0x7e, 0x12, 0xe7, 0x77, 0xd2, 0x3c, 0xd5, 0x1f, + 0xf1, 0xec, 0xf7, 0xc9, 0x0e, 0x45, 0x9c, 0xd4, 0xa1, 0xf8, 0x9b, 0x55, 0x2a, 0x65, 0x38, 0x17, + 0xe9, 0xed, 0x83, 0x4a, 0x25, 0x14, 0xab, 0x54, 0xce, 0x85, 0x7e, 0x4b, 0x4e, 0xfc, 0xad, 0x4c, + 0x44, 0x3b, 0x28, 0xc4, 0xb0, 0x0e, 0x92, 0x12, 0x84, 0x4f, 0x62, 0x52, 0x61, 0x85, 0x20, 0xf9, + 0x70, 0xd0, 0xc2, 0xe9, 0xe5, 0xb9, 0x3e, 0x0d, 0xd3, 0x0d, 0xab, 0x3c, 0x5d, 0xb5, 0x72, 0x1a, + 0x29, 0x46, 0x7c, 0x0a, 0x06, 0x9b, 0xeb, 0xd3, 0x78, 0x2a, 0xeb, 0x97, 0xa4, 0x94, 0x7e, 0xca, + 0x99, 0xe8, 0x14, 0x11, 0x20, 0xd8, 0x14, 0x11, 0x26, 0xfe, 0x9b, 0x4d, 0xa6, 0xbd, 0x53, 0xce, + 0x46, 0x97, 0x9a, 0x38, 0x7e, 0xae, 0x4f, 0x4b, 0xa6, 0xca, 0x7b, 0x2d, 0x92, 0x09, 0x4e, 0x39, + 0x17, 0x0b, 0x00, 0x16, 0xa2, 0x98, 0xb8, 0xe4, 0x9c, 0x71, 0x4b, 0xb1, 0xdc, 0xf7, 0x62, 0xb2, + 0x3a, 0x1f, 0xdd, 0xb8, 0xa4, 0x90, 0xcc, 0xf5, 0x69, 0x69, 0x25, 0xc9, 0x74, 0x22, 0x1f, 0x9b, + 0xa2, 0x44, 0x7d, 0x63, 0x62, 0xe8, 0xb9, 0x3e, 0x2d, 0x91, 0xc1, 0xed, 0x96, 0x9c, 0x08, 0x4d, + 0xb9, 0x10, 0xed, 0xc4, 0x10, 0xc3, 0x3a, 0x51, 0x4a, 0x98, 0x76, 0x4b, 0x4e, 0x8e, 0xa5, 0x5c, + 0x4c, 0x96, 0x0a, 0x67, 0x4e, 0x29, 0x89, 0x96, 0x96, 0x9e, 0xef, 0x47, 0x79, 0x4a, 0xe4, 0xed, + 0x15, 0xe5, 0xd3, 0x68, 0xe6, 0xfa, 0xb4, 0xf4, 0x5c, 0x41, 0x5a, 0x7a, 0xa2, 0x1c, 0xe5, 0x52, + 0x2f, 0x9e, 0x41, 0xeb, 0xd2, 0x93, 0xec, 0xe8, 0x3d, 0xd2, 0x96, 0x28, 0x4f, 0x47, 0xa3, 0x0f, + 0x67, 0x12, 0xce, 0xf5, 0x69, 0x3d, 0x92, 0x9f, 0xdc, 0xcb, 0xc8, 0x21, 0xa2, 0x5c, 0x8e, 0xa6, + 0xed, 0x4e, 0x25, 0x9a, 0xeb, 0xd3, 0x32, 0x32, 0x90, 0xdc, 0xcb, 0x48, 0x31, 0xa1, 0x4c, 0xf6, + 0x64, 0x1b, 0xc8, 0x23, 0x23, 0x41, 0xc5, 0x52, 0x6a, 0x76, 0x06, 0xe5, 0x99, 0xa8, 0xea, 0xa6, + 0x90, 0x30, 0xd5, 0x4d, 0xcb, 0xeb, 0xb0, 0x94, 0x9a, 0x4e, 0x40, 0x79, 0xb6, 0x07, 0xc3, 0xa0, + 0x8d, 0xa9, 0x89, 0x08, 0x96, 0x52, 0xe3, 0xf9, 0x2b, 0x6a, 0x94, 0x61, 0x0a, 0x09, 0x63, 0x98, + 0x96, 0x09, 0x60, 0x29, 0x35, 0xec, 0xbb, 0xf2, 0x5c, 0x0f, 0x86, 0x61, 0x0b, 0xd3, 0x02, 0xc6, + 0xbf, 0x16, 0x89, 0xbb, 0xae, 0x7c, 0x22, 0x3a, 0x6f, 0x48, 0x28, 0x36, 0x6f, 0xc8, 0x11, 0xda, + 0xa7, 0x13, 0x91, 0x65, 0x95, 0x4f, 0x46, 0x87, 0x79, 0x0c, 0xcd, 0x86, 0x79, 0x3c, 0x16, 0xed, + 0x74, 0x22, 0xc2, 0xa6, 0x72, 0x25, 0x8b, 0x09, 0xa2, 0xa3, 0x4c, 0x78, 0x4c, 0xce, 0x6a, 0x4a, + 0x88, 0x47, 0xe5, 0x53, 0x51, 0xbf, 0xee, 0x04, 0xc1, 0x5c, 0x9f, 0x96, 0x12, 0x18, 0x52, 0x4b, + 0x8f, 0x67, 0xa4, 0x5c, 0x8d, 0x0e, 0xdb, 0x34, 0x1a, 0x36, 0x6c, 0x53, 0x63, 0x21, 0xcd, 0xa7, + 0x3d, 0x3e, 0x51, 0xae, 0x45, 0x0d, 0xb3, 0x24, 0x05, 0x33, 0xcc, 0x52, 0x1e, 0xad, 0x68, 0xe9, + 0x31, 0x76, 0x94, 0xe7, 0x7b, 0xb6, 0x10, 0x69, 0x52, 0x5a, 0xc8, 0x43, 0xce, 0x84, 0xb6, 0xd3, + 0xbd, 0x4e, 0xcb, 0xd6, 0x0d, 0xe5, 0xd3, 0xa9, 0xb6, 0x13, 0x47, 0x4a, 0xb6, 0x13, 0x07, 0xb0, + 0x55, 0x5e, 0x7e, 0xe3, 0xa0, 0xbc, 0x10, 0x5d, 0xe5, 0x65, 0x1c, 0x5b, 0xe5, 0x23, 0xef, 0x21, + 0xa6, 0x13, 0xef, 0x01, 0x94, 0x17, 0xa3, 0x0a, 0x10, 0x43, 0x33, 0x05, 0x88, 0xbf, 0x20, 0xf8, + 0x72, 0xb6, 0x07, 0xbd, 0x72, 0x1d, 0xb9, 0x3d, 0xe3, 0x73, 0xcb, 0xa2, 0x9b, 0xeb, 0xd3, 0xb2, + 0xbd, 0xf0, 0xab, 0x29, 0x0e, 0xf1, 0xca, 0x8d, 0xa8, 0x82, 0x25, 0x08, 0x98, 0x82, 0x25, 0xdd, + 0xe8, 0xab, 0x29, 0x1e, 0xed, 0xca, 0x67, 0x32, 0x59, 0x05, 0xdf, 0x9c, 0xe2, 0x07, 0x7f, 0x4b, + 0x76, 0x49, 0x57, 0x5e, 0x8a, 0x2e, 0x76, 0x21, 0x86, 0x2d, 0x76, 0x92, 0xeb, 0xfa, 0x2d, 0xd9, + 0x19, 0x5b, 0xb9, 0x99, 0x2c, 0x15, 0x2e, 0x91, 0x92, 0xd3, 0xb6, 0x96, 0xee, 0xc3, 0xac, 0xbc, + 0x1c, 0xd5, 0xba, 0x34, 0x1a, 0xa6, 0x75, 0xa9, 0xfe, 0xcf, 0xb3, 0x49, 0x57, 0x64, 0xe5, 0x56, + 0x7c, 0x93, 0x1d, 0xc5, 0x33, 0xcb, 0x27, 0xe1, 0xbe, 0xfc, 0xf9, 0x78, 0xb0, 0x3d, 0xe5, 0x95, + 0xd8, 0xb5, 0x6f, 0x04, 0xcb, 0xec, 0xdb, 0x58, 0x70, 0xbe, 0xcf, 0xc7, 0xe3, 0xd3, 0x29, 0xaf, + 0xa6, 0x73, 0x08, 0x74, 0x25, 0x1e, 0xcf, 0xee, 0xf3, 0xf1, 0x90, 0x6e, 0xca, 0x6b, 0xe9, 0x1c, + 0x02, 0xe9, 0xc6, 0x43, 0xc0, 0xbd, 0x24, 0x05, 0x99, 0x57, 0x3e, 0x1b, 0x35, 0x1d, 0x03, 0x04, + 0x33, 0x1d, 0xc3, 0x50, 0xf4, 0x2f, 0x49, 0xc1, 0xd9, 0x95, 0xd7, 0x13, 0x45, 0x82, 0xc6, 0x4a, + 0x21, 0xdc, 0x5f, 0x92, 0x82, 0x9a, 0x2b, 0x6f, 0x24, 0x8a, 0x04, 0xad, 0x93, 0x42, 0x9f, 0x1b, + 0xbd, 0xde, 0xaf, 0x2a, 0x6f, 0x46, 0x0f, 0x83, 0xb3, 0x29, 0xe7, 0xfa, 0xb4, 0x5e, 0xef, 0x60, + 0xbf, 0x9c, 0xed, 0xd8, 0xad, 0xbc, 0x15, 0x1d, 0xc2, 0x59, 0x74, 0x6c, 0x08, 0x67, 0x3a, 0x87, + 0xbf, 0x1d, 0x8b, 0x65, 0xa1, 0xbc, 0x1d, 0x9d, 0xe2, 0x22, 0x48, 0x36, 0xc5, 0xc5, 0x23, 0x5f, + 0x44, 0x82, 0x34, 0x28, 0x9f, 0x8b, 0x4e, 0x71, 0x32, 0x8e, 0x4d, 0x71, 0x91, 0x80, 0x0e, 0xd3, + 0x89, 0xd8, 0x01, 0xca, 0x3b, 0xd1, 0x29, 0x2e, 0x86, 0x66, 0x53, 0x5c, 0x3c, 0xda, 0xc0, 0xdb, + 0xb1, 0x27, 0xf4, 0xca, 0xe7, 0xd3, 0xdb, 0x8f, 0x48, 0xb9, 0xfd, 0xfc, 0xc1, 0xbd, 0x96, 0xfe, + 0x16, 0x5c, 0x29, 0x47, 0xc7, 0x6f, 0x1a, 0x0d, 0x1b, 0xbf, 0xa9, 0xef, 0xc8, 0xe3, 0x1b, 0x07, + 0xa1, 0x55, 0x53, 0x3d, 0x36, 0x0e, 0xa1, 0x29, 0x92, 0x02, 0x8e, 0xec, 0x91, 0xf9, 0x46, 0x68, + 0x3a, 0x63, 0x8f, 0xec, 0x6f, 0x83, 0x62, 0xf4, 0x6c, 0x76, 0x4d, 0xf8, 0x19, 0x2b, 0x95, 0xe8, + 0xec, 0x9a, 0x20, 0x60, 0xb3, 0x6b, 0xd2, 0x3b, 0x79, 0x16, 0xc6, 0x85, 0x16, 0x71, 0xf7, 0x69, + 0xd3, 0x6a, 0x2a, 0x33, 0xb1, 0xf7, 0x96, 0x31, 0x3c, 0x9b, 0x9d, 0xe2, 0x30, 0x5c, 0xaf, 0x39, + 0x6c, 0xba, 0x65, 0x76, 0x56, 0x6d, 0xdd, 0x31, 0x6a, 0xd4, 0x32, 0x94, 0xd9, 0xd8, 0x7a, 0x9d, + 0x42, 0x83, 0xeb, 0x75, 0x0a, 0x1c, 0x43, 0xc4, 0xc5, 0xe0, 0x1a, 0x6d, 0x50, 0xf3, 0x11, 0x55, + 0x6e, 0x23, 0xdb, 0xc9, 0x2c, 0xb6, 0x82, 0x6c, 0xae, 0x4f, 0xcb, 0xe2, 0xc0, 0x6c, 0xf5, 0x85, + 0xcd, 0xda, 0xbb, 0xf3, 0x41, 0xf8, 0x81, 0x65, 0x87, 0x76, 0x74, 0x87, 0x2a, 0x73, 0x51, 0x5b, + 0x3d, 0x95, 0x88, 0xd9, 0xea, 0xa9, 0x88, 0x24, 0x5b, 0x7f, 0x2c, 0x54, 0x7b, 0xb1, 0x0d, 0x47, + 0x44, 0x7a, 0x69, 0x36, 0x3b, 0x45, 0x11, 0x4c, 0x40, 0xf3, 0xb6, 0xd5, 0xc4, 0x93, 0x8a, 0x3b, + 0xd1, 0xd9, 0x29, 0x9b, 0x92, 0xcd, 0x4e, 0xd9, 0x58, 0xa6, 0xea, 0x51, 0x2c, 0x1f, 0x83, 0x77, + 0xa3, 0xaa, 0x9e, 0x42, 0xc2, 0x54, 0x3d, 0x05, 0x9c, 0x64, 0xa8, 0x51, 0x97, 0x7a, 0xca, 0x7c, + 0x2f, 0x86, 0x48, 0x92, 0x64, 0x88, 0xe0, 0x24, 0xc3, 0x59, 0xea, 0x35, 0xd6, 0x95, 0x85, 0x5e, + 0x0c, 0x91, 0x24, 0xc9, 0x10, 0xc1, 0x6c, 0xb3, 0x19, 0x05, 0x4f, 0x75, 0x5b, 0x0f, 0xfd, 0x3e, + 0x5b, 0x8c, 0x6e, 0x36, 0x33, 0x09, 0xd9, 0x66, 0x33, 0x13, 0x49, 0x7e, 0x6c, 0xd7, 0x7e, 0xf0, + 0xca, 0x12, 0x56, 0x78, 0x3d, 0xb4, 0x0b, 0x76, 0x53, 0x6a, 0xae, 0x4f, 0xdb, 0xad, 0x9f, 0xfd, + 0xa7, 0x03, 0xa7, 0x51, 0x65, 0x19, 0xab, 0x3a, 0x15, 0x9c, 0x55, 0x70, 0xf0, 0x5c, 0x9f, 0x16, + 0xb8, 0x95, 0xbe, 0x06, 0xc3, 0xf8, 0x51, 0x55, 0xcb, 0xf4, 0x2a, 0x53, 0xca, 0xbb, 0xd1, 0x2d, + 0x93, 0x84, 0x62, 0x5b, 0x26, 0xe9, 0x27, 0x9b, 0xc4, 0xf1, 0x27, 0x9f, 0x62, 0x2a, 0x53, 0x8a, + 0x16, 0x9d, 0xc4, 0x23, 0x48, 0x36, 0x89, 0x47, 0x00, 0x41, 0xbd, 0x15, 0xc7, 0xee, 0x54, 0xa6, + 0x94, 0x5a, 0x4a, 0xbd, 0x1c, 0x15, 0xd4, 0xcb, 0x7f, 0x06, 0xf5, 0xd6, 0xd6, 0xbb, 0x5e, 0x85, + 0x7d, 0xe3, 0x4a, 0x4a, 0xbd, 0x3e, 0x32, 0xa8, 0xd7, 0x07, 0xb0, 0xa9, 0x10, 0x01, 0xcb, 0x8e, + 0xcd, 0x26, 0xed, 0xbb, 0x66, 0xab, 0xa5, 0xdc, 0x8b, 0x4e, 0x85, 0x71, 0x3c, 0x9b, 0x0a, 0xe3, + 0x30, 0x66, 0x7a, 0xf2, 0x56, 0xd1, 0xd5, 0x6e, 0x53, 0xb9, 0x1f, 0x35, 0x3d, 0x43, 0x0c, 0x33, + 0x3d, 0xc3, 0x5f, 0xb8, 0xbb, 0x60, 0xbf, 0x34, 0xba, 0xe6, 0x50, 0x77, 0x5d, 0x79, 0x10, 0xdb, + 0x5d, 0x48, 0x38, 0xdc, 0x5d, 0x48, 0xbf, 0x49, 0x13, 0x9e, 0x8a, 0x2c, 0x34, 0xfe, 0xa5, 0x4d, + 0x8d, 0xea, 0x4e, 0x63, 0x5d, 0xf9, 0x02, 0xb2, 0x7a, 0x2e, 0x75, 0xa9, 0x8a, 0x92, 0xce, 0xf5, + 0x69, 0xbd, 0x38, 0xe1, 0xb6, 0xfc, 0xdd, 0x79, 0x1e, 0x09, 0x56, 0x5b, 0x9e, 0xf6, 0x37, 0xa1, + 0xef, 0xc5, 0xb6, 0xe5, 0x49, 0x12, 0xdc, 0x96, 0x27, 0xc1, 0xa4, 0x03, 0x97, 0x63, 0x5b, 0xb5, + 0x05, 0xbd, 0xc5, 0xf6, 0x25, 0xd4, 0x58, 0xd6, 0x1b, 0x0f, 0xa9, 0xa7, 0x7c, 0x11, 0x79, 0x5f, + 0xc9, 0xd8, 0xf0, 0xc5, 0xa8, 0xe7, 0xfa, 0xb4, 0x1d, 0xf8, 0x11, 0x15, 0x8a, 0xb5, 0xd9, 0x95, + 0x65, 0xe5, 0xfb, 0xa2, 0xe7, 0x9b, 0x0c, 0x36, 0xd7, 0xa7, 0x21, 0x8e, 0x59, 0x69, 0xf7, 0x3a, + 0x4d, 0x47, 0x37, 0x28, 0x37, 0xb4, 0xd0, 0x76, 0x13, 0x06, 0xe8, 0xf7, 0x47, 0xad, 0xb4, 0x2c, + 0x3a, 0x66, 0xa5, 0x65, 0xe1, 0x98, 0xa2, 0x46, 0x92, 0x9e, 0x28, 0x5f, 0x8a, 0x2a, 0x6a, 0x04, + 0xc9, 0x14, 0x35, 0x9a, 0x22, 0xe5, 0x0b, 0x70, 0x2e, 0xd8, 0xcf, 0x8b, 0xf5, 0x97, 0x77, 0x9a, + 0xf2, 0x65, 0xe4, 0x73, 0x39, 0x71, 0x19, 0x10, 0xa1, 0x9a, 0xeb, 0xd3, 0x32, 0xca, 0xb3, 0x15, + 0x37, 0x91, 0xcf, 0x4b, 0x98, 0x17, 0x3f, 0x10, 0x5d, 0x71, 0x33, 0xc8, 0xd8, 0x8a, 0x9b, 0x81, + 0x4a, 0x65, 0x2e, 0x84, 0xaa, 0xef, 0xc0, 0x3c, 0x90, 0x69, 0x16, 0x87, 0x54, 0xe6, 0xc2, 0x52, + 0x5b, 0xdd, 0x81, 0x79, 0x60, 0xad, 0x65, 0x71, 0x20, 0x57, 0xa1, 0x54, 0xab, 0x2d, 0x68, 0x5d, + 0x4b, 0x69, 0xc4, 0xbc, 0x65, 0x11, 0x3a, 0xd7, 0xa7, 0x09, 0x3c, 0x33, 0x83, 0x66, 0x5a, 0xba, + 0xeb, 0x99, 0x0d, 0x17, 0x47, 0x8c, 0x3f, 0x42, 0x8c, 0xa8, 0x19, 0x94, 0x46, 0xc3, 0xcc, 0xa0, + 0x34, 0x38, 0xb3, 0x17, 0xa7, 0x75, 0xd7, 0xd5, 0x2d, 0xc3, 0xd1, 0xa7, 0x70, 0x99, 0xa0, 0xb1, + 0xd7, 0x58, 0x11, 0x2c, 0xb3, 0x17, 0xa3, 0x10, 0x3c, 0x7c, 0xf7, 0x21, 0xbe, 0x99, 0xb3, 0x16, + 0x3b, 0x7c, 0x8f, 0xe1, 0xf1, 0xf0, 0x3d, 0x06, 0x43, 0xbb, 0xd3, 0x87, 0x69, 0xb4, 0x69, 0x32, + 0x11, 0x29, 0xcd, 0x98, 0xdd, 0x19, 0x27, 0x40, 0xbb, 0x33, 0x0e, 0x8c, 0x34, 0xc9, 0x5f, 0x6e, + 0xd7, 0x33, 0x9a, 0x14, 0xae, 0xb2, 0x89, 0x32, 0x6c, 0xfd, 0x0e, 0x07, 0x47, 0x65, 0xd3, 0xd2, + 0xdb, 0x76, 0x65, 0xca, 0x97, 0xba, 0x19, 0x5d, 0xbf, 0x33, 0x09, 0xd9, 0xfa, 0x9d, 0x89, 0x64, + 0xb3, 0xab, 0xbf, 0xd1, 0x5a, 0xd7, 0x1d, 0x6a, 0x54, 0x4c, 0x07, 0x4f, 0x16, 0x37, 0xf9, 0xd6, + 0xf0, 0xfd, 0xe8, 0xec, 0xda, 0x83, 0x94, 0xcd, 0xae, 0x3d, 0xd0, 0xcc, 0xc8, 0x4b, 0x47, 0x6b, + 0x54, 0x37, 0x94, 0x87, 0x51, 0x23, 0x2f, 0x9b, 0x92, 0x19, 0x79, 0xd9, 0xd8, 0xec, 0xcf, 0x79, + 0xe0, 0x98, 0x1e, 0x55, 0x5a, 0xbb, 0xf9, 0x1c, 0x24, 0xcd, 0xfe, 0x1c, 0x44, 0xb3, 0x0d, 0x61, + 0xbc, 0x43, 0xda, 0xd1, 0x0d, 0x61, 0xb2, 0x1b, 0xe2, 0x25, 0x98, 0xc5, 0x22, 0x1e, 0xe5, 0x29, + 0x56, 0xd4, 0x62, 0x11, 0x60, 0x66, 0xb1, 0x84, 0xcf, 0xf6, 0x22, 0x4f, 0xb1, 0x14, 0x3b, 0xba, + 0x86, 0xca, 0x38, 0xb6, 0x86, 0x46, 0x9e, 0x6d, 0xbd, 0x16, 0x79, 0x67, 0xa0, 0x74, 0xa2, 0x56, + 0x87, 0x84, 0x62, 0x56, 0x87, 0xfc, 0x22, 0x61, 0x1a, 0x4e, 0xe1, 0x2d, 0xb8, 0xd6, 0x0d, 0xee, + 0x71, 0x7e, 0x30, 0xfa, 0x99, 0x31, 0x34, 0xfb, 0xcc, 0x18, 0x28, 0xc2, 0x44, 0x4c, 0x5b, 0x4e, + 0x06, 0x93, 0xf0, 0x7c, 0x30, 0x06, 0x22, 0xf3, 0x40, 0x6a, 0xe5, 0x85, 0xf9, 0xaa, 0xb1, 0x2c, + 0x5f, 0x91, 0xb9, 0xd1, 0x13, 0xd8, 0x24, 0xc5, 0x5c, 0x9f, 0x96, 0x52, 0x8e, 0xbc, 0x0f, 0x97, + 0x04, 0x54, 0xbc, 0xb8, 0xc6, 0xb4, 0xff, 0x46, 0xb0, 0x20, 0x78, 0x51, 0x3f, 0xb6, 0x5e, 0xb4, + 0x73, 0x7d, 0x5a, 0x4f, 0x5e, 0xd9, 0x75, 0x89, 0xf5, 0xa1, 0xbb, 0x9b, 0xba, 0x82, 0x45, 0xa2, + 0x27, 0xaf, 0xec, 0xba, 0x84, 0xdc, 0x1f, 0xed, 0xa6, 0xae, 0xa0, 0x13, 0x7a, 0xf2, 0x22, 0x2e, + 0x4c, 0xf6, 0xc2, 0x97, 0x5b, 0x2d, 0x65, 0x03, 0xab, 0xfb, 0xd4, 0x6e, 0xaa, 0x2b, 0xa3, 0xc1, + 0xb9, 0x13, 0x47, 0x36, 0x4b, 0x2f, 0x75, 0xa8, 0x55, 0x8b, 0x2c, 0x40, 0x8f, 0xa3, 0xb3, 0x74, + 0x82, 0x80, 0xcd, 0xd2, 0x09, 0x20, 0x1b, 0x50, 0xf2, 0x73, 0x15, 0x65, 0x33, 0x3a, 0xa0, 0x64, + 0x1c, 0x1b, 0x50, 0x91, 0xa7, 0x2d, 0x4b, 0x70, 0x7a, 0xe9, 0xa1, 0xa7, 0xfb, 0x16, 0xa4, 0x2b, + 0xba, 0xf2, 0x83, 0xd8, 0x25, 0x53, 0x92, 0x04, 0x2f, 0x99, 0x92, 0x60, 0x36, 0x46, 0x18, 0xb8, + 0xb6, 0x69, 0x35, 0x66, 0x75, 0xb3, 0xd5, 0x75, 0xa8, 0xf2, 0x6f, 0x44, 0xc7, 0x48, 0x0c, 0xcd, + 0xc6, 0x48, 0x0c, 0xc4, 0x16, 0x68, 0x06, 0x2a, 0xbb, 0xae, 0xd9, 0xb4, 0xc4, 0xbe, 0xb2, 0xdb, + 0xf2, 0x94, 0x7f, 0x33, 0xba, 0x40, 0xa7, 0xd1, 0xb0, 0x05, 0x3a, 0x0d, 0x8e, 0xa7, 0x4e, 0xac, + 0x17, 0xd8, 0xe2, 0x21, 0xdf, 0x55, 0xfe, 0x5b, 0xb1, 0x53, 0xa7, 0x14, 0x1a, 0x3c, 0x75, 0x4a, + 0x81, 0xb3, 0xf5, 0x91, 0xdb, 0x64, 0xf3, 0x66, 0x70, 0x57, 0xfd, 0x6f, 0x47, 0xd7, 0xc7, 0x38, + 0x9e, 0xad, 0x8f, 0x71, 0x58, 0x94, 0x8f, 0xe8, 0x82, 0x7f, 0x27, 0x8b, 0x4f, 0x20, 0xff, 0x44, + 0x19, 0x72, 0x5b, 0xe6, 0x23, 0x46, 0xca, 0x0f, 0xe5, 0xb2, 0x18, 0x05, 0xc3, 0x23, 0x51, 0x28, + 0xca, 0x48, 0xa3, 0x8f, 0x4c, 0xba, 0xa1, 0x7c, 0x25, 0x93, 0x11, 0x27, 0x88, 0x32, 0xe2, 0x30, + 0xf2, 0x1e, 0x9c, 0x0b, 0x61, 0x0b, 0xb4, 0xbd, 0x1a, 0xcc, 0x4c, 0x3f, 0x9c, 0x8b, 0x9a, 0xc1, + 0xe9, 0x64, 0xcc, 0x0c, 0x4e, 0xc7, 0xa4, 0xb1, 0x16, 0xa2, 0xfb, 0x77, 0x77, 0x60, 0x1d, 0x48, + 0x30, 0x83, 0x41, 0x1a, 0x6b, 0x21, 0xcd, 0x1f, 0xd9, 0x81, 0x75, 0x20, 0xd3, 0x0c, 0x06, 0xe4, + 0xc7, 0x73, 0x70, 0x25, 0x1d, 0x55, 0x6e, 0xb5, 0x66, 0x6d, 0x27, 0xc4, 0x29, 0x7f, 0x2a, 0x17, + 0x3d, 0x68, 0xd8, 0x5d, 0xb1, 0xb9, 0x3e, 0x6d, 0x97, 0x15, 0x90, 0xcf, 0xc1, 0x68, 0xb9, 0x6b, + 0x98, 0x1e, 0x5e, 0xbc, 0x31, 0xc3, 0xf9, 0x47, 0x73, 0xb1, 0x2d, 0x8e, 0x8c, 0xc5, 0x2d, 0x8e, + 0x0c, 0x20, 0x77, 0x60, 0xa2, 0x46, 0x1b, 0x5d, 0xc7, 0xf4, 0x36, 0x35, 0xda, 0xb1, 0x1d, 0x8f, + 0xf1, 0xf8, 0xd3, 0xb9, 0xe8, 0x24, 0x96, 0xa0, 0x60, 0x93, 0x58, 0x02, 0x48, 0xee, 0x27, 0x6e, + 0xe5, 0x45, 0x67, 0xfe, 0x58, 0xae, 0xe7, 0xb5, 0x7c, 0xd0, 0x97, 0xe9, 0xc5, 0xc9, 0x72, 0xec, + 0x16, 0x5d, 0x70, 0xfd, 0xf1, 0x5c, 0x8f, 0x6b, 0x74, 0x69, 0x86, 0x4b, 0x82, 0x19, 0xc7, 0x94, + 0x0c, 0xf0, 0xca, 0x9f, 0xc9, 0xf5, 0xb8, 0xf6, 0x0e, 0x39, 0xa6, 0x25, 0x8f, 0x7f, 0x85, 0x7b, + 0x8a, 0x08, 0x46, 0x3f, 0x91, 0x4b, 0xba, 0x8a, 0x04, 0xe5, 0x25, 0x42, 0x56, 0xec, 0x9e, 0x1b, + 0x28, 0xfd, 0x57, 0x73, 0x49, 0xdf, 0xbc, 0xb0, 0x58, 0xf8, 0x8b, 0x50, 0xb8, 0x38, 0xf3, 0xd8, + 0xa3, 0x8e, 0xa5, 0xb7, 0xb0, 0x3b, 0x6b, 0x9e, 0xed, 0xe8, 0x4d, 0x3a, 0x63, 0xe9, 0xab, 0x2d, + 0xaa, 0xfc, 0x64, 0x2e, 0x6a, 0xc1, 0x66, 0x93, 0x32, 0x0b, 0x36, 0x1b, 0x4b, 0xd6, 0xe1, 0xa9, + 0x34, 0x6c, 0xc5, 0x74, 0xb1, 0x9e, 0xaf, 0xe5, 0xa2, 0x26, 0x6c, 0x0f, 0x5a, 0x66, 0xc2, 0xf6, + 0x40, 0x93, 0x9b, 0x30, 0x34, 0x65, 0xfb, 0xd3, 0xef, 0x9f, 0x8d, 0x39, 0x43, 0x06, 0x98, 0xb9, + 0x3e, 0x2d, 0x24, 0x13, 0x65, 0xc4, 0xa0, 0xfe, 0x7a, 0xb2, 0x4c, 0x78, 0xf9, 0x14, 0xfc, 0x10, + 0x65, 0x84, 0xb8, 0xff, 0xbd, 0x64, 0x99, 0xf0, 0x8e, 0x2b, 0xf8, 0xc1, 0x66, 0x12, 0x5e, 0xe3, + 0xc2, 0x6c, 0x99, 0xd9, 0x6d, 0xd3, 0xeb, 0x7a, 0xab, 0x45, 0xad, 0x26, 0x55, 0xbe, 0x11, 0x9b, + 0x49, 0xd2, 0xc9, 0xd8, 0x4c, 0x92, 0x8e, 0x21, 0xdf, 0x0f, 0xe7, 0xef, 0xeb, 0x2d, 0xd3, 0x08, + 0x71, 0x7e, 0x3e, 0x70, 0xe5, 0xa7, 0x72, 0xd1, 0xdd, 0x74, 0x06, 0x1d, 0xdb, 0x4d, 0x67, 0xa0, + 0xc8, 0x02, 0x10, 0x5c, 0x46, 0x83, 0xd9, 0x82, 0xad, 0xcf, 0xca, 0xbf, 0x9f, 0x8b, 0xda, 0xa9, + 0x49, 0x12, 0x66, 0xa7, 0x26, 0xa1, 0xa4, 0x9e, 0x9d, 0x1a, 0x44, 0xf9, 0xe9, 0x5c, 0xf4, 0xb4, + 0x26, 0x8b, 0x70, 0xae, 0x4f, 0xcb, 0xce, 0x2f, 0x72, 0x1b, 0xc6, 0x6b, 0xcb, 0xd5, 0xd9, 0xd9, + 0x99, 0xda, 0xfd, 0x6a, 0x05, 0x1f, 0x3a, 0x18, 0xca, 0x9f, 0x8b, 0xad, 0x58, 0x71, 0x02, 0xb6, + 0x62, 0xc5, 0x61, 0xe4, 0x4d, 0x18, 0x61, 0xed, 0x67, 0x03, 0x06, 0x3f, 0xf9, 0x67, 0x72, 0x51, + 0x73, 0x4a, 0x46, 0x32, 0x73, 0x4a, 0xfe, 0x4d, 0x6a, 0x70, 0x86, 0x49, 0x71, 0xd9, 0xa1, 0x6b, + 0xd4, 0xa1, 0x56, 0xc3, 0x1f, 0xd3, 0x3f, 0x9b, 0x8b, 0x5a, 0x19, 0x69, 0x44, 0xcc, 0xca, 0x48, + 0x83, 0x93, 0x87, 0x70, 0x29, 0x7e, 0x12, 0x24, 0x3f, 0x3b, 0x55, 0xfe, 0x7c, 0x2e, 0x66, 0x0c, + 0xf7, 0x20, 0x46, 0x63, 0xb8, 0x07, 0x9e, 0x58, 0xf0, 0xb4, 0x38, 0x56, 0x11, 0x0e, 0x97, 0xf1, + 0xda, 0xfe, 0x02, 0xaf, 0xed, 0x93, 0xa1, 0x43, 0x60, 0x0f, 0xea, 0xb9, 0x3e, 0xad, 0x37, 0x3b, + 0xa6, 0x67, 0xc9, 0x04, 0x18, 0xca, 0x5f, 0xcc, 0xa5, 0x7b, 0xa4, 0x44, 0xdc, 0x94, 0xd3, 0x32, + 0x67, 0xbc, 0x97, 0x95, 0xbe, 0x41, 0xf9, 0x4b, 0xb1, 0xf1, 0x96, 0x4e, 0xc6, 0xc6, 0x5b, 0x46, + 0xfe, 0x87, 0x3b, 0x30, 0xc1, 0x95, 0x7a, 0x59, 0xc7, 0x61, 0x68, 0x35, 0xa9, 0xa1, 0xfc, 0x07, + 0xb1, 0xd5, 0x2e, 0x41, 0x81, 0xae, 0x3d, 0x71, 0x20, 0x9b, 0xba, 0x6b, 0x1d, 0xdd, 0xb2, 0xf0, + 0x98, 0x55, 0xf9, 0x0f, 0x63, 0x53, 0x77, 0x88, 0x42, 0xc7, 0xdd, 0xe0, 0x17, 0xd3, 0x84, 0x5e, + 0xa9, 0x8f, 0x94, 0xbf, 0x1c, 0xd3, 0x84, 0x5e, 0xc4, 0x4c, 0x13, 0x7a, 0xe6, 0x51, 0xba, 0x9f, + 0xf1, 0x04, 0x5c, 0xf9, 0xb9, 0xd8, 0x8a, 0x9c, 0x4a, 0xc5, 0x56, 0xe4, 0xf4, 0x17, 0xe4, 0xf7, + 0x33, 0x9e, 0x4f, 0x2b, 0x3f, 0xdf, 0x9b, 0x6f, 0xb8, 0xd2, 0xa7, 0xbf, 0xbe, 0xbe, 0x9f, 0xf1, + 0xf4, 0x58, 0xf9, 0x2b, 0xbd, 0xf9, 0x86, 0x8e, 0x7d, 0xe9, 0x2f, 0x97, 0xeb, 0xd9, 0xcf, 0x76, + 0x95, 0xbf, 0x1a, 0x9f, 0xba, 0x32, 0x08, 0x71, 0xea, 0xca, 0x7a, 0xfb, 0xbb, 0x0a, 0x17, 0xb8, + 0x86, 0xdc, 0x76, 0xf4, 0xce, 0x7a, 0x8d, 0x7a, 0x9e, 0x69, 0x35, 0xfd, 0x9d, 0xd8, 0x5f, 0xcb, + 0xc5, 0x8e, 0xc7, 0xb2, 0x28, 0xf1, 0x78, 0x2c, 0x0b, 0xc9, 0x94, 0x37, 0xf1, 0x40, 0x57, 0xf9, + 0xeb, 0x31, 0xe5, 0x4d, 0x50, 0x30, 0xe5, 0x4d, 0xbe, 0xeb, 0xbd, 0x93, 0xf2, 0x0e, 0x55, 0xf9, + 0x8f, 0xb2, 0x79, 0x05, 0xed, 0x4b, 0x79, 0xbe, 0x7a, 0x27, 0xe5, 0xb9, 0xa5, 0xf2, 0x1f, 0x67, + 0xf3, 0x0a, 0x7d, 0x90, 0x92, 0xaf, 0x34, 0xdf, 0x83, 0x73, 0x7c, 0x36, 0x9f, 0xa5, 0x06, 0x8d, + 0x7c, 0xe8, 0x2f, 0xc4, 0xc6, 0x7e, 0x3a, 0x19, 0x1e, 0xb9, 0xa7, 0x62, 0xd2, 0x58, 0x8b, 0xb6, + 0xfe, 0x8d, 0x1d, 0x58, 0x87, 0x1b, 0x82, 0x74, 0x0c, 0x5b, 0x6f, 0xe4, 0xc7, 0x6f, 0xca, 0x2f, + 0xc6, 0xd6, 0x1b, 0x19, 0x89, 0xee, 0x1c, 0xf2, 0x4b, 0xb9, 0x37, 0xa3, 0x0f, 0xbd, 0x94, 0xbf, + 0x99, 0x5a, 0x38, 0xe8, 0x80, 0xe8, 0xab, 0xb0, 0x37, 0xa3, 0x8f, 0x9a, 0x94, 0x5f, 0x4a, 0x2d, + 0x1c, 0x7c, 0x40, 0xf4, 0x05, 0x14, 0xdb, 0x22, 0x75, 0x3d, 0x9b, 0xb3, 0x8a, 0x4c, 0x0f, 0x7f, + 0x2b, 0xbe, 0x45, 0x4a, 0x25, 0xc3, 0x2d, 0x52, 0x2a, 0x26, 0x8d, 0xb5, 0xf8, 0xbc, 0x5f, 0xde, + 0x81, 0xb5, 0xb4, 0xb1, 0x4b, 0xc5, 0xa4, 0xb1, 0x16, 0x1f, 0xff, 0x2b, 0x3b, 0xb0, 0x96, 0x36, + 0x76, 0xa9, 0x18, 0x66, 0x8e, 0x85, 0x98, 0xfb, 0xd4, 0x71, 0x43, 0xf5, 0xfb, 0xdb, 0x31, 0x73, + 0x2c, 0x83, 0x8e, 0x99, 0x63, 0x19, 0xa8, 0x54, 0xee, 0x42, 0x28, 0xbf, 0xba, 0x13, 0xf7, 0xf0, + 0x5e, 0x26, 0x03, 0x95, 0xca, 0x5d, 0xc8, 0xe5, 0xef, 0xec, 0xc4, 0x3d, 0xbc, 0x98, 0xc9, 0x40, + 0x31, 0xa3, 0xa8, 0xe6, 0xe9, 0x9e, 0xd9, 0x98, 0xb3, 0x5d, 0x4f, 0x5a, 0xe4, 0xff, 0x6e, 0xcc, + 0x28, 0x4a, 0x23, 0x62, 0x46, 0x51, 0x1a, 0x3c, 0xc9, 0x54, 0x48, 0xe3, 0xd7, 0x7a, 0x32, 0x0d, + 0x2d, 0xad, 0x34, 0x78, 0x92, 0xa9, 0x10, 0xc2, 0x7f, 0xd2, 0x93, 0x69, 0xe8, 0x29, 0x9f, 0x06, + 0x67, 0x96, 0xe9, 0xb4, 0x63, 0x6f, 0x58, 0x77, 0xe8, 0x06, 0x6d, 0x89, 0x4f, 0xff, 0xf5, 0x98, + 0x65, 0x1a, 0x27, 0xc0, 0x5b, 0x94, 0x18, 0x2c, 0xca, 0x48, 0x7c, 0xee, 0x6f, 0x64, 0x32, 0x0a, + 0x8f, 0x89, 0xe2, 0xb0, 0x28, 0x23, 0xf1, 0x89, 0xbf, 0x99, 0xc9, 0x28, 0x3c, 0x26, 0x8a, 0xc3, + 0x48, 0x19, 0xc6, 0xf0, 0xad, 0x84, 0xee, 0xfa, 0x9e, 0x9f, 0xbf, 0x93, 0x8b, 0xde, 0x7a, 0x45, + 0xd1, 0x73, 0x7d, 0x5a, 0xac, 0x80, 0xcc, 0x42, 0x7c, 0xd2, 0xb7, 0x32, 0x58, 0x84, 0xfe, 0x8e, + 0x51, 0x88, 0xcc, 0x42, 0x7c, 0xcc, 0x7f, 0x9a, 0xc1, 0x22, 0x74, 0x78, 0x8c, 0x42, 0xc8, 0x67, + 0x61, 0xb8, 0x36, 0xbb, 0xb2, 0xec, 0xa7, 0xe7, 0xfb, 0x7b, 0xb9, 0xd8, 0xab, 0xa2, 0x10, 0x87, + 0xaf, 0x8a, 0xc2, 0x9f, 0x53, 0x03, 0xd0, 0x8f, 0x47, 0xa9, 0x77, 0x4a, 0x83, 0xdf, 0xcc, 0x8d, + 0xff, 0x56, 0xee, 0x4e, 0x69, 0xf0, 0xb7, 0x72, 0xe3, 0xbf, 0xcd, 0xfe, 0xff, 0xed, 0xdc, 0xf8, + 0xef, 0xe4, 0xb4, 0x0b, 0xe1, 0xb0, 0x28, 0x37, 0xa9, 0xe5, 0x2d, 0xb7, 0x74, 0x31, 0xa8, 0x53, + 0x51, 0xfc, 0x67, 0x2a, 0x4a, 0xa4, 0xc2, 0xfa, 0xb9, 0x1c, 0x8c, 0xd4, 0x3c, 0x87, 0xea, 0x6d, + 0x11, 0x59, 0xee, 0x22, 0x0c, 0x72, 0xe7, 0x67, 0xff, 0xa5, 0xb6, 0x16, 0xfc, 0x26, 0x57, 0x60, + 0x6c, 0x5e, 0x77, 0x3d, 0x6c, 0x62, 0xd5, 0x32, 0xe8, 0x63, 0x7c, 0xf8, 0x57, 0xd0, 0x62, 0x50, + 0x32, 0xcf, 0xe9, 0x78, 0x39, 0x0c, 0x26, 0x5a, 0xd8, 0x31, 0xa0, 0xda, 0xe0, 0x77, 0xb6, 0x26, + 0xfb, 0x30, 0x7e, 0x5a, 0xac, 0xac, 0xfa, 0xbb, 0x39, 0x48, 0xb8, 0x65, 0xef, 0x3f, 0x82, 0xc2, + 0x12, 0x9c, 0x8a, 0x05, 0xb0, 0x15, 0xaf, 0x17, 0x77, 0x19, 0xdf, 0x36, 0x5e, 0x9a, 0x7c, 0x2a, + 0x78, 0x35, 0x77, 0x4f, 0x9b, 0x17, 0xc1, 0xf2, 0x30, 0xcd, 0x43, 0xd7, 0x69, 0x69, 0x12, 0x4a, + 0x04, 0x43, 0xfa, 0xde, 0x78, 0x18, 0x9d, 0x93, 0x5c, 0x11, 0xe1, 0x1c, 0x72, 0x61, 0x88, 0xbd, + 0x58, 0x52, 0x79, 0x1e, 0xbe, 0xe1, 0x73, 0x30, 0x52, 0x6d, 0x77, 0xa8, 0xe3, 0xda, 0x96, 0xee, + 0xd9, 0x8e, 0x78, 0x0d, 0x8f, 0xe1, 0xd7, 0x4c, 0x09, 0x2e, 0x87, 0x04, 0x93, 0xe9, 0xc9, 0x35, + 0x3f, 0x53, 0x5d, 0x01, 0xe3, 0xa2, 0xe2, 0x93, 0xd6, 0x78, 0xa2, 0x72, 0x4e, 0xc1, 0x48, 0xef, + 0xb9, 0x3a, 0xbe, 0xaf, 0x0c, 0x48, 0xbb, 0x0c, 0x20, 0x93, 0x22, 0x05, 0x79, 0x01, 0x4a, 0x78, + 0x1f, 0xe5, 0x62, 0x06, 0x4a, 0x11, 0xf8, 0xaf, 0x85, 0x10, 0x39, 0xcc, 0x1a, 0xa7, 0x21, 0x77, + 0x61, 0x3c, 0xbc, 0x6c, 0xbf, 0xed, 0xd8, 0xdd, 0x8e, 0x9f, 0x73, 0x06, 0x13, 0xbc, 0x3f, 0x0c, + 0x70, 0xf5, 0x26, 0x22, 0x25, 0x16, 0x89, 0x82, 0x64, 0x0e, 0x4e, 0x85, 0x30, 0x26, 0x22, 0x3f, + 0xd7, 0x15, 0xe6, 0x19, 0x95, 0x78, 0x31, 0x71, 0x46, 0xf2, 0x8c, 0xc6, 0x8a, 0x91, 0x2a, 0x0c, + 0xf8, 0x51, 0xff, 0x06, 0x77, 0x54, 0xd2, 0xd3, 0x22, 0xea, 0xdf, 0x80, 0x1c, 0xef, 0xcf, 0x2f, + 0x4f, 0x66, 0x61, 0x4c, 0xb3, 0xbb, 0x1e, 0x5d, 0xb1, 0xc5, 0x2e, 0x55, 0x44, 0x97, 0xc4, 0x36, + 0x39, 0x0c, 0x53, 0xf7, 0x6c, 0x3f, 0x3f, 0xbe, 0x9c, 0xa7, 0x3d, 0x5a, 0x8a, 0x2c, 0xc2, 0x44, + 0xc2, 0x2d, 0x41, 0xce, 0x5a, 0x2f, 0x7d, 0x5e, 0x92, 0x59, 0xb2, 0x28, 0xf9, 0xd1, 0x1c, 0x94, + 0x56, 0x1c, 0xdd, 0xf4, 0x5c, 0xf1, 0x34, 0xf3, 0xec, 0xf5, 0x0d, 0x47, 0xef, 0x30, 0xfd, 0xb8, + 0x8e, 0x81, 0x6f, 0xef, 0xeb, 0xad, 0x2e, 0x75, 0xa7, 0x1e, 0xb0, 0xaf, 0xfb, 0xef, 0xb7, 0x26, + 0xdf, 0x6c, 0xe2, 0xe1, 0xe7, 0xf5, 0x86, 0xdd, 0xbe, 0xd1, 0x74, 0xf4, 0x47, 0xa6, 0x87, 0x26, + 0xa6, 0xde, 0xba, 0xe1, 0xd1, 0x16, 0x9e, 0xb1, 0xde, 0xd0, 0x3b, 0xe6, 0x0d, 0x0c, 0xb0, 0x7e, + 0x23, 0xe0, 0xc4, 0x6b, 0x60, 0x2a, 0xe0, 0xe1, 0x5f, 0xb2, 0x0a, 0x70, 0x1c, 0x59, 0x04, 0x10, + 0x9f, 0x5a, 0xee, 0x74, 0xc4, 0x3b, 0x4f, 0xe9, 0x64, 0xd2, 0xc7, 0x70, 0xc5, 0x0e, 0x04, 0xa6, + 0x77, 0xa4, 0xa0, 0xc2, 0x9a, 0xc4, 0x81, 0x69, 0xc1, 0x8a, 0x68, 0x91, 0x2f, 0xa6, 0xd1, 0x50, + 0xe2, 0x7e, 0x63, 0x53, 0x84, 0x14, 0x2f, 0x46, 0x56, 0xe1, 0x94, 0xe0, 0x1b, 0xa4, 0x20, 0x19, + 0x8b, 0xce, 0x0a, 0x31, 0x34, 0x57, 0xda, 0xa0, 0x8d, 0x86, 0x00, 0xcb, 0x75, 0xc4, 0x4a, 0x90, + 0xa9, 0x30, 0x65, 0xf2, 0xa2, 0xde, 0xa6, 0xae, 0x72, 0x0a, 0x35, 0xf6, 0xd2, 0xf6, 0xd6, 0xa4, + 0xe2, 0x97, 0xc7, 0x00, 0x98, 0xb2, 0xe8, 0xa2, 0x45, 0x64, 0x1e, 0x5c, 0xeb, 0xc7, 0x53, 0x78, + 0xc4, 0x75, 0x3e, 0x5a, 0x84, 0x4c, 0xc3, 0x68, 0xf0, 0xcc, 0xe4, 0xde, 0xbd, 0x6a, 0x05, 0x1f, + 0x92, 0x8a, 0x18, 0xa8, 0xb1, 0x24, 0x21, 0x32, 0x93, 0x48, 0x19, 0x29, 0x36, 0x07, 0x7f, 0x59, + 0x1a, 0x8b, 0xcd, 0xd1, 0x49, 0x89, 0xcd, 0xb1, 0x4c, 0xde, 0x86, 0xe1, 0xf2, 0x83, 0x9a, 0x88, + 0x39, 0xe2, 0x2a, 0xa7, 0xc3, 0x8c, 0x53, 0xfa, 0x86, 0x5b, 0xf7, 0xe3, 0x93, 0xc8, 0x4d, 0x97, + 0xe9, 0xc9, 0x0c, 0x8c, 0x45, 0x3c, 0xd5, 0x5c, 0xe5, 0x0c, 0x72, 0xc0, 0x96, 0xeb, 0x88, 0xa9, + 0x3b, 0x02, 0x25, 0x0f, 0xaf, 0x68, 0x21, 0xa6, 0x35, 0x15, 0xd3, 0xc5, 0xec, 0x3d, 0x1a, 0xc5, + 0xf0, 0x26, 0xf8, 0x2c, 0x75, 0x90, 0x6b, 0x8d, 0x21, 0x50, 0x75, 0x87, 0xe3, 0xe4, 0x1e, 0x8d, + 0x15, 0x23, 0xef, 0x03, 0xc1, 0x7c, 0x3f, 0xd4, 0xf0, 0x2f, 0x2e, 0xab, 0x15, 0x57, 0x39, 0x87, + 0x01, 0xc0, 0x49, 0x3c, 0x9c, 0x42, 0xb5, 0x32, 0x75, 0x45, 0x4c, 0x1f, 0x97, 0x75, 0x5e, 0xaa, + 0xee, 0x87, 0x52, 0xa8, 0x9b, 0x91, 0x64, 0xc8, 0x29, 0x5c, 0xc9, 0x06, 0x9c, 0x5f, 0x76, 0xe8, + 0x23, 0xd3, 0xee, 0xba, 0xfe, 0xf2, 0xe1, 0xcf, 0x5b, 0xe7, 0x77, 0x9c, 0xb7, 0x9e, 0x15, 0x15, + 0x9f, 0xed, 0x38, 0xf4, 0x51, 0xdd, 0x0f, 0xfb, 0x1c, 0x89, 0x5a, 0x9a, 0xc5, 0x1d, 0x53, 0x3a, + 0x7f, 0xd0, 0x75, 0xa8, 0x80, 0x9b, 0xd4, 0x55, 0x94, 0x70, 0xaa, 0xe5, 0x91, 0x6a, 0xcc, 0x00, + 0x17, 0x49, 0xe9, 0x1c, 0x2d, 0x46, 0x34, 0x20, 0xb7, 0xa7, 0xfd, 0x4b, 0xec, 0x72, 0x83, 0x27, + 0xbe, 0x55, 0x2e, 0x20, 0x33, 0x95, 0x89, 0xa5, 0xd9, 0x08, 0x42, 0xc0, 0xd7, 0x75, 0x81, 0x97, + 0xc5, 0x92, 0x2c, 0x4d, 0xe6, 0x61, 0x7c, 0xd9, 0xc1, 0x23, 0xb5, 0xbb, 0x74, 0x73, 0xd9, 0x6e, + 0x99, 0x8d, 0x4d, 0x7c, 0x1d, 0x2b, 0xa6, 0xca, 0x0e, 0xc7, 0xd5, 0x1f, 0xd2, 0xcd, 0x7a, 0x07, + 0xb1, 0xf2, 0xb2, 0x12, 0x2f, 0x29, 0x87, 0x64, 0x7e, 0x6a, 0x77, 0x21, 0x99, 0x29, 0x8c, 0x8b, + 0x2b, 0xf0, 0xc7, 0x1e, 0xb5, 0xd8, 0x52, 0xef, 0x8a, 0x97, 0xb0, 0x4a, 0xec, 0xca, 0x3c, 0xc0, + 0xf3, 0xa9, 0x43, 0x8c, 0x32, 0x1a, 0x80, 0xe5, 0x86, 0xc5, 0x8b, 0x24, 0xe3, 0x16, 0x3f, 0xbd, + 0x8f, 0xb8, 0xc5, 0x7f, 0xb7, 0x20, 0xcf, 0xbf, 0xe4, 0x12, 0x14, 0xa5, 0xb4, 0x42, 0x18, 0x94, + 0x15, 0x43, 0xb0, 0x17, 0x45, 0xac, 0xe9, 0x21, 0x61, 0xbb, 0x04, 0xd1, 0x77, 0x30, 0x8f, 0x64, + 0x18, 0xa8, 0x53, 0x0b, 0x09, 0x30, 0x87, 0x5f, 0x77, 0xb5, 0x65, 0x36, 0x30, 0x30, 0x7f, 0x41, + 0x0a, 0xb7, 0x81, 0x50, 0x1e, 0x97, 0x5f, 0x22, 0x21, 0x37, 0x61, 0xd8, 0x3f, 0xca, 0x0d, 0x83, + 0x12, 0x63, 0xbc, 0x76, 0x31, 0x5b, 0x8b, 0x70, 0xf0, 0x12, 0x11, 0x79, 0x03, 0x20, 0x9c, 0x0e, + 0x84, 0xa5, 0x85, 0x4b, 0x85, 0x3c, 0x7b, 0xc8, 0x4b, 0x45, 0x48, 0xcd, 0x26, 0x4e, 0x59, 0x1d, + 0xfd, 0xac, 0xa5, 0x38, 0x71, 0x46, 0x74, 0x58, 0x56, 0x90, 0x68, 0x11, 0xb2, 0x04, 0x13, 0x09, + 0x0d, 0x14, 0x21, 0x8c, 0x31, 0x73, 0x7d, 0x8a, 0xfa, 0xca, 0x0b, 0x73, 0xa2, 0x2c, 0x79, 0x0e, + 0x0a, 0xf7, 0xb4, 0xaa, 0x08, 0xa3, 0xca, 0x23, 0xf0, 0x46, 0x62, 0x2c, 0x31, 0xac, 0xfa, 0xc3, + 0xf9, 0xc4, 0xda, 0xc4, 0xa4, 0x27, 0x58, 0x49, 0x3d, 0x88, 0xd2, 0xf3, 0xeb, 0xe7, 0xd2, 0x93, + 0x88, 0xc8, 0x55, 0x18, 0x5c, 0x66, 0x33, 0x43, 0xc3, 0x6e, 0x89, 0xfe, 0xc4, 0x80, 0x58, 0x1d, + 0x01, 0xd3, 0x02, 0x2c, 0xb9, 0x29, 0x25, 0xdb, 0x95, 0x22, 0x93, 0xfb, 0xc9, 0x76, 0xe3, 0x21, + 0xba, 0x31, 0xed, 0xee, 0xcd, 0x58, 0xf2, 0x2e, 0x51, 0x26, 0x65, 0x5d, 0x0c, 0x93, 0x75, 0x05, + 0x56, 0x69, 0xff, 0x4e, 0x56, 0xa9, 0xfa, 0xf7, 0x73, 0xc9, 0x71, 0x46, 0x6e, 0x25, 0x83, 0x04, + 0xe3, 0x22, 0x14, 0x00, 0xe5, 0x5a, 0x83, 0x70, 0xc1, 0x91, 0x70, 0xbf, 0xf9, 0x7d, 0x87, 0xfb, + 0x2d, 0xec, 0x31, 0xdc, 0xaf, 0xfa, 0xff, 0x14, 0x7b, 0xba, 0x6c, 0x1f, 0x49, 0x58, 0xb8, 0xd7, + 0xd9, 0xce, 0x8a, 0xd5, 0x5e, 0x76, 0x13, 0xfb, 0x03, 0xee, 0x91, 0x5a, 0xd7, 0xf9, 0xd0, 0x72, + 0xb5, 0x28, 0x25, 0x79, 0x07, 0x46, 0xfc, 0x0f, 0xc0, 0x30, 0xd2, 0x52, 0xf8, 0xe3, 0x60, 0x55, + 0x8b, 0x05, 0x5c, 0x8e, 0x14, 0x20, 0xaf, 0xc0, 0x10, 0xda, 0x34, 0x1d, 0xbd, 0xe1, 0xc7, 0x18, + 0xe7, 0x41, 0xc9, 0x7d, 0xa0, 0x1c, 0xfa, 0x2c, 0xa0, 0x24, 0x5f, 0x82, 0x92, 0x48, 0xb4, 0xc1, + 0xf3, 0xd0, 0xdf, 0xd8, 0x85, 0x8f, 0xfb, 0x75, 0x39, 0xc9, 0x06, 0xdf, 0xa5, 0x20, 0x20, 0xb2, + 0x4b, 0xe1, 0xf9, 0x35, 0x56, 0xe0, 0xf4, 0xb2, 0x43, 0x0d, 0x7c, 0x4d, 0x31, 0xf3, 0xb8, 0xe3, + 0x88, 0x14, 0x28, 0x7c, 0x94, 0xe3, 0x22, 0xd5, 0xf1, 0xd1, 0x6c, 0xf9, 0x14, 0x78, 0x39, 0xd0, + 0x71, 0x4a, 0x71, 0x66, 0xb9, 0xf0, 0x96, 0xdc, 0xa5, 0x9b, 0x1b, 0xb6, 0x63, 0xf0, 0x2c, 0x21, + 0x62, 0xfe, 0x16, 0x82, 0x7e, 0x28, 0x50, 0xb2, 0xe5, 0x12, 0x2d, 0x74, 0xf1, 0x75, 0x18, 0xde, + 0x6f, 0xa2, 0x8a, 0x5f, 0xcd, 0x67, 0x3c, 0x7e, 0x7a, 0x72, 0x73, 0x05, 0x06, 0x09, 0xac, 0xfb, + 0x33, 0x12, 0x58, 0xff, 0x71, 0x3e, 0xe3, 0x65, 0xd7, 0x13, 0x9d, 0x68, 0x36, 0x10, 0x46, 0x34, + 0xd1, 0x6c, 0x98, 0xe3, 0xd7, 0x34, 0x34, 0x99, 0x28, 0x96, 0x92, 0xba, 0xb4, 0x63, 0x4a, 0xea, + 0x5f, 0x28, 0xf4, 0x7a, 0xf9, 0x76, 0x22, 0xfb, 0xbd, 0xc8, 0xfe, 0x26, 0x0c, 0x07, 0x92, 0xad, + 0x56, 0xd0, 0xe8, 0x19, 0x0d, 0xd2, 0xe2, 0x70, 0x30, 0x96, 0x91, 0x88, 0xc8, 0x35, 0xde, 0xd6, + 0x9a, 0xf9, 0x01, 0x4f, 0xd0, 0x30, 0x2a, 0x42, 0xef, 0xeb, 0x9e, 0x5e, 0x77, 0xcd, 0x0f, 0xa8, + 0x16, 0xa0, 0xd5, 0xff, 0x2c, 0x9f, 0xfa, 0x7c, 0xf0, 0xa4, 0x8f, 0xf6, 0xd0, 0x47, 0x29, 0x42, + 0xe4, 0x0f, 0x1f, 0x4f, 0x84, 0xb8, 0x07, 0x21, 0xfe, 0x51, 0x3e, 0xf5, 0x99, 0xe8, 0x89, 0x10, + 0xf7, 0x32, 0x5b, 0xbc, 0x00, 0x43, 0x9a, 0xbd, 0xe1, 0x4e, 0xe3, 0xc6, 0x86, 0xcf, 0x15, 0x38, + 0x51, 0x3b, 0xf6, 0x86, 0x5b, 0xc7, 0x2d, 0x8b, 0x16, 0x12, 0xa8, 0xdf, 0xcb, 0xf7, 0x78, 0x48, + 0x7b, 0x22, 0xf8, 0x0f, 0x73, 0x89, 0xfc, 0x8d, 0x7c, 0xe4, 0xa1, 0xee, 0x93, 0x2b, 0xec, 0x1b, + 0x00, 0xb5, 0xc6, 0x3a, 0x6d, 0xeb, 0x52, 0x92, 0x2b, 0x3c, 0x77, 0x70, 0x11, 0x2a, 0x92, 0x23, + 0x87, 0x24, 0xea, 0x37, 0xf3, 0xb1, 0x97, 0xca, 0x27, 0xb2, 0xdb, 0xb5, 0xec, 0x02, 0xad, 0x13, + 0x8f, 0xaf, 0x4f, 0x24, 0xb7, 0x5b, 0xc9, 0xfd, 0x58, 0x3e, 0xf6, 0x4e, 0xfd, 0x89, 0x95, 0x1d, + 0x1b, 0x80, 0xc9, 0xf7, 0xf3, 0x4f, 0xac, 0x26, 0xbd, 0x00, 0x43, 0x42, 0x0e, 0xc1, 0x52, 0xc1, + 0xe7, 0x7d, 0x0e, 0xc4, 0x53, 0xd6, 0x80, 0x40, 0xfd, 0x53, 0x79, 0x88, 0xc6, 0x0f, 0x78, 0x42, + 0x75, 0xe8, 0x37, 0xf2, 0xd1, 0xc8, 0x09, 0x4f, 0xae, 0xfe, 0x5c, 0x07, 0xa8, 0x75, 0x57, 0x1b, + 0x22, 0xf0, 0x6e, 0xbf, 0x74, 0x4c, 0x1f, 0x40, 0x35, 0x89, 0x42, 0xfd, 0x7f, 0xf3, 0xa9, 0xe1, + 0x1c, 0x9e, 0x5c, 0x01, 0xbe, 0x8c, 0xa7, 0xe2, 0x0d, 0x2b, 0x9c, 0xc8, 0xf1, 0x10, 0x92, 0x8d, + 0xbf, 0x44, 0x66, 0x44, 0x9f, 0x90, 0x7c, 0x36, 0xc5, 0x5c, 0xc3, 0xbc, 0x0d, 0xa1, 0xb9, 0x26, + 0x5f, 0x43, 0x48, 0x86, 0xdb, 0x3f, 0xca, 0xef, 0x14, 0xfd, 0xe2, 0x49, 0x5e, 0x55, 0x07, 0x96, + 0xf5, 0x4d, 0x8c, 0xd2, 0xc8, 0x7a, 0x62, 0x84, 0xe7, 0xed, 0xeb, 0x70, 0x90, 0x7c, 0xf7, 0x26, + 0xa8, 0xd4, 0x7f, 0xd1, 0x9f, 0x1e, 0x7a, 0xe1, 0xc9, 0x15, 0xe1, 0x25, 0x28, 0x2e, 0xeb, 0xde, + 0xba, 0xd0, 0x64, 0xbc, 0xd2, 0xeb, 0xe8, 0xde, 0xba, 0x86, 0x50, 0x72, 0x0d, 0x06, 0x35, 0x7d, + 0x83, 0x9f, 0x79, 0x96, 0xc2, 0x9c, 0x8a, 0x8e, 0xbe, 0x51, 0xe7, 0xe7, 0x9e, 0x01, 0x9a, 0xa8, + 0x41, 0x4e, 0x4f, 0x7e, 0xf2, 0x8d, 0x09, 0xe5, 0x78, 0x4e, 0xcf, 0x20, 0x93, 0xe7, 0x25, 0x28, + 0x4e, 0xd9, 0xc6, 0x26, 0x5e, 0x5f, 0x8d, 0xf0, 0xca, 0x56, 0x6d, 0x63, 0x53, 0x43, 0x28, 0xf9, + 0xf1, 0x1c, 0x0c, 0xcc, 0x51, 0xdd, 0x60, 0x23, 0x64, 0xa8, 0x97, 0xd7, 0xc9, 0x17, 0x0e, 0xc7, + 0xeb, 0x64, 0x62, 0x9d, 0x57, 0x26, 0x2b, 0x8a, 0xa8, 0x9f, 0xdc, 0x86, 0xc1, 0x69, 0xdd, 0xa3, + 0x4d, 0xdb, 0xd9, 0x44, 0x3f, 0x9a, 0xb1, 0xd0, 0x7d, 0x3f, 0xa2, 0x3f, 0x3e, 0x11, 0xbf, 0x19, + 0x6b, 0x88, 0x5f, 0x5a, 0x50, 0x98, 0x89, 0x65, 0x45, 0x77, 0x9a, 0xd4, 0x13, 0xf9, 0xab, 0x51, + 0x2c, 0x1e, 0x42, 0x34, 0x81, 0x09, 0x8f, 0x95, 0x47, 0xd2, 0x8f, 0x95, 0xd1, 0x7a, 0x44, 0x5f, + 0x3b, 0xcc, 0xa4, 0x39, 0x8a, 0x8b, 0x3e, 0xb7, 0x1e, 0x11, 0x8a, 0x89, 0x34, 0x35, 0x89, 0x44, + 0xfd, 0x6e, 0x3f, 0xa4, 0x3e, 0xd4, 0x3e, 0x51, 0xf2, 0x13, 0x25, 0x0f, 0x95, 0xbc, 0x92, 0x50, + 0xf2, 0x8b, 0xc9, 0xa7, 0xff, 0x1f, 0x51, 0x0d, 0xff, 0x99, 0x62, 0x22, 0x70, 0xc8, 0x93, 0xbd, + 0xbb, 0x0c, 0xa5, 0xd7, 0xbf, 0xa3, 0xf4, 0x82, 0x01, 0x51, 0xda, 0x71, 0x40, 0x0c, 0xec, 0x76, + 0x40, 0x0c, 0x66, 0x0e, 0x88, 0x50, 0x41, 0x86, 0x32, 0x15, 0xa4, 0x2a, 0x06, 0x0d, 0xf4, 0xce, + 0x5f, 0x72, 0x69, 0x7b, 0x6b, 0x72, 0x8c, 0x8d, 0xa6, 0xd4, 0xc4, 0x25, 0xc8, 0x42, 0xfd, 0xdd, + 0x62, 0x8f, 0x68, 0x3f, 0x47, 0xa2, 0x23, 0x2f, 0x43, 0xa1, 0xdc, 0xe9, 0x08, 0xfd, 0x38, 0x2d, + 0x05, 0x1a, 0xca, 0x28, 0xc5, 0xa8, 0xc9, 0x1b, 0x50, 0x28, 0x3f, 0xa8, 0xc5, 0x73, 0x96, 0x94, + 0x1f, 0xd4, 0xc4, 0x97, 0x64, 0x96, 0x7d, 0x50, 0x23, 0x6f, 0x85, 0xc1, 0x43, 0xd7, 0xbb, 0xd6, + 0x43, 0xb1, 0x51, 0x14, 0xee, 0xb6, 0xbe, 0x3b, 0x4e, 0x83, 0xa1, 0xd8, 0x76, 0x31, 0x46, 0x1b, + 0xd3, 0xa6, 0xd2, 0xee, 0xb5, 0x69, 0x60, 0x47, 0x6d, 0x1a, 0xdc, 0xad, 0x36, 0x0d, 0xed, 0x42, + 0x9b, 0x60, 0x47, 0x6d, 0x1a, 0x3e, 0xb8, 0x36, 0x75, 0xe0, 0x62, 0x32, 0x42, 0x5b, 0xa0, 0x11, + 0x1a, 0x90, 0x24, 0x56, 0x38, 0x96, 0xe0, 0xd5, 0x7f, 0x97, 0x63, 0xeb, 0x1b, 0x88, 0xae, 0xbb, + 0x0c, 0x2f, 0xfb, 0xa7, 0x25, 0x4b, 0xab, 0xbf, 0x9a, 0xcf, 0x0e, 0x2c, 0x77, 0x3c, 0xa7, 0xb8, + 0x1f, 0x48, 0x95, 0x52, 0x31, 0xfa, 0xd0, 0x3f, 0x5b, 0xca, 0x31, 0xb6, 0x69, 0x32, 0xfb, 0x76, + 0x2e, 0x2b, 0xda, 0xdd, 0x81, 0x24, 0xf6, 0xc9, 0xa4, 0x47, 0x1b, 0xfa, 0xe9, 0xbb, 0x51, 0x57, + 0xb6, 0x59, 0x18, 0x91, 0x85, 0x28, 0xa4, 0xb4, 0x1b, 0x01, 0x47, 0xca, 0xa9, 0x7f, 0x3f, 0x07, + 0xa7, 0xef, 0x76, 0x57, 0xa9, 0xf0, 0x60, 0x0b, 0x9a, 0xf1, 0x3e, 0x00, 0x03, 0x0b, 0x27, 0x96, + 0x1c, 0x3a, 0xb1, 0x7c, 0x5a, 0x8e, 0x54, 0x17, 0x2b, 0x70, 0x3d, 0xa4, 0xe6, 0x0e, 0x2c, 0x4f, + 0xfb, 0xce, 0x9c, 0x0f, 0xbb, 0xab, 0xb4, 0x9e, 0xf0, 0x64, 0x91, 0xb8, 0x5f, 0x7c, 0x9b, 0xbb, + 0xc9, 0xef, 0xd7, 0x69, 0xe4, 0x97, 0xf3, 0x99, 0xc1, 0x01, 0x8f, 0x6d, 0x16, 0xcb, 0xef, 0x4b, + 0xed, 0x95, 0x78, 0x36, 0xcb, 0x14, 0x92, 0x18, 0xc7, 0x34, 0x2e, 0xe9, 0x02, 0x3b, 0xe6, 0xb9, + 0x55, 0x3f, 0x54, 0x81, 0xfd, 0x41, 0x2e, 0x33, 0x88, 0xe3, 0x71, 0x15, 0x98, 0xfa, 0xbf, 0x14, + 0xfc, 0xd8, 0x91, 0x07, 0xfa, 0x84, 0x17, 0x60, 0x48, 0x3c, 0xa1, 0x8f, 0x3a, 0xe0, 0x8a, 0xa3, + 0x3c, 0x3c, 0x1a, 0x0e, 0x08, 0xd8, 0x32, 0x2f, 0x79, 0x07, 0x4b, 0x0e, 0xb8, 0x92, 0x67, 0xb0, + 0x26, 0x91, 0xb0, 0x85, 0x7c, 0xe6, 0xb1, 0xe9, 0xa1, 0x55, 0xc0, 0xfa, 0xb2, 0xc0, 0x17, 0x72, + 0xfa, 0xd8, 0xf4, 0xb8, 0x4d, 0x10, 0xa0, 0xd9, 0x22, 0x5d, 0x0b, 0x33, 0xc7, 0x8b, 0x45, 0xda, + 0x15, 0x09, 0xf4, 0xc5, 0xb3, 0xb1, 0x17, 0x60, 0x48, 0x78, 0xb5, 0x0a, 0x37, 0x13, 0xd1, 0x5a, + 0xe1, 0x07, 0x8b, 0xad, 0x0d, 0x08, 0x18, 0x47, 0x8d, 0x36, 0x43, 0xc7, 0x3a, 0xe4, 0xe8, 0x20, + 0x44, 0x13, 0x18, 0x72, 0x13, 0xc6, 0x6a, 0x9e, 0x6e, 0x19, 0xba, 0x63, 0x2c, 0x75, 0xbd, 0x4e, + 0xd7, 0x93, 0x8d, 0x52, 0xd7, 0x33, 0xec, 0xae, 0xa7, 0xc5, 0x28, 0xc8, 0x67, 0x60, 0xd4, 0x87, + 0xcc, 0x38, 0x8e, 0xed, 0xc8, 0x96, 0x87, 0xeb, 0x19, 0xd4, 0x71, 0xb4, 0x28, 0x01, 0xf9, 0x2c, + 0x8c, 0x56, 0xad, 0x47, 0x76, 0x83, 0x3f, 0x23, 0xd7, 0xe6, 0x85, 0x1d, 0x82, 0x4f, 0xb1, 0xcc, + 0x00, 0x51, 0xef, 0x3a, 0x2d, 0x2d, 0x4a, 0xa8, 0x6e, 0xe7, 0x93, 0x21, 0x36, 0x9f, 0xdc, 0x4d, + 0xcb, 0xb5, 0xa8, 0x33, 0x1d, 0x7a, 0x90, 0xa2, 0x41, 0x28, 0xfb, 0xf2, 0x72, 0xbb, 0xf0, 0x26, + 0x0c, 0xde, 0xa5, 0x9b, 0xdc, 0xef, 0xb3, 0x14, 0xba, 0x0a, 0x3f, 0x14, 0x30, 0xf9, 0xc4, 0xd5, + 0xa7, 0x53, 0xbf, 0x95, 0x4f, 0x06, 0x0f, 0x7d, 0x72, 0x85, 0xfd, 0x19, 0x18, 0x40, 0x51, 0x56, + 0xfd, 0x23, 0x7f, 0x14, 0x20, 0x8a, 0x3b, 0xea, 0x81, 0xec, 0x93, 0xa9, 0x3f, 0x5f, 0x8a, 0x47, + 0x94, 0x7d, 0x72, 0xa5, 0xf7, 0x26, 0x0c, 0x4f, 0xdb, 0x96, 0x6b, 0xba, 0x1e, 0xb5, 0x1a, 0xbe, + 0xc2, 0x5e, 0x60, 0x06, 0x55, 0x23, 0x04, 0xcb, 0x6f, 0x90, 0x24, 0xea, 0xfd, 0x28, 0x2f, 0x79, + 0x15, 0x86, 0x50, 0xe4, 0xe8, 0x27, 0xcd, 0x27, 0x3c, 0xbc, 0x2d, 0x58, 0x65, 0xc0, 0xb8, 0x93, + 0x74, 0x48, 0x4a, 0xee, 0xc1, 0xe0, 0xf4, 0xba, 0xd9, 0x32, 0x1c, 0x6a, 0xa1, 0xbf, 0xb0, 0x14, + 0xb8, 0x23, 0xda, 0x97, 0xd7, 0xf1, 0x5f, 0xa4, 0xe5, 0xcd, 0x69, 0x88, 0x62, 0x91, 0x57, 0x58, + 0x02, 0x76, 0xf1, 0xa7, 0xf3, 0x00, 0x61, 0x01, 0xf2, 0x0c, 0xe4, 0x83, 0xa4, 0xcc, 0xe8, 0xa6, + 0x12, 0xd1, 0xa0, 0x3c, 0x2e, 0x15, 0x62, 0x6c, 0xe7, 0x77, 0x1c, 0xdb, 0xf7, 0xa0, 0xc4, 0x4f, + 0xbc, 0xd0, 0x93, 0x5c, 0x0a, 0x72, 0x99, 0xd9, 0xe0, 0xeb, 0x48, 0xcf, 0x37, 0xb3, 0x68, 0x79, + 0x46, 0xbc, 0xb2, 0x39, 0xb3, 0x8b, 0x0d, 0xe8, 0xc7, 0xbf, 0xc8, 0x15, 0x28, 0xae, 0xf8, 0x09, + 0x5d, 0x47, 0xf9, 0x2c, 0x1d, 0x93, 0x1f, 0xe2, 0x59, 0x37, 0x4d, 0xdb, 0x96, 0xc7, 0xaa, 0xc6, + 0x56, 0x8f, 0x08, 0xb9, 0x08, 0x58, 0x44, 0x2e, 0x02, 0xa6, 0xfe, 0x57, 0xf9, 0x94, 0x58, 0xc7, + 0x4f, 0xee, 0x30, 0x79, 0x1d, 0x00, 0x9f, 0x74, 0x33, 0x79, 0xfa, 0x4f, 0x34, 0x70, 0x94, 0x20, + 0x23, 0x54, 0xdb, 0xc8, 0xb6, 0x23, 0x24, 0x56, 0xff, 0x61, 0x2e, 0x11, 0x20, 0xf7, 0x40, 0x72, + 0x94, 0xad, 0xb2, 0xfc, 0x3e, 0xcd, 0x58, 0xbf, 0x2f, 0x0a, 0x7b, 0xeb, 0x8b, 0xe8, 0xb7, 0x1c, + 0x82, 0x65, 0x7a, 0x94, 0xdf, 0xf2, 0xdd, 0x7c, 0x5a, 0xb8, 0xe0, 0xe3, 0xa9, 0xe2, 0xb7, 0x02, + 0xa3, 0xb4, 0x18, 0x0b, 0xd0, 0x8e, 0xd0, 0x78, 0xd2, 0x69, 0x61, 0xa6, 0x7e, 0x19, 0x4e, 0xc5, + 0x82, 0xe8, 0x8a, 0xfc, 0xbf, 0x57, 0x7a, 0x47, 0xe3, 0xcd, 0x0e, 0x06, 0x10, 0x21, 0x53, 0xff, + 0xbf, 0x5c, 0xef, 0x10, 0xca, 0x47, 0xae, 0x3a, 0x29, 0x02, 0x28, 0xfc, 0xc9, 0x08, 0xe0, 0x10, + 0xb6, 0xc1, 0xc7, 0x5b, 0x00, 0x1f, 0x91, 0xc9, 0xe3, 0xc3, 0x16, 0xc0, 0xcf, 0xe7, 0x76, 0x8c, + 0x80, 0x7d, 0xd4, 0x32, 0x50, 0xff, 0xc7, 0x5c, 0x6a, 0xa4, 0xea, 0x03, 0xb5, 0xeb, 0x2d, 0x28, + 0x71, 0xb7, 0x1a, 0xd1, 0x2a, 0x29, 0xb7, 0x17, 0x83, 0x66, 0x65, 0xc3, 0xe7, 0x58, 0x32, 0x0f, + 0x03, 0xbc, 0x0d, 0x86, 0xe8, 0x8d, 0x4f, 0xf4, 0x08, 0x97, 0x6d, 0x64, 0x4d, 0x8e, 0x02, 0xad, + 0xfe, 0x83, 0x5c, 0x22, 0x70, 0xf6, 0x11, 0x7e, 0x5b, 0x38, 0x55, 0x17, 0x76, 0x3f, 0x55, 0xab, + 0xff, 0x3c, 0x9f, 0x1e, 0xb7, 0xfb, 0x08, 0x3f, 0xe4, 0x30, 0x8e, 0xd3, 0xf6, 0xb7, 0x6e, 0xad, + 0xc0, 0x58, 0x54, 0x16, 0x62, 0xd9, 0xba, 0x9c, 0x1e, 0xbd, 0x3c, 0xa3, 0x15, 0x31, 0x1e, 0xea, + 0x77, 0x72, 0xc9, 0x90, 0xe3, 0x47, 0x3e, 0x3f, 0xed, 0x4f, 0x5b, 0xa2, 0x9f, 0xf2, 0x11, 0x59, + 0x6b, 0x0e, 0xe3, 0x53, 0x3e, 0x22, 0xab, 0xc6, 0xfe, 0x3e, 0xe5, 0x17, 0xf3, 0x59, 0x11, 0xdb, + 0x8f, 0xfc, 0x83, 0xbe, 0x28, 0x0b, 0x99, 0xb7, 0x4c, 0x7c, 0xda, 0x33, 0x59, 0x21, 0xd2, 0x33, + 0x78, 0x26, 0xf8, 0xec, 0x6f, 0x8c, 0xa7, 0x0a, 0xeb, 0x23, 0xa2, 0xc8, 0xc7, 0x43, 0x58, 0x1f, + 0x91, 0xa1, 0xf2, 0xd1, 0x13, 0xd6, 0x6f, 0xe5, 0x77, 0x9b, 0x26, 0xe0, 0x44, 0x78, 0x09, 0xe1, + 0x7d, 0x3d, 0x9f, 0x4c, 0x5f, 0x71, 0xe4, 0x62, 0x9a, 0x85, 0x92, 0x48, 0xa4, 0x91, 0x29, 0x1c, + 0x8e, 0xcf, 0xb2, 0x68, 0xc4, 0x77, 0xdc, 0x02, 0x71, 0x91, 0xb3, 0x3b, 0x91, 0x70, 0x5a, 0xf5, + 0x7b, 0xb9, 0x58, 0xae, 0x87, 0x23, 0x39, 0x42, 0xd8, 0xd7, 0x92, 0x44, 0xde, 0xf6, 0x0f, 0x33, + 0x8b, 0xb1, 0x58, 0xdb, 0xc1, 0xf7, 0x54, 0xa8, 0xa7, 0x9b, 0xad, 0x78, 0x79, 0x11, 0x13, 0xe0, + 0x5b, 0x79, 0x98, 0x48, 0x90, 0x92, 0x2b, 0x91, 0x50, 0x3a, 0x78, 0x2c, 0x19, 0x73, 0x1e, 0xe7, + 0x41, 0x75, 0xf6, 0x70, 0x92, 0x7a, 0x05, 0x8a, 0x15, 0x7d, 0x93, 0x7f, 0x5b, 0x3f, 0x67, 0x69, + 0xe8, 0x9b, 0xf2, 0x89, 0x1b, 0xe2, 0xc9, 0x2a, 0x9c, 0xe5, 0xf7, 0x21, 0xa6, 0x6d, 0xad, 0x98, + 0x6d, 0x5a, 0xb5, 0x16, 0xcc, 0x56, 0xcb, 0x74, 0xc5, 0xa5, 0xde, 0x0b, 0xdb, 0x5b, 0x93, 0x57, + 0x3d, 0xdb, 0xd3, 0x5b, 0x75, 0xea, 0x93, 0xd5, 0x3d, 0xb3, 0x4d, 0xeb, 0xa6, 0x55, 0x6f, 0x23, + 0xa5, 0xc4, 0x32, 0x9d, 0x15, 0xa9, 0xf2, 0xb0, 0xea, 0xb5, 0x86, 0x6e, 0x59, 0xd4, 0xa8, 0x5a, + 0x53, 0x9b, 0x1e, 0xe5, 0x97, 0x81, 0x05, 0x7e, 0x24, 0xc8, 0xdf, 0x86, 0x73, 0x34, 0x63, 0xbc, + 0xca, 0x08, 0xb4, 0x94, 0x42, 0xea, 0x6f, 0x17, 0x53, 0xd2, 0x7c, 0x1c, 0x23, 0xf5, 0xf1, 0x7b, + 0xba, 0xb8, 0x43, 0x4f, 0xdf, 0x80, 0x01, 0x11, 0xb7, 0x56, 0x5c, 0x30, 0xa0, 0x33, 0xfb, 0x23, + 0x0e, 0x92, 0x6f, 0x68, 0x04, 0x15, 0x69, 0xc1, 0xc5, 0x15, 0xd6, 0x4d, 0xe9, 0x9d, 0x59, 0xda, + 0x47, 0x67, 0xf6, 0xe0, 0x47, 0xde, 0x83, 0xf3, 0x88, 0x4d, 0xe9, 0xd6, 0x01, 0xac, 0x0a, 0x63, + 0x54, 0xf1, 0xaa, 0xd2, 0x3b, 0x37, 0xab, 0x3c, 0xf9, 0x22, 0x8c, 0x04, 0x03, 0xc4, 0xa4, 0xae, + 0xb8, 0xb9, 0xe8, 0x31, 0xce, 0x78, 0x00, 0x38, 0x06, 0x46, 0x17, 0xb2, 0x68, 0x10, 0xb1, 0x08, + 0x2f, 0xf5, 0x7f, 0xc8, 0xf5, 0x4a, 0x37, 0x72, 0xe4, 0xb3, 0xf2, 0xdb, 0x30, 0x60, 0xf0, 0x8f, + 0x12, 0x3a, 0xd5, 0x3b, 0x21, 0x09, 0x27, 0xd5, 0xfc, 0x32, 0xea, 0x3f, 0xcb, 0xf5, 0xcc, 0x72, + 0x72, 0xdc, 0x3f, 0xef, 0xeb, 0x85, 0x8c, 0xcf, 0x13, 0x93, 0xe8, 0x35, 0x18, 0x37, 0xc3, 0x30, + 0xec, 0xf5, 0x30, 0xfc, 0x94, 0x76, 0x4a, 0x82, 0xe3, 0xe8, 0xba, 0x05, 0xe7, 0x7c, 0xc7, 0x47, + 0xc7, 0xf7, 0x10, 0x73, 0xeb, 0x5d, 0xc7, 0xe4, 0xe3, 0x52, 0x3b, 0xe3, 0xc6, 0xdc, 0xc7, 0xdc, + 0x7b, 0x8e, 0xc9, 0x2a, 0xd0, 0xbd, 0x75, 0x6a, 0xe9, 0xf5, 0x0d, 0xdb, 0x79, 0x88, 0x51, 0x46, + 0xf9, 0xe0, 0xd4, 0x4e, 0x71, 0xf8, 0x03, 0x1f, 0x4c, 0x9e, 0x83, 0xd1, 0x66, 0xab, 0x4b, 0x83, + 0xb8, 0x8e, 0xfc, 0xae, 0x4f, 0x1b, 0x61, 0xc0, 0xe0, 0x86, 0xe4, 0x69, 0x00, 0x24, 0xf2, 0x30, + 0x07, 0x0d, 0x5e, 0xec, 0x69, 0x43, 0x0c, 0xb2, 0x22, 0xba, 0xeb, 0x22, 0xd7, 0x6a, 0x2e, 0xa4, + 0x7a, 0xcb, 0xb6, 0x9a, 0x75, 0x8f, 0x3a, 0x6d, 0x6c, 0x28, 0x3a, 0x33, 0x68, 0xe7, 0x90, 0x02, + 0xaf, 0x4e, 0xdc, 0x79, 0xdb, 0x6a, 0xae, 0x50, 0xa7, 0xcd, 0x9a, 0xfa, 0x02, 0x10, 0xd1, 0x54, + 0x07, 0x0f, 0x3d, 0xf8, 0xc7, 0xa1, 0x37, 0x83, 0x26, 0x3e, 0x82, 0x9f, 0x86, 0xe0, 0x87, 0x4d, + 0xc2, 0x30, 0x0f, 0x6e, 0xc7, 0x85, 0x86, 0x2e, 0x0c, 0x1a, 0x70, 0x10, 0xca, 0xeb, 0x1c, 0x08, + 0xef, 0x0a, 0xee, 0xd5, 0xad, 0x89, 0x5f, 0xea, 0x57, 0x0b, 0x69, 0x89, 0x59, 0x0e, 0xa4, 0x68, + 0xe1, 0xb4, 0x9a, 0xdf, 0xd3, 0xb4, 0x7a, 0xca, 0xea, 0xb6, 0xeb, 0x7a, 0xa7, 0x53, 0x5f, 0x33, + 0x5b, 0xf8, 0xac, 0x0a, 0x17, 0x3e, 0x6d, 0xd4, 0xea, 0xb6, 0xcb, 0x9d, 0xce, 0x2c, 0x07, 0x92, + 0xe7, 0x61, 0x82, 0xd1, 0x61, 0x27, 0x05, 0x94, 0x45, 0xa4, 0x64, 0x0c, 0x30, 0x3a, 0xac, 0x4f, + 0x7b, 0x01, 0x06, 0x05, 0x4f, 0xbe, 0x56, 0xf5, 0x6b, 0x03, 0x9c, 0x99, 0xcb, 0x7a, 0x2e, 0x60, + 0xc3, 0x27, 0xd7, 0x7e, 0x6d, 0xc8, 0x2f, 0x8f, 0x31, 0x90, 0xad, 0x6e, 0x9b, 0x47, 0xc4, 0x1a, + 0x40, 0x64, 0xf0, 0x9b, 0x5c, 0x81, 0x31, 0xc6, 0x25, 0x10, 0x18, 0x0f, 0x1b, 0xdb, 0xaf, 0xc5, + 0xa0, 0xe4, 0x26, 0x9c, 0x89, 0x40, 0xb8, 0x0d, 0xca, 0x9f, 0x09, 0xf4, 0x6b, 0xa9, 0x38, 0xf5, + 0x9b, 0x85, 0x68, 0xba, 0x98, 0x23, 0xe8, 0x88, 0xf3, 0x30, 0x60, 0x3b, 0xcd, 0x7a, 0xd7, 0x69, + 0x89, 0xb1, 0x57, 0xb2, 0x9d, 0xe6, 0x3d, 0xa7, 0x45, 0xce, 0x42, 0x89, 0xf5, 0x8e, 0x69, 0x88, + 0x21, 0xd6, 0xaf, 0x77, 0x3a, 0x55, 0x83, 0x94, 0x79, 0x87, 0x60, 0xc8, 0xd1, 0x7a, 0x03, 0xb7, + 0xf6, 0xdc, 0x29, 0xa1, 0x9f, 0xaf, 0x78, 0x09, 0x24, 0xf6, 0x13, 0x06, 0x22, 0xe5, 0x07, 0x01, + 0x31, 0x16, 0x06, 0x6e, 0x4b, 0x0c, 0xde, 0x27, 0x71, 0x16, 0x02, 0x19, 0xb2, 0xe0, 0x9b, 0x18, + 0x83, 0x54, 0x80, 0x84, 0x54, 0x6d, 0xdb, 0x30, 0xd7, 0x4c, 0xca, 0x5f, 0x75, 0xf4, 0xf3, 0x8b, + 0xdf, 0x24, 0x56, 0x1b, 0xf7, 0x99, 0x2c, 0x08, 0x08, 0x79, 0x93, 0x2b, 0x21, 0xa7, 0xc3, 0xb5, + 0x8f, 0xf7, 0x2d, 0xb7, 0xd3, 0x62, 0x28, 0xd4, 0x4c, 0x2c, 0x8f, 0x0b, 0xa1, 0xfa, 0xd7, 0x8a, + 0xc9, 0x9c, 0x41, 0x47, 0x62, 0xd7, 0xcc, 0x01, 0x88, 0x94, 0x60, 0xe1, 0xe5, 0x5a, 0xe0, 0x71, + 0x1e, 0x62, 0x32, 0x78, 0x48, 0x65, 0xc9, 0x35, 0x18, 0xe4, 0x5f, 0x54, 0xad, 0x08, 0x7b, 0x07, + 0x5d, 0xc4, 0xdc, 0x8e, 0xb9, 0xb6, 0x86, 0xfe, 0x64, 0x01, 0x9a, 0x5c, 0x81, 0x81, 0xca, 0x62, + 0xad, 0x56, 0x5e, 0xf4, 0x6f, 0x8a, 0xf1, 0x7d, 0x89, 0x61, 0xb9, 0x75, 0x57, 0xb7, 0x5c, 0xcd, + 0x47, 0x92, 0xe7, 0xa0, 0x54, 0x5d, 0x46, 0x32, 0xfe, 0x6a, 0x72, 0x78, 0x7b, 0x6b, 0x72, 0xc0, + 0xec, 0x70, 0x2a, 0x81, 0xc2, 0x7a, 0xef, 0x57, 0x2b, 0x92, 0xbb, 0x04, 0xaf, 0xf7, 0x91, 0x69, + 0xe0, 0xb5, 0xb3, 0x16, 0xa0, 0xc9, 0x2b, 0x30, 0x52, 0xa3, 0x8e, 0xa9, 0xb7, 0x16, 0xbb, 0xb8, + 0x55, 0x94, 0x42, 0x29, 0xba, 0x08, 0xaf, 0x5b, 0x88, 0xd0, 0x22, 0x64, 0xe4, 0x12, 0x14, 0xe7, + 0x4c, 0xcb, 0x7f, 0xc2, 0x80, 0x3e, 0xee, 0xeb, 0xa6, 0xe5, 0x69, 0x08, 0x25, 0xcf, 0x41, 0xe1, + 0xce, 0x4a, 0x55, 0x78, 0x82, 0x21, 0xaf, 0xf7, 0xbd, 0x48, 0x58, 0xc6, 0x3b, 0x2b, 0x55, 0xf2, + 0x0a, 0x0c, 0xb1, 0x45, 0x8c, 0x5a, 0x0d, 0xea, 0x2a, 0xc3, 0xf8, 0x31, 0x3c, 0x8c, 0xa0, 0x0f, + 0x94, 0x7d, 0x3a, 0x02, 0x4a, 0xf5, 0xff, 0xc8, 0xa7, 0x27, 0x75, 0x3a, 0x82, 0xa1, 0xbe, 0xcf, + 0x5b, 0xe4, 0x98, 0x82, 0x15, 0x0f, 0xa0, 0x60, 0x6b, 0x70, 0xaa, 0x6c, 0xb4, 0x4d, 0xab, 0x8c, + 0x3f, 0xdd, 0x85, 0xd9, 0x32, 0x4e, 0x1d, 0xd2, 0xf3, 0xbc, 0x18, 0x5a, 0x7c, 0x0f, 0x0f, 0xf8, + 0xcb, 0x50, 0x75, 0x9d, 0xe3, 0xea, 0xed, 0x35, 0xbd, 0xde, 0xe0, 0xf9, 0x90, 0xb4, 0x38, 0x53, + 0xf5, 0xa7, 0xf2, 0x3b, 0xe4, 0xa1, 0x7a, 0x12, 0xa5, 0xaf, 0x7e, 0x23, 0xdf, 0x3b, 0x15, 0xd8, + 0x13, 0x29, 0x94, 0x3f, 0xca, 0xa7, 0x24, 0xe6, 0x3a, 0x90, 0x24, 0xae, 0xc1, 0x20, 0x67, 0x13, + 0xb8, 0xf1, 0xe2, 0x6c, 0xc6, 0x95, 0x15, 0x67, 0x51, 0x1f, 0x4d, 0x16, 0xe1, 0x4c, 0x79, 0x6d, + 0x8d, 0x36, 0xbc, 0x30, 0xf4, 0xf3, 0x62, 0x18, 0x84, 0x95, 0x87, 0xba, 0x15, 0xf8, 0x30, 0x74, + 0x34, 0x06, 0x1b, 0x49, 0x2d, 0x47, 0x56, 0xe0, 0x5c, 0x1c, 0x5e, 0xe3, 0x5b, 0x80, 0xa2, 0x14, + 0xfd, 0x36, 0xc1, 0x91, 0xff, 0xa7, 0x65, 0x94, 0x4d, 0x6b, 0x25, 0x4e, 0xd5, 0xfd, 0xbd, 0x5a, + 0x89, 0xf3, 0x76, 0x6a, 0x39, 0xf5, 0x5b, 0x05, 0x39, 0x7f, 0xd9, 0x93, 0xeb, 0x70, 0x75, 0x2b, + 0xe2, 0x66, 0xbd, 0xdb, 0x21, 0xf3, 0x8a, 0x88, 0x20, 0x62, 0x74, 0x1d, 0xdf, 0x23, 0x31, 0x88, + 0x60, 0x80, 0x40, 0x79, 0x1d, 0x0a, 0x28, 0x49, 0x15, 0x8a, 0x65, 0xa7, 0xc9, 0xcd, 0xdb, 0x9d, + 0x1e, 0x55, 0xe9, 0x4e, 0xd3, 0x4d, 0x7f, 0x54, 0xc5, 0x58, 0xa8, 0x7f, 0x36, 0xdf, 0x23, 0xe5, + 0xd8, 0x13, 0x39, 0x89, 0xfc, 0x85, 0x7c, 0x56, 0xf2, 0xb0, 0xe3, 0xea, 0x3a, 0xf6, 0x21, 0x0b, + 0xe7, 0x78, 0xfb, 0xd5, 0x1d, 0xa2, 0x70, 0x7e, 0x3f, 0x9f, 0x95, 0x09, 0xed, 0x44, 0x38, 0xfb, + 0x9b, 0x20, 0x53, 0x45, 0xfa, 0x04, 0xdb, 0xdc, 0xb2, 0x2a, 0xf4, 0xef, 0xd3, 0x7d, 0x2a, 0x4d, + 0xa4, 0x27, 0x43, 0xf8, 0x40, 0x5a, 0xfa, 0x07, 0xf9, 0xcc, 0x8c, 0x7f, 0x27, 0x32, 0x3d, 0x4c, + 0x99, 0x9e, 0x0c, 0xfd, 0x03, 0x0d, 0xfd, 0x54, 0x99, 0x9e, 0x8c, 0xfd, 0x03, 0xe9, 0xe9, 0xef, + 0xe5, 0xd3, 0x73, 0x5a, 0x1e, 0x81, 0x92, 0x1e, 0x86, 0x87, 0xa3, 0xdf, 0x0d, 0xc5, 0x03, 0x75, + 0x43, 0xff, 0x01, 0xac, 0xa8, 0xa4, 0x40, 0x8f, 0x6c, 0xd4, 0x7f, 0x5c, 0x05, 0x7a, 0x08, 0x43, + 0xfe, 0x49, 0x16, 0xe8, 0x4f, 0x14, 0x92, 0x79, 0x5c, 0x9f, 0xd4, 0x35, 0xc9, 0xd9, 0xe7, 0x9a, + 0xe4, 0x97, 0x23, 0xef, 0xc0, 0xa9, 0x50, 0x96, 0x72, 0xe4, 0x2f, 0xbc, 0x3e, 0x6a, 0x30, 0x54, + 0xfd, 0x7d, 0x86, 0x13, 0x21, 0x6a, 0xe2, 0xd4, 0xea, 0xf7, 0x0a, 0xc9, 0x64, 0xb8, 0x27, 0xbd, + 0xb1, 0xcf, 0xde, 0xb8, 0x07, 0xe7, 0xa6, 0xbb, 0x8e, 0x43, 0x2d, 0x2f, 0xbd, 0x53, 0xf0, 0xf0, + 0xbe, 0xc1, 0x29, 0xea, 0xc9, 0xce, 0xc9, 0x28, 0xcc, 0xd8, 0x8a, 0xd7, 0x0d, 0x71, 0xb6, 0x03, + 0x21, 0xdb, 0x2e, 0xa7, 0x48, 0x63, 0x9b, 0x5e, 0x58, 0xfd, 0x47, 0xf9, 0x64, 0xfa, 0xe2, 0x93, + 0xae, 0xdf, 0x5f, 0xd7, 0xab, 0x5f, 0x2d, 0xc4, 0x53, 0x38, 0x9f, 0x2c, 0x10, 0xfb, 0xef, 0x0e, + 0x5f, 0x92, 0x38, 0x6e, 0xa4, 0xaf, 0xf0, 0xe1, 0x59, 0x5f, 0xe1, 0xe3, 0xd5, 0x5f, 0x2e, 0xc6, + 0xd3, 0x61, 0x9f, 0x74, 0xc7, 0xd1, 0x75, 0x07, 0x59, 0x82, 0x33, 0x62, 0x6e, 0xf3, 0x41, 0x98, + 0x02, 0x42, 0xcc, 0x5f, 0x3c, 0x93, 0x9c, 0x98, 0x16, 0xbb, 0x2e, 0x75, 0xea, 0x9e, 0xee, 0x3e, + 0xac, 0x63, 0xce, 0x08, 0x2d, 0xb5, 0x20, 0x63, 0x28, 0x66, 0xb5, 0x28, 0xc3, 0xc1, 0x90, 0xa1, + 0x3f, 0x21, 0x26, 0x18, 0xa6, 0x15, 0x54, 0x7f, 0x23, 0x07, 0xe3, 0xf1, 0xcf, 0x21, 0xd7, 0x61, + 0x90, 0xfd, 0x0e, 0x9e, 0xdd, 0x4b, 0x79, 0xaa, 0x39, 0x47, 0x7e, 0x25, 0xef, 0xd3, 0x90, 0x57, + 0x61, 0x08, 0xbd, 0x1f, 0xb0, 0x40, 0x3e, 0x8c, 0x76, 0x10, 0x16, 0xc0, 0xe4, 0xa9, 0xbc, 0x58, + 0x48, 0x4a, 0xde, 0x84, 0xe1, 0x6a, 0xe8, 0xe6, 0x25, 0xee, 0xbc, 0xd0, 0xbb, 0x54, 0x2a, 0x19, + 0x12, 0x68, 0x32, 0xb5, 0xfa, 0x9d, 0x7c, 0x3c, 0x6d, 0xfb, 0x89, 0xaa, 0xef, 0x4f, 0xd5, 0x9f, + 0x5f, 0xe0, 0xaa, 0x7e, 0xd7, 0xb4, 0x0c, 0x72, 0x01, 0xce, 0xde, 0xab, 0xcd, 0x68, 0xf5, 0xbb, + 0xd5, 0xc5, 0x4a, 0xfd, 0xde, 0x62, 0x6d, 0x79, 0x66, 0xba, 0x3a, 0x5b, 0x9d, 0xa9, 0x8c, 0xf7, + 0x91, 0xd3, 0x70, 0x2a, 0x44, 0xcd, 0xdd, 0x5b, 0x28, 0x2f, 0x8e, 0xe7, 0xc8, 0x04, 0x8c, 0x86, + 0xc0, 0xa9, 0xa5, 0x95, 0xf1, 0xfc, 0xf3, 0x9f, 0x82, 0x61, 0x74, 0x6f, 0xe3, 0xd7, 0xf1, 0x64, + 0x04, 0x06, 0x97, 0xa6, 0x6a, 0x33, 0xda, 0x7d, 0x64, 0x02, 0x50, 0xaa, 0xcc, 0x2c, 0x32, 0x86, + 0xb9, 0xe7, 0xff, 0xef, 0x1c, 0x40, 0x6d, 0x76, 0x65, 0x59, 0x10, 0x0e, 0xc3, 0x40, 0x75, 0xf1, + 0x7e, 0x79, 0xbe, 0xca, 0xe8, 0x06, 0xa1, 0xb8, 0xb4, 0x3c, 0xc3, 0x6a, 0x18, 0x82, 0xfe, 0xe9, + 0xf9, 0xa5, 0xda, 0xcc, 0x78, 0x9e, 0x01, 0xb5, 0x99, 0x72, 0x65, 0xbc, 0xc0, 0x80, 0x0f, 0xb4, + 0xea, 0xca, 0xcc, 0x78, 0x91, 0xfd, 0x39, 0x5f, 0x5b, 0x29, 0xaf, 0x8c, 0xf7, 0xb3, 0x3f, 0x67, + 0xf1, 0xcf, 0x12, 0x63, 0x56, 0x9b, 0x59, 0xc1, 0x1f, 0x03, 0xac, 0x09, 0xb3, 0xfe, 0xaf, 0x41, + 0x86, 0x62, 0xac, 0x2b, 0x55, 0x6d, 0x7c, 0x88, 0xfd, 0x60, 0x2c, 0xd9, 0x0f, 0x60, 0x8d, 0xd3, + 0x66, 0x16, 0x96, 0xee, 0xcf, 0x8c, 0x0f, 0x33, 0x5e, 0x0b, 0x77, 0x19, 0x78, 0x84, 0xfd, 0xa9, + 0x2d, 0xb0, 0x3f, 0x47, 0x19, 0x27, 0x6d, 0xa6, 0x3c, 0xbf, 0x5c, 0x5e, 0x99, 0x1b, 0x1f, 0x63, + 0xed, 0x41, 0x9e, 0xa7, 0x78, 0xc9, 0xc5, 0xf2, 0xc2, 0xcc, 0xf8, 0xb8, 0xa0, 0xa9, 0xcc, 0x57, + 0x17, 0xef, 0x8e, 0x4f, 0x60, 0x43, 0xde, 0x5b, 0xc0, 0x1f, 0x84, 0x15, 0xc0, 0xbf, 0x4e, 0x3f, + 0xff, 0xfd, 0x50, 0x5a, 0xaa, 0xe1, 0x28, 0x38, 0x0f, 0xa7, 0x97, 0x6a, 0xf5, 0x95, 0xf7, 0x96, + 0x67, 0x62, 0xf2, 0x9e, 0x80, 0x51, 0x1f, 0x31, 0x5f, 0x5d, 0xbc, 0xf7, 0x05, 0x2e, 0x6d, 0x1f, + 0xb4, 0x50, 0x9e, 0x5e, 0xaa, 0x8d, 0xe7, 0x59, 0xaf, 0xf8, 0xa0, 0x07, 0xd5, 0xc5, 0xca, 0xd2, + 0x83, 0xda, 0x78, 0xe1, 0xf9, 0x47, 0x30, 0xc2, 0x73, 0x67, 0x2e, 0x39, 0x66, 0xd3, 0xb4, 0xc8, + 0xd3, 0x70, 0xa1, 0x32, 0x73, 0xbf, 0x3a, 0x3d, 0x53, 0x5f, 0xd2, 0xaa, 0xb7, 0xab, 0x8b, 0xb1, + 0x9a, 0xce, 0xc2, 0x44, 0x14, 0x5d, 0x5e, 0xae, 0x8e, 0xe7, 0xc8, 0x39, 0x20, 0x51, 0xf0, 0x9d, + 0xf2, 0xc2, 0xec, 0x78, 0x9e, 0x28, 0x70, 0x26, 0x0a, 0xaf, 0x2e, 0xae, 0xdc, 0x5b, 0x9c, 0x19, + 0x2f, 0x3c, 0xff, 0x57, 0x73, 0x70, 0x36, 0x35, 0xbe, 0x32, 0x51, 0xe1, 0xf2, 0xcc, 0x7c, 0xb9, + 0xb6, 0x52, 0x9d, 0xae, 0xcd, 0x94, 0xb5, 0xe9, 0xb9, 0xfa, 0x74, 0x79, 0x65, 0xe6, 0xf6, 0x92, + 0xf6, 0x5e, 0xfd, 0xf6, 0xcc, 0xe2, 0x8c, 0x56, 0x9e, 0x1f, 0xef, 0x23, 0xcf, 0xc1, 0x64, 0x06, + 0x4d, 0x6d, 0x66, 0xfa, 0x9e, 0x56, 0x5d, 0x79, 0x6f, 0x3c, 0x47, 0x9e, 0x85, 0xa7, 0x33, 0x89, + 0xd8, 0xef, 0xf1, 0x3c, 0xb9, 0x0c, 0x17, 0xb3, 0x48, 0xde, 0x9d, 0x1f, 0x2f, 0x3c, 0xff, 0xb3, + 0x39, 0x20, 0xc9, 0x00, 0xb9, 0xe4, 0x19, 0xb8, 0xc4, 0xf4, 0xa2, 0x9e, 0xdd, 0xc0, 0x67, 0xe1, + 0xe9, 0x54, 0x0a, 0xa9, 0x79, 0x93, 0xf0, 0x54, 0x06, 0x89, 0x68, 0xdc, 0x25, 0x50, 0xd2, 0x09, + 0xb0, 0x69, 0xbf, 0x9e, 0x83, 0xb3, 0xa9, 0x1e, 0x30, 0xe4, 0x2a, 0x7c, 0xa2, 0x5c, 0x59, 0x60, + 0x7d, 0x33, 0xbd, 0x52, 0x5d, 0x5a, 0xac, 0xd5, 0x17, 0x66, 0xcb, 0x75, 0xa6, 0x7d, 0xf7, 0x6a, + 0xb1, 0xde, 0xbc, 0x02, 0x6a, 0x0f, 0xca, 0xe9, 0xb9, 0xf2, 0xe2, 0x6d, 0x36, 0xfc, 0xc8, 0x27, + 0xe0, 0x99, 0x4c, 0xba, 0x99, 0xc5, 0xf2, 0xd4, 0xfc, 0x4c, 0x65, 0x3c, 0x4f, 0x3e, 0x09, 0xcf, + 0x66, 0x52, 0x55, 0xaa, 0x35, 0x4e, 0x56, 0x98, 0xaa, 0x7c, 0xe7, 0x7f, 0xba, 0xdc, 0xf7, 0x9d, + 0x3f, 0xbc, 0x9c, 0xfb, 0xfd, 0x3f, 0xbc, 0x9c, 0xfb, 0xe7, 0x7f, 0x78, 0x39, 0xf7, 0xc5, 0x9b, + 0x7b, 0x09, 0x7c, 0xcc, 0xa7, 0xad, 0xd5, 0x12, 0xde, 0x46, 0xbf, 0xfc, 0xff, 0x07, 0x00, 0x00, + 0xff, 0xff, 0xd1, 0xef, 0x3e, 0x27, 0xe9, 0x7f, 0x01, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { @@ -20459,7 +20590,7 @@ func (m *SFTP) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Subsystem) Marshal() (dAtA []byte, err error) { +func (m *SFTPSummary) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -20469,12 +20600,12 @@ func (m *Subsystem) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Subsystem) MarshalTo(dAtA []byte) (int, error) { +func (m *SFTPSummary) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Subsystem) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *SFTPSummary) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -20483,42 +20614,22 @@ func (m *Subsystem) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if len(m.Error) > 0 { - i -= len(m.Error) - copy(dAtA[i:], m.Error) - i = encodeVarintEvents(dAtA, i, uint64(len(m.Error))) - i-- - dAtA[i] = 0x2a - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintEvents(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x22 - } - { - size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.FileTransferStats) > 0 { + for iNdEx := len(m.FileTransferStats) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.FileTransferStats[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x12 { - size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ServerMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -20526,43 +20637,198 @@ func (m *Subsystem) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintEvents(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ClientDisconnect) 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 *ClientDisconnect) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ClientDisconnect) 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.Reason) > 0 { - i -= len(m.Reason) - copy(dAtA[i:], m.Reason) - i = encodeVarintEvents(dAtA, i, uint64(len(m.Reason))) - i-- - dAtA[i] = 0x2a - } + dAtA[i] = 0x2a { - size, err := m.ServerMetadata.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.SessionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FileTransferStat) 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 *FileTransferStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FileTransferStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.BytesWritten != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.BytesWritten)) + i-- + dAtA[i] = 0x18 + } + if m.BytesRead != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.BytesRead)) + i-- + dAtA[i] = 0x10 + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Subsystem) 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 *Subsystem) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Subsystem) 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.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x2a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClientDisconnect) 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 *ClientDisconnect) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClientDisconnect) 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.Reason) > 0 { + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x2a + } + { + size, err := m.ServerMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -24254,20 +24520,20 @@ func (m *DatabaseSessionEnd) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n352, err352 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) - if err352 != nil { - return 0, err352 + n357, err357 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) + if err357 != nil { + return 0, err357 } - i -= n352 - i = encodeVarintEvents(dAtA, i, uint64(n352)) + i -= n357 + i = encodeVarintEvents(dAtA, i, uint64(n357)) i-- dAtA[i] = 0x32 - n353, err353 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) - if err353 != nil { - return 0, err353 + n358, err358 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) + if err358 != nil { + return 0, err358 } - i -= n353 - i = encodeVarintEvents(dAtA, i, uint64(n353)) + i -= n358 + i = encodeVarintEvents(dAtA, i, uint64(n358)) i-- dAtA[i] = 0x2a { @@ -24934,20 +25200,20 @@ func (m *WindowsDesktopSessionEnd) MarshalToSizedBuffer(dAtA []byte) (int, error i-- dAtA[i] = 0x5a } - n386, err386 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) - if err386 != nil { - return 0, err386 + n391, err391 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) + if err391 != nil { + return 0, err391 } - i -= n386 - i = encodeVarintEvents(dAtA, i, uint64(n386)) + i -= n391 + i = encodeVarintEvents(dAtA, i, uint64(n391)) i-- dAtA[i] = 0x52 - n387, err387 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) - if err387 != nil { - return 0, err387 + n392, err392 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) + if err392 != nil { + return 0, err392 } - i -= n387 - i = encodeVarintEvents(dAtA, i, uint64(n387)) + i -= n392 + i = encodeVarintEvents(dAtA, i, uint64(n392)) i-- dAtA[i] = 0x4a if len(m.DesktopLabels) > 0 { @@ -25281,12 +25547,12 @@ func (m *InstanceJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x52 - n401, err401 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.TokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.TokenExpires):]) - if err401 != nil { - return 0, err401 + n406, err406 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.TokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.TokenExpires):]) + if err406 != nil { + return 0, err406 } - i -= n401 - i = encodeVarintEvents(dAtA, i, uint64(n401)) + i -= n406 + i = encodeVarintEvents(dAtA, i, uint64(n406)) i-- dAtA[i] = 0x4a if m.Attributes != nil { @@ -30844,6 +31110,29 @@ func (m *OneOf_UserTaskDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *OneOf_SFTPSummary) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_SFTPSummary) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SFTPSummary != nil { + { + size, err := m.SFTPSummary.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xb + i-- + dAtA[i] = 0xfa + } + return len(dAtA) - i, nil +} func (m *StreamStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -30868,12 +31157,12 @@ func (m *StreamStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n648, err648 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) - if err648 != nil { - return 0, err648 + n654, err654 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) + if err654 != nil { + return 0, err654 } - i -= n648 - i = encodeVarintEvents(dAtA, i, uint64(n648)) + i -= n654 + i = encodeVarintEvents(dAtA, i, uint64(n654)) i-- dAtA[i] = 0x1a if m.LastEventIndex != 0 { @@ -31032,12 +31321,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xc2 } } - n652, err652 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) - if err652 != nil { - return 0, err652 + n658, err658 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) + if err658 != nil { + return 0, err658 } - i -= n652 - i = encodeVarintEvents(dAtA, i, uint64(n652)) + i -= n658 + i = encodeVarintEvents(dAtA, i, uint64(n658)) i-- dAtA[i] = 0x1 i-- @@ -31185,12 +31474,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x4a } - n656, err656 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err656 != nil { - return 0, err656 + n662, err662 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err662 != nil { + return 0, err662 } - i -= n656 - i = encodeVarintEvents(dAtA, i, uint64(n656)) + i -= n662 + i = encodeVarintEvents(dAtA, i, uint64(n662)) i-- dAtA[i] = 0x42 if len(m.KubernetesUsers) > 0 { @@ -36565,6 +36854,16 @@ func (m *AutoUpdateConfigCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -36632,6 +36931,16 @@ func (m *AutoUpdateConfigUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -36699,6 +37008,16 @@ func (m *AutoUpdateConfigDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -36766,6 +37085,16 @@ func (m *AutoUpdateVersionCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -36833,6 +37162,16 @@ func (m *AutoUpdateVersionUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -36900,6 +37239,16 @@ func (m *AutoUpdateVersionDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -39470,6 +39819,56 @@ func (m *SFTP) Size() (n int) { return n } +func (m *SFTPSummary) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.SessionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ServerMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + if len(m.FileTransferStats) > 0 { + for _, e := range m.FileTransferStats { + l = e.Size() + n += 1 + l + sovEvents(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *FileTransferStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Path) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + if m.BytesRead != 0 { + n += 1 + sovEvents(uint64(m.BytesRead)) + } + if m.BytesWritten != 0 { + n += 1 + sovEvents(uint64(m.BytesWritten)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *Subsystem) Size() (n int) { if m == nil { return 0 @@ -43803,6 +44202,18 @@ func (m *OneOf_UserTaskDelete) Size() (n int) { } return n } +func (m *OneOf_SFTPSummary) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SFTPSummary != nil { + l = m.SFTPSummary.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} func (m *StreamStatus) Size() (n int) { if m == nil { return 0 @@ -45914,6 +46325,8 @@ func (m *AutoUpdateConfigCreate) Size() (n int) { n += 1 + l + sovEvents(uint64(l)) l = m.ConnectionMetadata.Size() n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -45934,6 +46347,8 @@ func (m *AutoUpdateConfigUpdate) Size() (n int) { n += 1 + l + sovEvents(uint64(l)) l = m.ConnectionMetadata.Size() n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -45954,6 +46369,8 @@ func (m *AutoUpdateConfigDelete) Size() (n int) { n += 1 + l + sovEvents(uint64(l)) l = m.ConnectionMetadata.Size() n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -45974,6 +46391,8 @@ func (m *AutoUpdateVersionCreate) Size() (n int) { n += 1 + l + sovEvents(uint64(l)) l = m.ConnectionMetadata.Size() n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -45994,6 +46413,8 @@ func (m *AutoUpdateVersionUpdate) Size() (n int) { n += 1 + l + sovEvents(uint64(l)) l = m.ConnectionMetadata.Size() n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -46014,6 +46435,8 @@ func (m *AutoUpdateVersionDelete) Size() (n int) { n += 1 + l + sovEvents(uint64(l)) l = m.ConnectionMetadata.Size() n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -59903,6 +60326,377 @@ func (m *SFTP) Unmarshal(dAtA []byte) error { } return nil } +func (m *SFTPSummary) 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 ErrIntOverflowEvents + } + 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: SFTPSummary: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SFTPSummary: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FileTransferStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FileTransferStats = append(m.FileTransferStats, &FileTransferStat{}) + if err := m.FileTransferStats[len(m.FileTransferStats)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + 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 *FileTransferStat) 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 ErrIntOverflowEvents + } + 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: FileTransferStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FileTransferStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BytesRead", wireType) + } + m.BytesRead = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BytesRead |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BytesWritten", wireType) + } + m.BytesWritten = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BytesWritten |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + 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 *Subsystem) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -84241,50 +85035,85 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &CrownJewelUpdate{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Event = &OneOf_CrownJewelUpdate{v} - iNdEx = postIndex - case 184: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CrownJewelDelete", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &CrownJewelDelete{} + v := &CrownJewelUpdate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &OneOf_CrownJewelUpdate{v} + iNdEx = postIndex + case 184: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CrownJewelDelete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &CrownJewelDelete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &OneOf_CrownJewelDelete{v} + iNdEx = postIndex + case 188: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserTaskCreate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &UserTaskCreate{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Event = &OneOf_CrownJewelDelete{v} + m.Event = &OneOf_UserTaskCreate{v} iNdEx = postIndex - case 188: + case 189: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserTaskCreate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserTaskUpdate", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -84311,15 +85140,15 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &UserTaskCreate{} + v := &UserTaskUpdate{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Event = &OneOf_UserTaskCreate{v} + m.Event = &OneOf_UserTaskUpdate{v} iNdEx = postIndex - case 189: + case 190: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserTaskUpdate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserTaskDelete", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -84346,15 +85175,15 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &UserTaskUpdate{} + v := &UserTaskDelete{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Event = &OneOf_UserTaskUpdate{v} + m.Event = &OneOf_UserTaskDelete{v} iNdEx = postIndex - case 190: + case 191: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserTaskDelete", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SFTPSummary", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -84381,11 +85210,11 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &UserTaskDelete{} + v := &SFTPSummary{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Event = &OneOf_UserTaskDelete{v} + m.Event = &OneOf_SFTPSummary{v} iNdEx = postIndex default: iNdEx = preIndex @@ -101494,6 +102323,39 @@ func (m *AutoUpdateConfigCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -101677,6 +102539,39 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -101860,6 +102755,39 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -102043,6 +102971,39 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -102226,6 +103187,39 @@ func (m *AutoUpdateVersionUpdate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -102409,6 +103403,39 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) diff --git a/api/types/events/oneof.go b/api/types/events/oneof.go index 0188951054a1a..6e856b3c5f2b2 100644 --- a/api/types/events/oneof.go +++ b/api/types/events/oneof.go @@ -761,6 +761,35 @@ func ToOneOf(in AuditEvent) (*OneOf, error) { out.Event = &OneOf_UserTaskDelete{ UserTaskDelete: e, } + case *SFTPSummary: + out.Event = &OneOf_SFTPSummary{ + SFTPSummary: e, + } + case *AutoUpdateConfigCreate: + out.Event = &OneOf_AutoUpdateConfigCreate{ + AutoUpdateConfigCreate: e, + } + case *AutoUpdateConfigUpdate: + out.Event = &OneOf_AutoUpdateConfigUpdate{ + AutoUpdateConfigUpdate: e, + } + case *AutoUpdateConfigDelete: + out.Event = &OneOf_AutoUpdateConfigDelete{ + AutoUpdateConfigDelete: e, + } + + case *AutoUpdateVersionCreate: + out.Event = &OneOf_AutoUpdateVersionCreate{ + AutoUpdateVersionCreate: e, + } + case *AutoUpdateVersionUpdate: + out.Event = &OneOf_AutoUpdateVersionUpdate{ + AutoUpdateVersionUpdate: e, + } + case *AutoUpdateVersionDelete: + out.Event = &OneOf_AutoUpdateVersionDelete{ + AutoUpdateVersionDelete: e, + } default: slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType()) unknown := &Unknown{} diff --git a/build.assets/charts/smoke_tests/01_pam/test.sh b/build.assets/charts/smoke_tests/01_pam/test.sh index 442f2cea38d8f..8ae6c34f8f529 100755 --- a/build.assets/charts/smoke_tests/01_pam/test.sh +++ b/build.assets/charts/smoke_tests/01_pam/test.sh @@ -6,4 +6,8 @@ # # If teleport is still up when the timeout expires, then we're # probably OK -timeout --preserve-status 10s docker run --platform $1 --rm --entrypoint /usr/local/bin/teleport -v "$(pwd):/etc/teleport" $2 start -c /etc/teleport/config.yaml \ No newline at end of file +# +# A timeout of 20s is set to account for potentially slow startup times. +# QEMU eumlation may slow startup time for some platforms and during that +# time the process won't shutdown gracefully resulting in a nonzero code. +timeout --preserve-status 20s docker run --platform $1 --rm --entrypoint /usr/local/bin/teleport -v "$(pwd):/etc/teleport" $2 start -c /etc/teleport/config.yaml diff --git a/docs/pages/admin-guides/access-controls/access-lists/access-lists.mdx b/docs/pages/admin-guides/access-controls/access-lists/access-lists.mdx index c7501f5f6e368..0fca45b8f7297 100644 --- a/docs/pages/admin-guides/access-controls/access-lists/access-lists.mdx +++ b/docs/pages/admin-guides/access-controls/access-lists/access-lists.mdx @@ -11,4 +11,6 @@ traits, which then tie easily back into Teleport's existing RBAC system. [Getting Started with Access Lists](guide.mdx) +[Nested Access Lists](nested-access-lists.mdx) + [Access List Reference](../../../reference/access-controls/access-lists.mdx) diff --git a/docs/pages/admin-guides/access-controls/access-lists/guide.mdx b/docs/pages/admin-guides/access-controls/access-lists/guide.mdx index 42e5d5c81f6b8..081a5ff5d1ec7 100644 --- a/docs/pages/admin-guides/access-controls/access-lists/guide.mdx +++ b/docs/pages/admin-guides/access-controls/access-lists/guide.mdx @@ -13,7 +13,6 @@ This guide will help you: (!docs/pages/includes/commercial-prereqs-tabs.mdx!) - (!docs/pages/includes/tctl.mdx!) -- A running Teleport cluster. - A user with the preset `editor` role, which will have permissions to create Access Lists. ## Step 1/4. Setting up the Application Service on the cluster for testing @@ -68,7 +67,7 @@ not be able to manage the list, though they will still be reflected as an owner. Under "Members" select `requester` as a required role, then add your test user to the access list. Similar to the owner requirements, this will ensure that any member of the list must have the `requester` role in order to -be granted the access described in this list. If the user loses this role later, they will no be granted the +be granted the access described in this list. If the user loses this role later, they will not be granted the roles or traits described in the access list. ![Add a member](../../../../img/access-controls/access-lists/add-member.png) @@ -82,4 +81,5 @@ the cluster, and should be able to interact with it as expected. ## Next Steps -- Familiarize yourself with the CLI tooling available for managing access lists in the [reference](../../../reference/access-controls/access-lists.mdx). +- Familiarize yourself with the CLI tooling available for managing Access Lists in the [reference](../../../reference/access-controls/access-lists.mdx). +- Learn how to work with nested Access Lists in the [nested Access Lists guide](./nested-access-lists.mdx). diff --git a/docs/pages/admin-guides/access-controls/access-lists/nested-access-lists.mdx b/docs/pages/admin-guides/access-controls/access-lists/nested-access-lists.mdx new file mode 100644 index 0000000000000..611137dd609b6 --- /dev/null +++ b/docs/pages/admin-guides/access-controls/access-lists/nested-access-lists.mdx @@ -0,0 +1,83 @@ +--- +title: Nested Access Lists +description: Learn how to use nested Access Lists to manage complex permissions and grant inheritance in Teleport. +--- + +Nested Access Lists allow inclusion of an Access List as a member or owner of another Access List. +This enables hierarchical permission structures where permissions can be inherited from multiple levels of +parent Access Lists. + +This guide will help you: + +- Understand how nesting and inheritance work in Access Lists +- Create a nested Access List +- Verify inherited permissions granted through the nested Access List + +## How it works + +Let's break down inheritance in Access Lists. Imagine two Access Lists you might have in an organization: +"Engineering Team" and "Production Access". "Engineering Team" represents a group of engineers, while +"Production Access" is a higher-level Access List that grants access to production resources. + +- **Membership Inheritance**: If "Engineering Team" is added as a member of "Production Access", +all users who are members of "Engineering Team" inherit member grants (roles and traits) from "Production Access". +- **Ownership Inheritance**: If "Engineering Team" is added as an owner of "Production Access", +all users who are members of "Engineering Team" inherit owner grants (roles and traits) from "Production Access", and +can perform owner actions, such as modifying it or managing its members. + +Inheritance is recursive – members of "Engineering Team" can themselves be Access Lists +with their own members, and so on. However, circular nesting is not allowed, and nesting is limited +to a maximum depth of 10 levels. + +For more information, see the [Access Lists reference](../../../reference/access-controls/access-lists.mdx). + +## Prerequisites + +(!docs/pages/includes/commercial-prereqs-tabs.mdx!) + +- (!docs/pages/includes/tctl.mdx!) +- A user with the default `editor` role or equivalent permissions (ability to read, create, and manage Access Lists). +- Familiarity with basic Access List concepts (see the [Getting Started with Access Lists guide](./guide.mdx)). +- At least one user with only the `requester` role to add to the Access List. +- At least one application or resource to grant access to. + +Let's walk through creating a nested Access List and establishing inheritance. In this example, we'll +create a child Access List, "Engineering Team", which inherits permissions from a parent, "Production Access". + +## Step 1/3. Create child Access List + +In the Teleport Web UI, go to the "Identity" tab and select "Access Lists" from the sidebar. +Click on "Create New Access List", and fill in the details: + +- **Title**: Engineering Team +- **Deadline for First Review**: Select a future date. +- **Member Grants**: Leave this empty, as the list will inherit the parent's member grants. +- **Owners**: Add yourself or any appropriate users as owners. +- **Members**: Add users who should be part of this Access List, such as `test-user`. + +Click "Create Access List" to save the Access List. + +## Step 2/3. Create parent Access List + +From the "Access Lists" page, click on "Create New Access List" and fill in the details for our parent list: + +- **Title**: Production Access +- **Deadline for First Review**: Select a future date. +- **Member Grants**: Add the `access` role. +- **Owners**: Add yourself or any appropriate users as owners. +- **Members**: Select our child Access List, 'Engineering Team', from the dropdown. + +Click "Create Access List" to save the Access List. + +## Step 3/3. Verifying inherited permissions + +To confirm that members of "Engineering Team" have inherited member grants from "Production Access", log in as a user +who is a member of the child Access List (e.g., `test-user`). Verify that the user now has access to resources +granted by both "Engineering Team" and "Production Access". For example, if a Teleport Application Service +instance with the debugging application enabled is set up, and the `access` role is granted through "Production Access", +the "dumper" app should be visible to the user. + +## Next Steps + +- Review the [Access Lists reference](../../../reference/access-controls/access-lists.mdx) for more detailed information on Access Lists' nesting and inheritance. +- Learn how nested Access Lists work with Okta/SCIM synchronization in [Synchronization with Okta and SCIM](../../../enroll-resources/application-access/okta/sync-scim.mdx). diff --git a/docs/pages/enroll-resources/application-access/okta/sync-scim.mdx b/docs/pages/enroll-resources/application-access/okta/sync-scim.mdx index bcd6f6b9ac0e7..9535796d2cc41 100644 --- a/docs/pages/enroll-resources/application-access/okta/sync-scim.mdx +++ b/docs/pages/enroll-resources/application-access/okta/sync-scim.mdx @@ -26,14 +26,14 @@ Teleport. ### Importing users -During synchronization, the Okta integration will create Teleport user accounts +During synchronization, the Okta integration will create Teleport user accounts for all eligible Okta users, and clean up the Teleport accounts of any Okta users that have been deactivated. The list of "eligible Okta users" depends on the -integration configuration. +integration configuration. If the Okta integration is configured to use a specific Okta application, then -the Okta integration will consider any Okta user assigned to that Okta -application - either directly, or via group membership - as an "eligible user". +the Okta integration will consider any Okta user assigned to that Okta +application - either directly, or via group membership - as an "eligible user". If no Okta application is to use is supplied, all enabled Okta organization users are considered "eligible". @@ -54,7 +54,7 @@ administer and secure. The Teleport users created by the synchronization process or SCIM provisioning all inherit their username from the upstream Okta organization, and are given a -default role of `okta-requester`. +default role of `okta-requester`. This Role allows the user to log into Teleport, but grants no default access to Teleport resources. The Teleport admin can use Access Requests and Access Lists @@ -93,13 +93,13 @@ resources. ### Deleting Users -In the case where +Given a case where 1. the synchronization process detects that an Okta user has been deactivated - or suspended, or - 1. the Okta organization explicitly disables the account via SCIM, - + or suspended, or + 1. the Okta organization explicitly disables the account via SCIM, + The Okta integration will immediately delete the corresponding Teleport -account and create a temporary Teleport user lock. The user lock will +account and create a temporary Teleport user lock. The user lock will - terminate any active Teleport sessions, and - prevent the disabled user from accessing any Teleport resources with credentials issued before their Teleport account was deleted. @@ -147,6 +147,53 @@ The synchronizer will create the following resources for each matched group or a It should be noted that the Access List sync waits until the Okta groups and Okta applications has finished syncing as Teleport resources, so it may not start synchronizing immediately on startup. +### Handling nested Access Lists + +#### Synchronization from Teleport to Okta + +Teleport supports nested Access Lists, where an Access List can include other Access Lists as members, +creating a hierarchical structure. However, Okta does not support nested groups. +To accommodate this limitation, the synchronizer flattens nested Access Lists when synchronizing from Teleport to Okta. + +Members in Access Lists, from all levels of nesting, are aggregated into a single, flat list of members when +synchronized to Okta. This ensures that all users who should have access according to the Teleport hierarchy +are included in the corresponding Okta group or application. + +**Example**: + - **Teleport Structure**: + - **Access List A**: + - Members: User1 + - Nested Members: Access List B + - **Access List B**: + - Members: User2, User3 + - **Okta Representation**: + - Group/Application for Access List A: + - Members: User1, User2, User3 + +By flattening the Teleport hierarchy, all users receive the permissions associated with the root-level Access List in Okta. + +#### Synchronization from Okta to Teleport + +When synchronizing from Okta to Teleport, the synchronizer handles the flattened structure from Okta +by attempting to map it back to the Teleport hierarchy: + +- **Comparing with Teleport Hierarchy**: The flattened list of members from Okta is compared against the existing +Access List hierarchy in Teleport. +- **Adding New Members**: + - **New Users**: If there are new users added in Okta that are not present in the Teleport Access List hierarchy, + these users are added as members at the root-level Access List in Teleport. + - **Maintaining Hierarchy**: This approach maintains the hierarchical structure within Teleport while ensuring + that access changes made in Okta are reflected appropriately. +- **Example**: + - **Okta Group/Application for Access List A**: + - Members: User1, User2, User3, User4 (User4 is a new member added in Okta) + - **Teleport Update**: + - **Access List A**: + - Members: User1, User4 + - Nested Members: Access List B + - **Access List B**: + - Members: User2, User3 + #### Deletion of Access Lists Access Lists synchronized from Okta will automatically be deleted when there are no members assigned to them in diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 7e630c2f970a1..7e6df4e91ff19 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -102,10 +102,20 @@ Get started with Teleport Identity: ### Teleport Policy **Teleport Policy** unifies and controls access policies across all your -infrastructure. With Teleport Policy’s Access Graph feature, you gain insights into role-based -access control policies within Teleport and your cloud provider. - -Get started with [Teleport Policy](admin-guides/teleport-policy/teleport-policy.mdx). +infrastructure. With Teleport Policy’s Access Graph feature, you gain insights +into role-based access control policies within Teleport, your cloud providers, +and critical infrastructure. + +- Get started with [Teleport + Policy](admin-guides/teleport-policy/teleport-policy.mdx). +- Define [Crown Jewels](admin-guides/teleport-policy/crown-jewels.mdx) so you + can track changes to your most sensitive users and resources. +- Enable [Teleport Policy + integrations](admin-guides/teleport-policy/integrations/integrations.mdx) so + you can identify [insecure SSH key + distributions](admin-guides/teleport-policy/integrations/ssh-keys-scan.mdx), and + import RBAC rules from AWS, Entra ID, and other sources to visualize your + entire RBAC configuration in on a single screen. ## Architecture diff --git a/docs/pages/reference/access-controls/access-lists.mdx b/docs/pages/reference/access-controls/access-lists.mdx index e36b2c143bf3e..033f03a6c7001 100644 --- a/docs/pages/reference/access-controls/access-lists.mdx +++ b/docs/pages/reference/access-controls/access-lists.mdx @@ -29,10 +29,10 @@ to live on the order of hours or days. ## Access List Ownership -Access List owners are Teleport users who are granted special privileges over +Access List owners are Teleport users or nested Access Lists who are granted special privileges over an Access List. These owners are defined explicitly as part of the Access List, and must be added by a Teleport user who has RBAC access to access lists, which the preset `editor` -role has.. Owners must meet requirements in order for their ownership to be effective. +role has. Owners must meet requirements in order for their ownership to be effective. Provided owners meet requirements, owners are able to do the following: @@ -46,14 +46,51 @@ and traits are granted by the Access List. ## Access List Membership -Access List members are Teleport users who are granted the roles and traits specified -by the Access List. Upon login, users will be granted these roles and traits along with -their statically defined user permissions. These roles and traits will then tie into -Teleport's existing RBAC system. Members can be optionally granted an expire date, after -which their membership will no longer confer any grants to the user. +Access List members are Teleport users or nested Access Lists who are granted the roles +and traits specified by the Access List. Upon login, users will be granted these +roles and traits along with their statically defined user permissions. These roles and +traits will then tie into Teleport's existing RBAC system. Members can be optionally +granted an expiry date, after which their membership will no longer confer any +grants to the user. Members must meet requirements in order for their membership to be effective. +## Nested Access Lists + +Access Lists can be nested within other Access Lists as members or owners. This enables +hierarchical permission structures where permissions can be inherited from multiple levels of +parent Access Lists. Inheritance is recursive – members of a child Access List can +themselves be Access Lists with their own members, and so on. + +### Membership Inheritance + +If an Access List is a member of another Access List, members of the nested Access List will +inherit the member grants (roles and traits) of the parent Access List. + +Users granted membership through inheritance must meet both the nested Access List's membership +requirements, and the parent Access List's membership requirements in order for the +membership to be valid. + +### Ownership Inheritance + +If an Access List is an owner of another Access List, members of the nested Access List will +inherit the owner grants (roles and traits), as well as ownership of, the parent Access List. + +Users granted ownership through inheritance must meet both the nested Access List's +membership requirements, and the parent Access List's ownership requirements in order +for the ownership to be valid. + +### Limitations + +- **Circular Nesting**: Circular nesting is not allowed. Access Lists' membership and +ownership cannot be self-referential, directly or indirectly. +- **Nesting Depth**: Nesting is limited to a maximum depth of 10 levels. This means that +a child Access List cannot be more than 10 levels removed from the root Access List in +the hierarchy. +- **Deletion**: Deleting Access Lists that are members or owners of other Access Lists +is not allowed. Access Lists must be removed from all parent Access Lists before they +can be deleted. + ## Access List Auditing Access Lists must be defined with an audit frequency, which specifies how often the @@ -91,12 +128,13 @@ spec: start: 336h # two weeks next_audit_date: "2025-01-01T00:00:00Z" description: "A description of the Access List and its purpose" - # owners are a list of Teleport users who own the Access List. Provided the owners - # meet the ownership requirements, these users can control membership requirements - # and membership to the Access List. + # owners are a list of Teleport users or Access Lists who own the Access List. + # Provided the owners meet the ownership requirements, these users can control + # membership requirements and membership to the Access List. owners: - description: test user 1 name: teleport-admin + membership_kind: MEMBERSHIP_KIND_USER # ownership_requires defines roles and traits that are required for an owner to be # able to manage the Access List and its membership. ownership_requires: @@ -116,7 +154,7 @@ spec: roles: - access traits: - trait1: + trait1: - value1 # membership_requires defines roles and traits that are required for a member # to be granted the above roles and traits. Even if a user has been added as a @@ -126,10 +164,17 @@ spec: roles: - required_role1 traits: - required_trait1: + required_trait1: - required_value1 ``` +## Access Lists and Deny Rules + +Use of [deny rules](./roles.mdx) in Access List roles is discouraged. +Access Lists are not intended to be used as a tool for privilege reduction, +and Teleport may assume it is safe to ignore Access Lists under certain conditions. +Roles intended to reduce privileges should be assigned directly to users. + ## Managing Access Lists from the CLI In addition to using the web UI, Access Lists can be created and managed from the CLI diff --git a/docs/pages/reference/access-controls/roles.mdx b/docs/pages/reference/access-controls/roles.mdx index 2b17fd62d9189..012ecafa6a2c7 100644 --- a/docs/pages/reference/access-controls/roles.mdx +++ b/docs/pages/reference/access-controls/roles.mdx @@ -12,6 +12,7 @@ A Teleport role manages access by having two lists of rules: `allow` rules and - Nothing is allowed by default. - Deny rules get evaluated first and take priority. +- Deny rules should be avoided on roles granted through Access Lists. You can use any of the following to manage Teleport roles and other dynamic resources: @@ -571,7 +572,7 @@ attribute or OIDC claim called `trait`. You can specify an external trait in dot syntax if it begins with a letter and contains only letters, numbers, and underscores. Otherwise, you must use bracket -syntax to specify a trait. +syntax to specify a trait. When using Azure AD or ADFS as your IdP, you must use bracket notation, as these IdPs assign attribute keys to URLs such as the following: diff --git a/docs/pages/reference/operator-resources/resources.teleport.dev_accesslists.mdx b/docs/pages/reference/operator-resources/resources.teleport.dev_accesslists.mdx index 009cf351b2980..5b9d66fc1ea3e 100644 --- a/docs/pages/reference/operator-resources/resources.teleport.dev_accesslists.mdx +++ b/docs/pages/reference/operator-resources/resources.teleport.dev_accesslists.mdx @@ -83,6 +83,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |---|---|---| |description|string|description is the plaintext description of the owner and why they are an owner.| |ineligible_status|string or integer|ineligible_status describes if this owner is eligible or not and if not, describes how they're lacking eligibility. Can be either the string or the integer representation of each option.| +|membership_kind|string or integer|membership_kind describes the type of membership, either `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. Can be either the string or the integer representation of each option.| |name|string|name is the username of the owner.| ### spec.ownership_requires diff --git a/docs/pages/reference/terraform-provider/data-sources/access_list.mdx b/docs/pages/reference/terraform-provider/data-sources/access_list.mdx index b5ddd133fdb07..48cd5e48c0b51 100644 --- a/docs/pages/reference/terraform-provider/data-sources/access_list.mdx +++ b/docs/pages/reference/terraform-provider/data-sources/access_list.mdx @@ -113,6 +113,7 @@ Optional: Optional: - `description` (String) description is the plaintext description of the owner and why they are an owner. +- `membership_kind` (Number) membership_kind describes the type of membership, either `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. - `name` (String) name is the username of the owner. diff --git a/docs/pages/reference/terraform-provider/resources/access_list.mdx b/docs/pages/reference/terraform-provider/resources/access_list.mdx index 974584d3714ec..e45b98b603069 100644 --- a/docs/pages/reference/terraform-provider/resources/access_list.mdx +++ b/docs/pages/reference/terraform-provider/resources/access_list.mdx @@ -155,6 +155,7 @@ Optional: Optional: - `description` (String) description is the plaintext description of the owner and why they are an owner. +- `membership_kind` (Number) membership_kind describes the type of membership, either `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. - `name` (String) name is the username of the owner. diff --git a/e b/e index 91f2b752c1547..de03ce5fe4729 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit 91f2b752c154770eb08328307665037e5a9c8dac +Subproject commit de03ce5fe47298140975f9ac8cd5be71f98d3ff8 diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_accesslists.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_accesslists.yaml index 802e2a4f13a11..2c595617b69d3 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_accesslists.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_accesslists.yaml @@ -153,6 +153,10 @@ spec: description: ineligible_status describes if this owner is eligible or not and if not, describes how they're lacking eligibility. x-kubernetes-int-or-string: true + membership_kind: + description: membership_kind describes the type of membership, + either `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + x-kubernetes-int-or-string: true name: description: name is the username of the owner. type: string diff --git a/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts b/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts index 11062df8a111e..58f76b98dd6e8 100644 --- a/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts +++ b/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts @@ -145,6 +145,13 @@ export interface AccessListOwner { * @generated from protobuf field: teleport.accesslist.v1.IneligibleStatus ineligible_status = 3; */ ineligibleStatus: IneligibleStatus; + /** + * membership_kind describes the type of membership, either + * `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + * + * @generated from protobuf field: teleport.accesslist.v1.MembershipKind membership_kind = 4; + */ + membershipKind: MembershipKind; } /** * AccessListAudit describes the audit configuration for an Access List. @@ -319,6 +326,13 @@ export interface MemberSpec { * @generated from protobuf field: teleport.accesslist.v1.IneligibleStatus ineligible_status = 7; */ ineligibleStatus: IneligibleStatus; + /** + * membership_kind describes the type of membership, either + * `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + * + * @generated from protobuf field: teleport.accesslist.v1.MembershipKind membership_kind = 9; + */ + membershipKind: MembershipKind; } /** * Review is a review of an Access List. @@ -418,11 +432,29 @@ export interface ReviewChanges { */ export interface AccessListStatus { /** - * member_count is the number of members in the in the Access List. + * member_count is the number of members in the Access List. * * @generated from protobuf field: optional uint32 member_count = 1; */ memberCount?: number; + /** + * member_list_count is the number of nested list members in the Access List. + * + * @generated from protobuf field: optional uint32 member_list_count = 2; + */ + memberListCount?: number; + /** + * owner_of describes Access Lists where this Access List is an explicit owner. + * + * @generated from protobuf field: repeated string owner_of = 3; + */ + ownerOf: string[]; + /** + * member_of describes Access Lists where this Access List is an explicit member. + * + * @generated from protobuf field: repeated string member_of = 4; + */ + memberOf: string[]; } /** * ReviewFrequency is the frequency of reviews. @@ -474,6 +506,32 @@ export enum ReviewDayOfMonth { */ LAST = 31 } +/** + * MembershipKind represents the different kinds of list membership + * + * @generated from protobuf enum teleport.accesslist.v1.MembershipKind + */ +export enum MembershipKind { + /** + * MEMBERSHIP_KIND_UNSPECIFIED represents list members that are of + * unknown membership kind, defaulting to being treated as type USER + * + * @generated from protobuf enum value: MEMBERSHIP_KIND_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + /** + * MEMBERSHIP_KIND_USER represents list members that are normal users + * + * @generated from protobuf enum value: MEMBERSHIP_KIND_USER = 1; + */ + USER = 1, + /** + * MEMBERSHIP_KIND_LIST represents list members that are nested Access Lists + * + * @generated from protobuf enum value: MEMBERSHIP_KIND_LIST = 2; + */ + LIST = 2 +} /** * IneligibleStatus describes how the user is ineligible. * @@ -679,7 +737,8 @@ class AccessListOwner$Type extends MessageType { super("teleport.accesslist.v1.AccessListOwner", [ { no: 1, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 2, name: "description", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 3, name: "ineligible_status", kind: "enum", T: () => ["teleport.accesslist.v1.IneligibleStatus", IneligibleStatus, "INELIGIBLE_STATUS_"] } + { no: 3, name: "ineligible_status", kind: "enum", T: () => ["teleport.accesslist.v1.IneligibleStatus", IneligibleStatus, "INELIGIBLE_STATUS_"] }, + { no: 4, name: "membership_kind", kind: "enum", T: () => ["teleport.accesslist.v1.MembershipKind", MembershipKind, "MEMBERSHIP_KIND_"] } ]); } create(value?: PartialMessage): AccessListOwner { @@ -687,6 +746,7 @@ class AccessListOwner$Type extends MessageType { message.name = ""; message.description = ""; message.ineligibleStatus = 0; + message.membershipKind = 0; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -705,6 +765,9 @@ class AccessListOwner$Type extends MessageType { case /* teleport.accesslist.v1.IneligibleStatus ineligible_status */ 3: message.ineligibleStatus = reader.int32(); break; + case /* teleport.accesslist.v1.MembershipKind membership_kind */ 4: + message.membershipKind = reader.int32(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -726,6 +789,9 @@ class AccessListOwner$Type extends MessageType { /* teleport.accesslist.v1.IneligibleStatus ineligible_status = 3; */ if (message.ineligibleStatus !== 0) writer.tag(3, WireType.Varint).int32(message.ineligibleStatus); + /* teleport.accesslist.v1.MembershipKind membership_kind = 4; */ + if (message.membershipKind !== 0) + writer.tag(4, WireType.Varint).int32(message.membershipKind); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -1070,7 +1136,8 @@ class MemberSpec$Type extends MessageType { { no: 4, name: "expires", kind: "message", T: () => Timestamp }, { no: 5, name: "reason", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 6, name: "added_by", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 7, name: "ineligible_status", kind: "enum", T: () => ["teleport.accesslist.v1.IneligibleStatus", IneligibleStatus, "INELIGIBLE_STATUS_"] } + { no: 7, name: "ineligible_status", kind: "enum", T: () => ["teleport.accesslist.v1.IneligibleStatus", IneligibleStatus, "INELIGIBLE_STATUS_"] }, + { no: 9, name: "membership_kind", kind: "enum", T: () => ["teleport.accesslist.v1.MembershipKind", MembershipKind, "MEMBERSHIP_KIND_"] } ]); } create(value?: PartialMessage): MemberSpec { @@ -1080,6 +1147,7 @@ class MemberSpec$Type extends MessageType { message.reason = ""; message.addedBy = ""; message.ineligibleStatus = 0; + message.membershipKind = 0; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -1110,6 +1178,9 @@ class MemberSpec$Type extends MessageType { case /* teleport.accesslist.v1.IneligibleStatus ineligible_status */ 7: message.ineligibleStatus = reader.int32(); break; + case /* teleport.accesslist.v1.MembershipKind membership_kind */ 9: + message.membershipKind = reader.int32(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -1143,6 +1214,9 @@ class MemberSpec$Type extends MessageType { /* teleport.accesslist.v1.IneligibleStatus ineligible_status = 7; */ if (message.ineligibleStatus !== 0) writer.tag(7, WireType.Varint).int32(message.ineligibleStatus); + /* teleport.accesslist.v1.MembershipKind membership_kind = 9; */ + if (message.membershipKind !== 0) + writer.tag(9, WireType.Varint).int32(message.membershipKind); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -1357,11 +1431,16 @@ export const ReviewChanges = new ReviewChanges$Type(); class AccessListStatus$Type extends MessageType { constructor() { super("teleport.accesslist.v1.AccessListStatus", [ - { no: 1, name: "member_count", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ } + { no: 1, name: "member_count", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ }, + { no: 2, name: "member_list_count", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "owner_of", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "member_of", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): AccessListStatus { const message = globalThis.Object.create((this.messagePrototype!)); + message.ownerOf = []; + message.memberOf = []; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -1374,6 +1453,15 @@ class AccessListStatus$Type extends MessageType { case /* optional uint32 member_count */ 1: message.memberCount = reader.uint32(); break; + case /* optional uint32 member_list_count */ 2: + message.memberListCount = reader.uint32(); + break; + case /* repeated string owner_of */ 3: + message.ownerOf.push(reader.string()); + break; + case /* repeated string member_of */ 4: + message.memberOf.push(reader.string()); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -1389,6 +1477,15 @@ class AccessListStatus$Type extends MessageType { /* optional uint32 member_count = 1; */ if (message.memberCount !== undefined) writer.tag(1, WireType.Varint).uint32(message.memberCount); + /* optional uint32 member_list_count = 2; */ + if (message.memberListCount !== undefined) + writer.tag(2, WireType.Varint).uint32(message.memberListCount); + /* repeated string owner_of = 3; */ + for (let i = 0; i < message.ownerOf.length; i++) + writer.tag(3, WireType.LengthDelimited).string(message.ownerOf[i]); + /* repeated string member_of = 4; */ + for (let i = 0; i < message.memberOf.length; i++) + writer.tag(4, WireType.LengthDelimited).string(message.memberOf[i]); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/integration/autoupdate/tools/main_test.go b/integration/autoupdate/tools/main_test.go index a14a6dc9fc683..bbc3f559f65c0 100644 --- a/integration/autoupdate/tools/main_test.go +++ b/integration/autoupdate/tools/main_test.go @@ -37,7 +37,8 @@ import ( "github.com/gravitational/trace" - "github.com/gravitational/teleport/integration/helpers" + "github.com/gravitational/teleport/api/constants" + "github.com/gravitational/teleport/integration/helpers/archive" ) const ( @@ -133,9 +134,9 @@ func buildAndArchiveApps(ctx context.Context, path string, toolsDir string, vers for _, app := range []string{"tsh", "tctl"} { output := filepath.Join(versionPath, app) switch runtime.GOOS { - case "windows": + case constants.WindowsOS: output = filepath.Join(versionPath, app+".exe") - case "darwin": + case constants.DarwinOS: output = filepath.Join(versionPath, app+".app", "Contents", "MacOS", app) } if err := buildBinary(output, toolsDir, version, baseURL); err != nil { @@ -143,15 +144,15 @@ func buildAndArchiveApps(ctx context.Context, path string, toolsDir string, vers } } switch runtime.GOOS { - case "darwin": + case constants.DarwinOS: archivePath := filepath.Join(path, fmt.Sprintf("teleport-%s.pkg", version)) - return trace.Wrap(helpers.CompressDirToPkgFile(ctx, versionPath, archivePath, "com.example.pkgtest")) - case "windows": + return trace.Wrap(archive.CompressDirToPkgFile(ctx, versionPath, archivePath, "com.example.pkgtest")) + case constants.WindowsOS: archivePath := filepath.Join(path, fmt.Sprintf("teleport-v%s-windows-amd64-bin.zip", version)) - return trace.Wrap(helpers.CompressDirToZipFile(ctx, versionPath, archivePath)) + return trace.Wrap(archive.CompressDirToZipFile(ctx, versionPath, archivePath)) default: archivePath := filepath.Join(path, fmt.Sprintf("teleport-v%s-linux-%s-bin.tar.gz", version, runtime.GOARCH)) - return trace.Wrap(helpers.CompressDirToTarGzFile(ctx, versionPath, archivePath)) + return trace.Wrap(archive.CompressDirToTarGzFile(ctx, versionPath, archivePath)) } } diff --git a/integration/autoupdate/tools/updater/main.go b/integration/autoupdate/tools/updater/main.go index e14c76e5d5aa8..775c7ab7b2e9d 100644 --- a/integration/autoupdate/tools/updater/main.go +++ b/integration/autoupdate/tools/updater/main.go @@ -25,11 +25,9 @@ import ( "log" "os" "os/signal" - "runtime" "syscall" "time" - "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/lib/autoupdate/tools" ) @@ -40,17 +38,20 @@ var ( ) func main() { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() ctx, _ = signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM) updater := tools.NewUpdater( - clientTools(), + tools.DefaultClientTools(), toolsDir, version, tools.WithBaseURL(baseURL), ) - toolsVersion, reExec := updater.CheckLocal() + toolsVersion, reExec, err := updater.CheckLocal() + if err != nil { + log.Fatal(err) + } if reExec { // Download and update the version of client tools required by the cluster. // This is required if the user passed in the TELEPORT_TOOLS_VERSION explicitly. @@ -76,13 +77,3 @@ func main() { fmt.Printf("Teleport v%v git\n", version) } } - -// clientTools list of the client tools needs to be updated. -func clientTools() []string { - switch runtime.GOOS { - case constants.WindowsOS: - return []string{"tsh.exe", "tctl.exe"} - default: - return []string{"tsh", "tctl"} - } -} diff --git a/integration/autoupdate/tools/updater_test.go b/integration/autoupdate/tools/updater_test.go index 52d7a7b8ab385..d429a7483910a 100644 --- a/integration/autoupdate/tools/updater_test.go +++ b/integration/autoupdate/tools/updater_test.go @@ -26,7 +26,6 @@ import ( "os/exec" "path/filepath" "regexp" - "runtime" "strings" "testing" "time" @@ -34,7 +33,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/lib/autoupdate/tools" ) @@ -51,7 +49,7 @@ func TestUpdate(t *testing.T) { // Fetch compiled test binary with updater logic and install to $TELEPORT_HOME. updater := tools.NewUpdater( - clientTools(), + tools.DefaultClientTools(), toolsDir, testVersions[0], tools.WithBaseURL(baseURL), @@ -93,7 +91,7 @@ func TestParallelUpdate(t *testing.T) { // Initial fetch the updater binary un-archive and replace. updater := tools.NewUpdater( - clientTools(), + tools.DefaultClientTools(), toolsDir, testVersions[0], tools.WithBaseURL(baseURL), @@ -167,7 +165,7 @@ func TestUpdateInterruptSignal(t *testing.T) { // Initial fetch the updater binary un-archive and replace. updater := tools.NewUpdater( - clientTools(), + tools.DefaultClientTools(), toolsDir, testVersions[0], tools.WithBaseURL(baseURL), @@ -220,12 +218,3 @@ func TestUpdateInterruptSignal(t *testing.T) { } assert.Contains(t, output.String(), "Update progress:") } - -func clientTools() []string { - switch runtime.GOOS { - case constants.WindowsOS: - return []string{"tsh.exe", "tctl.exe"} - default: - return []string{"tsh", "tctl"} - } -} diff --git a/integration/helpers/archive.go b/integration/helpers/archive/packaging.go similarity index 99% rename from integration/helpers/archive.go rename to integration/helpers/archive/packaging.go index 6e48108013d86..ee237749115a3 100644 --- a/integration/helpers/archive.go +++ b/integration/helpers/archive/packaging.go @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package helpers +package archive import ( "archive/tar" diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml index 802e2a4f13a11..2c595617b69d3 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml @@ -153,6 +153,10 @@ spec: description: ineligible_status describes if this owner is eligible or not and if not, describes how they're lacking eligibility. x-kubernetes-int-or-string: true + membership_kind: + description: membership_kind describes the type of membership, + either `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`. + x-kubernetes-int-or-string: true name: description: name is the username of the owner. type: string diff --git a/integrations/operator/controllers/resources/setup.go b/integrations/operator/controllers/resources/setup.go index e35e09531acae..a2e78a8cdc68c 100644 --- a/integrations/operator/controllers/resources/setup.go +++ b/integrations/operator/controllers/resources/setup.go @@ -45,7 +45,6 @@ func SetupAllControllers(log logr.Logger, mgr manager.Manager, teleportClient *c {"TeleportUser", NewUserReconciler}, {"TeleportGithubConnector", NewGithubConnectorReconciler}, {"TeleportProvisionToken", NewProvisionTokenReconciler}, - {"TeleportOktaImportRule", NewOktaImportRuleReconciler}, {"TeleportOpenSSHServerV2", NewOpenSSHServerV2Reconciler}, {"TeleportOpenSSHEICEServerV2", NewOpenSSHEICEServerV2Reconciler}, } diff --git a/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go b/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go index d7a15f142f804..caba7e10a26b3 100644 --- a/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go +++ b/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go @@ -44,7 +44,7 @@ func newAccessListSpec(nextAudit time.Time) accesslist.Spec { return accesslist.Spec{ Title: "crane operation", Description: "Access list that Gru uses to allow the minions to operate the crane.", - Owners: []accesslist.Owner{{Name: "Gru", Description: "The super villain."}}, + Owners: []accesslist.Owner{{Name: "Gru", Description: "The super villain.", MembershipKind: accesslist.MembershipKindUser}}, Audit: accesslist.Audit{ Recurrence: accesslist.Recurrence{ Frequency: accesslist.SixMonths, diff --git a/integrations/terraform/go.mod b/integrations/terraform/go.mod index c9459a5381189..030b29ba08341 100644 --- a/integrations/terraform/go.mod +++ b/integrations/terraform/go.mod @@ -184,6 +184,7 @@ require ( github.com/google/go-tspi v0.3.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect + github.com/google/renameio/v2 v2.0.0 // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index 257c076fd1e5d..95ef579188b65 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -1252,7 +1252,6 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= diff --git a/integrations/terraform/tfschema/accesslist/v1/accesslist_terraform.go b/integrations/terraform/tfschema/accesslist/v1/accesslist_terraform.go index ef0bd9464ef7a..33058a3bad9a4 100644 --- a/integrations/terraform/tfschema/accesslist/v1/accesslist_terraform.go +++ b/integrations/terraform/tfschema/accesslist/v1/accesslist_terraform.go @@ -245,6 +245,11 @@ func GenSchemaAccessList(ctx context.Context) (github_com_hashicorp_terraform_pl Optional: true, Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, }, + "membership_kind": { + Description: "membership_kind describes the type of membership, either `MEMBERSHIP_KIND_USER` or `MEMBERSHIP_KIND_LIST`.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.Int64Type, + }, "name": { Description: "name is the username of the owner.", Optional: true, @@ -571,6 +576,23 @@ func CopyAccessListFromTerraform(_ context.Context, tf github_com_hashicorp_terr } } } + { + a, ok := tf.Attrs["membership_kind"] + if !ok { + diags.Append(attrReadMissingDiag{"AccessList.spec.owners.membership_kind"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AccessList.spec.owners.membership_kind", "github.com/hashicorp/terraform-plugin-framework/types.Int64"}) + } else { + var t github_com_gravitational_teleport_api_gen_proto_go_teleport_accesslist_v1.MembershipKind + if !v.Null && !v.Unknown { + t = github_com_gravitational_teleport_api_gen_proto_go_teleport_accesslist_v1.MembershipKind(v.Value) + } + obj.MembershipKind = t + } + } + } } obj.Owners[k] = t } @@ -1599,6 +1621,28 @@ func CopyAccessListToTerraform(ctx context.Context, obj *github_com_gravitationa tf.Attrs["description"] = v } } + { + t, ok := tf.AttrTypes["membership_kind"] + if !ok { + diags.Append(attrWriteMissingDiag{"AccessList.spec.owners.membership_kind"}) + } else { + v, ok := tf.Attrs["membership_kind"].(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AccessList.spec.owners.membership_kind", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AccessList.spec.owners.membership_kind", "github.com/hashicorp/terraform-plugin-framework/types.Int64"}) + } + v.Null = int64(obj.MembershipKind) == 0 + } + v.Value = int64(obj.MembershipKind) + v.Unknown = false + tf.Attrs["membership_kind"] = v + } + } } v.Unknown = false c.Elems[k] = v diff --git a/lib/accesslists/hierarchy.go b/lib/accesslists/hierarchy.go new file mode 100644 index 0000000000000..5b7778aa91245 --- /dev/null +++ b/lib/accesslists/hierarchy.go @@ -0,0 +1,743 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package accesslists + +import ( + "context" + "slices" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/accesslist" + "github.com/gravitational/teleport/api/types/trait" + "github.com/gravitational/teleport/lib/services" +) + +// RelationshipKind represents the type of relationship: member or owner. +type RelationshipKind int + +const ( + RelationshipKindMember RelationshipKind = iota + RelationshipKindOwner +) + +// MembershipOrOwnershipType represents the type of membership or ownership a User has for an Access List. +type MembershipOrOwnershipType int + +const ( + // MembershipOrOwnershipTypeNone indicates that the User lacks valid Membership or Ownership for the Access List. + MembershipOrOwnershipTypeNone MembershipOrOwnershipType = iota + // MembershipOrOwnershipTypeExplicit indicates that the User has explicit Membership or Ownership for the Access List. + MembershipOrOwnershipTypeExplicit + // MembershipOrOwnershipTypeInherited indicates that the User has inherited Membership or Ownership for the Access List. + MembershipOrOwnershipTypeInherited +) + +// AccessListAndMembersGetter is a minimal interface for fetching AccessLists by name, and AccessListMembers for an Access List. +type AccessListAndMembersGetter interface { + ListAccessListMembers(ctx context.Context, accessListName string, pageSize int, pageToken string) (members []*accesslist.AccessListMember, nextToken string, err error) + GetAccessList(ctx context.Context, accessListName string) (*accesslist.AccessList, error) +} + +// GetMembersFor returns a flattened list of Members for an Access List, including inherited Members. +// +// Returned Members are not validated for expiration or other requirements – use IsAccessListMember +// to validate a Member's membership status. +func GetMembersFor(ctx context.Context, accessListName string, g AccessListAndMembersGetter) ([]*accesslist.AccessListMember, error) { + return getMembersFor(ctx, accessListName, g, make(map[string]struct{})) +} + +func getMembersFor(ctx context.Context, accessListName string, g AccessListAndMembersGetter, visited map[string]struct{}) ([]*accesslist.AccessListMember, error) { + if _, ok := visited[accessListName]; ok { + return nil, nil + } + visited[accessListName] = struct{}{} + + members, err := fetchMembers(ctx, accessListName, g) + if err != nil { + return nil, trace.Wrap(err) + } + + var allMembers []*accesslist.AccessListMember + for _, member := range members { + if member.Spec.MembershipKind != accesslist.MembershipKindList { + allMembers = append(allMembers, member) + continue + } + childMembers, err := getMembersFor(ctx, member.Spec.Name, g, visited) + if err != nil { + return nil, trace.Wrap(err) + } + allMembers = append(allMembers, childMembers...) + } + + return allMembers, nil +} + +// fetchMembers is a simple helper to fetch all top-level AccessListMembers for an AccessList. +func fetchMembers(ctx context.Context, accessListName string, g AccessListAndMembersGetter) ([]*accesslist.AccessListMember, error) { + var allMembers []*accesslist.AccessListMember + pageToken := "" + for { + page, nextToken, err := g.ListAccessListMembers(ctx, accessListName, 0, pageToken) + if err != nil { + // If the AccessList doesn't exist yet, should return an empty list of members + if trace.IsNotFound(err) { + break + } + return nil, trace.Wrap(err) + } + allMembers = append(allMembers, page...) + if nextToken == "" { + break + } + pageToken = nextToken + } + return allMembers, nil +} + +// ValidateAccessListWithMembers validates a new or existing AccessList with a list of AccessListMembers. +func ValidateAccessListWithMembers(ctx context.Context, accessList *accesslist.AccessList, members []*accesslist.AccessListMember, g AccessListAndMembersGetter) error { + for _, owner := range accessList.Spec.Owners { + if owner.MembershipKind != accesslist.MembershipKindList { + continue + } + ownerList, err := g.GetAccessList(ctx, owner.Name) + if err != nil { + return trace.Wrap(err) + } + if err := validateAddition(ctx, accessList, ownerList, RelationshipKindOwner, g); err != nil { + return trace.Wrap(err) + } + } + for _, member := range members { + if member.Spec.MembershipKind != accesslist.MembershipKindList { + continue + } + memberList, err := g.GetAccessList(ctx, member.Spec.Name) + if err != nil { + return trace.Wrap(err) + } + if err := validateAddition(ctx, accessList, memberList, RelationshipKindMember, g); err != nil { + return trace.Wrap(err) + } + } + return nil +} + +// collectOwners is a helper to recursively collect all Owners for an Access List, including inherited Owners. +func collectOwners(ctx context.Context, accessList *accesslist.AccessList, g AccessListAndMembersGetter, owners map[string]*accesslist.Owner, visited map[string]struct{}) error { + //owners := make([]*accesslist.Owner, 0) + if _, ok := visited[accessList.GetName()]; ok { + return nil + } + visited[accessList.GetName()] = struct{}{} + + for _, owner := range accessList.Spec.Owners { + if owner.MembershipKind != accesslist.MembershipKindList { + // Collect direct owner users + owners[owner.Name] = &owner + continue + } + + // For owner lists, we need to collect their members as owners + ownerMembers, err := collectMembersAsOwners(ctx, owner.Name, g, visited) + if err != nil { + return trace.Wrap(err) + } + //owners = append(owners, ownerMembers...) + for _, ownerMember := range ownerMembers { + owners[ownerMember.Name] = ownerMember + } + } + + return nil +} + +// collectMembersAsOwners is a helper to collect all nested members of an AccessList and return them cast as Owners. +func collectMembersAsOwners(ctx context.Context, accessListName string, g AccessListAndMembersGetter, visited map[string]struct{}) ([]*accesslist.Owner, error) { + owners := make([]*accesslist.Owner, 0) + if _, ok := visited[accessListName]; ok { + return owners, nil + } + visited[accessListName] = struct{}{} + + listMembers, err := GetMembersFor(ctx, accessListName, g) + if err != nil { + return nil, trace.Wrap(err) + } + + for _, member := range listMembers { + owners = append(owners, &accesslist.Owner{ + Name: member.Spec.Name, + Description: member.Metadata.Description, + IneligibleStatus: "", + MembershipKind: accesslist.MembershipKindUser, + }) + } + + return owners, nil +} + +// GetOwnersFor returns a flattened list of Owners for an Access List, including inherited Owners. +// +// Returned Owners are not validated for expiration or other requirements – use IsAccessListOwner +// to validate an Owner's ownership status. +func GetOwnersFor(ctx context.Context, accessList *accesslist.AccessList, g AccessListAndMembersGetter) ([]*accesslist.Owner, error) { + ownersMap := make(map[string]*accesslist.Owner) + if err := collectOwners(ctx, accessList, g, ownersMap, make(map[string]struct{})); err != nil { + return nil, trace.Wrap(err) + } + owners := make([]*accesslist.Owner, 0, len(ownersMap)) + for _, owner := range ownersMap { + owners = append(owners, owner) + } + return owners, nil +} + +// ValidateAccessListMember validates a new or existing AccessListMember for an Access List. +func ValidateAccessListMember( + ctx context.Context, + parentList *accesslist.AccessList, + member *accesslist.AccessListMember, + g AccessListAndMembersGetter, +) error { + if member.Spec.MembershipKind != accesslist.MembershipKindList { + return nil + } + return validateAccessListMemberOrOwner(ctx, parentList, member.Spec.Name, RelationshipKindMember, g) +} + +// ValidateAccessListOwner validates a new or existing AccessListOwner for an Access List. +func ValidateAccessListOwner( + ctx context.Context, + parentList *accesslist.AccessList, + owner *accesslist.Owner, + g AccessListAndMembersGetter, +) error { + if owner.MembershipKind != accesslist.MembershipKindList { + return nil + } + return validateAccessListMemberOrOwner(ctx, parentList, owner.Name, RelationshipKindOwner, g) +} + +func validateAccessListMemberOrOwner( + ctx context.Context, + parentList *accesslist.AccessList, + memberOrOwnerName string, + kind RelationshipKind, + g AccessListAndMembersGetter, +) error { + // Ensure member or owner list exists + memberOrOwnerList, err := g.GetAccessList(ctx, memberOrOwnerName) + if err != nil { + return trace.Wrap(err) + } + + // Validate addition + if err := validateAddition(ctx, parentList, memberOrOwnerList, kind, g); err != nil { + return trace.Wrap(err) + } + return nil +} + +func validateAddition( + ctx context.Context, + parentList *accesslist.AccessList, + childList *accesslist.AccessList, + kind RelationshipKind, + g AccessListAndMembersGetter, +) error { + kindStr := "a Member" + if kind == RelationshipKindOwner { + kindStr = "an Owner" + } + + // Cycle detection + reachable, err := isReachable(ctx, childList, parentList, make(map[string]struct{}), g) + if err != nil { + return trace.Wrap(err) + } + if reachable { + return trace.BadParameter( + "Access List '%s' can't be added as %s of '%s' because '%s' is already included as a Member or Owner in '%s'", + childList.Spec.Title, kindStr, parentList.Spec.Title, parentList.Spec.Title, childList.Spec.Title) + } + + // Max depth check + exceeds, err := exceedsMaxDepth(ctx, parentList, childList, kind, g) + if err != nil { + return trace.Wrap(err) + } + if exceeds { + return trace.BadParameter( + "Access List '%s' can't be added as %s of '%s' because it would exceed the maximum nesting depth of %d", + childList.Spec.Title, kindStr, parentList.Spec.Title, accesslist.MaxAllowedDepth) + } + + return nil +} + +func isReachable( + ctx context.Context, + currentList *accesslist.AccessList, + targetList *accesslist.AccessList, + visited map[string]struct{}, + g AccessListAndMembersGetter, +) (bool, error) { + if currentList.GetName() == targetList.GetName() { + return true, nil + } + if _, ok := visited[currentList.GetName()]; ok { + return false, nil + } + visited[currentList.GetName()] = struct{}{} + + // Traverse member lists + listMembers, err := fetchMembers(ctx, currentList.GetName(), g) + if err != nil { + return false, trace.Wrap(err) + } + for _, member := range listMembers { + if member.Spec.MembershipKind == accesslist.MembershipKindList { + childList, err := g.GetAccessList(ctx, member.Spec.Name) + if err != nil { + return false, trace.Wrap(err) + } + reachable, err := isReachable(ctx, childList, targetList, visited, g) + if err != nil { + return false, trace.Wrap(err) + } + if reachable { + return true, nil + } + } + } + + // Traverse owner lists + for _, owner := range currentList.Spec.Owners { + if owner.MembershipKind == accesslist.MembershipKindList { + ownerList, err := g.GetAccessList(ctx, owner.Name) + if err != nil { + return false, trace.Wrap(err) + } + reachable, err := isReachable(ctx, ownerList, targetList, visited, g) + if err != nil { + return false, trace.Wrap(err) + } + if reachable { + return true, nil + } + } + } + + return false, nil +} + +func exceedsMaxDepth( + ctx context.Context, + parentList *accesslist.AccessList, + childList *accesslist.AccessList, + kind RelationshipKind, + g AccessListAndMembersGetter, +) (bool, error) { + switch kind { + case RelationshipKindOwner: + // For Owners, only consider the depth downwards from the child node + depthDownwards, err := maxDepthDownwards(ctx, childList.GetName(), make(map[string]struct{}), g) + if err != nil { + return false, trace.Wrap(err) + } + return depthDownwards > accesslist.MaxAllowedDepth, nil + default: + // For Members, consider the depth upwards from the parent node, downwards from the child node, and the edge between them + depthUpwards, err := maxDepthUpwards(ctx, parentList, make(map[string]struct{}), g) + if err != nil { + return false, trace.Wrap(err) + } + depthDownwards, err := maxDepthDownwards(ctx, childList.GetName(), make(map[string]struct{}), g) + if err != nil { + return false, trace.Wrap(err) + } + totalDepth := depthUpwards + depthDownwards + 1 // +1 for the edge between parent and child + return totalDepth > accesslist.MaxAllowedDepth, nil + } +} + +func maxDepthDownwards( + ctx context.Context, + currentListName string, + seen map[string]struct{}, + g AccessListAndMembersGetter, +) (int, error) { + if _, ok := seen[currentListName]; ok { + return 0, nil + } + seen[currentListName] = struct{}{} + + maxDepth := 0 + + listMembers, err := fetchMembers(ctx, currentListName, g) + if err != nil { + return 0, trace.Wrap(err) + } + for _, member := range listMembers { + if member.Spec.MembershipKind == accesslist.MembershipKindList { + childListName := member.Spec.Name + depth, err := maxDepthDownwards(ctx, childListName, seen, g) + if err != nil { + return 0, trace.Wrap(err) + } + depth += 1 // Edge to the child + if depth > maxDepth { + maxDepth = depth + } + } + } + + delete(seen, currentListName) + + return maxDepth, nil +} + +func maxDepthUpwards( + ctx context.Context, + currentList *accesslist.AccessList, + seen map[string]struct{}, + g AccessListAndMembersGetter, +) (int, error) { + if _, ok := seen[currentList.GetName()]; ok { + return 0, nil + } + seen[currentList.GetName()] = struct{}{} + + maxDepth := 0 + + // Traverse MemberOf relationships + for _, parentListName := range currentList.Status.MemberOf { + parentList, err := g.GetAccessList(ctx, parentListName) + if err != nil { + return 0, trace.Wrap(err) // Treat missing lists as depth 0 + } + depth, err := maxDepthUpwards(ctx, parentList, seen, g) + if err != nil { + return 0, trace.Wrap(err) + } + depth += 1 // Edge to the parent + if depth > maxDepth { + maxDepth = depth + } + } + + delete(seen, currentList.GetName()) + + return maxDepth, nil +} + +func IsAccessListOwner( + ctx context.Context, + user types.User, + accessList *accesslist.AccessList, + g AccessListAndMembersGetter, + lockGetter services.LockGetter, + clock clockwork.Clock, +) (MembershipOrOwnershipType, error) { + if lockGetter != nil { + locks, err := lockGetter.GetLocks(ctx, true, types.LockTarget{ + User: user.GetName(), + }) + if err != nil { + return MembershipOrOwnershipTypeNone, trace.Wrap(err) + } + if len(locks) > 0 { + return MembershipOrOwnershipTypeNone, trace.AccessDenied("User '%s' is currently locked", user.GetName()) + } + } + + var ownershipErr error + + for _, owner := range accessList.Spec.Owners { + // Is user an explicit owner? + if owner.MembershipKind != accesslist.MembershipKindList && owner.Name == user.GetName() { + if !UserMeetsRequirements(user, accessList.Spec.OwnershipRequires) { + // Avoid non-deterministic behavior in these checks. Rather than returning immediately, continue + // through all owners to make sure there isn't a valid match later on. + ownershipErr = trace.AccessDenied("User '%s' does not meet the ownership requirements for Access List '%s'", user.GetName(), accessList.Spec.Title) + continue + } + return MembershipOrOwnershipTypeExplicit, nil + } + // Is user an inherited owner through any potential owner AccessLists? + if owner.MembershipKind == accesslist.MembershipKindList { + ownerAccessList, err := g.GetAccessList(ctx, owner.Name) + if err != nil { + ownershipErr = trace.Wrap(err) + continue + } + // Since we already verified that the user is not locked, don't provide lockGetter here + membershipType, err := IsAccessListMember(ctx, user, ownerAccessList, g, nil, clock) + if err != nil { + ownershipErr = trace.Wrap(err) + continue + } + if membershipType != MembershipOrOwnershipTypeNone { + if !UserMeetsRequirements(user, accessList.Spec.OwnershipRequires) { + ownershipErr = trace.AccessDenied("User '%s' does not meet the ownership requirements for Access List '%s'", user.GetName(), accessList.Spec.Title) + continue + } + return MembershipOrOwnershipTypeInherited, nil + } + } + } + + return MembershipOrOwnershipTypeNone, trace.Wrap(ownershipErr) +} + +func IsAccessListMember( + ctx context.Context, + user types.User, + accessList *accesslist.AccessList, + g AccessListAndMembersGetter, + lockGetter services.LockGetter, + clock clockwork.Clock, +) (MembershipOrOwnershipType, error) { + if lockGetter != nil { + locks, err := lockGetter.GetLocks(ctx, true, types.LockTarget{ + User: user.GetName(), + }) + if err != nil { + return MembershipOrOwnershipTypeNone, trace.Wrap(err) + } + if len(locks) > 0 { + return MembershipOrOwnershipTypeNone, trace.AccessDenied("User '%s' is currently locked", user.GetName()) + } + } + + members, err := fetchMembers(ctx, accessList.GetName(), g) + if err != nil { + return MembershipOrOwnershipTypeNone, trace.Wrap(err) + } + + var membershipErr error + + for _, member := range members { + // Is user an explicit member? + if member.Spec.MembershipKind != accesslist.MembershipKindList && member.GetName() == user.GetName() { + if !UserMeetsRequirements(user, accessList.Spec.MembershipRequires) { + // Avoid non-deterministic behavior in these checks. Rather than returning immediately, continue + // through all members to make sure there isn't a valid match later on. + membershipErr = trace.AccessDenied("User '%s' does not meet the membership requirements for Access List '%s'", user.GetName(), accessList.Spec.Title) + continue + } + if !member.Spec.Expires.IsZero() && !clock.Now().Before(member.Spec.Expires) { + membershipErr = trace.AccessDenied("User '%s's membership in Access List '%s' has expired", user.GetName(), accessList.Spec.Title) + continue + } + return MembershipOrOwnershipTypeExplicit, nil + } + // Is user an inherited member through any potential member AccessLists? + if member.Spec.MembershipKind == accesslist.MembershipKindList { + memberAccessList, err := g.GetAccessList(ctx, member.GetName()) + if err != nil { + membershipErr = trace.Wrap(err) + continue + } + // Since we already verified that the user is not locked, don't provide lockGetter here + membershipType, err := IsAccessListMember(ctx, user, memberAccessList, g, nil, clock) + if err != nil { + membershipErr = trace.Wrap(err) + continue + } + if membershipType != MembershipOrOwnershipTypeNone { + if !UserMeetsRequirements(user, accessList.Spec.MembershipRequires) { + membershipErr = trace.AccessDenied("User '%s' does not meet the membership requirements for Access List '%s'", user.GetName(), accessList.Spec.Title) + continue + } + if !member.Spec.Expires.IsZero() && !clock.Now().Before(member.Spec.Expires) { + membershipErr = trace.AccessDenied("User '%s's membership in Access List '%s' has expired", user.GetName(), accessList.Spec.Title) + continue + } + return MembershipOrOwnershipTypeInherited, nil + } + } + } + + return MembershipOrOwnershipTypeNone, trace.Wrap(membershipErr) +} + +// UserMeetsRequirements is a helper which will return whether the User meets the AccessList Ownership/MembershipRequires. +func UserMeetsRequirements(identity types.User, requires accesslist.Requires) bool { + // Assemble the user's roles for easy look up. + userRolesMap := map[string]struct{}{} + for _, role := range identity.GetRoles() { + userRolesMap[role] = struct{}{} + } + + // Check that the user meets the role requirements. + for _, role := range requires.Roles { + if _, ok := userRolesMap[role]; !ok { + return false + } + } + + // Assemble traits for easy lookup. + userTraitsMap := map[string]map[string]struct{}{} + for k, values := range identity.GetTraits() { + if _, ok := userTraitsMap[k]; !ok { + userTraitsMap[k] = map[string]struct{}{} + } + + for _, v := range values { + userTraitsMap[k][v] = struct{}{} + } + } + + // Check that user meets trait requirements. + for k, values := range requires.Traits { + if _, ok := userTraitsMap[k]; !ok { + return false + } + + for _, v := range values { + if _, ok := userTraitsMap[k][v]; !ok { + return false + } + } + } + + // The user meets all requirements. + return true +} + +func getAncestorsFor(ctx context.Context, accessList *accesslist.AccessList, kind RelationshipKind, g AccessListAndMembersGetter) ([]*accesslist.AccessList, error) { + ancestorsMap := make(map[string]*accesslist.AccessList) + if err := collectAncestors(ctx, accessList, kind, g, make(map[string]struct{}), ancestorsMap); err != nil { + return nil, trace.Wrap(err) + } + ancestors := make([]*accesslist.AccessList, 0, len(ancestorsMap)) + for _, al := range ancestorsMap { + ancestors = append(ancestors, al) + } + return ancestors, nil +} + +func collectAncestors(ctx context.Context, accessList *accesslist.AccessList, kind RelationshipKind, g AccessListAndMembersGetter, visited map[string]struct{}, ancestors map[string]*accesslist.AccessList) error { + if _, ok := visited[accessList.GetName()]; ok { + return nil + } + visited[accessList.GetName()] = struct{}{} + + switch kind { + case RelationshipKindOwner: + // Add parents where this list is an owner to ancestors + for _, ownerParent := range accessList.Status.OwnerOf { + ownerParentAcl, err := g.GetAccessList(ctx, ownerParent) + if err != nil { + return trace.Wrap(err) + } + ancestors[ownerParent] = ownerParentAcl + } + // Recursively traverse parents where this list is a member + for _, memberParent := range accessList.Status.MemberOf { + memberParentAcl, err := g.GetAccessList(ctx, memberParent) + if err != nil { + return trace.Wrap(err) + } + if err := collectAncestors(ctx, memberParentAcl, kind, g, visited, ancestors); err != nil { + return trace.Wrap(err) + } + } + default: + // Only collect parents where this list is a member + for _, memberParent := range accessList.Status.MemberOf { + memberParentAcl, err := g.GetAccessList(ctx, memberParent) + if err != nil { + return trace.Wrap(err) + } + ancestors[memberParent] = memberParentAcl + if err := collectAncestors(ctx, memberParentAcl, kind, g, visited, ancestors); err != nil { + return trace.Wrap(err) + } + } + } + + return nil +} + +// GetInheritedGrants returns the combined Grants for an Access List's members, inherited from any ancestor lists. +func GetInheritedGrants(ctx context.Context, accessList *accesslist.AccessList, g AccessListAndMembersGetter) (*accesslist.Grants, error) { + grants := accesslist.Grants{ + Traits: trait.Traits{}, + } + + collectedRoles := make(map[string]struct{}) + collectedTraits := make(map[string]map[string]struct{}) + + addGrants := func(grantRoles []string, grantTraits trait.Traits) { + for _, role := range grantRoles { + if _, exists := collectedRoles[role]; !exists { + grants.Roles = append(grants.Roles, role) + collectedRoles[role] = struct{}{} + } + } + for traitKey, traitValues := range grantTraits { + if _, exists := collectedTraits[traitKey]; !exists { + collectedTraits[traitKey] = make(map[string]struct{}) + } + for _, traitValue := range traitValues { + if _, exists := collectedTraits[traitKey][traitValue]; !exists { + grants.Traits[traitKey] = append(grants.Traits[traitKey], traitValue) + collectedTraits[traitKey][traitValue] = struct{}{} + } + } + } + } + + // Get ancestors via member relationship + ancestorLists, err := getAncestorsFor(ctx, accessList, RelationshipKindMember, g) + if err != nil { + return nil, trace.Wrap(err) + } + for _, ancestor := range ancestorLists { + memberGrants := ancestor.GetGrants() + addGrants(memberGrants.Roles, memberGrants.Traits) + } + + // Get ancestors via owner relationship + ancestorOwnerLists, err := getAncestorsFor(ctx, accessList, RelationshipKindOwner, g) + if err != nil { + return nil, trace.Wrap(err) + } + for _, ancestorOwner := range ancestorOwnerLists { + ownerGrants := ancestorOwner.GetOwnerGrants() + addGrants(ownerGrants.Roles, ownerGrants.Traits) + } + + slices.Sort(grants.Roles) + grants.Roles = slices.Compact(grants.Roles) + + for k, v := range grants.Traits { + slices.Sort(v) + grants.Traits[k] = slices.Compact(v) + } + + return &grants, nil +} diff --git a/lib/accesslists/hierarchy_test.go b/lib/accesslists/hierarchy_test.go new file mode 100644 index 0000000000000..43d295fb34b6d --- /dev/null +++ b/lib/accesslists/hierarchy_test.go @@ -0,0 +1,666 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package accesslists + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/accesslist" + "github.com/gravitational/teleport/api/types/header" +) + +// Mock implementation of AccessListAndMembersGetter. +type mockAccessListAndMembersGetter struct { + accessLists map[string]*accesslist.AccessList + members map[string][]*accesslist.AccessListMember +} + +func (m *mockAccessListAndMembersGetter) GetAccessList(ctx context.Context, accessListName string) (*accesslist.AccessList, error) { + accessList, exists := m.accessLists[accessListName] + if !exists { + return nil, trace.NotFound("access list %v not found", accessListName) + } + return accessList, nil +} + +func (m *mockAccessListAndMembersGetter) ListAccessListMembers(ctx context.Context, accessListName string, pageSize int, pageToken string) ([]*accesslist.AccessListMember, string, error) { + members, exists := m.members[accessListName] + if !exists { + return nil, "", nil + } + return members, "", nil +} + +type mockLocksGetter struct { + targets map[string][]types.Lock +} + +func (m *mockLocksGetter) GetLock(ctx context.Context, name string) (types.Lock, error) { + panic("not implemented") +} + +func (m *mockLocksGetter) GetLocks(ctx context.Context, inForceOnly bool, targets ...types.LockTarget) ([]types.Lock, error) { + var locks []types.Lock + for _, target := range targets { + locks = append(locks, m.targets[target.User]...) + } + return locks, nil +} + +const ( + ownerUser = "ownerUser" + ownerUser2 = "ownerUser2" + member1 = "member1" + member2 = "member2" +) + +func TestAccessListHierarchyDepthCheck(t *testing.T) { + clock := clockwork.NewFakeClock() + ctx := context.Background() + + numAcls := accesslist.MaxAllowedDepth + 2 // Extra 2 to test exceeding the max depth + + acls := make([]*accesslist.AccessList, numAcls) + for i := 0; i < numAcls; i++ { + acls[i] = newAccessList(t, fmt.Sprintf("acl%d", i+1), clock) + } + + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + members: make(map[string][]*accesslist.AccessListMember), + accessLists: make(map[string]*accesslist.AccessList), + } + + // Create members up to MaxAllowedDepth + for i := 0; i < accesslist.MaxAllowedDepth; i++ { + member := newAccessListMember(t, acls[i].GetName(), acls[i+1].GetName(), accesslist.MembershipKindList, clock) + acls[i+1].Status.MemberOf = append(acls[i+1].Status.MemberOf, acls[i].GetName()) + accessListAndMembersGetter.members[acls[i].GetName()] = []*accesslist.AccessListMember{member} + accessListAndMembersGetter.accessLists[acls[i].GetName()] = acls[i] + } + // Set remaining Access Lists' members to empty slices + for i := accesslist.MaxAllowedDepth; i < numAcls; i++ { + accessListAndMembersGetter.members[acls[i].GetName()] = []*accesslist.AccessListMember{} + accessListAndMembersGetter.accessLists[acls[i].GetName()] = acls[i] + } + + // Should be valid with existing member < MaxAllowedDepth + err := ValidateAccessListMember(ctx, acls[accesslist.MaxAllowedDepth-1], accessListAndMembersGetter.members[acls[accesslist.MaxAllowedDepth-1].GetName()][0], accessListAndMembersGetter) + require.NoError(t, err) + + // Now, attempt to add a member that increases the depth beyond MaxAllowedDepth + extraMember := newAccessListMember( + t, + acls[accesslist.MaxAllowedDepth].GetName(), + acls[accesslist.MaxAllowedDepth+1].GetName(), + accesslist.MembershipKindList, + clock, + ) + + // Validate adding this member should fail due to exceeding max depth + err = ValidateAccessListMember(ctx, acls[accesslist.MaxAllowedDepth], extraMember, accessListAndMembersGetter) + require.Error(t, err) + require.ErrorIs(t, err, trace.BadParameter("Access List '%s' can't be added as a Member of '%s' because it would exceed the maximum nesting depth of %d", acls[accesslist.MaxAllowedDepth+1].Spec.Title, acls[accesslist.MaxAllowedDepth].Spec.Title, accesslist.MaxAllowedDepth)) +} + +func TestAccessListValidateWithMembers(t *testing.T) { + clock := clockwork.NewFakeClock() + ctx := context.Background() + + // We're creating a hierarchy with a depth of 10, and then trying to add it as a Member of a 'root' Access List. This should fail. + rootAcl := newAccessList(t, "root", clock) + nestedAcls := make([]*accesslist.AccessList, 0, accesslist.MaxAllowedDepth) + for i := 0; i < accesslist.MaxAllowedDepth+1; i++ { + acl := newAccessList(t, fmt.Sprintf("acl-%d", i), clock) + nestedAcls = append(nestedAcls, acl) + } + rootAclMember := newAccessListMember(t, rootAcl.GetName(), nestedAcls[0].GetName(), accesslist.MembershipKindList, clock) + members := make([]*accesslist.AccessListMember, 0, accesslist.MaxAllowedDepth-1) + for i := 0; i < accesslist.MaxAllowedDepth; i++ { + member := newAccessListMember(t, nestedAcls[i].GetName(), nestedAcls[i+1].GetName(), accesslist.MembershipKindList, clock) + nestedAcls[i+1].Status.MemberOf = append(nestedAcls[i+1].Status.MemberOf, nestedAcls[i].GetName()) + members = append(members, member) + } + + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{ + rootAcl.GetName(): {}, + }, + accessLists: map[string]*accesslist.AccessList{ + rootAcl.GetName(): rootAcl, + }, + } + for i := 0; i < accesslist.MaxAllowedDepth+1; i++ { + if i < accesslist.MaxAllowedDepth { + accessListAndMembersGetter.members[nestedAcls[i].GetName()] = []*accesslist.AccessListMember{members[i]} + } + accessListAndMembersGetter.accessLists[nestedAcls[i].GetName()] = nestedAcls[i] + } + + // Should validate successfully, as acl-0 -> acl-10 is a valid hierarchy of depth 10. + err := ValidateAccessListWithMembers(ctx, rootAcl, []*accesslist.AccessListMember{}, accessListAndMembersGetter) + require.NoError(t, err) + err = ValidateAccessListWithMembers(ctx, nestedAcls[0], []*accesslist.AccessListMember{accessListAndMembersGetter.members[nestedAcls[0].GetName()][0]}, accessListAndMembersGetter) + require.NoError(t, err) + + // Calling `ValidateAccessListWithMembers`, with `rootAclm1`, should fail, as it would exceed the maximum nesting depth. + err = ValidateAccessListWithMembers(ctx, rootAcl, []*accesslist.AccessListMember{rootAclMember}, accessListAndMembersGetter) + require.Error(t, err) + require.ErrorIs(t, err, trace.BadParameter("Access List '%s' can't be added as a Member of '%s' because it would exceed the maximum nesting depth of %d", nestedAcls[0].Spec.Title, rootAcl.Spec.Title, accesslist.MaxAllowedDepth)) + + const Length = accesslist.MaxAllowedDepth/2 + 1 + + // Next, we're creating two separate hierarchies, each with a depth of `MaxAllowedDepth/2`. When testing the validation, we'll try to connect the two hierarchies, which should fail. + nestedAcls1 := make([]*accesslist.AccessList, 0, Length) + for i := 0; i <= Length; i++ { + acl := newAccessList(t, fmt.Sprintf("acl1-%d", i), clock) + nestedAcls1 = append(nestedAcls1, acl) + } + + // Create the second hierarchy. + nestedAcls2 := make([]*accesslist.AccessList, 0, Length) + for i := 0; i <= Length; i++ { + acl := newAccessList(t, fmt.Sprintf("acl2-%d", i), clock) + nestedAcls2 = append(nestedAcls2, acl) + } + + accessListAndMembersGetter = &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{}, + accessLists: map[string]*accesslist.AccessList{}, + } + + // Create the members for the first hierarchy. + for i := 0; i < Length; i++ { + member := newAccessListMember(t, nestedAcls1[i].GetName(), nestedAcls1[i+1].GetName(), accesslist.MembershipKindList, clock) + nestedAcls1[i+1].Status.MemberOf = append(nestedAcls1[i+1].Status.MemberOf, nestedAcls1[i].GetName()) + accessListAndMembersGetter.members[nestedAcls1[i].GetName()] = []*accesslist.AccessListMember{member} + accessListAndMembersGetter.accessLists[nestedAcls1[i].GetName()] = nestedAcls1[i] + } + + // Create the members for the second hierarchy. + for i := 0; i < Length; i++ { + member := newAccessListMember(t, nestedAcls2[i].GetName(), nestedAcls2[i+1].GetName(), accesslist.MembershipKindList, clock) + nestedAcls2[i+1].Status.MemberOf = append(nestedAcls2[i+1].Status.MemberOf, nestedAcls2[i].GetName()) + accessListAndMembersGetter.members[nestedAcls2[i].GetName()] = []*accesslist.AccessListMember{member} + accessListAndMembersGetter.accessLists[nestedAcls2[i].GetName()] = nestedAcls2[i] + } + + // For the first hierarchy + nestedAcls1Last := nestedAcls1[len(nestedAcls1)-1] + accessListAndMembersGetter.accessLists[nestedAcls1Last.GetName()] = nestedAcls1Last + + // For the second hierarchy + nestedAcls2Last := nestedAcls2[len(nestedAcls2)-1] + accessListAndMembersGetter.accessLists[nestedAcls2Last.GetName()] = nestedAcls2Last + + // Should validate successfully when adding another list, as both hierarchies are valid. + err = ValidateAccessListWithMembers(ctx, nestedAcls1Last, []*accesslist.AccessListMember{newAccessListMember(t, nestedAcls1Last.GetName(), nestedAcls2Last.GetName(), accesslist.MembershipKindList, clock)}, accessListAndMembersGetter) + require.NoError(t, err) + err = ValidateAccessListWithMembers(ctx, nestedAcls2Last, []*accesslist.AccessListMember{newAccessListMember(t, nestedAcls2Last.GetName(), nestedAcls1Last.GetName(), accesslist.MembershipKindList, clock)}, accessListAndMembersGetter) + require.NoError(t, err) + + // Now, we'll try to connect the two hierarchies, which should fail. + err = ValidateAccessListWithMembers(ctx, nestedAcls1Last, []*accesslist.AccessListMember{newAccessListMember(t, nestedAcls1Last.GetName(), nestedAcls2[0].GetName(), accesslist.MembershipKindList, clock)}, accessListAndMembersGetter) + require.Error(t, err) + require.ErrorIs(t, err, trace.BadParameter("Access List '%s' can't be added as a Member of '%s' because it would exceed the maximum nesting depth of %d", nestedAcls2[0].Spec.Title, nestedAcls1[len(nestedAcls1)-1].Spec.Title, accesslist.MaxAllowedDepth)) +} + +func TestAccessListHierarchyCircularRefsCheck(t *testing.T) { + clock := clockwork.NewFakeClock() + ctx := context.Background() + + acl1 := newAccessList(t, "1", clock) + acl2 := newAccessList(t, "2", clock) + acl3 := newAccessList(t, "3", clock) + + // acl1 -> acl2 -> acl3 + acl1m1 := newAccessListMember(t, acl1.GetName(), acl2.GetName(), accesslist.MembershipKindList, clock) + acl2.Status.MemberOf = append(acl2.Status.MemberOf, acl1.GetName()) + acl2m1 := newAccessListMember(t, acl2.GetName(), acl3.GetName(), accesslist.MembershipKindList, clock) + acl3.Status.MemberOf = append(acl3.Status.MemberOf, acl2.GetName()) + + // acl3 -> acl1 + acl3m1 := newAccessListMember(t, acl3.GetName(), acl1.GetName(), accesslist.MembershipKindList, clock) + + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{ + acl1.GetName(): {acl1m1}, + acl2.GetName(): {acl2m1}, + acl3.GetName(): {}, + }, + accessLists: map[string]*accesslist.AccessList{ + acl1.GetName(): acl1, + acl2.GetName(): acl2, + acl3.GetName(): acl3, + }, + } + + // Circular references should not be allowed. + err := ValidateAccessListMember(ctx, acl3, acl3m1, accessListAndMembersGetter) + //err = hierarchy.ValidateAccessListMember(acl3.GetName(), acl3m1) + require.Error(t, err) + require.ErrorIs(t, err, trace.BadParameter("Access List '%s' can't be added as a Member of '%s' because '%s' is already included as a Member or Owner in '%s'", acl1.Spec.Title, acl3.Spec.Title, acl3.Spec.Title, acl1.Spec.Title)) + + // By removing acl3 as a member of acl2, the relationship should be valid. + accessListAndMembersGetter.members[acl2.GetName()] = []*accesslist.AccessListMember{} + accessListAndMembersGetter.accessLists[acl3.GetName()].Status.MemberOf = []string{} + err = ValidateAccessListMember(ctx, acl3, acl3m1, accessListAndMembersGetter) + require.NoError(t, err) + + // Circular references with Ownership should also be disallowed. + acl4 := newAccessList(t, "4", clock) + acl5 := newAccessList(t, "5", clock) + + // acl4 includes acl5 as a Member + acl4m1 := newAccessListMember(t, acl4.GetName(), acl5.GetName(), accesslist.MembershipKindList, clock) + acl5.Status.MemberOf = append(acl5.Status.MemberOf, acl4.GetName()) + + // acl5 includes acl4 as an Owner. + acl5.Spec.Owners = append(acl5.Spec.Owners, accesslist.Owner{ + Name: acl4.GetName(), + Description: "asdf", + MembershipKind: accesslist.MembershipKindList, + }) + acl4.Status.OwnerOf = append(acl4.Status.OwnerOf, acl5.GetName()) + + accessListAndMembersGetter = &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{ + acl4.GetName(): {acl4m1}, + acl5.GetName(): {}, + }, + accessLists: map[string]*accesslist.AccessList{ + acl4.GetName(): acl4, + acl5.GetName(): acl5, + }, + } + + err = ValidateAccessListWithMembers(ctx, acl5, []*accesslist.AccessListMember{acl4m1}, accessListAndMembersGetter) + require.Error(t, err) + require.ErrorIs(t, err, trace.BadParameter("Access List '%s' can't be added as an Owner of '%s' because '%s' is already included as a Member or Owner in '%s'", acl4.Spec.Title, acl5.Spec.Title, acl5.Spec.Title, acl4.Spec.Title)) +} + +func TestAccessListHierarchyIsOwner(t *testing.T) { + clock := clockwork.NewFakeClock() + ctx := context.Background() + + acl1 := newAccessList(t, "1", clock) + acl2 := newAccessList(t, "2", clock) + acl3 := newAccessList(t, "3", clock) + acl4 := newAccessList(t, "4", clock) + + // acl1 -> acl2 -> acl3 as members + acl1m1 := newAccessListMember(t, acl1.GetName(), acl2.GetName(), accesslist.MembershipKindList, clock) + acl2.Status.MemberOf = append(acl2.Status.MemberOf, acl1.GetName()) + acl1m2 := newAccessListMember(t, acl1.GetName(), member1, accesslist.MembershipKindUser, clock) + acl2m1 := newAccessListMember(t, acl2.GetName(), acl3.GetName(), accesslist.MembershipKindList, clock) + acl3.Status.MemberOf = append(acl3.Status.MemberOf, acl2.GetName()) + acl4m1 := newAccessListMember(t, acl4.GetName(), member2, accesslist.MembershipKindUser, clock) + + // acl4 -> acl1 as owner + acl4.Spec.Owners = append(acl4.Spec.Owners, accesslist.Owner{ + Name: acl1.GetName(), + Description: "asdf", + MembershipKind: accesslist.MembershipKindList, + }) + acl1.Status.OwnerOf = append(acl1.Status.OwnerOf, acl4.GetName()) + + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{ + acl1.GetName(): {acl1m1, acl1m2}, + acl2.GetName(): {acl2m1}, + acl3.GetName(): {}, + acl4.GetName(): {acl4m1}, + }, + accessLists: map[string]*accesslist.AccessList{ + acl1.GetName(): acl1, + acl2.GetName(): acl2, + acl3.GetName(): acl3, + acl4.GetName(): acl4, + }, + } + + // User which does not meet acl1's Membership requirements. + stubUserNoRequires, err := types.NewUser(member1) + require.NoError(t, err) + + ownershipType, err := IsAccessListOwner(ctx, stubUserNoRequires, acl4, accessListAndMembersGetter, nil, clock) + require.Error(t, err) + require.ErrorIs(t, err, trace.AccessDenied("User '%s' does not meet the membership requirements for Access List '%s'", member1, acl1.Spec.Title)) + // Should not have inherited ownership due to missing OwnershipRequires. + require.Equal(t, MembershipOrOwnershipTypeNone, ownershipType) + + // User which only meets acl1's Membership requirements. + stubUserMeetsMemberRequires, err := types.NewUser(member1) + require.NoError(t, err) + stubUserMeetsMemberRequires.SetTraits(map[string][]string{ + "mtrait1": {"mvalue1", "mvalue2"}, + "mtrait2": {"mvalue3", "mvalue4"}, + }) + stubUserMeetsMemberRequires.SetRoles([]string{"mrole1", "mrole2"}) + + ownershipType, err = IsAccessListOwner(ctx, stubUserMeetsMemberRequires, acl4, accessListAndMembersGetter, nil, clock) + require.Error(t, err) + require.ErrorIs(t, err, trace.AccessDenied("User '%s' does not meet the ownership requirements for Access List '%s'", member1, acl4.Spec.Title)) + require.Equal(t, MembershipOrOwnershipTypeNone, ownershipType) + + // User which meets acl1's Membership and acl1's Ownership requirements. + stubUserMeetsAllRequires, err := types.NewUser(member1) + require.NoError(t, err) + stubUserMeetsAllRequires.SetTraits(map[string][]string{ + "mtrait1": {"mvalue1", "mvalue2"}, + "mtrait2": {"mvalue3", "mvalue4"}, + "otrait1": {"ovalue1", "ovalue2"}, + "otrait2": {"ovalue3", "ovalue4"}, + }) + stubUserMeetsAllRequires.SetRoles([]string{"mrole1", "mrole2", "orole1", "orole2"}) + + ownershipType, err = IsAccessListOwner(ctx, stubUserMeetsAllRequires, acl4, accessListAndMembersGetter, nil, clock) + require.NoError(t, err) + // Should have inherited ownership from acl1's inclusion in acl4's Owners. + require.Equal(t, MembershipOrOwnershipTypeInherited, ownershipType) + + stubUserMeetsAllRequires.SetName(member2) + ownershipType, err = IsAccessListOwner(ctx, stubUserMeetsAllRequires, acl4, accessListAndMembersGetter, nil, clock) + require.NoError(t, err) + // Should not have ownership. + require.Equal(t, MembershipOrOwnershipTypeNone, ownershipType) +} + +func TestAccessListIsMember(t *testing.T) { + clock := clockwork.NewFakeClock() + ctx := context.Background() + + acl1 := newAccessList(t, "1", clock) + acl1m1 := newAccessListMember(t, acl1.GetName(), member1, accesslist.MembershipKindUser, clock) + + locksGetter := &mockLocksGetter{ + targets: map[string][]types.Lock{}, + } + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{ + acl1.GetName(): {acl1m1}, + }, + accessLists: map[string]*accesslist.AccessList{ + acl1.GetName(): acl1, + }, + } + + stubMember1, err := types.NewUser(member1) + require.NoError(t, err) + stubMember1.SetTraits(map[string][]string{ + "mtrait1": {"mvalue1", "mvalue2"}, + "mtrait2": {"mvalue3", "mvalue4"}, + }) + stubMember1.SetRoles([]string{"mrole1", "mrole2"}) + + membershipType, err := IsAccessListMember(ctx, stubMember1, acl1, accessListAndMembersGetter, locksGetter, clock) + require.NoError(t, err) + require.Equal(t, MembershipOrOwnershipTypeExplicit, membershipType) + + // When user is Locked, should not be considered a Member. + lock, err := types.NewLock("user-lock", types.LockSpecV2{ + Target: types.LockTarget{ + User: member1, + }, + }) + require.NoError(t, err) + locksGetter.targets[member1] = []types.Lock{lock} + + membershipType, err = IsAccessListMember(ctx, stubMember1, acl1, accessListAndMembersGetter, locksGetter, clock) + require.ErrorIs(t, err, trace.AccessDenied("User '%s' is currently locked", member1)) + require.Equal(t, MembershipOrOwnershipTypeNone, membershipType) +} + +func TestGetOwners(t *testing.T) { + ctx := context.Background() + clock := clockwork.NewFakeClock() + + // Create Access Lists + acl1 := newAccessList(t, "1", clock) + acl2 := newAccessList(t, "2", clock) + acl3 := newAccessList(t, "3", clock) + + // Set up owners + // acl1 is owned by user "ownerA" and access list acl2 + acl1.Spec.Owners = []accesslist.Owner{ + { + Name: "ownerA", + MembershipKind: accesslist.MembershipKindUser, + }, + { + Name: acl2.GetName(), + MembershipKind: accesslist.MembershipKindList, + }, + } + acl2.Status.OwnerOf = append(acl2.Status.OwnerOf, acl1.GetName()) + + // acl2 is owned by user "ownerB" and access list aclC + acl2.Spec.Owners = []accesslist.Owner{ + { + Name: "ownerB", + MembershipKind: accesslist.MembershipKindUser, + }, + { + Name: acl3.GetName(), + MembershipKind: accesslist.MembershipKindList, + }, + } + acl3.Status.OwnerOf = append(acl3.Status.OwnerOf, acl2.GetName()) + + // acl3 is owned by user "ownerC" + acl3.Spec.Owners = []accesslist.Owner{ + { + Name: "ownerC", + MembershipKind: accesslist.MembershipKindUser, + }, + } + + // Set up members for owner lists + // aclB has member "memberB" + acl2m1 := newAccessListMember(t, acl2.GetName(), "memberB", accesslist.MembershipKindUser, clock) + // aclC has member "memberC" + acl3m1 := newAccessListMember(t, acl3.GetName(), "memberC", accesslist.MembershipKindUser, clock) + + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + members: map[string][]*accesslist.AccessListMember{ + acl2.GetName(): {acl2m1}, + acl3.GetName(): {acl3m1}, + }, + } + + // Test GetOwners for acl1 + owners, err := GetOwnersFor(ctx, acl1, accessListAndMembersGetter) + require.NoError(t, err) + + // Expected owners: + // - Direct owner: "ownerA" + // - Inherited owners via acl2 (since acl2 is an owner of acl1): + // - Members of acl2: "memberB" + // Note: Owners of acl2 ("ownerB") and members/owners of acl3 are not inherited by acl1 + + expectedOwners := map[string]bool{ + "ownerA": true, // Direct owner of acl1 + "memberB": true, // Member of acl2 (owner list of acl1) + } + + actualOwners := make(map[string]bool) + for _, owner := range owners { + actualOwners[owner.Name] = true + } + + require.Equal(t, expectedOwners, actualOwners, "Owners do not match expected owners") + + // Test GetOwners for acl2 + owners, err = GetOwnersFor(ctx, acl2, accessListAndMembersGetter) + require.NoError(t, err) + + // Expected owners: + // - Direct owner: "ownerB" + // - Inherited owners via acl3 (since acl3 is an owner of acl2): + // - Members of acl3: "memberC" + + expectedOwners = map[string]bool{ + "ownerB": true, // Direct owner of acl2 + "memberC": true, // Member of acl3 (owner list of acl2) + } + + actualOwners = make(map[string]bool) + for _, owner := range owners { + actualOwners[owner.Name] = true + } + + require.Equal(t, expectedOwners, actualOwners, "Owners do not match expected owners") +} + +func TestGetInheritedGrants(t *testing.T) { + ctx := context.Background() + clock := clockwork.NewFakeClock() + + aclroot := newAccessList(t, "root", clock) + acl1 := newAccessList(t, "1", clock) + acl2 := newAccessList(t, "2", clock) + + // aclroot has a trait for owners - "root-owner-trait", and a role for owners - "root-owner-role" + aclroot.Spec.OwnerGrants = accesslist.Grants{ + Traits: map[string][]string{ + "root-owner-trait": {"root-owner-value"}, + }, + Roles: []string{"root-owner-role"}, + } + + // acl1 has a trait for members - "1-member-trait", and a role for members - "1-member-role" + acl1.Spec.Grants = accesslist.Grants{ + Traits: map[string][]string{ + "1-member-trait": {"1-member-value"}, + }, + Roles: []string{"1-member-role"}, + } + + // acl2 has no traits or roles + acl2.Spec.Grants = accesslist.Grants{} + + aclroot.SetOwners([]accesslist.Owner{ + { + Name: acl1.GetName(), + MembershipKind: accesslist.MembershipKindList, + }, + }) + acl1.Status.OwnerOf = append(acl1.Status.OwnerOf, aclroot.GetName()) + + accessListAndMembersGetter := &mockAccessListAndMembersGetter{ + accessLists: map[string]*accesslist.AccessList{ + aclroot.GetName(): aclroot, + acl1.GetName(): acl1, + acl2.GetName(): acl2, + }, + } + + // acl1 is an Owner of aclroot, and acl2 is a Member of acl1. + acl2.Status.MemberOf = append(acl2.Status.MemberOf, acl1.GetName()) + + // so, members of acl2 should inherit aclroot's owner grants, and acl1's member grants. + expectedGrants := &accesslist.Grants{ + Traits: map[string][]string{ + "1-member-trait": {"1-member-value"}, + "root-owner-trait": {"root-owner-value"}, + }, + Roles: []string{"1-member-role", "root-owner-role"}, + } + + grants, err := GetInheritedGrants(ctx, acl2, accessListAndMembersGetter) + require.NoError(t, err) + require.Equal(t, expectedGrants, grants) +} + +func newAccessList(t *testing.T, name string, clock clockwork.Clock) *accesslist.AccessList { + t.Helper() + + accessList, err := accesslist.NewAccessList( + header.Metadata{ + Name: name, + }, + accesslist.Spec{ + Title: name, + Description: "test access list", + Owners: []accesslist.Owner{ + {Name: ownerUser, Description: "owner user", MembershipKind: accesslist.MembershipKindUser}, + {Name: ownerUser2, Description: "owner user 2", MembershipKind: accesslist.MembershipKindUser}, + }, + Audit: accesslist.Audit{ + NextAuditDate: clock.Now().Add(time.Hour * 24 * 365), + Notifications: accesslist.Notifications{ + Start: 336 * time.Hour, // Two weeks. + }, + }, + MembershipRequires: accesslist.Requires{ + Roles: []string{"mrole1", "mrole2"}, + Traits: map[string][]string{ + "mtrait1": {"mvalue1", "mvalue2"}, + "mtrait2": {"mvalue3", "mvalue4"}, + }, + }, + OwnershipRequires: accesslist.Requires{ + Roles: []string{"orole1", "orole2"}, + Traits: map[string][]string{ + "otrait1": {"ovalue1", "ovalue2"}, + "otrait2": {"ovalue3", "ovalue4"}, + }, + }, + Grants: accesslist.Grants{ + Roles: []string{"grole1", "grole2"}, + Traits: map[string][]string{ + "gtrait1": {"gvalue1", "gvalue2"}, + "gtrait2": {"gvalue3", "gvalue4"}, + }, + }, + }, + ) + require.NoError(t, err) + + return accessList +} + +func newAccessListMember(t *testing.T, accessListName, memberName string, memberKind string, clock clockwork.Clock) *accesslist.AccessListMember { + t.Helper() + + member, err := accesslist.NewAccessListMember( + header.Metadata{ + Name: memberName, + }, + accesslist.AccessListMemberSpec{ + AccessList: accessListName, + Name: memberName, + Joined: clock.Now().UTC(), + Expires: clock.Now().UTC().Add(24 * time.Hour), + Reason: "because", + AddedBy: "maxim.dietz@goteleport.com", + MembershipKind: memberKind, + }, + ) + require.NoError(t, err) + + return member +} diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 8723e1c46260c..186a226b853cd 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -1294,30 +1294,6 @@ func (a *Server) syncUpgradeWindowStartHour(ctx context.Context) error { return nil } -func (a *Server) periodicSyncUpgradeWindowStartHour() { - checkInterval := interval.New(interval.Config{ - Duration: time.Minute * 3, - FirstDuration: utils.FullJitter(time.Second * 30), - Jitter: retryutils.NewSeventhJitter(), - }) - defer checkInterval.Stop() - - for { - select { - case <-checkInterval.Next(): - if err := a.syncUpgradeWindowStartHour(a.closeCtx); err != nil { - if a.closeCtx.Err() == nil { - // we run this periodic at a fairly high frequency, so errors are just - // logged but otherwise ignored. - log.Warnf("Failed to sync upgrade window start hour: %v", err) - } - } - case <-a.closeCtx.Done(): - return - } - } -} - // periodicIntervalKey is used to uniquely identify the subintervals registered with // the interval.MultiInterval instance that we use for managing periodics operations. @@ -1527,7 +1503,7 @@ func (a *Server) runPeriodicOperations() { case notificationsCleanupKey: go a.CleanupNotifications(a.closeCtx) case upgradeWindowCheckKey: - go a.periodicSyncUpgradeWindowStartHour() + go a.syncUpgradeWindowStartHour(a.closeCtx) case roleCountKey: go a.tallyRoles(a.closeCtx) } diff --git a/lib/auth/autoupdate/autoupdatev1/service.go b/lib/auth/autoupdate/autoupdatev1/service.go index 4852edaf6707a..993860203746f 100644 --- a/lib/auth/autoupdate/autoupdatev1/service.go +++ b/lib/auth/autoupdate/autoupdatev1/service.go @@ -20,13 +20,16 @@ package autoupdatev1 import ( "context" + "log/slog" "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/emptypb" "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" "github.com/gravitational/teleport/api/types" + apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/authz" + "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/services" ) @@ -50,6 +53,8 @@ type ServiceConfig struct { Backend services.AutoUpdateService // Cache is the cache used to store AutoUpdate resources. Cache Cache + // Emitter is the event emitter. + Emitter apievents.Emitter } // Service implements the gRPC API layer for the AutoUpdate. @@ -58,6 +63,7 @@ type Service struct { authorizer authz.Authorizer backend services.AutoUpdateService + emitter apievents.Emitter cache Cache } @@ -70,11 +76,14 @@ func NewService(cfg ServiceConfig) (*Service, error) { return nil, trace.BadParameter("authorizer is required") case cfg.Cache == nil: return nil, trace.BadParameter("cache is required") + case cfg.Emitter == nil: + return nil, trace.BadParameter("Emitter is required") } return &Service{ authorizer: cfg.Authorizer, backend: cfg.Backend, cache: cfg.Cache, + emitter: cfg.Emitter, }, nil } @@ -113,6 +122,27 @@ func (s *Service) CreateAutoUpdateConfig(ctx context.Context, req *autoupdate.Cr } config, err := s.backend.CreateAutoUpdateConfig(ctx, req.Config) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateConfigCreate{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateConfigCreateEvent, + Code: events.AutoUpdateConfigCreateCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateConfig, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) return config, trace.Wrap(err) } @@ -132,6 +162,27 @@ func (s *Service) UpdateAutoUpdateConfig(ctx context.Context, req *autoupdate.Up } config, err := s.backend.UpdateAutoUpdateConfig(ctx, req.Config) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateConfigUpdate{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateConfigUpdateEvent, + Code: events.AutoUpdateConfigUpdateCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateConfig, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) return config, trace.Wrap(err) } @@ -151,6 +202,27 @@ func (s *Service) UpsertAutoUpdateConfig(ctx context.Context, req *autoupdate.Up } config, err := s.backend.UpsertAutoUpdateConfig(ctx, req.Config) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateConfigUpdate{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateConfigUpdateEvent, + Code: events.AutoUpdateConfigUpdateCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateConfig, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) return config, trace.Wrap(err) } @@ -169,10 +241,29 @@ func (s *Service) DeleteAutoUpdateConfig(ctx context.Context, req *autoupdate.De return nil, trace.Wrap(err) } - if err := s.backend.DeleteAutoUpdateConfig(ctx); err != nil { - return nil, trace.Wrap(err) - } - return &emptypb.Empty{}, nil + err = s.backend.DeleteAutoUpdateConfig(ctx) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateConfigDelete{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateConfigDeleteEvent, + Code: events.AutoUpdateConfigDeleteCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateConfig, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) + return &emptypb.Empty{}, trace.Wrap(err) } // GetAutoUpdateVersion gets the current AutoUpdateVersion singleton. @@ -210,6 +301,28 @@ func (s *Service) CreateAutoUpdateVersion(ctx context.Context, req *autoupdate.C } autoUpdateVersion, err := s.backend.CreateAutoUpdateVersion(ctx, req.Version) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateVersionCreate{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateVersionCreateEvent, + Code: events.AutoUpdateVersionCreateCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateVersion, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) + return autoUpdateVersion, trace.Wrap(err) } @@ -229,6 +342,28 @@ func (s *Service) UpdateAutoUpdateVersion(ctx context.Context, req *autoupdate.U } autoUpdateVersion, err := s.backend.UpdateAutoUpdateVersion(ctx, req.Version) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateVersionUpdate{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateVersionUpdateEvent, + Code: events.AutoUpdateVersionUpdateCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateVersion, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) + return autoUpdateVersion, trace.Wrap(err) } @@ -248,6 +383,28 @@ func (s *Service) UpsertAutoUpdateVersion(ctx context.Context, req *autoupdate.U } autoUpdateVersion, err := s.backend.UpsertAutoUpdateVersion(ctx, req.Version) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateVersionUpdate{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateVersionUpdateEvent, + Code: events.AutoUpdateVersionUpdateCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateVersion, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) + return autoUpdateVersion, trace.Wrap(err) } @@ -266,10 +423,29 @@ func (s *Service) DeleteAutoUpdateVersion(ctx context.Context, req *autoupdate.D return nil, trace.Wrap(err) } - if err := s.backend.DeleteAutoUpdateVersion(ctx); err != nil { - return nil, trace.Wrap(err) - } - return &emptypb.Empty{}, nil + err = s.backend.DeleteAutoUpdateVersion(ctx) + var errMsg string + if err != nil { + errMsg = err.Error() + } + userMetadata := authz.ClientUserMetadata(ctx) + s.emitEvent(ctx, &apievents.AutoUpdateVersionDelete{ + Metadata: apievents.Metadata{ + Type: events.AutoUpdateVersionDeleteEvent, + Code: events.AutoUpdateVersionDeleteCode, + }, + UserMetadata: userMetadata, + ResourceMetadata: apievents.ResourceMetadata{ + Name: types.MetaNameAutoUpdateVersion, + UpdatedBy: userMetadata.User, + }, + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: apievents.Status{ + Success: err == nil, + Error: errMsg, + }, + }) + return &emptypb.Empty{}, trace.Wrap(err) } // GetAutoUpdateAgentRollout gets the current AutoUpdateAgentRollout singleton. @@ -404,3 +580,12 @@ func (s *Service) DeleteAutoUpdateAgentRollout(ctx context.Context, req *autoupd } return &emptypb.Empty{}, nil } + +func (s *Service) emitEvent(ctx context.Context, e apievents.AuditEvent) { + if err := s.emitter.EmitAuditEvent(ctx, e); err != nil { + slog.WarnContext(ctx, "Failed to emit audit event", + "type", e.GetType(), + "error", err, + ) + } +} diff --git a/lib/auth/autoupdate/autoupdatev1/service_test.go b/lib/auth/autoupdate/autoupdatev1/service_test.go index dd1d6df087db5..eb3220792b939 100644 --- a/lib/auth/autoupdate/autoupdatev1/service_test.go +++ b/lib/auth/autoupdate/autoupdatev1/service_test.go @@ -25,10 +25,14 @@ import ( "github.com/gravitational/trace" "github.com/stretchr/testify/require" - "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" + autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/autoupdate" + apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/backend/memory" + libevents "github.com/gravitational/teleport/lib/events" + "github.com/gravitational/teleport/lib/events/eventstest" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/local" "github.com/gravitational/teleport/lib/utils" @@ -63,7 +67,7 @@ func otherAdminStates(states []authz.AdminActionAuthState) []authz.AdminActionAu // callMethod calls a method with given name in the DatabaseObjectService service func callMethod(t *testing.T, service *Service, method string) error { - for _, desc := range autoupdate.AutoUpdateService_ServiceDesc.Methods { + for _, desc := range autoupdatev1pb.AutoUpdateService_ServiceDesc.Methods { if desc.MethodName == method { _, err := desc.Handler(service, context.Background(), func(_ any) error { return nil }, nil) return err @@ -225,7 +229,7 @@ func TestServiceAccess(t *testing.T) { t.Run(stateToString(state), func(t *testing.T) { for _, verbs := range utils.Combinations(tt.allowedVerbs) { t.Run(fmt.Sprintf("verbs=%v", verbs), func(t *testing.T) { - service := newService(t, state, fakeChecker{allowedVerbs: verbs, builtinRole: tt.builtinRole}) + service := newService(t, state, fakeChecker{allowedVerbs: verbs, builtinRole: tt.builtinRole}, &libevents.DiscardEmitter{}) err := callMethod(t, service, tt.name) // expect access denied except with full set of verbs. if len(verbs) == len(tt.allowedVerbs) { @@ -249,7 +253,7 @@ func TestServiceAccess(t *testing.T) { t.Run(stateToString(state), func(t *testing.T) { // it is enough to test against tt.allowedVerbs, // this is the only different data point compared to the test cases above. - service := newService(t, state, fakeChecker{allowedVerbs: tt.allowedVerbs, builtinRole: tt.builtinRole}) + service := newService(t, state, fakeChecker{allowedVerbs: tt.allowedVerbs, builtinRole: tt.builtinRole}, &libevents.DiscardEmitter{}) err := callMethod(t, service, tt.name) require.True(t, trace.IsAccessDenied(err)) }) @@ -260,7 +264,7 @@ func TestServiceAccess(t *testing.T) { // verify that all declared methods have matching test cases t.Run("verify coverage", func(t *testing.T) { - for _, method := range autoupdate.AutoUpdateService_ServiceDesc.Methods { + for _, method := range autoupdatev1pb.AutoUpdateService_ServiceDesc.Methods { t.Run(method.MethodName, func(t *testing.T) { match := false for _, testCase := range testCases { @@ -272,6 +276,98 @@ func TestServiceAccess(t *testing.T) { }) } +func TestAutoUpdateConfigEvents(t *testing.T) { + rwVerbs := []string{types.VerbList, types.VerbCreate, types.VerbRead, types.VerbUpdate, types.VerbDelete} + mockEmitter := &eventstest.MockRecorderEmitter{} + service := newService(t, authz.AdminActionAuthMFAVerified, fakeChecker{allowedVerbs: rwVerbs}, mockEmitter) + ctx := context.Background() + + config, err := autoupdate.NewAutoUpdateConfig(&autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeEnabled, + }, + }) + require.NoError(t, err) + + _, err = service.CreateAutoUpdateConfig(ctx, &autoupdatev1pb.CreateAutoUpdateConfigRequest{Config: config}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateConfigCreateEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateConfigCreateCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateConfig, mockEmitter.LastEvent().(*apievents.AutoUpdateConfigCreate).Name) + mockEmitter.Reset() + + _, err = service.UpdateAutoUpdateConfig(ctx, &autoupdatev1pb.UpdateAutoUpdateConfigRequest{Config: config}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateConfigUpdateEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateConfigUpdateCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateConfig, mockEmitter.LastEvent().(*apievents.AutoUpdateConfigUpdate).Name) + mockEmitter.Reset() + + _, err = service.UpsertAutoUpdateConfig(ctx, &autoupdatev1pb.UpsertAutoUpdateConfigRequest{Config: config}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateConfigUpdateEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateConfigUpdateCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateConfig, mockEmitter.LastEvent().(*apievents.AutoUpdateConfigUpdate).Name) + mockEmitter.Reset() + + _, err = service.DeleteAutoUpdateConfig(ctx, &autoupdatev1pb.DeleteAutoUpdateConfigRequest{}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateConfigDeleteEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateConfigDeleteCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateConfig, mockEmitter.LastEvent().(*apievents.AutoUpdateConfigDelete).Name) + mockEmitter.Reset() +} + +func TestAutoUpdateVersionEvents(t *testing.T) { + rwVerbs := []string{types.VerbList, types.VerbCreate, types.VerbRead, types.VerbUpdate, types.VerbDelete} + mockEmitter := &eventstest.MockRecorderEmitter{} + service := newService(t, authz.AdminActionAuthMFAVerified, fakeChecker{allowedVerbs: rwVerbs}, mockEmitter) + ctx := context.Background() + + config, err := autoupdate.NewAutoUpdateVersion(&autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, + }) + require.NoError(t, err) + + _, err = service.CreateAutoUpdateVersion(ctx, &autoupdatev1pb.CreateAutoUpdateVersionRequest{Version: config}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateVersionCreateEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateVersionCreateCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateVersion, mockEmitter.LastEvent().(*apievents.AutoUpdateVersionCreate).Name) + mockEmitter.Reset() + + _, err = service.UpdateAutoUpdateVersion(ctx, &autoupdatev1pb.UpdateAutoUpdateVersionRequest{Version: config}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateVersionUpdateEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateVersionUpdateCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateVersion, mockEmitter.LastEvent().(*apievents.AutoUpdateVersionUpdate).Name) + mockEmitter.Reset() + + _, err = service.UpsertAutoUpdateVersion(ctx, &autoupdatev1pb.UpsertAutoUpdateVersionRequest{Version: config}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateVersionUpdateEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateVersionUpdateCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateVersion, mockEmitter.LastEvent().(*apievents.AutoUpdateVersionUpdate).Name) + mockEmitter.Reset() + + _, err = service.DeleteAutoUpdateVersion(ctx, &autoupdatev1pb.DeleteAutoUpdateVersionRequest{}) + require.NoError(t, err) + require.Len(t, mockEmitter.Events(), 1) + require.Equal(t, libevents.AutoUpdateVersionDeleteEvent, mockEmitter.LastEvent().GetType()) + require.Equal(t, libevents.AutoUpdateVersionDeleteCode, mockEmitter.LastEvent().GetCode()) + require.Equal(t, types.MetaNameAutoUpdateVersion, mockEmitter.LastEvent().(*apievents.AutoUpdateVersionDelete).Name) + mockEmitter.Reset() +} + type fakeChecker struct { allowedVerbs []string builtinRole *authz.BuiltinRole @@ -304,7 +400,7 @@ func (f fakeChecker) identityGetter() authz.IdentityGetter { return nil } -func newService(t *testing.T, authState authz.AdminActionAuthState, checker fakeChecker) *Service { +func newService(t *testing.T, authState authz.AdminActionAuthState, checker fakeChecker, emitter apievents.Emitter) *Service { t.Helper() bk, err := memory.New(memory.Config{}) @@ -313,10 +409,10 @@ func newService(t *testing.T, authState authz.AdminActionAuthState, checker fake storage, err := local.NewAutoUpdateService(bk) require.NoError(t, err) - return newServiceWithStorage(t, authState, checker, storage) + return newServiceWithStorage(t, authState, checker, storage, emitter) } -func newServiceWithStorage(t *testing.T, authState authz.AdminActionAuthState, checker fakeChecker, storage services.AutoUpdateService) *Service { +func newServiceWithStorage(t *testing.T, authState authz.AdminActionAuthState, checker fakeChecker, storage services.AutoUpdateService, emitter apievents.Emitter) *Service { t.Helper() authorizer := authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { @@ -337,6 +433,7 @@ func newServiceWithStorage(t *testing.T, authState authz.AdminActionAuthState, c Authorizer: authorizer, Backend: storage, Cache: storage, + Emitter: emitter, }) require.NoError(t, err) return service diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index e94eea9fb04f9..b4bd1d985ea97 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -5336,6 +5336,7 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { autoUpdateServiceServer, err := autoupdatev1.NewService(autoupdatev1.ServiceConfig{ Authorizer: cfg.Authorizer, + Emitter: cfg.Emitter, Backend: cfg.AuthServer.Services, Cache: cfg.AuthServer.Cache, }) diff --git a/lib/auth/helpers.go b/lib/auth/helpers.go index ba403790d0675..99818886c00dc 100644 --- a/lib/auth/helpers.go +++ b/lib/auth/helpers.go @@ -1098,7 +1098,8 @@ func (t *TestTLSServer) CloneClient(tt *testing.T, clt *authclient.Client) *auth // shared between all clients that use the same TLS config. // Reusing the cache will skip the TLS handshake and may introduce a weird // behavior in tests. - if !tlsConfig.SessionTicketsDisabled { + if tlsConfig.ClientSessionCache != nil { + tlsConfig = tlsConfig.Clone() tlsConfig.ClientSessionCache = tls.NewLRUClientSessionCache(utils.DefaultLRUCapacity) } diff --git a/lib/autoupdate/tools/progress.go b/lib/autoupdate/tools/progress.go index 95395003730ec..34bbad2ff888d 100644 --- a/lib/autoupdate/tools/progress.go +++ b/lib/autoupdate/tools/progress.go @@ -20,24 +20,59 @@ package tools import ( "fmt" + "io" "strings" + + "github.com/gravitational/trace" ) type progressWriter struct { - n int64 - limit int64 + n int64 + limit int64 + size int + progress int } -func (w *progressWriter) Write(p []byte) (int, error) { - w.n = w.n + int64(len(p)) +// newProgressWriter creates progress writer instance and prints empty +// progress bar right after initialisation. +func newProgressWriter(size int) (*progressWriter, func()) { + pw := &progressWriter{size: size} + pw.Print(0) + return pw, func() { + fmt.Print("\n") + } +} - n := int((w.n*100)/w.limit) / 10 - bricks := strings.Repeat("▒", n) + strings.Repeat(" ", 10-n) +// Print prints the update progress bar with `n` bricks. +func (w *progressWriter) Print(n int) { + bricks := strings.Repeat("▒", n) + strings.Repeat(" ", w.size-n) fmt.Print("\rUpdate progress: [" + bricks + "] (Ctrl-C to cancel update)") +} - if w.n == w.limit { - fmt.Print("\n") +func (w *progressWriter) Write(p []byte) (int, error) { + if w.limit == 0 || w.size == 0 { + return len(p), nil + } + + w.n += int64(len(p)) + bricks := int((w.n*100)/w.limit) / w.size + if w.progress != bricks { + w.Print(bricks) + w.progress = bricks } return len(p), nil } + +// CopyLimit sets the limit of writing bytes to the progress writer and initiate copying process. +func (w *progressWriter) CopyLimit(dst io.Writer, src io.Reader, limit int64) (written int64, err error) { + if limit < 0 { + n, err := io.Copy(dst, io.TeeReader(src, w)) + w.Print(w.size) + return n, trace.Wrap(err) + } + + w.limit = limit + n, err := io.CopyN(dst, io.TeeReader(src, w), limit) + return n, trace.Wrap(err) +} diff --git a/lib/autoupdate/tools/updater.go b/lib/autoupdate/tools/updater.go index 96991044ccc31..96352e34d9910 100644 --- a/lib/autoupdate/tools/updater.go +++ b/lib/autoupdate/tools/updater.go @@ -36,12 +36,12 @@ import ( "syscall" "time" + "github.com/coreos/go-semver/semver" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/gravitational/teleport/api/client/webclient" "github.com/gravitational/teleport/api/constants" - "github.com/gravitational/teleport/api/types/autoupdate" "github.com/gravitational/teleport/lib/utils" "github.com/gravitational/teleport/lib/utils/packaging" ) @@ -114,30 +114,37 @@ func NewUpdater(tools []string, toolsDir string, localVersion string, options .. // CheckLocal is run at client tool startup and will only perform local checks. // Returns the version needs to be updated and re-executed, by re-execution flag we // understand that update and re-execute is required. -func (u *Updater) CheckLocal() (version string, reExec bool) { +func (u *Updater) CheckLocal() (version string, reExec bool, err error) { // Check if the user has requested a specific version of client tools. requestedVersion := os.Getenv(teleportToolsVersionEnv) switch requestedVersion { // The user has turned off any form of automatic updates. case "off": - return "", false + return "", false, nil // Requested version already the same as client version. case u.localVersion: - return u.localVersion, false + return u.localVersion, false, nil + // No requested version, we continue. + case "": + // Requested version that is not the local one. + default: + if _, err := semver.NewVersion(requestedVersion); err != nil { + return "", false, trace.Wrap(err, "checking that request version is semantic") + } + return requestedVersion, true, nil } // If a version of client tools has already been downloaded to // tools directory, return that. - toolsVersion, err := checkToolVersion(u.toolsDir) - if err != nil { - return "", false + toolsVersion, err := CheckToolVersion(u.toolsDir) + if trace.IsNotFound(err) { + return u.localVersion, false, nil } - // The user has requested a specific version of client tools. - if requestedVersion != "" && requestedVersion != toolsVersion { - return requestedVersion, true + if err != nil { + return "", false, trace.Wrap(err) } - return toolsVersion, false + return toolsVersion, true, nil } // CheckRemote first checks the version set by the environment variable. If not set or disabled, @@ -145,7 +152,7 @@ func (u *Updater) CheckLocal() (version string, reExec bool) { // the `webapi/find` handler, which stores information about the required client tools version to // operate with this cluster. It returns the semantic version that needs updating and whether // re-execution is necessary, by re-execution flag we understand that update and re-execute is required. -func (u *Updater) CheckRemote(ctx context.Context, proxyAddr string) (version string, reExec bool, err error) { +func (u *Updater) CheckRemote(ctx context.Context, proxyAddr string, insecure bool) (version string, reExec bool, err error) { // Check if the user has requested a specific version of client tools. requestedVersion := os.Getenv(teleportToolsVersionEnv) switch requestedVersion { @@ -155,6 +162,14 @@ func (u *Updater) CheckRemote(ctx context.Context, proxyAddr string) (version st // Requested version already the same as client version. case u.localVersion: return u.localVersion, false, nil + // No requested version, we continue. + case "": + // Requested version that is not the local one. + default: + if _, err := semver.NewVersion(requestedVersion); err != nil { + return "", false, trace.Wrap(err, "checking that request version is semantic") + } + return requestedVersion, true, nil } certPool, err := x509.SystemCertPool() @@ -165,7 +180,8 @@ func (u *Updater) CheckRemote(ctx context.Context, proxyAddr string) (version st Context: ctx, ProxyAddr: proxyAddr, Pool: certPool, - Timeout: 30 * time.Second, + Timeout: 10 * time.Second, + Insecure: insecure, }) if err != nil { return "", false, trace.Wrap(err) @@ -173,28 +189,28 @@ func (u *Updater) CheckRemote(ctx context.Context, proxyAddr string) (version st // If a version of client tools has already been downloaded to // tools directory, return that. - toolsVersion, err := checkToolVersion(u.toolsDir) - if err != nil { + toolsVersion, err := CheckToolVersion(u.toolsDir) + if err != nil && !trace.IsNotFound(err) { return "", false, trace.Wrap(err) } switch { - case requestedVersion != "" && requestedVersion != toolsVersion: - return requestedVersion, true, nil - case resp.AutoUpdate.ToolsMode != autoupdate.ToolsUpdateModeEnabled || resp.AutoUpdate.ToolsVersion == "": - return "", false, nil + case !resp.AutoUpdate.ToolsAutoUpdate || resp.AutoUpdate.ToolsVersion == "": + if toolsVersion == "" { + return u.localVersion, false, nil + } case u.localVersion == resp.AutoUpdate.ToolsVersion: - return resp.AutoUpdate.ToolsVersion, false, nil + return u.localVersion, false, nil case resp.AutoUpdate.ToolsVersion != toolsVersion: return resp.AutoUpdate.ToolsVersion, true, nil } - return toolsVersion, false, nil + return toolsVersion, true, nil } // UpdateWithLock acquires filesystem lock, downloads requested version package, // unarchive and replace existing one. -func (u *Updater) UpdateWithLock(ctx context.Context, toolsVersion string) (err error) { +func (u *Updater) UpdateWithLock(ctx context.Context, updateToolsVersion string) (err error) { // Create tools directory if it does not exist. if err := os.MkdirAll(u.toolsDir, 0o755); err != nil { return trace.Wrap(err) @@ -211,21 +227,20 @@ func (u *Updater) UpdateWithLock(ctx context.Context, toolsVersion string) (err // If the version of the running binary or the version downloaded to // tools directory is the same as the requested version of client tools, // nothing to be done, exit early. - teleportVersion, err := checkToolVersion(u.toolsDir) + toolsVersion, err := CheckToolVersion(u.toolsDir) if err != nil && !trace.IsNotFound(err) { return trace.Wrap(err) - } - if toolsVersion == u.localVersion || toolsVersion == teleportVersion { + if updateToolsVersion == toolsVersion { return nil } // Download and update client tools in tools directory. - if err := u.Update(ctx, toolsVersion); err != nil { + if err := u.Update(ctx, updateToolsVersion); err != nil { return trace.Wrap(err) } - return + return nil } // Update downloads requested version and replace it with existing one and cleanups the previous downloads @@ -237,10 +252,18 @@ func (u *Updater) Update(ctx context.Context, toolsVersion string) error { return trace.Wrap(err) } + var pkgNames []string for _, pkg := range packages { - if err := u.update(ctx, pkg); err != nil { + pkgName := fmt.Sprint(uuid.New().String(), updatePackageSuffix) + if err := u.update(ctx, pkg, pkgName); err != nil { return trace.Wrap(err) } + pkgNames = append(pkgNames, pkgName) + } + + // Cleanup the tools directory with previously downloaded and un-archived versions. + if err := packaging.RemoveWithSuffix(u.toolsDir, updatePackageSuffix, pkgNames); err != nil { + slog.WarnContext(ctx, "failed to clean up tools directory", "error", err) } return nil @@ -248,16 +271,8 @@ func (u *Updater) Update(ctx context.Context, toolsVersion string) error { // update downloads the archive and validate against the hash. Download to a // temporary path within tools directory. -func (u *Updater) update(ctx context.Context, pkg packageURL) error { - hash, err := u.downloadHash(ctx, pkg.Hash) - if pkg.Optional && trace.IsNotFound(err) { - return nil - } - if err != nil { - return trace.Wrap(err) - } - - f, err := os.CreateTemp(u.toolsDir, "tmp-") +func (u *Updater) update(ctx context.Context, pkg packageURL, pkgName string) error { + f, err := os.CreateTemp("", "teleport-") if err != nil { return trace.Wrap(err) } @@ -275,11 +290,19 @@ func (u *Updater) update(ctx context.Context, pkg packageURL) error { if err != nil { return trace.Wrap(err) } + + hash, err := u.downloadHash(ctx, pkg.Hash) + if pkg.Optional && trace.IsNotFound(err) { + return nil + } + if err != nil { + return trace.Wrap(err) + } + if !bytes.Equal(archiveHash, hash) { return trace.BadParameter("hash of archive does not match downloaded archive") } - pkgName := fmt.Sprint(uuid.New().String(), updatePackageSuffix) extractDir := filepath.Join(u.toolsDir, pkgName) if runtime.GOOS != constants.DarwinOS { if err := os.Mkdir(extractDir, 0o755); err != nil { @@ -291,10 +314,6 @@ func (u *Updater) update(ctx context.Context, pkg packageURL) error { if err := packaging.ReplaceToolsBinaries(u.toolsDir, f.Name(), extractDir, u.tools); err != nil { return trace.Wrap(err) } - // Cleanup the tools directory with previously downloaded and un-archived versions. - if err := packaging.RemoveWithSuffix(u.toolsDir, updatePackageSuffix, pkgName); err != nil { - return trace.Wrap(err) - } return nil } @@ -340,7 +359,7 @@ func (u *Updater) downloadHash(ctx context.Context, url string) ([]byte, error) } defer resp.Body.Close() if resp.StatusCode == http.StatusNotFound { - return nil, trace.NotFound("hash file is not found: %v", resp.StatusCode) + return nil, trace.NotFound("hash file is not found: %q", url) } if resp.StatusCode != http.StatusOK { return nil, trace.BadParameter("bad status when downloading archive hash: %v", resp.StatusCode) @@ -362,6 +381,11 @@ func (u *Updater) downloadHash(ctx context.Context, url string) ([]byte, error) // downloadArchive downloads the archive package by `url` and writes content to the writer interface, // return calculated sha256 hash sum of the content. func (u *Updater) downloadArchive(ctx context.Context, url string, f io.Writer) ([]byte, error) { + // Display a progress bar before initiating the update request to inform the user that + // an update is in progress, allowing them the option to cancel before actual response + // which might be delayed with slow internet connection or complete isolation to CDN. + pw, finish := newProgressWriter(10) + defer finish() req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, trace.Wrap(err) @@ -385,14 +409,10 @@ func (u *Updater) downloadArchive(ctx context.Context, url string, f io.Writer) } h := sha256.New() - pw := &progressWriter{n: 0, limit: resp.ContentLength} - body := io.TeeReader(io.TeeReader(resp.Body, h), pw) - // It is a little inefficient to download the file to disk and then re-load // it into memory to unarchive later, but this is safer as it allows client // tools to validate the hash before trying to operate on the archive. - _, err = io.CopyN(f, body, resp.ContentLength) - if err != nil { + if _, err := pw.CopyLimit(f, io.TeeReader(resp.Body, h), resp.ContentLength); err != nil { return nil, trace.Wrap(err) } diff --git a/lib/autoupdate/tools/utils.go b/lib/autoupdate/tools/utils.go index d552b31abefe4..f937d228b5cd4 100644 --- a/lib/autoupdate/tools/utils.go +++ b/lib/autoupdate/tools/utils.go @@ -33,6 +33,7 @@ import ( "github.com/coreos/go-semver/semver" "github.com/gravitational/trace" + "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/utils" @@ -52,14 +53,26 @@ func Dir() (string, error) { return filepath.Join(home, ".tsh", "bin"), nil } -func checkToolVersion(toolsDir string) (string, error) { +// DefaultClientTools list of the client tools needs to be updated by default. +func DefaultClientTools() []string { + switch runtime.GOOS { + case constants.WindowsOS: + return []string{"tsh.exe", "tctl.exe"} + default: + return []string{"tsh", "tctl"} + } +} + +// CheckToolVersion returns current installed client tools version, must return NotFoundError if +// the client tools is not found in tools directory. +func CheckToolVersion(toolsDir string) (string, error) { // Find the path to the current executable. path, err := toolName(toolsDir) if err != nil { return "", trace.Wrap(err) } if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { - return "", nil + return "", trace.NotFound("autoupdate tool not found in %q", toolsDir) } else if err != nil { return "", trace.Wrap(err) } @@ -76,7 +89,7 @@ func checkToolVersion(toolsDir string) (string, error) { command.Env = []string{teleportToolsVersionEnv + "=off"} output, err := command.Output() if err != nil { - return "", trace.Wrap(err) + return "", trace.WrapWithMessage(err, "failed to determine version of %q tool", path) } // The output for "{tsh, tctl} version" can be multiple lines. Find the diff --git a/lib/client/api.go b/lib/client/api.go index d087fb02d1e34..d8a35dc95feee 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -74,6 +74,7 @@ import ( "github.com/gravitational/teleport/lib/auth/touchid" wancli "github.com/gravitational/teleport/lib/auth/webauthncli" "github.com/gravitational/teleport/lib/authz" + "github.com/gravitational/teleport/lib/autoupdate/tools" libmfa "github.com/gravitational/teleport/lib/client/mfa" "github.com/gravitational/teleport/lib/client/sso" "github.com/gravitational/teleport/lib/client/terminal" @@ -95,6 +96,7 @@ import ( "github.com/gravitational/teleport/lib/utils" "github.com/gravitational/teleport/lib/utils/agentconn" logutils "github.com/gravitational/teleport/lib/utils/log" + "github.com/gravitational/teleport/lib/utils/signal" ) const ( @@ -702,6 +704,39 @@ func RetryWithRelogin(ctx context.Context, tc *TeleportClient, fn func() error, return trace.Wrap(err) } + // The user has typed a command like `tsh ssh ...` without being logged in, + // if the running binary needs to be updated, update and re-exec. + // + // If needed, download the new version of {tsh, tctl} and re-exec. Make + // sure to exit this process with the same exit code as the child process. + // + toolsDir, err := tools.Dir() + if err != nil { + return trace.Wrap(err) + } + updater := tools.NewUpdater(tools.DefaultClientTools(), toolsDir, teleport.Version) + toolsVersion, reExec, err := updater.CheckRemote(ctx, tc.WebProxyAddr, tc.InsecureSkipVerify) + if err != nil { + return trace.Wrap(err) + } + if reExec { + ctxUpdate, cancel := signal.GetSignalHandler().NotifyContext(context.Background()) + defer cancel() + // Download the version of client tools required by the cluster. + err := updater.UpdateWithLock(ctxUpdate, toolsVersion) + if err != nil && !errors.Is(err, context.Canceled) { + utils.FatalError(err) + } + // Re-execute client tools with the correct version of client tools. + code, err := updater.Exec() + if err != nil && !errors.Is(err, os.ErrNotExist) { + log.Debugf("Failed to re-exec client tool: %v.", err) + os.Exit(code) + } else if err == nil { + os.Exit(code) + } + } + if opt.afterLoginHook != nil { if err := opt.afterLoginHook(); err != nil { return trace.Wrap(err) diff --git a/lib/events/api.go b/lib/events/api.go index 387e82d7a541d..20b72ddd2e5f9 100644 --- a/lib/events/api.go +++ b/lib/events/api.go @@ -285,6 +285,8 @@ const ( // SFTPEvent means a user attempted a file operation SFTPEvent = "sftp" SFTPPath = "path" + // SFTPSummaryEvent is emitted at the end of an SFTP transfer. + SFTPSummaryEvent = "sftp_summary" // ResizeEvent means that some user resized PTY on the client ResizeEvent = "resize" @@ -822,6 +824,20 @@ const ( UserTaskUpdateEvent = "user_task.update" // UserTaskDeleteEvent is emitted when a user task resource is deleted. UserTaskDeleteEvent = "user_task.delete" + + // AutoUpdateConfigCreateEvent is emitted when a AutoUpdateConfig resource is created. + AutoUpdateConfigCreateEvent = "auto_update_config.create" + // AutoUpdateConfigUpdateEvent is emitted when a AutoUpdateConfig resource is updated. + AutoUpdateConfigUpdateEvent = "auto_update_config.update" + // AutoUpdateConfigDeleteEvent is emitted when a AutoUpdateConfig resource is deleted. + AutoUpdateConfigDeleteEvent = "auto_update_config.delete" + + // AutoUpdateVersionCreateEvent is emitted when a AutoUpdateVersion resource is created. + AutoUpdateVersionCreateEvent = "auto_update_version.create" + // AutoUpdateVersionUpdateEvent is emitted when a AutoUpdateVersion resource is updated. + AutoUpdateVersionUpdateEvent = "auto_update_version.update" + // AutoUpdateVersionDeleteEvent is emitted when a AutoUpdateVersion resource is deleted. + AutoUpdateVersionDeleteEvent = "auto_update_version.delete" ) // Add an entry to eventsMap in lib/events/events_test.go when you add diff --git a/lib/events/codes.go b/lib/events/codes.go index e26cc1294d257..fa8c284fe925b 100644 --- a/lib/events/codes.go +++ b/lib/events/codes.go @@ -320,45 +320,29 @@ const ( KubernetesClusterDeleteCode = "T3012I" // The following codes correspond to SFTP file operations. - SFTPOpenCode = "TS001I" - SFTPOpenFailureCode = "TS001E" - SFTPCloseCode = "TS002I" - SFTPCloseFailureCode = "TS002E" - SFTPReadCode = "TS003I" - SFTPReadFailureCode = "TS003E" - SFTPWriteCode = "TS004I" - SFTPWriteFailureCode = "TS004E" - SFTPLstatCode = "TS005I" - SFTPLstatFailureCode = "TS005E" - SFTPFstatCode = "TS006I" - SFTPFstatFailureCode = "TS006E" - SFTPSetstatCode = "TS007I" - SFTPSetstatFailureCode = "TS007E" - SFTPFsetstatCode = "TS008I" - SFTPFsetstatFailureCode = "TS008E" - SFTPOpendirCode = "TS009I" - SFTPOpendirFailureCode = "TS009E" - SFTPReaddirCode = "TS010I" - SFTPReaddirFailureCode = "TS010E" - SFTPRemoveCode = "TS011I" - SFTPRemoveFailureCode = "TS011E" - SFTPMkdirCode = "TS012I" - SFTPMkdirFailureCode = "TS012E" - SFTPRmdirCode = "TS013I" - SFTPRmdirFailureCode = "TS013E" - SFTPRealpathCode = "TS014I" - SFTPRealpathFailureCode = "TS014E" - SFTPStatCode = "TS015I" - SFTPStatFailureCode = "TS015E" - SFTPRenameCode = "TS016I" - SFTPRenameFailureCode = "TS016E" - SFTPReadlinkCode = "TS017I" - SFTPReadlinkFailureCode = "TS017E" - SFTPSymlinkCode = "TS018I" - SFTPSymlinkFailureCode = "TS018E" - SFTPLinkCode = "TS019I" - SFTPLinkFailureCode = "TS019E" - SFTPDisallowedCode = "TS020E" + SFTPOpenCode = "TS001I" + SFTPOpenFailureCode = "TS001E" + SFTPSetstatCode = "TS007I" + SFTPSetstatFailureCode = "TS007E" + SFTPOpendirCode = "TS009I" + SFTPOpendirFailureCode = "TS009E" + SFTPReaddirCode = "TS010I" + SFTPReaddirFailureCode = "TS010E" + SFTPRemoveCode = "TS011I" + SFTPRemoveFailureCode = "TS011E" + SFTPMkdirCode = "TS012I" + SFTPMkdirFailureCode = "TS012E" + SFTPRmdirCode = "TS013I" + SFTPRmdirFailureCode = "TS013E" + SFTPRenameCode = "TS016I" + SFTPRenameFailureCode = "TS016E" + SFTPSymlinkCode = "TS018I" + SFTPSymlinkFailureCode = "TS018E" + SFTPLinkCode = "TS019I" + SFTPLinkFailureCode = "TS019E" + SFTPDisallowedCode = "TS020E" + // SFTPSummaryCode is the SFTP summary code. + SFTPSummaryCode = "TS021I" // SessionCommandCode is a session command code. SessionCommandCode = "T4000I" @@ -671,6 +655,24 @@ const ( // UserTaskDeleteCode is the user task delete event code. UserTaskDeleteCode = "UT003I" + // AutoUpdateConfigCreateCode is the auto update config create event code. + AutoUpdateConfigCreateCode = "AUC001I" + // AutoUpdateConfigUpdateCode is the auto update config update event code. + AutoUpdateConfigUpdateCode = "AUC002I" + // AutoUpdateConfigDeleteCode is the auto update config delete event code. + AutoUpdateConfigDeleteCode = "AUC003I" + + // AutoUpdateVersionCreateCode is the auto update version create event code. + AutoUpdateVersionCreateCode = "AUV001I" + // AutoUpdateVersionUpdateCode is the auto update version update event code. + AutoUpdateVersionUpdateCode = "AUV002I" + // AutoUpdateVersionDeleteCode is the auto update version delete event code. + AutoUpdateVersionDeleteCode = "AUV003I" + // UnknownCode is used when an event of unknown type is encountered. UnknownCode = apievents.UnknownCode ) + +// After defining an event code, make sure to keep +// `web/packages/teleport/src/services/audit/types.ts` in sync and add an +// entry in the `eventsMap` in `lib/events/events_test.go`. diff --git a/lib/events/dynamic.go b/lib/events/dynamic.go index 748806a2a6246..476528255e5ba 100644 --- a/lib/events/dynamic.go +++ b/lib/events/dynamic.go @@ -445,6 +445,23 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) { e = &events.UserTaskUpdate{} case UserTaskDeleteEvent: e = &events.UserTaskDelete{} + + case SFTPSummaryEvent: + e = &events.SFTPSummary{} + + case AutoUpdateConfigCreateEvent: + e = &events.AutoUpdateConfigCreate{} + case AutoUpdateConfigUpdateEvent: + e = &events.AutoUpdateConfigUpdate{} + case AutoUpdateConfigDeleteEvent: + e = &events.AutoUpdateConfigDelete{} + + case AutoUpdateVersionCreateEvent: + e = &events.AutoUpdateVersionCreate{} + case AutoUpdateVersionUpdateEvent: + e = &events.AutoUpdateVersionUpdate{} + case AutoUpdateVersionDeleteEvent: + e = &events.AutoUpdateVersionDelete{} default: slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", eventType) unknown := &events.Unknown{} diff --git a/lib/events/dynamoevents/dynamoevents_test.go b/lib/events/dynamoevents/dynamoevents_test.go index 8a4080c7e44c3..27804a14143a8 100644 --- a/lib/events/dynamoevents/dynamoevents_test.go +++ b/lib/events/dynamoevents/dynamoevents_test.go @@ -315,17 +315,30 @@ func TestEmitAuditEventForLargeEvents(t *testing.T) { assert.Len(t, result, 1) }, 10*time.Second, 500*time.Millisecond) - appReqEvent := &apievents.AppSessionRequest{ - Metadata: apievents.Metadata{ - Time: tt.suite.Clock.Now().UTC(), - Type: events.AppSessionRequestEvent, + appReqEvent := &testAuditEvent{ + AppSessionRequest: apievents.AppSessionRequest{ + Metadata: apievents.Metadata{ + Time: tt.suite.Clock.Now().UTC(), + Type: events.AppSessionRequestEvent, + }, + Path: strings.Repeat("A", maxItemSize), }, - Path: strings.Repeat("A", maxItemSize), } err = tt.suite.Log.EmitAuditEvent(ctx, appReqEvent) require.ErrorContains(t, err, "ValidationException: Item size has exceeded the maximum allowed size") } +// testAuditEvent wraps an existing AuditEvent, but overrides +// the TrimToMaxSize to be a noop so that functionality can +// be tested if an event exceeds the size limits. +type testAuditEvent struct { + apievents.AppSessionRequest +} + +func (t *testAuditEvent) TrimToMaxSize(maxSizeBytes int) apievents.AuditEvent { + return t +} + func TestConfig_SetFromURL(t *testing.T) { useFipsCfg := Config{ UseFIPSEndpoint: types.ClusterAuditConfigSpecV2_FIPS_ENABLED, diff --git a/lib/events/events_test.go b/lib/events/events_test.go index 56e61392820f7..c178aa3272d31 100644 --- a/lib/events/events_test.go +++ b/lib/events/events_test.go @@ -235,6 +235,13 @@ var eventsMap = map[string]apievents.AuditEvent{ UserTaskCreateEvent: &apievents.UserTaskCreate{}, UserTaskUpdateEvent: &apievents.UserTaskUpdate{}, UserTaskDeleteEvent: &apievents.UserTaskDelete{}, + SFTPSummaryEvent: &apievents.SFTPSummary{}, + AutoUpdateConfigCreateEvent: &apievents.AutoUpdateConfigCreate{}, + AutoUpdateConfigUpdateEvent: &apievents.AutoUpdateConfigUpdate{}, + AutoUpdateConfigDeleteEvent: &apievents.AutoUpdateConfigDelete{}, + AutoUpdateVersionCreateEvent: &apievents.AutoUpdateVersionCreate{}, + AutoUpdateVersionUpdateEvent: &apievents.AutoUpdateVersionUpdate{}, + AutoUpdateVersionDeleteEvent: &apievents.AutoUpdateVersionDelete{}, } // TestJSON tests JSON marshal events diff --git a/lib/msgraph/client_test.go b/lib/msgraph/client_test.go index 8df3eb7852d81..8e49692249c0a 100644 --- a/lib/msgraph/client_test.go +++ b/lib/msgraph/client_test.go @@ -412,3 +412,65 @@ func TestRetry(t *testing.T) { require.Error(t, err) }) } + +const listGroupsMembersPayload = `[ + { + "@odata.type": "#microsoft.graph.user", + "id": "9f615773-8219-4a5e-9eb1-8e701324c683", + "mail": "alice@example.com" + }, + { + "@odata.type": "#microsoft.graph.device", + "id": "1566d9a7-c652-44e7-a75e-665b77431435", + "mail": "device@example.com" + }, + { + "@odata.type": "#microsoft.graph.group", + "id": "7db727c5-924a-4f6d-b1f0-d44e6cafa87c", + "displayName": "Test Group 1" + } + ]` + +func TestIterateGroupMembers(t *testing.T) { + t.Parallel() + + var membersJSON []json.RawMessage + require.NoError(t, json.Unmarshal([]byte(listGroupsMembersPayload), &membersJSON)) + mux := http.NewServeMux() + groupID := "fd5be192-6e51-4f54-bbdf-30407435ceb7" + mux.Handle("GET /groups/"+groupID+"/members", paginatedHandler(t, membersJSON)) + + srv := httptest.NewServer(mux) + t.Cleanup(func() { srv.Close() }) + + uri, err := url.Parse(srv.URL) + require.NoError(t, err) + client := &Client{ + httpClient: &http.Client{}, + tokenProvider: &fakeTokenProvider{}, + retryConfig: retryConfig, + baseURL: uri, + pageSize: 2, // smaller page size so we actually fetch multiple pages with our small test payload + } + + var members []GroupMember + err = client.IterateGroupMembers(context.Background(), groupID, func(u GroupMember) bool { + members = append(members, u) + return true + }) + + require.NoError(t, err) + require.Len(t, members, 2) + { + require.IsType(t, &User{}, members[0]) + user := members[0].(*User) + require.Equal(t, "9f615773-8219-4a5e-9eb1-8e701324c683", *user.ID) + require.Equal(t, "alice@example.com", *user.Mail) + } + { + require.IsType(t, &Group{}, members[1]) + group := members[1].(*Group) + require.Equal(t, "7db727c5-924a-4f6d-b1f0-d44e6cafa87c", *group.ID) + require.Equal(t, "Test Group 1", *group.DisplayName) + } +} diff --git a/lib/msgraph/models.go b/lib/msgraph/models.go index 829d55a040464..1150c8943e7d1 100644 --- a/lib/msgraph/models.go +++ b/lib/msgraph/models.go @@ -116,8 +116,14 @@ func decodeGroupMember(msg json.RawMessage) (GroupMember, error) { var u *User err = json.Unmarshal(msg, &u) member = u + case "#microsoft.graph.group": + var g *Group + err = json.Unmarshal(msg, &g) + member = g default: - err = trace.BadParameter("unsupported group member type: %s", temp.Type) + // Return an error if we encounter a type we do not support. + // The caller ignores the error and continues processing the next entry. + err = &unsupportedGroupMember{Type: temp.Type} } return member, trace.Wrap(err) diff --git a/lib/services/watcher.go b/lib/services/watcher.go index 7699f5459b070..d06d97dc7c7c2 100644 --- a/lib/services/watcher.go +++ b/lib/services/watcher.go @@ -839,9 +839,9 @@ func (g *genericCollector[T, R]) processEventsAndUpdateCurrent(ctx context.Conte } key := g.ResourceKey(resource) - current := g.current[key] + current, exists := g.current[key] g.current[key] = resource - updated = g.ResourceDiffer(current, resource) + updated = !exists || g.ResourceDiffer(current, resource) default: g.Logger.WarnContext(ctx, "Skipping unsupported event type", "event_type", event.Type) } diff --git a/lib/services/watcher_test.go b/lib/services/watcher_test.go index 730c7430696a4..52988beae8355 100644 --- a/lib/services/watcher_test.go +++ b/lib/services/watcher_test.go @@ -134,6 +134,9 @@ func TestProxyWatcher(t *testing.T) { }, ProxyGetter: presence, ProxiesC: make(chan []types.Server, 10), + ProxyDiffer: func(old, new types.Server) bool { + return old.GetPeerAddr() != new.GetPeerAddr() + }, }) require.NoError(t, err) t.Cleanup(w.Close) diff --git a/lib/srv/regular/sftp.go b/lib/srv/regular/sftp.go index 5c07a7eab26b6..10ed01d3ea594 100644 --- a/lib/srv/regular/sftp.go +++ b/lib/srv/regular/sftp.go @@ -189,20 +189,35 @@ func (s *sftpSubsys) Start(ctx context.Context, return } - var sftpEvent apievents.SFTP - err = jsonpb.UnmarshalString(eventStr[:len(eventStr)-1], &sftpEvent) + var oneOfEvent apievents.OneOf + err = jsonpb.UnmarshalString(eventStr[:len(eventStr)-1], &oneOfEvent) if err != nil { s.log.WithError(err).Warn("Failed to unmarshal SFTP event.") continue } + event, err := apievents.FromOneOf(oneOfEvent) + if err != nil { + s.log.WithError(err).Warn("Failed to convert SFTP event from OneOf.") + continue + } - sftpEvent.Metadata.ClusterName = serverCtx.ClusterName - sftpEvent.ServerMetadata = serverMeta - sftpEvent.SessionMetadata = sessionMeta - sftpEvent.UserMetadata = userMeta - sftpEvent.ConnectionMetadata = connectionMeta + event.SetClusterName(serverCtx.ClusterName) + switch e := event.(type) { + case *apievents.SFTP: + e.ServerMetadata = serverMeta + e.SessionMetadata = sessionMeta + e.UserMetadata = userMeta + e.ConnectionMetadata = connectionMeta + case *apievents.SFTPSummary: + e.ServerMetadata = serverMeta + e.SessionMetadata = sessionMeta + e.UserMetadata = userMeta + e.ConnectionMetadata = connectionMeta + default: + s.log.WithError(err).Warnf("Unknown event type received from SFTP server process: %q", event.GetType()) + } - if err := serverCtx.GetServer().EmitAuditEvent(ctx, &sftpEvent); err != nil { + if err := serverCtx.GetServer().EmitAuditEvent(ctx, event); err != nil { log.WithError(err).Warn("Failed to emit SFTP event.") } } diff --git a/lib/tlsca/ca.go b/lib/tlsca/ca.go index 19e04dc386d45..ce7d3cad32f0a 100644 --- a/lib/tlsca/ca.go +++ b/lib/tlsca/ca.go @@ -21,6 +21,7 @@ package tlsca import ( "crypto" "crypto/rand" + "crypto/rsa" "crypto/tls" "crypto/x509" "crypto/x509/pkix" @@ -1199,7 +1200,12 @@ func (c *CertificateRequest) CheckAndSetDefaults() error { return trace.BadParameter("missing parameter NotAfter") } if c.KeyUsage == 0 { - c.KeyUsage = x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature + c.KeyUsage = x509.KeyUsageDigitalSignature + if _, isRSA := c.PublicKey.(*rsa.PublicKey); isRSA { + // The KeyEncipherment bit is necessary for RSA key exchanges + // https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3 + c.KeyUsage |= x509.KeyUsageKeyEncipherment + } } c.DNSNames = utils.Deduplicate(c.DNSNames) diff --git a/lib/tlsca/ca_test.go b/lib/tlsca/ca_test.go index 91b4db336e173..d565a9f00d3bc 100644 --- a/lib/tlsca/ca_test.go +++ b/lib/tlsca/ca_test.go @@ -19,7 +19,9 @@ package tlsca import ( + "crypto" "crypto/tls" + "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "testing" @@ -37,6 +39,7 @@ import ( apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib/cryptosuites" + "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/fixtures" ) @@ -471,3 +474,57 @@ func TestIdentity_GetUserMetadata(t *testing.T) { }) } } + +// TestKeyUsage asserts that only certs with RSA subject keys get the +// KeyEncipherment keyUsage extension. +func TestKeyUsage(t *testing.T) { + rsaKey, err := keys.ParsePrivateKey(fixtures.PEMBytes["rsa"]) + require.NoError(t, err) + ecdsaKey, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.ECDSAP256) + require.NoError(t, err) + for _, tc := range []struct { + algo string + key crypto.Signer + expectCAKeyUsage x509.KeyUsage + expectSubjectKeyUsage x509.KeyUsage + }{ + { + algo: "RSA", + key: rsaKey, + expectCAKeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign | x509.KeyUsageKeyEncipherment, + expectSubjectKeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + }, + { + algo: "ECDSA", + key: ecdsaKey, + expectCAKeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + expectSubjectKeyUsage: x509.KeyUsageDigitalSignature, + }, + } { + t.Run(tc.algo, func(t *testing.T) { + caPEM, err := GenerateSelfSignedCAWithSigner(tc.key, pkix.Name{ + CommonName: "teleport.example.com", + Organization: []string{"teleport.example.com"}, + }, nil /*dnsNames*/, defaults.CATTL) + require.NoError(t, err) + + ca, err := FromCertAndSigner(caPEM, tc.key) + require.NoError(t, err) + require.Equal(t, tc.expectCAKeyUsage, ca.Cert.KeyUsage) + + subjectPEM, err := ca.GenerateCertificate(CertificateRequest{ + PublicKey: tc.key.Public(), + Subject: pkix.Name{ + CommonName: "teleport.example.com", + Organization: []string{"teleport.example.com"}, + }, + NotAfter: time.Now().Add(time.Hour), + }) + require.NoError(t, err) + + subject, err := ParseCertificatePEM(subjectPEM) + require.NoError(t, err) + require.Equal(t, tc.expectSubjectKeyUsage, subject.KeyUsage) + }) + } +} diff --git a/lib/tlsca/parsegen.go b/lib/tlsca/parsegen.go index 7d667ebaa19df..055670870466b 100644 --- a/lib/tlsca/parsegen.go +++ b/lib/tlsca/parsegen.go @@ -92,15 +92,22 @@ func GenerateSelfSignedCAWithConfig(config GenerateCAConfig) (certPEM []byte, er // signed by the same private key and having the same subject (happens in tests) config.Entity.SerialNumber = serialNumber.String() + // Note: KeyUsageCRLSign is set only to generate empty CRLs for Desktop + // Access authentication with Windows. + keyUsage := x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign + if _, isRSA := config.Signer.Public().(*rsa.PublicKey); isRSA { + // The KeyEncipherment bit is necessary for RSA key exchanges + // https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3 + keyUsage |= x509.KeyUsageKeyEncipherment + } + template := x509.Certificate{ - SerialNumber: serialNumber, - Issuer: config.Entity, - Subject: config.Entity, - NotBefore: notBefore, - NotAfter: notAfter, - // Note: KeyUsageCRLSign is set only to generate empty CRLs for Desktop - // Access authentication with Windows. - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + SerialNumber: serialNumber, + Issuer: config.Entity, + Subject: config.Entity, + NotBefore: notBefore, + NotAfter: notAfter, + KeyUsage: keyUsage, BasicConstraintsValid: true, IsCA: true, DNSNames: config.DNSNames, diff --git a/lib/utils/cert/selfsigned.go b/lib/utils/cert/selfsigned.go index cde88823f1af0..ea1f4adeda36a 100644 --- a/lib/utils/cert/selfsigned.go +++ b/lib/utils/cert/selfsigned.go @@ -84,7 +84,7 @@ func GenerateSelfSignedCert(hostNames []string, ipAddresses []string, eku ...x50 Subject: entity, NotBefore: notBefore, NotAfter: notAfter, - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: eku, BasicConstraintsValid: true, IsCA: true, diff --git a/lib/utils/packaging/unarchive.go b/lib/utils/packaging/unarchive.go index f1a197e095b1a..6496afbc182c3 100644 --- a/lib/utils/packaging/unarchive.go +++ b/lib/utils/packaging/unarchive.go @@ -38,13 +38,13 @@ const ( ) // RemoveWithSuffix removes all that matches the provided suffix, except for file or directory with `skipName`. -func RemoveWithSuffix(dir, suffix, skipName string) error { +func RemoveWithSuffix(dir, suffix string, skipNames []string) error { var removePaths []string err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return trace.Wrap(err) } - if skipName == info.Name() { + if slices.Contains(skipNames, info.Name()) { return nil } if !strings.HasSuffix(info.Name(), suffix) { @@ -59,12 +59,13 @@ func RemoveWithSuffix(dir, suffix, skipName string) error { if err != nil { return trace.Wrap(err) } + var aggErr []error for _, path := range removePaths { if err := os.RemoveAll(path); err != nil { - return trace.Wrap(err) + aggErr = append(aggErr, err) } } - return nil + return trace.NewAggregate(aggErr...) } // replaceZip un-archives the Teleport package in .zip format, iterates through @@ -118,7 +119,7 @@ func replaceZip(toolsDir string, archivePath string, extractDir string, execName defer file.Close() dest := filepath.Join(extractDir, baseName) - destFile, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) + destFile, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o755) if err != nil { return trace.Wrap(err) } @@ -131,7 +132,10 @@ func replaceZip(toolsDir string, archivePath string, extractDir string, execName if err := os.Remove(appPath); err != nil && !os.IsNotExist(err) { return trace.Wrap(err) } - if err := os.Symlink(dest, appPath); err != nil { + // For the Windows build we have to copy binary to be able + // to do this without administrative access as it required + // for symlinks. + if err := utils.CopyFile(dest, appPath, 0o755); err != nil { return trace.Wrap(err) } return trace.Wrap(destFile.Close()) diff --git a/lib/utils/packaging/unarchive_test.go b/lib/utils/packaging/unarchive_test.go index 30933bbb75927..b124b603b0fd5 100644 --- a/lib/utils/packaging/unarchive_test.go +++ b/lib/utils/packaging/unarchive_test.go @@ -30,7 +30,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/gravitational/teleport/integration/helpers" + "github.com/gravitational/teleport/integration/helpers/archive" ) // TestPackaging verifies un-archiving of all supported teleport package formats. @@ -63,7 +63,7 @@ func TestPackaging(t *testing.T) { t.Run("tar.gz", func(t *testing.T) { archivePath := filepath.Join(toolsDir, "tsh.tar.gz") - err = helpers.CompressDirToTarGzFile(ctx, sourceDir, archivePath) + err = archive.CompressDirToTarGzFile(ctx, sourceDir, archivePath) require.NoError(t, err) require.FileExists(t, archivePath, "archive not created") @@ -85,7 +85,7 @@ func TestPackaging(t *testing.T) { t.Skip("unsupported platform") } archivePath := filepath.Join(toolsDir, "tsh.pkg") - err = helpers.CompressDirToPkgFile(ctx, sourceDir, archivePath, "com.example.pkgtest") + err = archive.CompressDirToPkgFile(ctx, sourceDir, archivePath, "com.example.pkgtest") require.NoError(t, err) require.FileExists(t, archivePath, "archive not created") @@ -101,7 +101,7 @@ func TestPackaging(t *testing.T) { t.Run("zip", func(t *testing.T) { archivePath := filepath.Join(toolsDir, "tsh.zip") - err = helpers.CompressDirToZipFile(ctx, sourceDir, archivePath) + err = archive.CompressDirToZipFile(ctx, sourceDir, archivePath) require.NoError(t, err) require.FileExists(t, archivePath, "archive not created") @@ -132,7 +132,7 @@ func TestRemoveWithSuffix(t *testing.T) { dirInSkipPath := filepath.Join(skipPath, dirForRemove) require.NoError(t, os.MkdirAll(skipPath, 0o755)) - err := RemoveWithSuffix(testDir, dirForRemove, skipName) + err := RemoveWithSuffix(testDir, dirForRemove, []string{skipName}) require.NoError(t, err) _, err = os.Stat(filepath.Join(testDir, dirForRemove)) diff --git a/lib/utils/packaging/unarchive_unix.go b/lib/utils/packaging/unarchive_unix.go index ea51afdbbc7f0..8daf1b3aa5525 100644 --- a/lib/utils/packaging/unarchive_unix.go +++ b/lib/utils/packaging/unarchive_unix.go @@ -186,9 +186,10 @@ func replacePkg(toolsDir string, archivePath string, extractDir string, execName // swap operations. This ensures that the "com.apple.macl" extended // attribute is set and macOS will not send a SIGKILL to the process // if multiple processes are trying to operate on it. - command := exec.Command(path, "version", "--client") + command := exec.Command(path, "version") + command.Env = []string{"TELEPORT_TOOLS_VERSION=off"} if err := command.Run(); err != nil { - return trace.Wrap(err) + return trace.WrapWithMessage(err, "failed to validate binary") } // Due to macOS applications not being a single binary (they are a diff --git a/lib/utils/signal/stack_handler.go b/lib/utils/signal/stack_handler.go new file mode 100644 index 0000000000000..0fcbefb081d11 --- /dev/null +++ b/lib/utils/signal/stack_handler.go @@ -0,0 +1,98 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package signal + +import ( + "container/list" + "context" + "os" + "os/signal" + "sync" + "syscall" +) + +// Handler implements stack for context cancellation. +type Handler struct { + mu sync.Mutex + list *list.List +} + +var handler = &Handler{ + list: list.New(), +} + +// GetSignalHandler returns global singleton instance of signal +func GetSignalHandler() *Handler { + return handler +} + +// NotifyContext creates context which going to be canceled after SIGINT, SIGTERM +// in order of adding them to the stack. When very first context is canceled +// we stop watching the OS signals. +func (s *Handler) NotifyContext(parent context.Context) (context.Context, context.CancelFunc) { + s.mu.Lock() + defer s.mu.Unlock() + + if s.list.Len() == 0 { + s.listenSignals() + } + + ctx, cancel := context.WithCancel(parent) + element := s.list.PushBack(cancel) + + return ctx, func() { + s.mu.Lock() + defer s.mu.Unlock() + + s.list.Remove(element) + cancel() + } +} + +// listenSignals sets up the signal listener for SIGINT, SIGTERM. +func (s *Handler) listenSignals() { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + for { + if sig := <-sigChan; sig == nil { + return + } + if !s.cancelNext() { + signal.Stop(sigChan) + return + } + } + }() +} + +// cancelNext calls the most recent cancel func in the stack. +func (s *Handler) cancelNext() bool { + s.mu.Lock() + defer s.mu.Unlock() + + if s.list.Len() > 0 { + cancel := s.list.Remove(s.list.Back()) + if cancel != nil { + cancel.(context.CancelFunc)() + } + } + + return s.list.Len() != 0 +} diff --git a/lib/utils/signal/stack_handler_test.go b/lib/utils/signal/stack_handler_test.go new file mode 100644 index 0000000000000..b900939b886e8 --- /dev/null +++ b/lib/utils/signal/stack_handler_test.go @@ -0,0 +1,88 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package signal + +import ( + "context" + "os" + "syscall" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestGetSignalHandler verifies the cancellation stack order. +func TestGetSignalHandler(t *testing.T) { + testHandler := GetSignalHandler() + parent := context.Background() + + ctx1, cancel1 := testHandler.NotifyContext(parent) + ctx2, cancel2 := testHandler.NotifyContext(parent) + ctx3, cancel3 := testHandler.NotifyContext(parent) + ctx4, cancel4 := testHandler.NotifyContext(parent) + t.Cleanup(func() { + cancel4() + cancel2() + cancel1() + }) + + // Verify that all context not canceled. + require.NoError(t, ctx4.Err()) + require.NoError(t, ctx3.Err()) + require.NoError(t, ctx2.Err()) + require.NoError(t, ctx1.Err()) + + // Cancel context manually to ensure it was removed from stack in right order. + cancel3() + + // Check that last added context is canceled. + require.NoError(t, syscall.Kill(os.Getpid(), syscall.SIGINT)) + select { + case <-ctx4.Done(): + assert.ErrorIs(t, ctx3.Err(), context.Canceled) + assert.NoError(t, ctx2.Err()) + assert.NoError(t, ctx1.Err()) + case <-time.After(time.Second): + assert.Fail(t, "context 3 must be canceled") + } + + // Send interrupt signal to cancel next context in the stack. + require.NoError(t, syscall.Kill(os.Getpid(), syscall.SIGINT)) + select { + case <-ctx2.Done(): + assert.ErrorIs(t, ctx4.Err(), context.Canceled) + assert.ErrorIs(t, ctx3.Err(), context.Canceled) + assert.NoError(t, ctx1.Err()) + case <-time.After(time.Second): + assert.Fail(t, "context 2 must be canceled") + } + + // All context must be canceled. + require.NoError(t, syscall.Kill(os.Getpid(), syscall.SIGINT)) + select { + case <-ctx1.Done(): + assert.ErrorIs(t, ctx4.Err(), context.Canceled) + assert.ErrorIs(t, ctx3.Err(), context.Canceled) + assert.ErrorIs(t, ctx2.Err(), context.Canceled) + case <-time.After(time.Second): + assert.Fail(t, "context 1 must be canceled") + } +} diff --git a/lib/utils/tls.go b/lib/utils/tls.go index 8f619b63faf80..ca096a523b0a0 100644 --- a/lib/utils/tls.go +++ b/lib/utils/tls.go @@ -43,6 +43,11 @@ func SetupTLSConfig(config *tls.Config, cipherSuites []uint16) { config.CipherSuites = cipherSuites } + // pre-v17 Teleport uses a client ticket cache, which doesn't play well with + // verification (both client- and server-side) when using dynamic + // credentials and CAs (in v17+ Teleport) + config.SessionTicketsDisabled = true + config.MinVersion = tls.VersionTLS12 } diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index 2bbb2bcbdd561..cc309efe1043f 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -1593,7 +1593,7 @@ func (h *Handler) automaticUpdateSettings(ctx context.Context) webclient.AutoUpd } return webclient.AutoUpdateSettings{ - ToolsMode: getToolsMode(autoUpdateConfig), + ToolsAutoUpdate: getToolsAutoUpdate(autoUpdateConfig), ToolsVersion: getToolsVersion(autoUpdateVersion), AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentVersion: getAgentVersion(autoUpdateVersion), @@ -5154,15 +5154,15 @@ func readEtagFromAppHash(fs http.FileSystem) (string, error) { return etag, nil } -func getToolsMode(config *autoupdatepb.AutoUpdateConfig) string { +func getToolsAutoUpdate(config *autoupdatepb.AutoUpdateConfig) bool { // If we can't get the AU config or if AUs are not configured, we default to "disabled". // This ensures we fail open and don't accidentally update agents if something is going wrong. // If we want to enable AUs by default, it would be better to create a default "autoupdate_config" resource // than changing this logic. - if config.GetSpec().GetTools() == nil { - return autoupdate.ToolsUpdateModeDisabled + if config.GetSpec().GetTools() != nil { + return config.GetSpec().GetTools().GetMode() == autoupdate.ToolsUpdateModeEnabled } - return config.GetSpec().GetTools().GetMode() + return false } func getToolsVersion(version *autoupdatepb.AutoUpdateVersion) string { diff --git a/lib/web/apiserver_ping_test.go b/lib/web/apiserver_ping_test.go index 5ce3720375c46..2bf325d4f7902 100644 --- a/lib/web/apiserver_ping_test.go +++ b/lib/web/apiserver_ping_test.go @@ -306,7 +306,7 @@ func TestPing_autoUpdateResources(t *testing.T) { name: "resources not defined", expected: webclient.AutoUpdateSettings{ ToolsVersion: api.Version, - ToolsMode: autoupdate.ToolsUpdateModeDisabled, + ToolsAutoUpdate: false, AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, AgentVersion: api.Version, @@ -320,7 +320,7 @@ func TestPing_autoUpdateResources(t *testing.T) { }, }, expected: webclient.AutoUpdateSettings{ - ToolsMode: autoupdate.ToolsUpdateModeEnabled, + ToolsAutoUpdate: true, ToolsVersion: api.Version, AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, @@ -346,7 +346,7 @@ func TestPing_autoUpdateResources(t *testing.T) { }, expected: webclient.AutoUpdateSettings{ ToolsVersion: api.Version, - ToolsMode: autoupdate.ToolsUpdateModeDisabled, + ToolsAutoUpdate: false, AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: true, AgentVersion: "1.2.4", @@ -371,7 +371,7 @@ func TestPing_autoUpdateResources(t *testing.T) { }, expected: webclient.AutoUpdateSettings{ ToolsVersion: api.Version, - ToolsMode: autoupdate.ToolsUpdateModeDisabled, + ToolsAutoUpdate: false, AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, AgentVersion: "1.2.4", @@ -384,7 +384,7 @@ func TestPing_autoUpdateResources(t *testing.T) { version: &autoupdatev1pb.AutoUpdateVersionSpec{}, expected: webclient.AutoUpdateSettings{ ToolsVersion: api.Version, - ToolsMode: autoupdate.ToolsUpdateModeDisabled, + ToolsAutoUpdate: false, AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, AgentVersion: api.Version, @@ -400,7 +400,7 @@ func TestPing_autoUpdateResources(t *testing.T) { }, expected: webclient.AutoUpdateSettings{ ToolsVersion: "1.2.3", - ToolsMode: autoupdate.ToolsUpdateModeDisabled, + ToolsAutoUpdate: false, AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, AgentVersion: api.Version, @@ -420,7 +420,7 @@ func TestPing_autoUpdateResources(t *testing.T) { }, }, expected: webclient.AutoUpdateSettings{ - ToolsMode: autoupdate.ToolsUpdateModeEnabled, + ToolsAutoUpdate: true, ToolsVersion: "1.2.3", AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, @@ -440,7 +440,7 @@ func TestPing_autoUpdateResources(t *testing.T) { }, }, expected: webclient.AutoUpdateSettings{ - ToolsMode: autoupdate.ToolsUpdateModeDisabled, + ToolsAutoUpdate: false, ToolsVersion: "3.2.1", AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, AgentAutoUpdate: false, diff --git a/package.json b/package.json index dce649b86d057..e9a63311eedaf 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,11 @@ "nop": "exit 0" }, "private": true, + "pnpm": { + "overrides": { + "@bundled-es-modules/cookie>cookie": "0.7.1" + } + }, "devDependencies": { "@gravitational/build": "workspace:*", "@storybook/addon-toolbars": "^8.3.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a022806a05253..17bbecbf716fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@bundled-es-modules/cookie>cookie': 0.7.1 + pnpmfileChecksum: w7xzadmfdycxsdgkkk3qgpkydu importers: @@ -3402,12 +3405,8 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} core-js-compat@3.38.1: @@ -4117,8 +4116,8 @@ packages: exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} - express@4.21.0: - resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==} + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} engines: {node: '>= 0.10.0'} extract-zip@2.0.1: @@ -5604,8 +5603,8 @@ packages: path-to-regexp@0.1.10: resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} - path-to-regexp@1.8.0: - resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} @@ -7821,7 +7820,7 @@ snapshots: '@bundled-es-modules/cookie@2.0.0': dependencies: - cookie: 0.5.0 + cookie: 0.7.1 '@bundled-es-modules/statuses@1.0.1': dependencies: @@ -8998,7 +8997,7 @@ snapshots: '@types/find-cache-dir': 3.2.1 browser-assert: 1.2.1 es-module-lexer: 1.5.4 - express: 4.21.0 + express: 4.21.1 find-cache-dir: 3.3.2 fs-extra: 11.2.0 magic-string: 0.30.11 @@ -9027,7 +9026,7 @@ snapshots: browser-assert: 1.2.1 esbuild: 0.23.1 esbuild-register: 3.6.0(esbuild@0.23.1) - express: 4.21.0 + express: 4.21.1 jsdoc-type-pratt-parser: 4.1.0 process: 0.11.10 recast: 0.23.9 @@ -10536,9 +10535,7 @@ snapshots: cookie-signature@1.0.6: {} - cookie@0.5.0: {} - - cookie@0.6.0: {} + cookie@0.7.1: {} core-js-compat@3.38.1: dependencies: @@ -11433,14 +11430,14 @@ snapshots: exponential-backoff@3.1.1: {} - express@4.21.0: + express@4.21.1: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 body-parser: 1.20.3 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.6.0 + cookie: 0.7.1 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 @@ -13351,7 +13348,7 @@ snapshots: path-to-regexp@0.1.10: {} - path-to-regexp@1.8.0: + path-to-regexp@1.9.0: dependencies: isarray: 0.0.1 @@ -13601,7 +13598,7 @@ snapshots: history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 - path-to-regexp: 1.8.0 + path-to-regexp: 1.9.0 prop-types: 15.8.1 react: 18.3.1 react-is: 16.13.1 diff --git a/rfd/0170-nested-accesslists.md b/rfd/0170-nested-accesslists.md index 4f12228093992..f4b8ed35ffc30 100644 --- a/rfd/0170-nested-accesslists.md +++ b/rfd/0170-nested-accesslists.md @@ -10,15 +10,15 @@ state: in development # What This RFD proposes adding support for including owners and -members in access lists from other access lists +members in Access Lists from other Access Lists # Why -This allows a hierarchical access list structure for organizations -which is supported by access list implementations being integrated -with, for example Azure Entra supports including groups in other -groups which we want to be able to mimic the structure of in Teleport -access lists. +This allows a hierarchical Access List structure for organizations +which is supported by Access List implementations being integrated +with. For example, Azure Entra supports including groups in other +groups, which we want to be able to mimic the structure of in Teleport +Access Lists. Users in an access list hierarchy will inherit the granted roles and traits for members and owners from access lists referencing the lists @@ -26,86 +26,125 @@ they're in. # Implementation -New fields will be introduced into the access_list type: +The `AccessListMember` type will be modified to include a new field: -```yaml -kind: access_list -metadata: - name: e69aa529-2a7f-4de2-87be-97fd94309a9f -spec: - grants: - roles: - - access - - auditor - traits: {} - dynamic_members: - - access_list_members: - # A user becomes an access list member if its a member of the access list - - ea4cbbc7-bee1-49b3-bf78-734b4b27ea38 - dynamic_owners: - access_list_owners: - # A user becomes an access list owner if its a member of the access list - - 3e9df1e7-0b8a-4984-b2e8-5bc0d7b356a9 - title: access-list-a -version: v1 +```go +type AccessListMemberSpec struct { + // ... + + // MembershipKind describes the kind of membership, + // either "MEMBERSHIP_KIND_USER" or "MEMBERSHIP_KIND_LIST". + MembershipKind string `json:"membership_kind" yaml:"membership_kind"` +} +``` + +As well as `accesslist.Owner`: + +```go +type Owner struct { + // ... + + // MembershipKind describes the kind of ownership, + // either "MEMBERSHIP_KIND_USER" or "MEMBERSHIP_KIND_LIST". + MembershipKind string `json:"membership_kind" yaml:"membership_kind"` +} ``` -These fields will contain a list of other access lists that will be -included in the access list. +These fields will be used to indicate whether the member/owner refers to +a Teleport user or an Access List. + +Two fields will be added to the `AccessList.Status` struct as well: -Access lists included in `dynamic_members.access_list_members` and -`dynamic_members.access_list_owners` will take the membership only -from the list of members in the included access list. +```go +type Status struct { + // ... + OwnerOf []string `json:"owner_of" yaml:"owner_of"` + MemberOf []string `json:"member_of" yaml:"member_of"` +} +``` + +These fields will be used to store the names (UUIDs) of Access Lists which +the current Access List is an explicit member or owner of, respectively. # Implementation considerations -## Cycles within lists +## Limitations -The implementation will not support cycles within the hierarchy as -this would introduce confusing options for configuration. Teleport -will return an error if a cycle are introduced. It will also only look -10 layers deep before exiting a lookup to avoid overly complex -hierarchies. +### Cycles -Errors over cycles in the hierarchy will be detected and returned at -access list insertion/update time. +The implementation will not support cycles within the hierarchy, as +this would introduce confusing options for configuration. Teleport +will return an error if self-referential membership or ownership is +detected while modifying an Access List's members or owners. ### Nesting depth -Access list hierarchies will only recurse up to 10 layers deep -initially. +The implementation will not support a hierarchy that is +more than 10 levels deep. An error will be returned if a hierarchy +exceeds this depth while modifying an Access List's members or owners. +This may be configured to a higher value in the future. -## Access list reviews +Errors relating to cycles and depth will also be detected and returned +at Access List insertion time. -Access list periodic reviews will include in the member review page, -the list of nested access lists and an indicator to suggest that its -an access list not an individual member, but not the full list of -users. +## Access List reviews -## Impact on access requests +In the member review page for an Access List review, the list of members +will include both explicit members and nested Access Lists. An indicator +will be included to show that the member is an Access List, not an +individual user. -Access request suggested reviewers will include members included in -the `dynamic_access_lists.access_list_owners` field. +## Impact on Access Requests -The suggested lists field will remain operating as it presently does, +Access Requests' suggested reviewers will include users with inherited +ownership from nested Access Lists. + +The Suggested Lists field will remain operating as it presently does, only showing the list that actually grants the resource. -## Membership and Ownership requires +## Membership and Ownership -A user in a nested access list will only become a member/owner if the -user passes the respective membership/ownership requirements +### Inheritance -## Other considerations +Membership will be inherited when a user is a member in an Access List that +is a member of another Access List. + +Ownership will be inherited when a user is a member in an Access List that +is an owner of another Access List. + +These rules are recursive - if an Access List is a member of an +Access List that is a member of another Access List, the user will +inherit membership in all three Access Lists (or, ownership, if the +first Access List in the chain is added as an owner). -Access lists will need to be allowed to have empty grants so access -lists can represent only users and permissions can be assigned purely -through membership in other lists. +### Requirements -# Examples +Membership and ownership requirements will be checked at each level of the +hierarchy. If a user does not meet the requirements at a given level, +they will not inherit membership or ownership from that level or any +levels "above" it in the hierarchy. +## Grant inheritance -User Alice is in the below access list which does not include any -other access lists +When calculating a user's login state, the tree of Access Lists will +be traversed, granting roles and traits from each Access List in the +hierarchy that the user has either explicit or inherited membership or +ownership in. + +Explicit owners will not inherit roles or traits from any nested +Access Lists they own. They will only be granted roles and traits from +the Access List(s) they are explicit owners of. + +## Other considerations + +Access lists will need to be allowed to have empty grants so Access +Lists can represent only users, and permissions can be assigned purely +through inclusion in other Access Lists. + +# Example + +- User Alice is a member in `acl-a`, which does not include any other +Access Lists as members: ```yaml kind: access_list @@ -116,12 +155,12 @@ spec: roles: - some-role traits: {} - title: access-list-a version: v1 ``` -- `acl-c` includes members in `acl-a`, grants them `manager` -- `acl-b` includes members in `acl-c`, and grants them `auditor` and `reviewer` + +- `acl-c` includes members of `acl-a`, and grants them `manager` +- `acl-b` includes members of `acl-c`, and grants them `auditor` and `reviewer` ```yaml kind: access_list @@ -133,9 +172,9 @@ spec: - auditor - reviewer traits: {} - # list of references to other access lists, for users to include in this access list - dynamic_members: - access_list_members: "acl-c" + # In actuality, members are not stored directly on the Access List resource, this is just for brevity + members: + - acl-c title: access-list-a version: v1 --- @@ -147,24 +186,23 @@ spec: roles: - manager traits: {} - # list of references to other access lists, for users to include in this access list - dynamic_members: - access_list_members: "acl-a" + members: + - acl-a title: access-list-a version: v1 ``` -When calculating a users access roles, the tree of access lists will -be traversed and so upon login, user Alice will have been granted +When calculating a user's access roles, the tree of Access Lists will +be traversed, and so, upon login, user Alice will be granted: - `some-role` from `acl-a` -- `manager` from `acl-c` as it includes members of `acl-a` -- `auditor` and `reviewer` from `acl-b` as it includes members of - `acl-c`, who also include members of `acl-a` +- `manager` from `acl-c`, as it includes members from `acl-a` +- `auditor` and `reviewer` from `acl-b`, as it includes members from + `acl-c`, which in turn includes members from `acl-a` # Future considerations -Further development of membership reviews should be considered to +- Further development of membership reviews should be considered to expand reviews to include members of nested lists and to include -information in the UI that nested may need to be separately reviewed +information in the UI that nested lists may need to be separately reviewed. diff --git a/tool/tctl/common/tctl.go b/tool/tctl/common/tctl.go index 4a85be6e934b0..51ff5f8687f75 100644 --- a/tool/tctl/common/tctl.go +++ b/tool/tctl/common/tctl.go @@ -44,6 +44,7 @@ import ( "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/state" "github.com/gravitational/teleport/lib/auth/storage" + "github.com/gravitational/teleport/lib/autoupdate/tools" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/client/identityfile" libmfa "github.com/gravitational/teleport/lib/client/mfa" @@ -54,6 +55,7 @@ import ( "github.com/gravitational/teleport/lib/reversetunnelclient" "github.com/gravitational/teleport/lib/service/servicecfg" "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/lib/utils/signal" "github.com/gravitational/teleport/tool/common" ) @@ -104,8 +106,43 @@ type CLICommand interface { // "distributions" like OSS or Enterprise // // distribution: name of the Teleport distribution -func Run(commands []CLICommand) { - err := TryRun(commands, os.Args[1:]) +func Run(ctx context.Context, commands []CLICommand) { + // The user has typed a command like `tsh ssh ...` without being logged in, + // if the running binary needs to be updated, update and re-exec. + // + // If needed, download the new version of {tsh, tctl} and re-exec. Make + // sure to exit this process with the same exit code as the child process. + // + toolsDir, err := tools.Dir() + if err != nil { + utils.FatalError(err) + } + updater := tools.NewUpdater(tools.DefaultClientTools(), toolsDir, teleport.Version) + toolsVersion, reExec, err := updater.CheckLocal() + if err != nil { + utils.FatalError(err) + } + if reExec { + ctxUpdate, cancel := signal.GetSignalHandler().NotifyContext(ctx) + defer cancel() + // Download the version of client tools required by the cluster. This + // is required if the user passed in the TELEPORT_TOOLS_VERSION + // explicitly. + err := updater.UpdateWithLock(ctxUpdate, toolsVersion) + if err != nil && !errors.Is(err, context.Canceled) { + utils.FatalError(err) + } + // Re-execute client tools with the correct version of client tools. + code, err := updater.Exec() + if err != nil && !errors.Is(err, os.ErrNotExist) { + log.Debugf("Failed to re-exec client tool: %v.", err) + os.Exit(code) + } else if err == nil { + os.Exit(code) + } + } + + err = TryRun(commands, os.Args[1:]) if err != nil { var exitError *common.ExitCodeError if errors.As(err, &exitError) { diff --git a/tool/tctl/main.go b/tool/tctl/main.go index f363e347f25c9..6dfae87ffdef2 100644 --- a/tool/tctl/main.go +++ b/tool/tctl/main.go @@ -19,9 +19,15 @@ package main import ( + "context" + + "github.com/gravitational/teleport/lib/utils/signal" "github.com/gravitational/teleport/tool/tctl/common" ) func main() { - common.Run(common.Commands()) + ctx, cancel := signal.GetSignalHandler().NotifyContext(context.Background()) + defer cancel() + + common.Run(ctx, common.Commands()) } diff --git a/tool/teleport/common/sftp.go b/tool/teleport/common/sftp.go index 4710b0d050915..4d3e46f4decf7 100644 --- a/tool/teleport/common/sftp.go +++ b/tool/teleport/common/sftp.go @@ -30,6 +30,8 @@ import ( "os/user" "path" "strings" + "sync" + "sync/atomic" "time" "github.com/gogo/protobuf/jsonpb" @@ -89,10 +91,37 @@ type allowedOps struct { type sftpHandler struct { logger *log.Entry allowed *allowedOps - events chan<- *apievents.SFTP + + // mtx protects files + mtx sync.Mutex + files []*trackedFile + + events chan<- apievents.AuditEvent +} + +type trackedFile struct { + file *os.File + bytesRead atomic.Uint64 + bytesWritten atomic.Uint64 +} + +func (t *trackedFile) ReadAt(b []byte, off int64) (int, error) { + n, err := t.file.ReadAt(b, off) + t.bytesRead.Add(uint64(n)) + return n, err } -func newSFTPHandler(logger *log.Entry, req *srv.FileTransferRequest, events chan<- *apievents.SFTP) (*sftpHandler, error) { +func (t *trackedFile) WriteAt(b []byte, off int64) (int, error) { + n, err := t.file.WriteAt(b, off) + t.bytesWritten.Add(uint64(n)) + return n, err +} + +func (t *trackedFile) Close() error { + return t.file.Close() +} + +func newSFTPHandler(logger *log.Entry, req *srv.FileTransferRequest, events chan<- apievents.AuditEvent) (*sftpHandler, error) { var allowed *allowedOps if req != nil { allowed = &allowedOps{ @@ -188,7 +217,7 @@ func (s *sftpHandler) Filewrite(req *sftp.Request) (_ io.WriterAt, retErr error) return s.openFile(req) } -func (s *sftpHandler) openFile(req *sftp.Request) (*os.File, error) { +func (s *sftpHandler) openFile(req *sftp.Request) (sftp.WriterAtReaderAt, error) { if err := s.ensureReqIsAllowed(req); err != nil { return nil, err } @@ -220,8 +249,12 @@ func (s *sftpHandler) openFile(req *sftp.Request) (*os.File, error) { if err != nil { return nil, err } + trackFile := &trackedFile{file: f} + s.mtx.Lock() + s.files = append(s.files, trackFile) + s.mtx.Unlock() - return f, nil + return trackFile, nil } // Filecmd handles file modification requests. @@ -607,7 +640,7 @@ func onSFTP() error { } ch := compositeCh{io.NopCloser(bufferedReader), chw} - sftpEvents := make(chan *apievents.SFTP, 1) + sftpEvents := make(chan apievents.AuditEvent, 1) h, err := newSFTPHandler(logger, fileTransferReq, sftpEvents) if err != nil { return trace.Wrap(err) @@ -627,17 +660,24 @@ func onSFTP() error { var m jsonpb.Marshaler var buf bytes.Buffer for event := range sftpEvents { + oneOfEvent, err := apievents.ToOneOf(event) + if err != nil { + logger.WithError(err).Warn("Failed to convert SFTP event to OneOf.") + continue + } + buf.Reset() - if err := m.Marshal(&buf, event); err != nil { + if err := m.Marshal(&buf, oneOfEvent); err != nil { logger.WithError(err).Warn("Failed to marshal SFTP event.") - } else { - // Append a NULL byte so the parent process will know where - // this event ends - buf.WriteByte(0x0) - _, err = io.Copy(auditFile, &buf) - if err != nil { - logger.WithError(err).Warn("Failed to send SFTP event to parent.") - } + continue + } + + // Append a NULL byte so the parent process will know where + // this event ends + buf.WriteByte(0x0) + _, err = io.Copy(auditFile, &buf) + if err != nil { + logger.WithError(err).Warn("Failed to send SFTP event to parent.") } } @@ -651,6 +691,25 @@ func onSFTP() error { serveErr = trace.Wrap(serveErr) } + // Send a summary event last + summaryEvent := &apievents.SFTPSummary{ + Metadata: apievents.Metadata{ + Type: events.SFTPSummaryEvent, + Code: events.SFTPSummaryCode, + Time: time.Now(), + }, + } + // We don't need to worry about closing these files, handler will + // take care of that for us + for _, f := range h.files { + summaryEvent.FileTransferStats = append(summaryEvent.FileTransferStats, &apievents.FileTransferStat{ + Path: f.file.Name(), + BytesRead: f.bytesRead.Load(), + BytesWritten: f.bytesWritten.Load(), + }) + } + sftpEvents <- summaryEvent + // Wait until event marshaling goroutine is finished close(sftpEvents) <-done diff --git a/tool/tsh/common/tsh.go b/tool/tsh/common/tsh.go index 1adabe7b337c1..a1b0edc1d15c3 100644 --- a/tool/tsh/common/tsh.go +++ b/tool/tsh/common/tsh.go @@ -41,7 +41,6 @@ import ( "strconv" "strings" "sync" - "syscall" "time" "github.com/alecthomas/kingpin/v2" @@ -74,6 +73,7 @@ import ( "github.com/gravitational/teleport/lib/asciitable" "github.com/gravitational/teleport/lib/auth/authclient" wancli "github.com/gravitational/teleport/lib/auth/webauthncli" + "github.com/gravitational/teleport/lib/autoupdate/tools" "github.com/gravitational/teleport/lib/benchmark" benchmarkdb "github.com/gravitational/teleport/lib/benchmark/db" "github.com/gravitational/teleport/lib/client" @@ -94,6 +94,7 @@ import ( "github.com/gravitational/teleport/lib/utils" "github.com/gravitational/teleport/lib/utils/diagnostics/latency" "github.com/gravitational/teleport/lib/utils/mlock" + stacksignal "github.com/gravitational/teleport/lib/utils/signal" "github.com/gravitational/teleport/tool/common" "github.com/gravitational/teleport/tool/common/fido2" "github.com/gravitational/teleport/tool/common/touchid" @@ -609,7 +610,7 @@ func Main() { cmdLineOrig := os.Args[1:] var cmdLine []string - ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT) + ctx, cancel := stacksignal.GetSignalHandler().NotifyContext(context.Background()) defer cancel() // lets see: if the executable name is 'ssh' or 'scp' we convert @@ -707,6 +708,38 @@ func initLogger(cf *CLIConf) { // // DO NOT RUN TESTS that call Run() in parallel (unless you taken precautions). func Run(ctx context.Context, args []string, opts ...CliOption) error { + // At process startup, check if a version has already been downloaded to + // $TELEPORT_HOME/bin or if the user has set the TELEPORT_TOOLS_VERSION + // environment variable. If so, re-exec that version of {tsh, tctl}. + toolsDir, err := tools.Dir() + if err != nil { + return trace.Wrap(err) + } + updater := tools.NewUpdater(tools.DefaultClientTools(), toolsDir, teleport.Version) + toolsVersion, reExec, err := updater.CheckLocal() + if err != nil { + return trace.Wrap(err) + } + if reExec { + ctxUpdate, cancel := stacksignal.GetSignalHandler().NotifyContext(ctx) + defer cancel() + // Download the version of client tools required by the cluster. This + // is required if the user passed in the TELEPORT_TOOLS_VERSION + // explicitly. + err := updater.UpdateWithLock(ctxUpdate, toolsVersion) + if err != nil && !errors.Is(err, context.Canceled) { + return trace.Wrap(err) + } + // Re-execute client tools with the correct version of client tools. + code, err := updater.Exec() + if err != nil && !errors.Is(err, os.ErrNotExist) { + log.Debugf("Failed to re-exec client tool: %v.", err) + os.Exit(code) + } else if err == nil { + os.Exit(code) + } + } + cf := CLIConf{ Context: ctx, TracingProvider: tracing.NoopProvider(), @@ -1239,8 +1272,6 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { bench.Hidden() } - var err error - cf.executablePath, err = os.Executable() if err != nil { return trace.Wrap(err) @@ -1866,6 +1897,14 @@ func onLogin(cf *CLIConf) error { } tc.HomePath = cf.HomePath + // The user is not logged in and has typed in `tsh --proxy=... login`, if + // the running binary needs to be updated, update and re-exec. + if profile == nil { + if err := updateAndRun(cf.Context, tc.WebProxyAddr, tc.InsecureSkipVerify); err != nil { + return trace.Wrap(err) + } + } + // client is already logged in and profile is not expired if profile != nil && !profile.IsExpired(time.Now()) { switch { @@ -1876,6 +1915,13 @@ func onLogin(cf *CLIConf) error { // current status case cf.Proxy == "" && cf.SiteName == "" && cf.DesiredRoles == "" && cf.RequestID == "" && cf.IdentityFileOut == "" || host(cf.Proxy) == host(profile.ProxyURL.Host) && cf.SiteName == profile.Cluster && cf.DesiredRoles == "" && cf.RequestID == "": + + // The user has typed `tsh login`, if the running binary needs to + // be updated, update and re-exec. + if err := updateAndRun(cf.Context, tc.WebProxyAddr, tc.InsecureSkipVerify); err != nil { + return trace.Wrap(err) + } + _, err := tc.PingAndShowMOTD(cf.Context) if err != nil { return trace.Wrap(err) @@ -1889,6 +1935,13 @@ func onLogin(cf *CLIConf) error { // if the proxy names match but nothing else is specified; show motd and update active profile and kube configs case host(cf.Proxy) == host(profile.ProxyURL.Host) && cf.SiteName == "" && cf.DesiredRoles == "" && cf.RequestID == "" && cf.IdentityFileOut == "": + + // The user has typed `tsh login`, if the running binary needs to + // be updated, update and re-exec. + if err := updateAndRun(cf.Context, tc.WebProxyAddr, tc.InsecureSkipVerify); err != nil { + return trace.Wrap(err) + } + _, err := tc.PingAndShowMOTD(cf.Context) if err != nil { return trace.Wrap(err) @@ -1959,7 +2012,11 @@ func onLogin(cf *CLIConf) error { // otherwise just pass through to standard login default: - + // The user is logged in and has typed in `tsh --proxy=... login`, if + // the running binary needs to be updated, update and re-exec. + if err := updateAndRun(cf.Context, tc.WebProxyAddr, tc.InsecureSkipVerify); err != nil { + return trace.Wrap(err) + } } } @@ -5552,6 +5609,43 @@ const ( "https://goteleport.com/docs/access-controls/guides/headless/#troubleshooting" ) +func updateAndRun(ctx context.Context, proxy string, insecure bool) error { + // The user has typed a command like `tsh ssh ...` without being logged in, + // if the running binary needs to be updated, update and re-exec. + // + // If needed, download the new version of {tsh, tctl} and re-exec. Make + // sure to exit this process with the same exit code as the child process. + // + toolsDir, err := tools.Dir() + if err != nil { + return trace.Wrap(err) + } + updater := tools.NewUpdater(tools.DefaultClientTools(), toolsDir, teleport.Version) + toolsVersion, reExec, err := updater.CheckRemote(ctx, proxy, insecure) + if err != nil { + return trace.Wrap(err) + } + if reExec { + ctxUpdate, cancel := stacksignal.GetSignalHandler().NotifyContext(context.Background()) + defer cancel() + // Download the version of client tools required by the cluster. + err := updater.UpdateWithLock(ctxUpdate, toolsVersion) + if err != nil && !errors.Is(err, context.Canceled) { + return trace.Wrap(err) + } + // Re-execute client tools with the correct version of client tools. + code, err := updater.Exec() + if err != nil && !errors.Is(err, os.ErrNotExist) { + log.Debugf("Failed to re-exec client tool: %v.", err) + os.Exit(code) + } else if err == nil { + os.Exit(code) + } + } + + return nil +} + // Lock the process memory to prevent rsa keys and certificates in memory from being exposed in a swap. func tryLockMemory(cf *CLIConf) error { if cf.MlockMode == mlockModeAuto { diff --git a/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx b/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx index 704de4b00e33e..cb5c377d3f6d9 100644 --- a/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx +++ b/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx @@ -50,20 +50,8 @@ const EventIconMap: Record = { [eventCodes.SCP_DISALLOWED]: Icons.FolderPlus, [eventCodes.SFTP_OPEN_FAILURE]: Icons.FolderPlus, [eventCodes.SFTP_OPEN]: Icons.FolderPlus, - [eventCodes.SFTP_CLOSE_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_CLOSE]: Icons.FolderPlus, - [eventCodes.SFTP_READ_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_READ]: Icons.FolderPlus, - [eventCodes.SFTP_WRITE_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_WRITE]: Icons.FolderPlus, - [eventCodes.SFTP_LSTAT_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_LSTAT]: Icons.FolderPlus, - [eventCodes.SFTP_FSTAT_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_FSTAT]: Icons.FolderPlus, [eventCodes.SFTP_SETSTAT_FAILURE]: Icons.FolderPlus, [eventCodes.SFTP_SETSTAT]: Icons.FolderPlus, - [eventCodes.SFTP_FSETSTAT_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_FSETSTAT]: Icons.FolderPlus, [eventCodes.SFTP_OPENDIR_FAILURE]: Icons.FolderPlus, [eventCodes.SFTP_OPENDIR]: Icons.FolderPlus, [eventCodes.SFTP_READDIR_FAILURE]: Icons.FolderPlus, @@ -74,14 +62,8 @@ const EventIconMap: Record = { [eventCodes.SFTP_MKDIR]: Icons.FolderPlus, [eventCodes.SFTP_RMDIR_FAILURE]: Icons.FolderPlus, [eventCodes.SFTP_RMDIR]: Icons.FolderPlus, - [eventCodes.SFTP_REALPATH_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_REALPATH]: Icons.FolderPlus, - [eventCodes.SFTP_STAT_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_STAT]: Icons.FolderPlus, [eventCodes.SFTP_RENAME_FAILURE]: Icons.FolderPlus, [eventCodes.SFTP_RENAME]: Icons.FolderPlus, - [eventCodes.SFTP_READLINK_FAILURE]: Icons.FolderPlus, - [eventCodes.SFTP_READLINK]: Icons.FolderPlus, [eventCodes.SFTP_SYMLINK_FAILURE]: Icons.FolderPlus, [eventCodes.SFTP_SYMLINK]: Icons.FolderPlus, [eventCodes.SFTP_LINK]: Icons.FolderPlus, @@ -297,6 +279,7 @@ const EventIconMap: Record = { [eventCodes.USER_TASK_CREATE]: Icons.Info, [eventCodes.USER_TASK_UPDATE]: Icons.Info, [eventCodes.USER_TASK_DELETE]: Icons.Info, + [eventCodes.SFTP_SUMMARY]: Icons.FolderPlus, [eventCodes.UNKNOWN]: Icons.Question, }; diff --git a/web/packages/teleport/src/Navigation/RecentHistory.tsx b/web/packages/teleport/src/Navigation/RecentHistory.tsx new file mode 100644 index 0000000000000..38ae478bd6b2a --- /dev/null +++ b/web/packages/teleport/src/Navigation/RecentHistory.tsx @@ -0,0 +1,300 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React, { useState, useEffect, useRef } from 'react'; +import styled from 'styled-components'; +import { matchPath } from 'react-router'; +import { NavLink } from 'react-router-dom'; +import { Flex, Text, H4, P3, ButtonIcon } from 'design'; +import { Cross } from 'design/Icon'; + +import { TeleportFeature } from 'teleport/types'; +import { useFeatures } from 'teleport/FeaturesContext'; + +import { getSubsectionStyles } from './SideNavigation/Section'; +import { SidenavCategory } from './SideNavigation/categories'; + +export type RecentHistoryItem = { + category?: SidenavCategory; + title: string; + route: string; + exact?: boolean; +}; + +type AnimatedItem = RecentHistoryItem & { + animationState: 'exiting' | 'entering' | ''; +}; + +function getIconForRoute( + features: TeleportFeature[], + route: string +): (props) => JSX.Element { + const feature = features.find(feature => + matchPath(route, { + path: feature?.route?.path, + exact: false, + }) + ); + + const icon = feature?.navigationItem?.icon || feature?.topMenuItem?.icon; + if (!icon) { + return () => null; + } + + return icon; +} + +export function RecentHistory({ + recentHistoryItems, + onRemoveItem, +}: { + recentHistoryItems: RecentHistoryItem[]; + onRemoveItem: (route: string) => void; +}) { + const features = useFeatures(); + const [animatedItems, setAnimatedItems] = useState([]); + const prevItemsRef = useRef([]); + + useEffect(() => { + const prevItems = prevItemsRef.current; + let newAnimatedItems = recentHistoryItems.map(item => ({ + ...item, + animationState: '', + })) as AnimatedItem[]; + + const isFirstItemDeleted = + recentHistoryItems.findIndex( + item => item.route === prevItems[0]?.route + ) === -1; + + // If an item the previous list is not in the new list (deleted) OR was moved, animate it out. + prevItems.forEach((prevItem, index) => { + if ( + !recentHistoryItems.some(item => item.route === prevItem.route) || + (prevItem?.route !== recentHistoryItems[index]?.route && + recentHistoryItems[0]?.route === prevItem?.route) + ) { + // If the item is now in the first position (meaning it was moved to the top), animate it in at the top in addition to animating it out in its previous position. + if ( + recentHistoryItems.length > 0 && + prevItems[0]?.route !== recentHistoryItems[0]?.route && + !isFirstItemDeleted + ) { + newAnimatedItems.splice(0, 1); + newAnimatedItems = [ + { ...prevItem, animationState: 'entering' }, + ...newAnimatedItems.slice(0, index), + { ...prevItem, animationState: 'exiting' }, + ...newAnimatedItems.slice(index), + ]; + } else if ( + !recentHistoryItems.some(item => item.route === prevItem.route) + ) { + newAnimatedItems = [ + ...newAnimatedItems.slice(0, index), + { ...prevItem, animationState: 'exiting' }, + ...newAnimatedItems.slice(index), + ]; + } + } + }); + + setAnimatedItems(newAnimatedItems); + prevItemsRef.current = recentHistoryItems; + + // Clean up animated items after animation + const deletedItemTimeout = setTimeout(() => { + setAnimatedItems(items => + items.filter(item => item.animationState !== 'exiting') + ); + }, 300); + const newItemsTimeout = setTimeout(() => { + setAnimatedItems(items => + items.map(item => ({ ...item, animationState: '' })) + ); + }, 400); + + return () => { + clearTimeout(deletedItemTimeout); + clearTimeout(newItemsTimeout); + }; + }, [recentHistoryItems]); + + return ( + +

+ Recent Pages +

+ {!!animatedItems.length && ( + + {animatedItems.map((item, index) => { + const Icon = getIconForRoute(features, item.route); + return ( + onRemoveItem(item.route)} + /> + ); + })} + + )} +
+ ); +} + +function AnimatedHistoryItem({ + item, + Icon, + onRemove, +}: { + item: AnimatedItem; + Icon: (props) => JSX.Element; + onRemove: () => void; +}) { + const [hovered, setHovered] = useState(false); + const itemRef = useRef(null); + + useEffect(() => { + if (item.animationState === 'exiting' && itemRef.current) { + const height = item.category ? 60 : 40; + itemRef.current.style.height = `${height}px`; + itemRef.current.style.opacity = '1'; + itemRef.current.offsetHeight; // Force reflow + requestAnimationFrame(() => { + if (itemRef.current) { + itemRef.current.style.height = '0px'; + itemRef.current.style.opacity = '0'; + } + }); + } + + if (item.animationState === 'entering' && itemRef.current) { + const height = item.category ? 60 : 40; + itemRef.current.style.height = `0px`; + itemRef.current.style.opacity = '0'; + itemRef.current.offsetHeight; // Force reflow + requestAnimationFrame(() => { + if (itemRef.current) { + itemRef.current.style.height = `${height}px`; + itemRef.current.style.opacity = '1'; + } + }); + } + }, [item.animationState]); + + return ( + setHovered(true)} + onMouseLeave={() => setHovered(false)} + onMouseOver={() => setHovered(true)} + style={{ height: item.animationState === 'entering' ? 0 : 'auto' }} + > + + + + + + + + {item.title} + + {item.category && {item.category}} + + + {hovered && ( + { + e.preventDefault(); + e.stopPropagation(); + }} + onClick={e => { + e.stopPropagation(); + e.preventDefault(); + onRemove(); + }} + > + + + )} + + + ); +} + +const AnimatedItemWrapper = styled.div<{ + isExiting: boolean; + isEntering: boolean; +}>` + overflow: hidden; + height: auto; + width: 100%; + transition: all 0.3s ease-in-out; + padding: 3px; + + ${props => + props.isEntering && + ` + transition: all 0.3s ease-in-out 0.1s; + pointer-events: none; + opacity: 0; + `} + + ${props => + props.isExiting && + ` + pointer-events: none; + `} +`; + +const StyledNavLink = styled(NavLink)` + padding: ${props => props.theme.space[2]}px ${props => props.theme.space[3]}px; + text-decoration: none; + user-select: none; + border-radius: ${props => props.theme.radii[2]}px; + max-width: 100%; + display: flex; + position: relative; + + cursor: pointer; + + ${props => getSubsectionStyles(props.theme, false)} +`; + +const DeleteButtonAlt = styled(ButtonIcon)<{ size: number }>` + position: absolute; + right: 0; + top: 0; + height: ${props => props.size}px; + width: ${props => props.size}px; + border-radius: ${props => props.theme.radii[2]}px; +`; diff --git a/web/packages/teleport/src/Navigation/SideNavigation/Navigation.tsx b/web/packages/teleport/src/Navigation/SideNavigation/Navigation.tsx index 2099a09abd61f..9ba01936767d4 100644 --- a/web/packages/teleport/src/Navigation/SideNavigation/Navigation.tsx +++ b/web/packages/teleport/src/Navigation/SideNavigation/Navigation.tsx @@ -16,7 +16,13 @@ * along with this program. If not, see . */ -import React, { useState, useCallback, useEffect, useRef } from 'react'; +import React, { + useState, + useCallback, + useEffect, + useRef, + useMemo, +} from 'react'; import styled, { useTheme } from 'styled-components'; import { matchPath, useHistory } from 'react-router'; import { Text, Flex, Box, P2 } from 'design'; @@ -72,15 +78,18 @@ const PanelBackground = styled.div` /* NavigationSection is a section in the navbar, this can either be a standalone section (clickable button with no drawer), or a category with subsections shown in a drawer that expands. */ export type NavigationSection = { - category: SidenavCategory; + category?: SidenavCategory; subsections?: NavigationSubsection[]; /* standalone is whether this is a clickable nav section with no subsections/drawer. */ standalone?: boolean; }; -/* NavigationSubsection is a subsection of a NavigationSection, these are the items listed in the drawer of a NavigationSection. */ +/** + * NavigationSubsection is a subsection of a NavigationSection, these are the items listed in the drawer of a NavigationSection, or if isTopMenuItem is true, in the top menu (eg. Account Settings). + */ export type NavigationSubsection = { - category: SidenavCategory; + category?: SidenavCategory; + isTopMenuItem?: boolean; title: string; route: string; exact: boolean; @@ -139,6 +148,26 @@ function getSubsectionsForCategory( // getNavSubsectionForRoute returns the sidenav subsection that the user is correctly on (based on route). // Note that it is possible for this not to return anything, such as in the case where the user is on a page that isn't in the sidenav (eg. Account Settings). +/** + * getTopMenuSection returns a NavigationSection with the top menu items. This is not used in the sidenav, but will be used to make the top menu items searchable. + */ +function getTopMenuSection(features: TeleportFeature[]): NavigationSection { + const topMenuItems = features.filter( + feature => !!feature.topMenuItem && !feature.sideNavCategory + ); + + return { + subsections: topMenuItems.map(feature => ({ + isTopMenuItem: true, + title: feature.topMenuItem.title, + route: feature.topMenuItem.getLink(cfg.proxyCluster), + exact: feature?.route?.exact, + icon: feature.topMenuItem.icon, + searchableTags: feature.topMenuItem.searchableTags, + })), + }; +} + function getNavSubsectionForRoute( features: TeleportFeature[], route: history.Location | Location @@ -152,10 +181,22 @@ function getNavSubsectionForRoute( }) ); - if (!feature || !feature.sideNavCategory) { + if (!feature || (!feature.sideNavCategory && !feature.topMenuItem)) { return; } + if (feature.topMenuItem) { + return { + isTopMenuItem: true, + exact: feature.route.exact, + title: feature.topMenuItem.title, + route: feature.topMenuItem.getLink(cfg.proxyCluster), + icon: feature.topMenuItem.icon, + searchableTags: feature.topMenuItem.searchableTags, + category: feature?.sideNavCategory, + }; + } + return { category: feature.sideNavCategory, title: feature.navigationItem.title, @@ -223,11 +264,15 @@ export function Navigation() { } }; }, []); - const currentView = getNavSubsectionForRoute(features, history.location); + const currentView = useMemo( + () => getNavSubsectionForRoute(features, history.location), + [history.location] + ); const navSections = getNavigationSections(features).filter( section => section.subsections.length ); + const topMenuSection = getTopMenuSection(features); const handleSetExpandedSection = useCallback( (section: NavigationSection) => { @@ -300,7 +345,7 @@ export function Navigation() { . */ -import React, { useState, useRef } from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import { NavLink } from 'react-router-dom'; import styled from 'styled-components'; -import { Box, Flex, Text } from 'design'; +import { Box, Flex, P3, Text } from 'design'; import { height, space, color } from 'design/system'; import useStickyClusterId from 'teleport/useStickyClusterId'; import { useUser } from 'teleport/User/UserContext'; +import { storageService } from 'teleport/services/storageService'; + +import { RecentHistory, RecentHistoryItem } from '../RecentHistory'; import { NavigationSection, NavigationSubsection } from './Navigation'; import { @@ -33,7 +36,6 @@ import { verticalPadding, getSubsectionStyles, } from './Section'; -import { CategoryIcon } from './CategoryIcon'; import { CustomNavigationCategory } from './categories'; import { getResourcesSectionForSearch } from './ResourcesSection'; @@ -120,6 +122,28 @@ function SearchContent({ ) ); + const [recentHistory, setRecentHistory] = useState( + storageService.getRecentHistory() + ); + + useEffect(() => { + if (currentView) { + const newRecentHistory = storageService.addRecentHistoryItem({ + category: currentView?.category, + title: currentView?.title, + route: currentView?.route, + exact: currentView?.exact, + }); + + setRecentHistory(newRecentHistory); + } + }, [currentView]); + + function handleRemoveItem(route: string) { + const newRecentHistory = storageService.removeRecentHistoryItem(route); + setRecentHistory(newRecentHistory); + } + return ( @@ -150,6 +174,12 @@ function SearchContent({ ))} )} + {searchInput.length === 0 && ( + + )} ); @@ -170,20 +200,16 @@ function SearchResult({ onClick={subsection.onClick} > - - - + + + {subsection.title} - - {subsection.category} - + {subsection.category && ( + {subsection.category} + )} diff --git a/web/packages/teleport/src/features.tsx b/web/packages/teleport/src/features.tsx index f1aab44471ad5..722d97fb565e3 100644 --- a/web/packages/teleport/src/features.tsx +++ b/web/packages/teleport/src/features.tsx @@ -645,6 +645,13 @@ export class FeatureAccount implements TeleportFeature { getLink() { return cfg.routes.account; }, + searchableTags: [ + 'account settings', + 'settings', + 'password', + 'mfa', + 'change password', + ], }; } @@ -667,6 +674,7 @@ export class FeatureHelpAndSupport implements TeleportFeature { getLink() { return cfg.routes.support; }, + searchableTags: ['help', 'support', NavTitle.HelpAndSupport], }; } diff --git a/web/packages/teleport/src/services/audit/makeEvent.ts b/web/packages/teleport/src/services/audit/makeEvent.ts index 2a2bf26a3ba5e..121fca0660ce2 100644 --- a/web/packages/teleport/src/services/audit/makeEvent.ts +++ b/web/packages/teleport/src/services/audit/makeEvent.ts @@ -305,86 +305,6 @@ export const formatters: Formatters = { rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, - [eventCodes.SFTP_CLOSE]: { - type: 'sftp', - desc: 'SFTP Close', - format: ({ user, path, ...rest }) => - `User [${user}] closed file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_CLOSE_FAILURE]: { - type: 'sftp', - desc: 'SFTP Close Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to close file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, - [eventCodes.SFTP_READ]: { - type: 'sftp', - desc: 'SFTP Read', - format: ({ user, path, ...rest }) => - `User [${user}] read from file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_READ_FAILURE]: { - type: 'sftp', - desc: 'SFTP Read Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to read from file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, - [eventCodes.SFTP_WRITE]: { - type: 'sftp', - desc: 'SFTP Write', - format: ({ user, path, ...rest }) => - `User [${user}] wrote to file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_WRITE_FAILURE]: { - type: 'sftp', - desc: 'SFTP Write Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to write to file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, - [eventCodes.SFTP_LSTAT]: { - type: 'sftp', - desc: 'SFTP Lstat', - format: ({ user, path, ...rest }) => - `User [${user}] queried attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_LSTAT_FAILURE]: { - type: 'sftp', - desc: 'SFTP Lstat Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to query attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, - [eventCodes.SFTP_FSTAT]: { - type: 'sftp', - desc: 'SFTP Fstat', - format: ({ user, path, ...rest }) => - `User [${user}] queried attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_FSTAT_FAILURE]: { - type: 'sftp', - desc: 'SFTP Fstat Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to query attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, [eventCodes.SFTP_SETSTAT]: { type: 'sftp', desc: 'SFTP Setstat', @@ -401,22 +321,6 @@ export const formatters: Formatters = { rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, - [eventCodes.SFTP_FSETSTAT]: { - type: 'sftp', - desc: 'SFTP Fsetstat', - format: ({ user, path, ...rest }) => - `User [${user}] changed attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_FSETSTAT_FAILURE]: { - type: 'sftp', - desc: 'SFTP Fsetstat Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to change attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, [eventCodes.SFTP_OPENDIR]: { type: 'sftp', desc: 'SFTP Opendir', @@ -497,38 +401,6 @@ export const formatters: Formatters = { rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, - [eventCodes.SFTP_REALPATH]: { - type: 'sftp', - desc: 'SFTP Realpath', - format: ({ user, path, ...rest }) => - `User [${user}] queried absolute path of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_REALPATH_FAILURE]: { - type: 'sftp', - desc: 'SFTP Realpath Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to query absolute path of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, - [eventCodes.SFTP_STAT]: { - type: 'sftp', - desc: 'SFTP Stat', - format: ({ user, path, ...rest }) => - `User [${user}] queried attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_STAT_FAILURE]: { - type: 'sftp', - desc: 'SFTP Stat Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to query attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, [eventCodes.SFTP_RENAME]: { type: 'sftp', desc: 'SFTP Rename', @@ -545,22 +417,6 @@ export const formatters: Formatters = { rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, - [eventCodes.SFTP_READLINK]: { - type: 'sftp', - desc: 'SFTP Readlink', - format: ({ user, path, ...rest }) => - `User [${user}] read symbolic link [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]`, - }, - [eventCodes.SFTP_READLINK_FAILURE]: { - type: 'sftp', - desc: 'SFTP Readlink Failed', - format: ({ user, path, error, ...rest }) => - `User [${user}] failed to read symbolic link [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] - }]: [${error}]`, - }, [eventCodes.SFTP_SYMLINK]: { type: 'sftp', desc: 'SFTP Symlink', @@ -1971,6 +1827,13 @@ export const formatters: Formatters = { return `User [${user}] deleted a user task [${name}]`; }, }, + [eventCodes.SFTP_SUMMARY]: { + type: 'sftp_summary', + desc: 'File Transfer Completed', + format: ({ user, server_hostname }) => { + return `User [${user}] completed a file transfer on [${server_hostname}]`; + }, + }, [eventCodes.UNKNOWN]: { type: 'unknown', desc: 'Unknown Event', diff --git a/web/packages/teleport/src/services/audit/types.ts b/web/packages/teleport/src/services/audit/types.ts index 3a52afb6617f5..7bc36eaa7a449 100644 --- a/web/packages/teleport/src/services/audit/types.ts +++ b/web/packages/teleport/src/services/audit/types.ts @@ -163,20 +163,8 @@ export const eventCodes = { SCP_DISALLOWED: 'T3010E', SFTP_OPEN_FAILURE: 'TS001E', SFTP_OPEN: 'TS001I', - SFTP_CLOSE_FAILURE: 'TS002E', - SFTP_CLOSE: 'TS002I', - SFTP_READ_FAILURE: 'TS003E', - SFTP_READ: 'TS003I', - SFTP_WRITE_FAILURE: 'TS004E', - SFTP_WRITE: 'TS004I', - SFTP_LSTAT_FAILURE: 'TS005E', - SFTP_LSTAT: 'TS005I', - SFTP_FSTAT_FAILURE: 'TS006E', - SFTP_FSTAT: 'TS006I', SFTP_SETSTAT_FAILURE: 'TS007E', SFTP_SETSTAT: 'TS007I', - SFTP_FSETSTAT_FAILURE: 'TS008E', - SFTP_FSETSTAT: 'TS008I', SFTP_OPENDIR_FAILURE: 'TS009E', SFTP_OPENDIR: 'TS009I', SFTP_READDIR_FAILURE: 'TS010E', @@ -187,19 +175,14 @@ export const eventCodes = { SFTP_MKDIR: 'TS012I', SFTP_RMDIR_FAILURE: 'TS013E', SFTP_RMDIR: 'TS013I', - SFTP_REALPATH_FAILURE: 'TS014E', - SFTP_REALPATH: 'TS014I', - SFTP_STAT_FAILURE: 'TS015E', - SFTP_STAT: 'TS015I', SFTP_RENAME_FAILURE: 'TS016E', SFTP_RENAME: 'TS016I', - SFTP_READLINK_FAILURE: 'TS017E', - SFTP_READLINK: 'TS017I', SFTP_SYMLINK_FAILURE: 'TS018E', SFTP_SYMLINK: 'TS018I', SFTP_LINK: 'TS019I', SFTP_LINK_FAILURE: 'TS019E', SFTP_DISALLOWED: 'TS020E', + SFTP_SUMMARY: 'TS021I', SESSION_COMMAND: 'T4000I', SESSION_DATA: 'T2006I', SESSION_DISK: 'T4001I', @@ -457,34 +440,10 @@ export type RawEvents = { [eventCodes.SFTP_OPEN_FAILURE]: RawEventSFTP< typeof eventCodes.SFTP_OPEN_FAILURE >; - [eventCodes.SFTP_CLOSE]: RawEventSFTP; - [eventCodes.SFTP_CLOSE_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_CLOSE_FAILURE - >; - [eventCodes.SFTP_READ]: RawEventSFTP; - [eventCodes.SFTP_READ_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_READ_FAILURE - >; - [eventCodes.SFTP_WRITE]: RawEventSFTP; - [eventCodes.SFTP_WRITE_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_WRITE_FAILURE - >; - [eventCodes.SFTP_LSTAT]: RawEventSFTP; - [eventCodes.SFTP_LSTAT_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_LSTAT_FAILURE - >; - [eventCodes.SFTP_FSTAT]: RawEventSFTP; - [eventCodes.SFTP_FSTAT_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_FSTAT_FAILURE - >; [eventCodes.SFTP_SETSTAT]: RawEventSFTP; [eventCodes.SFTP_SETSTAT_FAILURE]: RawEventSFTP< typeof eventCodes.SFTP_SETSTAT_FAILURE >; - [eventCodes.SFTP_FSETSTAT]: RawEventSFTP; - [eventCodes.SFTP_FSETSTAT_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_FSETSTAT_FAILURE - >; [eventCodes.SFTP_OPENDIR]: RawEventSFTP; [eventCodes.SFTP_OPENDIR_FAILURE]: RawEventSFTP< typeof eventCodes.SFTP_OPENDIR_FAILURE @@ -505,22 +464,10 @@ export type RawEvents = { [eventCodes.SFTP_RMDIR_FAILURE]: RawEventSFTP< typeof eventCodes.SFTP_RMDIR_FAILURE >; - [eventCodes.SFTP_REALPATH]: RawEventSFTP; - [eventCodes.SFTP_REALPATH_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_REALPATH_FAILURE - >; - [eventCodes.SFTP_STAT]: RawEventSFTP; - [eventCodes.SFTP_STAT_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_STAT_FAILURE - >; [eventCodes.SFTP_RENAME]: RawEventSFTP; [eventCodes.SFTP_RENAME_FAILURE]: RawEventSFTP< typeof eventCodes.SFTP_RENAME_FAILURE >; - [eventCodes.SFTP_READLINK]: RawEventSFTP; - [eventCodes.SFTP_READLINK_FAILURE]: RawEventSFTP< - typeof eventCodes.SFTP_READLINK_FAILURE - >; [eventCodes.SFTP_SYMLINK]: RawEventSFTP; [eventCodes.SFTP_SYMLINK_FAILURE]: RawEventSFTP< typeof eventCodes.SFTP_SYMLINK_FAILURE @@ -1746,6 +1693,13 @@ export type RawEvents = { typeof eventCodes.USER_TASK_DELETE, HasName >; + [eventCodes.SFTP_SUMMARY]: RawEvent< + typeof eventCodes.SFTP_SUMMARY, + { + user: string; + server_hostname: string; + } + >; }; /** diff --git a/web/packages/teleport/src/services/storageService/storageService.ts b/web/packages/teleport/src/services/storageService/storageService.ts index 92b9b3ec3e283..ebef656ff7b58 100644 --- a/web/packages/teleport/src/services/storageService/storageService.ts +++ b/web/packages/teleport/src/services/storageService/storageService.ts @@ -28,6 +28,7 @@ import { convertBackendUserPreferences, isBackendUserPreferences, } from 'teleport/services/userPreferences/userPreferences'; +import { RecentHistoryItem } from 'teleport/Navigation/RecentHistory'; import { CloudUserInvites, KeysEnum, LocalStorageSurvey } from './types'; @@ -41,8 +42,11 @@ const KEEP_LOCALSTORAGE_KEYS_ON_LOGOUT = [ KeysEnum.LICENSE_ACKNOWLEDGED, KeysEnum.USERS_NOT_EQUAL_TO_MAU_ACKNOWLEDGED, KeysEnum.USE_NEW_ROLE_EDITOR, + KeysEnum.RECENT_HISTORY, ]; +const RECENT_HISTORY_MAX_LENGTH = 10; + export const storageService = { clear() { Object.keys(window.localStorage).forEach(key => { @@ -265,4 +269,45 @@ export const storageService = { getIsTopBarView(): boolean { return this.getParsedJSONValue(KeysEnum.USE_TOP_BAR, false); }, + + getRecentHistory(): RecentHistoryItem[] { + return this.getParsedJSONValue(KeysEnum.RECENT_HISTORY, []); + }, + + addRecentHistoryItem(item: RecentHistoryItem): RecentHistoryItem[] { + const history = storageService.getRecentHistory(); + const deduplicatedHistory = [...history]; + + // Remove a duplicate item if it exists. + const existingDuplicateIndex = history.findIndex( + historyItem => historyItem.route === item.route + ); + if (existingDuplicateIndex !== -1) { + deduplicatedHistory.splice(existingDuplicateIndex, 1); + } + + const newHistory = [item, ...deduplicatedHistory].slice( + 0, + RECENT_HISTORY_MAX_LENGTH + ); + + window.localStorage.setItem( + KeysEnum.RECENT_HISTORY, + JSON.stringify(newHistory) + ); + + return newHistory; + }, + + removeRecentHistoryItem(route: string): RecentHistoryItem[] { + const history = storageService.getRecentHistory(); + const newHistory = history.filter(item => item.route !== route); + + window.localStorage.setItem( + KeysEnum.RECENT_HISTORY, + JSON.stringify(newHistory) + ); + + return newHistory; + }, }; diff --git a/web/packages/teleport/src/services/storageService/types.ts b/web/packages/teleport/src/services/storageService/types.ts index f689442d13368..fa04cc88c704d 100644 --- a/web/packages/teleport/src/services/storageService/types.ts +++ b/web/packages/teleport/src/services/storageService/types.ts @@ -36,6 +36,7 @@ export const KeysEnum = { USERS_NOT_EQUAL_TO_MAU_ACKNOWLEDGED: 'grv_users_not_equal_to_mau_acknowledged', LOCAL_NOTIFICATION_STATES: 'grv_teleport_notification_states', + RECENT_HISTORY: 'grv_teleport_sidenav_recent_history', // TODO(bl-nero): Remove once the new role editor is in acceptable state. USE_NEW_ROLE_EDITOR: 'grv_teleport_use_new_role_editor',