From 96f692710842ec353e0951987c38789f3dfac213 Mon Sep 17 00:00:00 2001 From: Bartosz Leper Date: Wed, 29 Jan 2025 09:31:30 +0100 Subject: [PATCH 01/27] [v17] Support sticky tooltips in FieldInput and legend in LabelsInput (#51552) * Support sticky tooltips in FieldInput and legend in LabelsInput (#51457) * Support sticky tooltips in FieldInput and legend in LabelsInput * review * Revert "review" (#51510) This reverts commit ffe0554b75f35693f99934007e5a6cf9d65d99b1. --- .../components/FieldInput/FieldInput.tsx | 7 ++- .../LabelsInput/LabelsInput.story.tsx | 2 + .../components/LabelsInput/LabelsInput.tsx | 57 ++++++++++++++----- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/web/packages/shared/components/FieldInput/FieldInput.tsx b/web/packages/shared/components/FieldInput/FieldInput.tsx index 2f3a3eb012550..146db2849cdce 100644 --- a/web/packages/shared/components/FieldInput/FieldInput.tsx +++ b/web/packages/shared/components/FieldInput/FieldInput.tsx @@ -57,6 +57,7 @@ const FieldInput = forwardRef( spellCheck, readonly = false, toolTipContent = null, + tooltipSticky = false, disabled = false, markAsError = false, required = false, @@ -114,7 +115,10 @@ const FieldInput = forwardRef( > {label} - + ) : ( <>{label} @@ -242,6 +246,7 @@ export type FieldInputProps = BoxProps & { min?: number; max?: number; toolTipContent?: React.ReactNode; + tooltipSticky?: boolean; disabled?: boolean; // markAsError is a flag to highlight an // input box as error color before validator diff --git a/web/packages/teleport/src/components/LabelsInput/LabelsInput.story.tsx b/web/packages/teleport/src/components/LabelsInput/LabelsInput.story.tsx index 0fdbbfcb3cd05..d1cfa0853d8dd 100644 --- a/web/packages/teleport/src/components/LabelsInput/LabelsInput.story.tsx +++ b/web/packages/teleport/src/components/LabelsInput/LabelsInput.story.tsx @@ -60,6 +60,8 @@ export const Custom = () => { ; export function LabelsInput({ + legend, + tooltipContent, labels = [], setLabels, disableBtns = false, @@ -74,6 +77,8 @@ export function LabelsInput({ inputWidth = 200, rule = defaultRule, }: { + legend?: string; + tooltipContent?: string; labels: Label[]; setLabels(l: Label[]): void; disableBtns?: boolean; @@ -141,15 +146,34 @@ export function LabelsInput({ const width = `${inputWidth}px`; const inputSize = 'medium'; return ( - <> +
+ {legend && ( + + {tooltipContent ? ( + <> + + {legend} + + + + ) : ( + legend + )} + + )} {labels.length > 0 && ( - + - {labelKey.fieldName} (required field) - - - {labelVal.fieldName} (required field) + + {labelKey.fieldName} (required field) + + {labelVal.fieldName} (required field) )} @@ -229,17 +253,12 @@ export function LabelsInput({ {labels.length > 0 ? `Add another ${adjective}` : `Add a ${adjective}`} - +
); } const defaultRule = () => () => ({ valid: true }); -const SmallText = styled.span` - font-size: ${p => p.theme.fontSizes[1]}px; - font-weight: lighter; -`; - export const nonEmptyLabels: LabelsRule = labels => () => { const results = labels.map(label => ({ name: requiredField('required')(label.name)(), @@ -250,3 +269,15 @@ export const nonEmptyLabels: LabelsRule = labels => () => { results: results, }; }; + +const Fieldset = styled.fieldset` + border: none; + margin: 0; + padding: 0; +`; + +const Legend = styled.legend` + margin: 0 0 ${props => props.theme.space[1]}px 0; + padding: 0; + ${props => props.theme.typography.body3} +`; From 3afb16c78da43c040482df8e8785f373435630a7 Mon Sep 17 00:00:00 2001 From: Nic Klaassen Date: Wed, 29 Jan 2025 01:51:22 -0800 Subject: [PATCH 02/27] [v17][vnet] run networking stack on Windows (#51575) Backport #51280 to branch/v17 --- lib/vnet/admin_process_windows.go | 80 +++++++++++++++++-- lib/vnet/client_application_service_client.go | 15 ++-- lib/vnet/dns/osnameservers_darwin.go | 6 ++ lib/vnet/dns/osnameservers_other.go | 4 +- lib/vnet/dns/osnameservers_windows.go | 37 +++++++++ lib/vnet/service_windows.go | 24 ++++-- lib/vnet/user_process_windows.go | 39 ++++++++- 7 files changed, 183 insertions(+), 22 deletions(-) create mode 100644 lib/vnet/dns/osnameservers_windows.go diff --git a/lib/vnet/admin_process_windows.go b/lib/vnet/admin_process_windows.go index 1c30c38eb36d1..2eedec4256510 100644 --- a/lib/vnet/admin_process_windows.go +++ b/lib/vnet/admin_process_windows.go @@ -18,16 +18,36 @@ package vnet import ( "context" + "time" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" "golang.zx2c4.com/wireguard/tun" ) +type windowsAdminProcessConfig struct { + // clientApplicationServiceAddr is the local TCP address of the client + // application gRPC service. + clientApplicationServiceAddr string +} + // runWindowsAdminProcess must run as administrator. It creates and sets up a TUN // device, runs the VNet networking stack, and handles OS configuration. It will // continue to run until [ctx] is canceled or encountering an unrecoverable // error. -func runWindowsAdminProcess(ctx context.Context) error { +func runWindowsAdminProcess(ctx context.Context, cfg *windowsAdminProcessConfig) error { + log.InfoContext(ctx, "Running VNet admin process") + + clt, err := newClientApplicationServiceClient(ctx, cfg.clientApplicationServiceAddr) + if err != nil { + return trace.Wrap(err, "creating user process client") + } + defer clt.close() + + if err := authenticateUserProcess(ctx, clt); err != nil { + return trace.Wrap(err, "authenticating user process") + } + device, err := tun.CreateTUN("TeleportVNet", mtu) if err != nil { return trace.Wrap(err, "creating TUN device") @@ -38,8 +58,58 @@ func runWindowsAdminProcess(ctx context.Context) error { return trace.Wrap(err, "getting TUN device name") } log.InfoContext(ctx, "Created TUN interface", "tun", tunName) - // TODO(nklaassen): actually run VNet. For now, just stay alive until the - // context is canceled. - <-ctx.Done() - return trace.Wrap(ctx.Err()) + + networkStackConfig, err := newWindowsNetworkStackConfig(device, clt) + if err != nil { + return trace.Wrap(err, "creating network stack config") + } + networkStack, err := newNetworkStack(networkStackConfig) + if err != nil { + return trace.Wrap(err, "creating network stack") + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + errCh := make(chan error) + go func() { + errCh <- trace.Wrap(networkStack.run(ctx), "running network stack") + }() +loop: + for { + select { + case <-time.After(time.Second): + if err := clt.Ping(ctx); err != nil { + log.InfoContext(ctx, "Failed to ping client application, it may have exited, shutting down", "error", err) + break loop + } + case <-ctx.Done(): + log.InfoContext(ctx, "Context canceled, shutting down", "error", err) + break loop + } + } + // Cancel the context and wait for networkStack.run to terminate. + cancel() + err = <-errCh + return trace.Wrap(err, "running VNet network stack") +} + +func newWindowsNetworkStackConfig(tun tunDevice, clt *clientApplicationServiceClient) (*networkStackConfig, error) { + appProvider := newRemoteAppProvider(clt) + appResolver := newTCPAppResolver(appProvider, clockwork.NewRealClock()) + ipv6Prefix, err := NewIPv6Prefix() + if err != nil { + return nil, trace.Wrap(err, "creating new IPv6 prefix") + } + dnsIPv6 := ipv6WithSuffix(ipv6Prefix, []byte{2}) + return &networkStackConfig{ + tunDevice: tun, + ipv6Prefix: ipv6Prefix, + dnsIPv6: dnsIPv6, + tcpHandlerResolver: appResolver, + }, nil +} + +func authenticateUserProcess(ctx context.Context, clt *clientApplicationServiceClient) error { + // TODO(nklaassen): implement process authentication. + return nil } diff --git a/lib/vnet/client_application_service_client.go b/lib/vnet/client_application_service_client.go index 7a7bdd32ad161..ebd449f336d10 100644 --- a/lib/vnet/client_application_service_client.go +++ b/lib/vnet/client_application_service_client.go @@ -37,6 +37,7 @@ type clientApplicationServiceClient struct { } func newClientApplicationServiceClient(ctx context.Context, addr string) (*clientApplicationServiceClient, error) { + // TODO(nklaassen): add mTLS credentials for client application service. conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor(interceptors.GRPCClientUnaryErrorInterceptor), @@ -58,7 +59,7 @@ func (c *clientApplicationServiceClient) close() error { // Ping pings the client application. func (c *clientApplicationServiceClient) Ping(ctx context.Context) error { if _, err := c.clt.Ping(ctx, &vnetv1.PingRequest{}); err != nil { - return trace.Wrap(err, "pinging client application") + return trace.Wrap(err, "calling Ping rpc") } return nil } @@ -70,7 +71,7 @@ func (c *clientApplicationServiceClient) AuthenticateProcess(ctx context.Context PipePath: pipePath, }) if err != nil { - return trace.Wrap(err, "authenticating process") + return trace.Wrap(err, "calling AuthenticateProcess rpc") } if resp.Version != api.Version { return trace.BadParameter("version mismatch, user process version is %s, admin process version is %s", @@ -86,7 +87,7 @@ func (c *clientApplicationServiceClient) ResolveAppInfo(ctx context.Context, fqd Fqdn: fqdn, }) if err != nil { - return nil, trace.Wrap(err, "resolving app info") + return nil, trace.Wrap(err, "calling ResolveAppInfo rpc") } return resp.GetAppInfo(), nil } @@ -98,7 +99,7 @@ func (c *clientApplicationServiceClient) ReissueAppCert(ctx context.Context, app TargetPort: uint32(targetPort), }) if err != nil { - return nil, trace.Wrap(err, "reissuing app cert") + return nil, trace.Wrap(err, "calling ReissueAppCert rpc") } return resp.GetCert(), nil } @@ -108,7 +109,7 @@ func (c *clientApplicationServiceClient) ReissueAppCert(ctx context.Context, app func (c *clientApplicationServiceClient) SignForApp(ctx context.Context, req *vnetv1.SignForAppRequest) ([]byte, error) { resp, err := c.clt.SignForApp(ctx, req) if err != nil { - return nil, trace.Wrap(err, "signing for app") + return nil, trace.Wrap(err, "calling SignForApp rpc") } return resp.GetSignature(), nil } @@ -119,7 +120,7 @@ func (c *clientApplicationServiceClient) OnNewConnection(ctx context.Context, ap AppKey: appKey, }) if err != nil { - return trace.Wrap(err) + return trace.Wrap(err, "calling OnNewConnection rpc") } return nil } @@ -132,7 +133,7 @@ func (c *clientApplicationServiceClient) OnInvalidLocalPort(ctx context.Context, TargetPort: uint32(targetPort), }) if err != nil { - return trace.Wrap(err) + return trace.Wrap(err, "calling OnInvalidLocalPort rpc") } return nil } diff --git a/lib/vnet/dns/osnameservers_darwin.go b/lib/vnet/dns/osnameservers_darwin.go index 4e5f22b20a2f1..35bcb425db4ed 100644 --- a/lib/vnet/dns/osnameservers_darwin.go +++ b/lib/vnet/dns/osnameservers_darwin.go @@ -34,10 +34,14 @@ const ( confFilePath = "/etc/resolv.conf" ) +// OSUpstreamNameserverSource provides the list of upstream DNS nameservers +// configured in the OS. The VNet DNS resolver will forward unhandles queries to +// these nameservers. type OSUpstreamNameserverSource struct { ttlCache *utils.FnCache } +// NewOSUpstreamNameserverSource returns a new *OSUpstreamNameserverSource. func NewOSUpstreamNameserverSource() (*OSUpstreamNameserverSource, error) { ttlCache, err := utils.NewFnCache(utils.FnCacheConfig{ TTL: 10 * time.Second, @@ -50,6 +54,8 @@ func NewOSUpstreamNameserverSource() (*OSUpstreamNameserverSource, error) { }, nil } +// UpstreamNameservers returns a cached view of the host OS's current default +// nameservers, as found in /etc/resolv.conf. func (s *OSUpstreamNameserverSource) UpstreamNameservers(ctx context.Context) ([]string, error) { return utils.FnCacheGet(ctx, s.ttlCache, 0, s.upstreamNameservers) } diff --git a/lib/vnet/dns/osnameservers_other.go b/lib/vnet/dns/osnameservers_other.go index a353020fa0b67..06cca8d0856d3 100644 --- a/lib/vnet/dns/osnameservers_other.go +++ b/lib/vnet/dns/osnameservers_other.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -//go:build !darwin -// +build !darwin +//go:build !darwin && !windows +// +build !darwin,!windows package dns diff --git a/lib/vnet/dns/osnameservers_windows.go b/lib/vnet/dns/osnameservers_windows.go new file mode 100644 index 0000000000000..5ca17e61735a9 --- /dev/null +++ b/lib/vnet/dns/osnameservers_windows.go @@ -0,0 +1,37 @@ +// Teleport +// Copyright (C) 2025 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 dns + +import "context" + +// OSUpstreamNameserverSource provides the list of upstream DNS nameservers +// configured in the OS. The VNet DNS resolver will forward unhandles queries to +// these nameservers. +type OSUpstreamNameserverSource struct{} + +// NewOSUpstreamNameserverSource returns a new *OSUpstreamNameserverSource. +func NewOSUpstreamNameserverSource() (*OSUpstreamNameserverSource, error) { + return &OSUpstreamNameserverSource{}, nil +} + +// UpstreamNameservers is net yet implemented and currently returns a nil/empty +// list of upstream nameservers. It does not return an error so that the +// networking stack can actually run without just immediately exiting. +func (s *OSUpstreamNameserverSource) UpstreamNameservers(ctx context.Context) ([]string, error) { + // TODO(nklaassen): implement UpstreamNameservers on windows. + return nil, nil +} diff --git a/lib/vnet/service_windows.go b/lib/vnet/service_windows.go index 1387d6cca4407..6bf09342c9489 100644 --- a/lib/vnet/service_windows.go +++ b/lib/vnet/service_windows.go @@ -24,6 +24,7 @@ import ( "syscall" "time" + "github.com/alecthomas/kingpin/v2" "github.com/gravitational/trace" "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" @@ -40,8 +41,8 @@ const ( // runService is called from the normal user process to run the VNet Windows in // the background and wait for it to exit. It will terminate the service and // return immediately if [ctx] is canceled. -func runService(ctx context.Context) error { - service, err := startService(ctx) +func runService(ctx context.Context, cfg *windowsAdminProcessConfig) error { + service, err := startService(ctx, cfg) if err != nil { return trace.Wrap(err) } @@ -69,7 +70,7 @@ func runService(ctx context.Context) error { } // startService starts the Windows VNet admin service in the background. -func startService(ctx context.Context) (*mgr.Service, error) { +func startService(ctx context.Context, cfg *windowsAdminProcessConfig) (*mgr.Service, error) { // Avoid [mgr.Connect] because it requests elevated permissions. scManager, err := windows.OpenSCManager(nil /*machine*/, nil /*database*/, windows.SC_MANAGER_CONNECT) if err != nil { @@ -88,7 +89,7 @@ func startService(ctx context.Context) (*mgr.Service, error) { Name: serviceName, Handle: serviceHandle, } - if err := service.Start(ServiceCommand); err != nil { + if err := service.Start(ServiceCommand, "--addr", cfg.clientApplicationServiceAddr); err != nil { return nil, trace.Wrap(err, "starting Windows service %s", serviceName) } return service, nil @@ -157,7 +158,20 @@ loop: } func (s *windowsService) run(ctx context.Context, args []string) error { - if err := runWindowsAdminProcess(ctx); err != nil { + var clientApplicationServiceAddr string + app := kingpin.New(serviceName, "Teleport VNet Windows Service") + serviceCmd := app.Command("vnet-service", "Start the VNet service.") + serviceCmd.Flag("addr", "client application service address").Required().StringVar(&clientApplicationServiceAddr) + cmd, err := app.Parse(args[1:]) + if err != nil { + return trace.Wrap(err, "parsing runtime arguments to Windows service") + } + if cmd != serviceCmd.FullCommand() { + return trace.BadParameter("Windows service runtime arguments did not match \"vnet-service\", args: %v", args[1:]) + } + if err := runWindowsAdminProcess(ctx, &windowsAdminProcessConfig{ + clientApplicationServiceAddr: clientApplicationServiceAddr, + }); err != nil { return trace.Wrap(err, "running admin process") } return nil diff --git a/lib/vnet/user_process_windows.go b/lib/vnet/user_process_windows.go index 9fccd0bb528b3..0eb3dcf97762e 100644 --- a/lib/vnet/user_process_windows.go +++ b/lib/vnet/user_process_windows.go @@ -18,8 +18,15 @@ package vnet import ( "context" + "net" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "github.com/gravitational/teleport/api/utils/grpc/interceptors" + vnetv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/v1" ) // runPlatformUserProcess launches a Windows service in the background that will @@ -35,10 +42,36 @@ func runPlatformUserProcess(ctx context.Context, config *UserProcessConfig) (pm } }() + listener, err := net.Listen("tcp", ":0") + if err != nil { + return nil, trace.Wrap(err, "listening on tcp socket") + } pm, processCtx := newProcessManager() - pm.AddCriticalBackgroundTask("VNet Windows service", func() error { - return trace.Wrap(runService(processCtx), "running VNet Windows service in the background") + pm.AddCriticalBackgroundTask("tcp socket closer", func() error { + <-processCtx.Done() + return trace.Wrap(listener.Close()) + }) + pm.AddCriticalBackgroundTask("admin process", func() error { + return trace.Wrap(runService(processCtx, &windowsAdminProcessConfig{ + clientApplicationServiceAddr: listener.Addr().String(), + })) + }) + pm.AddCriticalBackgroundTask("gRPC service", func() error { + log.InfoContext(processCtx, "Starting gRPC service", "addr", listener.Addr().String()) + // TODO(nklaassen): add mTLS credentials for client application service. + grpcServer := grpc.NewServer( + grpc.Creds(insecure.NewCredentials()), + grpc.UnaryInterceptor(interceptors.GRPCServerUnaryErrorInterceptor), + grpc.StreamInterceptor(interceptors.GRPCServerStreamErrorInterceptor), + ) + clock := clockwork.NewRealClock() + appProvider := newLocalAppProvider(config.ClientApplication, clock) + svc := newClientApplicationService(appProvider) + vnetv1.RegisterClientApplicationServiceServer(grpcServer, svc) + if err := grpcServer.Serve(listener); err != nil { + return trace.Wrap(err, "serving VNet user process gRPC service") + } + return nil }) - // TODO(nklaassen): run user process gRPC service. return pm, nil } From cb0b17c4d10ef7fc38e79d6b36a5d244c6be225c Mon Sep 17 00:00:00 2001 From: Noah Stride Date: Wed, 29 Jan 2025 09:52:30 +0000 Subject: [PATCH 03/27] [v17] Update Workload Identity getting started guide for new configuration (#51542) * Update Workload Identity getting started guide * Update WorkloadIdentity -> Workload Identity --- .../workload-identity/getting-started.mdx | 217 ++++++++++-------- .../workload-identity/introduction.mdx | 2 +- 2 files changed, 124 insertions(+), 95 deletions(-) diff --git a/docs/pages/enroll-resources/workload-identity/getting-started.mdx b/docs/pages/enroll-resources/workload-identity/getting-started.mdx index 6acdfc9bf1bc2..9fb8ce801593f 100644 --- a/docs/pages/enroll-resources/workload-identity/getting-started.mdx +++ b/docs/pages/enroll-resources/workload-identity/getting-started.mdx @@ -11,8 +11,9 @@ meaning that it can be used in place of other SPIFFE compatible identity providers. In this guide, you'll configure the RBAC necessary to allow a Bot to issue -SPIFFE SVIDs and then configure `tbot` to expose a SPIFFE Workload API endpoint. -You can then connect your workloads to this endpoint to receive SPIFFE SVIDs. +workload identity credentials and then configure `tbot` to expose a SPIFFE +Workload API endpoint. You can then connect your workloads to this endpoint to +receive SPIFFE SVID-compatible workload identity credentials. ## Prerequisites @@ -23,125 +24,142 @@ You can then connect your workloads to this endpoint to receive SPIFFE SVIDs. workloads which need to access Teleport Workload Identity will run. For more information, see the [deployment guides](../machine-id/deployment/deployment.mdx). -## Step 1/4. Configure RBAC +## Step 1/4. Configure Workload Identity -First, Teleport must be configured to allow the Bot to issue SPIFFE SVIDs. -This is done by configuring a role to allow the issuance of SPIFFE SVIDs and -then granting this role to the Bot. +First, you will need to create a Workload Identity resource. + +This resource is the primary way that Teleport Workload Identity is configured. +Each Workload Identity resource represents the configuration of an identity for a +specific workload or a template to be used when representing the identity of a +group of workloads. The Workload Identity resource specifies a number of key +things, including: + +- The name of the Workload Identity, which will be needed when issuing it. +- The SPIFFE ID that will be included in credentials issued for this + WorkloadIdentity. +- Any rules around when this Workload Identity can be used to issue credentials. Before proceeding, you'll want to determine the SPIFFE ID path that your workload will use. In our example, we'll use `/svc/foo`. We provide more guidance on choosing a SPIFFE ID structure in the [Best Practices](./best-practices.mdx) guide. -Create a new file named `spiffe-issuer-role.yaml`: +Create a new file called `workload-identity.yaml`: ```yaml -kind: role -version: v6 +kind: workload_identity +version: v1 metadata: - name: spiffe-issuer + name: example-workload-identity + labels: + example: getting-started spec: - allow: - spiffe: - - path: "/svc/foo" + spiffe: + id: /svc/foo ``` Replace: -- `spiffe-issuer` with a name that describes your use-case. +- `example-workload-identity` with a name that describes your use-case. - `/svc/foo` with the SPIFFE ID path you have decided on issuing. -Use `tctl create -f ./spiffe-issuer-role.yaml` to create the role. +Use `tctl create -f ./workload-identity.yaml` to create the Workload Identity. + +Now, you'll need to create a role that will grant access to the Workload Identity +that you have just created. As with other Teleport resources, access is granted +by specifying label matchers on the role that will match the labels on the +resource itself. + +In addition to granting access to the resource, we will also need to grant the +ability to read and list the Workload Identity resource type. + +Create `workload-identity-issuer-role.yaml`: + +```yaml +kind: role +version: v6 +metadata: + name: example-workload-identity-issuer +spec: + allow: + workload_identity_labels: + example: ["getting-started"] + rules: + - resources: + - workload_identity + verbs: + - list + - read +``` -(!docs/pages/includes/create-role-using-web.mdx!) +Use `tctl create -f ./workload-identity-issuer-role.yaml` to create the role. Now, use `tctl bots update` to add the role to the Bot. Replace `example-bot` -with the name of the Bot you created in the deployment guide and `spiffe-issuer` -with the name of the role you just created: +with the name of the Bot you created in the deployment guide and +`example-workload-identity-issuer with the name of the role you just created: ```code -$ tctl bots update example-bot --add-roles spiffe-issuer +$ tctl bots update example-bot --add-roles example-workload-identity-issuer +``` + +### Configuring DNS SANs + +In some cases, you may wish to configure DNS SANs which should be included in +the X509 certificates issued by the Workload API. This is useful in cases +where the client may not be SPIFFE aware and will check the DNS SAN rather than +the SPIFFE URI during the TLS handshake. + +Modify your `workload-identity.yaml` resource definition to include the +`spec.spiffe.x509.dns_sans` field, replacing `example.com` with the DNS name you +require: + +```yaml +kind: workload_identity +version: v1 +metadata: + name: example-workload-identity + labels: + example: getting-started +spec: + spiffe: + id: /svc/foo + x509: + dns_sans: + - example.com ``` -## Step 2/4. Configure `spiffe-workload-api` service in `tbot` +Use `tctl create -f ./workload-identity.yaml` to update the WorkloadIdentity +resource with your changes. + +## Step 2/4. Configure `workload-identity-api` service in `tbot` To set up a SPIFFE Workload API endpoint with `tbot`, we configure an instance -of the `spiffe-workload-api` service. +of the `workload-identity-api` service. First, determine where you wish this socket to be created. In our example, we'll use `/opt/machine-id/workload.sock`. You may wish to choose a directory that is only accessible by the processes that will need to connect to the Workload API. -Modify your `tbot` configuration file to include the `spiffe-workload-api` +Modify your `tbot` configuration file to include the `workload-identity-api` service: ```yaml services: -- type: spiffe-workload-api +- type: workload-identity-api listen: unix:///opt/machine-id/workload.sock - svids: - - path: /svc/foo - hint: my-hint + selector: + name: example-workload-identity ``` Replace: - `/opt/machine-id/workload.sock` with the path to the socket you wish to create. -- `/svc/foo` with the SPIFFE ID path you have decided on issuing. -- `my-hint` with a hint that will be included with the SVID. This can help - workloads identify which SVID they should select if multiple are presented. - This field can be omitted if not required. +- `example-workload-identity` with the name of the Workload Identity resource you + created earlier. Start or restart your `tbot` instance to apply the new configuration -### Configuring DNS and IP SANs - -In some cases, you may wish to configure DNS and IP SANs which should be -included in the SVIDs issued by the Workload API. This is useful in cases -where the client may not be SPIFFE aware and will check the DNS SAN rather than -the SPIFFE URI during the TLS handshake. - -These can be configured in the `spiffe-workload-api` service using the `sans` -configuration block: - -```yaml -services: -- type: spiffe-workload-api - listen: unix:///opt/machine-id/workload.sock - svids: - - path: /svc/foo - hint: my-hint - sans: - dns: - - example.com - ip: - - 10.0.0.1 -``` - -You will also need to modify the role to explicitly grant the Bot permission to -request an SVID including a DNS or IP SAN. For example: - -```yaml -kind: role -version: v6 -metadata: - name: spiffe-issuer -spec: - allow: - spiffe: - - path: "/svc/foo" - # Replace with the DNS SANs that you wish your Bot to be able to include - # in SVIDs. - dns_sans: ["example.com"] - # Replace with the IP SANs that you wish your Bot to be able to include - # in SVIDs. You can remove this if you do not wish to include IP SANs. - # IPs must be specified using CIDR notation, which allows you to specify - # a single IP or a range of IPs. - ip_sans: ["10.0.0.1/32"] -``` - ### Configuring Unix Workload Attestation By default, an SVID listed under the Workload API service will be issued to any @@ -156,25 +174,35 @@ three characteristics of the workload process: - `gid`: The primary GID of the user that the workload process is running as. - `pid`: The PID of the workload process. -To configure Workload Attestation, you configure a set of rules for each SVID. -Each rule is a list of characteristics, and all characteristics within the rule -must match for that rule to pass. If you have multiple rules, any one rule can -pass for the SVID to be issued. +Within a Workload Identity, you can configure rules based on the attributes +determined via workload attestation. Each rule contains a number of tests and +all tests must pass for the rule to pass. At least one rule must pass for the +Workload Identity to be allowed to issue a credential. -For example, to configure an SVID to be issued only to workloads that are -running as the user with ID 1000 or running as a user with a primary group ID -of 50: +For example, to configure a Workload Identity to be issued only to workloads that +are running as the user with ID 1000 or running as a user with a primary group +ID of 50: ```yaml -services: -- type: spiffe-workload-api - listen: unix:///opt/machine-id/workload.sock - svids: - - path: /svc/foo - hint: my-hint - rules: - - uid: 1000 - - gid: 50 +kind: workload_identity +version: v1 +metadata: + name: example-workload-identity + labels: + example: getting-started +spec: + rules: + allow: + - conditions: + - attribute: workload.unix.uid + eq: + value: 1000 + - conditions: + - attribute: workload.unix.gid + eq: + value: 50 + spiffe: + id: /svc/foo ``` ## Step 3/4. Testing the Workload API with `tbot spiffe-inspect` @@ -196,7 +224,6 @@ INFO [TBOT] Inspecting SPIFFE Workload API Endpoint unix:///opt/machine-id/ INFO [TBOT] Received X.509 SVID context from Workload API bundles_count:1 svids_count:1 tbot/spiffe.go:46 SVIDS - spiffe://example.teleport.sh/svc/foo - - Hint: my-hint - Expiry: 2024-03-20 10:55:52 +0000 UTC Trust Bundles - example.teleport.sh @@ -220,5 +247,7 @@ integrating SPIFFE with your workloads. Workload Identity. - [Best Practices](./best-practices.mdx): Best practices for using Workload Identity in Production. +- Read the [Workload Identity reference](../../reference/workload-identity/workload-identity-resource.mdx) +to explore the configuration of the Workload Identity resource. - Read the [configuration reference](../../reference/machine-id/configuration.mdx) to explore -all the available configuration options. +all the available configuration options for `tbot`. diff --git a/docs/pages/enroll-resources/workload-identity/introduction.mdx b/docs/pages/enroll-resources/workload-identity/introduction.mdx index 3087572d86c08..0778a3838df6a 100644 --- a/docs/pages/enroll-resources/workload-identity/introduction.mdx +++ b/docs/pages/enroll-resources/workload-identity/introduction.mdx @@ -100,7 +100,7 @@ Learn more about Teleport Workload Identity: - [Federation](./federation.mdx): Learn about using Federation to allow workloads to trust workloads from other trust domains. - [JWT SVIDs](./jwt-svids.mdx): Learn about the short-lived JWTs issued by Workload Identity. - [Best Practices](./best-practices.mdx): Best practices for using Workload Identity in Production. -- [WorkloadIdentity Resource](../../reference/workload-identity/workload-identity-resource.mdx): The full reference for the WorkloadIdentity resource. +- [Workload Identity Resource](../../reference/workload-identity/workload-identity-resource.mdx): The full reference for the Workload Identity resource. - [Workload Identity API and Workload Attestation](../../reference/workload-identity/workload-identity-api-and-workload-attestation.mdx): To learn more about the Workload Identity API and Workload Attestation. Learn how to configure Teleport Workload Identity for specific use-cases: From 524a10bc0526502822dbd82d007a1c97430c0152 Mon Sep 17 00:00:00 2001 From: Marco Dinis Date: Wed, 29 Jan 2025 10:10:18 +0000 Subject: [PATCH 04/27] GCP Server AutoDiscover: only log when the script fails (#51117) (#51466) * GCP Server AutoDiscover: only log when the script fails When running Auto Discover for GCP VMs, teleport always logs the output in debug level. Now, it only logs the stdout/stderr when the installation fails. It also adds some context on which VMs it failed and the log level is now Error. * Log once per RunCommand invocation --- lib/cloud/gcp/vm.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/cloud/gcp/vm.go b/lib/cloud/gcp/vm.go index 514d0d3465988..1ebbece683129 100644 --- a/lib/cloud/gcp/vm.go +++ b/lib/cloud/gcp/vm.go @@ -25,6 +25,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net" "slices" "strings" @@ -574,24 +575,35 @@ https://cloud.google.com/solutions/connecting-securely#storing_host_keys_by_enab HostKeyCallback: callback, } + loggerWithVMMetadata := slog.With( + "project_id", req.ProjectID, + "zone", req.Zone, + "vm_name", req.Name, + "ips", ipAddrs, + ) + var errs []error for _, ip := range ipAddrs { addr := net.JoinHostPort(ip, req.SSHPort) stdout, stderr, err := sshutils.RunSSH(ctx, addr, req.Script, config, sshutils.WithDialer(req.dialContext)) - logrus.Debug(string(stdout)) - logrus.Debug(string(stderr)) if err == nil { return nil } // An exit error means the connection was successful, so don't try another address. if errors.Is(err, &ssh.ExitError{}) { + loggerWithVMMetadata.ErrorContext(ctx, "Installing teleport in GCP VM failed after connecting", + "ip", ip, + "error", err, + "stdout", string(stdout), + "stderr", string(stderr), + ) return trace.Wrap(err) } errs = append(errs, err) } err = trace.NewAggregate(errs...) - logrus.WithError(err).Debug("Command exited with error.") + loggerWithVMMetadata.ErrorContext(ctx, "Installing teleport in GCP VM failed", "error", err) return err } From 744b023c6b19d1c3d3ccc3eaed0267eb027da646 Mon Sep 17 00:00:00 2001 From: Yassine Bounekhla <56373201+rudream@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:00:49 -0500 Subject: [PATCH 05/27] add sidenav highlight support for children of features (#51569) --- web/packages/teleport/src/Login/useLogin.ts | 1 - web/packages/teleport/src/Navigation/Navigation.tsx | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/web/packages/teleport/src/Login/useLogin.ts b/web/packages/teleport/src/Login/useLogin.ts index a2bc274fc2934..585f4e3c658dd 100644 --- a/web/packages/teleport/src/Login/useLogin.ts +++ b/web/packages/teleport/src/Login/useLogin.ts @@ -205,7 +205,6 @@ export type State = ReturnType & { * moveToFront returns a copy of an array with the element that matches the condition to the front of it. */ function moveToFront(arr: T[], condition: (item: T) => boolean): T[] { - console.log(arr); const copy = [...arr]; const index = copy.findIndex(condition); diff --git a/web/packages/teleport/src/Navigation/Navigation.tsx b/web/packages/teleport/src/Navigation/Navigation.tsx index 2e0cbd81c53d6..2864ea7b14159 100644 --- a/web/packages/teleport/src/Navigation/Navigation.tsx +++ b/web/packages/teleport/src/Navigation/Navigation.tsx @@ -188,7 +188,7 @@ function getNavSubsectionForRoute( features: TeleportFeature[], route: history.Location | Location ): NavigationSubsection { - const feature = features + let feature = features .filter(feature => Boolean(feature.route)) .find(feature => matchPath(route.pathname, { @@ -197,6 +197,13 @@ function getNavSubsectionForRoute( }) ); + // If this is a child feature, use its parent as the subsection instead. + // We do this because children of features don't appear as subsections in the sidenav, but we want to highlight + // their parent's subsection as active. + if (feature?.parent) { + feature = features.find(f => f instanceof feature.parent); + } + if ( !feature || (!feature.category && !feature.topMenuItem && !feature.navigationItem) From b226f60ebd8af3e6bf0d1c5541c452a04e2476cc Mon Sep 17 00:00:00 2001 From: Yassine Bounekhla <56373201+rudream@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:07:00 -0500 Subject: [PATCH 06/27] update e ref (#51593) --- e | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e b/e index e57f5294b2c1c..4bdee5e5f2e38 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit e57f5294b2c1c5f3ba8d0871879106da4c2e117a +Subproject commit 4bdee5e5f2e38ba7fecdba5ea41c9dab86326293 From 9c412459a1f26c4344a9786faa268117c236bf8d Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Wed, 29 Jan 2025 13:09:11 -0300 Subject: [PATCH 07/27] [v17] feat: Allow alternative sudo path for NixOS (#51587) * Allow alternative sudo path for NixOS * Use logrus for logging --- lib/devicetrust/native/device_linux.go | 31 ++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/devicetrust/native/device_linux.go b/lib/devicetrust/native/device_linux.go index 07b1d3cb2cf86..69eb82845da51 100644 --- a/lib/devicetrust/native/device_linux.go +++ b/lib/devicetrust/native/device_linux.go @@ -265,10 +265,12 @@ func readDMIInfoEscalated() (*linux.DMIInfo, error) { return nil, trace.Wrap(err, "reading current executable") } + sudo := sudoPath() + // Run `sudo -v` first to re-authenticate, then run the actual tsh command // using `sudo --non-interactive`, so we don't risk getting sudo output // mixed with our desired output. - sudoCmd := exec.Command("/usr/bin/sudo", "-v") + sudoCmd := exec.Command(sudo, "-v") sudoCmd.Stdout = os.Stdout sudoCmd.Stderr = os.Stderr sudoCmd.Stdin = os.Stdin @@ -283,7 +285,7 @@ func readDMIInfoEscalated() (*linux.DMIInfo, error) { defer cancel() dmiOut := &bytes.Buffer{} - dmiCmd := exec.CommandContext(ctx, "/usr/bin/sudo", "-n", tshPath, "device", "dmi-read") + dmiCmd := exec.CommandContext(ctx, sudo, "-n", tshPath, "device", "dmi-read") dmiCmd.Stdout = dmiOut if err := dmiCmd.Run(); err != nil { return nil, trace.Wrap(err, "running `sudo tsh device dmi-read`") @@ -324,3 +326,28 @@ func saveDMIInfoToCache(dmiInfo *linux.DMIInfo) error { return nil } + +func sudoPath() string { + const defaultSudoPath = "/usr/bin/sudo" + + for i, path := range []string{ + defaultSudoPath, // preferred + + // Fallbacks are only allowed if /usr/bin/sudo does not exist. + // If it does exist, then it's used regardless of any other errors that may + // happen later. + "/run/wrappers/bin/sudo", // NixOS + } { + if _, err := os.Stat(path); err != nil { + log.WithError(err).WithField("path", path).Debug("Failed to stat sudo binary") + continue + } + if i > 0 { + log.WithField("path", path).Debug("Using alternative sudo path") + } + return path + } + + // If everything fails then use the default and hard-fail later. + return defaultSudoPath +} From fc448d112a19f4f366c8a5daef0f7b87da22c15a Mon Sep 17 00:00:00 2001 From: Noah Stride Date: Wed, 29 Jan 2025 17:45:41 +0000 Subject: [PATCH 08/27] [v17] Introduce `tsh workload-identity issue-x509` (#51597) * Start hacking on tsh support for new RPCs * Wire up to Run * Add test over new CLI command --- lib/auth/authclient/clt.go | 7 + lib/tbot/workloadidentity/issue.go | 7 +- tool/tsh/common/tsh.go | 9 +- tool/tsh/common/workload_identity.go | 191 ++++++++++++++++++++++ tool/tsh/common/workload_identity_test.go | 93 +++++++++++ 5 files changed, 303 insertions(+), 4 deletions(-) diff --git a/lib/auth/authclient/clt.go b/lib/auth/authclient/clt.go index 0657300951401..a8961866a46b4 100644 --- a/lib/auth/authclient/clt.go +++ b/lib/auth/authclient/clt.go @@ -56,6 +56,7 @@ import ( trustpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/trust/v1" userspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/users/v1" "github.com/gravitational/teleport/api/gen/proto/go/teleport/vnet/v1" + workloadidentityv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1" userpreferencesv1 "github.com/gravitational/teleport/api/gen/proto/go/userpreferences/v1" "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" @@ -1847,6 +1848,12 @@ type ClientI interface { // (as per the default gRPC behavior). WorkloadIdentityServiceClient() machineidv1pb.WorkloadIdentityServiceClient + // WorkloadIdentityIssuanceClient returns a workload identity issuance service client. + // Clients connecting to older Teleport versions, still get a client + // when calling this method, but all RPCs will return "not implemented" errors + // (as per the default gRPC behavior). + WorkloadIdentityIssuanceClient() workloadidentityv1pb.WorkloadIdentityIssuanceServiceClient + // NotificationServiceClient returns a notification service client. // Clients connecting to older Teleport versions, still get a client // when calling this method, but all RPCs will return "not implemented" errors diff --git a/lib/tbot/workloadidentity/issue.go b/lib/tbot/workloadidentity/issue.go index 5c3e46116b1b4..4f4710db22c74 100644 --- a/lib/tbot/workloadidentity/issue.go +++ b/lib/tbot/workloadidentity/issue.go @@ -68,12 +68,17 @@ func WorkloadIdentitiesLogValue(credentials []*workloadidentityv1pb.Credential) return values } +type authClient interface { + WorkloadIdentityIssuanceClient() workloadidentityv1pb.WorkloadIdentityIssuanceServiceClient + cryptosuites.AuthPreferenceGetter +} + // IssueX509WorkloadIdentity uses a given client and selector to issue a single // or multiple X509-SVID workload identity credentials. func IssueX509WorkloadIdentity( ctx context.Context, log *slog.Logger, - clt *authclient.Client, + clt authClient, workloadIdentity config.WorkloadIdentitySelector, ttl time.Duration, attest *workloadidentityv1pb.WorkloadAttrs, diff --git a/tool/tsh/common/tsh.go b/tool/tsh/common/tsh.go index 338ddb17750a6..3bbc7b9da1f08 100644 --- a/tool/tsh/common/tsh.go +++ b/tool/tsh/common/tsh.go @@ -1261,7 +1261,8 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { // Device Trust commands. deviceCmd := newDeviceCommand(app) - workloadIdentityCmd := newSVIDCommands(app) + svidCmd := newSVIDCommands(app) + workloadIdentityCmd := newWorkloadIdentityCommands(app) vnetCommand := newVnetCommand(app) vnetAdminSetupCommand := newVnetAdminSetupCommand(app) @@ -1639,8 +1640,10 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { err = onKubectlCommand(&cf, args, args[idx:]) case headlessApprove.FullCommand(): err = onHeadlessApprove(&cf) - case workloadIdentityCmd.issue.FullCommand(): - err = workloadIdentityCmd.issue.run(&cf) + case svidCmd.issue.FullCommand(): + err = svidCmd.issue.run(&cf) + case workloadIdentityCmd.issueX509.FullCommand(): + err = workloadIdentityCmd.issueX509.run(&cf) case vnetCommand.FullCommand(): err = vnetCommand.run(&cf) case vnetAdminSetupCommand.FullCommand(): diff --git a/tool/tsh/common/workload_identity.go b/tool/tsh/common/workload_identity.go index d46ce7cf63412..8a30b3f5c2033 100644 --- a/tool/tsh/common/workload_identity.go +++ b/tool/tsh/common/workload_identity.go @@ -33,12 +33,203 @@ import ( "github.com/gravitational/teleport" machineidv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" + workloadidentityv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/tbot/config" + "github.com/gravitational/teleport/lib/tbot/workloadidentity" ) +type workloadIdentityCommands struct { + issueX509 *issueX509Command +} + +func newWorkloadIdentityCommands( + app *kingpin.Application, +) workloadIdentityCommands { + cmd := app.Command("workload-identity", "Issue Workload Identity credentials") + cmds := workloadIdentityCommands{ + issueX509: newIssueX509Command(cmd), + } + return cmds +} + +type issueX509Command struct { + *kingpin.CmdClause + nameSelector string + labelSelector string + ttl time.Duration + outputDirectory string +} + +func newIssueX509Command(parent *kingpin.CmdClause) *issueX509Command { + cmd := &issueX509Command{ + CmdClause: parent.Command("issue-x509", "Use Teleport Workload Identity to issue an X509 credential write it to a local directory."), + } + + cmd.Flag( + "name-selector", + "The name of the workload identity to issue", + ).StringVar(&cmd.nameSelector) + cmd.Flag( + "label-selector", + "A label-based selector for which workload identities to issue. Multiple labels can be provided using ','.", + ).StringVar(&cmd.labelSelector) + cmd.Flag("credential-ttl", "Sets the time to live for the credential."). + Default("1h"). + DurationVar(&cmd.ttl) + cmd.Flag("output", "Path to the directory to write the SVID into."). + Required(). + StringVar(&cmd.outputDirectory) + + return cmd +} + +func (c *issueX509Command) run(cf *CLIConf) error { + ctx := cf.Context + + tc, err := makeClient(cf) + if err != nil { + return trace.Wrap(err) + } + tc.AllowHeadless = true + + selector := config.WorkloadIdentitySelector{} + switch { + case c.nameSelector != "" && c.labelSelector != "": + return trace.BadParameter("cannot specify both name and label selectors") + case c.nameSelector != "": + selector.Name = c.nameSelector + case c.labelSelector != "": + labels, err := client.ParseLabelSpec(c.labelSelector) + if err != nil { + return trace.Wrap(err) + } + selector.Labels = map[string][]string{} + for k, v := range labels { + selector.Labels[k] = []string{v} + } + default: + return trace.BadParameter("name-selector or label-selector must be specified") + } + + return client.RetryWithRelogin(ctx, tc, func() error { + clusterClient, err := tc.ConnectToCluster(ctx) + if err != nil { + return trace.Wrap(err) + } + defer clusterClient.Close() + + credentials, privateKey, err := workloadidentity.IssueX509WorkloadIdentity( + ctx, + logger, + clusterClient.AuthClient, + selector, + c.ttl, + nil, + ) + if err != nil { + return trace.Wrap(err) + } + var x509Credential *workloadidentityv1pb.Credential + switch len(credentials) { + case 0: + return trace.BadParameter("no X509 SVIDs returned") + case 1: + x509Credential = credentials[0] + default: + // We could eventually implement some kind of hint selection mechanism + // to pick the "right" one. + received := make([]string, 0, len(credentials)) + for _, cred := range credentials { + received = append(received, + fmt.Sprintf( + "%s:%s", + cred.WorkloadIdentityName, + cred.SpiffeId, + ), + ) + } + return trace.BadParameter( + "multiple X509 SVIDs received: %v", received, + ) + } + + // Write private key + privBytes, err := x509.MarshalPKCS8PrivateKey(privateKey) + if err != nil { + return trace.Wrap(err) + } + keyPath := filepath.Join(c.outputDirectory, svidKeyPEMPath) + err = os.WriteFile( + keyPath, + pem.EncodeToMemory(&pem.Block{ + Type: "PRIVATE KEY", + Bytes: privBytes, + }), + teleport.FileMaskOwnerOnly, + ) + if err != nil { + return trace.Wrap(err) + } + + // Write SVID + svidPath := filepath.Join(c.outputDirectory, svidPEMPath) + err = os.WriteFile( + svidPath, + pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: x509Credential.GetX509Svid().GetCert(), + }), + teleport.FileMaskOwnerOnly, + ) + if err != nil { + return trace.Wrap(err) + } + + // Write trust bundle + caRes, err := clusterClient.AuthClient.GetCertAuthorities( + ctx, types.SPIFFECA, false, + ) + if err != nil { + return trace.Wrap(err) + } + trustBundleBytes := &bytes.Buffer{} + for _, ca := range caRes { + for _, cert := range services.GetTLSCerts(ca) { + // Values are already PEM encoded, so we just append to the buffer + if _, err := trustBundleBytes.Write(cert); err != nil { + return trace.Wrap(err, "writing trust bundle to buffer") + } + } + } + trustBundlePath := filepath.Join(c.outputDirectory, svidTrustBundlePEMPath) + err = os.WriteFile( + trustBundlePath, + trustBundleBytes.Bytes(), + teleport.FileMaskOwnerOnly, + ) + if err != nil { + return trace.Wrap(err) + } + + fmt.Fprintf( + cf.Stdout(), + "SVID %q issued. Files written to: \n - %s\n - %s\n - %s\n", + x509Credential.SpiffeId, + keyPath, + svidPath, + trustBundlePath, + ) + + return nil + }) +} + +// svidCommands manages the SVID commands. +// Deprecated and being replaced by workloadIdentityCommands type svidCommands struct { issue *svidIssueCommand } diff --git a/tool/tsh/common/workload_identity_test.go b/tool/tsh/common/workload_identity_test.go index 04e73ce18f7e1..4cfa176c1ce5d 100644 --- a/tool/tsh/common/workload_identity_test.go +++ b/tool/tsh/common/workload_identity_test.go @@ -28,11 +28,16 @@ import ( "os" "path/filepath" "testing" + "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + workloadidentityv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/service/servicecfg" + "github.com/gravitational/teleport/lib/services" ) func TestWorkloadIdentityIssue(t *testing.T) { @@ -110,3 +115,91 @@ func TestWorkloadIdentityIssue(t *testing.T) { _, err = x509.ParseCertificate(bundleBlock.Bytes) require.NoError(t, err) } + +func TestWorkloadIdentityIssueX509(t *testing.T) { + ctx := context.Background() + + role, err := types.NewRole("workload-identity-issuer", types.RoleSpecV6{ + Allow: types.RoleConditions{ + WorkloadIdentityLabels: types.Labels{ + types.Wildcard: []string{types.Wildcard}, + }, + Rules: []types.Rule{ + types.NewRule(types.KindWorkloadIdentity, services.RO()), + }, + }, + }) + require.NoError(t, err) + s := newTestSuite(t, withRootConfigFunc(func(cfg *servicecfg.Config) { + // reconfig the user to use the new role instead of the default ones + // User is the second bootstrap resource. + user, ok := cfg.Auth.BootstrapResources[1].(types.User) + require.True(t, ok) + user.AddRole(role.GetName()) + cfg.Auth.BootstrapResources[1] = user + cfg.Auth.BootstrapResources = append(cfg.Auth.BootstrapResources, role) + })) + + _, err = s.root.GetAuthServer().Services.UpsertWorkloadIdentity( + ctx, + &workloadidentityv1pb.WorkloadIdentity{ + Kind: types.KindWorkloadIdentity, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: "my-workload-identity", + Labels: map[string]string{}, + }, + Spec: &workloadidentityv1pb.WorkloadIdentitySpec{ + Spiffe: &workloadidentityv1pb.WorkloadIdentitySPIFFE{ + Id: "/test", + }, + }, + }, + ) + require.NoError(t, err) + require.EventuallyWithT(t, func(collect *assert.CollectT) { + _, err := s.root.GetAuthServer().Cache.GetWorkloadIdentity(ctx, "my-workload-identity") + require.NoError(collect, err) + }, time.Second*5, 100*time.Millisecond) + + homeDir, _ := mustLoginLegacy(t, s) + temp := t.TempDir() + err = Run( + ctx, + []string{ + "workload-identity", + "issue-x509", + "--insecure", + "--output", temp, + "--credential-ttl", "10m", + "--name-selector", "my-workload-identity", + }, + setHomePath(homeDir), + ) + require.NoError(t, err) + + certPEM, err := os.ReadFile(filepath.Join(temp, "svid.pem")) + require.NoError(t, err) + certBlock, _ := pem.Decode(certPEM) + cert, err := x509.ParseCertificate(certBlock.Bytes) + require.NoError(t, err) + require.Equal(t, "spiffe://root/test", cert.URIs[0].String()) + // Sanity check we generated an ECDSA public key (test suite uses + // balanced-v1 algorithm suite). + require.IsType(t, &ecdsa.PublicKey{}, cert.PublicKey) + + keyPEM, err := os.ReadFile(filepath.Join(temp, "svid_key.pem")) + require.NoError(t, err) + keyBlock, _ := pem.Decode(keyPEM) + privateKey, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes) + require.NoError(t, err) + // Sanity check private key matches x509 cert subject. + require.Implements(t, (*crypto.Signer)(nil), privateKey) + require.Equal(t, cert.PublicKey, privateKey.(crypto.Signer).Public()) + + bundlePEM, err := os.ReadFile(filepath.Join(temp, "svid_bundle.pem")) + require.NoError(t, err) + bundleBlock, _ := pem.Decode(bundlePEM) + _, err = x509.ParseCertificate(bundleBlock.Bytes) + require.NoError(t, err) +} From 6d7421ffa1920ff317c3c859a0029c451dc75eb2 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Wed, 29 Jan 2025 19:53:11 +0000 Subject: [PATCH 09/27] [v17] backport netiq implementation (#51541) * netiq: Add NetIQ plugin boilerplate code (#50476) This PR introduces the necessary protobuf changes to accomodate NetIQ plugin. Part of https://github.com/gravitational/access-graph/issues/634 Signed-off-by: Tiago Silva * netiq: add access graph protobufs (#50477) * netiq: add access graph protobufs This PR introduces the necessary protobuf changes to accommodate Access Graph receiving NetIQ stream of changes. Part of https://github.com/gravitational/access-graph/issues/634 Signed-off-by: Tiago Silva * Update netiq.proto Co-authored-by: Gabriel Corado --------- Signed-off-by: Tiago Silva Co-authored-by: Gabriel Corado * netiq: Expose `GetNetIq` method in `PluginStatus` (#51285) This PR exposes the `GetNetIq` method in `PluginStatus` interface to be used in `e`. Signed-off-by: Tiago Silva * netiq: return type from netiq spec (#51290) * fix typo * netiq: add plugin install prompt (#51502) * netiq: add plugin install prompt This PR adds the plugin prompt code to read the required parameters to create the netiq plugin. Part of https://github.com/gravitational/access-graph/issues/634 Signed-off-by: Tiago Silva * add license * Update netiq.go Co-authored-by: Gavin Frazar * Update netiq.go Co-authored-by: Gavin Frazar * Update netiq.go Co-authored-by: Gavin Frazar * handle review comments * Apply suggestions from code review Co-authored-by: Gavin Frazar * Apply suggestions from code review Co-authored-by: Gavin Frazar * consolidate prompt methods --------- Signed-off-by: Tiago Silva Co-authored-by: Gavin Frazar --------- Signed-off-by: Tiago Silva Co-authored-by: Gabriel Corado Co-authored-by: Gavin Frazar --- api/proto/teleport/legacy/types/types.proto | 28 + api/types/plugin.go | 39 + api/types/plugin_test.go | 75 + api/types/types.pb.go | 4813 ++++++++++------- api/utils/prompt/confirmation.go | 43 + api/utils/prompt/context_reader_test.go | 84 + .../v1alpha/access_graph_service.pb.go | 682 ++- .../v1alpha/access_graph_service_grpc.pb.go | 34 + gen/proto/go/accessgraph/v1alpha/netiq.pb.go | 1324 +++++ .../v1alpha/access_graph_service.proto | 23 + proto/accessgraph/v1alpha/netiq.proto | 187 + tool/tctl/common/plugin/netiq.go | 520 ++ tool/tctl/common/plugin/plugins_command.go | 4 + 13 files changed, 5582 insertions(+), 2274 deletions(-) create mode 100644 gen/proto/go/accessgraph/v1alpha/netiq.pb.go create mode 100644 proto/accessgraph/v1alpha/netiq.proto create mode 100644 tool/tctl/common/plugin/netiq.go diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index dc3b5a19e3ff3..2c02db80ce69a 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -6455,6 +6455,8 @@ message PluginSpecV1 { PluginEmailSettings email = 17; // Settings for the Microsoft Teams plugin PluginMSTeamsSettings msteams = 18; + // Settings for the OpenTex NetIQ plugin. + PluginNetIQSettings net_iq = 19; } // generation contains a unique ID that should: @@ -6945,6 +6947,18 @@ message PluginMSTeamsSettings { string default_recipient = 5; } +// PluginNetIQSettings defines the settings for a NetIQ integration plugin +message PluginNetIQSettings { + option (gogoproto.equal) = true; + // oauth_issuer_endpoint is the NetIQ Oauth Issuer endpoint. + // Usually, it's equal to https://osp.domain.ext/a/idm/auth/oauth2 + string oauth_issuer_endpoint = 1; + // api_endpoint is the IDM PROV Rest API location. + string api_endpoint = 2; + // insecure_skip_verify controls whether the NetIQ certificate validation should be skipped. + bool insecure_skip_verify = 3; +} + message PluginBootstrapCredentialsV1 { oneof credentials { PluginOAuth2AuthorizationCodeCredentials oauth2_authorization_code = 1; @@ -6983,6 +6997,8 @@ message PluginStatusV1 { PluginOktaStatusV1 okta = 7; // AWSIC holds status details for the AWS Identity Center plugin. PluginAWSICStatusV1 aws_ic = 8; + // NetIQ holds status details for the NetIQ plugin. + PluginNetIQStatusV1 net_iq = 9; } // last_raw_error variable stores the most recent raw error message received from an API or service. @@ -6992,6 +7008,18 @@ message PluginStatusV1 { string last_raw_error = 6; } +// PluginNetIQStatusV1 is the status details for the NetIQ plugin. +message PluginNetIQStatusV1 { + // imported_users is the number of users imported from NetIQ eDirectory. + uint32 imported_users = 1; + // imported_groups is the number of groups imported from NetIQ eDirectory. + uint32 imported_groups = 2; + // imported_roles is the number of roles imported from NetIQ eDirectory. + uint32 imported_roles = 3; + // imported_resources is the number of resources imported from NetIQ eDirectory. + uint32 imported_resources = 4; +} + // PluginGitlabStatusV1 is the status details for the Gitlab plugin. message PluginGitlabStatusV1 { // imported_users is the number of users imported from Gitlab. diff --git a/api/types/plugin.go b/api/types/plugin.go index 0faaaec791d0c..bc0c0943724c5 100644 --- a/api/types/plugin.go +++ b/api/types/plugin.go @@ -17,6 +17,7 @@ limitations under the License. package types import ( + "net/url" "time" "github.com/gravitational/trace" @@ -83,6 +84,8 @@ const ( PluginTypeEmail = "email" // PluginTypeMSTeams indicates a Microsoft Teams integration PluginTypeMSTeams = "msteams" + // PluginTypeNetIQ indicates a NetIQ integration + PluginTypeNetIQ = "netiq" ) // PluginSubkind represents the type of the plugin, e.g., access request, MDM etc. @@ -131,6 +134,7 @@ type PluginStatus interface { GetEntraId() *PluginEntraIDStatusV1 GetOkta() *PluginOktaStatusV1 GetAwsIc() *PluginAWSICStatusV1 + GetNetIq() *PluginNetIQStatusV1 } // NewPluginV1 creates a new PluginV1 resource. @@ -377,6 +381,20 @@ func (p *PluginV1) CheckAndSetDefaults() error { if len(staticCreds.Labels) == 0 { return trace.BadParameter("labels must be specified") } + case *PluginSpecV1_NetIq: + if settings.NetIq == nil { + return trace.BadParameter("missing NetIQ settings") + } + if err := settings.NetIq.Validate(); err != nil { + return trace.Wrap(err) + } + staticCreds := p.Credentials.GetStaticCredentialsRef() + if staticCreds == nil { + return trace.BadParameter("NetIQ plugin must be used with the static credentials ref type") + } + if len(staticCreds.Labels) == 0 { + return trace.BadParameter("labels must be specified") + } default: return nil } @@ -547,6 +565,8 @@ func (p *PluginV1) GetType() PluginType { return PluginTypeEmail case *PluginSpecV1_Msteams: return PluginTypeMSTeams + case *PluginSpecV1_NetIq: + return PluginTypeNetIQ default: return PluginTypeUnknown } @@ -843,3 +863,22 @@ func (c *PluginGitlabSettings) Validate() error { return nil } + +func (c *PluginNetIQSettings) Validate() error { + if c.OauthIssuerEndpoint == "" { + return trace.BadParameter("oauth_issuer endpoint must be set") + } + + if _, err := url.Parse(c.OauthIssuerEndpoint); err != nil { + return trace.BadParameter("oauth_issuer endpoint must be a valid URL") + } + + if c.ApiEndpoint == "" { + return trace.BadParameter("api_endpoint must be set") + } + if _, err := url.Parse(c.ApiEndpoint); err != nil { + return trace.BadParameter("api_endpoint endpoint must be a valid URL") + } + + return nil +} diff --git a/api/types/plugin_test.go b/api/types/plugin_test.go index ec0b37cb184fd..c9c21c7ab7f9c 100644 --- a/api/types/plugin_test.go +++ b/api/types/plugin_test.go @@ -1343,3 +1343,78 @@ func TestPluginEmailSettings(t *testing.T) { }) } } + +func TestNetIQPluginSettings(t *testing.T) { + + validSettings := func() *PluginSpecV1_NetIq { + return &PluginSpecV1_NetIq{ + NetIq: &PluginNetIQSettings{ + OauthIssuerEndpoint: "https://example.com", + ApiEndpoint: "https://example.com", + }, + } + } + testCases := []struct { + name string + mutateSettings func(*PluginSpecV1_NetIq) + assertErr require.ErrorAssertionFunc + }{ + { + name: "valid", + mutateSettings: nil, + assertErr: require.NoError, + }, + { + name: "missing OauthIssuer", + mutateSettings: func(s *PluginSpecV1_NetIq) { + s.NetIq.OauthIssuerEndpoint = "" + }, + assertErr: requireNamedBadParameterError("oauth_issuer"), + }, + { + name: "missing ApiEndpoint", + mutateSettings: func(s *PluginSpecV1_NetIq) { + s.NetIq.ApiEndpoint = "" + }, + assertErr: requireNamedBadParameterError("api_endpoint"), + }, + { + name: "incorrect OauthIssuer", + mutateSettings: func(s *PluginSpecV1_NetIq) { + s.NetIq.OauthIssuerEndpoint = "invalidURL%%#" + }, + assertErr: requireNamedBadParameterError("oauth_issuer"), + }, + { + name: "missing ApiEndpoint", + mutateSettings: func(s *PluginSpecV1_NetIq) { + s.NetIq.ApiEndpoint = "invalidURL%%#" + }, + assertErr: requireNamedBadParameterError("api_endpoint"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + settings := validSettings() + if tc.mutateSettings != nil { + tc.mutateSettings(settings) + } + + plugin := NewPluginV1( + Metadata{Name: "uut"}, + PluginSpecV1{Settings: settings}, + &PluginCredentialsV1{ + Credentials: &PluginCredentialsV1_StaticCredentialsRef{ + StaticCredentialsRef: &PluginStaticCredentialsRef{ + Labels: map[string]string{ + "label1": "value1", + }, + }, + }, + }) + tc.assertErr(t, plugin.CheckAndSetDefaults()) + }) + } + +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 502c90f7a2356..1922be6a9b089 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -1263,7 +1263,7 @@ func (x OktaAssignmentSpecV1_OktaAssignmentStatus) String() string { } func (OktaAssignmentSpecV1_OktaAssignmentStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{346, 0} + return fileDescriptor_9198ee693835762e, []int{348, 0} } // OktaAssignmentTargetType is the type of Okta object that an assignment is targeting. @@ -1295,7 +1295,7 @@ func (x OktaAssignmentTargetV1_OktaAssignmentTargetType) String() string { } func (OktaAssignmentTargetV1_OktaAssignmentTargetType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{347, 0} + return fileDescriptor_9198ee693835762e, []int{349, 0} } type KeepAlive struct { @@ -16215,6 +16215,7 @@ type PluginSpecV1 struct { // *PluginSpecV1_AwsIc // *PluginSpecV1_Email // *PluginSpecV1_Msteams + // *PluginSpecV1_NetIq Settings isPluginSpecV1_Settings `protobuf_oneof:"settings"` // generation contains a unique ID that should: // - Be created by the backend on plugin creation. @@ -16318,6 +16319,9 @@ type PluginSpecV1_Email struct { type PluginSpecV1_Msteams struct { Msteams *PluginMSTeamsSettings `protobuf:"bytes,18,opt,name=msteams,proto3,oneof" json:"msteams,omitempty"` } +type PluginSpecV1_NetIq struct { + NetIq *PluginNetIQSettings `protobuf:"bytes,19,opt,name=net_iq,json=netIq,proto3,oneof" json:"net_iq,omitempty"` +} func (*PluginSpecV1_SlackAccessPlugin) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Opsgenie) isPluginSpecV1_Settings() {} @@ -16336,6 +16340,7 @@ func (*PluginSpecV1_Datadog) isPluginSpecV1_Settings() {} func (*PluginSpecV1_AwsIc) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Email) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Msteams) isPluginSpecV1_Settings() {} +func (*PluginSpecV1_NetIq) isPluginSpecV1_Settings() {} func (m *PluginSpecV1) GetSettings() isPluginSpecV1_Settings { if m != nil { @@ -16463,6 +16468,13 @@ func (m *PluginSpecV1) GetMsteams() *PluginMSTeamsSettings { return nil } +func (m *PluginSpecV1) GetNetIq() *PluginNetIQSettings { + if x, ok := m.GetSettings().(*PluginSpecV1_NetIq); ok { + return x.NetIq + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*PluginSpecV1) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -16483,6 +16495,7 @@ func (*PluginSpecV1) XXX_OneofWrappers() []interface{} { (*PluginSpecV1_AwsIc)(nil), (*PluginSpecV1_Email)(nil), (*PluginSpecV1_Msteams)(nil), + (*PluginSpecV1_NetIq)(nil), } } @@ -18020,6 +18033,53 @@ func (m *PluginMSTeamsSettings) XXX_DiscardUnknown() { var xxx_messageInfo_PluginMSTeamsSettings proto.InternalMessageInfo +// PluginNetIQSettings defines the settings for a NetIQ integration plugin +type PluginNetIQSettings struct { + // oauth_issuer_endpoint is the NetIQ Oauth Issuer endpoint. + // Usually, it's equal to https://osp.domain.ext/a/idm/auth/oauth2 + OauthIssuerEndpoint string `protobuf:"bytes,1,opt,name=oauth_issuer_endpoint,json=oauthIssuerEndpoint,proto3" json:"oauth_issuer_endpoint,omitempty"` + // api_endpoint is the IDM PROV Rest API location. + ApiEndpoint string `protobuf:"bytes,2,opt,name=api_endpoint,json=apiEndpoint,proto3" json:"api_endpoint,omitempty"` + // insecure_skip_verify controls whether the NetIQ certificate validation should be skipped. + InsecureSkipVerify bool `protobuf:"varint,3,opt,name=insecure_skip_verify,json=insecureSkipVerify,proto3" json:"insecure_skip_verify,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PluginNetIQSettings) Reset() { *m = PluginNetIQSettings{} } +func (m *PluginNetIQSettings) String() string { return proto.CompactTextString(m) } +func (*PluginNetIQSettings) ProtoMessage() {} +func (*PluginNetIQSettings) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{305} +} +func (m *PluginNetIQSettings) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PluginNetIQSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PluginNetIQSettings.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 *PluginNetIQSettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_PluginNetIQSettings.Merge(m, src) +} +func (m *PluginNetIQSettings) XXX_Size() int { + return m.Size() +} +func (m *PluginNetIQSettings) XXX_DiscardUnknown() { + xxx_messageInfo_PluginNetIQSettings.DiscardUnknown(m) +} + +var xxx_messageInfo_PluginNetIQSettings proto.InternalMessageInfo + type PluginBootstrapCredentialsV1 struct { // Types that are valid to be assigned to Credentials: // @@ -18036,7 +18096,7 @@ func (m *PluginBootstrapCredentialsV1) Reset() { *m = PluginBootstrapCre func (m *PluginBootstrapCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginBootstrapCredentialsV1) ProtoMessage() {} func (*PluginBootstrapCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{305} + return fileDescriptor_9198ee693835762e, []int{306} } func (m *PluginBootstrapCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18136,7 +18196,7 @@ func (m *PluginIdSecretCredential) Reset() { *m = PluginIdSecretCredenti func (m *PluginIdSecretCredential) String() string { return proto.CompactTextString(m) } func (*PluginIdSecretCredential) ProtoMessage() {} func (*PluginIdSecretCredential) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{306} + return fileDescriptor_9198ee693835762e, []int{307} } func (m *PluginIdSecretCredential) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18179,7 +18239,7 @@ func (m *PluginOAuth2AuthorizationCodeCredentials) Reset() { func (m *PluginOAuth2AuthorizationCodeCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AuthorizationCodeCredentials) ProtoMessage() {} func (*PluginOAuth2AuthorizationCodeCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{307} + return fileDescriptor_9198ee693835762e, []int{308} } func (m *PluginOAuth2AuthorizationCodeCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18223,6 +18283,7 @@ type PluginStatusV1 struct { // *PluginStatusV1_EntraId // *PluginStatusV1_Okta // *PluginStatusV1_AwsIc + // *PluginStatusV1_NetIq Details isPluginStatusV1_Details `protobuf_oneof:"details"` // last_raw_error variable stores the most recent raw error message received from an API or service. // It is intended to capture the original error message without any modifications or formatting. @@ -18238,7 +18299,7 @@ func (m *PluginStatusV1) Reset() { *m = PluginStatusV1{} } func (m *PluginStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginStatusV1) ProtoMessage() {} func (*PluginStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{308} + return fileDescriptor_9198ee693835762e, []int{309} } func (m *PluginStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18285,11 +18346,15 @@ type PluginStatusV1_Okta struct { type PluginStatusV1_AwsIc struct { AwsIc *PluginAWSICStatusV1 `protobuf:"bytes,8,opt,name=aws_ic,json=awsIc,proto3,oneof" json:"aws_ic,omitempty"` } +type PluginStatusV1_NetIq struct { + NetIq *PluginNetIQStatusV1 `protobuf:"bytes,9,opt,name=net_iq,json=netIq,proto3,oneof" json:"net_iq,omitempty"` +} func (*PluginStatusV1_Gitlab) isPluginStatusV1_Details() {} func (*PluginStatusV1_EntraId) isPluginStatusV1_Details() {} func (*PluginStatusV1_Okta) isPluginStatusV1_Details() {} func (*PluginStatusV1_AwsIc) isPluginStatusV1_Details() {} +func (*PluginStatusV1_NetIq) isPluginStatusV1_Details() {} func (m *PluginStatusV1) GetDetails() isPluginStatusV1_Details { if m != nil { @@ -18326,6 +18391,13 @@ func (m *PluginStatusV1) GetAwsIc() *PluginAWSICStatusV1 { return nil } +func (m *PluginStatusV1) GetNetIq() *PluginNetIQStatusV1 { + if x, ok := m.GetDetails().(*PluginStatusV1_NetIq); ok { + return x.NetIq + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*PluginStatusV1) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -18333,9 +18405,58 @@ func (*PluginStatusV1) XXX_OneofWrappers() []interface{} { (*PluginStatusV1_EntraId)(nil), (*PluginStatusV1_Okta)(nil), (*PluginStatusV1_AwsIc)(nil), + (*PluginStatusV1_NetIq)(nil), } } +// PluginNetIQStatusV1 is the status details for the NetIQ plugin. +type PluginNetIQStatusV1 struct { + // imported_users is the number of users imported from NetIQ eDirectory. + ImportedUsers uint32 `protobuf:"varint,1,opt,name=imported_users,json=importedUsers,proto3" json:"imported_users,omitempty"` + // imported_groups is the number of groups imported from NetIQ eDirectory. + ImportedGroups uint32 `protobuf:"varint,2,opt,name=imported_groups,json=importedGroups,proto3" json:"imported_groups,omitempty"` + // imported_roles is the number of roles imported from NetIQ eDirectory. + ImportedRoles uint32 `protobuf:"varint,3,opt,name=imported_roles,json=importedRoles,proto3" json:"imported_roles,omitempty"` + // imported_resources is the number of resources imported from NetIQ eDirectory. + ImportedResources uint32 `protobuf:"varint,4,opt,name=imported_resources,json=importedResources,proto3" json:"imported_resources,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PluginNetIQStatusV1) Reset() { *m = PluginNetIQStatusV1{} } +func (m *PluginNetIQStatusV1) String() string { return proto.CompactTextString(m) } +func (*PluginNetIQStatusV1) ProtoMessage() {} +func (*PluginNetIQStatusV1) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{310} +} +func (m *PluginNetIQStatusV1) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PluginNetIQStatusV1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PluginNetIQStatusV1.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 *PluginNetIQStatusV1) XXX_Merge(src proto.Message) { + xxx_messageInfo_PluginNetIQStatusV1.Merge(m, src) +} +func (m *PluginNetIQStatusV1) XXX_Size() int { + return m.Size() +} +func (m *PluginNetIQStatusV1) XXX_DiscardUnknown() { + xxx_messageInfo_PluginNetIQStatusV1.DiscardUnknown(m) +} + +var xxx_messageInfo_PluginNetIQStatusV1 proto.InternalMessageInfo + // PluginGitlabStatusV1 is the status details for the Gitlab plugin. type PluginGitlabStatusV1 struct { // imported_users is the number of users imported from Gitlab. @@ -18353,7 +18474,7 @@ func (m *PluginGitlabStatusV1) Reset() { *m = PluginGitlabStatusV1{} } func (m *PluginGitlabStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginGitlabStatusV1) ProtoMessage() {} func (*PluginGitlabStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{309} + return fileDescriptor_9198ee693835762e, []int{311} } func (m *PluginGitlabStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18397,7 +18518,7 @@ func (m *PluginEntraIDStatusV1) Reset() { *m = PluginEntraIDStatusV1{} } func (m *PluginEntraIDStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDStatusV1) ProtoMessage() {} func (*PluginEntraIDStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{310} + return fileDescriptor_9198ee693835762e, []int{312} } func (m *PluginEntraIDStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18451,7 +18572,7 @@ func (m *PluginOktaStatusV1) Reset() { *m = PluginOktaStatusV1{} } func (m *PluginOktaStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusV1) ProtoMessage() {} func (*PluginOktaStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{311} + return fileDescriptor_9198ee693835762e, []int{313} } func (m *PluginOktaStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18499,7 +18620,7 @@ func (m *PluginOktaStatusDetailsSSO) Reset() { *m = PluginOktaStatusDeta func (m *PluginOktaStatusDetailsSSO) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsSSO) ProtoMessage() {} func (*PluginOktaStatusDetailsSSO) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{312} + return fileDescriptor_9198ee693835762e, []int{314} } func (m *PluginOktaStatusDetailsSSO) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18556,7 +18677,7 @@ func (m *PluginOktaStatusDetailsAppGroupSync) Reset() { *m = PluginOktaS func (m *PluginOktaStatusDetailsAppGroupSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsAppGroupSync) ProtoMessage() {} func (*PluginOktaStatusDetailsAppGroupSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{313} + return fileDescriptor_9198ee693835762e, []int{315} } func (m *PluginOktaStatusDetailsAppGroupSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18610,7 +18731,7 @@ func (m *PluginOktaStatusDetailsUsersSync) Reset() { *m = PluginOktaStat func (m *PluginOktaStatusDetailsUsersSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsUsersSync) ProtoMessage() {} func (*PluginOktaStatusDetailsUsersSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{314} + return fileDescriptor_9198ee693835762e, []int{316} } func (m *PluginOktaStatusDetailsUsersSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18653,7 +18774,7 @@ func (m *PluginOktaStatusDetailsSCIM) Reset() { *m = PluginOktaStatusDet func (m *PluginOktaStatusDetailsSCIM) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsSCIM) ProtoMessage() {} func (*PluginOktaStatusDetailsSCIM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{315} + return fileDescriptor_9198ee693835762e, []int{317} } func (m *PluginOktaStatusDetailsSCIM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18715,7 +18836,7 @@ func (m *PluginOktaStatusDetailsAccessListsSync) Reset() { func (m *PluginOktaStatusDetailsAccessListsSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsAccessListsSync) ProtoMessage() {} func (*PluginOktaStatusDetailsAccessListsSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{316} + return fileDescriptor_9198ee693835762e, []int{318} } func (m *PluginOktaStatusDetailsAccessListsSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18763,7 +18884,7 @@ func (m *PluginCredentialsV1) Reset() { *m = PluginCredentialsV1{} } func (m *PluginCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginCredentialsV1) ProtoMessage() {} func (*PluginCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{317} + return fileDescriptor_9198ee693835762e, []int{319} } func (m *PluginCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18874,7 +18995,7 @@ func (m *PluginOAuth2AccessTokenCredentials) Reset() { *m = PluginOAuth2 func (m *PluginOAuth2AccessTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AccessTokenCredentials) ProtoMessage() {} func (*PluginOAuth2AccessTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{318} + return fileDescriptor_9198ee693835762e, []int{320} } func (m *PluginOAuth2AccessTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18915,7 +19036,7 @@ func (m *PluginBearerTokenCredentials) Reset() { *m = PluginBearerTokenC func (m *PluginBearerTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginBearerTokenCredentials) ProtoMessage() {} func (*PluginBearerTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{319} + return fileDescriptor_9198ee693835762e, []int{321} } func (m *PluginBearerTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18957,7 +19078,7 @@ func (m *PluginStaticCredentialsRef) Reset() { *m = PluginStaticCredenti func (m *PluginStaticCredentialsRef) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsRef) ProtoMessage() {} func (*PluginStaticCredentialsRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{320} + return fileDescriptor_9198ee693835762e, []int{322} } func (m *PluginStaticCredentialsRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18999,7 +19120,7 @@ func (m *PluginListV1) Reset() { *m = PluginListV1{} } func (m *PluginListV1) String() string { return proto.CompactTextString(m) } func (*PluginListV1) ProtoMessage() {} func (*PluginListV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{321} + return fileDescriptor_9198ee693835762e, []int{323} } func (m *PluginListV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19042,7 +19163,7 @@ type PluginStaticCredentialsV1 struct { func (m *PluginStaticCredentialsV1) Reset() { *m = PluginStaticCredentialsV1{} } func (*PluginStaticCredentialsV1) ProtoMessage() {} func (*PluginStaticCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{322} + return fileDescriptor_9198ee693835762e, []int{324} } func (m *PluginStaticCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19089,7 +19210,7 @@ func (m *PluginStaticCredentialsSpecV1) Reset() { *m = PluginStaticCrede func (m *PluginStaticCredentialsSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsSpecV1) ProtoMessage() {} func (*PluginStaticCredentialsSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{323} + return fileDescriptor_9198ee693835762e, []int{325} } func (m *PluginStaticCredentialsSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19204,7 +19325,7 @@ func (m *PluginStaticCredentialsBasicAuth) Reset() { *m = PluginStaticCr func (m *PluginStaticCredentialsBasicAuth) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsBasicAuth) ProtoMessage() {} func (*PluginStaticCredentialsBasicAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{324} + return fileDescriptor_9198ee693835762e, []int{326} } func (m *PluginStaticCredentialsBasicAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19250,7 +19371,7 @@ func (m *PluginStaticCredentialsOAuthClientSecret) Reset() { func (m *PluginStaticCredentialsOAuthClientSecret) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsOAuthClientSecret) ProtoMessage() {} func (*PluginStaticCredentialsOAuthClientSecret) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{325} + return fileDescriptor_9198ee693835762e, []int{327} } func (m *PluginStaticCredentialsOAuthClientSecret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19298,7 +19419,7 @@ func (m *PluginStaticCredentialsSSHCertAuthorities) String() string { } func (*PluginStaticCredentialsSSHCertAuthorities) ProtoMessage() {} func (*PluginStaticCredentialsSSHCertAuthorities) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{326} + return fileDescriptor_9198ee693835762e, []int{328} } func (m *PluginStaticCredentialsSSHCertAuthorities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19341,7 +19462,7 @@ type SAMLIdPServiceProviderV1 struct { func (m *SAMLIdPServiceProviderV1) Reset() { *m = SAMLIdPServiceProviderV1{} } func (*SAMLIdPServiceProviderV1) ProtoMessage() {} func (*SAMLIdPServiceProviderV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{327} + return fileDescriptor_9198ee693835762e, []int{329} } func (m *SAMLIdPServiceProviderV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19412,7 +19533,7 @@ func (m *SAMLIdPServiceProviderSpecV1) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderSpecV1) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderSpecV1) ProtoMessage() {} func (*SAMLIdPServiceProviderSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{328} + return fileDescriptor_9198ee693835762e, []int{330} } func (m *SAMLIdPServiceProviderSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19459,7 +19580,7 @@ func (m *SAMLAttributeMapping) Reset() { *m = SAMLAttributeMapping{} } func (m *SAMLAttributeMapping) String() string { return proto.CompactTextString(m) } func (*SAMLAttributeMapping) ProtoMessage() {} func (*SAMLAttributeMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{329} + return fileDescriptor_9198ee693835762e, []int{331} } func (m *SAMLAttributeMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19501,7 +19622,7 @@ func (m *IdPOptions) Reset() { *m = IdPOptions{} } func (m *IdPOptions) String() string { return proto.CompactTextString(m) } func (*IdPOptions) ProtoMessage() {} func (*IdPOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{330} + return fileDescriptor_9198ee693835762e, []int{332} } func (m *IdPOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19543,7 +19664,7 @@ func (m *IdPSAMLOptions) Reset() { *m = IdPSAMLOptions{} } func (m *IdPSAMLOptions) String() string { return proto.CompactTextString(m) } func (*IdPSAMLOptions) ProtoMessage() {} func (*IdPSAMLOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{331} + return fileDescriptor_9198ee693835762e, []int{333} } func (m *IdPSAMLOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19593,7 +19714,7 @@ func (m *KubernetesResourceV1) Reset() { *m = KubernetesResourceV1{} } func (m *KubernetesResourceV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceV1) ProtoMessage() {} func (*KubernetesResourceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{332} + return fileDescriptor_9198ee693835762e, []int{334} } func (m *KubernetesResourceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19635,7 +19756,7 @@ func (m *KubernetesResourceSpecV1) Reset() { *m = KubernetesResourceSpec func (m *KubernetesResourceSpecV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceSpecV1) ProtoMessage() {} func (*KubernetesResourceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{333} + return fileDescriptor_9198ee693835762e, []int{335} } func (m *KubernetesResourceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19681,7 +19802,7 @@ func (m *ClusterMaintenanceConfigV1) Reset() { *m = ClusterMaintenanceCo func (m *ClusterMaintenanceConfigV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigV1) ProtoMessage() {} func (*ClusterMaintenanceConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{334} + return fileDescriptor_9198ee693835762e, []int{336} } func (m *ClusterMaintenanceConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19723,7 +19844,7 @@ func (m *ClusterMaintenanceConfigSpecV1) Reset() { *m = ClusterMaintenan func (m *ClusterMaintenanceConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigSpecV1) ProtoMessage() {} func (*ClusterMaintenanceConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{335} + return fileDescriptor_9198ee693835762e, []int{337} } func (m *ClusterMaintenanceConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19769,7 +19890,7 @@ func (m *AgentUpgradeWindow) Reset() { *m = AgentUpgradeWindow{} } func (m *AgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeWindow) ProtoMessage() {} func (*AgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{336} + return fileDescriptor_9198ee693835762e, []int{338} } func (m *AgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19816,7 +19937,7 @@ func (m *ScheduledAgentUpgradeWindow) Reset() { *m = ScheduledAgentUpgra func (m *ScheduledAgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*ScheduledAgentUpgradeWindow) ProtoMessage() {} func (*ScheduledAgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{337} + return fileDescriptor_9198ee693835762e, []int{339} } func (m *ScheduledAgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19859,7 +19980,7 @@ func (m *AgentUpgradeSchedule) Reset() { *m = AgentUpgradeSchedule{} } func (m *AgentUpgradeSchedule) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeSchedule) ProtoMessage() {} func (*AgentUpgradeSchedule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{338} + return fileDescriptor_9198ee693835762e, []int{340} } func (m *AgentUpgradeSchedule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19902,7 +20023,7 @@ type UserGroupV1 struct { func (m *UserGroupV1) Reset() { *m = UserGroupV1{} } func (*UserGroupV1) ProtoMessage() {} func (*UserGroupV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{339} + return fileDescriptor_9198ee693835762e, []int{341} } func (m *UserGroupV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19944,7 +20065,7 @@ func (m *UserGroupSpecV1) Reset() { *m = UserGroupSpecV1{} } func (m *UserGroupSpecV1) String() string { return proto.CompactTextString(m) } func (*UserGroupSpecV1) ProtoMessage() {} func (*UserGroupSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{340} + return fileDescriptor_9198ee693835762e, []int{342} } func (m *UserGroupSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19988,7 +20109,7 @@ func (m *OktaImportRuleSpecV1) Reset() { *m = OktaImportRuleSpecV1{} } func (m *OktaImportRuleSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleSpecV1) ProtoMessage() {} func (*OktaImportRuleSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{341} + return fileDescriptor_9198ee693835762e, []int{343} } func (m *OktaImportRuleSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20032,7 +20153,7 @@ func (m *OktaImportRuleMappingV1) Reset() { *m = OktaImportRuleMappingV1 func (m *OktaImportRuleMappingV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMappingV1) ProtoMessage() {} func (*OktaImportRuleMappingV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{342} + return fileDescriptor_9198ee693835762e, []int{344} } func (m *OktaImportRuleMappingV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20075,7 +20196,7 @@ type OktaImportRuleV1 struct { func (m *OktaImportRuleV1) Reset() { *m = OktaImportRuleV1{} } func (*OktaImportRuleV1) ProtoMessage() {} func (*OktaImportRuleV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{343} + return fileDescriptor_9198ee693835762e, []int{345} } func (m *OktaImportRuleV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20123,7 +20244,7 @@ func (m *OktaImportRuleMatchV1) Reset() { *m = OktaImportRuleMatchV1{} } func (m *OktaImportRuleMatchV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMatchV1) ProtoMessage() {} func (*OktaImportRuleMatchV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{344} + return fileDescriptor_9198ee693835762e, []int{346} } func (m *OktaImportRuleMatchV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20166,7 +20287,7 @@ type OktaAssignmentV1 struct { func (m *OktaAssignmentV1) Reset() { *m = OktaAssignmentV1{} } func (*OktaAssignmentV1) ProtoMessage() {} func (*OktaAssignmentV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{345} + return fileDescriptor_9198ee693835762e, []int{347} } func (m *OktaAssignmentV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20220,7 +20341,7 @@ func (m *OktaAssignmentSpecV1) Reset() { *m = OktaAssignmentSpecV1{} } func (m *OktaAssignmentSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentSpecV1) ProtoMessage() {} func (*OktaAssignmentSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{346} + return fileDescriptor_9198ee693835762e, []int{348} } func (m *OktaAssignmentSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20264,7 +20385,7 @@ func (m *OktaAssignmentTargetV1) Reset() { *m = OktaAssignmentTargetV1{} func (m *OktaAssignmentTargetV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentTargetV1) ProtoMessage() {} func (*OktaAssignmentTargetV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{347} + return fileDescriptor_9198ee693835762e, []int{349} } func (m *OktaAssignmentTargetV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20309,7 +20430,7 @@ type IntegrationV1 struct { func (m *IntegrationV1) Reset() { *m = IntegrationV1{} } func (*IntegrationV1) ProtoMessage() {} func (*IntegrationV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{348} + return fileDescriptor_9198ee693835762e, []int{350} } func (m *IntegrationV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20357,7 +20478,7 @@ func (m *IntegrationSpecV1) Reset() { *m = IntegrationSpecV1{} } func (m *IntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*IntegrationSpecV1) ProtoMessage() {} func (*IntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{349} + return fileDescriptor_9198ee693835762e, []int{351} } func (m *IntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20476,7 +20597,7 @@ func (m *AWSOIDCIntegrationSpecV1) Reset() { *m = AWSOIDCIntegrationSpec func (m *AWSOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AWSOIDCIntegrationSpecV1) ProtoMessage() {} func (*AWSOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{350} + return fileDescriptor_9198ee693835762e, []int{352} } func (m *AWSOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20522,7 +20643,7 @@ func (m *AzureOIDCIntegrationSpecV1) Reset() { *m = AzureOIDCIntegration func (m *AzureOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AzureOIDCIntegrationSpecV1) ProtoMessage() {} func (*AzureOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{351} + return fileDescriptor_9198ee693835762e, []int{353} } func (m *AzureOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20564,7 +20685,7 @@ func (m *GitHubIntegrationSpecV1) Reset() { *m = GitHubIntegrationSpecV1 func (m *GitHubIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*GitHubIntegrationSpecV1) ProtoMessage() {} func (*GitHubIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{352} + return fileDescriptor_9198ee693835762e, []int{354} } func (m *GitHubIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20625,7 +20746,7 @@ func (m *HeadlessAuthentication) Reset() { *m = HeadlessAuthentication{} func (m *HeadlessAuthentication) String() string { return proto.CompactTextString(m) } func (*HeadlessAuthentication) ProtoMessage() {} func (*HeadlessAuthentication) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{353} + return fileDescriptor_9198ee693835762e, []int{355} } func (m *HeadlessAuthentication) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20682,7 +20803,7 @@ func (m *WatchKind) Reset() { *m = WatchKind{} } func (m *WatchKind) String() string { return proto.CompactTextString(m) } func (*WatchKind) ProtoMessage() {} func (*WatchKind) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{354} + return fileDescriptor_9198ee693835762e, []int{356} } func (m *WatchKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20732,7 +20853,7 @@ func (m *WatchStatusV1) Reset() { *m = WatchStatusV1{} } func (m *WatchStatusV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusV1) ProtoMessage() {} func (*WatchStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{355} + return fileDescriptor_9198ee693835762e, []int{357} } func (m *WatchStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20773,7 +20894,7 @@ func (m *WatchStatusSpecV1) Reset() { *m = WatchStatusSpecV1{} } func (m *WatchStatusSpecV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusSpecV1) ProtoMessage() {} func (*WatchStatusSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{356} + return fileDescriptor_9198ee693835762e, []int{358} } func (m *WatchStatusSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20823,7 +20944,7 @@ func (m *ServerInfoV1) Reset() { *m = ServerInfoV1{} } func (m *ServerInfoV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoV1) ProtoMessage() {} func (*ServerInfoV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{357} + return fileDescriptor_9198ee693835762e, []int{359} } func (m *ServerInfoV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20865,7 +20986,7 @@ func (m *ServerInfoSpecV1) Reset() { *m = ServerInfoSpecV1{} } func (m *ServerInfoSpecV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoSpecV1) ProtoMessage() {} func (*ServerInfoSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{358} + return fileDescriptor_9198ee693835762e, []int{360} } func (m *ServerInfoSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20922,7 +21043,7 @@ func (m *JamfSpecV1) Reset() { *m = JamfSpecV1{} } func (m *JamfSpecV1) String() string { return proto.CompactTextString(m) } func (*JamfSpecV1) ProtoMessage() {} func (*JamfSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{359} + return fileDescriptor_9198ee693835762e, []int{361} } func (m *JamfSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20987,7 +21108,7 @@ func (m *JamfInventoryEntry) Reset() { *m = JamfInventoryEntry{} } func (m *JamfInventoryEntry) String() string { return proto.CompactTextString(m) } func (*JamfInventoryEntry) ProtoMessage() {} func (*JamfInventoryEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{360} + return fileDescriptor_9198ee693835762e, []int{362} } func (m *JamfInventoryEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21044,7 +21165,7 @@ type MessageWithHeader struct { func (m *MessageWithHeader) Reset() { *m = MessageWithHeader{} } func (*MessageWithHeader) ProtoMessage() {} func (*MessageWithHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{361} + return fileDescriptor_9198ee693835762e, []int{363} } func (m *MessageWithHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21108,7 +21229,7 @@ func (m *AWSMatcher) Reset() { *m = AWSMatcher{} } func (m *AWSMatcher) String() string { return proto.CompactTextString(m) } func (*AWSMatcher) ProtoMessage() {} func (*AWSMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{362} + return fileDescriptor_9198ee693835762e, []int{364} } func (m *AWSMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21153,7 +21274,7 @@ func (m *AssumeRole) Reset() { *m = AssumeRole{} } func (m *AssumeRole) String() string { return proto.CompactTextString(m) } func (*AssumeRole) ProtoMessage() {} func (*AssumeRole) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{363} + return fileDescriptor_9198ee693835762e, []int{365} } func (m *AssumeRole) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21215,7 +21336,7 @@ func (m *InstallerParams) Reset() { *m = InstallerParams{} } func (m *InstallerParams) String() string { return proto.CompactTextString(m) } func (*InstallerParams) ProtoMessage() {} func (*InstallerParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{364} + return fileDescriptor_9198ee693835762e, []int{366} } func (m *InstallerParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21258,7 +21379,7 @@ func (m *AWSSSM) Reset() { *m = AWSSSM{} } func (m *AWSSSM) String() string { return proto.CompactTextString(m) } func (*AWSSSM) ProtoMessage() {} func (*AWSSSM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{365} + return fileDescriptor_9198ee693835762e, []int{367} } func (m *AWSSSM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21301,7 +21422,7 @@ func (m *AzureInstallerParams) Reset() { *m = AzureInstallerParams{} } func (m *AzureInstallerParams) String() string { return proto.CompactTextString(m) } func (*AzureInstallerParams) ProtoMessage() {} func (*AzureInstallerParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{366} + return fileDescriptor_9198ee693835762e, []int{368} } func (m *AzureInstallerParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21355,7 +21476,7 @@ func (m *AzureMatcher) Reset() { *m = AzureMatcher{} } func (m *AzureMatcher) String() string { return proto.CompactTextString(m) } func (*AzureMatcher) ProtoMessage() {} func (*AzureMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{367} + return fileDescriptor_9198ee693835762e, []int{369} } func (m *AzureMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21410,7 +21531,7 @@ func (m *GCPMatcher) Reset() { *m = GCPMatcher{} } func (m *GCPMatcher) String() string { return proto.CompactTextString(m) } func (*GCPMatcher) ProtoMessage() {} func (*GCPMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{368} + return fileDescriptor_9198ee693835762e, []int{370} } func (m *GCPMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21456,7 +21577,7 @@ func (m *KubernetesMatcher) Reset() { *m = KubernetesMatcher{} } func (m *KubernetesMatcher) String() string { return proto.CompactTextString(m) } func (*KubernetesMatcher) ProtoMessage() {} func (*KubernetesMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{369} + return fileDescriptor_9198ee693835762e, []int{371} } func (m *KubernetesMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21498,7 +21619,7 @@ func (m *OktaOptions) Reset() { *m = OktaOptions{} } func (m *OktaOptions) String() string { return proto.CompactTextString(m) } func (*OktaOptions) ProtoMessage() {} func (*OktaOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{370} + return fileDescriptor_9198ee693835762e, []int{372} } func (m *OktaOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21542,7 +21663,7 @@ func (m *AccessGraphSync) Reset() { *m = AccessGraphSync{} } func (m *AccessGraphSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphSync) ProtoMessage() {} func (*AccessGraphSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{371} + return fileDescriptor_9198ee693835762e, []int{373} } func (m *AccessGraphSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21588,7 +21709,7 @@ func (m *AccessGraphAWSSync) Reset() { *m = AccessGraphAWSSync{} } func (m *AccessGraphAWSSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphAWSSync) ProtoMessage() {} func (*AccessGraphAWSSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{372} + return fileDescriptor_9198ee693835762e, []int{374} } func (m *AccessGraphAWSSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21985,10 +22106,12 @@ func init() { proto.RegisterType((*MailgunSpec)(nil), "types.MailgunSpec") proto.RegisterType((*SMTPSpec)(nil), "types.SMTPSpec") proto.RegisterType((*PluginMSTeamsSettings)(nil), "types.PluginMSTeamsSettings") + proto.RegisterType((*PluginNetIQSettings)(nil), "types.PluginNetIQSettings") proto.RegisterType((*PluginBootstrapCredentialsV1)(nil), "types.PluginBootstrapCredentialsV1") proto.RegisterType((*PluginIdSecretCredential)(nil), "types.PluginIdSecretCredential") proto.RegisterType((*PluginOAuth2AuthorizationCodeCredentials)(nil), "types.PluginOAuth2AuthorizationCodeCredentials") proto.RegisterType((*PluginStatusV1)(nil), "types.PluginStatusV1") + proto.RegisterType((*PluginNetIQStatusV1)(nil), "types.PluginNetIQStatusV1") proto.RegisterType((*PluginGitlabStatusV1)(nil), "types.PluginGitlabStatusV1") proto.RegisterType((*PluginEntraIDStatusV1)(nil), "types.PluginEntraIDStatusV1") proto.RegisterType((*PluginOktaStatusV1)(nil), "types.PluginOktaStatusV1") @@ -22062,1911 +22185,1919 @@ func init() { func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } var fileDescriptor_9198ee693835762e = []byte{ - // 30463 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6d, 0x70, 0x1c, 0x49, - 0x76, 0x20, 0x36, 0xdd, 0x8d, 0x8f, 0xc6, 0xc3, 0x57, 0x23, 0x01, 0x92, 0x20, 0x66, 0x86, 0xcd, - 0xa9, 0x99, 0xe1, 0x90, 0xb3, 0x33, 0xe4, 0x12, 0xdc, 0xe1, 0xee, 0xec, 0x7c, 0x6d, 0xa3, 0x1b, - 0x24, 0x9a, 0x04, 0x01, 0x6c, 0x35, 0x40, 0xec, 0x68, 0x3f, 0x6a, 0x0b, 0xdd, 0x09, 0xa0, 0x06, - 0xdd, 0x5d, 0xbd, 0x55, 0xd5, 0x04, 0xa1, 0x3d, 0xf9, 0xf4, 0xb5, 0x27, 0x2b, 0x64, 0x7d, 0x9e, - 0x74, 0xd2, 0x39, 0x74, 0xb2, 0x42, 0xbe, 0xf3, 0x29, 0xce, 0x21, 0xc5, 0x59, 0xb2, 0xec, 0xb3, - 0x15, 0x96, 0x25, 0x87, 0x2c, 0xcb, 0x8a, 0x8b, 0x93, 0xe2, 0x7c, 0xb6, 0xc3, 0xeb, 0x0b, 0xc8, - 0xb2, 0xfc, 0xc3, 0x81, 0x08, 0x47, 0x48, 0xbe, 0x08, 0x47, 0x78, 0x1d, 0xba, 0x73, 0xe4, 0xcb, - 0xcc, 0xaa, 0xcc, 0xaa, 0xea, 0x46, 0x63, 0x86, 0xa3, 0x13, 0x27, 0xf4, 0x87, 0x44, 0xbf, 0x7c, - 0xef, 0x65, 0xe5, 0xf7, 0xcb, 0x97, 0xef, 0x03, 0x5e, 0x08, 0x68, 0x93, 0x76, 0x5c, 0x2f, 0xb8, - 0xd1, 0xa4, 0x7b, 0x76, 0xfd, 0xe8, 0x46, 0x70, 0xd4, 0xa1, 0x3e, 0xff, 0xf7, 0x7a, 0xc7, 0x73, - 0x03, 0x97, 0x0c, 0xe3, 0x8f, 0x85, 0xb9, 0x3d, 0x77, 0xcf, 0x45, 0xc8, 0x0d, 0xf6, 0x17, 0x2f, - 0x5c, 0xb8, 0xb4, 0xe7, 0xba, 0x7b, 0x4d, 0x7a, 0x03, 0x7f, 0xed, 0x74, 0x77, 0x6f, 0x34, 0xba, - 0x9e, 0x1d, 0x38, 0x6e, 0x5b, 0x94, 0x17, 0xe3, 0xe5, 0x81, 0xd3, 0xa2, 0x7e, 0x60, 0xb7, 0x3a, - 0xbd, 0x18, 0x1c, 0x7a, 0x76, 0xa7, 0x43, 0x3d, 0x51, 0xfb, 0xc2, 0xb5, 0xf0, 0x03, 0xed, 0x20, - 0x60, 0x94, 0x8c, 0xf9, 0x8d, 0x47, 0x37, 0xd5, 0x9f, 0x02, 0xf5, 0x76, 0x8f, 0xb6, 0x78, 0x5d, - 0x3f, 0xa0, 0x0d, 0xab, 0x41, 0x1f, 0x39, 0x75, 0x6a, 0x79, 0xf4, 0x1b, 0x5d, 0xc7, 0xa3, 0x2d, - 0xda, 0x0e, 0x04, 0xdd, 0xeb, 0xe9, 0x74, 0xf2, 0x43, 0x62, 0x5f, 0x64, 0xfc, 0x42, 0x0e, 0xc6, - 0xee, 0x53, 0xda, 0x29, 0x35, 0x9d, 0x47, 0x94, 0xbc, 0x08, 0x43, 0x6b, 0x76, 0x8b, 0xce, 0x67, - 0x2e, 0x67, 0xae, 0x8e, 0x2d, 0x4d, 0x9f, 0x1c, 0x17, 0xc7, 0x7d, 0xea, 0x3d, 0xa2, 0x9e, 0xd5, - 0xb6, 0x5b, 0xd4, 0xc4, 0x42, 0xf2, 0x29, 0x18, 0x63, 0xff, 0xfb, 0x1d, 0xbb, 0x4e, 0xe7, 0xb3, - 0x88, 0x39, 0x79, 0x72, 0x5c, 0x1c, 0x6b, 0x4b, 0xa0, 0x19, 0x95, 0x93, 0x2a, 0x8c, 0x2e, 0x3f, - 0xee, 0x38, 0x1e, 0xf5, 0xe7, 0x87, 0x2e, 0x67, 0xae, 0x8e, 0x2f, 0x2e, 0x5c, 0xe7, 0x7d, 0x74, - 0x5d, 0xf6, 0xd1, 0xf5, 0x4d, 0xd9, 0x89, 0x4b, 0xb3, 0xbf, 0x7f, 0x5c, 0x7c, 0xe6, 0xe4, 0xb8, - 0x38, 0x4a, 0x39, 0xc9, 0x4f, 0xfc, 0x71, 0x31, 0x63, 0x4a, 0x7a, 0xf2, 0x36, 0x0c, 0x6d, 0x1e, - 0x75, 0xe8, 0xfc, 0xd8, 0xe5, 0xcc, 0xd5, 0xa9, 0xc5, 0x4b, 0xd7, 0xf9, 0xb0, 0x86, 0x1f, 0x1f, - 0xfd, 0xc5, 0xb0, 0x96, 0xf2, 0x27, 0xc7, 0xc5, 0x21, 0x86, 0x62, 0x22, 0x15, 0x79, 0x1d, 0x46, - 0x56, 0x5c, 0x3f, 0xa8, 0x56, 0xe6, 0x01, 0x3f, 0xf9, 0xdc, 0xc9, 0x71, 0x71, 0x66, 0xdf, 0xf5, - 0x03, 0xcb, 0x69, 0xbc, 0xe6, 0xb6, 0x9c, 0x80, 0xb6, 0x3a, 0xc1, 0x91, 0x29, 0x90, 0x8c, 0xc7, - 0x30, 0xa9, 0xf1, 0x23, 0xe3, 0x30, 0xba, 0xb5, 0x76, 0x7f, 0x6d, 0x7d, 0x7b, 0xad, 0xf0, 0x0c, - 0xc9, 0xc3, 0xd0, 0xda, 0x7a, 0x65, 0xb9, 0x90, 0x21, 0xa3, 0x90, 0x2b, 0x6d, 0x6c, 0x14, 0xb2, - 0x64, 0x02, 0xf2, 0x95, 0xd2, 0x66, 0x69, 0xa9, 0x54, 0x5b, 0x2e, 0xe4, 0xc8, 0x2c, 0x4c, 0x6f, - 0x57, 0xd7, 0x2a, 0xeb, 0xdb, 0x35, 0xab, 0xb2, 0x5c, 0xbb, 0xbf, 0xb9, 0xbe, 0x51, 0x18, 0x22, - 0x53, 0x00, 0xf7, 0xb7, 0x96, 0x96, 0xcd, 0xb5, 0xe5, 0xcd, 0xe5, 0x5a, 0x61, 0x98, 0xcc, 0x41, - 0x41, 0x92, 0x58, 0xb5, 0x65, 0xf3, 0x61, 0xb5, 0xbc, 0x5c, 0x18, 0xb9, 0x37, 0x94, 0xcf, 0x15, - 0x86, 0xcc, 0xd1, 0x55, 0x6a, 0xfb, 0xb4, 0x5a, 0x31, 0xfe, 0xc3, 0x1c, 0xe4, 0x1f, 0xd0, 0xc0, - 0x6e, 0xd8, 0x81, 0x4d, 0x9e, 0xd3, 0xc6, 0x07, 0x9b, 0xa8, 0x0c, 0xcc, 0x8b, 0xc9, 0x81, 0x19, - 0x3e, 0x39, 0x2e, 0x66, 0x5e, 0x57, 0x07, 0xe4, 0x2d, 0x18, 0xaf, 0x50, 0xbf, 0xee, 0x39, 0x1d, - 0x36, 0xd9, 0xe6, 0x73, 0x88, 0x76, 0xf1, 0xe4, 0xb8, 0x78, 0xae, 0x11, 0x81, 0x95, 0x0e, 0x51, - 0xb1, 0x49, 0x15, 0x46, 0x56, 0xed, 0x1d, 0xda, 0xf4, 0xe7, 0x87, 0x2f, 0xe7, 0xae, 0x8e, 0x2f, - 0x3e, 0x2b, 0x06, 0x41, 0x7e, 0xe0, 0x75, 0x5e, 0xba, 0xdc, 0x0e, 0xbc, 0xa3, 0xa5, 0xb9, 0x93, - 0xe3, 0x62, 0xa1, 0x89, 0x00, 0xb5, 0x83, 0x39, 0x0a, 0xa9, 0x45, 0x13, 0x63, 0xe4, 0xd4, 0x89, - 0xf1, 0xfc, 0xef, 0x1f, 0x17, 0x33, 0x6c, 0xc0, 0xc4, 0xc4, 0x88, 0xf8, 0xe9, 0x53, 0x64, 0x11, - 0xf2, 0x26, 0x7d, 0xe4, 0xf8, 0xac, 0x65, 0x79, 0x6c, 0xd9, 0xf9, 0x93, 0xe3, 0x22, 0xf1, 0x04, - 0x4c, 0xf9, 0x8c, 0x10, 0x6f, 0xe1, 0x4d, 0x18, 0x57, 0xbe, 0x9a, 0x14, 0x20, 0x77, 0x40, 0x8f, - 0x78, 0x0f, 0x9b, 0xec, 0x4f, 0x32, 0x07, 0xc3, 0x8f, 0xec, 0x66, 0x57, 0x74, 0xa9, 0xc9, 0x7f, - 0x7c, 0x3e, 0xfb, 0xb9, 0xcc, 0xbd, 0xa1, 0xfc, 0x68, 0x21, 0x6f, 0x66, 0xab, 0x15, 0xe3, 0xa7, - 0x86, 0x20, 0x6f, 0xba, 0x7c, 0x01, 0x93, 0x6b, 0x30, 0x5c, 0x0b, 0xec, 0x40, 0x0e, 0xd3, 0xec, - 0xc9, 0x71, 0x71, 0x9a, 0x2d, 0x6e, 0xaa, 0xd4, 0xcf, 0x31, 0x18, 0xea, 0xc6, 0xbe, 0xed, 0xcb, - 0xe1, 0x42, 0xd4, 0x0e, 0x03, 0xa8, 0xa8, 0x88, 0x41, 0xae, 0xc0, 0xd0, 0x03, 0xb7, 0x41, 0xc5, - 0x88, 0x91, 0x93, 0xe3, 0xe2, 0x54, 0xcb, 0x6d, 0xa8, 0x88, 0x58, 0x4e, 0x5e, 0x83, 0xb1, 0x72, - 0xd7, 0xf3, 0x68, 0x9b, 0xcd, 0xf5, 0x21, 0x44, 0x9e, 0x3a, 0x39, 0x2e, 0x42, 0x9d, 0x03, 0x2d, - 0xa7, 0x61, 0x46, 0x08, 0x6c, 0x18, 0x6a, 0x81, 0xed, 0x05, 0xb4, 0x31, 0x3f, 0x3c, 0xd0, 0x30, - 0xb0, 0xf5, 0x39, 0xe3, 0x73, 0x92, 0xf8, 0x30, 0x08, 0x4e, 0x64, 0x05, 0xc6, 0xef, 0x7a, 0x76, - 0x9d, 0x6e, 0x50, 0xcf, 0x71, 0x1b, 0x38, 0xbe, 0xb9, 0xa5, 0x2b, 0x27, 0xc7, 0xc5, 0xf3, 0x7b, - 0x0c, 0x6c, 0x75, 0x10, 0x1e, 0x51, 0x7f, 0xe7, 0xb8, 0x98, 0xaf, 0x88, 0xad, 0xd6, 0x54, 0x49, - 0xc9, 0xd7, 0xd9, 0xe0, 0xf8, 0x01, 0x76, 0x2d, 0x6d, 0xcc, 0x8f, 0x9e, 0xfa, 0x89, 0x86, 0xf8, - 0xc4, 0xf3, 0x4d, 0xdb, 0x0f, 0x2c, 0x8f, 0xd3, 0xc5, 0xbe, 0x53, 0x65, 0x49, 0xd6, 0x21, 0x5f, - 0xab, 0xef, 0xd3, 0x46, 0xb7, 0x49, 0x71, 0xca, 0x8c, 0x2f, 0x5e, 0x10, 0x93, 0x5a, 0x8e, 0xa7, - 0x2c, 0x5e, 0x5a, 0x10, 0xbc, 0x89, 0x2f, 0x20, 0xea, 0x7c, 0x92, 0x58, 0x9f, 0xcf, 0xff, 0xdc, - 0x2f, 0x16, 0x9f, 0xf9, 0xde, 0x7f, 0x79, 0xf9, 0x19, 0xe3, 0x3f, 0xcf, 0x42, 0x21, 0xce, 0x84, - 0xec, 0xc2, 0xe4, 0x56, 0xa7, 0x61, 0x07, 0xb4, 0xdc, 0x74, 0x68, 0x3b, 0xf0, 0x71, 0x92, 0xf4, - 0x6f, 0xd3, 0x4b, 0xa2, 0xde, 0xf9, 0x2e, 0x12, 0x5a, 0x75, 0x4e, 0x19, 0x6b, 0x95, 0xce, 0x36, - 0xaa, 0xa7, 0x86, 0x1b, 0xb8, 0x8f, 0x33, 0xec, 0x6c, 0xf5, 0xf0, 0xad, 0xbf, 0x47, 0x3d, 0x82, - 0xad, 0x98, 0x40, 0xed, 0xc6, 0xce, 0x11, 0xce, 0xcc, 0xc1, 0x27, 0x10, 0x23, 0x49, 0x99, 0x40, - 0x0c, 0x6c, 0xfc, 0x1f, 0x19, 0x98, 0x32, 0xa9, 0xef, 0x76, 0xbd, 0x3a, 0x5d, 0xa1, 0x76, 0x83, - 0x7a, 0x6c, 0xfa, 0xdf, 0x77, 0xda, 0x0d, 0xb1, 0xa6, 0x70, 0xfa, 0x1f, 0x38, 0x6d, 0x75, 0xeb, - 0xc6, 0x72, 0xf2, 0x69, 0x18, 0xad, 0x75, 0x77, 0x10, 0x35, 0x1b, 0xed, 0x00, 0x7e, 0x77, 0xc7, - 0x8a, 0xa1, 0x4b, 0x34, 0x72, 0x03, 0x46, 0x1f, 0x52, 0xcf, 0x8f, 0x76, 0x43, 0x3c, 0x1a, 0x1e, - 0x71, 0x90, 0x4a, 0x20, 0xb0, 0xc8, 0xdd, 0x68, 0x47, 0x16, 0x87, 0xda, 0x74, 0x6c, 0x1f, 0x8c, - 0xa6, 0x4a, 0x4b, 0x40, 0xd4, 0xa9, 0x22, 0xb1, 0x8c, 0x9f, 0xcc, 0x42, 0xa1, 0x62, 0x07, 0xf6, - 0x8e, 0xed, 0x8b, 0xfe, 0x7c, 0x78, 0x8b, 0xed, 0xf1, 0x4a, 0x43, 0x71, 0x8f, 0x67, 0x5f, 0xfe, - 0xa1, 0x9b, 0xf7, 0x72, 0xbc, 0x79, 0xe3, 0xec, 0x84, 0x15, 0xcd, 0x8b, 0x1a, 0xf5, 0xce, 0xe9, - 0x8d, 0x2a, 0x88, 0x46, 0xe5, 0x65, 0xa3, 0xa2, 0xa6, 0x90, 0x77, 0x60, 0xa8, 0xd6, 0xa1, 0x75, - 0xb1, 0x89, 0xc8, 0x73, 0x41, 0x6f, 0x1c, 0x43, 0x78, 0x78, 0x6b, 0x69, 0x42, 0xb0, 0x19, 0xf2, - 0x3b, 0xb4, 0x6e, 0x22, 0x99, 0xb2, 0x68, 0xfe, 0x49, 0x0e, 0xe6, 0xd2, 0xc8, 0xd4, 0x76, 0x8c, - 0xf4, 0x69, 0xc7, 0x55, 0xc8, 0xb3, 0x23, 0x9c, 0x1d, 0x8b, 0xb8, 0x5d, 0x8c, 0x2d, 0x4d, 0xb0, - 0x4f, 0xde, 0x17, 0x30, 0x33, 0x2c, 0x25, 0x2f, 0x86, 0x12, 0x41, 0x3e, 0xe2, 0x27, 0x24, 0x02, - 0x29, 0x07, 0xb0, 0xb1, 0x96, 0x4b, 0x18, 0x05, 0x87, 0xa8, 0x5b, 0x24, 0x38, 0x1a, 0x6b, 0x4f, - 0x40, 0xb4, 0x63, 0x46, 0x1e, 0x0a, 0xcb, 0x90, 0x97, 0xcd, 0x9a, 0x9f, 0x40, 0x46, 0x33, 0xb1, - 0x4e, 0x7a, 0x78, 0x8b, 0x0f, 0x66, 0x43, 0xfc, 0x56, 0xd9, 0x48, 0x1c, 0x72, 0x0b, 0xf2, 0x1b, - 0x9e, 0xfb, 0xf8, 0xa8, 0x5a, 0xf1, 0xe7, 0x27, 0x2f, 0xe7, 0xae, 0x8e, 0x2d, 0x5d, 0x38, 0x39, - 0x2e, 0xce, 0x76, 0x18, 0xcc, 0x72, 0x1a, 0xea, 0x49, 0x1b, 0x22, 0xde, 0x1b, 0xca, 0x67, 0x0a, - 0xd9, 0x7b, 0x43, 0xf9, 0x6c, 0x21, 0xc7, 0xc5, 0x8b, 0x7b, 0x43, 0xf9, 0xa1, 0xc2, 0xf0, 0xbd, - 0xa1, 0xfc, 0x30, 0x0a, 0x1c, 0x63, 0x05, 0xb8, 0x37, 0x94, 0x1f, 0x2f, 0x4c, 0x68, 0xa7, 0x3d, - 0x32, 0x08, 0xdc, 0xba, 0xdb, 0x34, 0x73, 0x5b, 0x66, 0xd5, 0x1c, 0x29, 0x97, 0xca, 0xd4, 0x0b, - 0xcc, 0x5c, 0x69, 0xbb, 0x66, 0x4e, 0x56, 0x8e, 0xda, 0x76, 0xcb, 0xa9, 0xf3, 0xa3, 0xd3, 0xcc, - 0xdd, 0x2d, 0x6f, 0x18, 0x25, 0x98, 0x8a, 0xda, 0xb2, 0xea, 0xf8, 0x01, 0xb9, 0x01, 0x63, 0x12, - 0xc2, 0x36, 0xba, 0x5c, 0x6a, 0xab, 0xcd, 0x08, 0xc7, 0xf8, 0xbd, 0x2c, 0x40, 0x54, 0xf2, 0x94, - 0xae, 0x85, 0xcf, 0x6a, 0x6b, 0xe1, 0x5c, 0x7c, 0x2d, 0xf4, 0x5c, 0x05, 0xe4, 0x3d, 0x18, 0x61, - 0x62, 0x41, 0x57, 0x8a, 0x44, 0x17, 0xe2, 0xa4, 0x58, 0xf8, 0xf0, 0xd6, 0xd2, 0x94, 0x20, 0x1e, - 0xf1, 0x11, 0x62, 0x0a, 0x32, 0x65, 0x19, 0xfd, 0xc2, 0x68, 0x34, 0x18, 0x62, 0x01, 0x5d, 0x85, - 0x70, 0x40, 0x45, 0x87, 0xe2, 0xca, 0xe8, 0xc8, 0x41, 0x0e, 0x4b, 0xc9, 0x45, 0x60, 0x03, 0x2e, - 0x3a, 0x75, 0xf4, 0xe4, 0xb8, 0x98, 0xeb, 0x7a, 0x0e, 0x4e, 0x02, 0x72, 0x03, 0xc4, 0x34, 0x10, - 0x1d, 0xc8, 0x66, 0xdf, 0x4c, 0xdd, 0xb6, 0xea, 0xd4, 0x0b, 0xa2, 0x1e, 0x9f, 0xcf, 0xc8, 0xd9, - 0x42, 0x3a, 0xa0, 0x4f, 0x95, 0xf9, 0x21, 0x9c, 0x06, 0x57, 0x53, 0x7b, 0xe5, 0xba, 0x86, 0xca, - 0xc5, 0xc8, 0xcb, 0xf2, 0x54, 0x6a, 0xf0, 0x32, 0x2b, 0x21, 0x52, 0xea, 0x15, 0x90, 0x5b, 0xc0, - 0x66, 0xa8, 0xe8, 0x7d, 0x10, 0xf5, 0x94, 0xb6, 0x6b, 0x4b, 0xe7, 0x04, 0xa7, 0x49, 0xfb, 0x50, - 0x25, 0x67, 0xd8, 0xe4, 0x2d, 0x60, 0x53, 0x58, 0xf4, 0x3b, 0x11, 0x44, 0x77, 0xcb, 0x1b, 0xe5, - 0xa6, 0xdb, 0x6d, 0xd4, 0xbe, 0xb8, 0x1a, 0x11, 0xef, 0xd5, 0x3b, 0x2a, 0xf1, 0xdd, 0xf2, 0x06, - 0x79, 0x0b, 0x86, 0x4b, 0xdf, 0xdd, 0xf5, 0xa8, 0x90, 0x4f, 0x26, 0x64, 0x9d, 0x0c, 0xb6, 0x74, - 0x41, 0x10, 0x4e, 0xdb, 0xec, 0xa7, 0x2a, 0xd7, 0x61, 0x39, 0xab, 0x79, 0x73, 0xb5, 0x26, 0x64, - 0x0f, 0x12, 0xeb, 0x96, 0xcd, 0x55, 0xe5, 0xb3, 0x03, 0xad, 0xd5, 0x8c, 0x8a, 0xdc, 0x80, 0x6c, - 0xa9, 0x82, 0x37, 0xa2, 0xf1, 0xc5, 0x31, 0x59, 0x6d, 0x65, 0x69, 0x4e, 0x90, 0x4c, 0xd8, 0xea, - 0x32, 0xc8, 0x96, 0x2a, 0x64, 0x09, 0x86, 0x1f, 0x1c, 0xd5, 0xbe, 0xb8, 0x2a, 0x36, 0xb3, 0x59, - 0x39, 0xaf, 0x19, 0x6c, 0x1d, 0x97, 0xbd, 0x1f, 0x7d, 0x71, 0xeb, 0xc8, 0xff, 0x46, 0x53, 0xfd, - 0x62, 0x44, 0x23, 0x1b, 0x30, 0x56, 0x6a, 0xb4, 0x9c, 0xf6, 0x96, 0x4f, 0xbd, 0xf9, 0x71, 0xe4, - 0x33, 0x1f, 0xfb, 0xee, 0xb0, 0x7c, 0x69, 0xfe, 0xe4, 0xb8, 0x38, 0x67, 0xb3, 0x9f, 0x56, 0xd7, - 0xa7, 0x9e, 0xc2, 0x2d, 0x62, 0x42, 0x36, 0x00, 0x1e, 0xb8, 0xed, 0x3d, 0xb7, 0x14, 0x34, 0x6d, - 0x3f, 0xb6, 0x3d, 0x46, 0x05, 0xa1, 0xf8, 0x70, 0xae, 0xc5, 0x60, 0x96, 0xcd, 0x80, 0x0a, 0x43, - 0x85, 0x07, 0xb9, 0x03, 0x23, 0xeb, 0x9e, 0x5d, 0x6f, 0xd2, 0xf9, 0x49, 0xe4, 0x36, 0x27, 0xb8, - 0x71, 0xa0, 0x6c, 0xe9, 0xbc, 0x60, 0x58, 0x70, 0x11, 0xac, 0x5e, 0x53, 0x38, 0xe2, 0xc2, 0x36, - 0x90, 0xe4, 0x9c, 0x4c, 0xb9, 0x24, 0x7c, 0x4a, 0xbd, 0x24, 0x44, 0x8b, 0xbe, 0xec, 0xb6, 0x5a, - 0x76, 0xbb, 0x81, 0xb4, 0x0f, 0x17, 0x95, 0xbb, 0x83, 0xf1, 0x0d, 0x98, 0x49, 0x74, 0xd6, 0x29, - 0xf7, 0xbb, 0x77, 0x61, 0xba, 0x42, 0x77, 0xed, 0x6e, 0x33, 0x08, 0x4f, 0x12, 0xbe, 0x44, 0xf1, - 0xa6, 0xd5, 0xe0, 0x45, 0x96, 0x3c, 0x3e, 0xcc, 0x38, 0xb2, 0xf1, 0x0e, 0x4c, 0x6a, 0xcd, 0x67, - 0x57, 0x85, 0x52, 0xb7, 0xe1, 0x04, 0x38, 0x90, 0x99, 0xe8, 0xaa, 0x60, 0x33, 0x20, 0x0e, 0x97, - 0x19, 0x21, 0x18, 0x7f, 0x5f, 0x95, 0x56, 0xc4, 0x4e, 0xc4, 0xae, 0xd5, 0x62, 0x3f, 0xc8, 0x44, - 0xb2, 0x53, 0x62, 0x3f, 0x08, 0x77, 0x83, 0x6b, 0x7c, 0x6d, 0x66, 0x13, 0x6b, 0x73, 0x5c, 0x8c, - 0x44, 0xce, 0x3e, 0xf4, 0xf9, 0x8a, 0x0c, 0x67, 0x6a, 0xee, 0xc3, 0xcf, 0xd4, 0xf7, 0x60, 0xe2, - 0x81, 0xdd, 0xb6, 0xf7, 0x68, 0x83, 0xb5, 0x80, 0xef, 0x3d, 0x63, 0x4b, 0xcf, 0x9e, 0x1c, 0x17, - 0x2f, 0xb4, 0x38, 0x1c, 0x5b, 0xa9, 0x4e, 0x22, 0x8d, 0x80, 0xdc, 0x94, 0x2b, 0x7b, 0x38, 0x65, - 0x65, 0x4f, 0x8a, 0xda, 0x87, 0x71, 0x65, 0x8b, 0xf5, 0x6c, 0xfc, 0xf6, 0x18, 0xb6, 0x91, 0xbc, - 0x06, 0x23, 0x26, 0xdd, 0x63, 0x47, 0x4d, 0x26, 0x1a, 0x24, 0x0f, 0x21, 0x6a, 0xc7, 0x70, 0x1c, - 0x94, 0x33, 0x68, 0xc3, 0xdf, 0x77, 0x76, 0x03, 0xd1, 0x3b, 0xa1, 0x9c, 0x21, 0xc0, 0x8a, 0x9c, - 0x21, 0x20, 0xfa, 0x75, 0x96, 0xc3, 0xd8, 0xee, 0x67, 0x56, 0x6a, 0xa2, 0xd3, 0x64, 0x0f, 0x9b, - 0x15, 0x65, 0x1b, 0xf1, 0x34, 0x29, 0x81, 0x61, 0x93, 0xdb, 0x30, 0x56, 0xaa, 0xd7, 0xdd, 0xae, - 0x72, 0x67, 0xe4, 0xeb, 0x96, 0x03, 0x75, 0x15, 0x49, 0x84, 0x4a, 0x6a, 0x30, 0xbe, 0xcc, 0x2e, - 0x5a, 0x4e, 0xd9, 0xae, 0xef, 0xcb, 0x4e, 0x92, 0x7b, 0x98, 0x52, 0x12, 0xad, 0x5c, 0x8a, 0xc0, - 0x3a, 0x03, 0xaa, 0x4a, 0x06, 0x05, 0x97, 0x6c, 0xc2, 0x78, 0x8d, 0xd6, 0x3d, 0x1a, 0xd4, 0x02, - 0xd7, 0xa3, 0xb1, 0x2d, 0x59, 0x29, 0x59, 0xba, 0x24, 0xef, 0x7a, 0x3e, 0x02, 0x2d, 0x9f, 0x41, - 0x55, 0xae, 0x0a, 0x32, 0x17, 0xda, 0x5b, 0xae, 0x77, 0x54, 0x59, 0x12, 0xdb, 0x74, 0x74, 0xa6, - 0x73, 0xb0, 0x2a, 0xb4, 0x33, 0x48, 0x63, 0x47, 0x17, 0xda, 0x39, 0x16, 0x8e, 0x54, 0xa5, 0x86, - 0xb2, 0x95, 0xd8, 0xb4, 0xa7, 0xa3, 0x5e, 0x46, 0xb0, 0x32, 0x52, 0x0d, 0x1f, 0x25, 0x33, 0x6d, - 0xa4, 0x04, 0x16, 0xe9, 0x00, 0x91, 0xa3, 0xc6, 0x05, 0xdd, 0x26, 0xf5, 0x7d, 0xb1, 0x97, 0x5f, - 0x8c, 0x0d, 0x7e, 0x84, 0xb0, 0xf4, 0xb2, 0x60, 0xfe, 0xbc, 0x9c, 0x06, 0xe2, 0x9e, 0xc6, 0x0a, - 0x95, 0x7a, 0x52, 0x78, 0x93, 0x37, 0x01, 0x96, 0x1f, 0x07, 0xd4, 0x6b, 0xdb, 0xcd, 0x50, 0x0f, - 0x86, 0xaa, 0x1f, 0x2a, 0xa0, 0xfa, 0x40, 0x2b, 0xc8, 0xa4, 0x0c, 0x93, 0x25, 0xdf, 0xef, 0xb6, - 0xa8, 0xe9, 0x36, 0x69, 0xc9, 0x5c, 0xc3, 0x7d, 0x7f, 0x6c, 0xe9, 0xf9, 0x93, 0xe3, 0xe2, 0x45, - 0x1b, 0x0b, 0x2c, 0xcf, 0x6d, 0x52, 0xcb, 0xf6, 0xd4, 0xd9, 0xad, 0xd3, 0x90, 0x75, 0x80, 0xf5, - 0x0e, 0x6d, 0xd7, 0xa8, 0xed, 0xd5, 0xf7, 0x63, 0xdb, 0x7c, 0x54, 0xb0, 0xf4, 0x9c, 0x68, 0xe1, - 0x9c, 0xdb, 0xa1, 0x6d, 0x1f, 0x61, 0xea, 0x57, 0x45, 0x98, 0x64, 0x1b, 0xa6, 0xab, 0xa5, 0x07, - 0x1b, 0x6e, 0xd3, 0xa9, 0x1f, 0x09, 0xc9, 0x69, 0x0a, 0xb5, 0x83, 0xe7, 0x05, 0xd7, 0x58, 0x29, - 0xdf, 0x9e, 0x1c, 0xbb, 0x65, 0x75, 0x10, 0x6a, 0x09, 0xf9, 0x29, 0xce, 0x85, 0xbc, 0xcf, 0xe6, - 0xa0, 0xcf, 0x84, 0xc1, 0x4d, 0x7b, 0xcf, 0x9f, 0x9f, 0xd6, 0xb4, 0x5d, 0xa5, 0xed, 0xda, 0x75, - 0xa5, 0x94, 0x8b, 0x29, 0x0b, 0x7c, 0x22, 0x22, 0xd4, 0x0a, 0xec, 0x3d, 0x5f, 0x9f, 0x88, 0x21, - 0x36, 0xb9, 0x07, 0x50, 0x71, 0xeb, 0xdd, 0x16, 0x6d, 0x07, 0x95, 0xa5, 0xf9, 0x82, 0x7e, 0x15, - 0x08, 0x0b, 0xa2, 0xad, 0xad, 0xe1, 0xd6, 0xb5, 0x99, 0xa8, 0x50, 0x2f, 0xbc, 0x0b, 0x85, 0xf8, - 0x87, 0x9c, 0x51, 0x81, 0x35, 0x59, 0x98, 0x52, 0x5a, 0xbf, 0xfc, 0xd8, 0xf1, 0x03, 0xdf, 0xf8, - 0xa6, 0xb6, 0x02, 0xd9, 0xee, 0x70, 0x9f, 0x1e, 0x6d, 0x78, 0x74, 0xd7, 0x79, 0x2c, 0x36, 0x33, - 0xdc, 0x1d, 0x0e, 0xe8, 0x91, 0xd5, 0x41, 0xa8, 0xba, 0x3b, 0x84, 0xa8, 0xe4, 0x33, 0x90, 0xbf, - 0xff, 0xa0, 0x76, 0x9f, 0x1e, 0x55, 0x2b, 0xe2, 0xa0, 0xe2, 0x64, 0x2d, 0xdf, 0x62, 0xa4, 0xda, - 0x5c, 0x0b, 0x31, 0x8d, 0xa5, 0x68, 0x27, 0x64, 0x35, 0x97, 0x9b, 0x5d, 0x3f, 0xa0, 0x5e, 0xb5, - 0xa2, 0xd6, 0x5c, 0xe7, 0xc0, 0xd8, 0xbe, 0x14, 0xa2, 0x1a, 0xff, 0x26, 0x8b, 0xbb, 0x20, 0x9b, - 0xf0, 0xd5, 0xb6, 0x1f, 0xd8, 0xed, 0x3a, 0x0d, 0x19, 0xe0, 0x84, 0x77, 0x04, 0x34, 0x36, 0xe1, - 0x23, 0x64, 0xbd, 0xea, 0xec, 0xc0, 0x55, 0xb3, 0x2a, 0xa5, 0xe6, 0xa2, 0x5a, 0x51, 0xd5, 0xab, - 0x9e, 0x80, 0xc6, 0xaa, 0x8c, 0x90, 0xc9, 0x15, 0x18, 0xad, 0x96, 0x1e, 0x94, 0xba, 0xc1, 0x3e, - 0xee, 0xc1, 0x79, 0x2e, 0x9f, 0xb3, 0xd9, 0x6a, 0x77, 0x83, 0x7d, 0x53, 0x16, 0x92, 0x1b, 0x78, - 0xef, 0x69, 0xd3, 0x80, 0xab, 0x61, 0xc5, 0xa1, 0xeb, 0x73, 0x50, 0xec, 0xda, 0xc3, 0x40, 0xe4, - 0x55, 0x18, 0x7e, 0xb8, 0x51, 0xae, 0x56, 0xc4, 0xc5, 0x19, 0x4f, 0xa2, 0x47, 0x9d, 0xba, 0xfe, - 0x25, 0x1c, 0x85, 0x2c, 0xc3, 0x54, 0x8d, 0xd6, 0xbb, 0x9e, 0x13, 0x1c, 0xdd, 0xf5, 0xdc, 0x6e, - 0xc7, 0x9f, 0x1f, 0xc5, 0x3a, 0x70, 0xa5, 0xfb, 0xa2, 0xc4, 0xda, 0xc3, 0x22, 0x85, 0x3a, 0x46, - 0x64, 0xfc, 0x4e, 0x26, 0xda, 0x26, 0xc9, 0x15, 0x4d, 0xac, 0x41, 0xdd, 0x0d, 0x13, 0x6b, 0x54, - 0xdd, 0x0d, 0x0a, 0x38, 0x26, 0x90, 0x72, 0xd7, 0x0f, 0xdc, 0xd6, 0x72, 0xbb, 0xd1, 0x71, 0x9d, - 0x76, 0x80, 0x54, 0xbc, 0xf3, 0x8d, 0x93, 0xe3, 0xe2, 0xa5, 0x3a, 0x96, 0x5a, 0x54, 0x14, 0x5b, - 0x31, 0x2e, 0x29, 0xd4, 0x1f, 0x61, 0x3c, 0x8c, 0x3f, 0xc8, 0x6a, 0xc7, 0x1b, 0xfb, 0x3c, 0x93, - 0x76, 0x9a, 0x4e, 0x1d, 0x6f, 0xf4, 0xd8, 0xd0, 0x70, 0x56, 0xe1, 0xe7, 0x79, 0x51, 0x29, 0xef, - 0x21, 0x9d, 0x77, 0x0a, 0x35, 0xf9, 0x02, 0x4c, 0x30, 0x49, 0x43, 0xfc, 0xf4, 0xe7, 0xb3, 0xd8, - 0xd9, 0xcf, 0xa1, 0x16, 0xce, 0xa7, 0x5e, 0xc8, 0x46, 0x13, 0x51, 0x54, 0x0a, 0xd2, 0x80, 0xf9, - 0x4d, 0xcf, 0x6e, 0xfb, 0x4e, 0xb0, 0xdc, 0xae, 0x7b, 0x47, 0x28, 0x19, 0x2d, 0xb7, 0xed, 0x9d, - 0x26, 0x6d, 0x60, 0x73, 0xf3, 0x4b, 0x57, 0x4f, 0x8e, 0x8b, 0x2f, 0x05, 0x1c, 0xc7, 0xa2, 0x21, - 0x92, 0x45, 0x39, 0x96, 0xc2, 0xb9, 0x27, 0x27, 0x26, 0x49, 0xc9, 0x6e, 0xc5, 0x47, 0x18, 0x2e, - 0x24, 0xa0, 0x24, 0x15, 0x8e, 0x06, 0xdb, 0xc3, 0xd4, 0xcf, 0x54, 0x09, 0x8c, 0xff, 0x27, 0x13, - 0x1d, 0xc0, 0xe4, 0x6d, 0x18, 0x17, 0x2b, 0x46, 0x99, 0x17, 0xb8, 0x83, 0xca, 0xe5, 0x15, 0x1b, - 0x59, 0x15, 0x9d, 0xdd, 0xfb, 0x4b, 0xe5, 0x55, 0x65, 0x6e, 0xe0, 0xbd, 0xdf, 0xae, 0x37, 0xe3, - 0x54, 0x12, 0x8d, 0x4d, 0x82, 0xcd, 0xd5, 0x9a, 0xde, 0x2b, 0x38, 0x09, 0x82, 0xa6, 0x9f, 0xd2, - 0x0d, 0x0a, 0xf2, 0x47, 0x6f, 0xf8, 0xff, 0x9c, 0x49, 0x3b, 0xe7, 0xc9, 0x12, 0x4c, 0x6e, 0xbb, - 0xde, 0x01, 0x8e, 0xaf, 0xd2, 0x09, 0x38, 0xf2, 0x87, 0xb2, 0x20, 0xde, 0x20, 0x9d, 0x44, 0xfd, - 0x36, 0xa5, 0x37, 0xf4, 0x6f, 0x8b, 0x71, 0xd0, 0x08, 0xd8, 0x38, 0x84, 0x1c, 0xc3, 0xd5, 0x81, - 0xe3, 0x10, 0x7d, 0x82, 0x36, 0x85, 0x55, 0x74, 0xe3, 0xbf, 0xca, 0xa8, 0xe7, 0x39, 0xeb, 0xe4, - 0x8a, 0xdb, 0xb2, 0x9d, 0xb6, 0xd2, 0x1c, 0xfe, 0xb0, 0x84, 0xd0, 0xf8, 0x97, 0x28, 0xc8, 0xe4, - 0x16, 0xe4, 0xf9, 0xaf, 0x70, 0xaf, 0x45, 0xad, 0x96, 0x20, 0xd4, 0x0f, 0x0a, 0x89, 0x98, 0x18, - 0x99, 0xdc, 0x59, 0x47, 0xe6, 0xb7, 0x33, 0xea, 0x51, 0xfc, 0x61, 0x0f, 0x9b, 0xd8, 0x21, 0x93, - 0x3d, 0xcb, 0x21, 0xf3, 0x91, 0x9b, 0xf0, 0xbd, 0x19, 0x18, 0x57, 0xb4, 0x14, 0xac, 0x0d, 0x1b, - 0x9e, 0xfb, 0x01, 0xad, 0x07, 0x7a, 0x1b, 0x3a, 0x1c, 0x18, 0x6b, 0x43, 0x88, 0xfa, 0x11, 0xda, - 0x60, 0xfc, 0x79, 0x46, 0xdc, 0x91, 0x06, 0xde, 0xe6, 0xf5, 0x2d, 0x39, 0x7b, 0x96, 0x23, 0xf2, - 0x0b, 0x30, 0x6c, 0xd2, 0x86, 0xe3, 0x8b, 0xfb, 0xcd, 0x8c, 0x7a, 0x1f, 0xc3, 0x82, 0x48, 0x6e, - 0xf2, 0xd8, 0x4f, 0xf5, 0x7c, 0xc3, 0x72, 0x26, 0xc8, 0x56, 0xfd, 0x3b, 0x4d, 0xfa, 0xd8, 0xe1, - 0x8b, 0x51, 0x1c, 0xb5, 0x78, 0xbc, 0x39, 0xbe, 0xb5, 0xcb, 0x4a, 0x84, 0x44, 0xad, 0x2e, 0x3c, - 0x8d, 0xc6, 0x78, 0x1f, 0x20, 0xaa, 0x92, 0xdc, 0x87, 0x82, 0x98, 0x0d, 0x4e, 0x7b, 0x8f, 0x0b, - 0x52, 0xa2, 0x0f, 0x8a, 0x27, 0xc7, 0xc5, 0x67, 0xeb, 0x61, 0x99, 0x90, 0x3a, 0x15, 0xbe, 0x09, - 0x42, 0xe3, 0x1f, 0x66, 0x21, 0x5b, 0xc2, 0x01, 0xb9, 0x4f, 0x8f, 0x02, 0x7b, 0xe7, 0x8e, 0xd3, - 0xd4, 0x16, 0xd3, 0x01, 0x42, 0xad, 0x5d, 0x47, 0x53, 0x57, 0x28, 0xc8, 0x6c, 0x31, 0xdd, 0xf7, - 0x76, 0xde, 0x40, 0x42, 0x65, 0x31, 0x1d, 0x78, 0x3b, 0x6f, 0xc4, 0xc9, 0x42, 0x44, 0x62, 0xc0, - 0x08, 0x5f, 0x58, 0x62, 0x0e, 0xc2, 0xc9, 0x71, 0x71, 0x84, 0xaf, 0x3f, 0x53, 0x94, 0x90, 0x8b, - 0x90, 0xab, 0x6d, 0xac, 0x89, 0x1d, 0x10, 0xd5, 0x82, 0x7e, 0xa7, 0x6d, 0x32, 0x18, 0xab, 0x73, - 0xb5, 0x52, 0xda, 0x40, 0x45, 0xc0, 0x70, 0x54, 0x67, 0xb3, 0x61, 0x77, 0xe2, 0xaa, 0x80, 0x10, - 0x91, 0xbc, 0x03, 0xe3, 0xf7, 0x2b, 0xe5, 0x15, 0xd7, 0xe7, 0xbb, 0xd7, 0x48, 0x34, 0xf9, 0x0f, - 0x1a, 0x75, 0x0b, 0x35, 0xf1, 0xf1, 0x63, 0x40, 0xc1, 0x37, 0xbe, 0x95, 0x85, 0x71, 0x45, 0x4f, - 0x46, 0x3e, 0x23, 0x1e, 0x48, 0x33, 0xda, 0x0d, 0x40, 0xc1, 0x60, 0xa5, 0x5c, 0xa9, 0xd2, 0x72, - 0x1b, 0x54, 0x3c, 0x97, 0x46, 0x0a, 0x8c, 0xec, 0x20, 0x0a, 0x8c, 0x37, 0x01, 0xf8, 0x1c, 0xc0, - 0x4f, 0x56, 0xc4, 0x09, 0xc5, 0x4e, 0x42, 0x1d, 0x97, 0x08, 0x99, 0x3c, 0x84, 0xd9, 0x4d, 0xaf, - 0xeb, 0x07, 0xb5, 0x23, 0x3f, 0xa0, 0x2d, 0xc6, 0x6d, 0xc3, 0x75, 0x9b, 0x62, 0xfe, 0xbd, 0x74, - 0x72, 0x5c, 0xbc, 0x8c, 0xc6, 0x1d, 0x96, 0x8f, 0xe5, 0xf8, 0x01, 0x56, 0xc7, 0x75, 0x55, 0xb5, - 0x46, 0x1a, 0x03, 0xc3, 0x84, 0x09, 0x55, 0x29, 0xc2, 0x4e, 0x16, 0xf1, 0x98, 0x24, 0x54, 0xdd, - 0xca, 0xc9, 0x22, 0xbe, 0x32, 0xf9, 0xb8, 0xa5, 0x93, 0x18, 0x9f, 0x51, 0x15, 0x72, 0x83, 0x2e, - 0x6c, 0xe3, 0xfb, 0x33, 0xd1, 0x36, 0xf2, 0xf0, 0x26, 0x79, 0x0b, 0x46, 0xf8, 0xe3, 0x9d, 0x78, - 0xe3, 0x3c, 0x17, 0x5e, 0x6a, 0xd5, 0x97, 0x3d, 0xae, 0x09, 0xff, 0x23, 0xfe, 0xc0, 0xff, 0x8c, - 0x29, 0x48, 0x42, 0x25, 0xba, 0xae, 0x4f, 0x93, 0xdc, 0x51, 0x5d, 0x7c, 0x33, 0x4d, 0x89, 0x6e, - 0xfc, 0xee, 0x10, 0x4c, 0xe9, 0x68, 0xea, 0x0b, 0x5f, 0x66, 0xa0, 0x17, 0xbe, 0x2f, 0x40, 0x9e, - 0xf5, 0x87, 0x53, 0xa7, 0x52, 0x22, 0x7b, 0x09, 0x9f, 0x16, 0x04, 0x4c, 0x7b, 0xb9, 0x06, 0x3e, - 0x1c, 0xec, 0x8e, 0x6b, 0x86, 0x54, 0x64, 0x51, 0x79, 0x86, 0xca, 0x45, 0x42, 0x8a, 0x7c, 0x86, - 0x52, 0xd7, 0x43, 0xf8, 0x20, 0xf5, 0x3a, 0x8c, 0x30, 0xf9, 0x3e, 0x54, 0xc1, 0xe0, 0x57, 0x32, - 0xd1, 0x3f, 0x66, 0xa2, 0xc2, 0x91, 0xc8, 0x36, 0xe4, 0x57, 0x6d, 0x3f, 0xa8, 0x51, 0xda, 0x1e, - 0xe0, 0xed, 0xbe, 0x28, 0xba, 0x6a, 0x16, 0x1f, 0xc6, 0x7d, 0x4a, 0xdb, 0xb1, 0xc7, 0xd7, 0x90, - 0x19, 0xf9, 0x2a, 0x40, 0xd9, 0x6d, 0x07, 0x9e, 0xdb, 0x5c, 0x75, 0xf7, 0xe6, 0x47, 0xf0, 0xee, - 0x7b, 0x29, 0x36, 0x00, 0x11, 0x02, 0xbf, 0xfe, 0x86, 0x0a, 0x9e, 0x3a, 0x2f, 0xb0, 0x9a, 0xee, - 0x9e, 0xba, 0x0e, 0x22, 0x7c, 0x72, 0x07, 0x0a, 0x52, 0xb1, 0xb0, 0xd5, 0xd9, 0xf3, 0x70, 0x82, - 0x8c, 0x46, 0x92, 0x07, 0x7d, 0x1c, 0x58, 0x5d, 0x01, 0x57, 0x77, 0xca, 0x38, 0x0d, 0xf9, 0x0a, - 0x5c, 0x88, 0xc3, 0xe4, 0x28, 0xe7, 0x23, 0x99, 0x5c, 0x65, 0x97, 0x32, 0xef, 0x7b, 0xb1, 0x30, - 0xbe, 0x93, 0x85, 0x0b, 0x3d, 0x1a, 0xcb, 0xd6, 0x03, 0x1e, 0xd7, 0xca, 0x7a, 0x88, 0x9d, 0xd2, - 0xdc, 0xe6, 0xe8, 0x32, 0x64, 0xc5, 0x01, 0x37, 0xb4, 0x54, 0x38, 0x39, 0x2e, 0x4e, 0x68, 0xe3, - 0x98, 0xad, 0x56, 0xc8, 0x3d, 0x18, 0x62, 0x43, 0x34, 0xc0, 0xd3, 0xb9, 0xd4, 0x29, 0x4d, 0x05, - 0x8e, 0x3a, 0x7d, 0x70, 0xe8, 0x90, 0x07, 0xf9, 0x0c, 0xe4, 0x36, 0x37, 0x57, 0x71, 0xee, 0xe4, - 0xb0, 0xed, 0x93, 0x41, 0xd0, 0xd4, 0xa6, 0xea, 0x24, 0xa3, 0xbd, 0x1e, 0x5a, 0x5a, 0x30, 0x74, - 0xf2, 0xa5, 0x98, 0x49, 0xcf, 0xab, 0xfd, 0x07, 0x7a, 0x70, 0x0b, 0x9f, 0x8f, 0x60, 0x58, 0x63, - 0xfc, 0x7c, 0x36, 0x5a, 0xc3, 0x77, 0x9c, 0x66, 0x40, 0x3d, 0xb2, 0xc0, 0x97, 0x64, 0x24, 0x9c, - 0x99, 0xe1, 0x6f, 0x32, 0x1f, 0xad, 0x6f, 0xce, 0x2a, 0x5c, 0xc8, 0xaf, 0x2a, 0x0b, 0x39, 0x87, - 0x0b, 0x79, 0xaa, 0xe7, 0x92, 0x7d, 0x35, 0x65, 0x5e, 0xe2, 0x42, 0x4c, 0x99, 0x7b, 0x2f, 0xc1, - 0xe4, 0x9a, 0xbb, 0xfc, 0x38, 0x08, 0x11, 0xd9, 0x02, 0xcc, 0x9b, 0x3a, 0x90, 0x71, 0x5c, 0x6f, - 0x36, 0xa8, 0xb7, 0xb9, 0x6f, 0xb7, 0xb5, 0xb7, 0x6b, 0x33, 0x01, 0x67, 0xb8, 0x6b, 0xf4, 0x50, - 0xc7, 0x1d, 0xe5, 0xb8, 0x71, 0xb8, 0xf1, 0x7d, 0x59, 0xd9, 0x19, 0x0f, 0x17, 0x9f, 0xd2, 0x37, - 0xd2, 0x37, 0xb4, 0x37, 0xd2, 0xd9, 0x50, 0xbb, 0x1b, 0x3e, 0xf8, 0x2f, 0x9e, 0x62, 0x27, 0xf0, - 0xf7, 0x47, 0x60, 0x42, 0x45, 0x67, 0xfd, 0x50, 0x6a, 0x34, 0x3c, 0xb5, 0x1f, 0xec, 0x46, 0xc3, - 0x33, 0x11, 0xaa, 0x99, 0x05, 0xe4, 0xfa, 0x9a, 0x05, 0x7c, 0x0d, 0xc6, 0xca, 0xad, 0x86, 0xf6, - 0x58, 0x69, 0xa4, 0x7c, 0xde, 0xf5, 0x10, 0x89, 0xaf, 0x85, 0x50, 0x69, 0x59, 0x6f, 0x35, 0x92, - 0x4f, 0x94, 0x11, 0x4b, 0xcd, 0xa2, 0x60, 0xf8, 0xa3, 0x58, 0x14, 0xdc, 0x86, 0xb1, 0x2d, 0x9f, - 0x6e, 0x76, 0xdb, 0x6d, 0xda, 0xc4, 0x69, 0x95, 0xe7, 0xb2, 0x7e, 0xd7, 0xa7, 0x56, 0x80, 0x50, - 0xf5, 0x03, 0x42, 0x54, 0x75, 0x80, 0x47, 0xfb, 0x0c, 0xf0, 0x2d, 0xc8, 0x6f, 0x50, 0xea, 0x61, - 0x9f, 0x8e, 0x47, 0x22, 0x5d, 0x87, 0x52, 0xcf, 0x62, 0x1d, 0xab, 0x59, 0x1a, 0x08, 0x44, 0xcd, - 0x3c, 0x61, 0x62, 0x40, 0xf3, 0x04, 0xf2, 0x02, 0x4c, 0x74, 0xba, 0x3b, 0x4d, 0xa7, 0x8e, 0x7c, - 0x85, 0x5d, 0x83, 0x39, 0xce, 0x61, 0x8c, 0xad, 0x4f, 0xbe, 0x04, 0x93, 0x78, 0xc7, 0x09, 0xa7, - 0xdc, 0x94, 0xf6, 0xaa, 0xa7, 0x95, 0x71, 0x49, 0xa7, 0xce, 0x40, 0x56, 0x8a, 0xf9, 0x8d, 0xce, - 0x88, 0xdc, 0x83, 0xd1, 0x3d, 0x27, 0xb0, 0xf6, 0xbb, 0x3b, 0xf3, 0xd3, 0x9a, 0xed, 0xca, 0x5d, - 0x27, 0x58, 0xe9, 0xee, 0xf0, 0x21, 0x0f, 0x59, 0xe3, 0x8e, 0xb7, 0xe7, 0x04, 0xfb, 0x5d, 0x55, - 0x25, 0x3b, 0xb2, 0x87, 0xb8, 0x0b, 0x35, 0x98, 0xd2, 0x67, 0xc5, 0x13, 0x78, 0x28, 0x0c, 0xcd, - 0x36, 0xf2, 0x85, 0xb1, 0x7b, 0x43, 0x79, 0x28, 0x8c, 0x73, 0x83, 0x0d, 0x13, 0x36, 0xc2, 0xfe, - 0x31, 0xc9, 0xfd, 0xee, 0x0e, 0xf5, 0xda, 0x34, 0xa0, 0xbe, 0xb8, 0x50, 0xf8, 0xe6, 0x50, 0xa9, - 0xd3, 0xf1, 0x8d, 0xff, 0x34, 0x0b, 0xa3, 0xa5, 0xed, 0x5a, 0xb5, 0xbd, 0xeb, 0xe2, 0x73, 0x5f, - 0xf8, 0xca, 0xa3, 0x3e, 0xf7, 0x85, 0xaf, 0x3c, 0xea, 0xdb, 0xce, 0x8d, 0x94, 0x2b, 0x21, 0x5a, - 0x04, 0x2b, 0x57, 0x42, 0xed, 0x32, 0x1b, 0x3d, 0x78, 0xe5, 0x06, 0x78, 0xf0, 0x0a, 0x75, 0x92, - 0x43, 0xa7, 0xeb, 0x24, 0xdf, 0x82, 0xf1, 0x6a, 0x3b, 0xa0, 0x7b, 0x5e, 0xb4, 0x6a, 0xc2, 0xeb, - 0x69, 0x08, 0x56, 0xaf, 0x09, 0x0a, 0x36, 0x9b, 0x92, 0x5c, 0x0f, 0x1a, 0xea, 0x3f, 0x71, 0x4a, - 0x72, 0x75, 0x69, 0x4c, 0xb7, 0x20, 0x11, 0x8d, 0x4a, 0x6c, 0xbe, 0x49, 0xa3, 0x02, 0x2e, 0xc8, - 0x4e, 0x45, 0x0f, 0x01, 0xac, 0x63, 0x97, 0x66, 0xd2, 0x8d, 0x0a, 0x8c, 0xbf, 0x9d, 0x81, 0xb9, - 0xb4, 0x69, 0x44, 0xde, 0x85, 0x09, 0xd7, 0xdb, 0xb3, 0xdb, 0xce, 0x77, 0xf3, 0x16, 0x29, 0x0a, - 0x30, 0x15, 0xae, 0x5e, 0xfb, 0x55, 0x38, 0xeb, 0x10, 0xa5, 0xe5, 0xfa, 0x7d, 0x3d, 0xb5, 0x43, - 0x14, 0xb0, 0xf1, 0x43, 0x59, 0x18, 0x2f, 0x75, 0x3a, 0x4f, 0xb9, 0xc1, 0xd9, 0xe7, 0xb4, 0x03, - 0x44, 0xde, 0xf6, 0xc2, 0x76, 0x0d, 0x64, 0x6b, 0xf6, 0xab, 0x59, 0x98, 0x8e, 0x51, 0xa8, 0x5f, - 0x9f, 0x19, 0xd0, 0xcc, 0x2c, 0x3b, 0xa0, 0x99, 0x59, 0x6e, 0x30, 0x33, 0xb3, 0xa1, 0x8f, 0x72, - 0x28, 0xbc, 0x02, 0xb9, 0x52, 0xa7, 0x13, 0x7f, 0xae, 0xee, 0x74, 0x1e, 0xde, 0xe2, 0x37, 0x76, - 0xbb, 0xd3, 0x31, 0x19, 0x86, 0xb6, 0x53, 0x8f, 0x0c, 0xb8, 0x53, 0x1b, 0xaf, 0xc3, 0x18, 0xf2, - 0x42, 0xe3, 0xae, 0xcb, 0x80, 0x5b, 0x8c, 0xb0, 0xeb, 0xd2, 0xea, 0x12, 0x9b, 0xcf, 0xff, 0x97, - 0x81, 0x61, 0xfc, 0xfd, 0x94, 0xce, 0xb1, 0x45, 0x6d, 0x8e, 0x15, 0x94, 0x39, 0x36, 0xc8, 0xec, - 0xfa, 0x47, 0x39, 0x80, 0xf2, 0xba, 0x59, 0xe3, 0x8a, 0x1d, 0x72, 0x07, 0xa6, 0xed, 0x66, 0xd3, - 0x3d, 0xa4, 0x0d, 0xcb, 0xf5, 0x9c, 0x3d, 0xa7, 0xcd, 0x7b, 0x4e, 0xbe, 0xa1, 0xea, 0x45, 0xea, - 0xcb, 0x8a, 0x28, 0x5a, 0xe7, 0x25, 0x2a, 0x9f, 0x16, 0x0d, 0xf6, 0xdd, 0x86, 0xbc, 0xa2, 0x6a, - 0x7c, 0x44, 0x51, 0x0a, 0x9f, 0x07, 0xbc, 0x44, 0xe5, 0xb3, 0x8f, 0x57, 0x6e, 0x29, 0x21, 0x6b, - 0x7c, 0x44, 0x51, 0x0a, 0x1f, 0x7e, 0x4f, 0xf7, 0xc9, 0x2a, 0xcc, 0x20, 0xc4, 0xaa, 0x7b, 0xb4, - 0x41, 0xdb, 0x81, 0x63, 0x37, 0x7d, 0xa1, 0xd4, 0x40, 0xf5, 0x57, 0xa2, 0x50, 0xbd, 0xd4, 0x61, - 0x61, 0x39, 0x2a, 0x23, 0xd7, 0x61, 0xb4, 0x65, 0x3f, 0xb6, 0xec, 0x3d, 0x6e, 0x4d, 0x30, 0xc9, - 0x2f, 0xc1, 0x02, 0xa4, 0x1e, 0x23, 0x2d, 0xfb, 0x71, 0x69, 0x8f, 0xb2, 0x56, 0xd0, 0xc7, 0x1d, - 0xd7, 0x57, 0x5a, 0x31, 0x12, 0xb5, 0x22, 0x56, 0xa4, 0xb6, 0x42, 0x14, 0x89, 0x56, 0x18, 0xbf, - 0x92, 0x81, 0x67, 0xab, 0xf8, 0x15, 0xc1, 0x51, 0x99, 0xb6, 0x03, 0xea, 0x6d, 0x50, 0xaf, 0xe5, - 0xe0, 0xdb, 0x6a, 0x8d, 0x06, 0xe4, 0x45, 0xc8, 0x95, 0xcc, 0x35, 0x31, 0x7f, 0xf9, 0x7e, 0xaf, - 0xbd, 0x74, 0xb3, 0xd2, 0x50, 0x4f, 0x92, 0x3d, 0x45, 0x01, 0x5a, 0x82, 0x89, 0x92, 0xef, 0x3b, - 0x7b, 0xed, 0x16, 0xb7, 0xd2, 0xcf, 0x69, 0x6f, 0xe9, 0x02, 0x9e, 0xd0, 0xdc, 0xab, 0x24, 0xc6, - 0x7f, 0x96, 0x81, 0x99, 0x52, 0xa7, 0xa3, 0x7f, 0xb2, 0x6e, 0xc7, 0x91, 0x19, 0xdc, 0x8e, 0xc3, - 0x81, 0x29, 0xad, 0xb9, 0x7c, 0x4a, 0x45, 0x82, 0x6f, 0x9f, 0x9e, 0xe1, 0x9f, 0xdd, 0x09, 0x41, - 0x96, 0xaf, 0x3f, 0x42, 0xc6, 0x18, 0x1b, 0xff, 0xc1, 0x28, 0xee, 0x21, 0x62, 0xb7, 0x15, 0x96, - 0x86, 0x99, 0x14, 0x4b, 0xc3, 0x37, 0x41, 0x91, 0x70, 0xd4, 0x23, 0x4e, 0x91, 0x15, 0x55, 0x0d, - 0x43, 0x84, 0x4c, 0x0e, 0xe2, 0x36, 0x87, 0x39, 0x6c, 0xcd, 0x8b, 0xf1, 0x05, 0xfc, 0x44, 0xcc, - 0x0d, 0x57, 0x80, 0x54, 0xdb, 0xf8, 0x30, 0x4a, 0x6b, 0x07, 0x4e, 0xe7, 0x21, 0xf5, 0x9c, 0xdd, - 0x23, 0xb1, 0x00, 0xb0, 0xf3, 0x1d, 0x51, 0x6a, 0xf9, 0x07, 0x4e, 0xc7, 0x7a, 0x84, 0xe5, 0x66, - 0x0a, 0x0d, 0x79, 0x0f, 0x46, 0x4d, 0x7a, 0xe8, 0x39, 0x81, 0xb4, 0xa4, 0x99, 0x0a, 0x15, 0x66, - 0x08, 0xe5, 0x6b, 0xc1, 0xe3, 0x3f, 0xd4, 0x5d, 0x51, 0x94, 0x93, 0x45, 0x2e, 0xa4, 0x70, 0x8b, - 0x99, 0xc9, 0xa8, 0xb5, 0xa5, 0xed, 0x5a, 0x2f, 0x19, 0x85, 0x5c, 0x83, 0x61, 0x94, 0x74, 0xc4, - 0x5d, 0x00, 0x3d, 0x50, 0x50, 0x76, 0x56, 0xc5, 0x30, 0xc4, 0x20, 0x97, 0x00, 0xc2, 0x97, 0x47, - 0x7f, 0x3e, 0x8f, 0x52, 0xba, 0x02, 0x89, 0x8b, 0x69, 0x63, 0x67, 0x12, 0xd3, 0x56, 0xa1, 0x60, - 0x72, 0x67, 0xb6, 0x46, 0xa9, 0x83, 0xcf, 0x5b, 0xfe, 0x3c, 0xe0, 0x4a, 0xbe, 0x7c, 0x72, 0x5c, - 0x7c, 0x4e, 0x38, 0xba, 0x35, 0x2c, 0xbb, 0xc3, 0x5f, 0xc5, 0xb4, 0x6d, 0x24, 0x4e, 0x49, 0xde, - 0x84, 0x21, 0xb6, 0xf5, 0x0a, 0xeb, 0x44, 0xf9, 0x4c, 0x10, 0xed, 0xc6, 0x7c, 0x71, 0xd6, 0x5d, - 0x6d, 0x4f, 0x40, 0x12, 0x62, 0xc1, 0x94, 0x3e, 0xdd, 0x85, 0xa1, 0xca, 0x7c, 0xd4, 0x9f, 0x7a, - 0xb9, 0x78, 0x3b, 0x10, 0x30, 0xab, 0x8e, 0x40, 0x75, 0x05, 0xc4, 0x16, 0xe9, 0x32, 0xe4, 0x37, - 0xcb, 0x1b, 0x1b, 0xae, 0x17, 0xf0, 0xab, 0x4e, 0x74, 0xb2, 0x30, 0x98, 0x69, 0xb7, 0xf7, 0x28, - 0x3f, 0x8b, 0x83, 0x7a, 0xc7, 0xea, 0x30, 0x34, 0xf5, 0x2c, 0x96, 0xa4, 0x1f, 0x9f, 0x65, 0xe2, - 0xaf, 0x66, 0xe1, 0xc5, 0x50, 0x2a, 0x5a, 0xf7, 0x6a, 0xa5, 0x07, 0xab, 0xd5, 0xc6, 0x86, 0x50, - 0x93, 0x6c, 0x78, 0xee, 0x23, 0xa7, 0x41, 0xbd, 0x87, 0x37, 0x4f, 0x39, 0xd3, 0x57, 0xf9, 0x32, - 0xe7, 0x6f, 0x2c, 0x59, 0xcd, 0x86, 0x4b, 0x11, 0x3e, 0xc5, 0xf6, 0xd4, 0xe9, 0x24, 0x9e, 0x5c, - 0x56, 0x9e, 0x31, 0x23, 0x06, 0xe4, 0xfb, 0x33, 0x70, 0x3e, 0xfd, 0x43, 0x84, 0xea, 0xac, 0x28, - 0xaf, 0xe8, 0x3d, 0xbe, 0x76, 0xe9, 0x95, 0x93, 0xe3, 0xe2, 0x8b, 0xbe, 0xdd, 0x6a, 0x5a, 0x4e, - 0x83, 0xd7, 0xe6, 0xd4, 0xa9, 0xd5, 0x11, 0x08, 0x5a, 0xbd, 0x3d, 0x6a, 0xfa, 0x3c, 0xc8, 0xa3, - 0x7d, 0x3e, 0xb3, 0x04, 0x90, 0x97, 0x6a, 0x6c, 0xe3, 0x37, 0x32, 0xa0, 0x2c, 0xc1, 0xbc, 0x49, - 0x1b, 0x8e, 0x47, 0xeb, 0x81, 0x38, 0xde, 0x85, 0x07, 0x1a, 0x87, 0xc5, 0x4c, 0xf6, 0x10, 0x46, - 0xde, 0x85, 0x51, 0x71, 0x0c, 0x89, 0x6d, 0x57, 0x2e, 0x5d, 0xa1, 0x20, 0xe7, 0xae, 0x8a, 0x89, - 0x23, 0x4c, 0x12, 0xb1, 0x5d, 0xff, 0xde, 0xf6, 0x66, 0xb9, 0x69, 0x3b, 0x2d, 0x5f, 0x9c, 0x25, - 0xd8, 0xad, 0x1f, 0x1c, 0x06, 0x56, 0x1d, 0xa1, 0xea, 0xae, 0x1f, 0xa2, 0x1a, 0x77, 0xa5, 0x7e, - 0xfe, 0x14, 0xbb, 0xd3, 0x22, 0x0c, 0x3f, 0x8c, 0xf4, 0x74, 0x4b, 0x63, 0x27, 0xc7, 0x45, 0x3e, - 0x5d, 0x4c, 0x0e, 0x37, 0x28, 0x8c, 0x85, 0x53, 0x97, 0xf1, 0x62, 0x3f, 0x90, 0xd7, 0x24, 0xe7, - 0xc5, 0x26, 0xb1, 0x89, 0x50, 0x26, 0xea, 0x2d, 0xb7, 0x1b, 0x88, 0x90, 0x45, 0x04, 0xec, 0x1e, - 0xda, 0x6e, 0xe0, 0x4c, 0x57, 0x5b, 0x27, 0xd0, 0x14, 0x81, 0xea, 0x47, 0x32, 0x30, 0xa5, 0x4f, - 0x5b, 0x72, 0x1d, 0x46, 0x84, 0x93, 0x59, 0x06, 0xd5, 0x9e, 0x8c, 0xdb, 0x08, 0x77, 0x2f, 0xd3, - 0x9c, 0xca, 0x04, 0x16, 0x93, 0x1b, 0x05, 0x07, 0x21, 0x34, 0xa1, 0xdc, 0x58, 0xe7, 0x20, 0x53, - 0x96, 0x11, 0x83, 0x5d, 0x65, 0xfd, 0x6e, 0x33, 0x50, 0x5f, 0xc3, 0x3c, 0x84, 0x98, 0xa2, 0xc4, - 0x28, 0xc3, 0x08, 0xdf, 0x5a, 0x63, 0x66, 0x75, 0x99, 0x33, 0x98, 0xd5, 0x19, 0xc7, 0x19, 0x80, - 0x5a, 0x6d, 0xe5, 0x3e, 0x3d, 0xda, 0xb0, 0x1d, 0x3c, 0xbf, 0xf9, 0x31, 0x76, 0x5f, 0xac, 0xe1, - 0x09, 0xf1, 0x7c, 0xcb, 0x8f, 0xbc, 0x03, 0x7a, 0xa4, 0x3d, 0xdf, 0x4a, 0x54, 0x3c, 0x2b, 0x3d, - 0xe7, 0x91, 0x1d, 0x50, 0x46, 0x98, 0x45, 0x42, 0x7e, 0x56, 0x72, 0x68, 0x8c, 0x52, 0x41, 0x26, - 0x5f, 0x85, 0xa9, 0xe8, 0x57, 0xf8, 0x08, 0x3d, 0x15, 0xee, 0x13, 0x7a, 0xe1, 0xd2, 0xa5, 0x93, - 0xe3, 0xe2, 0x82, 0xc2, 0x35, 0xfe, 0x3c, 0x1d, 0x63, 0x66, 0xfc, 0x52, 0x06, 0x4d, 0x2f, 0x64, - 0x03, 0xaf, 0xc0, 0x50, 0x68, 0x2c, 0x3c, 0x21, 0x36, 0x61, 0xfd, 0xa1, 0x0d, 0xcb, 0x99, 0xb8, - 0x15, 0xb5, 0x04, 0x8f, 0x2e, 0xbd, 0x05, 0xac, 0x94, 0xdc, 0x85, 0xd1, 0x81, 0xbe, 0x19, 0xa7, - 0x58, 0xca, 0xb7, 0x4a, 0x6a, 0x1c, 0x85, 0x7b, 0xdb, 0x9b, 0x9f, 0xdc, 0x51, 0xf8, 0xf1, 0x2c, - 0x4c, 0xb3, 0x7e, 0x2d, 0x75, 0x83, 0x7d, 0xd7, 0x73, 0x82, 0xa3, 0xa7, 0x56, 0x6f, 0xfc, 0xb6, - 0x76, 0x25, 0x5b, 0x90, 0x87, 0x99, 0xda, 0xb6, 0x81, 0xd4, 0xc7, 0xff, 0x74, 0x18, 0x66, 0x53, - 0xa8, 0xc8, 0x6b, 0xda, 0xd3, 0xce, 0xbc, 0x74, 0x22, 0xff, 0xce, 0x71, 0x71, 0x42, 0xa2, 0x6f, - 0x46, 0x4e, 0xe5, 0x8b, 0xba, 0x1d, 0x13, 0xef, 0x29, 0x7c, 0xe9, 0x51, 0xed, 0x98, 0x74, 0xeb, - 0xa5, 0x6b, 0x30, 0x6c, 0xba, 0x4d, 0x2a, 0x6d, 0xf7, 0x50, 0xe0, 0xf2, 0x18, 0x40, 0xb3, 0x55, - 0x60, 0x00, 0xb2, 0x02, 0xa3, 0xec, 0x8f, 0x07, 0x76, 0x47, 0xbc, 0xc2, 0x91, 0x50, 0x29, 0x80, - 0xd0, 0x8e, 0xd3, 0xde, 0x53, 0xf5, 0x02, 0x4d, 0x6a, 0xb5, 0xec, 0x8e, 0x26, 0x19, 0x72, 0x44, - 0x4d, 0xbf, 0x90, 0xef, 0xad, 0x5f, 0xc8, 0x9c, 0xaa, 0x5f, 0xd8, 0x05, 0xa8, 0x39, 0x7b, 0x6d, - 0xa7, 0xbd, 0x57, 0x6a, 0xee, 0x09, 0x57, 0xfc, 0x6b, 0xbd, 0x47, 0xe1, 0x7a, 0x84, 0x8c, 0x13, - 0xf7, 0x59, 0x7c, 0x2a, 0xe7, 0x30, 0xcb, 0x6e, 0xee, 0x69, 0x2e, 0x43, 0x0a, 0x67, 0xb2, 0x06, - 0x50, 0xaa, 0x07, 0xce, 0x23, 0x36, 0x85, 0x7d, 0x21, 0xc6, 0xc9, 0x4f, 0x2e, 0x97, 0xee, 0xd3, - 0x23, 0xbc, 0x7a, 0xc8, 0x47, 0x47, 0x1b, 0x51, 0xd9, 0x4a, 0xd0, 0xfc, 0x41, 0x22, 0x0e, 0xa4, - 0x03, 0xe7, 0x4a, 0x8d, 0x86, 0xc3, 0xda, 0x60, 0x37, 0x37, 0x79, 0x10, 0x05, 0x64, 0x3d, 0x91, - 0xce, 0xfa, 0x9a, 0x60, 0xfd, 0x82, 0x1d, 0x52, 0x59, 0x32, 0xf6, 0x42, 0xac, 0x9a, 0x74, 0xc6, - 0x46, 0x0d, 0xa6, 0xf4, 0xc6, 0xeb, 0x21, 0x04, 0x26, 0x20, 0x6f, 0xd6, 0x4a, 0x56, 0x6d, 0xa5, - 0x74, 0xb3, 0x90, 0x21, 0x05, 0x98, 0x10, 0xbf, 0x16, 0xad, 0xc5, 0x37, 0x6e, 0x17, 0xb2, 0x1a, - 0xe4, 0x8d, 0x9b, 0x8b, 0x85, 0xdc, 0x42, 0x76, 0x3e, 0x13, 0xf3, 0xde, 0x1b, 0x2d, 0xe4, 0xb9, - 0x4a, 0xd8, 0xf8, 0xb5, 0x0c, 0xe4, 0xe5, 0xb7, 0x93, 0xdb, 0x90, 0xab, 0xd5, 0x56, 0x62, 0xfe, - 0x76, 0xd1, 0x29, 0xc3, 0xf7, 0x53, 0xdf, 0x57, 0x8d, 0xaa, 0x19, 0x01, 0xa3, 0xdb, 0x5c, 0xad, - 0x09, 0x19, 0x44, 0xd2, 0x45, 0x9b, 0x37, 0xa7, 0x4b, 0x71, 0x42, 0xba, 0x0d, 0xb9, 0x7b, 0xdb, - 0x9b, 0xe2, 0x92, 0x25, 0xe9, 0xa2, 0xfd, 0x94, 0xd3, 0x7d, 0x70, 0xa8, 0xee, 0xf2, 0x8c, 0xc0, - 0x30, 0x61, 0x5c, 0x99, 0xc8, 0xfc, 0xd0, 0x6d, 0xb9, 0xa1, 0xdf, 0xbc, 0x38, 0x74, 0x19, 0xc4, - 0x14, 0x25, 0x4c, 0x14, 0x59, 0x75, 0xeb, 0x76, 0x53, 0x9c, 0xde, 0x28, 0x8a, 0x34, 0x19, 0xc0, - 0xe4, 0x70, 0xe3, 0x77, 0x32, 0x50, 0x40, 0x81, 0x0d, 0x8d, 0xa2, 0xdd, 0x03, 0xda, 0x7e, 0x78, - 0x93, 0xbc, 0x2e, 0x97, 0x5c, 0x26, 0x54, 0x74, 0x0d, 0xe3, 0x92, 0x8b, 0xbd, 0x05, 0x8a, 0x65, - 0xa7, 0x84, 0x26, 0xc8, 0x0e, 0xee, 0xd2, 0x7c, 0x4a, 0x68, 0x82, 0x22, 0x0c, 0xe3, 0xe7, 0x88, - 0xcd, 0x11, 0xbf, 0x3c, 0x60, 0x00, 0x93, 0xc3, 0x95, 0xbd, 0xe9, 0x27, 0xb3, 0x89, 0x36, 0x2c, - 0x7e, 0xa2, 0xdc, 0x82, 0xf5, 0xc6, 0x0d, 0xb4, 0x5f, 0xbf, 0x0f, 0x73, 0xf1, 0x2e, 0x41, 0x25, - 0x64, 0x09, 0xa6, 0x75, 0xb8, 0xd4, 0x47, 0x5e, 0x48, 0xad, 0xeb, 0xe1, 0xa2, 0x19, 0xc7, 0x37, - 0xfe, 0xf7, 0x0c, 0x8c, 0xe1, 0x9f, 0x66, 0xb7, 0x89, 0xc6, 0x69, 0xa5, 0xed, 0x9a, 0x50, 0x8d, - 0xa8, 0xc2, 0x9c, 0x7d, 0xe8, 0x5b, 0x42, 0x8f, 0xa2, 0xed, 0x31, 0x21, 0xb2, 0x20, 0xe5, 0xef, - 0x1b, 0x52, 0x29, 0x17, 0x92, 0xf2, 0x87, 0x10, 0x3f, 0x46, 0x2a, 0x90, 0xd1, 0xa4, 0x75, 0xbb, - 0xc6, 0xa6, 0x9f, 0x6a, 0x2d, 0x82, 0x74, 0x6e, 0x53, 0x37, 0x69, 0xe5, 0x68, 0x68, 0x2c, 0xb2, - 0x5d, 0x2b, 0x99, 0x6b, 0x9a, 0xb1, 0x08, 0xfb, 0x46, 0x4d, 0x2f, 0x25, 0x90, 0x8c, 0x9f, 0x1f, - 0x8f, 0x77, 0xa0, 0x38, 0xf0, 0xce, 0xb8, 0x36, 0xde, 0x82, 0xe1, 0x52, 0xb3, 0xe9, 0x1e, 0x8a, - 0x5d, 0x42, 0xde, 0x5c, 0xc3, 0xfe, 0xe3, 0xe7, 0x19, 0xaa, 0xf5, 0x34, 0x57, 0x47, 0x06, 0x20, - 0x65, 0x18, 0x2b, 0x6d, 0xd7, 0xaa, 0xd5, 0xca, 0xe6, 0x26, 0x77, 0xeb, 0xca, 0x2d, 0xbd, 0x2c, - 0xfb, 0xc7, 0x71, 0x1a, 0x56, 0xdc, 0x5e, 0x21, 0x92, 0xdf, 0x23, 0x3a, 0xf2, 0x0e, 0xc0, 0x3d, - 0xd7, 0x69, 0x73, 0x35, 0xa6, 0x68, 0x3c, 0xbb, 0x81, 0x8f, 0x7f, 0xe0, 0x3a, 0x6d, 0xa1, 0xf7, - 0x64, 0xdf, 0x1e, 0x21, 0x99, 0xca, 0xdf, 0xac, 0xa7, 0x97, 0x5c, 0x6e, 0x70, 0x36, 0x1c, 0xf5, - 0xf4, 0x8e, 0x9b, 0xd0, 0xb7, 0x49, 0x34, 0xd2, 0x82, 0xe9, 0x5a, 0x77, 0x6f, 0x8f, 0xb2, 0x9d, - 0x5d, 0xe8, 0x93, 0x46, 0xc4, 0x55, 0x3a, 0x0c, 0xa6, 0xc3, 0xef, 0x23, 0xec, 0x32, 0xe4, 0x2f, - 0xbd, 0xc6, 0x26, 0xf2, 0xb7, 0x8f, 0x8b, 0xc2, 0x0e, 0x82, 0x89, 0x6a, 0xbe, 0xa4, 0x4f, 0x6a, - 0x93, 0xe2, 0xbc, 0xc9, 0x3a, 0x8c, 0xf0, 0x37, 0x23, 0xe1, 0xa6, 0xf4, 0x42, 0x9f, 0x45, 0xc3, - 0x11, 0x7b, 0xbd, 0x4a, 0xf2, 0x52, 0xb2, 0x0d, 0xf9, 0xb2, 0xe3, 0xd5, 0x9b, 0xb4, 0x5c, 0x15, - 0x67, 0xff, 0x8b, 0x7d, 0x58, 0x4a, 0x54, 0xde, 0x2f, 0x75, 0xfc, 0x55, 0x77, 0x54, 0x59, 0x40, - 0x62, 0x90, 0xbf, 0x9d, 0x81, 0x67, 0xc3, 0xaf, 0x2f, 0xed, 0xd1, 0x76, 0xf0, 0xc0, 0x0e, 0xea, - 0xfb, 0xd4, 0x13, 0xbd, 0x34, 0xd6, 0xaf, 0x97, 0x3e, 0x9f, 0xe8, 0xa5, 0xab, 0x51, 0x2f, 0xd9, - 0x8c, 0x99, 0xd5, 0xe2, 0xdc, 0x92, 0x7d, 0xd6, 0xaf, 0x56, 0x62, 0x01, 0x44, 0xaf, 0xa1, 0xc2, - 0xcd, 0xf5, 0xe5, 0x3e, 0x0d, 0x8e, 0x90, 0x85, 0x7b, 0x4a, 0xf8, 0x5b, 0xb3, 0xaf, 0x0c, 0xa1, - 0xe4, 0xbe, 0xf4, 0x09, 0xe4, 0x52, 0xc9, 0xe5, 0x3e, 0xbc, 0xb9, 0x9f, 0xe0, 0x6c, 0x1f, 0xef, - 0x5f, 0x3e, 0xda, 0xab, 0xf6, 0x8e, 0x10, 0x44, 0x4e, 0x19, 0xed, 0x55, 0x3b, 0x1a, 0xed, 0xa6, - 0x1d, 0x1f, 0xed, 0x55, 0x7b, 0x87, 0x94, 0xb9, 0x23, 0x33, 0xf7, 0x7a, 0xbd, 0xd4, 0x8f, 0x5b, - 0x79, 0x83, 0x9f, 0xcc, 0x29, 0x0e, 0xcd, 0x5f, 0x86, 0xb1, 0x5a, 0xc7, 0xae, 0xd3, 0xa6, 0xb3, - 0x1b, 0x88, 0xa7, 0xf6, 0x97, 0xfa, 0xb0, 0x0a, 0x71, 0xc5, 0xd3, 0xaa, 0xfc, 0xa9, 0x5e, 0x93, - 0x42, 0x1c, 0xf6, 0x85, 0x9b, 0x1b, 0x0f, 0xc4, 0x6b, 0x7b, 0xbf, 0x2f, 0xdc, 0xdc, 0x78, 0x20, - 0x64, 0x8e, 0x4e, 0x4b, 0x93, 0x39, 0x36, 0x1e, 0x90, 0x0e, 0x4c, 0x6d, 0x52, 0xcf, 0xb3, 0x77, - 0x5d, 0xaf, 0xc5, 0xf5, 0x97, 0xdc, 0x93, 0xea, 0x5a, 0x3f, 0x7e, 0x1a, 0x01, 0x57, 0xdb, 0x05, - 0x12, 0x66, 0xc5, 0x95, 0x9e, 0x31, 0xfe, 0xac, 0x4f, 0x96, 0x9c, 0x60, 0xa7, 0x5b, 0x3f, 0xa0, - 0xc1, 0xfc, 0xcc, 0xa9, 0x7d, 0x12, 0xe2, 0xf2, 0x3e, 0xd9, 0x91, 0x3f, 0xd5, 0x3e, 0x09, 0x71, - 0x8c, 0xdf, 0xcc, 0xc1, 0x85, 0x1e, 0x5d, 0x40, 0xd6, 0xe4, 0x96, 0x9b, 0xd1, 0xb4, 0xd8, 0x3d, - 0xd0, 0xaf, 0x9f, 0xba, 0x0b, 0xaf, 0x42, 0x61, 0xf9, 0x3e, 0xca, 0xea, 0xfc, 0x21, 0xa7, 0x5c, - 0x92, 0x87, 0x15, 0x6a, 0x5a, 0xe9, 0x01, 0x5a, 0x9e, 0xca, 0x07, 0xa0, 0xba, 0xe6, 0x62, 0x9d, - 0xa0, 0x5c, 0xf8, 0xbe, 0x2c, 0x0c, 0xe1, 0xc1, 0x19, 0x0b, 0x2c, 0x95, 0x39, 0x53, 0x60, 0xa9, - 0x2f, 0xc0, 0xc4, 0xf2, 0x7d, 0x7e, 0x93, 0x5e, 0xb1, 0xfd, 0x7d, 0xb1, 0xad, 0xa3, 0x21, 0x07, - 0x3d, 0xb0, 0xc4, 0xc5, 0x7b, 0xdf, 0xd6, 0x64, 0x56, 0x8d, 0x82, 0x6c, 0xc1, 0x2c, 0xff, 0x36, - 0x67, 0xd7, 0xa9, 0xf3, 0xf8, 0x34, 0x8e, 0xdd, 0x14, 0x7b, 0xfc, 0x8b, 0x27, 0xc7, 0xc5, 0x22, - 0x3d, 0x40, 0x9b, 0x5a, 0x51, 0x6e, 0xf9, 0x88, 0xa0, 0x1a, 0xd7, 0xa6, 0xd0, 0xab, 0x41, 0x33, - 0xcc, 0x31, 0xac, 0x90, 0xd5, 0xc6, 0xea, 0x66, 0xb8, 0x1c, 0xc9, 0xf8, 0xb3, 0x61, 0x58, 0xe8, - 0xbd, 0x3d, 0x93, 0x2f, 0xea, 0x03, 0x78, 0xe5, 0xd4, 0x0d, 0xfd, 0xf4, 0x31, 0xfc, 0x12, 0xcc, - 0x2d, 0xb7, 0x03, 0xea, 0x75, 0x3c, 0x47, 0x86, 0x49, 0x59, 0x71, 0x7d, 0x69, 0xc3, 0x8c, 0xc6, - 0xc4, 0x34, 0x2c, 0x17, 0xba, 0x55, 0xb4, 0xa8, 0x56, 0x58, 0xa5, 0x72, 0x20, 0xcb, 0x30, 0xa5, - 0xc0, 0x9b, 0xdd, 0x3d, 0xf5, 0x75, 0x4a, 0xe5, 0xd9, 0xec, 0xaa, 0x06, 0x9e, 0x31, 0x22, 0xb4, - 0x93, 0x66, 0x57, 0xc6, 0xfa, 0xbd, 0xed, 0xfb, 0x35, 0x31, 0x9c, 0xdc, 0x4e, 0x1a, 0xa1, 0xd6, - 0x07, 0x87, 0x07, 0xda, 0xfe, 0x1a, 0x21, 0x2f, 0xfc, 0x52, 0x4e, 0xcc, 0xa8, 0x17, 0x21, 0x57, - 0xeb, 0xee, 0xa8, 0x6f, 0x6e, 0xbe, 0x76, 0xc0, 0xb1, 0x52, 0xf2, 0x39, 0x00, 0x93, 0x76, 0x5c, - 0xdf, 0x09, 0x5c, 0xef, 0x48, 0x75, 0xd4, 0xf3, 0x42, 0xa8, 0xee, 0x4b, 0x20, 0xa1, 0x64, 0x05, - 0xa6, 0xa3, 0x5f, 0xeb, 0x87, 0x6d, 0xa1, 0x4b, 0x1e, 0xe3, 0xda, 0x95, 0x88, 0xdc, 0x72, 0x59, - 0x99, 0x7a, 0x64, 0xc7, 0xc8, 0xc8, 0x22, 0xe4, 0xb7, 0x5d, 0xef, 0x60, 0x97, 0x8d, 0xf1, 0x50, - 0x24, 0x54, 0x1c, 0x0a, 0x98, 0x7a, 0x78, 0x4a, 0x3c, 0xb6, 0x5c, 0x96, 0xdb, 0x8f, 0x1c, 0xcf, - 0xc5, 0x17, 0x3d, 0xd5, 0xa6, 0x85, 0x46, 0x60, 0xcd, 0x45, 0x3a, 0x02, 0x93, 0x6b, 0x30, 0x5c, - 0xaa, 0x07, 0xae, 0x27, 0x0c, 0x5a, 0xf8, 0x4c, 0x61, 0x00, 0x6d, 0xa6, 0x30, 0x00, 0xeb, 0x44, - 0x93, 0xee, 0x8a, 0xd7, 0x1d, 0xec, 0x44, 0x8f, 0xee, 0x6a, 0xfe, 0xdf, 0x74, 0x97, 0x09, 0x45, - 0x26, 0xdd, 0x45, 0xc5, 0x87, 0x16, 0x36, 0x6d, 0x37, 0xa1, 0x32, 0x13, 0x68, 0xc6, 0xef, 0x8f, - 0xf5, 0x9c, 0xf2, 0xec, 0x14, 0x3a, 0xdb, 0x94, 0x5f, 0xb5, 0x07, 0x98, 0xf2, 0xaf, 0x85, 0x1e, - 0x0a, 0x6a, 0xd0, 0x03, 0x84, 0xa8, 0xc7, 0x20, 0xc7, 0x59, 0xf8, 0xe5, 0xfc, 0x59, 0x26, 0x91, - 0xe8, 0xa4, 0xec, 0xa0, 0x9d, 0x94, 0x1b, 0xa8, 0x93, 0xc8, 0x12, 0x4c, 0x86, 0x81, 0xf7, 0x36, - 0xec, 0x40, 0xdb, 0xd6, 0xc2, 0x68, 0x89, 0x56, 0xc7, 0x0e, 0xd4, 0x6d, 0x4d, 0x27, 0x21, 0x6f, - 0xc3, 0xb8, 0x70, 0xd3, 0x41, 0x0e, 0xc3, 0x91, 0xa5, 0x90, 0xf4, 0xe9, 0x89, 0xd1, 0xab, 0xe8, - 0x6c, 0x35, 0x6f, 0x38, 0x1d, 0xda, 0x74, 0xda, 0xb4, 0x86, 0x8f, 0x15, 0x62, 0xc6, 0xf0, 0x47, - 0x5b, 0x51, 0x62, 0xf1, 0x77, 0x0c, 0x4d, 0x7f, 0xa8, 0x11, 0xc5, 0x27, 0xeb, 0xe8, 0x99, 0x26, - 0x2b, 0xb7, 0x53, 0xf4, 0x56, 0xdd, 0x3d, 0x47, 0x5a, 0x66, 0x4b, 0x3b, 0x45, 0xcf, 0x6a, 0x32, - 0x68, 0xcc, 0x4e, 0x91, 0xa3, 0xb2, 0x1b, 0x0e, 0xfb, 0x51, 0xad, 0x88, 0x97, 0x44, 0xbc, 0xe1, - 0x20, 0x91, 0x6e, 0x0e, 0xcf, 0x91, 0x64, 0x35, 0xcb, 0x2d, 0xdb, 0x69, 0x0a, 0xdf, 0xf6, 0xa8, - 0x1a, 0xca, 0xa0, 0xf1, 0x6a, 0x10, 0x95, 0xd4, 0x61, 0xc2, 0xa4, 0xbb, 0x1b, 0x9e, 0x1b, 0xd0, - 0x7a, 0x40, 0x1b, 0x42, 0xaa, 0x93, 0x17, 0x9b, 0x25, 0xd7, 0xe5, 0x12, 0xeb, 0xd2, 0xeb, 0xbf, - 0x7f, 0x5c, 0xcc, 0x7c, 0xfb, 0xb8, 0x08, 0x0c, 0xc4, 0x7d, 0x2d, 0x4e, 0x8e, 0x8b, 0x17, 0xd8, - 0xf8, 0x77, 0x24, 0xb1, 0x7a, 0x3a, 0xa9, 0x4c, 0xc9, 0x37, 0xd9, 0x7e, 0x1d, 0x76, 0x49, 0x54, - 0xd9, 0x44, 0x8f, 0xca, 0xde, 0x48, 0xad, 0xac, 0xa8, 0xf4, 0x76, 0x6a, 0xa5, 0xa9, 0x95, 0x90, - 0x77, 0x60, 0xbc, 0x5c, 0x2d, 0xbb, 0xed, 0x5d, 0x67, 0xaf, 0xb6, 0x52, 0x42, 0xd1, 0x50, 0xf8, - 0xd9, 0xd4, 0x1d, 0xab, 0x8e, 0x70, 0xcb, 0xdf, 0xb7, 0x35, 0x77, 0xcb, 0x08, 0x9f, 0xdc, 0x85, - 0x29, 0xf9, 0xd3, 0xa4, 0xbb, 0x5b, 0x66, 0x15, 0x25, 0x42, 0xe9, 0xdc, 0x14, 0x72, 0x60, 0x1d, - 0xd1, 0xf5, 0xd4, 0x9b, 0x42, 0x8c, 0x8c, 0x4d, 0xc6, 0x0a, 0xed, 0x34, 0xdd, 0x23, 0xf6, 0x79, - 0x9b, 0x0e, 0xf5, 0x50, 0x06, 0x14, 0x93, 0xb1, 0x11, 0x96, 0x58, 0x81, 0xa3, 0xbf, 0x9f, 0xea, - 0x44, 0x64, 0x0d, 0x66, 0xc4, 0x14, 0x7f, 0xe8, 0xf8, 0xce, 0x8e, 0xd3, 0x74, 0x82, 0x23, 0x94, - 0xfe, 0x84, 0x00, 0x23, 0xd7, 0xc5, 0xa3, 0xb0, 0x54, 0x61, 0x96, 0x24, 0x35, 0x7e, 0x2d, 0x0b, - 0xcf, 0xf5, 0xbb, 0x09, 0x91, 0x9a, 0xbe, 0x99, 0x5d, 0x1d, 0xe0, 0xf6, 0x74, 0xfa, 0x76, 0xb6, - 0x0c, 0x53, 0xeb, 0x8a, 0x49, 0x5f, 0x68, 0x62, 0x89, 0x9d, 0xa1, 0x1a, 0xfb, 0xe9, 0xb3, 0x3d, - 0x46, 0xb4, 0xf0, 0x48, 0x6c, 0x73, 0x1f, 0xd6, 0xf1, 0xef, 0x36, 0x8c, 0x95, 0xdd, 0x76, 0x40, - 0x1f, 0x07, 0x31, 0x37, 0x77, 0x0e, 0x8c, 0x3b, 0x3d, 0x4a, 0x54, 0xe3, 0xdf, 0x64, 0xe1, 0xf9, - 0xbe, 0x57, 0x01, 0xb2, 0xa9, 0xf7, 0xda, 0xb5, 0x41, 0xee, 0x0f, 0xa7, 0x77, 0xdb, 0x62, 0xc2, - 0xee, 0xee, 0x54, 0xbf, 0x9a, 0x85, 0xff, 0x21, 0x23, 0x3a, 0xe9, 0xd3, 0x30, 0x8a, 0x55, 0x85, - 0x5d, 0xc4, 0xb5, 0x64, 0xb8, 0x0b, 0x3b, 0xba, 0x96, 0x8c, 0xa3, 0x91, 0x5b, 0x90, 0x2f, 0xdb, - 0xcd, 0xa6, 0x12, 0x04, 0x00, 0xa5, 0xf9, 0x3a, 0xc2, 0x62, 0xc6, 0xa3, 0x12, 0x91, 0xc9, 0x3e, - 0xfc, 0x6f, 0xe5, 0xac, 0xc0, 0xcd, 0x52, 0x90, 0xc5, 0x8e, 0x0b, 0x05, 0x19, 0x43, 0x87, 0xd6, - 0xdd, 0xd0, 0xcd, 0x98, 0x87, 0x0e, 0x65, 0x00, 0x2d, 0x74, 0x28, 0x03, 0x18, 0xbf, 0x9e, 0x83, - 0x4b, 0xfd, 0xef, 0xb3, 0x64, 0x4b, 0x1f, 0x82, 0x57, 0x07, 0xba, 0x05, 0x9f, 0x3e, 0x06, 0x32, - 0x10, 0x2f, 0xef, 0x90, 0xab, 0x49, 0xf7, 0x97, 0xef, 0x1c, 0x17, 0x15, 0x8b, 0xe4, 0x7b, 0xae, - 0xd3, 0x56, 0xde, 0x4c, 0xbe, 0xa1, 0x49, 0x86, 0xfc, 0xf5, 0xfe, 0xf6, 0x60, 0x5f, 0x16, 0xd1, - 0xf1, 0x7d, 0x65, 0x50, 0x89, 0xf2, 0xf3, 0x50, 0x88, 0x93, 0x92, 0x2b, 0x30, 0x84, 0x1f, 0xa0, - 0xf8, 0xf0, 0xc4, 0x38, 0x60, 0xf9, 0xc2, 0x03, 0x31, 0x77, 0x30, 0x2e, 0x02, 0xda, 0x03, 0xe8, - 0xba, 0x41, 0x11, 0x17, 0x81, 0x9b, 0x13, 0x24, 0xf5, 0x83, 0x31, 0x22, 0xe3, 0x2f, 0x32, 0x70, - 0xb1, 0xa7, 0xa6, 0x80, 0x6c, 0xe8, 0x03, 0xf6, 0xf2, 0x69, 0xaa, 0x85, 0x53, 0xc7, 0x6a, 0xe1, - 0x47, 0xe5, 0xdc, 0x7f, 0x17, 0x26, 0x6a, 0xdd, 0x9d, 0xf8, 0xfd, 0x8c, 0x47, 0x2d, 0x51, 0xe0, - 0xea, 0x09, 0xa6, 0xe2, 0xb3, 0xf6, 0x4b, 0x83, 0x07, 0x61, 0x00, 0xa4, 0x58, 0x1d, 0x86, 0x8e, - 0xbb, 0xc9, 0xb8, 0x10, 0x3a, 0x91, 0xf1, 0xab, 0xd9, 0xf4, 0x8b, 0xee, 0xdd, 0xf2, 0xc6, 0x59, - 0x2e, 0xba, 0x77, 0xcb, 0x1b, 0xa7, 0xb7, 0xfd, 0xbf, 0x91, 0x6d, 0xc7, 0x87, 0x59, 0xb1, 0xe3, - 0x49, 0x45, 0xa7, 0x78, 0x98, 0x95, 0xbb, 0xa3, 0xaf, 0x3f, 0xcc, 0x4a, 0x64, 0xf2, 0x06, 0x8c, - 0xad, 0xba, 0x3c, 0x64, 0x83, 0x6c, 0x31, 0xf7, 0x6c, 0x95, 0x40, 0x75, 0x7b, 0x0c, 0x31, 0xd9, - 0xdd, 0x42, 0x1f, 0x78, 0x69, 0x5c, 0x89, 0x77, 0x8b, 0xd8, 0x74, 0xd1, 0xd5, 0x81, 0x3a, 0x99, - 0xf1, 0x9f, 0x0c, 0x83, 0x71, 0xba, 0x32, 0x83, 0xbc, 0xaf, 0xf7, 0xdd, 0xf5, 0x81, 0xd5, 0x20, - 0x03, 0x6d, 0xb9, 0xa5, 0x6e, 0xc3, 0xa1, 0xed, 0xba, 0x1e, 0x6f, 0x41, 0xc0, 0xd4, 0x2d, 0x50, - 0xe2, 0x7d, 0x18, 0xf7, 0xc7, 0x85, 0xff, 0x2e, 0x17, 0x2d, 0xb5, 0xd8, 0xd1, 0x98, 0xf9, 0x10, - 0x47, 0x23, 0xb9, 0x0f, 0x05, 0x15, 0xa2, 0xbc, 0xd0, 0xa2, 0xe4, 0xa2, 0x31, 0x8a, 0x7d, 0x54, - 0x82, 0x50, 0x3f, 0x5f, 0x73, 0x83, 0x9f, 0xaf, 0x91, 0xf8, 0x8e, 0xf5, 0x0f, 0x25, 0xc5, 0xf7, - 0xb8, 0x8b, 0xb3, 0x82, 0x2e, 0xe3, 0x33, 0xf8, 0xe2, 0xd0, 0x1a, 0xd6, 0xe3, 0x33, 0xa4, 0x1c, - 0x5c, 0x2a, 0xba, 0x0c, 0x31, 0x81, 0x3f, 0x15, 0x0f, 0xeb, 0x30, 0xc4, 0x04, 0xa7, 0x4f, 0x0b, - 0x31, 0x11, 0x92, 0xb0, 0x03, 0xd0, 0xec, 0xb6, 0x79, 0x8c, 0xea, 0xd1, 0xe8, 0x00, 0xf4, 0xba, - 0x6d, 0x2b, 0x1e, 0xa7, 0x3a, 0x44, 0x34, 0xfe, 0xc9, 0x50, 0xba, 0x70, 0x10, 0xea, 0xbb, 0xce, - 0x22, 0x1c, 0x84, 0x44, 0x1f, 0xcf, 0x4c, 0xdd, 0x82, 0x59, 0x69, 0x9f, 0x27, 0x0d, 0xbd, 0xb6, - 0xcc, 0x55, 0x31, 0xc4, 0xa8, 0x37, 0x0a, 0x2d, 0xfb, 0xa4, 0xb1, 0x98, 0xd5, 0xf5, 0x34, 0xbd, - 0x51, 0x0a, 0xfd, 0xc2, 0x6f, 0x48, 0xb5, 0x98, 0x3a, 0x08, 0x5b, 0x5b, 0xe1, 0x5c, 0x8e, 0x0d, - 0x42, 0xb7, 0xab, 0x0d, 0xa3, 0x4e, 0xc2, 0xf7, 0x5e, 0xa9, 0x72, 0x40, 0x26, 0x8a, 0xac, 0xa8, - 0x28, 0x2a, 0x62, 0x5c, 0x62, 0x44, 0x64, 0x0f, 0x2e, 0x46, 0xa2, 0xb4, 0x72, 0x53, 0x40, 0x8e, - 0xbc, 0xc1, 0xd7, 0x4e, 0x8e, 0x8b, 0x2f, 0x2b, 0xa2, 0xb8, 0x7a, 0xe1, 0x88, 0x71, 0xef, 0xcd, - 0x8b, 0xed, 0xb7, 0x4b, 0x9e, 0xdd, 0xae, 0xef, 0x2b, 0x73, 0x1e, 0xf7, 0xdb, 0x1d, 0x84, 0x26, - 0x9c, 0xe4, 0x23, 0x64, 0xe3, 0x47, 0xb3, 0x30, 0xc5, 0xcf, 0x6a, 0xfe, 0x3a, 0xf7, 0xd4, 0xbe, - 0x7c, 0xbe, 0xa5, 0xbd, 0x7c, 0xca, 0x78, 0x6e, 0x6a, 0xd3, 0x06, 0x7a, 0xf7, 0xdc, 0x07, 0x92, - 0xa4, 0x21, 0x26, 0x4c, 0xa8, 0xd0, 0xfe, 0x4f, 0x9e, 0x37, 0xa3, 0xd0, 0x7f, 0x42, 0x54, 0xc2, - 0x77, 0x67, 0xdf, 0xd4, 0x78, 0x18, 0x3f, 0x92, 0x85, 0x49, 0xc5, 0x4e, 0xe5, 0xa9, 0xed, 0xf8, - 0xcf, 0x6b, 0x1d, 0x3f, 0x1f, 0x7a, 0x08, 0x86, 0x2d, 0x1b, 0xa8, 0xdf, 0xbb, 0x30, 0x93, 0x20, - 0x89, 0x9b, 0xfb, 0x64, 0x06, 0x31, 0xf7, 0x79, 0x2d, 0x19, 0x47, 0x8c, 0x87, 0xe3, 0x0f, 0xa3, - 0xca, 0xa8, 0x81, 0xcb, 0x7e, 0x3c, 0x0b, 0x73, 0xe2, 0x17, 0x06, 0xde, 0xe4, 0xc2, 0xea, 0x53, - 0x3b, 0x16, 0x25, 0x6d, 0x2c, 0x8a, 0xfa, 0x58, 0x28, 0x0d, 0xec, 0x3d, 0x24, 0xc6, 0x0f, 0x02, - 0xcc, 0xf7, 0x22, 0x18, 0xd8, 0x11, 0x3f, 0x72, 0x4d, 0xcc, 0x0e, 0xe0, 0x9a, 0xb8, 0x0a, 0x05, - 0xac, 0x4a, 0x84, 0xd6, 0xf3, 0xb7, 0xcc, 0xaa, 0xe8, 0x24, 0xd4, 0x2f, 0xf0, 0xe8, 0xa8, 0x22, - 0xd4, 0x9f, 0x1f, 0xd3, 0x79, 0x24, 0x28, 0xc9, 0x2f, 0x65, 0x60, 0x0a, 0x81, 0xcb, 0x8f, 0x68, - 0x3b, 0x40, 0x66, 0x43, 0xc2, 0x67, 0x2d, 0x7c, 0x18, 0xad, 0x05, 0x9e, 0xd3, 0xde, 0x13, 0x2f, - 0xa3, 0x3b, 0xe2, 0x65, 0xf4, 0x6d, 0xfe, 0xa2, 0x7b, 0xbd, 0xee, 0xb6, 0x6e, 0xec, 0x79, 0xf6, - 0x23, 0x87, 0x9b, 0x60, 0xd9, 0xcd, 0x1b, 0x51, 0x16, 0x99, 0x8e, 0x13, 0xcb, 0xef, 0x22, 0x58, - 0xe1, 0xab, 0x33, 0xff, 0x50, 0x8a, 0xd5, 0xc6, 0x55, 0x33, 0xfa, 0x17, 0x91, 0xef, 0x82, 0x0b, - 0x3c, 0xe0, 0x15, 0xbb, 0xe1, 0x3b, 0xed, 0xae, 0xdb, 0xf5, 0x97, 0xec, 0xfa, 0x01, 0x13, 0xf3, - 0xb9, 0x67, 0x31, 0xb6, 0xbc, 0x1e, 0x16, 0x5a, 0x3b, 0xbc, 0x54, 0x8b, 0xa4, 0x90, 0xce, 0x80, - 0xac, 0xc0, 0x0c, 0x2f, 0x2a, 0x75, 0x03, 0xb7, 0x56, 0xb7, 0x9b, 0x4e, 0x7b, 0x0f, 0x65, 0x89, - 0x3c, 0x17, 0x65, 0xec, 0x6e, 0xe0, 0x5a, 0x3e, 0x87, 0xab, 0x9a, 0x9a, 0x04, 0x11, 0xa9, 0xc2, - 0xb4, 0x49, 0xed, 0xc6, 0x03, 0xfb, 0x71, 0xd9, 0xee, 0xd8, 0x75, 0x27, 0xe0, 0x11, 0x38, 0x73, - 0x5c, 0xa0, 0xf3, 0xa8, 0xdd, 0xb0, 0x5a, 0xf6, 0x63, 0xab, 0x2e, 0x0a, 0x75, 0x95, 0xbd, 0x46, - 0x17, 0xb2, 0x72, 0xda, 0x21, 0xab, 0xb1, 0x38, 0x2b, 0xa7, 0xdd, 0x9b, 0x55, 0x44, 0x27, 0x59, - 0x6d, 0xda, 0xde, 0x1e, 0x0d, 0xb8, 0xa1, 0x34, 0x5c, 0xce, 0x5c, 0xcd, 0x28, 0xac, 0x02, 0x2c, - 0xb3, 0xd0, 0x68, 0x3a, 0xce, 0x4a, 0xa1, 0x63, 0x33, 0x6f, 0xdb, 0x73, 0x02, 0xaa, 0xb6, 0x70, - 0x1c, 0x3f, 0x0b, 0xfb, 0x1f, 0x4d, 0xcc, 0x7b, 0x35, 0x31, 0x41, 0x19, 0x71, 0x53, 0x1a, 0x39, - 0x91, 0xe0, 0x96, 0xde, 0xca, 0x04, 0x65, 0xc8, 0x4d, 0x6d, 0xe7, 0x24, 0xb6, 0x53, 0xe1, 0xd6, - 0xa3, 0xa1, 0x09, 0x4a, 0xb2, 0xc6, 0x3a, 0x2d, 0x60, 0x72, 0x93, 0xdb, 0x16, 0x16, 0xdc, 0x53, - 0xf8, 0x69, 0x2f, 0x09, 0x33, 0xc4, 0x82, 0x27, 0x8b, 0xad, 0x14, 0x7b, 0xee, 0x38, 0x31, 0xf9, - 0x1b, 0x30, 0xbd, 0xe5, 0xd3, 0x3b, 0xd5, 0x8d, 0x9a, 0x8c, 0x8f, 0x85, 0xca, 0xc5, 0xa9, 0xc5, - 0x9b, 0xa7, 0x6c, 0x3a, 0xd7, 0x55, 0x1a, 0x4c, 0xca, 0xc2, 0xc7, 0xad, 0xeb, 0x53, 0x6b, 0xd7, - 0xe9, 0xf8, 0x61, 0xb0, 0x41, 0x75, 0xdc, 0x62, 0x55, 0x19, 0x2b, 0x30, 0x93, 0x60, 0x43, 0xa6, - 0x00, 0x18, 0xd0, 0xda, 0x5a, 0xab, 0x2d, 0x6f, 0x16, 0x9e, 0x21, 0x05, 0x98, 0xc0, 0xdf, 0xcb, - 0x6b, 0xa5, 0xa5, 0xd5, 0xe5, 0x4a, 0x21, 0x43, 0x66, 0x60, 0x12, 0x21, 0x95, 0x6a, 0x8d, 0x83, - 0xb2, 0x3c, 0x24, 0xbf, 0x59, 0xe0, 0x4b, 0x37, 0x60, 0x0b, 0x00, 0xcf, 0x14, 0xe3, 0xef, 0x66, - 0xe1, 0xa2, 0x3c, 0x56, 0x68, 0xc0, 0x04, 0x47, 0xa7, 0xbd, 0xf7, 0x94, 0x9f, 0x0e, 0x77, 0xb4, - 0xd3, 0xe1, 0xa5, 0xd8, 0x49, 0x1d, 0x6b, 0x65, 0x9f, 0x23, 0xe2, 0xb7, 0xc7, 0xe0, 0xf9, 0xbe, - 0x54, 0xe4, 0x8b, 0xec, 0x34, 0x77, 0x68, 0x3b, 0xa8, 0x36, 0x9a, 0x74, 0xd3, 0x69, 0x51, 0xb7, - 0x1b, 0x08, 0x8f, 0x81, 0x17, 0x51, 0x9f, 0x87, 0x85, 0x96, 0xd3, 0x68, 0x52, 0x2b, 0xe0, 0xc5, - 0xda, 0x74, 0x4b, 0x52, 0x33, 0x96, 0x61, 0x82, 0xa8, 0x6a, 0x3b, 0xa0, 0xde, 0x23, 0xb4, 0x4a, - 0x0c, 0x59, 0x1e, 0x50, 0xda, 0xb1, 0x6c, 0x56, 0x6a, 0x39, 0xa2, 0x58, 0x67, 0x99, 0xa0, 0x26, - 0x77, 0x14, 0x96, 0x65, 0x76, 0xfb, 0x7f, 0x60, 0x3f, 0x16, 0x66, 0x52, 0x22, 0xde, 0x6a, 0xc8, - 0x92, 0xbb, 0xf3, 0xb5, 0xec, 0xc7, 0x66, 0x92, 0x84, 0x7c, 0x15, 0xce, 0x89, 0x03, 0x48, 0x04, - 0x6f, 0x91, 0x2d, 0xe6, 0xa1, 0x61, 0x5e, 0x39, 0x39, 0x2e, 0x5e, 0x90, 0x91, 0x6a, 0x65, 0xb8, - 0x9e, 0xb4, 0x56, 0xa7, 0x73, 0x21, 0x9b, 0xec, 0x40, 0x8e, 0x75, 0xc7, 0x03, 0xea, 0xfb, 0xd2, - 0x67, 0x53, 0xdc, 0x8c, 0xd5, 0xce, 0xb4, 0x5a, 0xbc, 0xdc, 0xec, 0x49, 0x49, 0x56, 0x60, 0x6a, - 0x9b, 0xee, 0xa8, 0xe3, 0x33, 0x12, 0x6e, 0x55, 0x85, 0x43, 0xba, 0xd3, 0x7b, 0x70, 0x62, 0x74, - 0xc4, 0xc1, 0xf7, 0x81, 0xc7, 0x47, 0xab, 0x8e, 0x1f, 0xd0, 0x36, 0xf5, 0x30, 0x28, 0xd8, 0x28, - 0x6e, 0x06, 0xf3, 0x91, 0x84, 0xac, 0x97, 0x2f, 0xbd, 0x70, 0x72, 0x5c, 0x7c, 0x9e, 0x3b, 0x3f, - 0x37, 0x05, 0xdc, 0x8a, 0xa5, 0x57, 0x4a, 0x72, 0x25, 0x5f, 0x87, 0x69, 0xd3, 0xed, 0x06, 0x4e, - 0x7b, 0xaf, 0x16, 0x78, 0x76, 0x40, 0xf7, 0xf8, 0x81, 0x14, 0x45, 0x1f, 0x8b, 0x95, 0x8a, 0xa7, - 0x65, 0x0e, 0xb4, 0x7c, 0x01, 0xd5, 0x4e, 0x04, 0x9d, 0x80, 0x7c, 0x0d, 0xa6, 0x78, 0xd8, 0x8e, - 0xb0, 0x82, 0x31, 0x2d, 0x35, 0x84, 0x5e, 0xf8, 0xf0, 0xa6, 0xb0, 0x6a, 0x41, 0x68, 0x5a, 0x05, - 0x31, 0x6e, 0xe4, 0xcb, 0xa2, 0xb3, 0x36, 0x9c, 0xf6, 0x5e, 0x38, 0x8d, 0x01, 0x7b, 0xfe, 0xf5, - 0xa8, 0x4b, 0x3a, 0xec, 0x73, 0xe5, 0x34, 0xee, 0x61, 0xa2, 0x97, 0xe4, 0x43, 0x02, 0x78, 0xbe, - 0xe4, 0xfb, 0x8e, 0x1f, 0x08, 0xbf, 0x9a, 0xe5, 0xc7, 0xb4, 0xde, 0x65, 0xc8, 0xec, 0x7a, 0x4b, - 0x3d, 0x6e, 0xd7, 0x3d, 0xbc, 0x74, 0xfd, 0xe4, 0xb8, 0xf8, 0xaa, 0x8d, 0x88, 0x96, 0x70, 0xc5, - 0xb1, 0xa8, 0x44, 0xb5, 0x0e, 0x39, 0xae, 0xd2, 0x86, 0xfe, 0x4c, 0xc9, 0xd7, 0xe0, 0x7c, 0xd9, - 0xf6, 0x69, 0xb5, 0xed, 0xd3, 0xb6, 0xef, 0x04, 0xce, 0x23, 0x2a, 0x3a, 0x15, 0x0f, 0xbf, 0x3c, - 0x26, 0xa2, 0x32, 0xea, 0xb6, 0xcf, 0x16, 0x66, 0x88, 0x62, 0x89, 0x41, 0x51, 0xaa, 0xe9, 0xc1, - 0x85, 0x98, 0x30, 0x55, 0xab, 0xad, 0x54, 0x1c, 0x3b, 0x5c, 0x57, 0x93, 0xd8, 0x5f, 0xaf, 0xa2, - 0x6a, 0xcf, 0xdf, 0xb7, 0x1a, 0x8e, 0x1d, 0x2e, 0xa8, 0x1e, 0x9d, 0x15, 0xe3, 0x60, 0x1c, 0x67, - 0xa0, 0x10, 0x1f, 0x4a, 0xf2, 0x25, 0x18, 0xe3, 0xf6, 0x6d, 0xd4, 0xdf, 0x17, 0x91, 0x27, 0xa4, - 0xb9, 0x54, 0x08, 0xd7, 0x89, 0x84, 0x3b, 0x1d, 0xb7, 0x9e, 0xa3, 0xaa, 0xb5, 0x0c, 0xba, 0xd3, - 0x49, 0x22, 0xd2, 0x80, 0x09, 0x3e, 0x5a, 0x14, 0x43, 0x0f, 0x0a, 0x33, 0xe7, 0x17, 0xd4, 0xd5, - 0x21, 0x8a, 0x62, 0xfc, 0xf1, 0xd5, 0x50, 0xcc, 0x09, 0x8e, 0xa0, 0x55, 0xa1, 0x71, 0x5d, 0x02, - 0xc8, 0x4b, 0x42, 0xe3, 0x22, 0x5c, 0xe8, 0xf1, 0xcd, 0xc6, 0x23, 0xb4, 0x24, 0xe8, 0x51, 0x23, - 0xf9, 0x12, 0xcc, 0x21, 0x61, 0xd9, 0x6d, 0xb7, 0x69, 0x3d, 0xc0, 0xed, 0x48, 0x6a, 0xdf, 0x73, - 0xdc, 0xd2, 0x85, 0xb7, 0xb7, 0x1e, 0x22, 0x58, 0x71, 0x25, 0x7c, 0x2a, 0x07, 0xe3, 0x67, 0xb3, - 0x30, 0x2f, 0x76, 0x38, 0x93, 0xd6, 0x5d, 0xaf, 0xf1, 0xf4, 0x9f, 0xa8, 0xcb, 0xda, 0x89, 0xfa, - 0x62, 0x18, 0xb6, 0x28, 0xad, 0x91, 0x7d, 0x0e, 0xd4, 0x5f, 0xcd, 0xc0, 0x73, 0xfd, 0x88, 0x58, - 0xef, 0x84, 0xa1, 0x16, 0xc7, 0x12, 0x21, 0x15, 0x3b, 0x30, 0x8b, 0x03, 0x5a, 0xde, 0xa7, 0xf5, - 0x03, 0x7f, 0xc5, 0xf5, 0x03, 0xf4, 0xb4, 0xc8, 0xf6, 0x78, 0xeb, 0x7e, 0x2d, 0xf5, 0xad, 0xfb, - 0x3c, 0x9f, 0x65, 0x75, 0xe4, 0xc1, 0x83, 0x41, 0x1e, 0xd0, 0x23, 0xdf, 0x4c, 0x63, 0x8d, 0x16, - 0xf3, 0xa5, 0x6e, 0xb0, 0xbf, 0xe1, 0xd1, 0x5d, 0xea, 0xd1, 0x76, 0x9d, 0x7e, 0xc2, 0x2c, 0xe6, - 0xf5, 0xc6, 0x0d, 0xa4, 0xc1, 0xf8, 0xdd, 0x49, 0x98, 0x4b, 0x23, 0x63, 0xfd, 0xa2, 0x5c, 0x9a, - 0xe3, 0x79, 0x32, 0xbf, 0x95, 0x81, 0x89, 0x1a, 0xad, 0xbb, 0xed, 0xc6, 0x1d, 0xb4, 0x28, 0x12, - 0xbd, 0x63, 0x73, 0xa1, 0x81, 0xc1, 0xad, 0xdd, 0x98, 0xa9, 0xd1, 0x77, 0x8e, 0x8b, 0x5f, 0x18, - 0xec, 0xae, 0x5a, 0x77, 0x31, 0x5c, 0x50, 0x80, 0x79, 0x1c, 0xc2, 0x2a, 0xf8, 0xd7, 0x98, 0x5a, - 0xb5, 0x64, 0x09, 0x26, 0xc5, 0x82, 0x75, 0xd5, 0x58, 0x9b, 0x3c, 0xb6, 0x93, 0x2c, 0x48, 0x28, - 0xaf, 0x35, 0x12, 0x72, 0x0b, 0x72, 0x5b, 0x8b, 0x77, 0xc4, 0x28, 0xc8, 0x5c, 0x18, 0x5b, 0x8b, - 0x77, 0x50, 0x21, 0xc6, 0x2e, 0x19, 0x93, 0xdd, 0x45, 0xcd, 0xcc, 0x67, 0x6b, 0xf1, 0x0e, 0xf9, - 0x9b, 0x70, 0xae, 0xe2, 0xf8, 0xa2, 0x0a, 0xee, 0xbd, 0xd1, 0x40, 0x9f, 0xc5, 0x91, 0x1e, 0xf3, - 0xf7, 0xb3, 0xa9, 0xf3, 0xf7, 0x85, 0x46, 0xc8, 0xc4, 0xe2, 0xae, 0x21, 0x8d, 0x78, 0x4c, 0xd1, - 0xf4, 0x7a, 0xc8, 0x07, 0x30, 0x85, 0xea, 0x6c, 0x74, 0x68, 0xc1, 0x68, 0xf0, 0xa3, 0x3d, 0x6a, - 0xfe, 0x74, 0x6a, 0xcd, 0x0b, 0x3c, 0xe2, 0x06, 0xba, 0xc5, 0x60, 0xe4, 0x78, 0xed, 0xde, 0xaf, - 0x71, 0x26, 0xf7, 0x60, 0x5a, 0x08, 0x60, 0xeb, 0xbb, 0x9b, 0xfb, 0xb4, 0x62, 0x1f, 0x09, 0x0b, - 0x1d, 0xbc, 0xd3, 0x09, 0xa9, 0xcd, 0x72, 0x77, 0xad, 0x60, 0x9f, 0x5a, 0x0d, 0x5b, 0x13, 0x55, - 0x62, 0x84, 0xe4, 0x9b, 0x30, 0xbe, 0xea, 0xd6, 0x99, 0xec, 0x8d, 0x7b, 0x03, 0x37, 0xda, 0x79, - 0x1f, 0x73, 0x31, 0x72, 0x70, 0x4c, 0xa0, 0xfa, 0xce, 0x71, 0xf1, 0xad, 0xb3, 0x4e, 0x1b, 0xa5, - 0x02, 0x53, 0xad, 0x8d, 0x94, 0x21, 0xbf, 0x4d, 0x77, 0x58, 0x6b, 0xe3, 0x79, 0xda, 0x24, 0x58, - 0xd8, 0xe4, 0x89, 0x5f, 0x9a, 0x4d, 0x9e, 0x80, 0x11, 0x0f, 0x66, 0xb0, 0x7f, 0x36, 0x6c, 0xdf, - 0x3f, 0x74, 0xbd, 0x06, 0x26, 0xe4, 0xe8, 0x65, 0x0f, 0xb4, 0x98, 0xda, 0xf9, 0xcf, 0xf1, 0xce, - 0xef, 0x28, 0x1c, 0x54, 0x11, 0x32, 0xc1, 0x9e, 0x7c, 0x1d, 0xa6, 0x44, 0xf4, 0x82, 0x07, 0x77, - 0x4a, 0xb8, 0x12, 0x26, 0x34, 0xcf, 0x4f, 0xbd, 0x90, 0xcb, 0xa9, 0x22, 0x18, 0x82, 0xd4, 0x41, - 0x59, 0xad, 0x5d, 0x5b, 0x57, 0xfb, 0xab, 0x24, 0x64, 0x03, 0xc6, 0x2b, 0x98, 0x2d, 0x18, 0xbd, - 0xd3, 0x84, 0x65, 0x78, 0x98, 0x68, 0x2a, 0x2a, 0xe1, 0xda, 0x18, 0x91, 0x58, 0x18, 0x7d, 0xdd, - 0x74, 0x6b, 0xdd, 0x10, 0x91, 0xdc, 0x86, 0x5c, 0xb5, 0xb2, 0x21, 0x0c, 0xc3, 0x67, 0xc2, 0x18, - 0x21, 0x1b, 0x32, 0x2d, 0x0f, 0x5a, 0xd0, 0x39, 0x0d, 0xcd, 0xac, 0xbc, 0x5a, 0xd9, 0x20, 0xbb, - 0x30, 0x89, 0x1d, 0xb0, 0x42, 0x6d, 0xde, 0xb7, 0xd3, 0x3d, 0xfa, 0xf6, 0x7a, 0x6a, 0xdf, 0xce, - 0xf3, 0xbe, 0xdd, 0x17, 0xd4, 0x5a, 0x9e, 0x11, 0x95, 0x2d, 0x13, 0x6a, 0x45, 0xee, 0x23, 0x99, - 0x1d, 0x63, 0x73, 0x15, 0x2d, 0x84, 0x84, 0x50, 0x2b, 0x53, 0x25, 0x85, 0xe9, 0x3a, 0x7a, 0xfa, - 0x9d, 0x24, 0xf9, 0x90, 0xcf, 0xc3, 0xd0, 0xfa, 0x41, 0x60, 0x0b, 0x13, 0x70, 0xd9, 0x8f, 0x0c, - 0x24, 0x9b, 0x8f, 0x7a, 0x48, 0xf7, 0x40, 0x8b, 0x3a, 0x87, 0x34, 0x6c, 0x28, 0x56, 0x6c, 0xaf, - 0x71, 0x68, 0x7b, 0xe8, 0x22, 0x3c, 0xab, 0xb1, 0x50, 0x4a, 0xf8, 0x50, 0xec, 0x0b, 0x40, 0xcc, - 0x6f, 0x58, 0x65, 0x41, 0xbe, 0x0b, 0x2e, 0xfa, 0xce, 0x5e, 0xdb, 0x0e, 0xba, 0x1e, 0xb5, 0xec, - 0xe6, 0x9e, 0xeb, 0x39, 0xc1, 0x7e, 0xcb, 0xf2, 0xbb, 0x4e, 0x40, 0xe7, 0xe7, 0xb4, 0x4c, 0xc9, - 0x35, 0x89, 0x57, 0x92, 0x68, 0x35, 0x86, 0x65, 0x5e, 0xf0, 0xd3, 0x0b, 0xc8, 0x97, 0x61, 0x52, - 0xdd, 0x92, 0xfd, 0xf9, 0x73, 0x97, 0x73, 0x57, 0xa7, 0xc2, 0xab, 0x47, 0x7c, 0x0b, 0x97, 0x11, - 0x86, 0x95, 0x33, 0xc2, 0xd7, 0x23, 0x0c, 0x2b, 0xbc, 0xc2, 0xdc, 0x83, 0xa4, 0x30, 0x6b, 0xce, - 0x88, 0x19, 0x2b, 0x7a, 0xf9, 0xc1, 0x9d, 0x92, 0x39, 0xba, 0x51, 0x7d, 0x58, 0x6b, 0xba, 0x81, - 0xf1, 0x5f, 0x64, 0x70, 0x13, 0x27, 0xaf, 0x62, 0x28, 0xa9, 0xf0, 0xfd, 0x0c, 0x35, 0xb8, 0x76, - 0x27, 0x16, 0x9e, 0x9e, 0xa3, 0x90, 0xd7, 0x60, 0xe4, 0x8e, 0x5d, 0x97, 0x61, 0x6c, 0x04, 0xf2, - 0x2e, 0x42, 0x54, 0x75, 0x2f, 0xc7, 0x61, 0x12, 0x26, 0x9f, 0xdc, 0xa5, 0x28, 0x09, 0x77, 0xb9, - 0x24, 0x1f, 0xec, 0x51, 0xc2, 0x14, 0x8b, 0x42, 0xc9, 0xd2, 0x1d, 0xb3, 0x8b, 0x4f, 0xe5, 0x60, - 0xfc, 0x59, 0x26, 0xda, 0x95, 0xc8, 0x2b, 0x30, 0x64, 0x6e, 0x84, 0xdf, 0xcf, 0xdd, 0x7e, 0x63, - 0x9f, 0x8f, 0x08, 0xe4, 0xcb, 0x70, 0x4e, 0xe1, 0x93, 0x30, 0xd2, 0x7f, 0x19, 0xbd, 0x52, 0x95, - 0x2f, 0x49, 0xb7, 0xd4, 0x4f, 0xe7, 0x81, 0xe2, 0x74, 0x54, 0x50, 0xa1, 0x6d, 0x87, 0xf3, 0x56, - 0x1a, 0xab, 0xf2, 0x6e, 0x20, 0x42, 0xbc, 0xb1, 0x69, 0x1c, 0xb8, 0x53, 0xaa, 0xf1, 0x5b, 0x19, - 0x6d, 0xb7, 0x09, 0xb3, 0x16, 0x67, 0x4e, 0xc9, 0x5a, 0xfc, 0x26, 0x40, 0xa9, 0x1b, 0xb8, 0xcb, - 0x6d, 0xcf, 0x6d, 0x72, 0x3d, 0x8a, 0xc8, 0xd0, 0x80, 0xda, 0x61, 0x8a, 0x60, 0xcd, 0x77, 0x2e, - 0x44, 0x4e, 0xf5, 0x67, 0xc8, 0x7d, 0x58, 0x7f, 0x06, 0xe3, 0x0f, 0x32, 0xda, 0x1a, 0x65, 0x72, - 0xa2, 0x98, 0x8a, 0xaa, 0xcd, 0x58, 0xc7, 0x79, 0x64, 0xf9, 0x4d, 0x57, 0x0b, 0x58, 0x21, 0xd0, - 0xc8, 0xbf, 0x9b, 0x81, 0xf3, 0xdc, 0x31, 0x60, 0xad, 0xdb, 0xda, 0xa1, 0xde, 0x43, 0xbb, 0xe9, - 0x34, 0xa2, 0x40, 0x7d, 0x91, 0x01, 0xa1, 0x52, 0x4d, 0x3a, 0x3e, 0xbf, 0xaa, 0x72, 0x47, 0x05, - 0xab, 0x8d, 0x85, 0xd6, 0xa3, 0xb0, 0x54, 0xbd, 0xaa, 0xa6, 0xd3, 0x1b, 0xbf, 0x96, 0x81, 0x17, - 0x4e, 0xad, 0x85, 0xdc, 0x80, 0x51, 0x99, 0x1a, 0x23, 0x83, 0x1d, 0x8f, 0x96, 0xb6, 0xc9, 0xb4, - 0x18, 0x12, 0x8b, 0x7c, 0x05, 0xce, 0xa9, 0xac, 0x36, 0x3d, 0xdb, 0x51, 0x13, 0x50, 0xa4, 0x7c, - 0x75, 0xc0, 0x50, 0xe2, 0xd2, 0x5a, 0x3a, 0x13, 0xe3, 0xff, 0xcd, 0x28, 0x79, 0xcc, 0x9f, 0x52, - 0x29, 0xfe, 0xb6, 0x26, 0xc5, 0xcb, 0x30, 0xa5, 0x61, 0xab, 0x58, 0x59, 0xea, 0xcd, 0x6b, 0x5a, - 0xb1, 0x18, 0x47, 0xc0, 0x0f, 0x65, 0x61, 0x7c, 0xcb, 0xa7, 0x1e, 0x7f, 0xca, 0xfd, 0x64, 0x05, - 0x6b, 0x0c, 0xdb, 0x35, 0x50, 0x38, 0xbd, 0x3f, 0xc9, 0xa0, 0x8a, 0x5f, 0xa5, 0x60, 0xbd, 0xa1, - 0xe4, 0x2e, 0xc4, 0xde, 0xc0, 0xac, 0x85, 0x08, 0xe5, 0xc1, 0xc5, 0x56, 0xf5, 0x34, 0xa6, 0x98, - 0xcb, 0x76, 0x95, 0x7c, 0x01, 0x86, 0xb7, 0x50, 0x61, 0xa9, 0x87, 0xd9, 0x08, 0xf9, 0x63, 0x21, - 0xdf, 0xa4, 0xbb, 0xbe, 0x1e, 0x79, 0x8e, 0x13, 0x92, 0x1a, 0x8c, 0x96, 0x3d, 0x8a, 0x59, 0xc9, - 0x87, 0x06, 0x77, 0x12, 0xaf, 0x73, 0x92, 0xb8, 0x93, 0xb8, 0xe0, 0x64, 0xfc, 0x4c, 0x16, 0x48, - 0xd4, 0x46, 0x4c, 0xc1, 0xe5, 0x3f, 0xb5, 0x83, 0xfe, 0x9e, 0x36, 0xe8, 0xcf, 0x27, 0x06, 0x9d, - 0x37, 0x6f, 0xa0, 0xb1, 0xff, 0x9d, 0x0c, 0x9c, 0x4f, 0x27, 0x24, 0x2f, 0xc2, 0xc8, 0xfa, 0xe6, - 0x86, 0x8c, 0xd4, 0x22, 0x9a, 0xe2, 0x76, 0x50, 0x5b, 0x60, 0x8a, 0x22, 0xf2, 0x3a, 0x8c, 0x7c, - 0xd1, 0x2c, 0xb3, 0x73, 0x48, 0x49, 0xf2, 0xf0, 0x0d, 0xcf, 0xaa, 0xeb, 0x47, 0x91, 0x40, 0x52, - 0xc7, 0x36, 0xf7, 0xc4, 0xc6, 0xf6, 0xc7, 0xb3, 0x30, 0x5d, 0xaa, 0xd7, 0xa9, 0xef, 0x33, 0x69, - 0x87, 0xfa, 0xc1, 0x53, 0x3b, 0xb0, 0xe9, 0x31, 0x58, 0xb4, 0xb6, 0x0d, 0x34, 0xaa, 0xbf, 0x97, - 0x81, 0x73, 0x92, 0xea, 0x91, 0x43, 0x0f, 0x37, 0xf7, 0x3d, 0xea, 0xef, 0xbb, 0xcd, 0xc6, 0xc0, - 0x99, 0x64, 0x98, 0xa0, 0x87, 0xe1, 0xe1, 0xd5, 0x77, 0xfd, 0x5d, 0x84, 0x68, 0x82, 0x1e, 0x0f, - 0x21, 0x7f, 0x03, 0x46, 0x4b, 0x9d, 0x8e, 0xe7, 0x3e, 0xe2, 0xcb, 0x5e, 0xc4, 0x96, 0xb4, 0x39, - 0x48, 0xf3, 0xb1, 0xe7, 0x20, 0xf6, 0x19, 0x15, 0xda, 0xe6, 0xc1, 0xfc, 0x26, 0xf9, 0x67, 0x34, - 0x68, 0x5b, 0x95, 0xc5, 0xb1, 0xdc, 0xa8, 0x01, 0xd9, 0xf0, 0xdc, 0x96, 0x1b, 0xd0, 0x06, 0x6f, - 0x0f, 0x86, 0x26, 0x38, 0x35, 0xa8, 0xd6, 0xa6, 0x13, 0x34, 0xb5, 0xa0, 0x5a, 0x01, 0x03, 0x98, - 0x1c, 0x6e, 0xfc, 0xdf, 0xc3, 0x30, 0xa1, 0xf6, 0x0e, 0x31, 0x78, 0x7a, 0x08, 0xd7, 0x53, 0xe3, - 0x63, 0xd8, 0x08, 0x31, 0x45, 0x49, 0x14, 0x5c, 0x26, 0x7b, 0x6a, 0x70, 0x99, 0x6d, 0x98, 0xdc, - 0xf0, 0x5c, 0x0c, 0x82, 0x89, 0xef, 0x95, 0x62, 0x2b, 0x9c, 0x55, 0xee, 0x9d, 0x6c, 0x20, 0xf1, - 0x45, 0x14, 0x25, 0xfb, 0x8e, 0xc0, 0xc6, 0xa4, 0x89, 0x9a, 0xd6, 0x45, 0xe3, 0xc3, 0x8d, 0x2d, - 0x6c, 0x5f, 0x44, 0xb2, 0x0d, 0x8d, 0x2d, 0x18, 0x44, 0x37, 0xb6, 0x60, 0x10, 0x75, 0xad, 0x0d, - 0x3f, 0xa9, 0xb5, 0x46, 0x7e, 0x26, 0x03, 0xe3, 0xa5, 0x76, 0x5b, 0x04, 0xad, 0x39, 0xc5, 0x5f, - 0xff, 0x2b, 0xc2, 0xde, 0xe2, 0xad, 0x0f, 0x65, 0x6f, 0x81, 0x72, 0x8b, 0x8f, 0x92, 0x6a, 0x54, - 0xa1, 0x7a, 0x5b, 0x53, 0xbe, 0x83, 0xbc, 0x05, 0x85, 0x70, 0x92, 0x57, 0xdb, 0x0d, 0xfa, 0x98, - 0xf2, 0xf4, 0x7a, 0x93, 0x22, 0xb2, 0xb6, 0x2a, 0x99, 0xc6, 0x11, 0xc9, 0x26, 0x80, 0x1d, 0xce, - 0xae, 0x58, 0x9e, 0xd0, 0xe4, 0xf4, 0x13, 0xd2, 0x33, 0xfe, 0xc6, 0x27, 0x2d, 0x55, 0x7a, 0x8e, - 0xf8, 0x90, 0x16, 0x4c, 0xf3, 0x24, 0x9d, 0xb5, 0xc0, 0xf6, 0x02, 0x4c, 0x46, 0x01, 0xa7, 0x8e, - 0xc3, 0x2b, 0x42, 0x7f, 0xf6, 0xac, 0x48, 0xfd, 0xe9, 0x33, 0x5a, 0x2b, 0x25, 0x33, 0x45, 0x9c, - 0x37, 0x8f, 0x63, 0x6e, 0x5e, 0x48, 0x7e, 0x2f, 0x9f, 0xf4, 0x3f, 0x9e, 0x81, 0xf3, 0xea, 0xa4, - 0xaf, 0x75, 0x77, 0x44, 0xf0, 0x50, 0x72, 0x1d, 0xc6, 0xc4, 0x9c, 0x0c, 0x2f, 0x51, 0xc9, 0x9c, - 0x1a, 0x11, 0x0a, 0x59, 0x66, 0xd3, 0x90, 0xf1, 0x10, 0x52, 0xf7, 0x6c, 0x6c, 0x9f, 0x62, 0x45, - 0x51, 0x02, 0x68, 0x0f, 0x7f, 0xeb, 0xf3, 0x93, 0x41, 0x8c, 0x77, 0x61, 0x46, 0x1f, 0x89, 0x1a, - 0x0d, 0xc8, 0x35, 0x18, 0x95, 0xc3, 0x97, 0x49, 0x1f, 0x3e, 0x59, 0x6e, 0x6c, 0x03, 0x49, 0xd0, - 0xfb, 0x68, 0x18, 0xc5, 0xee, 0xa7, 0xdc, 0x70, 0x4f, 0x3e, 0x4b, 0x26, 0x10, 0x97, 0x66, 0xc5, - 0xf7, 0x8d, 0x6b, 0x8e, 0x09, 0x18, 0x48, 0xf5, 0x9f, 0x4f, 0xc3, 0x6c, 0xca, 0x9e, 0x7b, 0x8a, - 0x4c, 0x54, 0xd4, 0x37, 0x88, 0xb1, 0x30, 0xdc, 0x87, 0xdc, 0x16, 0xde, 0x85, 0xe1, 0x53, 0xb7, - 0x03, 0xee, 0x96, 0x12, 0xdb, 0x05, 0x38, 0xd9, 0xc7, 0x22, 0x17, 0xa9, 0x11, 0x79, 0x86, 0x9f, - 0x58, 0x44, 0x9e, 0x25, 0x98, 0x14, 0xad, 0x12, 0xdb, 0x95, 0x62, 0x1e, 0xed, 0xf1, 0x02, 0x2b, - 0xb1, 0x6d, 0xe9, 0x24, 0x9c, 0x87, 0xef, 0x36, 0x1f, 0x51, 0xc1, 0x63, 0x54, 0xe5, 0x81, 0x05, - 0xa9, 0x3c, 0x14, 0x12, 0xf2, 0x1f, 0x63, 0x82, 0x40, 0x84, 0xa8, 0x7b, 0x56, 0xbe, 0xdf, 0x9e, - 0xd5, 0x78, 0x32, 0x7b, 0xd6, 0xf3, 0xf2, 0x1b, 0xd3, 0xf7, 0xae, 0x94, 0xcf, 0x22, 0xbf, 0x9c, - 0x81, 0x19, 0x1e, 0x16, 0x46, 0xfd, 0xd8, 0xbe, 0xa1, 0x3e, 0xea, 0x4f, 0xe6, 0x63, 0x9f, 0x13, - 0x89, 0xb1, 0xd2, 0xbf, 0x35, 0xf9, 0x51, 0xe4, 0xbb, 0x00, 0xc2, 0x15, 0xc5, 0x83, 0xc9, 0x8e, - 0x2f, 0x3e, 0x97, 0xb2, 0x0b, 0x84, 0x48, 0x51, 0x12, 0x8f, 0x20, 0xa4, 0xd3, 0xd2, 0x42, 0x86, - 0x50, 0xf2, 0x37, 0x61, 0x8e, 0xad, 0x97, 0x10, 0x22, 0x82, 0x58, 0xcd, 0x8f, 0x63, 0x2d, 0x9f, - 0xe9, 0x2d, 0x13, 0x5d, 0x4f, 0x23, 0xe3, 0xa1, 0x87, 0xa3, 0x0c, 0xdd, 0x81, 0x1a, 0xef, 0x22, - 0xb5, 0x22, 0x8c, 0x0d, 0x87, 0x5f, 0xcf, 0x13, 0x6d, 0xf4, 0xd8, 0xdf, 0x2e, 0xca, 0xb5, 0xc0, - 0xf7, 0x37, 0x5f, 0xf7, 0x52, 0x46, 0x10, 0xf9, 0x22, 0x90, 0x30, 0x9e, 0x0a, 0x87, 0x51, 0x99, - 0x84, 0x83, 0xab, 0x9b, 0xa3, 0xb8, 0x2c, 0x9e, 0x2c, 0x56, 0x27, 0x49, 0x92, 0x98, 0x50, 0x98, - 0x13, 0x8d, 0x66, 0x50, 0x99, 0xbd, 0xcf, 0x9f, 0x9f, 0xd2, 0x42, 0x84, 0x45, 0x25, 0x51, 0x2a, - 0x6f, 0x25, 0x05, 0xa0, 0xa6, 0x72, 0x4a, 0x63, 0x47, 0x6e, 0xc3, 0x18, 0xba, 0x0a, 0xaf, 0x48, - 0x73, 0x2f, 0x61, 0x7a, 0x82, 0x4e, 0xc5, 0xd6, 0xbe, 0x6e, 0xb4, 0x15, 0xa1, 0xb2, 0xeb, 0x40, - 0xc5, 0x3b, 0x32, 0xbb, 0x6d, 0x54, 0x0a, 0x0b, 0x7d, 0x47, 0xc3, 0x3b, 0xb2, 0xbc, 0xae, 0xee, - 0x4b, 0x8e, 0x48, 0xe4, 0xeb, 0x30, 0xfe, 0xc0, 0x7e, 0x2c, 0x75, 0xc2, 0x42, 0xf1, 0xdb, 0x6f, - 0x07, 0x32, 0x64, 0x6b, 0x5a, 0xf6, 0x63, 0xab, 0xd1, 0x8d, 0x07, 0x3e, 0xc6, 0x6d, 0x48, 0x65, - 0x49, 0xbe, 0x0a, 0xa0, 0x68, 0xaa, 0xc9, 0xa9, 0x15, 0xbc, 0x20, 0x03, 0xdf, 0xa5, 0x6a, 0xb0, - 0x91, 0xbf, 0xc2, 0x30, 0x26, 0x39, 0xcc, 0x7d, 0x7c, 0x92, 0xc3, 0xb9, 0x8f, 0x4f, 0x72, 0xe0, - 0x0f, 0x25, 0x7c, 0xec, 0x71, 0x07, 0x3f, 0x9a, 0x3f, 0x7f, 0x6a, 0x6d, 0xcf, 0x49, 0x63, 0x42, - 0x3c, 0x0a, 0x8e, 0x62, 0x55, 0xc4, 0xf8, 0x2d, 0xec, 0xc0, 0xc5, 0x9e, 0x8b, 0x33, 0x25, 0xb0, - 0xf2, 0x0d, 0x3d, 0xb0, 0xf2, 0xc5, 0x5e, 0x87, 0xb8, 0xaf, 0x67, 0x73, 0x99, 0x2d, 0xcc, 0xf5, - 0x96, 0x7f, 0xbe, 0x9d, 0x8d, 0x1d, 0xea, 0xe2, 0xea, 0xc2, 0x33, 0x89, 0xf5, 0x92, 0x7a, 0xb2, - 0x98, 0x3c, 0x9a, 0x1f, 0xfb, 0x4a, 0xec, 0x79, 0x76, 0xec, 0xab, 0x62, 0x03, 0x0a, 0x00, 0x1f, - 0xf5, 0x7c, 0x7f, 0x1b, 0xa6, 0x78, 0xbe, 0xd7, 0xfb, 0xf4, 0xe8, 0xd0, 0xf5, 0x1a, 0x3c, 0x47, - 0x92, 0x90, 0xf2, 0x13, 0xc9, 0xda, 0x63, 0xb8, 0xa4, 0x22, 0xfd, 0x5b, 0x87, 0xb1, 0xf6, 0x8b, - 0xa9, 0xfb, 0x24, 0x43, 0xe8, 0xe7, 0xfa, 0x4a, 0xde, 0x08, 0x45, 0x41, 0xea, 0xa9, 0x39, 0x5d, - 0x3c, 0x09, 0x4c, 0x91, 0x08, 0xa9, 0x67, 0xfc, 0xcb, 0x1c, 0x10, 0x5e, 0x53, 0xd9, 0xee, 0xd8, - 0xe8, 0xfd, 0xed, 0x60, 0x3c, 0xa7, 0x82, 0xc0, 0xb1, 0x77, 0x9a, 0x54, 0x0d, 0x86, 0x26, 0x0c, - 0x78, 0xc3, 0x32, 0x2b, 0x7e, 0x95, 0x4a, 0x10, 0xf6, 0xd8, 0x4c, 0xb3, 0x1f, 0x65, 0x33, 0xfd, - 0x3a, 0x3c, 0x5b, 0xea, 0x60, 0xe2, 0x68, 0x59, 0xcb, 0x1d, 0xd7, 0x93, 0x53, 0x57, 0xf3, 0x2b, - 0xb4, 0x43, 0xb4, 0xc4, 0x97, 0xf6, 0x63, 0xa1, 0x48, 0x42, 0x6c, 0x5e, 0x76, 0x02, 0x35, 0x4e, - 0x85, 0x94, 0x84, 0x3a, 0x58, 0x92, 0x22, 0x09, 0x71, 0x12, 0xc9, 0xc3, 0xf1, 0xa4, 0x24, 0x84, - 0x19, 0xd1, 0x22, 0x1e, 0x8e, 0x47, 0x7b, 0x48, 0x53, 0x21, 0x09, 0x79, 0x1b, 0xc6, 0x4b, 0xdd, - 0xc0, 0x15, 0x8c, 0x85, 0xe5, 0x79, 0x64, 0x23, 0x2e, 0x3e, 0x45, 0xbb, 0x5c, 0x45, 0xe8, 0xc6, - 0x9f, 0xe6, 0xe0, 0x62, 0x72, 0x78, 0x45, 0x69, 0xb8, 0x3e, 0x32, 0xa7, 0xac, 0x8f, 0xb4, 0xd9, - 0x90, 0x8d, 0xb2, 0x59, 0x3c, 0x89, 0xd9, 0xc0, 0xf3, 0x4f, 0x7f, 0xc8, 0xd9, 0x50, 0x83, 0x71, - 0xf5, 0x44, 0x1d, 0xfa, 0xb0, 0x27, 0xaa, 0xca, 0x85, 0x5c, 0x83, 0x61, 0x1e, 0x9e, 0x63, 0x38, - 0x7a, 0x9c, 0x8a, 0x47, 0xe6, 0xe0, 0x18, 0xe4, 0xdf, 0x81, 0xcb, 0x7c, 0x4f, 0x8a, 0x37, 0x76, - 0xe9, 0x48, 0x72, 0x14, 0x03, 0xb7, 0x78, 0x72, 0x5c, 0xbc, 0xce, 0x95, 0x31, 0x56, 0xa2, 0xdb, - 0xac, 0x9d, 0x23, 0x4b, 0x7e, 0x99, 0x52, 0xc9, 0xa9, 0xbc, 0x8d, 0x32, 0x5c, 0x14, 0xa5, 0x91, - 0x63, 0xb8, 0x2c, 0x64, 0x83, 0x7c, 0x10, 0xe9, 0xd3, 0x70, 0x90, 0x63, 0xaa, 0x32, 0x2c, 0xc7, - 0xcc, 0xd5, 0x4a, 0x56, 0xe1, 0xd7, 0xd3, 0xfc, 0x7a, 0x78, 0x64, 0x70, 0x0e, 0xd6, 0x5d, 0x7a, - 0xa4, 0xd6, 0x2e, 0x9b, 0xaa, 0xb5, 0x93, 0x6a, 0x9f, 0x5c, 0xaa, 0xda, 0xa7, 0x02, 0xd3, 0xb5, - 0xee, 0x8e, 0xac, 0x3b, 0xee, 0x13, 0xea, 0x77, 0x77, 0xd2, 0x7a, 0x25, 0x4e, 0x62, 0xfc, 0x70, - 0x16, 0x26, 0x36, 0x9a, 0xdd, 0x3d, 0xa7, 0x5d, 0xb1, 0x03, 0xfb, 0xa9, 0x55, 0x24, 0xbe, 0xa9, - 0x29, 0x12, 0x43, 0xf7, 0xb5, 0xb0, 0x61, 0x03, 0x69, 0x11, 0x7f, 0x3a, 0x03, 0xd3, 0x11, 0x09, - 0x3f, 0xac, 0x57, 0x60, 0x88, 0xfd, 0x10, 0xd7, 0xeb, 0xcb, 0x09, 0xc6, 0x3c, 0x95, 0x65, 0xf8, - 0x97, 0x50, 0xed, 0xe9, 0x79, 0xe2, 0x90, 0xc3, 0xc2, 0x67, 0x61, 0x2c, 0x62, 0x7b, 0x96, 0x14, - 0x96, 0xbf, 0x9e, 0x81, 0x42, 0xbc, 0x25, 0xe4, 0x3e, 0x8c, 0x32, 0x4e, 0x0e, 0x95, 0x37, 0xff, - 0x97, 0x7a, 0xb4, 0xf9, 0xba, 0x40, 0xe3, 0x9f, 0x87, 0x9d, 0x4f, 0x39, 0xc4, 0x94, 0x1c, 0x16, - 0x4c, 0x98, 0x50, 0xb1, 0x52, 0xbe, 0xee, 0x35, 0x5d, 0x42, 0x39, 0x9f, 0xde, 0x0f, 0x5a, 0xe2, - 0x4d, 0xed, 0xab, 0x85, 0xf0, 0x71, 0x45, 0x9b, 0x5c, 0xa9, 0xab, 0x0a, 0x27, 0xcd, 0x62, 0x94, - 0x13, 0x41, 0x9d, 0x67, 0x29, 0x13, 0x3a, 0xc4, 0x23, 0xaf, 0xc1, 0x08, 0xaf, 0x4f, 0x4d, 0x1a, - 0xd7, 0x41, 0x88, 0x2a, 0x89, 0x73, 0x1c, 0xe3, 0xef, 0xe5, 0xe0, 0x7c, 0xf4, 0x79, 0x5b, 0x9d, - 0x86, 0x1d, 0xd0, 0x0d, 0xdb, 0xb3, 0x5b, 0xfe, 0x29, 0x2b, 0xe0, 0x6a, 0xe2, 0xd3, 0x30, 0x5d, - 0x97, 0xfc, 0x34, 0xe5, 0x83, 0x8c, 0xd8, 0x07, 0xa1, 0x96, 0x95, 0x7f, 0x90, 0xfc, 0x0c, 0x72, - 0x1f, 0x72, 0x35, 0x1a, 0x88, 0xbd, 0xf7, 0x4a, 0xa2, 0x57, 0xd5, 0xef, 0xba, 0x5e, 0xa3, 0x01, - 0x1f, 0x44, 0x1e, 0x7b, 0x4a, 0x0b, 0x00, 0xc8, 0xb8, 0x90, 0x6d, 0x18, 0x59, 0x7e, 0xdc, 0xa1, - 0xf5, 0x40, 0x24, 0x60, 0xbd, 0xd6, 0x9f, 0x1f, 0xc7, 0x55, 0xf2, 0xaf, 0x52, 0x04, 0xa8, 0x9d, - 0xc5, 0x51, 0x16, 0x6e, 0x43, 0x5e, 0x56, 0x7e, 0x96, 0x99, 0xbb, 0xf0, 0x26, 0x8c, 0x2b, 0x95, - 0x9c, 0x69, 0xd2, 0xff, 0x02, 0xdb, 0x57, 0xdd, 0xa6, 0xcc, 0xd9, 0xba, 0x9c, 0x90, 0x15, 0x95, - 0x8c, 0x57, 0x5c, 0x56, 0xb4, 0x0e, 0x44, 0x51, 0x1f, 0xa1, 0xb1, 0x0a, 0xd3, 0xb5, 0x03, 0xa7, - 0x13, 0x05, 0xa3, 0xd5, 0x4e, 0x64, 0xcc, 0xaa, 0x23, 0x54, 0x03, 0xf1, 0x13, 0x39, 0x4e, 0x67, - 0xfc, 0x45, 0x06, 0x46, 0xd8, 0x5f, 0x0f, 0x6f, 0x3f, 0xa5, 0x5b, 0xe6, 0x2d, 0x6d, 0xcb, 0x9c, - 0x51, 0xe2, 0xc1, 0xe3, 0xc6, 0x71, 0xfb, 0x94, 0xcd, 0xf2, 0x58, 0x0c, 0x10, 0x47, 0x26, 0x77, - 0x61, 0x54, 0x18, 0x2d, 0x09, 0xfb, 0x72, 0x35, 0xc0, 0xbc, 0x34, 0x67, 0x0a, 0x75, 0x08, 0x6e, - 0x27, 0xae, 0x74, 0x91, 0xd4, 0x4c, 0xae, 0x97, 0x61, 0x81, 0xb5, 0x4c, 0xdf, 0x2e, 0x3a, 0x04, - 0xf2, 0xf0, 0xe8, 0x4a, 0x6e, 0xfe, 0x1e, 0xfe, 0xfb, 0x25, 0xf1, 0xde, 0x92, 0xeb, 0xc7, 0xe4, - 0xbc, 0x4c, 0x84, 0x9c, 0xfa, 0x14, 0xd3, 0x82, 0xf3, 0xb5, 0xda, 0x0a, 0x1a, 0x38, 0x6e, 0xb8, - 0x5e, 0x70, 0xc7, 0xf5, 0x0e, 0x6d, 0xb4, 0x5f, 0x46, 0x1d, 0xa2, 0x62, 0xe5, 0x90, 0x66, 0x76, - 0xf6, 0x4a, 0xaa, 0xd9, 0x59, 0x1f, 0x4b, 0x08, 0xa3, 0x0d, 0x17, 0x6a, 0xb5, 0x15, 0x1e, 0x9c, - 0xfc, 0x2f, 0xa3, 0xbe, 0x5f, 0xcf, 0xc0, 0x4c, 0xad, 0xb6, 0x12, 0xab, 0x6a, 0x55, 0x46, 0x45, - 0xcf, 0x68, 0x4f, 0xad, 0xe9, 0x1d, 0x81, 0xa3, 0x90, 0xe1, 0x12, 0x5e, 0x5d, 0x0b, 0x80, 0xc9, - 0x99, 0x90, 0x8d, 0x30, 0x0e, 0x7b, 0x56, 0xf3, 0x39, 0xe8, 0xd1, 0x50, 0xd4, 0xa1, 0x0b, 0x8f, - 0x3d, 0x56, 0xaa, 0xeb, 0xd0, 0x19, 0xc4, 0xf8, 0x6f, 0xcf, 0xf3, 0x48, 0xef, 0x72, 0xb6, 0xbc, - 0x03, 0x13, 0x82, 0x1e, 0x0d, 0xf3, 0x85, 0xd5, 0xc9, 0x45, 0xb6, 0x41, 0xee, 0x72, 0x38, 0x8f, - 0x00, 0xfc, 0x9d, 0xe3, 0xe2, 0x10, 0xeb, 0x1a, 0x53, 0x43, 0x27, 0xeb, 0x30, 0xf9, 0xc0, 0x7e, - 0xac, 0x28, 0x4c, 0xb8, 0xdb, 0xd5, 0x35, 0xb6, 0xab, 0xb4, 0xec, 0xc7, 0x03, 0x98, 0xf5, 0xe9, - 0xf4, 0xe4, 0x00, 0xa6, 0xf4, 0x36, 0x89, 0x19, 0x98, 0x1c, 0xb1, 0x9b, 0xa9, 0x23, 0x76, 0xb1, - 0xe3, 0x7a, 0x81, 0xb5, 0x1b, 0x92, 0x6b, 0x59, 0x0d, 0x62, 0xac, 0xc9, 0x3b, 0x30, 0xa3, 0x84, - 0x19, 0xbd, 0xe3, 0x7a, 0x2d, 0x5b, 0x5e, 0xb8, 0xf0, 0x15, 0x01, 0xad, 0x95, 0x76, 0x11, 0x6c, - 0x26, 0x31, 0xc9, 0x97, 0xd3, 0x5c, 0xd9, 0x86, 0x23, 0xdb, 0xc6, 0x14, 0x57, 0xb6, 0x5e, 0xb6, - 0x8d, 0x49, 0xa7, 0xb6, 0xbd, 0x7e, 0xb6, 0xcf, 0x79, 0xde, 0xfa, 0x81, 0x6c, 0x9b, 0xc3, 0x91, - 0xeb, 0x61, 0xe3, 0xbc, 0x08, 0xb9, 0xa5, 0x8d, 0x3b, 0xf8, 0xf6, 0x25, 0xcd, 0xb4, 0xda, 0xfb, - 0x76, 0xbb, 0x8e, 0x17, 0x21, 0xe1, 0x71, 0xa0, 0x1e, 0x94, 0x4b, 0x1b, 0x77, 0x88, 0x0d, 0xb3, - 0x98, 0x4b, 0x2e, 0xf8, 0xd2, 0xcd, 0x9b, 0xca, 0x50, 0xe5, 0xf1, 0xd3, 0x6e, 0x88, 0x4f, 0x2b, - 0x62, 0x26, 0xba, 0xc0, 0x7a, 0x7c, 0xf3, 0x66, 0xea, 0x80, 0x84, 0x1f, 0x96, 0xc6, 0x8b, 0x1d, - 0x58, 0x0f, 0xec, 0xc7, 0x91, 0xa3, 0x88, 0x2f, 0x9c, 0x82, 0x9f, 0x97, 0x53, 0x2b, 0x72, 0x32, - 0xd1, 0x0e, 0x2c, 0x9d, 0x88, 0xdd, 0x63, 0xa3, 0x09, 0xe6, 0x0b, 0x77, 0xaa, 0x05, 0xa9, 0x10, - 0x94, 0x9e, 0xe3, 0xea, 0x65, 0x4c, 0x41, 0x27, 0x5b, 0xe1, 0x6d, 0x9c, 0xdf, 0x66, 0x45, 0xf6, - 0xe5, 0x1b, 0xea, 0x6d, 0x9c, 0xab, 0xe1, 0xb4, 0x66, 0x4d, 0x87, 0x2a, 0x1c, 0xee, 0x39, 0x63, - 0xea, 0x5c, 0x92, 0x97, 0xfc, 0x89, 0xb3, 0x5f, 0xf2, 0x29, 0x0c, 0xad, 0xba, 0xf5, 0x03, 0x11, - 0x00, 0xf0, 0x8b, 0x6c, 0x17, 0x6e, 0xba, 0xf5, 0x83, 0x27, 0x67, 0xd3, 0x8d, 0xec, 0xc9, 0x1a, - 0xfb, 0x54, 0x36, 0x0b, 0x44, 0x9f, 0x08, 0x3b, 0xe1, 0xb9, 0xf0, 0x96, 0xab, 0x94, 0x71, 0x79, - 0x94, 0x4f, 0x1a, 0xd9, 0xb5, 0xa6, 0x4e, 0x4e, 0x28, 0x14, 0x2a, 0xd4, 0x3f, 0x08, 0xdc, 0x4e, - 0xb9, 0xe9, 0x74, 0x76, 0x5c, 0xdb, 0x93, 0xe1, 0xa2, 0x07, 0xde, 0x93, 0x1b, 0x9c, 0xde, 0xaa, - 0x4b, 0x06, 0x66, 0x82, 0x25, 0xf9, 0x32, 0x4c, 0xb1, 0xc9, 0xbd, 0xfc, 0x38, 0xa0, 0x6d, 0x3e, - 0xf2, 0x33, 0x28, 0xd1, 0xcd, 0x29, 0xf9, 0x51, 0xc2, 0x42, 0x3e, 0xa7, 0x70, 0xb1, 0xd3, 0x90, - 0x40, 0x0b, 0x9e, 0xa8, 0xb1, 0x22, 0x0d, 0x98, 0x7f, 0x60, 0x3f, 0x56, 0xf2, 0x3c, 0x2b, 0x93, - 0x94, 0xe0, 0x04, 0xbb, 0x7a, 0x72, 0x5c, 0x7c, 0x89, 0x4d, 0xb0, 0x28, 0x82, 0x79, 0x8f, 0xf9, - 0xda, 0x93, 0x13, 0xf9, 0x26, 0x5c, 0x10, 0xcd, 0xaa, 0x60, 0x6e, 0x32, 0xd7, 0x3b, 0xaa, 0xed, - 0xdb, 0xe8, 0x23, 0x36, 0xdb, 0xa3, 0xc3, 0x6e, 0xa4, 0x6f, 0x89, 0xb2, 0xc3, 0x1a, 0x92, 0x8f, - 0xe5, 0x73, 0x46, 0x66, 0xaf, 0x1a, 0xc8, 0x07, 0x30, 0xc5, 0x1f, 0xfc, 0x56, 0x5c, 0x3f, 0x40, - 0x65, 0xcd, 0xdc, 0xd9, 0x1c, 0x1f, 0xf8, 0x2b, 0x22, 0x77, 0x16, 0x8a, 0x29, 0x77, 0x62, 0x9c, - 0xc9, 0x5b, 0x30, 0xbe, 0xe1, 0xb4, 0x79, 0x78, 0xd3, 0xea, 0x06, 0x2a, 0xae, 0xc5, 0x09, 0xd4, - 0x71, 0xda, 0x96, 0xd4, 0x98, 0x74, 0xc2, 0xed, 0x42, 0xc5, 0x26, 0xdb, 0x30, 0x5e, 0xab, 0xad, - 0xdc, 0x71, 0x98, 0x5c, 0xd2, 0x91, 0x7a, 0xe8, 0xe4, 0x57, 0xbe, 0x98, 0xfa, 0x95, 0x93, 0xbe, - 0xbf, 0x6f, 0xed, 0x3a, 0x4d, 0x6a, 0xd5, 0xdd, 0xce, 0x91, 0xa9, 0x72, 0x4a, 0x71, 0x06, 0xb8, - 0xf0, 0x84, 0x9d, 0x01, 0xaa, 0x30, 0xad, 0x98, 0xe7, 0xa2, 0x69, 0xee, 0x7c, 0x14, 0x13, 0x4b, - 0x35, 0xfe, 0x8f, 0xbb, 0xbf, 0xc6, 0xe9, 0xa4, 0x17, 0xc0, 0xc5, 0xb3, 0x7a, 0x01, 0x38, 0x30, - 0xc3, 0x07, 0x43, 0xcc, 0x03, 0x1c, 0xe9, 0x85, 0x1e, 0x7d, 0x78, 0x2d, 0xb5, 0x0f, 0x67, 0xc5, - 0x48, 0xcb, 0x49, 0x86, 0x0f, 0xdc, 0x49, 0xae, 0x64, 0x17, 0x88, 0x00, 0xda, 0x81, 0xbd, 0x63, - 0xfb, 0x14, 0xeb, 0x7a, 0xb6, 0x47, 0x5d, 0x2f, 0xa5, 0xd6, 0x35, 0x25, 0xeb, 0xda, 0xe1, 0xd5, - 0xa4, 0x70, 0x24, 0x6d, 0x59, 0x8f, 0x9c, 0x5f, 0xd8, 0xb1, 0xcf, 0x69, 0x3a, 0xee, 0x24, 0x02, - 0x0f, 0x2f, 0x15, 0x9f, 0xb4, 0xf1, 0x7e, 0x4f, 0xe1, 0x4c, 0x1e, 0xc3, 0xf9, 0xe4, 0x57, 0x60, - 0x9d, 0xcf, 0x63, 0x9d, 0xcf, 0x6b, 0x75, 0xc6, 0x91, 0xf8, 0xbc, 0xd1, 0x9b, 0x15, 0xaf, 0xb5, - 0x07, 0x7f, 0xf2, 0x83, 0x19, 0xb8, 0xf0, 0xe0, 0x4e, 0x09, 0x33, 0x96, 0x3a, 0x3c, 0xda, 0x5d, - 0xe8, 0x36, 0x7c, 0x49, 0xbc, 0x83, 0xc4, 0xdf, 0x63, 0xa4, 0xc4, 0x81, 0x5b, 0x05, 0x13, 0xdd, - 0x5f, 0x6c, 0xed, 0xda, 0x3c, 0x11, 0xaa, 0x60, 0x91, 0xe2, 0x5b, 0xfc, 0x73, 0x7f, 0x5c, 0xcc, - 0x98, 0xbd, 0xaa, 0x22, 0x4d, 0x58, 0xd0, 0xbb, 0x45, 0xfa, 0x69, 0xec, 0xd3, 0x66, 0x73, 0xbe, - 0x88, 0x33, 0xfa, 0xb5, 0x93, 0xe3, 0xe2, 0xd5, 0x44, 0xef, 0x86, 0xbe, 0x1f, 0x0c, 0x53, 0x69, - 0x70, 0x1f, 0x7e, 0xa4, 0x95, 0x22, 0x74, 0xcf, 0x5f, 0xd6, 0xe2, 0x0b, 0x25, 0xca, 0x97, 0x5e, - 0x16, 0x12, 0xc9, 0xf3, 0x6c, 0xbd, 0xf7, 0x14, 0x10, 0xcd, 0x24, 0xe7, 0x7b, 0x43, 0xf9, 0xc9, - 0xc2, 0x54, 0x8a, 0x53, 0x84, 0xf1, 0xdb, 0xd9, 0xd8, 0xc1, 0x48, 0xaa, 0x30, 0x2a, 0xe6, 0x7b, - 0xcf, 0x4b, 0xc6, 0xf3, 0xa9, 0xb3, 0x7a, 0x54, 0x2c, 0x1d, 0x53, 0xd2, 0x93, 0x43, 0xc6, 0x0a, - 0x1b, 0x2d, 0x6e, 0xbc, 0x5f, 0xe5, 0xe7, 0x1e, 0x82, 0xb4, 0x13, 0xbe, 0x72, 0x76, 0x67, 0x3f, - 0xdd, 0x97, 0x14, 0x8f, 0x7a, 0x59, 0x1b, 0x39, 0xe0, 0xe9, 0xaa, 0x72, 0xa1, 0xbf, 0x98, 0x9e, - 0x9b, 0xea, 0x89, 0x55, 0xc8, 0x6a, 0x31, 0x7e, 0x2b, 0x03, 0x93, 0xda, 0xc9, 0x4a, 0x6e, 0x2b, - 0xee, 0x90, 0x51, 0x84, 0x00, 0x0d, 0x07, 0x37, 0xdb, 0xb8, 0xa3, 0xe4, 0x6d, 0xe1, 0xd9, 0x90, - 0xed, 0x4d, 0x87, 0x8b, 0x2d, 0xee, 0x1d, 0xdb, 0x5f, 0x3f, 0x1c, 0xe6, 0xda, 0x1c, 0xea, 0x91, - 0x6b, 0xf3, 0x1f, 0x16, 0x61, 0x4a, 0xbf, 0x11, 0x93, 0xd7, 0x60, 0x04, 0x75, 0xf3, 0x52, 0xbd, - 0x82, 0x6a, 0x21, 0x54, 0xdf, 0x6b, 0xee, 0x2e, 0x1c, 0x87, 0xbc, 0x0c, 0x10, 0x9a, 0x98, 0xcb, - 0x97, 0xa9, 0xe1, 0x93, 0xe3, 0x62, 0xe6, 0x75, 0x53, 0x29, 0x20, 0x5f, 0x03, 0x58, 0x73, 0x1b, - 0x34, 0x4c, 0xa0, 0xdc, 0xc7, 0xbe, 0xe3, 0x95, 0x44, 0x2a, 0x97, 0x73, 0x6d, 0xb7, 0x41, 0x93, - 0x79, 0x5b, 0x14, 0x8e, 0xe4, 0xf3, 0x30, 0x6c, 0x76, 0x9b, 0x54, 0xbe, 0x60, 0x8c, 0xcb, 0x13, - 0xae, 0xdb, 0xa4, 0x91, 0x9e, 0xc0, 0xeb, 0xc6, 0x4d, 0x17, 0x19, 0x80, 0xbc, 0xc7, 0x53, 0xbc, - 0x88, 0x38, 0xa4, 0xc3, 0xd1, 0x5b, 0x9d, 0x22, 0xf9, 0x24, 0x22, 0x91, 0x2a, 0x24, 0x64, 0x1d, - 0x46, 0xd5, 0x47, 0x26, 0xc5, 0xaf, 0x5e, 0x7d, 0x88, 0x54, 0x94, 0x0e, 0x22, 0xf3, 0x72, 0xfc, - 0xfd, 0x49, 0x72, 0x21, 0x6f, 0xc3, 0x18, 0x63, 0xcf, 0x76, 0x0e, 0x5f, 0xdc, 0x6a, 0xf0, 0x45, - 0x4e, 0xf9, 0x20, 0xb6, 0xfb, 0x68, 0xd1, 0x42, 0x43, 0x02, 0xf2, 0x65, 0xcc, 0x95, 0x2b, 0xba, - 0xba, 0xaf, 0xdd, 0xcf, 0x95, 0x44, 0x57, 0x63, 0xf2, 0xdc, 0x44, 0x4f, 0x47, 0xfc, 0xc8, 0x5e, - 0x18, 0xd6, 0x6d, 0x90, 0xb4, 0x3c, 0xaf, 0x26, 0x2a, 0x98, 0x97, 0x91, 0xca, 0x92, 0x89, 0xb0, - 0x35, 0xbe, 0xa4, 0x03, 0x85, 0x48, 0xa8, 0x14, 0x75, 0x41, 0xbf, 0xba, 0x5e, 0x4f, 0xd4, 0xa5, - 0x0e, 0x60, 0xa2, 0xba, 0x04, 0x77, 0xd2, 0x80, 0x29, 0x79, 0x40, 0x89, 0xfa, 0xc6, 0xfb, 0xd5, - 0xf7, 0x72, 0xa2, 0xbe, 0xd9, 0xc6, 0x4e, 0xb2, 0x9e, 0x18, 0x4f, 0xf2, 0x36, 0x4c, 0x4a, 0x08, - 0x4f, 0x4b, 0x3d, 0x11, 0xe5, 0xf5, 0x6d, 0xec, 0x24, 0x92, 0x51, 0xeb, 0xc8, 0x2a, 0x35, 0x9f, - 0x1d, 0x93, 0x1a, 0x75, 0x7c, 0x56, 0xe8, 0xc8, 0xe4, 0x7d, 0x18, 0xaf, 0xb6, 0x58, 0x43, 0xdc, - 0xb6, 0x1d, 0x50, 0xe1, 0x71, 0x29, 0x6d, 0x98, 0x94, 0x12, 0x65, 0xaa, 0xf2, 0x84, 0xdb, 0x51, - 0x91, 0x96, 0x70, 0x3b, 0x02, 0xb3, 0xce, 0xe3, 0xaf, 0x8a, 0x62, 0x0e, 0x4b, 0x6f, 0xcc, 0xe7, - 0x53, 0xec, 0x88, 0x14, 0xf6, 0x22, 0xe6, 0x24, 0x83, 0xca, 0x57, 0xbd, 0x58, 0xbc, 0x5f, 0x95, - 0x27, 0x79, 0x07, 0xc6, 0x45, 0xc6, 0xb2, 0x92, 0xb9, 0xe6, 0xcf, 0x17, 0xb0, 0xf1, 0x18, 0x45, - 0x42, 0x26, 0x37, 0xb3, 0x6c, 0x2f, 0x66, 0x30, 0x1b, 0xe1, 0x93, 0x2f, 0xc1, 0xdc, 0xb6, 0xd3, - 0x6e, 0xb8, 0x87, 0xbe, 0x38, 0xa6, 0xc4, 0x46, 0x37, 0x13, 0xb9, 0xab, 0x1d, 0xf2, 0xf2, 0x50, - 0x16, 0x4c, 0x6c, 0x7c, 0xa9, 0x1c, 0xc8, 0xf7, 0x24, 0x38, 0xf3, 0x19, 0x44, 0xfa, 0xcd, 0xa0, - 0xc5, 0xc4, 0x0c, 0x4a, 0x56, 0x1f, 0x9f, 0x4e, 0xa9, 0xd5, 0x10, 0x17, 0x88, 0x7e, 0xbe, 0xdf, - 0x73, 0x9d, 0xf6, 0xfc, 0x2c, 0xee, 0x85, 0xcf, 0xc6, 0xe3, 0x36, 0x20, 0x9e, 0x48, 0x5c, 0x6e, - 0x9c, 0x1c, 0x17, 0x2f, 0xc5, 0x65, 0xfe, 0x0f, 0x5c, 0xed, 0xb9, 0x24, 0x85, 0x35, 0x79, 0x1f, - 0x26, 0xd8, 0xff, 0xa1, 0x52, 0x62, 0x4e, 0xb3, 0x3c, 0x55, 0x30, 0x45, 0x3d, 0x38, 0x46, 0x98, - 0x52, 0x2d, 0x45, 0x5f, 0xa1, 0xb1, 0x22, 0x6f, 0x02, 0x30, 0xb1, 0x49, 0x6c, 0xc7, 0xe7, 0xa2, - 0xf0, 0xca, 0x28, 0x75, 0x25, 0x37, 0xe2, 0x08, 0x99, 0xbc, 0x0d, 0xe3, 0xec, 0x57, 0xad, 0xdb, - 0x70, 0xd9, 0xda, 0x38, 0x8f, 0xb4, 0xdc, 0xf9, 0x95, 0xd1, 0xfa, 0x1c, 0xae, 0x39, 0xbf, 0x46, - 0xe8, 0x64, 0x05, 0xa6, 0x31, 0x0c, 0xb6, 0x08, 0xc0, 0xea, 0x50, 0x7f, 0xfe, 0x82, 0x62, 0x0d, - 0xc1, 0x8a, 0x2c, 0x27, 0x2c, 0x53, 0xef, 0x32, 0x31, 0x32, 0xe2, 0xc3, 0x6c, 0xf2, 0x39, 0xd9, - 0x9f, 0x9f, 0xc7, 0x4e, 0x92, 0x12, 0x7c, 0x12, 0x83, 0xef, 0xc7, 0x6c, 0x44, 0x94, 0x8d, 0x4b, - 0x3e, 0x2a, 0xa9, 0x15, 0xa6, 0x71, 0x27, 0x26, 0x90, 0xbb, 0xe5, 0x8d, 0x78, 0x9c, 0xe8, 0x8b, - 0xd8, 0x02, 0x1c, 0xe6, 0xbd, 0x7a, 0x94, 0xa9, 0x3c, 0x25, 0x56, 0x74, 0x0a, 0x35, 0xf9, 0x6e, - 0x38, 0x27, 0x77, 0x10, 0x51, 0x24, 0xe6, 0xf5, 0xc2, 0x19, 0x77, 0xe2, 0xc6, 0x4e, 0x58, 0x75, - 0x62, 0x4a, 0xa7, 0x57, 0x41, 0x6c, 0x18, 0xc7, 0x61, 0x15, 0x35, 0x3e, 0xdb, 0xaf, 0xc6, 0xab, - 0x89, 0x1a, 0xcf, 0xe3, 0x44, 0x49, 0x56, 0xa6, 0xf2, 0x24, 0x4b, 0x30, 0x29, 0xd6, 0x91, 0x98, - 0x6d, 0xcf, 0x61, 0x6f, 0xa1, 0x12, 0x4b, 0xae, 0xc0, 0xc4, 0x84, 0xd3, 0x49, 0xd4, 0x1d, 0x99, - 0x3f, 0x26, 0x3d, 0xaf, 0xed, 0xc8, 0xf1, 0x37, 0x24, 0x1d, 0x99, 0xed, 0x48, 0x91, 0x14, 0xb3, - 0xfc, 0xb8, 0xe3, 0x09, 0x15, 0xd5, 0xa5, 0x28, 0xf3, 0x92, 0x22, 0xfc, 0x58, 0x34, 0xc4, 0x50, - 0xb7, 0x84, 0x34, 0x0e, 0x64, 0x0b, 0x66, 0xc3, 0x53, 0x5b, 0x61, 0x5c, 0x8c, 0x22, 0x11, 0x47, - 0x47, 0x7d, 0x3a, 0xdf, 0x34, 0x7a, 0x62, 0xc3, 0x05, 0xed, 0x9c, 0x56, 0x58, 0x5f, 0x46, 0xd6, - 0x98, 0x19, 0x5f, 0x3f, 0xe4, 0xd3, 0xd9, 0xf7, 0xe2, 0x43, 0x3e, 0x80, 0x85, 0xf8, 0xd9, 0xac, - 0xd4, 0xf2, 0x02, 0xd6, 0xf2, 0xea, 0xc9, 0x71, 0xf1, 0x4a, 0xe2, 0x78, 0x4f, 0xaf, 0xa8, 0x0f, - 0x37, 0xf2, 0x35, 0x98, 0xd7, 0xcf, 0x67, 0xa5, 0x26, 0x03, 0x6b, 0xc2, 0xa5, 0x13, 0x1e, 0xec, - 0xe9, 0x35, 0xf4, 0xe4, 0x41, 0x02, 0x28, 0xa6, 0xce, 0x6e, 0xa5, 0x9a, 0x17, 0xa3, 0x06, 0x25, - 0x56, 0x49, 0x7a, 0x75, 0xa7, 0xb1, 0x24, 0x87, 0x70, 0x29, 0xed, 0x98, 0x50, 0x2a, 0x7d, 0x29, - 0x54, 0x02, 0x7f, 0x2a, 0xfd, 0xc8, 0x49, 0xaf, 0xf9, 0x14, 0xb6, 0xe4, 0xcb, 0x70, 0x4e, 0x59, - 0x5f, 0x4a, 0x7d, 0x2f, 0x63, 0x7d, 0xe8, 0x6c, 0xae, 0x2e, 0xcc, 0xf4, 0x5a, 0xd2, 0x79, 0x90, - 0x16, 0xcc, 0xca, 0x86, 0xa3, 0xb6, 0x5d, 0x1c, 0x3d, 0x57, 0xb4, 0x5d, 0x35, 0x89, 0xb1, 0x74, - 0x59, 0xec, 0xaa, 0xf3, 0x8d, 0x1d, 0xab, 0x13, 0x11, 0xaa, 0x33, 0x3d, 0x85, 0x2f, 0x59, 0x81, - 0x91, 0xda, 0x46, 0xf5, 0xce, 0x9d, 0xe5, 0xf9, 0x57, 0xb0, 0x06, 0xe9, 0x99, 0xc6, 0x81, 0xda, - 0xa5, 0x49, 0x98, 0x2b, 0x76, 0x9c, 0xdd, 0x5d, 0xed, 0xc1, 0x8a, 0xa3, 0x92, 0xef, 0x41, 0x43, - 0x41, 0xb6, 0xa3, 0x96, 0x7c, 0xdf, 0xd9, 0xc3, 0xc8, 0xd6, 0xfe, 0xfc, 0xab, 0xda, 0x7b, 0xbf, - 0x8c, 0xfa, 0x5d, 0xc6, 0xa4, 0x68, 0x09, 0x74, 0x2e, 0x6d, 0xb2, 0xfb, 0xbf, 0xd8, 0xb9, 0x2d, - 0x3b, 0x62, 0xa5, 0x6e, 0xe2, 0xc9, 0x8a, 0x58, 0xbf, 0xed, 0x39, 0x81, 0xb5, 0xdf, 0xd5, 0x9a, - 0x3f, 0xff, 0x29, 0x2d, 0xca, 0x33, 0x4f, 0x15, 0xa7, 0xf4, 0xda, 0x4b, 0xa2, 0xc2, 0xe7, 0xf8, - 0x6d, 0xb9, 0x47, 0xcf, 0xcd, 0xec, 0xc5, 0xe8, 0x7c, 0xf2, 0x03, 0x19, 0x38, 0xbf, 0xed, 0x7a, - 0x07, 0x4d, 0xd7, 0x6e, 0xc8, 0x56, 0x89, 0x3d, 0xfc, 0xb5, 0x7e, 0x7b, 0xf8, 0x67, 0x12, 0x7b, - 0xb8, 0x71, 0x28, 0xd8, 0x58, 0x61, 0xd0, 0xf4, 0xc4, 0x7e, 0xde, 0xa3, 0x2a, 0xf2, 0x3d, 0x70, - 0x39, 0xbd, 0x44, 0x99, 0x94, 0xaf, 0xe3, 0xa4, 0xbc, 0x79, 0x72, 0x5c, 0x7c, 0xbd, 0x57, 0x4d, - 0xe9, 0x13, 0xf4, 0x54, 0xd6, 0xf7, 0x86, 0xf2, 0x57, 0x0b, 0xd7, 0xee, 0x0d, 0xe5, 0xaf, 0x15, - 0x5e, 0x35, 0x9f, 0xab, 0x95, 0x1e, 0xac, 0x56, 0x1b, 0xf2, 0x70, 0x95, 0x71, 0xdd, 0x39, 0x8d, - 0x79, 0xa5, 0x5f, 0x69, 0xc4, 0xd1, 0xf8, 0x3b, 0x19, 0x28, 0x9e, 0x32, 0x49, 0xd8, 0x79, 0x16, - 0x8d, 0x44, 0x8d, 0x06, 0x6a, 0x74, 0xf8, 0x68, 0xfc, 0x2c, 0xdd, 0x6c, 0x44, 0x27, 0x41, 0xb7, - 0x46, 0x91, 0x92, 0x44, 0xf1, 0x6e, 0x4d, 0xa6, 0x22, 0x91, 0x58, 0xc6, 0x2a, 0x14, 0xe2, 0x93, - 0x87, 0x7c, 0x0e, 0x26, 0xd5, 0x84, 0x08, 0x52, 0x95, 0xc0, 0x43, 0x99, 0x78, 0x7b, 0xda, 0x81, - 0xa8, 0x21, 0x1a, 0xbf, 0x90, 0x81, 0xd9, 0x94, 0x15, 0x46, 0xae, 0xc0, 0x10, 0x66, 0x2c, 0x53, - 0xac, 0x86, 0x62, 0x99, 0xca, 0xb0, 0x9c, 0x7c, 0x1a, 0x46, 0x2b, 0x6b, 0xb5, 0x5a, 0x69, 0x4d, - 0x2a, 0x23, 0xf8, 0x41, 0xdc, 0xf6, 0x2d, 0xdf, 0xd6, 0x8d, 0x0d, 0x04, 0x1a, 0x79, 0x1d, 0x46, - 0xaa, 0x1b, 0x48, 0xc0, 0x6d, 0x5f, 0xb1, 0xbd, 0x4e, 0x27, 0x8e, 0x2f, 0x90, 0x8c, 0x1f, 0xcd, - 0x00, 0x49, 0x6e, 0x17, 0xe4, 0x26, 0x8c, 0xab, 0x9b, 0x12, 0x6f, 0x2f, 0xbe, 0xc0, 0x2a, 0x0b, - 0xc7, 0x54, 0x71, 0x48, 0x05, 0x86, 0x31, 0xd7, 0x6c, 0x68, 0xe5, 0x90, 0xba, 0x2c, 0x2e, 0x24, - 0x96, 0xc5, 0x30, 0x66, 0xb2, 0x35, 0x39, 0xb1, 0xf1, 0x7b, 0x19, 0x20, 0xe9, 0xb6, 0x8b, 0x03, - 0x59, 0x59, 0xbd, 0xa1, 0x44, 0x47, 0x50, 0x73, 0x12, 0x85, 0x09, 0xe5, 0x54, 0x35, 0x40, 0x14, - 0x47, 0xe1, 0x8a, 0xa6, 0x76, 0xea, 0xed, 0x52, 0x7b, 0x0d, 0x86, 0x1f, 0x52, 0x6f, 0x47, 0x9a, - 0x75, 0xa3, 0x29, 0xe8, 0x23, 0x06, 0x50, 0xd5, 0x30, 0x88, 0x61, 0xfc, 0x69, 0x06, 0xe6, 0xd2, - 0xee, 0x28, 0xa7, 0x78, 0xbe, 0x1a, 0x31, 0xa7, 0x5d, 0xb4, 0xb0, 0xe2, 0x76, 0xa2, 0xa1, 0xab, - 0x6e, 0x11, 0x86, 0x59, 0x63, 0xe5, 0x08, 0xa3, 0x1a, 0x8c, 0xf5, 0x86, 0x6f, 0x72, 0x38, 0x43, - 0xe0, 0x71, 0x00, 0x87, 0x30, 0x84, 0x24, 0x22, 0xe0, 0xec, 0x36, 0x39, 0x9c, 0x21, 0x3c, 0x70, - 0x1b, 0x54, 0xaa, 0x87, 0x10, 0xa1, 0xc5, 0x00, 0x26, 0x87, 0x93, 0x2b, 0x30, 0xba, 0xde, 0x5e, - 0xa5, 0xf6, 0x23, 0x99, 0x17, 0x03, 0x2d, 0xc2, 0xdc, 0xb6, 0xd5, 0x64, 0x30, 0x53, 0x16, 0x1a, - 0x3f, 0x9d, 0x81, 0x99, 0xc4, 0xf5, 0xe8, 0x74, 0xe7, 0xde, 0xfe, 0x5e, 0x76, 0x83, 0xb4, 0x8f, - 0x7f, 0xfe, 0x50, 0xfa, 0xe7, 0x1b, 0xff, 0xfd, 0x08, 0x5c, 0xe8, 0xa1, 0xad, 0x8a, 0xbc, 0x80, - 0x33, 0xa7, 0x7a, 0x01, 0x7f, 0x05, 0x26, 0xcb, 0x4d, 0xdb, 0x69, 0xf9, 0x9b, 0x6e, 0xf4, 0xc5, - 0x91, 0x33, 0x11, 0x96, 0x09, 0x3f, 0x88, 0xd0, 0xeb, 0xe4, 0x62, 0x1d, 0x29, 0xac, 0xc0, 0x4d, - 0x0a, 0xcb, 0x1a, 0xb3, 0x84, 0x1f, 0x6e, 0xee, 0xaf, 0x88, 0x1f, 0xae, 0xee, 0x19, 0x36, 0xf4, - 0x44, 0x3d, 0xc3, 0xd2, 0x6d, 0xbe, 0x87, 0x3f, 0x8a, 0x07, 0x40, 0x19, 0x26, 0xb9, 0x49, 0x5c, - 0xc9, 0xe7, 0x83, 0x34, 0x92, 0x30, 0xa3, 0xb3, 0xfd, 0xe4, 0x58, 0x68, 0x34, 0x64, 0x45, 0xf7, - 0x62, 0x1a, 0xc5, 0x37, 0xe3, 0x2b, 0xbd, 0xbd, 0x94, 0x34, 0x5b, 0x11, 0xcd, 0x5b, 0xe9, 0x9b, - 0x30, 0x97, 0x76, 0xdd, 0x9d, 0xcf, 0x6b, 0xd6, 0xb6, 0x3d, 0xad, 0xb4, 0x07, 0xbf, 0x34, 0x1f, - 0xa4, 0x5e, 0x9a, 0xa5, 0x77, 0xf9, 0x98, 0x16, 0x36, 0xba, 0xc7, 0x5a, 0xe0, 0xb8, 0xfd, 0x7d, - 0xd0, 0x8d, 0xaf, 0xc0, 0xf3, 0x7d, 0xc9, 0xc9, 0x5b, 0x5a, 0x14, 0xa3, 0x57, 0x92, 0x51, 0x8c, - 0xbe, 0x73, 0x5c, 0x9c, 0xd1, 0x3c, 0x43, 0x1f, 0x84, 0x0a, 0x7f, 0xe3, 0xa7, 0xb3, 0xba, 0x4f, - 0xf3, 0x5f, 0xc5, 0x85, 0x7a, 0x0d, 0x86, 0xb7, 0xf7, 0xa9, 0x27, 0x8f, 0x07, 0xfc, 0x90, 0x43, - 0x06, 0x50, 0x3f, 0x04, 0x31, 0xc8, 0x1d, 0x98, 0xda, 0xe0, 0x13, 0x57, 0xce, 0xc6, 0xa1, 0x48, - 0xe7, 0xd2, 0x11, 0x9a, 0xc1, 0x94, 0xe9, 0x18, 0xa3, 0x32, 0xee, 0xc6, 0x3a, 0x5d, 0xc4, 0x60, - 0xe2, 0x9e, 0x51, 0x5c, 0x80, 0x98, 0x8a, 0xbc, 0xcd, 0xa2, 0xcd, 0xd6, 0x8c, 0x41, 0x8d, 0x5d, - 0xb8, 0xd4, 0x97, 0x11, 0x3b, 0xb7, 0xa1, 0x13, 0xfe, 0x8a, 0x59, 0x5e, 0xf7, 0x25, 0x35, 0x15, - 0x3a, 0xe3, 0x9b, 0x30, 0xa1, 0xf6, 0x32, 0x1e, 0x41, 0xec, 0xb7, 0x98, 0x15, 0xfc, 0x08, 0x62, - 0x00, 0x93, 0xc3, 0xa3, 0xb7, 0x9c, 0x6c, 0xfa, 0x5b, 0x4e, 0x34, 0xfc, 0xb9, 0xd3, 0x86, 0x9f, - 0x55, 0x8e, 0x3b, 0x9c, 0x52, 0x39, 0xfe, 0x56, 0x2b, 0xc7, 0x20, 0x4b, 0x26, 0x87, 0x3f, 0xd1, - 0xca, 0x7f, 0x57, 0x26, 0x52, 0x43, 0xc7, 0x2b, 0xb9, 0xdc, 0x33, 0x51, 0x36, 0xb4, 0xb4, 0xd5, - 0x1b, 0x61, 0x46, 0x32, 0x45, 0xf6, 0x34, 0x99, 0xe2, 0x2c, 0x13, 0x11, 0xe5, 0x5e, 0x3e, 0xa4, - 0x43, 0x91, 0x1c, 0x68, 0x27, 0xac, 0x5d, 0x24, 0x96, 0xf1, 0x73, 0x19, 0x38, 0x97, 0xaa, 0x33, - 0x67, 0xb5, 0x72, 0xe5, 0xbc, 0xb2, 0x0e, 0xe3, 0x9a, 0x79, 0x8e, 0x71, 0x96, 0x08, 0x1b, 0x83, - 0xb7, 0xc5, 0x78, 0x01, 0xc6, 0xc2, 0x17, 0x5b, 0x32, 0x27, 0x87, 0x0e, 0xed, 0x22, 0xe5, 0xc3, - 0x5f, 0x0d, 0x80, 0x7d, 0xc1, 0x13, 0x35, 0xad, 0x36, 0x7e, 0x37, 0xcb, 0x93, 0xec, 0x3e, 0xb5, - 0xe1, 0x72, 0xd3, 0xed, 0xa1, 0x59, 0x93, 0x7a, 0x07, 0xc9, 0x25, 0xcb, 0x30, 0x52, 0x0b, 0xec, - 0xa0, 0x2b, 0x03, 0x83, 0xcc, 0xaa, 0x64, 0x58, 0xf0, 0x70, 0x31, 0x0a, 0x0d, 0xe1, 0x23, 0x44, - 0xd3, 0x12, 0x20, 0x44, 0x31, 0xab, 0xfe, 0xc3, 0x0c, 0x4c, 0xa8, 0xc4, 0xe4, 0x7d, 0x98, 0x92, - 0x21, 0x40, 0x79, 0xb8, 0x14, 0xf1, 0xbc, 0x2c, 0x4d, 0xc1, 0x64, 0x08, 0x50, 0x35, 0xbc, 0x8a, - 0x86, 0xaf, 0x6e, 0xd5, 0x1d, 0x15, 0x99, 0x34, 0x80, 0xb4, 0x76, 0x6d, 0xeb, 0x90, 0xda, 0x07, - 0xd4, 0x0f, 0x2c, 0x6e, 0xb2, 0x23, 0x5e, 0xa1, 0x25, 0xfb, 0x07, 0x77, 0x4a, 0xdc, 0x5a, 0x87, - 0x8d, 0x84, 0x88, 0xe5, 0x9a, 0xa0, 0x51, 0x9f, 0xd6, 0x5a, 0xbb, 0xf6, 0x36, 0x2f, 0xe4, 0x74, - 0xc6, 0x9f, 0x8d, 0xf0, 0xe9, 0x26, 0x62, 0x06, 0xef, 0xc0, 0xd4, 0x7a, 0xb5, 0x52, 0x56, 0x14, - 0xed, 0x7a, 0xca, 0xa9, 0xe5, 0xc7, 0x01, 0xf5, 0xda, 0x76, 0x53, 0xde, 0x77, 0xa3, 0x23, 0xc8, - 0x75, 0x1a, 0xf5, 0x74, 0x25, 0x7c, 0x8c, 0x23, 0xab, 0x83, 0xdf, 0xac, 0xc3, 0x3a, 0xb2, 0x03, - 0xd6, 0xe1, 0xdb, 0xad, 0x66, 0x8f, 0x3a, 0x74, 0x8e, 0x64, 0x1f, 0xaf, 0xbe, 0xfb, 0xdd, 0x1d, - 0xa5, 0x96, 0x5c, 0xff, 0x5a, 0x5e, 0x14, 0xb5, 0x3c, 0x2b, 0xd4, 0x2a, 0xa9, 0xf5, 0x24, 0xb8, - 0x46, 0xfb, 0xc4, 0xd0, 0xa9, 0xfb, 0xc4, 0xdf, 0xca, 0xc0, 0x08, 0x17, 0x5f, 0xc5, 0x34, 0xee, - 0x21, 0x20, 0x6f, 0x3f, 0x19, 0x01, 0xb9, 0x80, 0xe7, 0x84, 0x36, 0xa1, 0x79, 0x19, 0xa9, 0xc4, - 0xd6, 0x85, 0xf4, 0x06, 0xc0, 0x27, 0x33, 0x5e, 0x72, 0xfa, 0xb2, 0x20, 0xd5, 0x28, 0x58, 0xc7, - 0xe8, 0xa9, 0x1e, 0xda, 0x32, 0xc0, 0xc9, 0xa8, 0x08, 0xd6, 0xa1, 0x87, 0xe8, 0x58, 0x85, 0x31, - 0x11, 0x02, 0x64, 0xe9, 0x48, 0x3c, 0x8c, 0x17, 0x34, 0xd3, 0xa6, 0xc6, 0xd2, 0x51, 0x24, 0x9a, - 0x8b, 0x20, 0x22, 0xd6, 0xce, 0x91, 0x96, 0xb3, 0x58, 0x22, 0x92, 0x75, 0x9e, 0xcb, 0x93, 0xc7, - 0x54, 0xd6, 0xd3, 0x28, 0x84, 0x70, 0x11, 0x5c, 0x4c, 0xc6, 0x11, 0x48, 0x09, 0xa1, 0x1c, 0xf1, - 0x20, 0xab, 0x50, 0x40, 0x73, 0x38, 0xda, 0xe0, 0xab, 0xa6, 0x5a, 0xe1, 0x61, 0x26, 0x84, 0x49, - 0x73, 0xc0, 0xcb, 0xc4, 0x72, 0x8b, 0xf9, 0x5f, 0x26, 0x28, 0x8d, 0x9f, 0xca, 0x42, 0x21, 0x3e, - 0xfb, 0xc8, 0xdb, 0x30, 0x1e, 0xc6, 0xb4, 0x0e, 0x3d, 0xc0, 0xf1, 0x81, 0x2c, 0x0a, 0x82, 0xad, - 0x67, 0x80, 0x54, 0xd0, 0xc9, 0x22, 0xe4, 0xd9, 0x22, 0x8e, 0x67, 0x4b, 0xee, 0x0a, 0x98, 0xea, - 0x91, 0x25, 0xf1, 0x48, 0x0d, 0x66, 0xd9, 0xa2, 0xa9, 0x39, 0xed, 0xbd, 0x26, 0x5d, 0x75, 0xf7, - 0xdc, 0x6e, 0x10, 0x25, 0x44, 0xe4, 0x17, 0x18, 0xbb, 0xd5, 0xd4, 0x8a, 0xf5, 0x74, 0x88, 0x29, - 0xd4, 0x4a, 0x2e, 0xf7, 0xa1, 0x01, 0x72, 0xb9, 0x2b, 0x3b, 0xeb, 0x1f, 0x67, 0x61, 0x5c, 0x99, - 0x7e, 0xe4, 0x1a, 0xe4, 0xab, 0xfe, 0xaa, 0x5b, 0x3f, 0x08, 0x83, 0x55, 0x4e, 0x9e, 0x1c, 0x17, - 0xc7, 0x1c, 0xdf, 0x6a, 0x22, 0xd0, 0x0c, 0x8b, 0xc9, 0x12, 0x4c, 0xf2, 0xbf, 0x64, 0x72, 0x92, - 0x6c, 0xa4, 0x5b, 0xe3, 0xc8, 0x32, 0x2d, 0x89, 0xba, 0xd9, 0x6a, 0x24, 0xe4, 0xab, 0x00, 0x1c, - 0x80, 0xe1, 0x0d, 0x72, 0x83, 0x07, 0x66, 0x10, 0x15, 0xa4, 0x04, 0x36, 0x50, 0x18, 0x92, 0xaf, - 0xf3, 0x90, 0xd9, 0x72, 0xb9, 0x0c, 0x0d, 0x1e, 0x59, 0x82, 0xf1, 0xb7, 0xd2, 0x03, 0xdc, 0xa8, - 0x2c, 0x45, 0x3e, 0xa1, 0x05, 0x93, 0xd6, 0xdd, 0x47, 0xd4, 0x3b, 0x2a, 0x05, 0x88, 0xa8, 0x60, - 0x18, 0xff, 0x4b, 0x46, 0x59, 0x64, 0x64, 0x0d, 0xf3, 0x81, 0xf3, 0x09, 0x24, 0x4c, 0xca, 0xc2, - 0x2b, 0x86, 0x84, 0x9b, 0x74, 0x77, 0xe9, 0x59, 0x61, 0xdd, 0x36, 0x1b, 0x4e, 0xc3, 0x58, 0x9e, - 0x70, 0x0e, 0x24, 0x5f, 0x80, 0x21, 0xec, 0xba, 0xec, 0xa9, 0x4d, 0x93, 0xa7, 0xfc, 0x10, 0xeb, - 0x33, 0x6c, 0x08, 0x52, 0x92, 0x4f, 0x0b, 0xc7, 0x6d, 0xde, 0xf9, 0x53, 0xca, 0x51, 0xcd, 0xbe, - 0x23, 0x3c, 0xde, 0xa3, 0x18, 0x47, 0xca, 0xec, 0xf9, 0x3b, 0x59, 0x28, 0xc4, 0x97, 0x36, 0x79, - 0x0f, 0x26, 0xe4, 0xf1, 0xbb, 0x62, 0x8b, 0xcc, 0x1a, 0x13, 0x22, 0xb3, 0x85, 0x3c, 0x83, 0xf7, - 0x6d, 0xd5, 0x04, 0xcd, 0xd4, 0x08, 0x98, 0x2c, 0xb4, 0x29, 0x62, 0x0e, 0x2a, 0x8b, 0x2a, 0x70, - 0x83, 0x4e, 0x2c, 0x52, 0xb3, 0x44, 0x23, 0x6f, 0x40, 0xee, 0xc1, 0x9d, 0x92, 0x70, 0xf0, 0x2b, - 0xc4, 0x0f, 0x69, 0x6e, 0x29, 0xab, 0xdb, 0xed, 0x32, 0x7c, 0xb2, 0xaa, 0x04, 0x35, 0x1f, 0xd1, - 0xcc, 0x0d, 0x25, 0x38, 0x6c, 0xdc, 0xe9, 0xd1, 0xcd, 0xef, 0x0d, 0xe5, 0x73, 0x85, 0x21, 0x11, - 0xa6, 0xf7, 0x9f, 0xe7, 0x60, 0x2c, 0xac, 0x9f, 0x10, 0xd5, 0x6d, 0x9a, 0xbb, 0x48, 0x93, 0x8b, - 0x90, 0x97, 0xd2, 0x9d, 0xf0, 0xf3, 0x1b, 0xf5, 0x85, 0x64, 0x37, 0x0f, 0x52, 0x8c, 0xe3, 0xbb, - 0x82, 0x29, 0x7f, 0x92, 0x9b, 0x10, 0xca, 0x68, 0xbd, 0x84, 0xb9, 0x21, 0x36, 0x60, 0x66, 0x88, - 0x46, 0xa6, 0x20, 0xeb, 0xf0, 0xd0, 0x6f, 0x63, 0x66, 0xd6, 0x69, 0x90, 0xf7, 0x20, 0x6f, 0x37, - 0x1a, 0xb4, 0x61, 0xd9, 0xd2, 0x36, 0xab, 0xdf, 0xa4, 0xc9, 0x33, 0x6e, 0xfc, 0xcc, 0x40, 0xaa, - 0x52, 0x40, 0x4a, 0x30, 0xd6, 0xb4, 0xb9, 0xb5, 0x67, 0x63, 0x80, 0x03, 0x28, 0xe2, 0x90, 0x67, - 0x64, 0x5b, 0x3e, 0x6d, 0x90, 0x57, 0x60, 0x88, 0x8d, 0xa6, 0x38, 0x71, 0xa4, 0x50, 0xc9, 0x06, - 0x93, 0x77, 0xd8, 0xca, 0x33, 0x26, 0x22, 0x90, 0x97, 0x20, 0xd7, 0x5d, 0xdc, 0x15, 0x67, 0x49, - 0x21, 0x4a, 0x30, 0x10, 0xa2, 0xb1, 0x62, 0x72, 0x0b, 0xf2, 0x87, 0x7a, 0x6c, 0xfa, 0x73, 0xb1, - 0x61, 0x0c, 0xf1, 0x43, 0x44, 0xf2, 0x0a, 0xe4, 0x7c, 0xdf, 0x15, 0x06, 0x4d, 0xb3, 0xa1, 0x95, - 0xe9, 0x7a, 0x38, 0x6a, 0x8c, 0xbb, 0xef, 0xbb, 0x4b, 0x79, 0x18, 0xe1, 0x07, 0x8c, 0x71, 0x09, - 0x20, 0xfa, 0xc6, 0xa4, 0xdf, 0xa6, 0xf1, 0x55, 0x18, 0x0b, 0xbf, 0x8d, 0x3c, 0x0f, 0x70, 0x40, - 0x8f, 0xac, 0x7d, 0xbb, 0xdd, 0x68, 0x72, 0xe9, 0x74, 0xc2, 0x1c, 0x3b, 0xa0, 0x47, 0x2b, 0x08, - 0x20, 0x17, 0x60, 0xb4, 0xc3, 0x86, 0x5f, 0xcc, 0xf1, 0x09, 0x73, 0xa4, 0xd3, 0xdd, 0x61, 0x53, - 0x79, 0x1e, 0x46, 0x51, 0xcf, 0x2a, 0x56, 0xe4, 0xa4, 0x29, 0x7f, 0x1a, 0x7f, 0x9e, 0xc3, 0x14, - 0x4e, 0x4a, 0x83, 0xc8, 0x8b, 0x30, 0x59, 0xf7, 0x28, 0x9e, 0x65, 0x36, 0x93, 0xd0, 0x44, 0x3d, - 0x13, 0x11, 0xb0, 0xda, 0x20, 0x57, 0x60, 0xba, 0xd3, 0xdd, 0x69, 0x3a, 0x75, 0x56, 0x9b, 0x55, - 0xdf, 0x11, 0x39, 0x27, 0x26, 0xcc, 0x49, 0x0e, 0xbe, 0x4f, 0x8f, 0xca, 0x3b, 0x18, 0xdb, 0xb0, - 0xa0, 0x86, 0xa6, 0x0e, 0xc2, 0xe4, 0xfa, 0xe6, 0xb4, 0x02, 0x47, 0xdb, 0xcc, 0xf3, 0x30, 0x62, - 0xdb, 0x7b, 0x5d, 0x87, 0xc7, 0x20, 0x9b, 0x30, 0xc5, 0x2f, 0xf2, 0x29, 0x98, 0x89, 0xa2, 0xa5, - 0xcb, 0x66, 0x0c, 0x63, 0x33, 0x0a, 0x61, 0x41, 0x99, 0xc3, 0xc9, 0xeb, 0x40, 0xd4, 0xfa, 0xdc, - 0x9d, 0x0f, 0x68, 0x9d, 0xcf, 0xc9, 0x09, 0x73, 0x46, 0x29, 0x59, 0xc7, 0x02, 0xf2, 0x02, 0x4c, - 0x78, 0xd4, 0x47, 0xe9, 0x10, 0xbb, 0x0d, 0x33, 0x1c, 0x9a, 0xe3, 0x12, 0xc6, 0xfa, 0xee, 0x2a, - 0x14, 0x94, 0xee, 0xc0, 0xe8, 0xdf, 0x3c, 0xdd, 0x82, 0x39, 0x15, 0xc1, 0xcd, 0x4e, 0xb5, 0x41, - 0xbe, 0x04, 0x0b, 0x0a, 0x26, 0x4f, 0xb6, 0x68, 0xd1, 0xa6, 0xb3, 0xe7, 0xec, 0x34, 0xa9, 0x98, - 0x6f, 0xc9, 0x59, 0x1d, 0x5e, 0x21, 0xcd, 0xf9, 0x88, 0x9a, 0xa7, 0x61, 0x5c, 0x16, 0xb4, 0x64, - 0x15, 0xe6, 0x62, 0x9c, 0x69, 0xc3, 0xea, 0x76, 0x7a, 0x06, 0xfd, 0x8b, 0x78, 0x12, 0x9d, 0x27, - 0x6d, 0x6c, 0x75, 0x8c, 0x6f, 0xc2, 0x84, 0x3a, 0x27, 0x59, 0x27, 0xa8, 0x72, 0x89, 0x98, 0x7d, - 0xe3, 0x21, 0xac, 0xca, 0xee, 0x85, 0x53, 0x11, 0x0a, 0x0e, 0x22, 0xdf, 0x5e, 0x26, 0x43, 0x28, - 0x0e, 0xe1, 0x0b, 0x30, 0xd1, 0x70, 0xfc, 0x4e, 0xd3, 0x3e, 0xb2, 0xa2, 0x2c, 0xe2, 0xe6, 0xb8, - 0x80, 0xa1, 0xe2, 0x67, 0x09, 0x66, 0x12, 0xfb, 0xa0, 0x22, 0x69, 0xf0, 0x7d, 0xbd, 0xbf, 0xa4, - 0x61, 0xb4, 0x61, 0x42, 0x3d, 0xd7, 0x4e, 0x49, 0x8e, 0x72, 0x1e, 0xc3, 0xf0, 0xf0, 0x4d, 0x7f, - 0xe4, 0xe4, 0xb8, 0x98, 0x75, 0x1a, 0x18, 0x7c, 0xe7, 0x2a, 0xe4, 0xa5, 0xc4, 0x26, 0x04, 0x25, - 0x7c, 0x4c, 0x90, 0x4f, 0x93, 0x66, 0x58, 0x6a, 0xbc, 0x02, 0xa3, 0xe2, 0xe8, 0xea, 0xff, 0x84, - 0x60, 0x7c, 0x2b, 0x0b, 0xd3, 0x26, 0x65, 0x1b, 0x2b, 0xe5, 0x19, 0x91, 0x9e, 0xda, 0x2b, 0x7a, - 0x7a, 0xb8, 0x58, 0xad, 0x6d, 0x7d, 0x72, 0x11, 0xfd, 0x4a, 0x06, 0x66, 0x53, 0x70, 0x3f, 0x54, - 0x2e, 0xde, 0xdb, 0x30, 0x56, 0x71, 0xec, 0x66, 0xa9, 0xd1, 0x08, 0x63, 0xf2, 0xa0, 0x9c, 0x8f, - 0x09, 0xbb, 0x6c, 0x06, 0x55, 0x85, 0x98, 0x10, 0x95, 0xbc, 0x2a, 0x26, 0x45, 0x94, 0xc9, 0x1e, - 0x27, 0xc5, 0x77, 0x8e, 0x8b, 0xc0, 0xbf, 0x69, 0x33, 0x9c, 0x22, 0x18, 0xc2, 0x99, 0x03, 0x23, - 0xbf, 0xaa, 0xa7, 0x76, 0xe8, 0xd2, 0x43, 0x38, 0xc7, 0x9b, 0x37, 0x50, 0x3a, 0xa2, 0x1f, 0xcb, - 0xc2, 0xf9, 0x74, 0xc2, 0x0f, 0x9b, 0x56, 0x19, 0x13, 0x41, 0x29, 0x61, 0xe7, 0x31, 0xad, 0x32, - 0xcf, 0x1a, 0x85, 0xf8, 0x11, 0x02, 0xd9, 0x85, 0xc9, 0x55, 0xdb, 0x0f, 0x56, 0xa8, 0xed, 0x05, - 0x3b, 0xd4, 0x0e, 0x06, 0x90, 0xe4, 0xa5, 0x35, 0xc5, 0x3c, 0x0a, 0x13, 0xfb, 0x92, 0x32, 0x26, - 0x6b, 0xeb, 0x6c, 0xc3, 0x89, 0x32, 0x34, 0xc0, 0x44, 0xf9, 0x06, 0x4c, 0xd7, 0x68, 0xcb, 0xee, - 0xec, 0xbb, 0x9e, 0x8c, 0x97, 0x70, 0x1d, 0x26, 0x43, 0x50, 0xea, 0x6c, 0xd1, 0x8b, 0x35, 0x7c, - 0xa5, 0x23, 0xa2, 0xad, 0x44, 0x2f, 0x36, 0xfe, 0x6e, 0x16, 0x2e, 0x94, 0xea, 0xc2, 0x34, 0x54, - 0x14, 0x48, 0x0b, 0xf6, 0x8f, 0xb9, 0x6e, 0x72, 0x03, 0xc6, 0x1e, 0xd8, 0x8f, 0x57, 0xa9, 0xed, - 0x53, 0x5f, 0x24, 0xb5, 0xe4, 0x62, 0xaf, 0xfd, 0x38, 0x7a, 0xfc, 0x31, 0x23, 0x1c, 0x55, 0x8d, - 0x30, 0xf4, 0x11, 0xd5, 0x08, 0x06, 0x8c, 0xac, 0xb8, 0xcd, 0x86, 0x38, 0xeb, 0xc5, 0x8b, 0xf3, - 0x3e, 0x42, 0x4c, 0x51, 0x62, 0xfc, 0x69, 0x06, 0xa6, 0xc2, 0x2f, 0xc6, 0x4f, 0xf8, 0xd8, 0xbb, - 0xe4, 0x0a, 0x8c, 0x62, 0x45, 0x61, 0xf6, 0x7d, 0x3c, 0x34, 0x9a, 0x14, 0x53, 0x13, 0x36, 0x4c, - 0x59, 0xa8, 0xf6, 0xc4, 0xf0, 0x47, 0xeb, 0x09, 0xe3, 0x1f, 0xe1, 0x63, 0xb6, 0xda, 0x4a, 0x76, - 0x12, 0x29, 0x1f, 0x92, 0x19, 0xf0, 0x43, 0xb2, 0x4f, 0x6c, 0x48, 0x72, 0x3d, 0x87, 0xe4, 0x87, - 0xb2, 0x30, 0x1e, 0x7e, 0xec, 0x27, 0x2c, 0xf7, 0x41, 0xd8, 0xae, 0x81, 0x62, 0x1c, 0xd5, 0x94, - 0xbd, 0x42, 0x84, 0x12, 0xfa, 0x02, 0x8c, 0x88, 0xc5, 0x94, 0x89, 0x59, 0x72, 0xc7, 0x46, 0x77, - 0x69, 0x4a, 0xb0, 0x1e, 0xc1, 0x01, 0xf5, 0x4d, 0x41, 0x87, 0x41, 0xa4, 0xb6, 0xe9, 0x8e, 0xb0, - 0x6d, 0x78, 0x6a, 0xcf, 0xa8, 0xf4, 0x20, 0x52, 0x51, 0xc3, 0x06, 0x3a, 0x9d, 0xfe, 0x59, 0x1e, - 0x0a, 0x71, 0x92, 0xd3, 0xb3, 0x4b, 0x6c, 0x74, 0x77, 0xf8, 0x55, 0x85, 0x67, 0x97, 0xe8, 0x74, - 0x77, 0x4c, 0x06, 0x43, 0xd3, 0x27, 0xcf, 0x79, 0x84, 0xad, 0x9e, 0x10, 0xa6, 0x4f, 0x9e, 0xf3, - 0x48, 0x33, 0x7d, 0xf2, 0x9c, 0x47, 0xa8, 0x48, 0x58, 0xad, 0x61, 0x80, 0x05, 0xbc, 0xa7, 0x08, - 0x45, 0x42, 0xd3, 0x8f, 0x67, 0x8a, 0x93, 0x68, 0xec, 0xa8, 0x5c, 0xa2, 0xb6, 0x27, 0x32, 0x21, - 0x88, 0xed, 0x0c, 0x8f, 0xca, 0x1d, 0x04, 0x5b, 0x01, 0x83, 0x9b, 0x2a, 0x12, 0x69, 0x02, 0x51, - 0x7e, 0xca, 0x05, 0x7c, 0xfa, 0xdd, 0x5a, 0x5a, 0x61, 0xce, 0xa9, 0xac, 0x2d, 0x75, 0x35, 0xa7, - 0xf0, 0x7d, 0x92, 0xda, 0xdf, 0x0d, 0x11, 0xde, 0x15, 0x15, 0x48, 0xf9, 0x53, 0x99, 0xc9, 0xc0, - 0x30, 0xc0, 0xc3, 0xbf, 0x86, 0x6a, 0xa4, 0x88, 0x09, 0x79, 0x17, 0xc6, 0xd5, 0xb0, 0x19, 0x3c, - 0xb8, 0xc3, 0x73, 0x3c, 0x9e, 0x66, 0x8f, 0xec, 0xc2, 0x2a, 0x01, 0xd9, 0x81, 0x0b, 0x65, 0xb7, - 0xed, 0x77, 0x5b, 0x32, 0x72, 0x67, 0x14, 0x91, 0x1c, 0x70, 0x28, 0xd0, 0x07, 0xbf, 0x2e, 0x50, - 0x44, 0x94, 0x06, 0xe9, 0x26, 0xa3, 0x5f, 0x40, 0x7a, 0x31, 0x22, 0x9b, 0x30, 0x8e, 0x1a, 0x54, - 0x61, 0xf2, 0x38, 0xae, 0x6f, 0x1b, 0x51, 0x49, 0x85, 0x2d, 0x0c, 0x1e, 0x35, 0xce, 0x6e, 0x35, - 0xa5, 0x97, 0x86, 0xaa, 0x09, 0x56, 0x90, 0xc9, 0x57, 0x61, 0x8a, 0x5f, 0xd1, 0xb6, 0xe9, 0x0e, - 0x9f, 0x3b, 0x13, 0x9a, 0x26, 0x42, 0x2f, 0xe4, 0x8f, 0xf9, 0x42, 0x6f, 0x7d, 0x48, 0x77, 0xf8, - 0xd8, 0x6b, 0x3e, 0x52, 0x1a, 0x3e, 0xd9, 0x82, 0xd9, 0x15, 0xdb, 0xe7, 0x40, 0x25, 0xfe, 0xc1, - 0x24, 0x6a, 0x68, 0xd1, 0x76, 0x7d, 0xdf, 0xf6, 0xa5, 0x22, 0x3c, 0x35, 0xde, 0x41, 0x1a, 0x3d, - 0xf9, 0x56, 0x06, 0xe6, 0x35, 0x3d, 0xb9, 0xb0, 0x33, 0x6b, 0xd1, 0x76, 0x80, 0xce, 0x50, 0x53, - 0x8b, 0x45, 0x29, 0x94, 0xf6, 0x40, 0xe3, 0x43, 0x12, 0x53, 0xc5, 0x7b, 0x51, 0xb9, 0x6a, 0x14, - 0xde, 0x8b, 0x87, 0x58, 0xa8, 0xb8, 0xa6, 0xa7, 0xf5, 0x85, 0x1a, 0x5b, 0xd7, 0x12, 0xcd, 0xb8, - 0x1d, 0xef, 0x6f, 0xa1, 0xe8, 0xca, 0x84, 0x8a, 0xae, 0x39, 0x18, 0xc6, 0x5e, 0x95, 0x51, 0xb4, - 0xf0, 0x87, 0xf1, 0x69, 0x75, 0x1f, 0x12, 0x62, 0x61, 0xdf, 0x7d, 0xc8, 0xf8, 0x1f, 0x47, 0x60, - 0x3a, 0x36, 0x2d, 0xc4, 0x3d, 0x35, 0x93, 0xb8, 0xa7, 0xd6, 0x00, 0xb8, 0xaa, 0x77, 0x40, 0x9d, - 0xac, 0x74, 0xc4, 0x1c, 0x17, 0x6e, 0xd4, 0xe1, 0x9a, 0x52, 0xd8, 0x30, 0xa6, 0x7c, 0xc5, 0x0e, - 0xa8, 0x23, 0x0f, 0x99, 0xf2, 0x45, 0xaf, 0x30, 0x8d, 0xd8, 0x90, 0x22, 0x0c, 0x63, 0xfc, 0x5c, - 0xd5, 0x0f, 0xd6, 0x61, 0x00, 0x93, 0xc3, 0xc9, 0x8b, 0x30, 0xc2, 0x84, 0xa8, 0x6a, 0x45, 0x6c, - 0x82, 0x78, 0xb6, 0x30, 0x29, 0x8b, 0x49, 0x2c, 0xa2, 0x88, 0xdc, 0x86, 0x09, 0xfe, 0x97, 0x08, - 0xb3, 0x33, 0xa2, 0x1b, 0x3f, 0x5a, 0x4e, 0x43, 0x46, 0xda, 0xd1, 0xf0, 0xd8, 0xed, 0xa2, 0xd6, - 0x45, 0xb5, 0x4e, 0xb5, 0x22, 0x42, 0xba, 0xe3, 0xed, 0xc2, 0xe7, 0x40, 0x56, 0x45, 0x84, 0xc0, - 0x64, 0x19, 0xe1, 0x8d, 0x92, 0xc7, 0x3b, 0x25, 0xca, 0x32, 0xdc, 0x0b, 0xc5, 0x14, 0x25, 0xe4, - 0x1a, 0x7f, 0x89, 0x41, 0xb1, 0x90, 0x67, 0xc6, 0xc4, 0x77, 0x0b, 0x54, 0x4c, 0xa0, 0x6c, 0x18, - 0x16, 0xb3, 0xca, 0xd9, 0xdf, 0xcb, 0x2d, 0xdb, 0x69, 0x8a, 0x6d, 0x05, 0x2b, 0x47, 0x5c, 0xca, - 0xa0, 0x66, 0x84, 0x40, 0xde, 0x86, 0x29, 0xf6, 0xa3, 0xec, 0xb6, 0x5a, 0x6e, 0x1b, 0xd9, 0x8f, - 0x47, 0x81, 0xf4, 0x90, 0xa4, 0x8e, 0x45, 0xbc, 0x96, 0x18, 0x2e, 0x3b, 0x4f, 0xf0, 0x95, 0xb7, - 0xcb, 0xdf, 0x88, 0x26, 0xa2, 0xf3, 0x04, 0x49, 0x7d, 0x0e, 0x37, 0x55, 0x24, 0xf2, 0x26, 0x4c, - 0xb2, 0x9f, 0x77, 0x9d, 0x47, 0x94, 0x57, 0x38, 0x19, 0x99, 0x37, 0x20, 0xd5, 0x1e, 0x2b, 0xe1, - 0xf5, 0xe9, 0x98, 0xe4, 0x8b, 0x70, 0x0e, 0x39, 0xd5, 0xdd, 0x0e, 0x6d, 0x94, 0x76, 0x77, 0x9d, - 0xa6, 0xc3, 0xad, 0xd1, 0x78, 0x40, 0x19, 0xd4, 0xc1, 0xf3, 0x8a, 0x11, 0xc3, 0xb2, 0x23, 0x14, - 0x33, 0x9d, 0x92, 0x6c, 0x43, 0xa1, 0xdc, 0xf5, 0x03, 0xb7, 0x55, 0x0a, 0x02, 0xcf, 0xd9, 0xe9, - 0x06, 0xd4, 0x9f, 0x9f, 0xd6, 0xc2, 0xae, 0xb0, 0xc5, 0x11, 0x16, 0x72, 0x7d, 0x50, 0x1d, 0x29, - 0x2c, 0x3b, 0x24, 0x31, 0x13, 0x4c, 0x8c, 0x7f, 0x91, 0x81, 0x49, 0x8d, 0x94, 0xbc, 0x01, 0x13, - 0x77, 0x3c, 0x87, 0xb6, 0x1b, 0xcd, 0x23, 0xe5, 0xa2, 0x8a, 0xb7, 0x98, 0x5d, 0x01, 0xe7, 0xad, - 0xd6, 0xd0, 0x42, 0x3d, 0x4f, 0x36, 0xd5, 0x54, 0xf4, 0x06, 0x77, 0xc7, 0x16, 0x13, 0x34, 0x17, - 0xc5, 0x81, 0xc2, 0x09, 0x2a, 0x66, 0xa7, 0x82, 0x42, 0xde, 0x81, 0x11, 0xfe, 0x1e, 0x2c, 0xec, - 0x16, 0x2f, 0xa6, 0x35, 0x93, 0xbb, 0xfe, 0xe3, 0x44, 0x44, 0xa3, 0x1f, 0xdf, 0x14, 0x44, 0xc6, - 0xcf, 0x64, 0x80, 0x24, 0x51, 0x4f, 0xd1, 0x7b, 0x9d, 0x6a, 0x4c, 0xf4, 0x85, 0x70, 0x35, 0xe6, - 0x34, 0x9d, 0x39, 0xab, 0x89, 0x17, 0xf0, 0x8e, 0x17, 0xab, 0x4e, 0x55, 0xc4, 0xf1, 0x62, 0xe3, - 0x07, 0xb3, 0x00, 0x11, 0x36, 0xf9, 0x1c, 0x4f, 0x84, 0xf6, 0xc5, 0xae, 0xdd, 0x74, 0x76, 0x1d, - 0x3d, 0x6e, 0x2f, 0x32, 0xf9, 0x86, 0x2c, 0x31, 0x75, 0x44, 0xf2, 0x1e, 0x4c, 0xd7, 0x36, 0x74, - 0x5a, 0xc5, 0x2c, 0xde, 0xef, 0x58, 0x31, 0xf2, 0x38, 0x36, 0xda, 0x27, 0xab, 0xa3, 0xc1, 0xed, - 0x93, 0xf9, 0x40, 0x88, 0x12, 0xb6, 0xb1, 0xd4, 0x36, 0x84, 0xe5, 0x7f, 0x23, 0x7c, 0xd5, 0xc4, - 0xaf, 0xf3, 0x3b, 0x56, 0x47, 0xb8, 0x04, 0xb0, 0x7d, 0x42, 0xc3, 0x8b, 0x3a, 0x72, 0xb8, 0x87, - 0x7b, 0xff, 0xcf, 0xa2, 0xda, 0xaf, 0xe5, 0x06, 0x54, 0x68, 0x3b, 0x9e, 0xda, 0x7b, 0x4f, 0x64, - 0x4c, 0x30, 0xac, 0x79, 0x2d, 0x6b, 0xad, 0x13, 0x06, 0x33, 0xb7, 0xa2, 0x4b, 0x0a, 0x37, 0x2b, - 0x48, 0xb1, 0xb1, 0xf9, 0x07, 0x19, 0x38, 0x97, 0x4a, 0x4b, 0xae, 0x03, 0x44, 0x3a, 0x25, 0xd1, - 0x4b, 0xb8, 0x63, 0x46, 0xd1, 0x8f, 0x4c, 0x05, 0x83, 0x7c, 0x25, 0xae, 0x0d, 0x3a, 0xfd, 0x20, - 0x5c, 0x90, 0x41, 0x07, 0x75, 0x6d, 0x50, 0x8a, 0x0e, 0xc8, 0xf8, 0x95, 0x1c, 0xcc, 0x28, 0xc1, - 0x95, 0xf8, 0xb7, 0x9e, 0x62, 0x2f, 0x7e, 0x00, 0x13, 0xac, 0x35, 0x4e, 0x5d, 0xb8, 0xdd, 0x70, - 0xc3, 0x97, 0x57, 0x13, 0x7e, 0xa7, 0x82, 0xdb, 0x75, 0x15, 0x99, 0x87, 0x02, 0xc5, 0xad, 0x13, - 0x1f, 0x24, 0xea, 0x49, 0x97, 0x1b, 0x8d, 0x39, 0xf1, 0x61, 0xb2, 0x72, 0xd4, 0xb6, 0x5b, 0x61, - 0x6d, 0xdc, 0x00, 0xe6, 0x53, 0x3d, 0x6b, 0xd3, 0xb0, 0x79, 0x75, 0x91, 0x87, 0x16, 0x2f, 0x4b, - 0x09, 0x0e, 0xa0, 0x51, 0x2d, 0xbc, 0x07, 0x33, 0x89, 0x8f, 0x3e, 0x53, 0x54, 0xd2, 0x6d, 0x20, - 0xc9, 0xef, 0x48, 0xe1, 0xf0, 0x29, 0x3d, 0xe6, 0xed, 0xb9, 0xf0, 0xf1, 0xba, 0xd5, 0xb2, 0xdb, - 0x0d, 0x6e, 0x4e, 0xb3, 0xa8, 0xc6, 0x2c, 0xfd, 0xd9, 0xac, 0xea, 0xfb, 0xfb, 0xb4, 0xaf, 0xba, - 0x2f, 0x68, 0xb7, 0xe1, 0x4b, 0xbd, 0xc6, 0x74, 0x20, 0xad, 0xc3, 0xb7, 0x73, 0x70, 0xa1, 0x07, - 0x25, 0x39, 0x8a, 0x4f, 0x22, 0xae, 0x85, 0xb8, 0xd9, 0xbf, 0xc2, 0x27, 0x31, 0x95, 0xc8, 0xe7, - 0x78, 0xf4, 0x8f, 0xba, 0xdb, 0xde, 0x75, 0xf6, 0xc4, 0xfd, 0x1b, 0xd5, 0xf8, 0x07, 0x21, 0x34, - 0x1e, 0xf6, 0x83, 0x43, 0xc9, 0x7b, 0x30, 0x8c, 0x8e, 0xdf, 0xb1, 0xf0, 0x8e, 0x0c, 0x03, 0xe1, - 0x4a, 0x80, 0x52, 0xf6, 0x53, 0x0b, 0x50, 0xca, 0x00, 0xe4, 0xb3, 0x90, 0x2b, 0x6d, 0xd7, 0xc4, - 0xb8, 0x4c, 0xa9, 0xe4, 0xdb, 0xb5, 0x28, 0x7d, 0x8b, 0xad, 0xe5, 0x59, 0x61, 0x14, 0x8c, 0xf0, - 0x6e, 0x79, 0x43, 0x8c, 0x8a, 0x4a, 0x78, 0xb7, 0xbc, 0x11, 0x11, 0xee, 0xd5, 0xb5, 0x60, 0x59, - 0x77, 0xcb, 0x1b, 0x1f, 0xdf, 0xb4, 0xff, 0xf7, 0xb2, 0x3c, 0x64, 0x09, 0x6f, 0xd8, 0x7b, 0x30, - 0xa1, 0xc5, 0x24, 0xcf, 0x44, 0xf2, 0x58, 0x18, 0x3f, 0x3e, 0x66, 0x31, 0xa4, 0x11, 0xc8, 0x44, - 0x48, 0xec, 0x37, 0x4a, 0xbc, 0xaa, 0xb1, 0x4d, 0xc8, 0x01, 0x65, 0xe2, 0x78, 0x22, 0xa4, 0x90, - 0x84, 0xdc, 0x82, 0xfc, 0x26, 0x6d, 0xdb, 0xed, 0x20, 0x54, 0x88, 0xa2, 0x71, 0x71, 0x80, 0x30, - 0x5d, 0x6a, 0x08, 0x11, 0xd1, 0x10, 0xb6, 0xbb, 0xe3, 0xd7, 0x3d, 0x07, 0x43, 0x1b, 0x85, 0x67, - 0x31, 0x37, 0x84, 0x55, 0x4a, 0x74, 0x06, 0x31, 0x22, 0xe3, 0x67, 0x33, 0x30, 0x2a, 0x06, 0x92, - 0x27, 0xb0, 0xdb, 0x8b, 0xce, 0x12, 0xe1, 0x3c, 0xb0, 0xe7, 0xc4, 0x9d, 0x07, 0xf6, 0x78, 0xfc, - 0xa0, 0x31, 0xe1, 0x58, 0x17, 0x3e, 0x0d, 0xe2, 0x6c, 0x94, 0x6e, 0x9f, 0x7a, 0x7e, 0xb2, 0x10, - 0x75, 0x50, 0x87, 0x2c, 0xe3, 0xef, 0x89, 0x2f, 0xbb, 0x5b, 0xde, 0x20, 0x8b, 0x90, 0x5f, 0x75, - 0x79, 0x28, 0x2c, 0x35, 0x1b, 0x71, 0x53, 0xc0, 0xd4, 0x0e, 0x92, 0x78, 0xec, 0xfb, 0x36, 0x3c, - 0x57, 0xdc, 0x65, 0x94, 0xef, 0xeb, 0x70, 0x60, 0xec, 0xfb, 0x42, 0xd4, 0x81, 0xbf, 0x8f, 0xa6, - 0x6c, 0x12, 0x0f, 0x6f, 0x61, 0x86, 0x98, 0x7b, 0xaa, 0xa3, 0x9b, 0x28, 0x92, 0x3b, 0xc5, 0x42, - 0xaf, 0x9d, 0xe2, 0xe1, 0x2d, 0x33, 0x85, 0x0a, 0xdf, 0xd5, 0x22, 0x70, 0x8d, 0x7a, 0x8f, 0x9e, - 0xe2, 0x5d, 0x3a, 0xfd, 0x5d, 0x2d, 0xde, 0xbc, 0x81, 0x36, 0xe9, 0x3f, 0xcc, 0xc2, 0xf9, 0x74, - 0x42, 0xb5, 0x2d, 0x99, 0x3e, 0x6d, 0xb9, 0x0a, 0xf9, 0x15, 0xd7, 0x0f, 0x14, 0x23, 0x41, 0x54, - 0xff, 0xef, 0x0b, 0x98, 0x19, 0x96, 0xb2, 0x3b, 0x37, 0xfb, 0x3b, 0x5c, 0x9e, 0xc8, 0x0f, 0x03, - 0x75, 0xb0, 0x3b, 0x37, 0x2f, 0x22, 0x77, 0x21, 0x6f, 0x0a, 0x47, 0xab, 0x58, 0xd7, 0x48, 0x70, - 0x28, 0x4d, 0x11, 0x4f, 0x40, 0xb4, 0xd0, 0xf0, 0x02, 0x46, 0x4a, 0x30, 0x2a, 0x46, 0x3f, 0xf6, - 0x74, 0x9c, 0x32, 0x65, 0xf4, 0x6c, 0x0d, 0x92, 0x8e, 0xed, 0x28, 0xf8, 0x08, 0x58, 0xad, 0x48, - 0x9f, 0x29, 0xdc, 0x51, 0xf8, 0x23, 0xa1, 0x6e, 0x8f, 0x19, 0x22, 0x1a, 0xdf, 0xca, 0x02, 0x48, - 0xad, 0xcd, 0x53, 0x3b, 0xc3, 0x3e, 0xab, 0xcd, 0x30, 0xc5, 0xde, 0x68, 0xf0, 0x84, 0xcb, 0xeb, - 0x68, 0xce, 0x33, 0x78, 0xba, 0xe5, 0x22, 0x0c, 0x6f, 0x46, 0x0a, 0x2d, 0xe1, 0x92, 0x82, 0xea, - 0x68, 0x0e, 0x37, 0x76, 0x60, 0xee, 0x2e, 0x0d, 0x22, 0xf5, 0x96, 0x7c, 0x7a, 0xec, 0xcf, 0xf6, - 0x35, 0x18, 0x13, 0xf8, 0xe1, 0xfe, 0xc5, 0x75, 0x31, 0x22, 0xf6, 0x0d, 0xea, 0x62, 0x24, 0x02, - 0xdb, 0x8d, 0x2a, 0xb4, 0x49, 0x03, 0xfa, 0xf1, 0x56, 0x53, 0x03, 0xc2, 0x9b, 0x82, 0x2d, 0x1b, - 0xac, 0x86, 0x53, 0xfb, 0xe7, 0x21, 0x9c, 0x0b, 0xbf, 0xfd, 0x49, 0xf2, 0xbd, 0xc1, 0xae, 0x94, - 0x22, 0xd1, 0x41, 0xc4, 0xb1, 0x8f, 0xed, 0xc9, 0x63, 0x58, 0x90, 0x04, 0xdb, 0x4e, 0x68, 0x38, - 0x39, 0x10, 0x2d, 0x79, 0x1b, 0xc6, 0x15, 0x1a, 0x11, 0xa8, 0x1f, 0xd5, 0xd4, 0x87, 0x4e, 0xb0, - 0x6f, 0xf9, 0x1c, 0xae, 0xaa, 0xa9, 0x15, 0x74, 0xe3, 0xcb, 0xf0, 0x6c, 0xe8, 0x36, 0x94, 0x52, - 0x75, 0x8c, 0x79, 0xe6, 0x6c, 0xcc, 0xd7, 0xa2, 0x66, 0x55, 0xdb, 0xa1, 0x67, 0xb4, 0xe4, 0x4d, - 0xd4, 0x66, 0x89, 0xc6, 0x3c, 0x97, 0xf0, 0xb5, 0x56, 0x5c, 0xaa, 0x8d, 0xb7, 0x94, 0x8f, 0x4d, - 0x61, 0xa8, 0x11, 0x67, 0xe2, 0xc4, 0xdf, 0xca, 0xc2, 0xf4, 0x7a, 0xb5, 0x52, 0x0e, 0xad, 0x8f, - 0x3e, 0x61, 0xe9, 0xa0, 0xb5, 0xb6, 0xf5, 0xde, 0x6f, 0x8c, 0x2d, 0x98, 0x8d, 0x75, 0x03, 0x8a, - 0x0e, 0xef, 0x72, 0x87, 0x93, 0x10, 0x2c, 0xc5, 0x86, 0xf3, 0x69, 0xec, 0x1f, 0xde, 0x32, 0x63, - 0xd8, 0xc6, 0x7f, 0x09, 0x31, 0xbe, 0x62, 0x0b, 0x7b, 0x0d, 0xc6, 0xaa, 0xbe, 0xdf, 0xa5, 0xde, - 0x96, 0xb9, 0xaa, 0xaa, 0x0a, 0x1c, 0x04, 0x5a, 0x5d, 0xaf, 0x69, 0x46, 0x08, 0xe4, 0x1a, 0xe4, - 0x45, 0x90, 0x74, 0xb9, 0x27, 0xa0, 0xd6, 0x36, 0x8c, 0xb1, 0x6e, 0x86, 0xc5, 0xe4, 0x0d, 0x98, - 0xe0, 0x7f, 0xf3, 0xd9, 0x26, 0x3a, 0x1c, 0x95, 0x83, 0x02, 0x9d, 0xcf, 0x4e, 0x53, 0x43, 0x23, - 0xaf, 0x42, 0xae, 0x54, 0x36, 0x85, 0x3a, 0x48, 0xc8, 0x8d, 0x9e, 0xc5, 0x75, 0x76, 0xda, 0x25, - 0xa2, 0x6c, 0x32, 0xe9, 0x4f, 0x06, 0x9b, 0x10, 0x9a, 0x6c, 0x9c, 0x01, 0x52, 0xdb, 0x14, 0x3b, - 0xcc, 0x10, 0x46, 0x6e, 0xc0, 0x68, 0x85, 0x9b, 0xcc, 0x09, 0x3d, 0x36, 0xcf, 0x75, 0xc8, 0x41, - 0x5a, 0x70, 0x05, 0x0e, 0x22, 0xd7, 0x64, 0x86, 0xb6, 0x7c, 0xe4, 0xb7, 0xd2, 0x23, 0x0d, 0xdb, - 0x6b, 0x30, 0x22, 0x42, 0x89, 0x8f, 0x29, 0xb9, 0x5b, 0xe2, 0x21, 0xc4, 0x05, 0x4e, 0xd2, 0x81, - 0x15, 0x9e, 0xa4, 0x03, 0xeb, 0x0e, 0x5c, 0xb8, 0x8b, 0xda, 0x1b, 0x3d, 0x20, 0xd6, 0x96, 0x59, - 0x15, 0xfa, 0x70, 0x7c, 0x06, 0xe2, 0x0a, 0x9e, 0x78, 0x4c, 0x2d, 0xab, 0xeb, 0xa9, 0xa9, 0x7b, - 0x7b, 0x31, 0x22, 0x5f, 0x82, 0xb9, 0xb4, 0x22, 0xa1, 0x35, 0xc7, 0xd0, 0x4f, 0xe9, 0x15, 0xa8, - 0xa1, 0x9f, 0xd2, 0x38, 0x90, 0x55, 0x28, 0x70, 0x78, 0xa9, 0xd1, 0x72, 0xda, 0x5c, 0xf3, 0xcf, - 0xb5, 0xea, 0xe8, 0x48, 0x22, 0xb8, 0xda, 0xac, 0x90, 0xbf, 0x00, 0x68, 0xae, 0x47, 0x31, 0x4a, - 0xf2, 0x13, 0x19, 0x76, 0x9b, 0xe3, 0x81, 0xb7, 0xb7, 0xcc, 0x55, 0x5f, 0x84, 0x0d, 0x3c, 0x1f, - 0x79, 0x15, 0xd5, 0x02, 0xcf, 0x69, 0xef, 0x09, 0xb7, 0xa2, 0x4d, 0xe1, 0x56, 0xf4, 0xf6, 0x87, - 0x72, 0x2b, 0xe2, 0xac, 0xfc, 0x93, 0xe3, 0xe2, 0x84, 0x27, 0xea, 0xc4, 0x55, 0xa4, 0x7d, 0x01, - 0xeb, 0x3a, 0xf4, 0xad, 0xdd, 0x6a, 0xf3, 0xb0, 0xbf, 0xb4, 0xc1, 0x1b, 0x39, 0x8d, 0x3b, 0x38, - 0x76, 0x1d, 0xe6, 0x04, 0xb1, 0xba, 0x21, 0x42, 0xa2, 0xa1, 0xa9, 0x1c, 0xd8, 0xc5, 0x53, 0xba, - 0xae, 0x70, 0x6f, 0xdc, 0x42, 0x74, 0xf1, 0x94, 0x7e, 0x2e, 0x16, 0x4e, 0x23, 0x75, 0xf2, 0x68, - 0x24, 0xe4, 0x06, 0x8c, 0x3c, 0xb0, 0x1f, 0x97, 0xf6, 0xa8, 0xc8, 0xed, 0x39, 0x29, 0xb7, 0x3f, - 0x04, 0x2e, 0xe5, 0xff, 0x88, 0xfb, 0x3a, 0x3c, 0x63, 0x0a, 0x34, 0xf2, 0xbd, 0x19, 0x38, 0xcf, - 0x97, 0xb1, 0x6c, 0x65, 0x8d, 0x06, 0x01, 0xeb, 0x07, 0x11, 0x3f, 0xf0, 0x72, 0x64, 0xb0, 0x9d, - 0x8e, 0x87, 0x9e, 0xf7, 0x86, 0xd8, 0x19, 0xc2, 0x8e, 0xf3, 0x45, 0xa9, 0x16, 0x88, 0x39, 0x95, - 0x9e, 0x6c, 0xc2, 0xf8, 0x83, 0x3b, 0xa5, 0xb0, 0x5a, 0x1e, 0x9d, 0xbd, 0x98, 0xb6, 0x3b, 0x2a, - 0x68, 0x69, 0x9e, 0x06, 0x2a, 0x1b, 0xe1, 0x1d, 0xf0, 0x59, 0xd9, 0x1f, 0xe4, 0x75, 0xd5, 0x15, - 0x35, 0x87, 0xd2, 0xf3, 0x68, 0xcb, 0x7e, 0x6c, 0xd9, 0x7b, 0x54, 0x7b, 0x25, 0x17, 0xda, 0xeb, - 0x9f, 0xce, 0xc0, 0xc5, 0x9e, 0x4d, 0x26, 0xb7, 0xe1, 0x82, 0xcd, 0x1d, 0xac, 0xad, 0xfd, 0x20, - 0xe8, 0xf8, 0x96, 0xbc, 0x62, 0x08, 0xe7, 0x55, 0xf3, 0x9c, 0x28, 0x5e, 0x61, 0xa5, 0xf2, 0xd6, - 0xe1, 0x93, 0xf7, 0xe0, 0x39, 0xa7, 0xed, 0xd3, 0x7a, 0xd7, 0xa3, 0x96, 0x64, 0x50, 0x77, 0x1a, - 0x9e, 0xe5, 0xd9, 0xed, 0x3d, 0xe9, 0x89, 0x6b, 0x5e, 0x94, 0x38, 0xc2, 0x89, 0xbb, 0xec, 0x34, - 0x3c, 0x13, 0x11, 0x8c, 0x7f, 0x91, 0x81, 0xf9, 0x5e, 0x5d, 0x42, 0xe6, 0x61, 0x94, 0x2a, 0x79, - 0x5a, 0xf2, 0xa6, 0xfc, 0x49, 0x9e, 0x85, 0x68, 0xa7, 0x17, 0xa7, 0x7f, 0xbe, 0x2e, 0x72, 0x66, - 0xa0, 0x69, 0xbb, 0xba, 0xaf, 0x0b, 0x03, 0xe5, 0x89, 0xba, 0xba, 0xbb, 0x3f, 0x0f, 0x10, 0x6d, - 0xe7, 0x5c, 0x31, 0x61, 0x8e, 0xd9, 0x75, 0x8f, 0xaf, 0x3c, 0x72, 0x1e, 0x46, 0xf8, 0x76, 0x29, - 0xfc, 0x1f, 0xc4, 0x2f, 0x76, 0x6e, 0x8b, 0x4e, 0xc6, 0x7d, 0x3e, 0xb7, 0x34, 0xa1, 0x75, 0xf6, - 0x48, 0x0b, 0x07, 0xc7, 0xf8, 0xc9, 0x49, 0x2e, 0x42, 0x94, 0xba, 0xc1, 0xbe, 0x14, 0x3a, 0x16, - 0xd3, 0xfc, 0xc5, 0xb8, 0x2d, 0xa5, 0x62, 0x97, 0xad, 0x7b, 0x89, 0xc9, 0xb7, 0x9f, 0x6c, 0xea, - 0xdb, 0xcf, 0x6b, 0x30, 0x56, 0xde, 0xa7, 0xf5, 0x83, 0xd0, 0x09, 0x27, 0x2f, 0x94, 0xeb, 0x0c, - 0xc8, 0x43, 0xa2, 0x47, 0x08, 0xe4, 0x06, 0x00, 0xba, 0xa9, 0x72, 0x89, 0x54, 0x49, 0x6b, 0x82, - 0x5e, 0xad, 0xc2, 0x3c, 0x45, 0x41, 0x41, 0xf6, 0x35, 0xf3, 0x8e, 0x6a, 0xcf, 0xc2, 0xd9, 0xfb, - 0xde, 0xae, 0x40, 0x8f, 0x10, 0x58, 0xf3, 0x94, 0x7d, 0x45, 0x9c, 0x82, 0x85, 0xc4, 0xe6, 0xa3, - 0x22, 0x91, 0xeb, 0x30, 0xb6, 0x21, 0x1d, 0x09, 0xf0, 0x10, 0x9c, 0x40, 0x0a, 0x88, 0x9c, 0x0e, - 0xe6, 0x33, 0x66, 0x84, 0x42, 0x3e, 0x0b, 0xa3, 0x65, 0xea, 0x05, 0x9b, 0x9b, 0xab, 0x68, 0x74, - 0xc2, 0xb3, 0x7f, 0xe4, 0x31, 0x53, 0x43, 0x10, 0x34, 0xbf, 0x73, 0x5c, 0x9c, 0x0c, 0x9c, 0x16, - 0x0d, 0xa3, 0x9a, 0x9b, 0x12, 0x9b, 0x2c, 0x41, 0x81, 0x3f, 0x8b, 0x47, 0x77, 0x0f, 0x3c, 0x19, - 0xf3, 0xfc, 0x9c, 0x16, 0x6f, 0xe8, 0x87, 0x74, 0x27, 0xcc, 0x53, 0x91, 0xc0, 0x27, 0xcb, 0x32, - 0xbd, 0x8b, 0xda, 0x4c, 0x88, 0x94, 0x61, 0xf1, 0x1d, 0x83, 0xb5, 0x36, 0x49, 0x41, 0x4a, 0x30, - 0x59, 0x76, 0x5b, 0x1d, 0x3b, 0x70, 0x30, 0x0f, 0xe6, 0x91, 0x38, 0x04, 0x51, 0xa1, 0x57, 0x57, - 0x0b, 0xb4, 0x13, 0x55, 0x2d, 0x20, 0x77, 0x60, 0xca, 0x74, 0xbb, 0x6c, 0x98, 0xe4, 0x2d, 0x9c, - 0x9f, 0x73, 0x68, 0x1a, 0xe2, 0xb1, 0x12, 0x76, 0x2c, 0x8b, 0x2b, 0xb7, 0x16, 0x01, 0x56, 0xa3, - 0x22, 0x6b, 0x29, 0xcf, 0x21, 0xea, 0xe1, 0xa6, 0x66, 0xab, 0x48, 0x30, 0x4b, 0x79, 0x49, 0xb9, - 0x05, 0xe3, 0xb5, 0xda, 0xfa, 0x26, 0xf5, 0x83, 0x3b, 0x4d, 0xf7, 0x10, 0xcf, 0xb6, 0xbc, 0x48, - 0xae, 0xe6, 0xbb, 0x56, 0x40, 0xfd, 0xc0, 0xda, 0x6d, 0xba, 0x87, 0xa6, 0x8a, 0x45, 0xbe, 0xc6, - 0xfa, 0x43, 0x91, 0x04, 0x45, 0xac, 0xdb, 0x7e, 0xc2, 0x2a, 0x9e, 0x20, 0xd1, 0xa2, 0x61, 0x22, - 0xab, 0xde, 0x59, 0x0a, 0x3a, 0xfa, 0x94, 0x79, 0xee, 0xe3, 0xa3, 0x52, 0xa3, 0xe1, 0x51, 0xdf, - 0x17, 0x87, 0x10, 0xf7, 0x29, 0x43, 0x65, 0x83, 0xcd, 0x0b, 0x34, 0x9f, 0x32, 0x85, 0x80, 0xfc, - 0x70, 0x06, 0xce, 0xa9, 0xde, 0x26, 0xb8, 0x5c, 0xd0, 0xcc, 0x85, 0x1f, 0x49, 0xaf, 0x5f, 0x97, - 0x87, 0xf0, 0x75, 0x05, 0xed, 0xfa, 0xa3, 0x9b, 0xd7, 0x4b, 0xd1, 0xcf, 0x9a, 0x24, 0xc2, 0xb8, - 0x7d, 0xc5, 0x54, 0x7e, 0x5a, 0x6e, 0xa2, 0x39, 0x3b, 0x85, 0x98, 0x94, 0x99, 0xa4, 0xc6, 0x66, - 0x14, 0x1a, 0x4e, 0x55, 0x37, 0xf0, 0x4c, 0x13, 0x1a, 0x55, 0x31, 0xff, 0xb8, 0x89, 0x95, 0xd3, - 0xd1, 0x05, 0x32, 0x85, 0x86, 0x54, 0x61, 0x9a, 0x03, 0xd8, 0xb6, 0xc0, 0xd3, 0x3c, 0xcd, 0x46, - 0x89, 0x26, 0x04, 0x1b, 0x7c, 0xeb, 0xc7, 0x54, 0x4f, 0x6a, 0x70, 0xd6, 0x18, 0x1d, 0x79, 0x0f, - 0xa6, 0x30, 0x86, 0x7e, 0xb4, 0x5e, 0xe7, 0x70, 0x15, 0x63, 0x8c, 0x59, 0x51, 0x12, 0xf3, 0xbc, - 0x9b, 0xf0, 0xfd, 0xfd, 0x68, 0x45, 0xbf, 0x07, 0x53, 0x68, 0xab, 0x13, 0x31, 0x38, 0x17, 0x31, - 0x10, 0x25, 0x71, 0x06, 0x41, 0xd3, 0x8f, 0x18, 0xfc, 0x54, 0x06, 0x2e, 0xb2, 0x8a, 0xd2, 0x47, - 0xe8, 0xfc, 0x87, 0x19, 0x21, 0x8c, 0xba, 0xd9, 0x93, 0xa7, 0x2a, 0x8e, 0xfa, 0xfe, 0x7e, 0x1a, - 0x07, 0xfc, 0x28, 0xf6, 0xf1, 0xe9, 0x1f, 0x75, 0xe1, 0x43, 0x7f, 0x54, 0x4f, 0x9e, 0xea, 0x47, - 0x05, 0x4d, 0x3f, 0x8d, 0x03, 0x5e, 0x6b, 0x6b, 0xa5, 0x07, 0xab, 0xd1, 0xdd, 0xec, 0x93, 0xe5, - 0xb6, 0xa2, 0xb5, 0xad, 0x8f, 0xdb, 0xca, 0x16, 0xf7, 0xa2, 0x56, 0xba, 0x41, 0x5e, 0x6b, 0x35, - 0x70, 0xfc, 0x5a, 0x1b, 0xa3, 0x31, 0x63, 0xd8, 0xc6, 0x2f, 0x41, 0x8c, 0xaf, 0x30, 0x55, 0x35, - 0x60, 0x84, 0xdf, 0x5a, 0x45, 0x27, 0xa3, 0xcd, 0x02, 0xbf, 0xd3, 0x9a, 0xa2, 0x84, 0x5c, 0x84, - 0x5c, 0xad, 0xb6, 0x2e, 0x3a, 0x19, 0x0d, 0x56, 0x7d, 0xdf, 0x35, 0x19, 0x8c, 0x8d, 0x10, 0x5a, - 0xa1, 0x2a, 0x39, 0x09, 0xd8, 0x79, 0x67, 0x22, 0x94, 0xf5, 0xb7, 0xbc, 0x43, 0x0e, 0x45, 0xfd, - 0x2d, 0xee, 0x90, 0xd1, 0xcd, 0xb1, 0x0c, 0xf3, 0x25, 0xdf, 0xa7, 0x1e, 0x9b, 0x10, 0xc2, 0xb8, - 0xd1, 0x13, 0xf7, 0x1c, 0x71, 0xb0, 0x63, 0xa5, 0x76, 0xdd, 0x37, 0x7b, 0x22, 0x92, 0xab, 0x90, - 0x2f, 0x75, 0x1b, 0x0e, 0x6d, 0xd7, 0xb5, 0xb0, 0x6c, 0xb6, 0x80, 0x99, 0x61, 0x29, 0xf9, 0x22, - 0x9c, 0x8b, 0x45, 0x60, 0x14, 0x3d, 0x30, 0x1a, 0xed, 0xbd, 0xf2, 0x1e, 0x16, 0x19, 0x64, 0xf0, - 0x2e, 0x49, 0xa7, 0x24, 0x25, 0x28, 0x2c, 0xa3, 0x9b, 0x56, 0x85, 0xf2, 0xb7, 0x21, 0xd7, 0xe3, - 0xfe, 0x79, 0xfc, 0xd6, 0x2c, 0xe2, 0x4c, 0x36, 0xc2, 0x42, 0x33, 0x81, 0x4e, 0xee, 0xc3, 0x6c, - 0x1c, 0xc6, 0x4e, 0x70, 0x7e, 0x41, 0xc6, 0xfd, 0x26, 0xc1, 0x05, 0xcf, 0xf0, 0x34, 0x2a, 0xb2, - 0x03, 0x33, 0x91, 0x41, 0x92, 0x7e, 0x6d, 0x96, 0x76, 0xce, 0x61, 0xb9, 0xbc, 0x3a, 0x3f, 0x2b, - 0x26, 0xe3, 0x6c, 0x64, 0xdc, 0x14, 0x5e, 0x9f, 0xcd, 0x24, 0x3b, 0xd2, 0x80, 0xa9, 0x9a, 0xb3, - 0xd7, 0x76, 0xda, 0x7b, 0xf7, 0xe9, 0xd1, 0x86, 0xed, 0x78, 0xc2, 0xe2, 0x54, 0xda, 0x93, 0x97, - 0xfc, 0xa3, 0x56, 0x8b, 0x06, 0x1e, 0x6e, 0x84, 0xac, 0x1c, 0x7d, 0xd0, 0xd9, 0x75, 0x68, 0xc1, - 0xe7, 0x74, 0xe8, 0xb6, 0xd9, 0xb1, 0x1d, 0x4d, 0x08, 0xd0, 0x79, 0x6a, 0xaa, 0x8b, 0x89, 0x01, - 0x55, 0x17, 0x4d, 0x98, 0x59, 0x6e, 0xd7, 0xbd, 0x23, 0x7c, 0xa2, 0x93, 0x1f, 0x37, 0x79, 0xca, - 0xc7, 0xbd, 0x24, 0x3e, 0xee, 0x39, 0x5b, 0xce, 0xb0, 0xb4, 0xcf, 0x4b, 0x32, 0x26, 0x35, 0x98, - 0xc1, 0x8b, 0x43, 0xb5, 0xb2, 0x51, 0x6d, 0x3b, 0x81, 0x63, 0x07, 0xb4, 0x21, 0x84, 0x8b, 0x30, - 0x93, 0x0b, 0xbf, 0xa2, 0x3a, 0x8d, 0x8e, 0xe5, 0x48, 0x14, 0x95, 0x69, 0x82, 0xbe, 0xdf, 0x3d, - 0x71, 0xfa, 0x2f, 0xe9, 0x9e, 0x58, 0x85, 0xe9, 0x78, 0x28, 0x87, 0x42, 0x74, 0x0e, 0xfb, 0x58, - 0xc4, 0x8e, 0x73, 0xb7, 0x8b, 0xc2, 0xa4, 0x96, 0x3c, 0x35, 0x16, 0xc4, 0x21, 0x76, 0xe5, 0x9c, - 0xd1, 0xae, 0x9c, 0xda, 0xae, 0x74, 0x86, 0x2b, 0x27, 0xd9, 0x00, 0xb8, 0xe3, 0x7a, 0x75, 0x5a, - 0x42, 0xff, 0x68, 0xa2, 0xe5, 0xbb, 0x62, 0x4c, 0xa3, 0x42, 0xbe, 0x7e, 0x76, 0xd9, 0x6f, 0x2b, - 0xee, 0xe6, 0xae, 0xf0, 0x30, 0x7e, 0x24, 0x0b, 0xf3, 0xbd, 0x3e, 0xa7, 0xcf, 0x75, 0xef, 0x53, - 0x90, 0x5c, 0xe1, 0xe2, 0xda, 0x57, 0xa0, 0xf1, 0x75, 0xbe, 0x08, 0xe9, 0x0b, 0x59, 0x5c, 0x03, - 0x67, 0xe3, 0x04, 0x5b, 0x5e, 0x93, 0xdc, 0x86, 0x71, 0xe5, 0xe3, 0x71, 0x2f, 0xed, 0xd5, 0x54, - 0x13, 0x76, 0xc3, 0xbf, 0xd9, 0x35, 0x91, 0xef, 0x5b, 0xf2, 0x9a, 0xc8, 0x7f, 0x91, 0x02, 0x77, - 0x11, 0x1f, 0xe1, 0x56, 0x00, 0xbe, 0xef, 0x12, 0x02, 0xb8, 0x6f, 0xf3, 0x2d, 0xd0, 0xc4, 0xbf, - 0x8d, 0xdf, 0x98, 0xe0, 0x27, 0xb2, 0x7a, 0x4b, 0xec, 0x65, 0x1f, 0x1c, 0xbb, 0x3d, 0x66, 0xcf, - 0x72, 0x7b, 0xcc, 0x9d, 0x7e, 0x7b, 0x1c, 0x3a, 0xed, 0xf6, 0x18, 0xbb, 0xde, 0x0d, 0x9f, 0xf9, - 0x7a, 0x37, 0x72, 0xa6, 0xeb, 0xdd, 0xe8, 0x99, 0xae, 0x77, 0xda, 0x4d, 0x35, 0x7f, 0xda, 0x4d, - 0xf5, 0xaf, 0x2f, 0x83, 0x4f, 0xeb, 0x65, 0x30, 0x4d, 0xc4, 0x3b, 0xd3, 0x65, 0xf0, 0x87, 0x7a, - 0xde, 0xe5, 0x0a, 0x1f, 0x46, 0x28, 0x7f, 0x71, 0x80, 0xbb, 0xdc, 0xa0, 0x37, 0xb9, 0x99, 0x27, - 0x73, 0x93, 0x23, 0x4f, 0xec, 0x26, 0x37, 0xfb, 0x51, 0x6f, 0x72, 0x73, 0x4f, 0xf2, 0x26, 0x77, - 0xee, 0xaf, 0xe2, 0x4d, 0xee, 0xfc, 0xbf, 0x9d, 0x9b, 0xdc, 0xdf, 0x80, 0x42, 0x5c, 0xb8, 0x3c, - 0x3d, 0xea, 0xf1, 0x13, 0x0b, 0x39, 0xc9, 0x44, 0xdf, 0xb8, 0x70, 0x47, 0x6e, 0x00, 0x6c, 0x78, - 0xce, 0x23, 0x3b, 0xa0, 0xf7, 0xa5, 0xf5, 0x9b, 0x88, 0xd8, 0xcd, 0xa1, 0x6c, 0xe4, 0x4d, 0x05, - 0x25, 0xbc, 0xd7, 0x64, 0xd3, 0xee, 0x35, 0xc6, 0x0f, 0x67, 0x61, 0x86, 0xc7, 0x6d, 0x7b, 0xfa, - 0x1f, 0x61, 0xdf, 0xd5, 0x6e, 0xab, 0xcf, 0x45, 0x39, 0x02, 0xd4, 0xd6, 0xf5, 0x79, 0x86, 0xfd, - 0x2a, 0x9c, 0x4b, 0x74, 0x05, 0xde, 0x58, 0x2b, 0x32, 0x62, 0x5e, 0xe2, 0xce, 0x3a, 0x9f, 0x5e, - 0xc9, 0xc3, 0x5b, 0x66, 0x82, 0xc2, 0xf8, 0xf3, 0xa1, 0x04, 0x7f, 0xf1, 0x20, 0xab, 0x3e, 0xb1, - 0x66, 0xce, 0xf6, 0xc4, 0x9a, 0x1d, 0xec, 0x89, 0x35, 0x26, 0x54, 0xe4, 0x06, 0x11, 0x2a, 0xbe, - 0x08, 0x93, 0x9b, 0xd4, 0x6e, 0xf9, 0x9b, 0xae, 0x48, 0x38, 0xc5, 0x7d, 0x2d, 0x64, 0x40, 0x3c, - 0x56, 0x26, 0x2f, 0x5c, 0xa1, 0xcd, 0x68, 0xc0, 0x08, 0xd8, 0x31, 0xc8, 0x33, 0x50, 0x99, 0x3a, - 0x07, 0xf5, 0x16, 0x3d, 0xdc, 0xe7, 0x16, 0x5d, 0x83, 0x09, 0x41, 0x17, 0x85, 0x7a, 0x8e, 0xae, - 0x7b, 0xac, 0x08, 0xe1, 0xb2, 0xf6, 0x30, 0x1b, 0x7e, 0x58, 0x3b, 0xbf, 0xe9, 0x69, 0x4c, 0x58, - 0x17, 0x2c, 0xb7, 0x1b, 0x1d, 0xd7, 0x69, 0x63, 0x17, 0x8c, 0x46, 0x5d, 0x40, 0x05, 0x98, 0x77, - 0x81, 0x82, 0x44, 0xde, 0x86, 0xa9, 0xd2, 0x46, 0x55, 0x25, 0xcb, 0x47, 0xaf, 0xbc, 0x76, 0xc7, - 0xb1, 0x34, 0xd2, 0x18, 0x6e, 0xbf, 0x9b, 0xcf, 0xd8, 0x5f, 0xce, 0xcd, 0xc7, 0xf8, 0xa7, 0x93, - 0x72, 0x79, 0x7f, 0xbc, 0x0f, 0x24, 0xfa, 0x93, 0x47, 0xee, 0x8c, 0x4f, 0x1e, 0x43, 0xa7, 0x09, - 0x92, 0x9a, 0x7c, 0x3b, 0x7c, 0x26, 0xf9, 0x76, 0xe4, 0x23, 0x3f, 0x5f, 0x8c, 0x9e, 0x51, 0x62, - 0x8d, 0xad, 0xb5, 0xfc, 0x20, 0x6b, 0x2d, 0x55, 0xca, 0x1d, 0xfb, 0xe8, 0x52, 0x2e, 0x9c, 0x59, - 0xca, 0xad, 0x45, 0xbe, 0xcb, 0xe3, 0xa7, 0xba, 0x84, 0x3c, 0x2f, 0xb4, 0x02, 0x33, 0xe9, 0x51, - 0xf8, 0x42, 0x2f, 0xe6, 0x4f, 0x94, 0xe8, 0xfc, 0xf5, 0x74, 0xd1, 0xb9, 0xff, 0x79, 0x73, 0x26, - 0xe1, 0xf9, 0x87, 0x9f, 0xac, 0xf0, 0xfc, 0x64, 0x1f, 0x42, 0xfe, 0x5a, 0x7c, 0xfe, 0x6b, 0xf1, - 0x79, 0x30, 0xf1, 0x99, 0xac, 0x03, 0xb1, 0xbb, 0xc1, 0x3e, 0x6d, 0x07, 0x4e, 0x1d, 0xa3, 0xd2, - 0xb2, 0x21, 0xc6, 0x57, 0x19, 0xb1, 0x5e, 0x93, 0xa5, 0xea, 0x7a, 0xd5, 0x4a, 0xd1, 0xcf, 0xdb, - 0xc3, 0xf5, 0xba, 0x6d, 0x7b, 0x6d, 0xd4, 0x63, 0xdd, 0x80, 0x51, 0x19, 0xd7, 0x34, 0x13, 0xa9, - 0xa8, 0x93, 0x01, 0x4d, 0x25, 0x16, 0x59, 0x84, 0xbc, 0x24, 0x56, 0x13, 0xed, 0x1c, 0x0a, 0x98, - 0x16, 0x32, 0x52, 0xc0, 0x8c, 0xff, 0x68, 0x48, 0x9e, 0x09, 0xec, 0x13, 0x36, 0x6c, 0xcf, 0x6e, - 0x61, 0x0e, 0xbe, 0x70, 0xc9, 0x2a, 0xb7, 0x81, 0xd8, 0x2a, 0x8f, 0xf9, 0x0a, 0xe8, 0x24, 0x1f, - 0x2a, 0x30, 0x6d, 0x94, 0xe6, 0x38, 0x37, 0x40, 0x9a, 0xe3, 0x37, 0xb5, 0x1c, 0xc1, 0x43, 0x51, - 0x52, 0x4a, 0xb6, 0x4f, 0xf6, 0xcf, 0x0e, 0x7c, 0x5b, 0x4d, 0xe6, 0x3b, 0x1c, 0x85, 0x09, 0x43, - 0xca, 0x3e, 0x69, 0x7c, 0xc3, 0xeb, 0xcd, 0xc8, 0x59, 0x42, 0x3e, 0x8f, 0xfe, 0x5b, 0x0d, 0xf9, - 0xbc, 0x0c, 0x20, 0xce, 0xee, 0xc8, 0xde, 0xe1, 0x65, 0xdc, 0x4e, 0x84, 0xdd, 0x73, 0x10, 0x34, - 0x7b, 0xe4, 0x04, 0x51, 0x08, 0x8d, 0x3f, 0x20, 0x30, 0x53, 0xab, 0xad, 0x57, 0x1c, 0x7b, 0xaf, - 0xed, 0xfa, 0x81, 0x53, 0xaf, 0xb6, 0x77, 0x5d, 0x26, 0xdb, 0x87, 0xe7, 0x8b, 0x12, 0xac, 0x37, - 0x3a, 0x5b, 0xc2, 0x62, 0x76, 0x77, 0x5c, 0xf6, 0x3c, 0xa9, 0x70, 0xe5, 0x77, 0x47, 0xca, 0x00, - 0x26, 0x87, 0x33, 0xf1, 0xb9, 0xd6, 0xc5, 0x50, 0x19, 0xc2, 0x08, 0x05, 0xc5, 0x67, 0x9f, 0x83, - 0x4c, 0x59, 0x46, 0x68, 0x72, 0xc2, 0x8a, 0xeb, 0xd4, 0x05, 0x2d, 0x70, 0x74, 0x54, 0xcc, 0x57, - 0xa3, 0x90, 0x6e, 0x70, 0x1f, 0xee, 0x20, 0x5c, 0x35, 0xb1, 0x4b, 0xac, 0x81, 0x23, 0x38, 0xa7, - 0x39, 0x51, 0x0f, 0xfa, 0x3a, 0xf3, 0xaa, 0x10, 0xd7, 0x0d, 0x8c, 0xd9, 0x91, 0xf2, 0x44, 0xa3, - 0x26, 0xd5, 0x4b, 0xad, 0x81, 0x1d, 0x90, 0xcf, 0xa7, 0x96, 0x84, 0xab, 0x7b, 0x5c, 0x0b, 0xde, - 0xad, 0x6c, 0x1a, 0x3c, 0x7d, 0x60, 0xaf, 0xaa, 0xad, 0x94, 0xad, 0xa0, 0x7f, 0x4d, 0xe4, 0x37, - 0x33, 0x70, 0x41, 0xc3, 0x08, 0xf7, 0x3f, 0x3f, 0x8c, 0x2f, 0x92, 0x3a, 0xaf, 0x3f, 0x78, 0x32, - 0xf3, 0xfa, 0x45, 0xbd, 0x2d, 0xd1, 0x0e, 0xad, 0xb6, 0xa1, 0xd7, 0x17, 0x92, 0x47, 0x30, 0x83, - 0x45, 0xf2, 0xa5, 0x88, 0xcd, 0x59, 0xf1, 0xc0, 0x34, 0x17, 0x7d, 0x36, 0x0f, 0x0c, 0x80, 0x29, - 0xe0, 0x17, 0xbf, 0x7d, 0x5c, 0x9c, 0xd4, 0xd0, 0x65, 0x38, 0x6c, 0x2b, 0x7a, 0x6e, 0x72, 0xda, - 0xbb, 0xae, 0x96, 0xdf, 0x3f, 0x5e, 0x05, 0xf9, 0xaf, 0x33, 0xfc, 0x7d, 0x82, 0x37, 0xe3, 0x8e, - 0xe7, 0xb6, 0xc2, 0x72, 0x69, 0xab, 0xd9, 0xa3, 0xdb, 0x9a, 0x4f, 0xa6, 0xdb, 0x5e, 0xc6, 0x4f, - 0xe6, 0x7b, 0x82, 0xb5, 0xeb, 0xb9, 0xad, 0xe8, 0xf3, 0xd5, 0x8e, 0xeb, 0xf9, 0x91, 0xe4, 0xfb, - 0x32, 0x70, 0x51, 0x53, 0x93, 0xaa, 0xb9, 0x49, 0x44, 0xf8, 0x85, 0xd9, 0x30, 0x30, 0x4b, 0x54, - 0xb4, 0x74, 0x5d, 0xcc, 0xff, 0x2b, 0xf8, 0x05, 0x4a, 0x1c, 0x50, 0x86, 0x64, 0xb5, 0x38, 0x96, - 0xf2, 0x09, 0xbd, 0x6b, 0x21, 0x0e, 0xcc, 0xa0, 0xd9, 0x8e, 0x66, 0x53, 0x3c, 0xd7, 0xdb, 0xa6, - 0x38, 0xcc, 0x3a, 0x84, 0x19, 0x09, 0x7a, 0x1b, 0x16, 0x27, 0xb9, 0x92, 0xef, 0x81, 0x8b, 0x09, - 0x60, 0xb8, 0xda, 0xce, 0xf5, 0x5c, 0x6d, 0x9f, 0x3a, 0x39, 0x2e, 0xbe, 0x92, 0x56, 0x5b, 0xda, - 0x4a, 0xeb, 0x5d, 0x03, 0xb1, 0x01, 0xa2, 0x42, 0x21, 0xcf, 0xa4, 0x4f, 0xd0, 0x4f, 0x89, 0xf9, - 0xa1, 0xe0, 0xb3, 0xbd, 0x5c, 0xf9, 0x06, 0xf5, 0xc8, 0x8b, 0x90, 0x08, 0x85, 0x09, 0x25, 0x1b, - 0xc3, 0x91, 0xb0, 0x1e, 0xe9, 0x51, 0xc9, 0xb7, 0x8f, 0x8b, 0x1a, 0x36, 0xbb, 0x61, 0xa9, 0x69, - 0x1e, 0x34, 0xf1, 0x51, 0x45, 0x24, 0xbf, 0x9e, 0x81, 0x39, 0x06, 0x88, 0x26, 0x95, 0x68, 0xd4, - 0x7c, 0xbf, 0x59, 0xbf, 0xff, 0x64, 0x66, 0xfd, 0x0b, 0xf8, 0x8d, 0xea, 0xac, 0x4f, 0x74, 0x49, - 0xea, 0xc7, 0xe1, 0x6c, 0xd7, 0x2c, 0xc4, 0xb4, 0xd9, 0x7e, 0x71, 0x80, 0xd9, 0xce, 0x07, 0xe0, - 0xf4, 0xd9, 0xde, 0xb3, 0x16, 0xb2, 0x09, 0x13, 0xe2, 0x72, 0xc5, 0x3b, 0xec, 0x92, 0x16, 0x17, - 0x5a, 0x2d, 0xe2, 0x37, 0x5e, 0x91, 0xac, 0x22, 0xd1, 0x42, 0x8d, 0x0b, 0x69, 0xc3, 0x2c, 0xff, - 0xad, 0x2b, 0xbb, 0x8a, 0x3d, 0x95, 0x5d, 0x57, 0x45, 0x8b, 0x2e, 0x0b, 0xfe, 0x31, 0x9d, 0x97, - 0x1a, 0xcf, 0x29, 0x85, 0x31, 0xe9, 0x00, 0xd1, 0xc0, 0x7c, 0xd1, 0x5e, 0xee, 0xaf, 0xe2, 0x7a, - 0x45, 0xd4, 0x59, 0x8c, 0xd7, 0x19, 0x5f, 0xb9, 0x29, 0xbc, 0x89, 0x0d, 0xd3, 0x02, 0xea, 0x1e, - 0x50, 0xbe, 0xc3, 0xbf, 0xa0, 0x45, 0xd4, 0x8a, 0x95, 0xf2, 0x5b, 0x99, 0xac, 0x09, 0x23, 0x9e, - 0xc5, 0x36, 0xf4, 0x38, 0x3f, 0xb2, 0x0e, 0x33, 0xa5, 0x4e, 0xa7, 0xe9, 0xd0, 0x06, 0xb6, 0xd2, - 0xec, 0xb2, 0x36, 0x19, 0x51, 0xbe, 0x37, 0x9b, 0x17, 0x8a, 0xab, 0xa2, 0xd7, 0x8d, 0x6d, 0x37, - 0x09, 0x5a, 0xe3, 0x87, 0x32, 0x89, 0x8f, 0x26, 0xaf, 0xc1, 0x18, 0xfe, 0x50, 0x82, 0xb4, 0xa0, - 0xce, 0x88, 0x7f, 0x22, 0x6a, 0xa3, 0x22, 0x04, 0x26, 0x2c, 0xa9, 0x81, 0x1a, 0x73, 0x5c, 0x58, - 0x12, 0x8a, 0x8a, 0x48, 0x35, 0x51, 0x94, 0xbe, 0x1e, 0xb9, 0x48, 0xe8, 0x42, 0x5f, 0x0f, 0xe1, - 0xe1, 0x61, 0xfc, 0xe3, 0xac, 0x3e, 0xed, 0xc8, 0x55, 0x45, 0x6e, 0x57, 0x42, 0x45, 0x4a, 0xb9, - 0x5d, 0x91, 0xd6, 0xff, 0x41, 0x06, 0x66, 0xd7, 0x95, 0x44, 0xa1, 0x9b, 0x2e, 0x8e, 0x4b, 0xff, - 0xd4, 0x99, 0x4f, 0x2a, 0x05, 0xa0, 0x9a, 0xa1, 0x94, 0xcd, 0x14, 0x9c, 0x32, 0x66, 0xda, 0xf7, - 0xa0, 0xf7, 0x1c, 0x7e, 0x98, 0x92, 0x89, 0x91, 0xa3, 0x73, 0xf8, 0x19, 0x53, 0x57, 0x18, 0x3f, - 0x96, 0x85, 0x71, 0x65, 0xc5, 0x90, 0xcf, 0xc0, 0x84, 0x5a, 0xad, 0xaa, 0x70, 0x54, 0xbf, 0xd2, - 0xd4, 0xb0, 0x50, 0xe3, 0x48, 0xed, 0x96, 0xa6, 0x71, 0x64, 0xeb, 0x02, 0xa1, 0x67, 0xbc, 0x09, - 0xbd, 0x97, 0x72, 0x13, 0xc2, 0x59, 0xae, 0x68, 0x8c, 0xfa, 0xde, 0x87, 0xde, 0x4e, 0xde, 0x87, - 0x50, 0x79, 0xa5, 0xd0, 0xf7, 0xbe, 0x15, 0x19, 0x3f, 0x99, 0x81, 0x42, 0x7c, 0x4d, 0x7f, 0x2c, - 0xbd, 0x72, 0x86, 0xd7, 0xa5, 0x1f, 0xcd, 0x86, 0x99, 0x5b, 0xa4, 0x0b, 0xf1, 0xd3, 0x6a, 0xa6, - 0xf8, 0x8e, 0xf6, 0xf0, 0xf3, 0xac, 0x1e, 0x0d, 0x4f, 0x0d, 0xbe, 0x91, 0x1e, 0x02, 0x73, 0xe8, - 0xe7, 0x7e, 0xb1, 0xf8, 0x8c, 0xf1, 0x3e, 0xcc, 0xc5, 0xbb, 0x03, 0x1f, 0x7f, 0x4a, 0x30, 0xad, - 0xc3, 0xe3, 0x79, 0x9f, 0xe2, 0x54, 0x66, 0x1c, 0xdf, 0xf8, 0xa3, 0x6c, 0x9c, 0xb7, 0x30, 0x59, - 0x64, 0x7b, 0x94, 0x6a, 0x88, 0x23, 0xf6, 0x28, 0x0e, 0x32, 0x65, 0xd9, 0x59, 0xf2, 0xad, 0x85, - 0x8e, 0xb0, 0xb9, 0x74, 0x47, 0x58, 0x72, 0x3b, 0x66, 0xa5, 0xad, 0x44, 0x6d, 0x3a, 0xa4, 0x3b, - 0x56, 0x64, 0xa9, 0x1d, 0x33, 0xce, 0x2e, 0xc3, 0x9c, 0x16, 0x82, 0x5c, 0xd2, 0x0f, 0x47, 0xba, - 0xfe, 0x00, 0x0b, 0x38, 0x71, 0x2a, 0x32, 0x59, 0x81, 0x51, 0xf6, 0x99, 0x0f, 0xec, 0x8e, 0x78, - 0xd3, 0x21, 0xa1, 0x5b, 0x7c, 0x33, 0xbc, 0x1f, 0x2a, 0x9e, 0xf1, 0x4d, 0xca, 0x24, 0x04, 0x75, - 0x62, 0x09, 0x44, 0xe3, 0x5f, 0x65, 0xd8, 0xfa, 0xaf, 0x1f, 0x7c, 0xc2, 0x92, 0xb6, 0xb1, 0x26, - 0xf5, 0xb1, 0xa8, 0xfd, 0x93, 0x2c, 0xcf, 0xc5, 0x23, 0xa6, 0xcf, 0x9b, 0x30, 0xb2, 0x69, 0x7b, - 0x7b, 0x22, 0x65, 0xb6, 0xce, 0x85, 0x17, 0x44, 0x31, 0xa5, 0x02, 0xfc, 0x6d, 0x0a, 0x02, 0x55, - 0x75, 0x96, 0x1d, 0x48, 0x75, 0xa6, 0xbc, 0x0b, 0xe4, 0x9e, 0xd8, 0xbb, 0xc0, 0x77, 0x85, 0x69, - 0x77, 0x4a, 0xc1, 0x00, 0x11, 0xae, 0x2f, 0xc7, 0xb3, 0x5c, 0x25, 0x62, 0x91, 0x47, 0xec, 0xc8, - 0x6d, 0x35, 0x6f, 0x96, 0xe2, 0x5b, 0x7a, 0x4a, 0x86, 0x2c, 0xe3, 0x4f, 0x72, 0xbc, 0x8f, 0x45, - 0x47, 0x5d, 0xd1, 0xfc, 0xce, 0x71, 0x9d, 0xc4, 0xf4, 0x94, 0xdc, 0x03, 0xfd, 0x0a, 0x0c, 0xb1, - 0xb9, 0x29, 0x7a, 0x13, 0xf1, 0xd8, 0xfc, 0x55, 0xf1, 0x58, 0x39, 0x5b, 0xcb, 0x78, 0x26, 0xa9, - 0x09, 0x11, 0xf1, 0xd8, 0x52, 0xd7, 0x32, 0x62, 0x90, 0xab, 0x30, 0xb4, 0xe6, 0x36, 0x64, 0x24, - 0xf5, 0x39, 0x8c, 0x3e, 0xa2, 0x65, 0x5c, 0x9d, 0xcf, 0x98, 0x88, 0xc1, 0xda, 0x1a, 0xe6, 0x9f, - 0x50, 0xdb, 0xda, 0xda, 0xb5, 0x93, 0x89, 0xee, 0x94, 0xa4, 0x37, 0xcb, 0x30, 0xb5, 0xed, 0xb4, - 0x1b, 0xee, 0xa1, 0x5f, 0xa1, 0xfe, 0x41, 0xe0, 0x76, 0x84, 0xbd, 0x31, 0x6a, 0xf7, 0x0f, 0x79, - 0x89, 0xd5, 0xe0, 0x45, 0xea, 0xb3, 0x8c, 0x4e, 0x44, 0x96, 0x60, 0x52, 0x8b, 0xe0, 0x2a, 0x1e, - 0x57, 0x51, 0x1b, 0xaa, 0xc7, 0x7f, 0x55, 0xb5, 0xa1, 0x1a, 0x09, 0x3b, 0xcf, 0xc5, 0xf7, 0x2b, - 0x4f, 0xac, 0x89, 0x6f, 0x17, 0x38, 0xe4, 0x16, 0xe4, 0x79, 0x98, 0x8f, 0x6a, 0x45, 0x7d, 0x26, - 0xf3, 0x11, 0x16, 0x0b, 0x93, 0x23, 0x11, 0x95, 0xb0, 0x0e, 0x9f, 0x86, 0x82, 0xd8, 0x92, 0xa2, - 0x5c, 0xed, 0xcf, 0xc1, 0x50, 0xb9, 0x5a, 0x31, 0xd5, 0x6d, 0xa4, 0xee, 0x34, 0x3c, 0x13, 0xa1, - 0xe8, 0xd5, 0xb7, 0x46, 0x83, 0x43, 0xd7, 0x3b, 0x30, 0xa9, 0x1f, 0x78, 0x0e, 0xcf, 0xa7, 0x89, - 0x0b, 0xf1, 0x33, 0xe4, 0x6d, 0x18, 0x46, 0xc3, 0xd7, 0xd8, 0xc9, 0x10, 0xaf, 0x63, 0x69, 0x52, - 0x4c, 0xe0, 0x61, 0xb4, 0xa2, 0x35, 0x39, 0x11, 0x79, 0x13, 0x86, 0x2a, 0xb4, 0x7d, 0x14, 0x4b, - 0xf5, 0x97, 0x20, 0x0e, 0x37, 0x84, 0x06, 0x6d, 0x1f, 0x99, 0x48, 0x62, 0xfc, 0x64, 0x16, 0xce, - 0xa5, 0x7c, 0xd6, 0xc3, 0xcf, 0x3c, 0xa5, 0xbb, 0xe2, 0x92, 0xb6, 0x2b, 0xca, 0xf7, 0xf1, 0x9e, - 0x1d, 0x9f, 0xba, 0x49, 0xfe, 0x7c, 0x06, 0x2e, 0xe8, 0x13, 0x54, 0x58, 0xba, 0x3f, 0xbc, 0x45, - 0xde, 0x82, 0x91, 0x15, 0x6a, 0x37, 0xa8, 0xcc, 0xeb, 0x75, 0x2e, 0x0c, 0xc8, 0xc7, 0x63, 0x18, - 0xf0, 0x42, 0xce, 0x36, 0xf2, 0x78, 0xe5, 0x50, 0x52, 0x11, 0x1f, 0xc7, 0xc5, 0x77, 0x43, 0xc6, - 0x13, 0x49, 0xab, 0xaa, 0x8f, 0x95, 0xc9, 0xb7, 0x33, 0xf0, 0x6c, 0x1f, 0x1a, 0x36, 0x70, 0x6c, - 0xe8, 0xd5, 0x81, 0xc3, 0x13, 0x15, 0xa1, 0xe4, 0x5d, 0x98, 0xde, 0x14, 0xe2, 0xbf, 0x1c, 0x8e, - 0x6c, 0xb4, 0x5e, 0xe4, 0xcd, 0xc0, 0x92, 0xe3, 0x12, 0x47, 0xd6, 0x02, 0xdd, 0xe4, 0xfa, 0x06, - 0xba, 0x51, 0xe3, 0xc6, 0x0c, 0x0d, 0x1a, 0x37, 0xe6, 0x7d, 0x98, 0xd3, 0xdb, 0x26, 0xc2, 0xf7, - 0x46, 0x51, 0x73, 0x32, 0xbd, 0xa3, 0xe6, 0xf4, 0x0d, 0x12, 0x6a, 0xfc, 0x58, 0x06, 0x0a, 0x3a, - 0xef, 0x8f, 0x3a, 0x9e, 0xef, 0x68, 0xe3, 0xf9, 0x6c, 0xfa, 0x78, 0xf6, 0x1e, 0xc8, 0xff, 0x2b, - 0x13, 0x6f, 0xec, 0x40, 0x23, 0x68, 0xc0, 0x48, 0xc5, 0x6d, 0xd9, 0x4e, 0x5b, 0x4d, 0xfd, 0xdf, - 0x40, 0x88, 0x29, 0x4a, 0x06, 0x0b, 0x32, 0x74, 0x19, 0x86, 0xd7, 0xdc, 0x76, 0xa9, 0x22, 0x4c, - 0x8a, 0x91, 0x4f, 0xdb, 0x6d, 0x5b, 0x76, 0xc3, 0xe4, 0x05, 0x64, 0x15, 0xa0, 0x56, 0xf7, 0x28, - 0x6d, 0xd7, 0x9c, 0xef, 0xa6, 0x31, 0x49, 0x83, 0xf5, 0x50, 0xb3, 0x8b, 0x1b, 0x0b, 0x7f, 0x3a, - 0x45, 0x44, 0xcb, 0x77, 0xbe, 0x5b, 0xdd, 0x6f, 0x15, 0x7a, 0x5c, 0x57, 0x22, 0x0e, 0x5b, 0x6c, - 0x1c, 0x6e, 0x7e, 0x1c, 0xeb, 0x2a, 0xb5, 0x2a, 0xec, 0xe1, 0x9b, 0xa9, 0xc3, 0xf1, 0x87, 0x19, - 0x78, 0xb6, 0x0f, 0xcd, 0x13, 0x18, 0x95, 0xbf, 0xec, 0x0e, 0xa7, 0x00, 0x11, 0x11, 0x66, 0x52, - 0x76, 0x1a, 0x01, 0xcf, 0xd5, 0x37, 0x29, 0x32, 0x29, 0x33, 0x80, 0x96, 0x49, 0x99, 0x01, 0xd8, - 0x59, 0xba, 0x42, 0x9d, 0xbd, 0x7d, 0x6e, 0x1e, 0x36, 0xc9, 0xf7, 0x86, 0x7d, 0x84, 0xa8, 0x67, - 0x29, 0xc7, 0x31, 0xfe, 0xf5, 0x30, 0x5c, 0x34, 0xe9, 0x9e, 0xc3, 0xee, 0x25, 0x5b, 0xbe, 0xd3, - 0xde, 0xd3, 0xe2, 0xee, 0x18, 0xb1, 0x95, 0x2b, 0x92, 0x54, 0x30, 0x48, 0x38, 0x13, 0xaf, 0x41, - 0x9e, 0x89, 0x21, 0xca, 0xe2, 0xc5, 0x37, 0x2e, 0x26, 0xac, 0x88, 0xc0, 0xce, 0xb2, 0x98, 0xbc, - 0x2a, 0xc4, 0x24, 0x25, 0x8d, 0x10, 0x13, 0x93, 0xbe, 0x73, 0x5c, 0x84, 0xda, 0x91, 0x1f, 0x50, - 0xbc, 0x22, 0x0b, 0x51, 0x29, 0xbc, 0xcb, 0x0c, 0xf5, 0xb8, 0xcb, 0x3c, 0x80, 0xb9, 0x52, 0x83, - 0x9f, 0x8e, 0x76, 0x73, 0xc3, 0x73, 0xda, 0x75, 0xa7, 0x63, 0x37, 0xe5, 0xfd, 0x1c, 0x7b, 0xd9, - 0x0e, 0xcb, 0xad, 0x4e, 0x88, 0x60, 0xa6, 0x92, 0xb1, 0x66, 0x54, 0xd6, 0x6a, 0x18, 0x9e, 0x46, - 0x3c, 0x5f, 0x62, 0x33, 0x1a, 0x6d, 0x1f, 0x5b, 0xe1, 0x9b, 0x61, 0x31, 0xde, 0xa2, 0xd0, 0x20, - 0x60, 0x73, 0xb5, 0x16, 0xb9, 0x54, 0xf3, 0x2c, 0x07, 0xdc, 0xb0, 0x20, 0x68, 0xfa, 0x68, 0x8a, - 0xa9, 0xe1, 0x45, 0x74, 0xb5, 0xda, 0x0a, 0xa3, 0xcb, 0x27, 0xe8, 0x7c, 0x7f, 0x5f, 0xa5, 0xe3, - 0x78, 0xe4, 0x06, 0x9b, 0x0a, 0x2d, 0x37, 0xa0, 0x38, 0x85, 0xc7, 0xa2, 0x3b, 0x97, 0x87, 0x50, - 0x7e, 0xe7, 0x52, 0x50, 0xc8, 0xdb, 0x30, 0xbb, 0x5c, 0x5e, 0x94, 0x4a, 0xe7, 0x8a, 0x5b, 0xef, - 0xa2, 0x21, 0x00, 0x60, 0x7d, 0x38, 0x86, 0xb4, 0xbe, 0xc8, 0x76, 0x93, 0x34, 0x34, 0x72, 0x05, - 0x46, 0xab, 0x15, 0xde, 0xf7, 0xe3, 0x6a, 0x2a, 0x2f, 0x61, 0x99, 0x25, 0x0b, 0xc9, 0x7a, 0x74, - 0x29, 0x98, 0x38, 0x55, 0x7a, 0xbf, 0x38, 0xc0, 0x85, 0xe0, 0x4d, 0x98, 0x5c, 0x72, 0x83, 0x6a, - 0xdb, 0x0f, 0xec, 0x76, 0x9d, 0x56, 0x2b, 0x6a, 0x5c, 0xed, 0x1d, 0x37, 0xb0, 0x1c, 0x51, 0xc2, - 0xbe, 0x5c, 0xc7, 0x24, 0x9f, 0x43, 0xd2, 0xbb, 0xb4, 0x4d, 0xbd, 0x28, 0x9e, 0xf6, 0x30, 0xef, - 0x5b, 0x46, 0xba, 0x17, 0x96, 0x98, 0x3a, 0xa2, 0x48, 0x33, 0xc6, 0x93, 0x83, 0x96, 0xdd, 0x06, - 0xf5, 0xf9, 0x6e, 0xf1, 0x09, 0x4a, 0x33, 0xa6, 0xb4, 0xad, 0xcf, 0x0e, 0xfa, 0xef, 0x63, 0x9a, - 0xb1, 0x04, 0x2e, 0xf9, 0x1c, 0x0c, 0xe3, 0x4f, 0x21, 0xdd, 0xce, 0xa6, 0xb0, 0x8d, 0x24, 0xdb, - 0x3a, 0xc3, 0x34, 0x39, 0x01, 0xa9, 0xc2, 0xa8, 0xb8, 0x58, 0x9d, 0x25, 0x59, 0x8e, 0xb8, 0xa1, - 0xf1, 0x99, 0x21, 0xe8, 0x8d, 0x06, 0x4c, 0xa8, 0x15, 0xb2, 0x15, 0xb1, 0x62, 0xfb, 0xfb, 0xb4, - 0xc1, 0x7e, 0x89, 0x3c, 0x77, 0xb8, 0x22, 0xf6, 0x11, 0x6a, 0xb1, 0xef, 0x30, 0x15, 0x14, 0x76, - 0xa6, 0x56, 0xfd, 0x2d, 0x5f, 0x7c, 0x8a, 0x50, 0xb5, 0x38, 0xa8, 0xb6, 0x6b, 0x98, 0xa2, 0xc8, - 0xf8, 0x2e, 0x98, 0x5b, 0xeb, 0x36, 0x9b, 0xf6, 0x4e, 0x93, 0xca, 0x3c, 0x28, 0x98, 0x70, 0x7c, - 0x09, 0x86, 0x6b, 0x4a, 0x0a, 0xf3, 0x30, 0x17, 0xa5, 0x82, 0x83, 0x46, 0xb0, 0x19, 0x0c, 0x15, - 0x14, 0x4b, 0x5e, 0xce, 0x49, 0x8d, 0xdf, 0xcf, 0xc0, 0x9c, 0x34, 0x17, 0xf0, 0xec, 0xfa, 0x41, - 0x98, 0xc7, 0xfe, 0x8a, 0x36, 0xd7, 0x70, 0xc2, 0xc6, 0xa6, 0x11, 0x9f, 0x75, 0xf7, 0xe4, 0x47, - 0xe8, 0x02, 0x4b, 0xda, 0x07, 0x9f, 0xf6, 0x31, 0xe4, 0x6d, 0x18, 0x17, 0xc7, 0xa3, 0x12, 0xe0, - 0x12, 0xa3, 0x88, 0x89, 0xeb, 0x5e, 0xdc, 0x78, 0x45, 0x45, 0x47, 0x59, 0x4c, 0x6f, 0xca, 0x47, - 0x95, 0x01, 0xd2, 0x65, 0x31, 0xbd, 0x8e, 0x3e, 0x53, 0xf7, 0xb7, 0xc7, 0xe3, 0x7d, 0x2b, 0xe6, - 0xee, 0x6d, 0x35, 0xa4, 0x5d, 0x26, 0xba, 0x19, 0x47, 0x21, 0xed, 0xd4, 0x9b, 0x71, 0x88, 0x1a, - 0x8e, 0x49, 0xf6, 0x94, 0x31, 0x79, 0x57, 0x8e, 0x49, 0xae, 0xf7, 0xc4, 0x98, 0xed, 0x33, 0x0e, - 0xb5, 0x68, 0x85, 0x0c, 0x0d, 0xa4, 0x56, 0x79, 0x06, 0x63, 0xf7, 0x73, 0x92, 0xf8, 0x2e, 0x2a, - 0x38, 0xa9, 0xba, 0x9a, 0xe1, 0xc1, 0x99, 0x9e, 0xb2, 0x35, 0x7f, 0x1e, 0x26, 0x4a, 0x41, 0x60, - 0xd7, 0xf7, 0x69, 0xa3, 0xc2, 0xb6, 0x27, 0x25, 0xfa, 0x96, 0x2d, 0xe0, 0xea, 0x1b, 0x9b, 0x8a, - 0xcb, 0xa3, 0xc9, 0xda, 0xbe, 0x30, 0xa6, 0x0d, 0xa3, 0xc9, 0x32, 0x88, 0x1e, 0x4d, 0x96, 0x41, - 0xc8, 0x0d, 0x18, 0xad, 0xb6, 0x1f, 0x39, 0xac, 0x4f, 0x78, 0x00, 0x2e, 0xd4, 0x4d, 0x39, 0x1c, - 0xa4, 0x6e, 0xae, 0x02, 0x8b, 0xbc, 0xa9, 0x5c, 0x6a, 0xc6, 0x22, 0x05, 0x06, 0x57, 0x79, 0x85, - 0x11, 0x76, 0xd4, 0x0b, 0x4b, 0x78, 0xcb, 0xb9, 0x0d, 0xa3, 0x52, 0x93, 0x09, 0x91, 0xd2, 0x42, - 0x50, 0x26, 0x03, 0x56, 0x48, 0x64, 0xcc, 0x49, 0xae, 0xe4, 0xeb, 0x1b, 0x57, 0x72, 0x92, 0x2b, - 0xf9, 0xfa, 0xb4, 0x9c, 0xe4, 0x4a, 0xe6, 0xbe, 0x50, 0x09, 0x34, 0x71, 0xaa, 0x12, 0xe8, 0x21, - 0x4c, 0x6c, 0xd8, 0x5e, 0xe0, 0x30, 0x19, 0xa5, 0x1d, 0xf8, 0xf3, 0x93, 0x9a, 0xde, 0x54, 0x29, - 0x5a, 0xba, 0x24, 0xf3, 0x62, 0x77, 0x14, 0x7c, 0x3d, 0x81, 0x73, 0x04, 0x4f, 0x37, 0xa5, 0x9d, - 0xfa, 0x28, 0xa6, 0xb4, 0xd8, 0xa9, 0xa8, 0x2b, 0x9b, 0x8e, 0x34, 0x32, 0x78, 0x69, 0x89, 0x29, - 0xcc, 0x42, 0x44, 0xf2, 0x15, 0x98, 0x60, 0x7f, 0x6f, 0xb8, 0x4d, 0xa7, 0xee, 0x50, 0x7f, 0xbe, - 0x80, 0x8d, 0xbb, 0x94, 0xba, 0xfa, 0x11, 0xe9, 0xa8, 0x46, 0x03, 0xbe, 0x80, 0x91, 0x71, 0x5c, - 0x09, 0xae, 0x71, 0x23, 0xef, 0xc1, 0x04, 0x9b, 0x7d, 0x3b, 0xb6, 0xcf, 0x45, 0xd3, 0x99, 0xc8, - 0x18, 0xba, 0x21, 0xe0, 0x89, 0x80, 0xce, 0x2a, 0x01, 0x3b, 0xe6, 0x4b, 0x1d, 0xbe, 0x41, 0x12, - 0x65, 0xb6, 0x77, 0x12, 0x9b, 0xa3, 0x44, 0x23, 0x5f, 0x80, 0x89, 0x52, 0xa7, 0x13, 0xed, 0x38, - 0xb3, 0x8a, 0x22, 0xac, 0xd3, 0xb1, 0x52, 0x77, 0x1d, 0x8d, 0x22, 0xbe, 0x31, 0xcf, 0x9d, 0x69, - 0x63, 0x26, 0xaf, 0x87, 0xd2, 0xfa, 0xb9, 0x48, 0xab, 0x2b, 0x2e, 0x8e, 0x9a, 0xe8, 0xcf, 0x05, - 0xf7, 0x32, 0x4c, 0x72, 0x35, 0xa7, 0x94, 0x66, 0xce, 0x27, 0x56, 0x4f, 0x8a, 0x50, 0xa3, 0xd3, - 0x90, 0x65, 0x98, 0xe2, 0xde, 0xde, 0x4d, 0x11, 0x69, 0x7b, 0xfe, 0x02, 0xae, 0x5a, 0xe4, 0xc2, - 0x9d, 0xc4, 0x9b, 0x98, 0x80, 0xc5, 0xd6, 0xb8, 0xc4, 0x88, 0x8c, 0x3f, 0xcd, 0xc0, 0x85, 0x1e, - 0x23, 0x1e, 0xc6, 0x61, 0xce, 0xf4, 0x8f, 0xc3, 0xcc, 0x76, 0x0e, 0x5d, 0x2b, 0x82, 0xed, 0x17, - 0x52, 0x96, 0x3a, 0x5e, 0x52, 0xde, 0x72, 0x81, 0x88, 0x1c, 0x47, 0xa2, 0xea, 0x7b, 0x2e, 0xaa, - 0x66, 0x73, 0xc9, 0x43, 0x48, 0xe0, 0xf1, 0x8f, 0x5a, 0x32, 0x4e, 0x8e, 0x8b, 0x97, 0x44, 0x0a, - 0xa5, 0x70, 0x58, 0x3f, 0x70, 0xb5, 0x15, 0x9c, 0xc2, 0xda, 0x38, 0xce, 0xc0, 0xb8, 0xb2, 0x0e, - 0xc9, 0x65, 0xc5, 0x0b, 0xb9, 0xc0, 0x93, 0x70, 0x29, 0x1c, 0xb2, 0xfc, 0x24, 0xc2, 0x45, 0x95, - 0x3d, 0x5d, 0x01, 0xfd, 0x80, 0x89, 0x42, 0x4a, 0xac, 0xea, 0x96, 0xa6, 0x2d, 0x36, 0xb1, 0x1c, - 0xd3, 0xf9, 0xdb, 0x7e, 0x50, 0xaa, 0x07, 0xce, 0x23, 0x3a, 0xc0, 0xa1, 0x13, 0xa5, 0xf3, 0xb7, - 0xfd, 0xc0, 0xb2, 0x91, 0x2c, 0x91, 0xce, 0x3f, 0x64, 0x68, 0x7c, 0x7f, 0x06, 0x60, 0xab, 0x5a, - 0xc6, 0x60, 0xf3, 0x1f, 0x55, 0x28, 0x48, 0x0f, 0xe0, 0x2b, 0xb9, 0xf7, 0x11, 0x07, 0xfe, 0xa7, - 0x0c, 0x4c, 0xe9, 0x68, 0xe4, 0x5d, 0x98, 0xae, 0xd5, 0x3d, 0xb7, 0xd9, 0xdc, 0xb1, 0xeb, 0x07, - 0xab, 0x4e, 0x9b, 0xf2, 0xd0, 0xa9, 0xc3, 0xfc, 0x2c, 0xf2, 0xc3, 0x22, 0xab, 0xc9, 0xca, 0xcc, - 0x38, 0x32, 0xf9, 0x81, 0x0c, 0x4c, 0xd6, 0xf6, 0xdd, 0xc3, 0x30, 0xda, 0xa9, 0x18, 0x90, 0xaf, - 0xb2, 0xb5, 0xed, 0xef, 0xbb, 0x87, 0x51, 0x06, 0x4f, 0xcd, 0x56, 0xf4, 0x9d, 0xc1, 0x9e, 0xf1, - 0xeb, 0x2e, 0xde, 0x64, 0x02, 0xff, 0xba, 0x56, 0x89, 0xa9, 0xd7, 0x69, 0xfc, 0x45, 0x06, 0xc6, - 0xf1, 0xce, 0xd3, 0x6c, 0xa2, 0xcc, 0xf5, 0x49, 0x4a, 0x07, 0x19, 0xb6, 0xab, 0xcf, 0xc0, 0xbe, - 0x01, 0xd3, 0x31, 0x34, 0x62, 0xc0, 0x48, 0x0d, 0x03, 0x0c, 0xa8, 0x0a, 0x0a, 0x1e, 0x72, 0xc0, - 0x14, 0x25, 0xc6, 0xb2, 0x42, 0xf6, 0xf0, 0x26, 0x3e, 0xeb, 0x2e, 0x02, 0x38, 0x12, 0x24, 0x6f, - 0x36, 0x24, 0xfe, 0x25, 0x0f, 0x6f, 0x9a, 0x0a, 0x96, 0xb1, 0x06, 0x23, 0x35, 0xd7, 0x0b, 0x96, - 0x8e, 0xf8, 0x65, 0xa2, 0x42, 0xfd, 0xba, 0xfa, 0x6e, 0xeb, 0xe0, 0x5b, 0x49, 0xdd, 0x14, 0x45, - 0xa4, 0x08, 0xc3, 0x77, 0x1c, 0xda, 0x6c, 0xa8, 0xf6, 0xbc, 0xbb, 0x0c, 0x60, 0x72, 0x38, 0xbb, - 0x70, 0x9d, 0x8f, 0x72, 0xb2, 0x44, 0x86, 0xc3, 0x1f, 0x75, 0xdd, 0x94, 0xb5, 0xfe, 0x7d, 0x21, - 0xcc, 0x83, 0x90, 0xac, 0xa9, 0x4f, 0x57, 0xff, 0xe3, 0x0c, 0x2c, 0xf4, 0x26, 0x51, 0x6d, 0x91, - 0x33, 0x7d, 0x6c, 0x91, 0x5f, 0x8e, 0xbf, 0x33, 0x22, 0x9a, 0x78, 0x67, 0x8c, 0x5e, 0x17, 0x2b, - 0x68, 0x0a, 0x5e, 0xa7, 0x32, 0x11, 0xcb, 0xe5, 0x3e, 0xdf, 0x8c, 0x88, 0x7c, 0x98, 0x03, 0xa4, - 0x31, 0x05, 0xad, 0xf1, 0x5b, 0x43, 0x70, 0xb1, 0x27, 0x05, 0x59, 0x51, 0xd2, 0x3b, 0x4d, 0x85, - 0x89, 0x65, 0x7a, 0xe2, 0x5f, 0xc7, 0x7f, 0xd1, 0xda, 0x2f, 0xee, 0xed, 0xb6, 0x1e, 0xa6, 0xf5, - 0xc9, 0x22, 0xaf, 0x4f, 0x9d, 0xca, 0x8b, 0xa3, 0x23, 0x33, 0x48, 0x66, 0xf8, 0x41, 0xbf, 0x48, - 0x1a, 0xd8, 0x4e, 0xd3, 0x57, 0x97, 0x5d, 0x83, 0x83, 0x4c, 0x59, 0x16, 0x19, 0x88, 0x0f, 0xa5, - 0x1b, 0x88, 0x1b, 0xff, 0x3a, 0x03, 0x63, 0xe1, 0x67, 0x93, 0x05, 0x38, 0xbf, 0x69, 0x96, 0xca, - 0xcb, 0xd6, 0xe6, 0xfb, 0x1b, 0xcb, 0xd6, 0xd6, 0x5a, 0x6d, 0x63, 0xb9, 0x5c, 0xbd, 0x53, 0x5d, - 0xae, 0x14, 0x9e, 0x21, 0x33, 0x30, 0xb9, 0xb5, 0x76, 0x7f, 0x6d, 0x7d, 0x7b, 0xcd, 0x5a, 0x36, - 0xcd, 0x75, 0xb3, 0x90, 0x21, 0x93, 0x30, 0x66, 0x2e, 0x95, 0xca, 0xd6, 0xda, 0x7a, 0x65, 0xb9, - 0x90, 0x25, 0x05, 0x98, 0x28, 0xaf, 0xaf, 0xad, 0x2d, 0x97, 0x37, 0xab, 0x0f, 0xab, 0x9b, 0xef, - 0x17, 0x72, 0x84, 0xc0, 0x14, 0x22, 0x6c, 0x98, 0xd5, 0xb5, 0x72, 0x75, 0xa3, 0xb4, 0x5a, 0x18, - 0x62, 0x30, 0x86, 0xaf, 0xc0, 0x86, 0x43, 0x46, 0xf7, 0xb7, 0x96, 0x96, 0x0b, 0x23, 0x0c, 0x85, - 0xfd, 0xa5, 0xa0, 0x8c, 0xb2, 0xea, 0x11, 0xa5, 0x52, 0xda, 0x2c, 0x2d, 0x95, 0x6a, 0xcb, 0x85, - 0x3c, 0xb9, 0x00, 0xb3, 0x1a, 0xc8, 0x5a, 0x5d, 0xbf, 0x5b, 0x5d, 0x2b, 0x8c, 0x91, 0x39, 0x28, - 0x84, 0xb0, 0xca, 0x92, 0xb5, 0x55, 0x5b, 0x36, 0x0b, 0x10, 0x87, 0xae, 0x95, 0x1e, 0x2c, 0x17, - 0xc6, 0x8d, 0x77, 0xb8, 0x1f, 0x22, 0xef, 0x6a, 0x72, 0x1e, 0x48, 0x6d, 0xb3, 0xb4, 0xb9, 0x55, - 0x8b, 0x35, 0x7e, 0x1c, 0x46, 0x6b, 0x5b, 0xe5, 0xf2, 0x72, 0xad, 0x56, 0xc8, 0x10, 0x80, 0x91, - 0x3b, 0xa5, 0xea, 0xea, 0x72, 0xa5, 0x90, 0x35, 0x7e, 0x22, 0x03, 0x33, 0x52, 0x02, 0x94, 0x8f, - 0x46, 0x1f, 0x71, 0x2d, 0xbe, 0xab, 0x5d, 0x6c, 0xa5, 0x93, 0x58, 0xac, 0x92, 0x3e, 0xcb, 0xf0, - 0xe7, 0x33, 0x70, 0x2e, 0x15, 0x9b, 0xbc, 0x0f, 0x05, 0xf9, 0x05, 0x0f, 0xec, 0xa0, 0xbe, 0x1f, - 0xed, 0x63, 0x97, 0x62, 0xb5, 0xc4, 0xd0, 0xb8, 0x5a, 0x33, 0x4a, 0x38, 0x9d, 0x60, 0x33, 0x78, - 0x3a, 0x04, 0xe3, 0xe7, 0x32, 0x70, 0xa1, 0x47, 0x35, 0xa4, 0x0c, 0x23, 0x61, 0x62, 0x9c, 0x3e, - 0x06, 0x6f, 0x73, 0xdf, 0x3e, 0x2e, 0x0a, 0x44, 0xcc, 0xd0, 0x8b, 0x7f, 0x99, 0x23, 0x61, 0xa6, - 0x1b, 0x4c, 0x37, 0xc3, 0xbb, 0xef, 0x62, 0xac, 0xe7, 0x45, 0x4d, 0xa5, 0xed, 0xda, 0xd2, 0xb8, - 0xe8, 0xbb, 0x9c, 0x7d, 0xe8, 0x63, 0xbe, 0x19, 0xe3, 0xa7, 0x33, 0x4c, 0xb8, 0x8b, 0x23, 0x32, - 0x99, 0xb7, 0xe4, 0xfb, 0xdd, 0x16, 0x35, 0xdd, 0x26, 0x2d, 0x99, 0x6b, 0xe2, 0xd8, 0x40, 0x69, - 0xd5, 0xc6, 0x02, 0xbc, 0x56, 0x58, 0xb6, 0xd7, 0xd6, 0x5e, 0xab, 0x55, 0x1a, 0xf2, 0x26, 0xc0, - 0xf2, 0xe3, 0x80, 0x7a, 0x6d, 0xbb, 0x19, 0xc6, 0x88, 0xe1, 0x91, 0xad, 0x04, 0x54, 0x97, 0xb7, - 0x15, 0x64, 0xe3, 0x6f, 0x65, 0x60, 0x42, 0x5c, 0x9a, 0x4a, 0x4d, 0xea, 0x05, 0x1f, 0x6d, 0x7a, - 0xbd, 0xa9, 0x4d, 0xaf, 0xd0, 0xbf, 0x43, 0xe1, 0xcf, 0x8a, 0x53, 0x67, 0xd6, 0x3f, 0xcb, 0x40, - 0x21, 0x8e, 0x48, 0xde, 0x85, 0x7c, 0x8d, 0x3e, 0xa2, 0x9e, 0x13, 0x1c, 0x89, 0x8d, 0x52, 0xa6, - 0x10, 0xe4, 0x38, 0xa2, 0x8c, 0xcf, 0x07, 0x5f, 0xfc, 0x32, 0x43, 0x9a, 0x41, 0xf7, 0x7b, 0x45, - 0xed, 0x91, 0x7b, 0x52, 0x6a, 0x0f, 0xe3, 0x7f, 0xcb, 0xc2, 0x85, 0xbb, 0x34, 0x50, 0xdb, 0x14, - 0x9a, 0x17, 0x7c, 0x7a, 0xb0, 0x76, 0x29, 0x2d, 0x99, 0x87, 0x51, 0x2c, 0x92, 0xe3, 0x6b, 0xca, - 0x9f, 0x64, 0x29, 0x9c, 0xd7, 0x39, 0x2d, 0x47, 0x59, 0x8f, 0xba, 0xaf, 0x2b, 0x59, 0x8b, 0xc2, - 0x69, 0x7d, 0x05, 0xa6, 0x30, 0x2c, 0x7f, 0x97, 0x2d, 0x07, 0xda, 0x10, 0xea, 0x9f, 0xbc, 0x19, - 0x83, 0x92, 0x57, 0xa1, 0xc0, 0x20, 0xa5, 0xfa, 0x41, 0xdb, 0x3d, 0x6c, 0xd2, 0xc6, 0x1e, 0x6d, - 0xe0, 0xb1, 0x9e, 0x37, 0x13, 0x70, 0xc9, 0x73, 0xab, 0xcd, 0xaf, 0x6e, 0xb4, 0x81, 0x3a, 0x1a, - 0xc1, 0x33, 0x82, 0x2e, 0xbc, 0x09, 0xe3, 0x1f, 0x32, 0x03, 0x99, 0xf1, 0xbf, 0x66, 0x60, 0x0e, - 0x1b, 0xa7, 0x54, 0x2c, 0xb3, 0xc3, 0xca, 0xde, 0x52, 0x92, 0xf2, 0xd8, 0x0c, 0xa4, 0x2f, 0x85, - 0xb0, 0x17, 0x23, 0x9d, 0x50, 0x76, 0x00, 0x9d, 0x50, 0xed, 0x2c, 0x99, 0xf0, 0x07, 0x54, 0x69, - 0xdd, 0x1b, 0xca, 0xe7, 0x0a, 0x43, 0xd1, 0x90, 0x1b, 0x3f, 0x90, 0x85, 0x51, 0x93, 0x62, 0x8a, - 0x70, 0x72, 0x05, 0x46, 0xd7, 0xdc, 0x80, 0xfa, 0x0f, 0xb4, 0x7c, 0xf0, 0x6d, 0x06, 0xb2, 0x5a, - 0x0d, 0x53, 0x16, 0xb2, 0x09, 0xbf, 0xe1, 0xb9, 0x8d, 0x6e, 0x3d, 0x50, 0x27, 0x7c, 0x87, 0x83, - 0x4c, 0x59, 0x46, 0x5e, 0x83, 0x31, 0xc1, 0x39, 0x7c, 0xd4, 0x45, 0xdb, 0x65, 0x8f, 0x86, 0x29, - 0xe6, 0x23, 0x04, 0x94, 0x69, 0xb9, 0x80, 0x31, 0xa4, 0xc8, 0xb4, 0x09, 0x99, 0x41, 0x8a, 0xea, - 0xc3, 0x7d, 0x44, 0xf5, 0x4f, 0xc3, 0x48, 0xc9, 0xf7, 0x69, 0x20, 0xa3, 0x28, 0x4c, 0x84, 0x61, - 0xe3, 0x7c, 0x1a, 0x70, 0xc6, 0x36, 0x96, 0x9b, 0x02, 0xcf, 0xf8, 0x57, 0x59, 0x18, 0xc6, 0x3f, - 0xf1, 0xc9, 0xd4, 0xab, 0xef, 0x6b, 0x4f, 0xa6, 0x5e, 0x7d, 0xdf, 0x44, 0x28, 0xb9, 0x89, 0x9a, - 0x0a, 0x99, 0x3f, 0x4a, 0xb4, 0x1e, 0x55, 0xf0, 0x8d, 0x08, 0x6c, 0xaa, 0x38, 0xe1, 0x0b, 0x7f, - 0x2e, 0x35, 0x76, 0xca, 0x79, 0xc8, 0xae, 0xd7, 0x44, 0x8b, 0x31, 0x22, 0x97, 0xeb, 0x9b, 0xd9, - 0xf5, 0x1a, 0xf6, 0xc6, 0x4a, 0x69, 0xf1, 0x8d, 0xdb, 0xa2, 0xa1, 0xbc, 0x37, 0xf6, 0xed, 0xc5, - 0x37, 0x6e, 0x9b, 0xa2, 0x84, 0xf5, 0x2f, 0x7e, 0x33, 0x3e, 0xbc, 0x72, 0x9f, 0x7f, 0xec, 0x5f, - 0x6c, 0x1b, 0x3e, 0xb2, 0x9a, 0x11, 0x02, 0x59, 0x84, 0x71, 0x11, 0x6b, 0x02, 0xf1, 0x95, 0x58, - 0x10, 0x22, 0x16, 0x05, 0xa7, 0x50, 0x91, 0xf8, 0x13, 0x9c, 0x18, 0x20, 0x99, 0xe5, 0x56, 0x3c, - 0xc1, 0xc9, 0x21, 0xf4, 0x4d, 0x05, 0x85, 0x7d, 0x12, 0x7f, 0xc3, 0x8b, 0x7c, 0xf9, 0xa7, 0x94, - 0xa0, 0x05, 0x98, 0x66, 0x21, 0x44, 0x30, 0x7e, 0x39, 0x0b, 0xf9, 0x8d, 0x66, 0x77, 0xcf, 0x69, - 0x3f, 0xbc, 0x49, 0x08, 0xe0, 0x35, 0x4e, 0xe6, 0xe1, 0x60, 0x7f, 0x93, 0x8b, 0x90, 0x97, 0x37, - 0x37, 0xb9, 0x21, 0xf9, 0xe2, 0xd6, 0x36, 0x0f, 0x72, 0xdc, 0x45, 0xe8, 0x35, 0xf9, 0x93, 0xdc, - 0x84, 0xf0, 0xfe, 0xd5, 0xeb, 0xa2, 0x36, 0xc4, 0x16, 0x8b, 0x19, 0xa2, 0x91, 0xd7, 0x01, 0x0f, - 0x09, 0x71, 0x79, 0x90, 0x0a, 0x6d, 0xfe, 0x69, 0x42, 0x4e, 0xe1, 0x24, 0x88, 0x46, 0x6e, 0x81, - 0x98, 0x98, 0x22, 0x9b, 0xfa, 0x39, 0x9d, 0x80, 0xe7, 0xa7, 0x94, 0x24, 0x02, 0x95, 0xbc, 0x0d, - 0xe3, 0x75, 0x8f, 0xe2, 0xab, 0xa3, 0xdd, 0x8c, 0x92, 0xa4, 0xab, 0x94, 0xe5, 0xa8, 0xfc, 0xe1, - 0x4d, 0x53, 0x45, 0x37, 0x7e, 0x39, 0x0f, 0x13, 0xea, 0xf7, 0x10, 0x13, 0x66, 0xfd, 0x26, 0xbb, - 0xbb, 0x0b, 0x63, 0xb3, 0x0e, 0x16, 0x8a, 0xe3, 0xf4, 0xb2, 0xfe, 0x41, 0x0c, 0x8f, 0x5b, 0x9e, - 0xc9, 0x20, 0x19, 0x2b, 0xcf, 0x98, 0x33, 0x7e, 0x04, 0xe6, 0x78, 0xa4, 0x04, 0x79, 0xb7, 0xe3, - 0xef, 0xd1, 0xb6, 0x23, 0xdf, 0x5b, 0x5e, 0xd4, 0x18, 0xad, 0x8b, 0xc2, 0x04, 0xaf, 0x90, 0x8c, - 0xbc, 0x01, 0x23, 0x6e, 0x87, 0xb6, 0x6d, 0x47, 0x9c, 0x71, 0xcf, 0xc6, 0x18, 0xd0, 0x76, 0xa9, - 0xaa, 0x10, 0x0a, 0x64, 0x72, 0x03, 0x86, 0xdc, 0x83, 0x70, 0xbc, 0x2e, 0xea, 0x44, 0x07, 0x81, - 0xad, 0x90, 0x20, 0x22, 0x23, 0xf8, 0xc0, 0x6e, 0xed, 0x8a, 0x11, 0xd3, 0x09, 0xee, 0xd9, 0xad, - 0x5d, 0x95, 0x80, 0x21, 0x92, 0xf7, 0x00, 0x3a, 0xf6, 0x1e, 0xf5, 0xac, 0x46, 0x37, 0x38, 0x12, - 0xe3, 0x76, 0x49, 0x23, 0xdb, 0x60, 0xc5, 0x95, 0x6e, 0x70, 0xa4, 0xd0, 0x8e, 0x75, 0x24, 0x90, - 0x94, 0x00, 0x5a, 0x76, 0x10, 0x50, 0xaf, 0xe5, 0x0a, 0x6b, 0xbf, 0x28, 0x08, 0x22, 0x67, 0xf0, - 0x20, 0x2c, 0x56, 0x38, 0x28, 0x44, 0xf8, 0xd1, 0x8e, 0x67, 0x8b, 0x9c, 0xf6, 0xb1, 0x8f, 0x76, - 0x3c, 0xad, 0x95, 0x0c, 0x91, 0x7c, 0x0e, 0x46, 0x1b, 0x8e, 0x5f, 0x77, 0xbd, 0x86, 0x88, 0x9e, - 0xf2, 0x9c, 0x46, 0x53, 0xe1, 0x65, 0x0a, 0x99, 0x44, 0x67, 0x5f, 0x2b, 0x82, 0xa0, 0xae, 0xb9, - 0x87, 0xa8, 0xe6, 0x8f, 0x7f, 0x6d, 0x2d, 0x2c, 0x56, 0xbf, 0x36, 0x22, 0x62, 0x43, 0xb9, 0xe7, - 0x04, 0x4d, 0x7b, 0x47, 0xbc, 0x73, 0xeb, 0x43, 0x79, 0x17, 0x8b, 0xd4, 0xa1, 0xe4, 0xc8, 0xe4, - 0x4d, 0xc8, 0xd3, 0x76, 0xe0, 0xd9, 0x96, 0xd3, 0x10, 0x4e, 0x95, 0xfa, 0x47, 0xb3, 0x03, 0xd8, - 0xae, 0x56, 0xd4, 0x8f, 0x46, 0xfc, 0x6a, 0x83, 0xf5, 0x8f, 0x5f, 0x77, 0x5a, 0xc2, 0x17, 0x52, - 0xef, 0x9f, 0x5a, 0xb9, 0xfa, 0x40, 0xed, 0x1f, 0x86, 0x48, 0xde, 0x85, 0x51, 0xb6, 0x7e, 0x1b, - 0xee, 0x9e, 0x08, 0x48, 0x61, 0xe8, 0xfd, 0xc3, 0xcb, 0x12, 0xd3, 0x55, 0x12, 0xb1, 0x85, 0x6c, - 0x1f, 0xfa, 0x96, 0x53, 0x17, 0x41, 0x26, 0xf4, 0xe5, 0x58, 0xda, 0xae, 0x55, 0xcb, 0x0a, 0xd9, - 0xb0, 0x7d, 0xe8, 0x57, 0xeb, 0x64, 0x11, 0x86, 0x31, 0x45, 0x85, 0x08, 0x84, 0xa9, 0xd3, 0x60, - 0x72, 0x0a, 0x95, 0x06, 0x51, 0xd9, 0x40, 0xb6, 0x7c, 0x74, 0x2f, 0x11, 0x89, 0x22, 0xf4, 0x3e, - 0x79, 0x50, 0x43, 0x9f, 0x13, 0xf5, 0x13, 0x05, 0x3a, 0xb9, 0x04, 0x10, 0xbd, 0xe2, 0xf3, 0x37, - 0x17, 0x53, 0x81, 0x7c, 0x7e, 0xe8, 0xff, 0xfc, 0xc5, 0x62, 0x66, 0x09, 0x20, 0x2f, 0x23, 0xe4, - 0x18, 0xab, 0x70, 0xb1, 0xe7, 0xba, 0x27, 0xd7, 0xa0, 0xb0, 0x6b, 0x0b, 0xad, 0x5f, 0x7d, 0xdf, - 0x6e, 0xb7, 0x69, 0x53, 0xec, 0xb8, 0xd3, 0x12, 0x5e, 0xe6, 0x60, 0xce, 0xd9, 0x78, 0x0f, 0xe6, - 0xd2, 0x06, 0x9c, 0xbc, 0x00, 0x13, 0x6a, 0x30, 0x20, 0xc1, 0x64, 0xdc, 0xee, 0x38, 0x32, 0x1c, - 0x90, 0x60, 0xf0, 0x9b, 0x19, 0x78, 0xae, 0xdf, 0xf6, 0x41, 0x16, 0x20, 0xdf, 0xf1, 0x1c, 0x17, - 0xc5, 0x54, 0x91, 0x6d, 0x41, 0xfe, 0xc6, 0x44, 0x0a, 0x28, 0x4f, 0x05, 0xf6, 0x9e, 0x70, 0xf0, - 0x30, 0xc7, 0x10, 0xb2, 0x69, 0xff, 0xff, 0xec, 0x7d, 0x4b, 0x8c, 0x1b, 0xd9, 0x75, 0xa8, 0x8a, - 0x64, 0x77, 0xb3, 0x0f, 0xfb, 0x53, 0x7d, 0xf5, 0xe9, 0x1e, 0x7d, 0x47, 0x35, 0x1a, 0x59, 0xe2, - 0x78, 0xc6, 0x96, 0xe6, 0x8d, 0x67, 0x64, 0x7b, 0x6c, 0x57, 0xb3, 0xab, 0x9b, 0x94, 0xf8, 0x73, - 0x15, 0xd9, 0xb2, 0x2c, 0xdb, 0xe5, 0x12, 0x59, 0xdd, 0x5d, 0x36, 0x9b, 0x45, 0xb3, 0xc8, 0x91, - 0x65, 0x3c, 0xe0, 0xd9, 0x78, 0x88, 0x0d, 0xe4, 0xe7, 0xc4, 0x49, 0x90, 0x41, 0x36, 0x5e, 0xc4, - 0x08, 0xb2, 0xf0, 0x36, 0x48, 0x90, 0xac, 0xbc, 0x33, 0x60, 0x18, 0x30, 0x90, 0x9d, 0x13, 0x4c, - 0x92, 0x01, 0x12, 0x20, 0x9f, 0x5d, 0x90, 0x2c, 0xbc, 0x0a, 0xee, 0xb9, 0xf7, 0x56, 0xdd, 0xfa, - 0x90, 0x6a, 0x79, 0xc6, 0x49, 0x0c, 0x78, 0xd5, 0xcd, 0x73, 0xcf, 0x39, 0x75, 0xff, 0xf7, 0xdc, - 0x73, 0xcf, 0xe7, 0x30, 0x20, 0x2f, 0xc1, 0x46, 0xdf, 0x3d, 0x70, 0xa6, 0x83, 0x89, 0x1d, 0xf4, - 0x8e, 0xdc, 0x3e, 0xba, 0x60, 0xa1, 0xe1, 0x9e, 0xa9, 0xf2, 0x02, 0x4b, 0xc0, 0x53, 0x35, 0x5e, - 0x98, 0x51, 0xe3, 0xbb, 0x85, 0xa2, 0xa2, 0xe6, 0x4c, 0xb4, 0x94, 0xd2, 0xbe, 0x9e, 0x83, 0xad, - 0x59, 0xeb, 0x85, 0xbc, 0x99, 0xd5, 0x07, 0xec, 0xe1, 0x42, 0x86, 0xcb, 0x0f, 0x17, 0xd2, 0xd7, - 0xc8, 0x6d, 0x08, 0x1d, 0xa8, 0x9e, 0x16, 0x0c, 0x41, 0xc0, 0x28, 0xcd, 0xc8, 0x09, 0x82, 0xc7, - 0x74, 0x4b, 0xc8, 0x4b, 0x01, 0x75, 0x39, 0x4c, 0xa6, 0x11, 0x30, 0xf2, 0x3a, 0x40, 0x6f, 0xe0, - 0x07, 0x2e, 0xda, 0x07, 0x70, 0x59, 0x83, 0x99, 0x85, 0x87, 0x50, 0xf9, 0x41, 0x18, 0xa1, 0x15, - 0xbf, 0xef, 0xf2, 0x01, 0x74, 0x60, 0x73, 0xc6, 0x06, 0x49, 0x87, 0x27, 0xca, 0x4e, 0x2f, 0x72, - 0x5d, 0x4d, 0xc3, 0x1c, 0xf5, 0xc9, 0x1e, 0xcf, 0xcd, 0x9a, 0x23, 0x4f, 0x80, 0xa4, 0x77, 0x41, - 0xca, 0x9d, 0x1b, 0x37, 0x4f, 0xc7, 0x21, 0x77, 0x06, 0xe9, 0x8e, 0x07, 0xe4, 0x0a, 0x94, 0x44, - 0x2e, 0x4b, 0x2a, 0xcb, 0x33, 0xe6, 0xc0, 0x41, 0xf7, 0x5c, 0x9c, 0x3c, 0x18, 0x31, 0x15, 0xdd, - 0xe4, 0xb8, 0x94, 0xb0, 0x8c, 0x90, 0xce, 0x93, 0x91, 0x68, 0xdd, 0x45, 0x31, 0xbf, 0xe3, 0x67, - 0x13, 0x2f, 0xfd, 0x03, 0x45, 0x0c, 0x7f, 0x7a, 0x73, 0x7f, 0x5a, 0xfd, 0x08, 0xa0, 0x97, 0x12, - 0xaf, 0x18, 0xfe, 0x4f, 0xa5, 0x16, 0xb1, 0xea, 0xb8, 0xd4, 0xc2, 0x7f, 0x92, 0xeb, 0xb0, 0x3e, - 0x66, 0x76, 0xac, 0x13, 0x9f, 0xf7, 0x27, 0xcb, 0x1b, 0xb2, 0xca, 0xc0, 0x1d, 0x1f, 0xfb, 0x94, - 0xd7, 0xeb, 0x6e, 0xd8, 0x61, 0xd2, 0x59, 0x47, 0x5e, 0x81, 0x65, 0x7a, 0xd6, 0x61, 0xa4, 0x9d, - 0x84, 0x7b, 0x04, 0xe2, 0xa1, 0xe4, 0x60, 0x16, 0xbf, 0xc4, 0xff, 0xe7, 0xbc, 0xde, 0xce, 0x09, - 0x66, 0xf2, 0x49, 0x4b, 0x36, 0x61, 0xc9, 0x1f, 0x1f, 0x4a, 0x4d, 0x5b, 0xf4, 0xc7, 0x87, 0xb4, - 0x5d, 0x37, 0x40, 0x65, 0xde, 0x3a, 0x2c, 0x6a, 0x42, 0xf0, 0x64, 0xc8, 0xae, 0xe2, 0x45, 0x73, - 0x8d, 0xc1, 0x31, 0x61, 0xff, 0x93, 0x61, 0x8f, 0x62, 0x06, 0x81, 0x6f, 0xcb, 0x01, 0xb6, 0x78, - 0xb3, 0xd7, 0x82, 0xc0, 0x8f, 0x22, 0x6d, 0xf5, 0xc9, 0x36, 0xac, 0x52, 0x3e, 0x61, 0x98, 0x2f, - 0x2e, 0x08, 0x5c, 0x4a, 0x0b, 0x02, 0x4f, 0x86, 0x3d, 0x51, 0x45, 0x73, 0x25, 0x90, 0x7e, 0x91, - 0x7b, 0xa0, 0x4a, 0x12, 0x13, 0xba, 0x6f, 0x26, 0x6c, 0xaa, 0x23, 0x36, 0x92, 0xa4, 0x55, 0x1b, - 0x1e, 0xf8, 0xe6, 0x7a, 0x2f, 0x0e, 0xe0, 0x5d, 0xf3, 0x5d, 0x45, 0xec, 0xa5, 0x19, 0x44, 0x44, - 0x83, 0xd5, 0x23, 0x27, 0xb0, 0x83, 0xe0, 0x98, 0xd9, 0x88, 0xf1, 0xc0, 0xc2, 0xa5, 0x23, 0x27, - 0xb0, 0x82, 0x63, 0x91, 0xb8, 0xe4, 0x2c, 0xc5, 0xf1, 0x9d, 0xe9, 0xe4, 0xc8, 0x96, 0xe5, 0x3f, - 0xd6, 0x63, 0xa7, 0x8f, 0x9c, 0xa0, 0x45, 0xcb, 0x24, 0xde, 0xe4, 0x1a, 0xac, 0x21, 0xdf, 0x9e, - 0x27, 0x18, 0x63, 0xe4, 0x0b, 0x73, 0x85, 0x32, 0xee, 0x79, 0x8c, 0x33, 0xaf, 0xe1, 0x3f, 0xe7, - 0xe0, 0x5c, 0x76, 0xef, 0xe0, 0xf4, 0xa4, 0x7d, 0x8a, 0x3e, 0x7a, 0xbc, 0x6e, 0xcb, 0x14, 0xc2, - 0xa2, 0x96, 0x64, 0x0d, 0x4e, 0x2e, 0x73, 0x70, 0xca, 0xb0, 0x81, 0x8c, 0xb8, 0xa4, 0x39, 0xf0, - 0x82, 0x09, 0x0f, 0xc6, 0x61, 0xae, 0xd3, 0x02, 0xb6, 0x9f, 0xd7, 0x29, 0x98, 0xbc, 0x08, 0x6b, - 0x62, 0x47, 0xf6, 0x1f, 0x0f, 0xe9, 0x87, 0xd9, 0x76, 0xbc, 0xca, 0xa1, 0x2d, 0x04, 0x92, 0xb3, - 0xb0, 0xe8, 0x8c, 0x46, 0xf4, 0x93, 0x6c, 0x17, 0x5e, 0x70, 0x46, 0x23, 0x96, 0x5c, 0x07, 0x3d, - 0x12, 0xed, 0x03, 0xb4, 0x12, 0xe2, 0x26, 0x89, 0xe6, 0x0a, 0x02, 0x99, 0xe5, 0x50, 0x40, 0xd7, - 0x3d, 0xa5, 0x15, 0x28, 0x4b, 0x88, 0x02, 0xce, 0x28, 0x44, 0x78, 0x0e, 0x8a, 0xe2, 0xbd, 0x9a, - 0x39, 0x56, 0x98, 0x4b, 0x0e, 0x7f, 0xab, 0x7e, 0x0d, 0x36, 0xfb, 0x5e, 0x80, 0x93, 0x97, 0x35, - 0x69, 0x34, 0xe2, 0x3e, 0x90, 0x2c, 0x48, 0xaf, 0x79, 0x86, 0x17, 0xd3, 0x9e, 0xd4, 0x47, 0x23, - 0xe6, 0x09, 0xc9, 0xfb, 0xfa, 0x0d, 0x58, 0xe7, 0x12, 0x17, 0x3f, 0x22, 0xb1, 0x2e, 0x7c, 0x01, - 0xd3, 0xab, 0x10, 0x4f, 0x67, 0x04, 0x1c, 0x54, 0xeb, 0x0b, 0xca, 0xbf, 0x55, 0xe0, 0x6c, 0xa6, - 0xc8, 0x46, 0xbe, 0x08, 0xcc, 0xe5, 0x6b, 0xe2, 0xdb, 0x63, 0xb7, 0xe7, 0x8d, 0x3c, 0x8c, 0xa1, - 0xc1, 0x54, 0x9a, 0xb7, 0xe7, 0x09, 0x7b, 0xe8, 0x3e, 0xd6, 0xf1, 0xcd, 0x90, 0x88, 0xe9, 0x5a, - 0xd4, 0x71, 0x02, 0x7c, 0xfe, 0x21, 0x9c, 0xcd, 0x44, 0xcd, 0xd0, 0x81, 0x7c, 0x30, 0x9e, 0x4c, - 0x5a, 0x3c, 0x52, 0x25, 0x1a, 0x2d, 0xe9, 0x46, 0x78, 0xf3, 0x7e, 0x10, 0x36, 0x2f, 0x21, 0xdc, - 0x11, 0x23, 0xb9, 0xae, 0xb3, 0xee, 0x27, 0x82, 0x68, 0xf6, 0xd2, 0x7e, 0x08, 0x67, 0xf9, 0xe4, - 0x3b, 0x1c, 0x3b, 0xa3, 0xa3, 0x88, 0x1d, 0xab, 0xe8, 0x07, 0xb2, 0xd8, 0xb1, 0x59, 0xb9, 0x47, - 0xf1, 0x43, 0xae, 0xa7, 0x9d, 0x34, 0x90, 0xb7, 0xe1, 0x1b, 0x39, 0xb1, 0xd4, 0x33, 0xaa, 0x93, - 0x31, 0xad, 0x95, 0xac, 0x69, 0x7d, 0xf2, 0x35, 0xd5, 0x04, 0x22, 0x6f, 0x56, 0x4c, 0xeb, 0xc9, - 0x0d, 0xaa, 0x84, 0x9c, 0xce, 0x2b, 0x22, 0x6d, 0x0d, 0x16, 0x4b, 0xe6, 0xb9, 0xd1, 0x4b, 0x82, - 0xc8, 0x05, 0x58, 0x0e, 0xf3, 0x65, 0xf3, 0x83, 0xa3, 0xc8, 0x00, 0xb5, 0x3e, 0x79, 0x1e, 0x56, - 0x98, 0x48, 0x1e, 0x5b, 0x73, 0x80, 0x30, 0x9d, 0x2e, 0x3c, 0xd1, 0x07, 0x0a, 0x3c, 0xff, 0xb4, - 0x3e, 0x24, 0xf7, 0xe1, 0x1c, 0x9a, 0x75, 0x04, 0x7e, 0x38, 0x0c, 0x76, 0xcf, 0xe9, 0x1d, 0xb9, - 0x7c, 0xd6, 0x6a, 0x99, 0x83, 0x31, 0x1a, 0x59, 0x56, 0x4b, 0x1a, 0x87, 0xd1, 0xc8, 0x0a, 0x7c, - 0xf1, 0xbb, 0x42, 0xc9, 0x79, 0x1d, 0xfa, 0x70, 0x61, 0x0e, 0xa5, 0xb4, 0x71, 0x28, 0xf2, 0xc6, - 0x71, 0x03, 0xd4, 0x03, 0xb7, 0x4f, 0x65, 0x62, 0xb7, 0x8f, 0x55, 0x7b, 0xeb, 0x36, 0xcb, 0x10, - 0x6f, 0xae, 0x85, 0x70, 0x2b, 0xf0, 0xf7, 0x6f, 0xf3, 0xaf, 0x1c, 0x8b, 0x23, 0x4f, 0xbe, 0x56, - 0x90, 0x57, 0xe0, 0x74, 0x22, 0x3e, 0x49, 0xe4, 0xf0, 0x6e, 0x6e, 0xd0, 0xa2, 0x78, 0x34, 0xab, - 0xab, 0xb0, 0x22, 0x66, 0xc5, 0x38, 0xf4, 0x83, 0x33, 0x4b, 0x1c, 0x46, 0x57, 0x1d, 0xff, 0xdc, - 0x54, 0x34, 0x2a, 0xf3, 0x46, 0x72, 0x02, 0x59, 0x9a, 0xbc, 0x0c, 0x24, 0x94, 0xdb, 0xc3, 0x8d, - 0x82, 0x7f, 0x70, 0x43, 0x94, 0x84, 0x2b, 0x9c, 0x7f, 0xf6, 0xef, 0x0a, 0x70, 0x3a, 0xe3, 0x2a, - 0x43, 0x2f, 0x01, 0xde, 0x70, 0xe2, 0x1e, 0xb2, 0x2b, 0x84, 0xdc, 0xc8, 0x75, 0x09, 0xce, 0xf5, - 0x53, 0x8b, 0x2c, 0x03, 0x3a, 0xff, 0x16, 0xff, 0x45, 0x37, 0x0f, 0x67, 0x2c, 0x54, 0x2f, 0xf4, - 0x5f, 0x52, 0x83, 0x0d, 0x4c, 0xeb, 0x10, 0x78, 0x3e, 0x66, 0x87, 0x40, 0x21, 0xa4, 0x10, 0xbb, - 0xec, 0x60, 0x2d, 0xda, 0x12, 0x12, 0x95, 0x42, 0x4c, 0x75, 0x94, 0x80, 0x90, 0x8f, 0xc1, 0x79, - 0xe9, 0xac, 0xb1, 0x13, 0x2b, 0x0f, 0x2d, 0xdd, 0xcd, 0x4d, 0x27, 0x3c, 0x75, 0x76, 0x62, 0x6b, - 0x70, 0x1b, 0x2e, 0xe3, 0x20, 0x7a, 0xfd, 0x91, 0x9d, 0xca, 0x03, 0x82, 0x4d, 0x65, 0x81, 0xf3, - 0xcf, 0x53, 0xac, 0x5a, 0x7f, 0x94, 0x48, 0x09, 0x82, 0xad, 0xae, 0x67, 0xae, 0xce, 0x25, 0x5c, - 0x9d, 0x97, 0xe4, 0xc6, 0x9c, 0x68, 0x6d, 0x1e, 0xc2, 0x46, 0x28, 0x29, 0x85, 0xc7, 0x56, 0x31, - 0x96, 0x0d, 0x1d, 0x99, 0x09, 0xb9, 0x89, 0x9d, 0x63, 0xcc, 0x57, 0x3f, 0x45, 0x28, 0x47, 0xa4, - 0x98, 0xc6, 0x08, 0x02, 0xf2, 0x25, 0x20, 0xec, 0xf8, 0x8c, 0x7d, 0x09, 0xd2, 0x5f, 0x12, 0xcf, - 0x2c, 0xfc, 0x4b, 0x2c, 0xd9, 0x64, 0x8a, 0x52, 0x8e, 0x84, 0x85, 0xa5, 0xd2, 0xb7, 0xf8, 0x0c, - 0xfb, 0x35, 0x05, 0x4e, 0x67, 0x70, 0x24, 0x1a, 0xe4, 0xc4, 0x12, 0x4d, 0x9b, 0xf8, 0x54, 0x4f, - 0x99, 0x39, 0xaf, 0x4f, 0xee, 0x00, 0x60, 0x92, 0xc6, 0xb1, 0x7b, 0xe8, 0x7e, 0x55, 0xce, 0x50, - 0x1f, 0x41, 0x63, 0x34, 0xcb, 0xa8, 0x36, 0xa5, 0x60, 0x7e, 0xe9, 0x5d, 0x86, 0x25, 0x6f, 0xd8, - 0x1b, 0x4c, 0xfb, 0xae, 0xf6, 0x7d, 0x51, 0x8f, 0x78, 0x1f, 0x92, 0x0e, 0xf0, 0xb7, 0x35, 0xde, - 0xdf, 0xd7, 0x67, 0xf7, 0xb7, 0xfc, 0x64, 0xc1, 0x23, 0x2b, 0x20, 0x40, 0x56, 0xcc, 0x33, 0xc8, - 0x7b, 0x78, 0x4c, 0xe0, 0xdd, 0xf6, 0x10, 0xce, 0x66, 0xae, 0x05, 0x2a, 0xba, 0xa0, 0x89, 0x5e, - 0x24, 0x75, 0x2f, 0xd1, 0xdf, 0x54, 0xec, 0xbe, 0x0a, 0x2b, 0x8f, 0x5c, 0x67, 0xec, 0x8e, 0xb9, - 0x4c, 0xc8, 0x37, 0x1b, 0x06, 0x93, 0x45, 0xc2, 0x7e, 0x7c, 0xd1, 0x73, 0x6d, 0x24, 0x69, 0xc0, - 0x69, 0x36, 0xc4, 0xde, 0x31, 0x5e, 0x33, 0xb8, 0x06, 0x53, 0x89, 0x09, 0xda, 0x48, 0x82, 0x42, - 0x4f, 0x0d, 0xb1, 0x18, 0xb5, 0xb9, 0x71, 0x98, 0x04, 0xd1, 0xb3, 0xe2, 0x5c, 0x36, 0x36, 0xd9, - 0x86, 0x12, 0x63, 0xce, 0x2e, 0x9c, 0xec, 0xe9, 0xe9, 0xea, 0xdc, 0x2f, 0x54, 0xd0, 0x72, 0x3d, - 0x08, 0xff, 0xa7, 0x92, 0x20, 0xbe, 0xf2, 0xdb, 0xc7, 0xf2, 0xcb, 0x9a, 0xb9, 0x82, 0x40, 0xfe, - 0xa2, 0xa6, 0xfd, 0xb5, 0x22, 0x9a, 0x1a, 0x53, 0xbb, 0xd0, 0x4d, 0x2b, 0x70, 0x87, 0xe2, 0x75, - 0x71, 0xd9, 0xe4, 0xbf, 0x9e, 0x71, 0x13, 0x25, 0xaf, 0xc3, 0x0a, 0x65, 0x7b, 0x38, 0x1d, 0xb2, - 0xcd, 0x2c, 0x1f, 0x8b, 0xf8, 0xd4, 0x60, 0x45, 0x74, 0xd8, 0xaa, 0xa7, 0xcc, 0xd2, 0x71, 0xf4, - 0x93, 0xde, 0xc3, 0x82, 0xe3, 0xc9, 0x48, 0xde, 0x02, 0x85, 0x0a, 0xda, 0x6a, 0x74, 0xda, 0x9c, - 0xa4, 0x48, 0x71, 0xa2, 0x7b, 0xd8, 0xf6, 0x22, 0x53, 0x42, 0x6b, 0x2f, 0x41, 0x49, 0xe2, 0x4d, - 0x1b, 0xc3, 0x7c, 0xb2, 0x44, 0x63, 0xd8, 0x2f, 0x3e, 0xd8, 0x8f, 0xa0, 0x28, 0x58, 0xd2, 0x0b, - 0xe7, 0x91, 0x1f, 0x88, 0xe3, 0x03, 0xff, 0xa7, 0x30, 0xda, 0xcb, 0xd8, 0xc8, 0x05, 0x13, 0xff, - 0x47, 0x29, 0x65, 0xe2, 0xd0, 0x9b, 0xe6, 0x20, 0xb0, 0x47, 0x68, 0xdb, 0x17, 0x5e, 0xcb, 0x28, - 0xbc, 0x33, 0x08, 0x98, 0xc5, 0x1f, 0xff, 0xc6, 0x5f, 0x84, 0xe2, 0x5d, 0x42, 0x4f, 0x35, 0xeb, - 0x34, 0x8e, 0x09, 0x23, 0xb9, 0xb4, 0x30, 0xc2, 0x22, 0xf9, 0x70, 0x4a, 0xf6, 0x65, 0x40, 0x18, - 0x0a, 0x23, 0xd2, 0x99, 0x53, 0x88, 0x9d, 0x39, 0x92, 0xb6, 0x27, 0x1a, 0x3d, 0x26, 0xcb, 0x08, - 0x6d, 0x4f, 0xf2, 0x04, 0xfc, 0x93, 0x9c, 0x50, 0x3e, 0x6d, 0xfb, 0xfe, 0x24, 0x98, 0x8c, 0x9d, - 0x51, 0x4c, 0xc9, 0x4e, 0x8e, 0xe1, 0x39, 0xbc, 0x9b, 0xdd, 0xc6, 0xe4, 0x2c, 0xfe, 0x58, 0x04, - 0x8f, 0x09, 0x67, 0x6e, 0xe9, 0xf6, 0x87, 0xe2, 0xb7, 0x47, 0x9d, 0x62, 0xeb, 0x32, 0x32, 0x9d, - 0xb0, 0x12, 0xd7, 0xea, 0x29, 0x73, 0x93, 0xf1, 0x4c, 0x61, 0x91, 0x6a, 0xc6, 0x22, 0x4e, 0x6a, - 0xd9, 0xb7, 0xa3, 0x15, 0x1d, 0xe7, 0x2a, 0xaf, 0x75, 0xf2, 0x09, 0x58, 0xf6, 0xfa, 0x72, 0x0e, - 0xd2, 0xa4, 0x7e, 0xb7, 0xd6, 0x67, 0x71, 0xd0, 0x23, 0x1e, 0x74, 0xce, 0x79, 0x1c, 0xba, 0xbd, - 0x1a, 0x7b, 0x8e, 0xd0, 0xb6, 0x85, 0x9e, 0x23, 0x4d, 0x46, 0xd6, 0xa2, 0xcd, 0x1c, 0x37, 0x6e, - 0x5c, 0x5e, 0x51, 0x24, 0x76, 0x93, 0xff, 0xd2, 0xfe, 0x2f, 0xdc, 0x38, 0x69, 0x1f, 0xd1, 0xa5, - 0x38, 0xa3, 0xc3, 0x97, 0x59, 0x10, 0xd4, 0x78, 0xbf, 0x5d, 0x05, 0x39, 0x90, 0xb4, 0x27, 0x36, - 0x3f, 0x01, 0xeb, 0x8e, 0x3d, 0xed, 0xcf, 0xf3, 0xb0, 0x16, 0x7f, 0x80, 0x21, 0x2f, 0x41, 0x41, - 0xda, 0x81, 0x36, 0x33, 0x5e, 0x69, 0x70, 0xdf, 0x41, 0xa4, 0x13, 0xed, 0x38, 0xe4, 0x2e, 0xac, - 0xa1, 0x49, 0x28, 0x1e, 0x93, 0x13, 0x8f, 0x3f, 0xeb, 0xcd, 0x7f, 0x99, 0x2d, 0xfe, 0xf0, 0x9d, - 0x2b, 0xa7, 0xf0, 0x11, 0x76, 0x85, 0xd2, 0xd2, 0x13, 0x87, 0x16, 0x4a, 0xfa, 0xf5, 0xc2, 0x6c, - 0xfd, 0x3a, 0x6f, 0xca, 0x0c, 0xfd, 0xfa, 0xc2, 0x1c, 0xfd, 0x7a, 0x44, 0x29, 0xeb, 0xd7, 0xf1, - 0x95, 0x65, 0x69, 0xd6, 0x2b, 0x4b, 0x44, 0xc3, 0x5e, 0x59, 0x22, 0xfd, 0x78, 0x71, 0xa6, 0x7e, - 0x3c, 0xa2, 0xe1, 0xfa, 0xf1, 0x6b, 0xbc, 0x8f, 0xc6, 0xce, 0x63, 0x1b, 0x3b, 0x8f, 0x0b, 0x5c, - 0xd8, 0x7a, 0xd3, 0x79, 0x8c, 0x66, 0x5b, 0xf4, 0xf0, 0xe6, 0xb6, 0x5e, 0xda, 0xef, 0x29, 0x09, - 0x1d, 0xb3, 0x18, 0xbf, 0x17, 0x61, 0x8d, 0x1d, 0x56, 0x3c, 0x50, 0x2e, 0x3b, 0xad, 0x56, 0xcd, - 0x55, 0x01, 0x65, 0x9a, 0x8c, 0x0f, 0xc0, 0x7a, 0x88, 0xc6, 0x2f, 0xf3, 0xe8, 0x03, 0x6a, 0x86, - 0xd4, 0x3c, 0xa0, 0xd1, 0x4b, 0xb0, 0x11, 0x22, 0x72, 0x3d, 0x21, 0x53, 0x64, 0xac, 0x9a, 0xaa, - 0x28, 0x68, 0x73, 0xb8, 0x76, 0x98, 0xbc, 0xd3, 0xfe, 0x82, 0x6a, 0xa5, 0xfd, 0x20, 0x1f, 0xd3, - 0xbf, 0x89, 0xcf, 0xd0, 0x53, 0x34, 0xf0, 0x6d, 0xde, 0x49, 0x7c, 0x2f, 0xba, 0x3a, 0x63, 0xcc, - 0xb8, 0xb5, 0x9c, 0x65, 0xb5, 0x4c, 0x08, 0x02, 0x5f, 0x18, 0xcf, 0xd9, 0xec, 0xae, 0x26, 0x89, - 0x76, 0x82, 0x1d, 0xdb, 0x78, 0xca, 0xf3, 0xd9, 0x09, 0x05, 0x08, 0x9d, 0xb2, 0x78, 0x67, 0x0b, - 0x7f, 0x89, 0x0f, 0x74, 0x01, 0xd5, 0xd5, 0x41, 0x9c, 0x79, 0x3e, 0xe3, 0x56, 0x9e, 0x62, 0x8e, - 0xbd, 0x84, 0x9c, 0xd5, 0xa9, 0xf8, 0x57, 0xb0, 0x35, 0x60, 0x05, 0xb5, 0x5f, 0x82, 0x61, 0x21, - 0xe3, 0x71, 0x27, 0xdd, 0xf8, 0x4a, 0xad, 0x61, 0x96, 0x28, 0x9d, 0x60, 0x73, 0x04, 0xcf, 0xc9, - 0x3a, 0xab, 0x78, 0x25, 0x17, 0x44, 0x7c, 0xe8, 0xb9, 0x3d, 0x10, 0xa9, 0xb6, 0xb0, 0xaa, 0xe7, - 0x9c, 0x38, 0x80, 0xa3, 0x69, 0x47, 0x70, 0x7e, 0xf6, 0x90, 0xcc, 0xc9, 0x3d, 0x16, 0x1d, 0xa0, - 0x39, 0xf9, 0x00, 0x95, 0x35, 0x58, 0xf9, 0x98, 0x06, 0x4b, 0xfb, 0xe3, 0x3c, 0xbc, 0x70, 0x82, - 0xe1, 0x9a, 0xf3, 0xcd, 0x4f, 0xc5, 0xc5, 0xb3, 0x5c, 0x4c, 0xe7, 0x40, 0x99, 0xf2, 0x0d, 0xf2, - 0xc9, 0xb0, 0x37, 0x43, 0x38, 0xfb, 0x22, 0xac, 0xb3, 0x5d, 0x90, 0x19, 0xbc, 0x1e, 0x4c, 0x07, - 0x27, 0xd8, 0x06, 0x2f, 0x08, 0xef, 0xbc, 0x04, 0x29, 0xee, 0x8c, 0xb8, 0x63, 0x58, 0x21, 0x8c, - 0x74, 0xa0, 0x84, 0x68, 0x07, 0x8e, 0x37, 0x38, 0x91, 0x9b, 0x98, 0xf0, 0xfd, 0x93, 0xc9, 0x98, - 0x9d, 0x3e, 0x05, 0xec, 0xe2, 0x6f, 0x72, 0x1d, 0xd6, 0x87, 0xd3, 0x63, 0x2a, 0x78, 0xb0, 0xb9, - 0xc0, 0xed, 0x8a, 0x16, 0xcc, 0xd5, 0xe1, 0xf4, 0x58, 0x1f, 0x8d, 0x70, 0x48, 0xd1, 0x00, 0x69, - 0x83, 0xe2, 0xb1, 0x55, 0x2b, 0x30, 0x17, 0x11, 0x93, 0x32, 0x60, 0xeb, 0x96, 0xe3, 0x9e, 0x01, - 0x66, 0x8e, 0xca, 0x73, 0xaf, 0xb1, 0x1f, 0xda, 0x7f, 0xe6, 0x84, 0x26, 0x65, 0xf6, 0xbc, 0xff, - 0xd5, 0x10, 0x65, 0x0c, 0xd1, 0x0d, 0x50, 0x69, 0xd7, 0x47, 0x9b, 0x4a, 0x38, 0x46, 0x6b, 0xc3, - 0xe9, 0x71, 0xd8, 0x77, 0x72, 0xc7, 0x2f, 0xca, 0x1d, 0xff, 0xba, 0xd0, 0xb4, 0x64, 0x6e, 0x0f, - 0xb3, 0xbb, 0x5c, 0xfb, 0xb7, 0x3c, 0x5c, 0x3f, 0xd9, 0x26, 0xf0, 0xab, 0x71, 0xcb, 0x18, 0xb7, - 0x84, 0x52, 0x7e, 0x21, 0xa5, 0x94, 0xcf, 0x58, 0x7b, 0x8b, 0x59, 0x6b, 0x2f, 0xf5, 0x04, 0xb0, - 0x94, 0xf1, 0x04, 0x90, 0xb9, 0x40, 0x8b, 0x4f, 0x59, 0xa0, 0xcb, 0xf2, 0x3c, 0xf9, 0xa7, 0x9c, - 0xb8, 0x3a, 0xc6, 0xef, 0x03, 0x0f, 0xe1, 0xb4, 0xb8, 0x0f, 0xb0, 0x93, 0x23, 0x7a, 0xd9, 0x29, - 0xdd, 0xbe, 0x99, 0x75, 0x13, 0x40, 0xb4, 0x0c, 0x69, 0x7d, 0x83, 0xdf, 0x01, 0xa2, 0xf2, 0xff, - 0x3d, 0xd2, 0x3f, 0x79, 0x00, 0xe7, 0x30, 0x73, 0x41, 0x4f, 0x7e, 0x93, 0xb2, 0xc7, 0xee, 0x01, - 0x9f, 0x0f, 0x57, 0x53, 0xb2, 0xb2, 0xd7, 0x93, 0xaa, 0x63, 0xba, 0x07, 0xd5, 0x53, 0xe6, 0x99, - 0x20, 0x03, 0x9e, 0xbc, 0x58, 0x7c, 0x5f, 0x01, 0xed, 0xe9, 0xfd, 0x85, 0x2a, 0xd0, 0x64, 0x87, - 0x2f, 0x9b, 0x25, 0x47, 0xea, 0xbd, 0x17, 0x60, 0x75, 0xec, 0x1e, 0x8c, 0xdd, 0xe0, 0x28, 0xa6, - 0x01, 0x59, 0xe1, 0x40, 0xd1, 0x31, 0x22, 0xdc, 0xe9, 0x33, 0x49, 0xe6, 0x82, 0x48, 0xdb, 0x0d, - 0xef, 0x8b, 0x99, 0xe3, 0x40, 0x67, 0x93, 0x5c, 0x41, 0xf6, 0xe3, 0x6e, 0xa1, 0x98, 0x53, 0xf3, - 0x26, 0x0f, 0xca, 0x7a, 0xe0, 0x0d, 0x5c, 0xed, 0x2f, 0x15, 0x21, 0x11, 0x64, 0x75, 0x1e, 0x79, - 0x28, 0x99, 0x89, 0xe7, 0x53, 0x62, 0x48, 0x16, 0xc9, 0x49, 0xd4, 0x53, 0xf5, 0xf7, 0x49, 0x3d, - 0x75, 0x47, 0xd8, 0x9a, 0xd1, 0x3d, 0x6f, 0xff, 0x16, 0xb9, 0x09, 0x4b, 0xcc, 0xbc, 0x4c, 0x54, - 0x77, 0x3d, 0x56, 0xdd, 0xfd, 0x5b, 0xa6, 0x28, 0xd7, 0xde, 0x0e, 0x5f, 0x4c, 0x53, 0x8d, 0xd8, - 0xbf, 0x45, 0x5e, 0x3f, 0x99, 0xd9, 0x77, 0x51, 0x98, 0x7d, 0x87, 0x26, 0xdf, 0x6f, 0xc4, 0x4c, - 0xbe, 0xaf, 0xcd, 0xef, 0x2d, 0xfe, 0xce, 0xcd, 0x02, 0x5d, 0x46, 0x01, 0xd0, 0x7e, 0x9a, 0x83, - 0x4b, 0x73, 0x29, 0xc8, 0x45, 0x28, 0xea, 0xed, 0x5a, 0x27, 0x1a, 0x5f, 0xba, 0x66, 0x04, 0x84, - 0xec, 0xc1, 0xf2, 0xb6, 0x13, 0x78, 0x3d, 0x3a, 0x8d, 0x33, 0x1f, 0x9e, 0x52, 0x6c, 0x43, 0xf4, - 0xea, 0x29, 0x33, 0xa2, 0x25, 0x36, 0x6c, 0xe0, 0x5a, 0x88, 0x25, 0x35, 0xcb, 0x67, 0xe8, 0x1a, - 0x52, 0x0c, 0x53, 0x64, 0x74, 0x9f, 0x49, 0x01, 0xc9, 0x23, 0x20, 0x96, 0x55, 0xad, 0xb8, 0xe3, - 0x09, 0xbf, 0x83, 0x4f, 0xbc, 0xd0, 0x86, 0xf8, 0xc3, 0x4f, 0xe9, 0xbb, 0x14, 0x5d, 0xf5, 0x94, - 0x99, 0xc1, 0x2d, 0xb9, 0xcc, 0xdf, 0x12, 0xf2, 0xce, 0xec, 0x4e, 0x78, 0x86, 0x20, 0xc2, 0x37, - 0xa0, 0xd8, 0x16, 0x56, 0x2e, 0x92, 0x2f, 0x86, 0xb0, 0x68, 0x31, 0xc3, 0x52, 0xed, 0x37, 0x15, - 0xa1, 0x74, 0x78, 0x7a, 0x67, 0x49, 0x39, 0xe7, 0xfa, 0xf3, 0x73, 0xce, 0xf5, 0x7f, 0xce, 0x9c, - 0x73, 0x9a, 0x07, 0x37, 0x4f, 0xdc, 0xb1, 0xe4, 0xe3, 0xa0, 0x62, 0x7a, 0x2e, 0x47, 0x1a, 0x24, - 0xb6, 0xbe, 0x36, 0xc2, 0xa8, 0xf2, 0x55, 0x9e, 0x03, 0xd1, 0x5c, 0xef, 0xc5, 0xa9, 0xb5, 0x3f, - 0xe5, 0xd9, 0x04, 0x6a, 0xfd, 0x76, 0xe2, 0x09, 0xe3, 0xbd, 0xba, 0xef, 0x18, 0xb1, 0xc5, 0xf6, - 0x82, 0x94, 0x1e, 0x35, 0xfd, 0xad, 0xd9, 0x5e, 0x3c, 0xd2, 0xca, 0xfb, 0xc3, 0x3c, 0x5c, 0x9c, - 0x47, 0x9e, 0x99, 0x80, 0x5d, 0x79, 0xb6, 0x04, 0xec, 0x37, 0xa1, 0xc8, 0x60, 0xa1, 0x6f, 0x0a, - 0x8e, 0x2d, 0x27, 0xa5, 0x63, 0x2b, 0x8a, 0xc9, 0x0b, 0xb0, 0xa8, 0x57, 0xac, 0x28, 0x27, 0x20, - 0x1a, 0x91, 0x3b, 0xbd, 0x00, 0xcd, 0x93, 0x79, 0x11, 0xf9, 0x42, 0x3a, 0x0d, 0x26, 0x4f, 0x06, - 0x78, 0x41, 0xea, 0x90, 0x54, 0xa2, 0x0f, 0xac, 0x6f, 0x94, 0x98, 0x82, 0xc7, 0x7a, 0x37, 0xd3, - 0x29, 0x35, 0x35, 0x58, 0x6c, 0x8f, 0xdd, 0xc0, 0x9d, 0xc8, 0x06, 0xde, 0x23, 0x84, 0x98, 0xbc, - 0x84, 0x9b, 0x5f, 0x3b, 0x4f, 0x58, 0xb4, 0x8d, 0x45, 0x39, 0x02, 0x12, 0xda, 0x6b, 0x53, 0xb0, - 0x29, 0xa1, 0x50, 0x82, 0xba, 0x33, 0x1d, 0xf6, 0x8e, 0xba, 0x66, 0x9d, 0x4b, 0x4e, 0x8c, 0x60, - 0x80, 0x50, 0xda, 0xc0, 0xc0, 0x94, 0x50, 0xb4, 0x6f, 0x29, 0x70, 0x26, 0xab, 0x1d, 0xe4, 0x22, - 0x14, 0x86, 0x99, 0x19, 0x3f, 0x87, 0x2c, 0x48, 0x40, 0x09, 0x1f, 0x69, 0x0e, 0xfc, 0xf1, 0xb1, - 0x33, 0x91, 0xcd, 0xe0, 0x25, 0xb0, 0x89, 0xcf, 0x3b, 0xbb, 0xf8, 0x3f, 0xb9, 0x22, 0x8e, 0x9c, - 0x7c, 0x2a, 0x47, 0x28, 0xfe, 0xd1, 0x74, 0x80, 0x5a, 0xbf, 0xdd, 0x1a, 0xb1, 0x44, 0x13, 0xaf, - 0x42, 0x81, 0x56, 0x2b, 0x31, 0x7b, 0xe9, 0xfc, 0xd1, 0x1b, 0x75, 0x8e, 0xc4, 0x6a, 0x15, 0x38, - 0xc7, 0x03, 0x13, 0x91, 0xb5, 0xfb, 0xb0, 0x16, 0xc7, 0x20, 0x46, 0x3c, 0xd6, 0x70, 0xe9, 0xb6, - 0xca, 0x39, 0x6d, 0xfb, 0x3e, 0x73, 0xc5, 0xda, 0x7e, 0xee, 0xa7, 0xef, 0x5c, 0x01, 0xfa, 0x93, - 0xd1, 0x64, 0xc5, 0x22, 0xd6, 0xbe, 0x9d, 0x83, 0x33, 0x51, 0xf4, 0x07, 0xb1, 0x86, 0x7e, 0x69, - 0x5d, 0x91, 0xf5, 0x98, 0xab, 0xac, 0x90, 0x1b, 0xd3, 0x0d, 0x9c, 0xe3, 0xa1, 0xb7, 0x07, 0x5b, - 0xb3, 0xf0, 0xc9, 0x4b, 0xb0, 0x8c, 0x01, 0xc3, 0x46, 0x4e, 0xcf, 0x95, 0xb7, 0xd9, 0xa1, 0x00, - 0x9a, 0x51, 0xb9, 0xf6, 0x63, 0x05, 0xce, 0x73, 0x07, 0xa2, 0x86, 0xe3, 0x0d, 0xf1, 0x95, 0xa0, - 0xe7, 0xbe, 0x3f, 0xae, 0xf4, 0x7b, 0xb1, 0x7d, 0xec, 0xc5, 0xb8, 0x9f, 0x58, 0xea, 0x6b, 0xb3, - 0x5b, 0x4b, 0x6e, 0x62, 0x10, 0x3c, 0x6e, 0x9f, 0x51, 0x60, 0xa1, 0x4b, 0x86, 0x14, 0x20, 0x87, - 0x2e, 0x41, 0x0c, 0xed, 0xff, 0xc1, 0xe5, 0xf9, 0x1f, 0x20, 0x9f, 0x87, 0x55, 0xcc, 0xea, 0xd6, - 0x1d, 0x1d, 0x8e, 0x9d, 0xbe, 0x2b, 0x34, 0x7b, 0x42, 0x1b, 0x2b, 0x97, 0xb1, 0x98, 0x7e, 0x3c, - 0x94, 0xc6, 0x21, 0xe6, 0x8b, 0xe3, 0x44, 0x31, 0x2f, 0x3d, 0x99, 0x9b, 0xf6, 0x75, 0x05, 0x48, - 0x9a, 0x07, 0xf9, 0x08, 0xac, 0x74, 0x3b, 0x15, 0x6b, 0xe2, 0x8c, 0x27, 0x55, 0x7f, 0x3a, 0xe6, - 0x01, 0xf5, 0x58, 0x64, 0x85, 0x49, 0xcf, 0x66, 0xef, 0x41, 0x47, 0xfe, 0x74, 0x6c, 0xc6, 0xf0, - 0x30, 0x7b, 0x98, 0xeb, 0x7e, 0xb9, 0xef, 0x3c, 0x89, 0x67, 0x0f, 0xe3, 0xb0, 0x58, 0xf6, 0x30, - 0x0e, 0xd3, 0xbe, 0xa7, 0xc0, 0x05, 0x61, 0x76, 0xdb, 0xcf, 0xa8, 0x4b, 0x05, 0xe3, 0x07, 0x8d, - 0x45, 0x04, 0xe7, 0x79, 0x12, 0xfa, 0x86, 0x08, 0xb1, 0x85, 0x15, 0x44, 0x51, 0x9d, 0xd1, 0x92, - 0x4f, 0x41, 0xc1, 0x9a, 0xf8, 0xa3, 0x13, 0xc4, 0xd8, 0x52, 0xc3, 0x11, 0x9d, 0xf8, 0x23, 0x64, - 0x81, 0x94, 0x9a, 0x0b, 0x67, 0xe4, 0xca, 0x89, 0x1a, 0x93, 0x06, 0x2c, 0xf1, 0x60, 0x8a, 0x09, - 0x8b, 0x96, 0x39, 0x6d, 0xda, 0x5e, 0x17, 0x81, 0xbc, 0x78, 0x04, 0x61, 0x53, 0xf0, 0xd0, 0x7e, - 0x5b, 0x81, 0x12, 0x15, 0x6c, 0xf0, 0x52, 0xfa, 0x5e, 0xa7, 0x74, 0x5c, 0x0e, 0x16, 0x06, 0x5a, - 0x21, 0xfb, 0x13, 0x9d, 0xc6, 0xaf, 0xc1, 0x7a, 0x82, 0x80, 0x68, 0x18, 0xc2, 0x65, 0xe0, 0xf5, - 0x1c, 0x96, 0x8c, 0x88, 0x19, 0x37, 0xc5, 0x60, 0xda, 0xaf, 0x2b, 0x70, 0xa6, 0xf5, 0xe5, 0x89, - 0xc3, 0x9e, 0x6d, 0xcd, 0xe9, 0x40, 0xac, 0x77, 0x2a, 0xac, 0x09, 0xfb, 0x6d, 0x16, 0x5e, 0x82, - 0x09, 0x6b, 0x1c, 0x66, 0x86, 0xa5, 0xa4, 0x0a, 0x45, 0x7e, 0xbe, 0x04, 0x3c, 0xf0, 0xef, 0x65, - 0x49, 0x37, 0x12, 0x31, 0xe6, 0x48, 0xb4, 0x25, 0xb8, 0x85, 0x71, 0x1a, 0x33, 0xa4, 0xd6, 0xfe, - 0x5d, 0x81, 0xcd, 0x19, 0x34, 0xe4, 0x4d, 0x58, 0x40, 0xd7, 0x57, 0x3e, 0x7a, 0x17, 0x67, 0x7c, - 0x62, 0xd2, 0x3b, 0xda, 0xbf, 0xc5, 0x0e, 0xa2, 0x63, 0xfa, 0xc3, 0x64, 0x54, 0xe4, 0x21, 0x2c, - 0xeb, 0xfd, 0x3e, 0xbf, 0x9d, 0xe5, 0x62, 0xb7, 0xb3, 0x19, 0x5f, 0x7c, 0x25, 0xc4, 0x67, 0xb7, - 0x33, 0xe6, 0x84, 0xd5, 0xef, 0xdb, 0xdc, 0xad, 0x37, 0xe2, 0x77, 0xfe, 0xe3, 0xb0, 0x16, 0x47, - 0x7e, 0x26, 0x4f, 0xc4, 0xb7, 0x15, 0x50, 0xe3, 0x75, 0xf8, 0xc5, 0x84, 0x20, 0xcb, 0x1a, 0xe6, - 0xa7, 0x4c, 0xaa, 0xdf, 0xcd, 0xc1, 0xd9, 0xcc, 0x1e, 0x26, 0x2f, 0xc3, 0xa2, 0x3e, 0x1a, 0xd5, - 0x76, 0xf8, 0xac, 0xe2, 0x12, 0x12, 0x2a, 0xbd, 0x63, 0x97, 0x57, 0x86, 0x44, 0x5e, 0x85, 0x22, - 0xb3, 0x0e, 0xd8, 0x11, 0x1b, 0x0e, 0xc6, 0x54, 0xe2, 0xa6, 0x0b, 0xf1, 0x10, 0xbc, 0x02, 0x91, - 0xec, 0xc2, 0x1a, 0x8f, 0x46, 0x84, 0xf6, 0x21, 0x61, 0x2e, 0x08, 0x4c, 0x57, 0x21, 0x34, 0xe9, - 0xcc, 0xa4, 0x24, 0xb6, 0x77, 0x26, 0xa8, 0x48, 0x1d, 0x54, 0xe4, 0x29, 0x73, 0x62, 0x71, 0x80, - 0x25, 0x13, 0x99, 0x19, 0xbc, 0x52, 0x94, 0xe1, 0x70, 0xe9, 0x41, 0xe0, 0x1d, 0x0e, 0x8f, 0xdd, - 0xe1, 0xe4, 0x17, 0x37, 0x5c, 0xd1, 0x37, 0x4e, 0x34, 0x5c, 0xbf, 0x5f, 0x60, 0x8b, 0x39, 0x49, - 0x46, 0x25, 0x1a, 0x29, 0xf4, 0x3b, 0x4a, 0x34, 0xf4, 0x7e, 0xc6, 0xe3, 0xed, 0xec, 0xc0, 0x12, - 0x8b, 0x83, 0x24, 0x56, 0xc6, 0xa5, 0xcc, 0x2a, 0x30, 0x9c, 0xfd, 0x5b, 0x4c, 0x7c, 0x61, 0x3e, - 0xb8, 0x81, 0x29, 0x48, 0xc9, 0x3e, 0x94, 0x2a, 0x03, 0xd7, 0x19, 0x4e, 0x47, 0x9d, 0x93, 0xbd, - 0xa0, 0x6e, 0xf1, 0xb6, 0xac, 0xf4, 0x18, 0x19, 0xbe, 0xbc, 0xe2, 0x4e, 0x2e, 0x33, 0x22, 0x9d, - 0xd0, 0x2d, 0xaf, 0x80, 0x8a, 0xd7, 0x0f, 0xcf, 0xe9, 0x9f, 0x24, 0x10, 0xe9, 0xe2, 0x3e, 0xa7, - 0xdc, 0x6f, 0xcf, 0x86, 0xb5, 0xba, 0x13, 0x4c, 0x3a, 0x63, 0x67, 0x18, 0x60, 0xfc, 0xd4, 0x13, - 0xc4, 0x97, 0xbb, 0x20, 0x72, 0x83, 0xa3, 0xca, 0x74, 0x12, 0x92, 0x32, 0x85, 0x6c, 0x9c, 0x1d, - 0x95, 0x97, 0x76, 0xbd, 0xa1, 0x33, 0xf0, 0xbe, 0x26, 0xbc, 0x97, 0x99, 0xbc, 0x74, 0x20, 0x80, - 0x66, 0x54, 0xae, 0x7d, 0x2e, 0x35, 0x6e, 0xac, 0x96, 0x25, 0x58, 0xe2, 0xb1, 0x2d, 0x58, 0xac, - 0x87, 0xb6, 0xd1, 0xdc, 0xa9, 0x35, 0xf7, 0x54, 0x85, 0xac, 0x01, 0xb4, 0xcd, 0x56, 0xc5, 0xb0, - 0x2c, 0xfa, 0x3b, 0x47, 0x7f, 0xf3, 0x40, 0x10, 0xbb, 0xdd, 0xba, 0x9a, 0x97, 0x62, 0x41, 0x14, - 0xb4, 0x1f, 0x29, 0x70, 0x2e, 0x7b, 0x28, 0x49, 0x07, 0x30, 0x1a, 0x08, 0x7f, 0x4b, 0xff, 0xc8, - 0xdc, 0x71, 0xcf, 0x04, 0x27, 0xa3, 0x8a, 0x4c, 0x58, 0xb4, 0x8a, 0x9c, 0x78, 0xfb, 0x62, 0xee, - 0xaf, 0x5e, 0xdf, 0xcc, 0x79, 0x7d, 0xad, 0x02, 0x5b, 0xb3, 0x78, 0xc4, 0x9b, 0xba, 0x0e, 0x25, - 0xbd, 0xdd, 0xae, 0xd7, 0x2a, 0x7a, 0xa7, 0xd6, 0x6a, 0xaa, 0x0a, 0x59, 0x86, 0x85, 0x3d, 0xb3, - 0xd5, 0x6d, 0xab, 0x39, 0xed, 0x3b, 0x0a, 0xac, 0xd6, 0x22, 0x7b, 0xc6, 0xf7, 0xba, 0xf8, 0x3e, - 0x1a, 0x5b, 0x7c, 0x5b, 0x61, 0xdc, 0x9c, 0xf0, 0x03, 0x27, 0x5a, 0x79, 0xef, 0xe6, 0x60, 0x23, - 0x45, 0x43, 0x2c, 0x58, 0xd2, 0xef, 0x5b, 0xad, 0xda, 0x4e, 0x85, 0xd7, 0xec, 0x4a, 0x64, 0x2e, - 0x85, 0x99, 0xd4, 0x52, 0x5f, 0x61, 0xbe, 0xe6, 0x8f, 0x03, 0xdb, 0xf7, 0xfa, 0xbd, 0x98, 0x9d, - 0x9c, 0xe0, 0x84, 0x27, 0xd9, 0xd7, 0xa6, 0x63, 0x17, 0xd9, 0xe6, 0x62, 0x7a, 0xdd, 0x10, 0x9e, - 0x66, 0x8c, 0x26, 0x78, 0x0e, 0x2d, 0x4f, 0xb3, 0x8e, 0xf8, 0x91, 0x26, 0x2c, 0xee, 0x79, 0x93, - 0xea, 0xf4, 0x11, 0x5f, 0xbf, 0x97, 0xa3, 0xbc, 0x5a, 0xd5, 0xe9, 0xa3, 0x34, 0x5b, 0x54, 0x59, - 0xb2, 0xb8, 0x50, 0x31, 0x96, 0x9c, 0x4b, 0xd2, 0x3d, 0xb6, 0xf0, 0x4c, 0xee, 0xb1, 0xdb, 0xab, - 0x50, 0xe2, 0x77, 0x28, 0xbc, 0x9e, 0xfc, 0x40, 0x81, 0xad, 0x59, 0x3d, 0x47, 0xaf, 0x65, 0xf1, - 0x30, 0x18, 0xe7, 0xc2, 0xc4, 0x2b, 0xf1, 0xf8, 0x17, 0x02, 0x8d, 0x7c, 0x12, 0x4a, 0xb5, 0x20, - 0x98, 0xba, 0x63, 0xeb, 0xd5, 0xae, 0x59, 0xe3, 0xd3, 0xf5, 0xd2, 0xbf, 0xbc, 0x73, 0x65, 0x13, - 0xbd, 0x89, 0xc6, 0x76, 0xf0, 0xaa, 0x3d, 0x1d, 0x7b, 0xb1, 0x24, 0x15, 0x32, 0x05, 0x95, 0xa2, - 0x9d, 0x69, 0xdf, 0x73, 0xc5, 0x1d, 0x42, 0x84, 0x0a, 0xe0, 0x30, 0xf9, 0x4c, 0x13, 0x30, 0xed, - 0x9b, 0x0a, 0x9c, 0x9f, 0x3d, 0x4c, 0xf4, 0x9c, 0xec, 0x30, 0x93, 0x2a, 0xe1, 0xac, 0x8f, 0xe7, - 0x64, 0x68, 0x77, 0x25, 0xf3, 0x14, 0x88, 0x94, 0x88, 0x6b, 0xb8, 0x84, 0x92, 0x44, 0xce, 0xb4, - 0x1e, 0x27, 0x12, 0x88, 0xda, 0x03, 0xd8, 0x9c, 0x31, 0xa8, 0xe4, 0x13, 0x99, 0xe9, 0x9c, 0xd0, - 0x01, 0x4e, 0x4e, 0xe7, 0x14, 0xcb, 0x0b, 0x28, 0xc1, 0xb5, 0x7f, 0xcd, 0xc1, 0x39, 0xba, 0xba, - 0x06, 0x6e, 0x10, 0xe8, 0x51, 0xe6, 0x63, 0xba, 0x2b, 0xbe, 0x0e, 0x8b, 0x47, 0xcf, 0xa6, 0x2a, - 0x66, 0xe8, 0x84, 0x00, 0x9e, 0x58, 0xc2, 0xed, 0x8a, 0xfe, 0x4f, 0xae, 0x82, 0x9c, 0x36, 0x3f, - 0x8f, 0x81, 0x73, 0x73, 0x5b, 0x8a, 0xb9, 0x3c, 0x0a, 0x33, 0x5c, 0xbf, 0x01, 0x0b, 0xa8, 0x4f, - 0xe1, 0x67, 0x87, 0x90, 0xf9, 0xb3, 0x6b, 0x87, 0xda, 0x16, 0x93, 0x11, 0x90, 0x0f, 0x01, 0x44, - 0x39, 0x47, 0xf8, 0xe1, 0x20, 0xf4, 0x0c, 0x61, 0xda, 0x11, 0x73, 0xf9, 0xf8, 0xc0, 0xe1, 0x89, - 0x3c, 0xca, 0xb0, 0x21, 0x7a, 0x7c, 0x24, 0xe2, 0x6d, 0xf2, 0x57, 0xcc, 0x75, 0x56, 0x50, 0x1b, - 0x89, 0x98, 0x9b, 0xd7, 0x52, 0xa9, 0xbf, 0x31, 0xec, 0x76, 0x22, 0xbf, 0xf7, 0xb5, 0x54, 0x7e, - 0xef, 0x22, 0xc3, 0x92, 0x93, 0x78, 0x6b, 0xff, 0x98, 0x83, 0xe5, 0xfb, 0x54, 0x2a, 0x43, 0x5d, - 0xc3, 0x7c, 0xdd, 0xc5, 0x6d, 0x28, 0xd5, 0x7d, 0x87, 0x3f, 0x17, 0x71, 0x6f, 0x25, 0x66, 0xc9, - 0x3b, 0xf0, 0x1d, 0xf1, 0xf2, 0x14, 0x98, 0x32, 0xd2, 0x53, 0x22, 0x1d, 0xdc, 0x85, 0x45, 0xf6, - 0x7c, 0xc7, 0xd5, 0x68, 0x42, 0x2e, 0x0f, 0x6b, 0xf4, 0x0a, 0x2b, 0x96, 0x5e, 0x38, 0xd8, 0x13, - 0xa0, 0x2c, 0x24, 0x72, 0xb3, 0x5e, 0x49, 0xb3, 0xb2, 0x70, 0x32, 0xcd, 0x8a, 0x14, 0x25, 0x71, - 0xf1, 0x24, 0x51, 0x12, 0xcf, 0xdf, 0x81, 0x92, 0x54, 0x9f, 0x67, 0x12, 0xd3, 0xbf, 0x91, 0x83, - 0x55, 0x6c, 0x55, 0x68, 0xcb, 0xf3, 0xcb, 0xa9, 0x27, 0xfa, 0x68, 0x4c, 0x4f, 0xb4, 0x25, 0x8f, - 0x17, 0x6b, 0xd9, 0x1c, 0x05, 0xd1, 0x5d, 0xd8, 0x48, 0x21, 0x92, 0xd7, 0x60, 0x81, 0x56, 0x5f, - 0xdc, 0xab, 0xd5, 0xe4, 0x0c, 0x88, 0x22, 0x6a, 0xd3, 0x86, 0x07, 0x26, 0xc3, 0xd6, 0xfe, 0x43, - 0x81, 0x15, 0x9e, 0xd0, 0x66, 0x78, 0xe0, 0x3f, 0xb5, 0x3b, 0xaf, 0x27, 0xbb, 0x93, 0xc5, 0xed, - 0xe1, 0xdd, 0xf9, 0xdf, 0xdd, 0x89, 0x77, 0x62, 0x9d, 0xb8, 0x19, 0xc6, 0xd7, 0x14, 0xcd, 0x99, - 0xd3, 0x87, 0x7f, 0x85, 0x11, 0xa7, 0xe3, 0x88, 0xe4, 0x0b, 0xb0, 0xdc, 0x74, 0x1f, 0xc7, 0xae, - 0xa7, 0xd7, 0x67, 0x30, 0x7d, 0x25, 0x44, 0x64, 0x6b, 0x8a, 0x19, 0xd7, 0xbb, 0x8f, 0xed, 0xd4, - 0xcb, 0x61, 0xc4, 0x92, 0xde, 0x50, 0xe3, 0x64, 0xcf, 0x32, 0xf5, 0xb9, 0xeb, 0x34, 0x86, 0xa2, - 0xfa, 0x56, 0x1e, 0x20, 0xf2, 0x3a, 0xa5, 0x0b, 0x30, 0x66, 0x34, 0x21, 0x34, 0xfb, 0x08, 0x92, - 0xe7, 0xb8, 0xb0, 0xa5, 0xb8, 0xce, 0x35, 0xd0, 0xb9, 0xd9, 0xf1, 0x4f, 0x51, 0x17, 0x5d, 0xe1, - 0x6e, 0x8e, 0x7d, 0x77, 0xe0, 0xb0, 0xbd, 0x3d, 0xbf, 0x7d, 0x0d, 0xc3, 0x5d, 0x87, 0xd0, 0x19, - 0x89, 0xcc, 0xd1, 0x19, 0x72, 0x87, 0x22, 0xa4, 0x3c, 0xb9, 0x0b, 0xcf, 0xe6, 0xc9, 0xdd, 0x86, - 0x65, 0x6f, 0xf8, 0x96, 0x3b, 0x9c, 0xf8, 0xe3, 0x27, 0xa8, 0x76, 0x8f, 0xf4, 0x79, 0xb4, 0x0b, - 0x6a, 0xa2, 0x8c, 0x8d, 0x03, 0x9e, 0xb9, 0x21, 0xbe, 0x3c, 0x0c, 0x21, 0x30, 0xf4, 0x44, 0x5f, - 0x50, 0x17, 0xef, 0x16, 0x8a, 0x8b, 0xea, 0xd2, 0xdd, 0x42, 0xb1, 0xa8, 0x2e, 0xdf, 0x2d, 0x14, - 0x97, 0x55, 0x30, 0xa5, 0x37, 0xb3, 0xf0, 0x4d, 0x4c, 0x7a, 0xc6, 0x8a, 0x3f, 0x51, 0x69, 0x3f, - 0xcb, 0x01, 0x49, 0x57, 0x83, 0x7c, 0x14, 0x4a, 0x6c, 0x83, 0xb5, 0xc7, 0xc1, 0x57, 0xb8, 0xbb, - 0x01, 0x0b, 0xe8, 0x25, 0x81, 0xe5, 0x80, 0x5e, 0x0c, 0x6c, 0x06, 0x5f, 0x19, 0x90, 0xcf, 0xc3, - 0x69, 0xec, 0xde, 0x91, 0x3b, 0xf6, 0xfc, 0xbe, 0x8d, 0xd1, 0x97, 0x9d, 0x01, 0x4f, 0x3a, 0xfa, - 0x32, 0x66, 0xc7, 0x4e, 0x17, 0xcf, 0x18, 0x06, 0x74, 0x2e, 0x6d, 0x23, 0x66, 0x9b, 0x21, 0x92, - 0x0e, 0xa8, 0x32, 0xfd, 0xc1, 0x74, 0x30, 0xe0, 0x23, 0x5b, 0xa6, 0x37, 0xfa, 0x64, 0xd9, 0x0c, - 0xc6, 0x6b, 0x11, 0xe3, 0xdd, 0xe9, 0x60, 0x40, 0x5e, 0x07, 0xf0, 0x87, 0xf6, 0xb1, 0x17, 0x04, - 0xec, 0x31, 0x27, 0x74, 0x38, 0x89, 0xa0, 0xf2, 0x60, 0xf8, 0xc3, 0x06, 0x03, 0x92, 0xff, 0x03, - 0x18, 0x07, 0x04, 0x03, 0xe4, 0x30, 0x6b, 0x24, 0x9e, 0x17, 0x48, 0x00, 0xe3, 0x6e, 0xf7, 0x87, - 0xae, 0xe5, 0x7d, 0x4d, 0xb8, 0x7e, 0x7d, 0x16, 0x36, 0xb8, 0xf1, 0xf0, 0x7d, 0x6f, 0x72, 0xc4, - 0xaf, 0x12, 0xef, 0xe5, 0x1e, 0x22, 0xdd, 0x25, 0xfe, 0xa6, 0x00, 0xa0, 0xdf, 0xb7, 0x44, 0xec, - 0xb9, 0x9b, 0xb0, 0x40, 0x2f, 0x48, 0x42, 0xd1, 0x82, 0x6a, 0x6a, 0xe4, 0x2b, 0xab, 0xa9, 0x11, - 0x83, 0xae, 0x46, 0x13, 0x8d, 0xea, 0x85, 0x92, 0x05, 0x57, 0x23, 0xb3, 0xb3, 0x8f, 0xc5, 0xfe, - 0xe6, 0x58, 0xa4, 0x0e, 0x10, 0x45, 0x83, 0xe3, 0x22, 0xff, 0x46, 0x14, 0x56, 0x89, 0x17, 0xf0, - 0xfc, 0x23, 0x51, 0x44, 0x39, 0x79, 0xfa, 0x44, 0x68, 0xe4, 0x1e, 0x14, 0x3a, 0x4e, 0xe8, 0xe5, - 0x3d, 0x23, 0x46, 0xde, 0xf3, 0x3c, 0x29, 0x6c, 0x14, 0x27, 0x6f, 0x6d, 0xe2, 0xc4, 0x72, 0x67, - 0x23, 0x13, 0x62, 0xc0, 0x22, 0x4f, 0xf8, 0x3f, 0x23, 0xb6, 0x2a, 0xcf, 0xf7, 0xcf, 0x23, 0xaa, - 0x23, 0x50, 0x96, 0x29, 0x78, 0x6a, 0xff, 0xdb, 0x90, 0xb7, 0xac, 0x06, 0x8f, 0x0c, 0xb3, 0x1a, - 0x5d, 0xbf, 0x2c, 0xab, 0xc1, 0xde, 0x7d, 0x83, 0xe0, 0x58, 0x22, 0xa3, 0xc8, 0xe4, 0x63, 0x50, - 0x92, 0x84, 0x62, 0x1e, 0x53, 0x09, 0xfb, 0x40, 0xf2, 0xa3, 0x93, 0x37, 0x0d, 0x09, 0x9b, 0xd4, - 0x41, 0xbd, 0x37, 0x7d, 0xe4, 0xea, 0xa3, 0x11, 0x3a, 0xd8, 0xbe, 0xe5, 0x8e, 0x99, 0xd8, 0x56, - 0x8c, 0x82, 0x91, 0xa3, 0x8f, 0x44, 0x5f, 0x94, 0xca, 0xca, 0xa6, 0x24, 0x25, 0x69, 0xc3, 0x86, - 0xe5, 0x4e, 0xa6, 0x23, 0x66, 0x5f, 0xb3, 0xeb, 0x8f, 0xe9, 0xfd, 0x86, 0x45, 0x60, 0xc2, 0xb8, - 0xcd, 0x01, 0x2d, 0x14, 0x46, 0x4d, 0x07, 0xfe, 0x38, 0x71, 0xd7, 0x49, 0x13, 0x6b, 0xae, 0x3c, - 0xe4, 0xf4, 0x54, 0x8d, 0xdf, 0x9a, 0xf0, 0x54, 0x15, 0xb7, 0xa6, 0xe8, 0xae, 0xf4, 0xa1, 0x8c, - 0x28, 0x81, 0xf8, 0x32, 0x28, 0x45, 0x09, 0x8c, 0xc5, 0x06, 0xfc, 0x5e, 0x41, 0x0a, 0x54, 0xcb, - 0xc7, 0xe2, 0x4d, 0x80, 0xbb, 0xbe, 0x37, 0x6c, 0xb8, 0x93, 0x23, 0xbf, 0x2f, 0x05, 0x2b, 0x2c, - 0x7d, 0xc9, 0xf7, 0x86, 0xf6, 0x31, 0x82, 0x7f, 0xf6, 0xce, 0x15, 0x09, 0xc9, 0x94, 0xfe, 0x27, - 0x1f, 0x84, 0x65, 0xfa, 0xab, 0x13, 0x59, 0x09, 0x31, 0x9d, 0x2c, 0x52, 0xb3, 0x74, 0x2e, 0x11, - 0x02, 0xb9, 0x83, 0x09, 0x8c, 0xbc, 0xd1, 0x44, 0x12, 0x5e, 0x45, 0xb6, 0x22, 0x6f, 0x34, 0x49, - 0xc6, 0x1e, 0x97, 0x90, 0x49, 0x35, 0xac, 0xba, 0xc8, 0x39, 0xc6, 0xf3, 0x24, 0xa1, 0xe2, 0x91, - 0xcf, 0x35, 0x5b, 0x04, 0x3d, 0x96, 0x5d, 0xf7, 0x12, 0x64, 0x58, 0x09, 0xab, 0xba, 0xc3, 0x5e, - 0x8a, 0xb8, 0x50, 0xcb, 0x2a, 0x11, 0x1c, 0xf5, 0xed, 0x1e, 0x82, 0x63, 0x95, 0x08, 0x91, 0xc9, - 0x36, 0xac, 0x33, 0x19, 0x3f, 0xcc, 0x5d, 0xca, 0x45, 0x5c, 0xdc, 0xdb, 0xa2, 0xe4, 0xa6, 0xf2, - 0xe7, 0x13, 0x04, 0x64, 0x17, 0x16, 0xf0, 0xae, 0xc9, 0x5d, 0x03, 0x2e, 0xc8, 0x6a, 0x82, 0xe4, - 0x3a, 0xc2, 0x7d, 0x05, 0x15, 0x04, 0xf2, 0xbe, 0x82, 0xa8, 0xe4, 0x33, 0x00, 0xc6, 0x70, 0xec, - 0x0f, 0x06, 0x18, 0x96, 0xbb, 0x18, 0x73, 0x98, 0xe4, 0x7c, 0x90, 0x4b, 0x84, 0xc4, 0x43, 0x48, - 0xe2, 0x6f, 0x3b, 0x11, 0xbc, 0x5b, 0xe2, 0xa5, 0xd5, 0x60, 0x91, 0x2d, 0x46, 0x0c, 0x71, 0xcf, - 0x93, 0xf6, 0x48, 0x01, 0xd2, 0x59, 0x88, 0x7b, 0x0e, 0x4f, 0x87, 0xb8, 0x97, 0x08, 0xb4, 0x7b, - 0x70, 0x26, 0xab, 0x61, 0xb1, 0xdb, 0xb1, 0x72, 0xd2, 0xdb, 0xf1, 0x77, 0xf3, 0xb0, 0x82, 0xdc, - 0xc4, 0x2e, 0xac, 0xc3, 0xaa, 0x35, 0x7d, 0x14, 0xc6, 0x7f, 0x13, 0xbb, 0x31, 0xd6, 0x2f, 0x90, - 0x0b, 0xe4, 0x37, 0xbc, 0x18, 0x05, 0x31, 0x60, 0x4d, 0x9c, 0x04, 0x7b, 0xc2, 0x73, 0x20, 0x8c, - 0x2e, 0x2f, 0x62, 0x98, 0xa6, 0x73, 0x37, 0x27, 0x88, 0xa2, 0xf3, 0x20, 0xff, 0x2c, 0xe7, 0x41, - 0xe1, 0x44, 0xe7, 0xc1, 0x43, 0x58, 0x11, 0x5f, 0xc3, 0x9d, 0x7c, 0xe1, 0xbd, 0xed, 0xe4, 0x31, - 0x66, 0xa4, 0x1e, 0xee, 0xe8, 0x8b, 0x73, 0x77, 0x74, 0x7c, 0x18, 0x15, 0xab, 0x6c, 0x84, 0xb0, - 0xf4, 0xc6, 0x8e, 0xc9, 0x4d, 0xf7, 0x2a, 0xed, 0x9f, 0xe3, 0x94, 0x7c, 0x0d, 0x96, 0xeb, 0xbe, - 0x78, 0x13, 0x93, 0x1e, 0x23, 0x06, 0x02, 0x28, 0x8b, 0x0b, 0x21, 0x66, 0x78, 0xba, 0xe5, 0xdf, - 0x8f, 0xd3, 0xed, 0x0e, 0x00, 0x77, 0x49, 0x89, 0x92, 0x12, 0xe2, 0x92, 0x11, 0xb1, 0x6f, 0xe2, - 0x6f, 0x22, 0x12, 0x32, 0xdd, 0x9d, 0xb8, 0xb9, 0x8d, 0xde, 0xeb, 0xf9, 0xd3, 0xe1, 0x24, 0x96, - 0xc5, 0x5b, 0xf8, 0x46, 0x3b, 0xbc, 0x4c, 0xde, 0x1e, 0x12, 0x64, 0xef, 0xef, 0x80, 0x90, 0x4f, - 0x87, 0xc6, 0x8f, 0x4b, 0xf3, 0x7a, 0x48, 0x4b, 0xf5, 0xd0, 0x4c, 0x93, 0x47, 0xed, 0x47, 0x8a, - 0x9c, 0xda, 0xe3, 0xe7, 0x18, 0xea, 0x37, 0x00, 0x42, 0xa3, 0x04, 0x31, 0xd6, 0xa1, 0x33, 0x32, - 0x83, 0xca, 0xbd, 0x1c, 0xe1, 0x4a, 0xad, 0xc9, 0xbf, 0x5f, 0xad, 0xe9, 0x40, 0xa9, 0xf5, 0xe5, - 0x89, 0x13, 0x59, 0xb1, 0x80, 0x15, 0x4a, 0xb2, 0xb8, 0x33, 0xe5, 0xb7, 0x5f, 0xc4, 0xb3, 0x21, - 0x92, 0x83, 0x67, 0x88, 0xc0, 0x12, 0xa1, 0xf6, 0x67, 0x0a, 0xac, 0xcb, 0x01, 0x1d, 0x9e, 0x0c, - 0x7b, 0xe4, 0x13, 0x2c, 0xd2, 0xb0, 0x12, 0xbb, 0xb2, 0x48, 0x48, 0x74, 0xcb, 0x7d, 0x32, 0xec, - 0x31, 0x01, 0xc8, 0x79, 0x2c, 0x57, 0x96, 0x12, 0x92, 0x47, 0xb0, 0xd2, 0xf6, 0x07, 0x03, 0x2a, - 0xd6, 0x8c, 0xdf, 0xe2, 0x17, 0x00, 0xca, 0x28, 0xf9, 0x34, 0x22, 0x2a, 0xb4, 0xfd, 0x02, 0xbf, - 0xe7, 0x6e, 0x8e, 0xe8, 0x7e, 0xef, 0x71, 0xba, 0x88, 0xed, 0xdb, 0xe8, 0x27, 0x27, 0xf3, 0xd4, - 0x7e, 0xa2, 0x00, 0x49, 0x57, 0x49, 0xde, 0xb2, 0x94, 0xff, 0x01, 0x11, 0x36, 0x21, 0xfa, 0x15, - 0x9e, 0x45, 0xf4, 0x2b, 0xff, 0x8e, 0x02, 0xeb, 0x35, 0xbd, 0xc1, 0x93, 0x7d, 0xb0, 0x17, 0x9c, - 0xab, 0x70, 0xa9, 0xa6, 0x37, 0xec, 0x76, 0xab, 0x5e, 0xab, 0x3c, 0xb0, 0x33, 0x63, 0x78, 0x5f, - 0x82, 0xe7, 0xd2, 0x28, 0xd1, 0x4b, 0xcf, 0x45, 0xd8, 0x4a, 0x17, 0x8b, 0x38, 0xdf, 0xd9, 0xc4, - 0x22, 0x24, 0x78, 0xbe, 0xfc, 0x49, 0x58, 0x17, 0x31, 0xad, 0x3b, 0x75, 0x0b, 0xb3, 0x66, 0xac, - 0x43, 0x69, 0xdf, 0x30, 0x6b, 0xbb, 0x0f, 0xec, 0xdd, 0x6e, 0xbd, 0xae, 0x9e, 0x22, 0xab, 0xb0, - 0xcc, 0x01, 0x15, 0x5d, 0x55, 0xc8, 0x0a, 0x14, 0x6b, 0x4d, 0xcb, 0xa8, 0x74, 0x4d, 0x43, 0xcd, - 0x95, 0x3f, 0x09, 0x6b, 0xed, 0xb1, 0xf7, 0x96, 0x33, 0x71, 0xef, 0xb9, 0x4f, 0xf0, 0xa1, 0x66, - 0x09, 0xf2, 0xa6, 0x7e, 0x5f, 0x3d, 0x45, 0x00, 0x16, 0xdb, 0xf7, 0x2a, 0xd6, 0xad, 0x5b, 0xaa, - 0x42, 0x4a, 0xb0, 0xb4, 0x57, 0x69, 0xdb, 0xf7, 0x1a, 0x96, 0x9a, 0xa3, 0x3f, 0xf4, 0xfb, 0x16, - 0xfe, 0xc8, 0x97, 0x3f, 0x0c, 0x1b, 0x28, 0x90, 0xd4, 0xbd, 0x60, 0xe2, 0x0e, 0xdd, 0x31, 0xd6, - 0x61, 0x05, 0x8a, 0x96, 0x4b, 0x77, 0x92, 0x89, 0xcb, 0x2a, 0xd0, 0x98, 0x0e, 0x26, 0xde, 0x68, - 0xe0, 0x7e, 0x55, 0x55, 0xca, 0x77, 0x60, 0xdd, 0xf4, 0xa7, 0x13, 0x6f, 0x78, 0x68, 0x4d, 0x28, - 0xc6, 0xe1, 0x13, 0x72, 0x16, 0x36, 0xba, 0x4d, 0xbd, 0xb1, 0x5d, 0xdb, 0xeb, 0xb6, 0xba, 0x96, - 0xdd, 0xd0, 0x3b, 0x95, 0x2a, 0x7b, 0x26, 0x6a, 0xb4, 0xac, 0x8e, 0x6d, 0x1a, 0x15, 0xa3, 0xd9, - 0x51, 0x95, 0xf2, 0xb7, 0x51, 0xb7, 0xd2, 0xf3, 0x87, 0xfd, 0x5d, 0xa7, 0x37, 0xf1, 0xc7, 0x58, - 0x61, 0x0d, 0x2e, 0x5b, 0x46, 0xa5, 0xd5, 0xdc, 0xb1, 0x77, 0xf5, 0x4a, 0xa7, 0x65, 0x66, 0x05, - 0x91, 0x3f, 0x0f, 0xe7, 0x32, 0x70, 0x5a, 0x9d, 0xb6, 0xaa, 0x90, 0x2b, 0x70, 0x21, 0xa3, 0xec, - 0xbe, 0xb1, 0xad, 0x77, 0x3b, 0xd5, 0xa6, 0x9a, 0x9b, 0x41, 0x6c, 0x59, 0x2d, 0x35, 0x5f, 0xfe, - 0x0d, 0x05, 0xd6, 0xba, 0x01, 0x37, 0x39, 0xef, 0xa2, 0xb7, 0xe9, 0xf3, 0x70, 0xb1, 0x6b, 0x19, - 0xa6, 0xdd, 0x69, 0xdd, 0x33, 0x9a, 0x76, 0xd7, 0xd2, 0xf7, 0x92, 0xb5, 0xb9, 0x02, 0x17, 0x24, - 0x0c, 0xd3, 0xa8, 0xb4, 0xf6, 0x0d, 0xd3, 0x6e, 0xeb, 0x96, 0x75, 0xbf, 0x65, 0xee, 0xa8, 0x0a, - 0xfd, 0x62, 0x06, 0x42, 0x63, 0x57, 0x67, 0xb5, 0x89, 0x95, 0x35, 0x8d, 0xfb, 0x7a, 0xdd, 0xde, - 0x6e, 0x75, 0xd4, 0x7c, 0xb9, 0x41, 0xcf, 0x77, 0x0c, 0xe5, 0xcc, 0x2c, 0x0b, 0x8b, 0x50, 0x68, - 0xb6, 0x9a, 0x46, 0xf2, 0x71, 0x71, 0x05, 0x8a, 0x7a, 0xbb, 0x6d, 0xb6, 0xf6, 0x71, 0x8a, 0x01, - 0x2c, 0xee, 0x18, 0x4d, 0x5a, 0xb3, 0x3c, 0x2d, 0x69, 0x9b, 0xad, 0x46, 0xab, 0x63, 0xec, 0xa8, - 0x85, 0xb2, 0x29, 0x96, 0xb0, 0x60, 0xda, 0xf3, 0xd9, 0x4b, 0xde, 0x8e, 0xb1, 0xab, 0x77, 0xeb, - 0x1d, 0x3e, 0x44, 0x0f, 0x6c, 0xd3, 0xf8, 0x74, 0xd7, 0xb0, 0x3a, 0x96, 0xaa, 0x10, 0x15, 0x56, - 0x9a, 0x86, 0xb1, 0x63, 0xd9, 0xa6, 0xb1, 0x5f, 0x33, 0xee, 0xab, 0x39, 0xca, 0x93, 0xfd, 0x4f, - 0xbf, 0x50, 0xfe, 0x9e, 0x02, 0x84, 0x85, 0xc1, 0x16, 0xb9, 0x95, 0x70, 0xc6, 0x5c, 0x86, 0xf3, - 0x55, 0x3a, 0xd4, 0xd8, 0xb4, 0x46, 0x6b, 0x27, 0xd9, 0x65, 0xe7, 0x80, 0x24, 0xca, 0x5b, 0xbb, - 0xbb, 0xaa, 0x42, 0x2e, 0xc0, 0xe9, 0x04, 0x7c, 0xc7, 0x6c, 0xb5, 0xd5, 0xdc, 0xf9, 0x5c, 0x51, - 0x21, 0x9b, 0xa9, 0xc2, 0x7b, 0x86, 0xd1, 0x56, 0xf3, 0x74, 0x88, 0x12, 0x05, 0x62, 0x49, 0x30, - 0xf2, 0x42, 0xf9, 0x9b, 0x0a, 0x9c, 0x63, 0xd5, 0x14, 0xeb, 0x2b, 0xac, 0xea, 0x45, 0xd8, 0xe2, - 0xc1, 0xfd, 0xb3, 0x2a, 0x7a, 0x06, 0xd4, 0x58, 0x29, 0xab, 0xe6, 0x59, 0xd8, 0x88, 0x41, 0xb1, - 0x1e, 0x39, 0xba, 0x7b, 0xc4, 0xc0, 0xdb, 0x86, 0xd5, 0xb1, 0x8d, 0xdd, 0xdd, 0x96, 0xd9, 0x61, - 0x15, 0xc9, 0x97, 0x35, 0xd8, 0xa8, 0xb8, 0xe3, 0x09, 0xbd, 0x7a, 0x0d, 0x03, 0xcf, 0x1f, 0x62, - 0x15, 0x56, 0x61, 0xd9, 0xf8, 0x4c, 0xc7, 0x68, 0x5a, 0xb5, 0x56, 0x53, 0x3d, 0x55, 0xbe, 0x98, - 0xc0, 0x11, 0xeb, 0xd8, 0xb2, 0xaa, 0xea, 0xa9, 0xb2, 0x03, 0xab, 0xc2, 0xf0, 0x9a, 0xcd, 0x8a, - 0xcb, 0x70, 0x5e, 0xcc, 0x35, 0xdc, 0x51, 0x92, 0x4d, 0xd8, 0x82, 0x33, 0xe9, 0x72, 0xa3, 0xa3, - 0x2a, 0x74, 0x14, 0x12, 0x25, 0x14, 0x9e, 0x2b, 0xff, 0x7f, 0x05, 0x56, 0xc3, 0x47, 0x13, 0x54, - 0xd3, 0x5e, 0x81, 0x0b, 0x8d, 0x5d, 0xdd, 0xde, 0x31, 0xf6, 0x6b, 0x15, 0xc3, 0xbe, 0x57, 0x6b, - 0xee, 0x24, 0x3e, 0xf2, 0x1c, 0x9c, 0xcd, 0x40, 0xc0, 0xaf, 0x6c, 0xc1, 0x99, 0x64, 0x51, 0x87, - 0x2e, 0xd5, 0x1c, 0xed, 0xfa, 0x64, 0x49, 0xb8, 0x4e, 0xf3, 0xe5, 0x7d, 0x58, 0xb3, 0xf4, 0x46, - 0x7d, 0xd7, 0x1f, 0xf7, 0x5c, 0x7d, 0x3a, 0x39, 0x1a, 0x92, 0x0b, 0xb0, 0xb9, 0xdb, 0x32, 0x2b, - 0x86, 0x8d, 0x28, 0x89, 0x1a, 0x9c, 0x86, 0x75, 0xb9, 0xf0, 0x81, 0x41, 0xa7, 0x2f, 0x81, 0x35, - 0x19, 0xd8, 0x6c, 0xa9, 0xb9, 0xf2, 0xe7, 0x60, 0x25, 0x96, 0x62, 0x71, 0x13, 0x4e, 0xcb, 0xbf, - 0xdb, 0xee, 0xb0, 0xef, 0x0d, 0x0f, 0xd5, 0x53, 0xc9, 0x02, 0x73, 0x3a, 0x1c, 0xd2, 0x02, 0x5c, - 0xcf, 0x72, 0x41, 0xc7, 0x1d, 0x1f, 0x7b, 0x43, 0x67, 0xe2, 0xf6, 0xd5, 0x5c, 0xf9, 0x15, 0x58, - 0x8d, 0x05, 0x76, 0xa7, 0x03, 0x57, 0x6f, 0xf1, 0x0d, 0xb8, 0x61, 0xec, 0xd4, 0xba, 0x0d, 0x75, - 0x81, 0xae, 0xe4, 0x6a, 0x6d, 0xaf, 0xaa, 0x42, 0xf9, 0x3b, 0x0a, 0xbd, 0x67, 0x60, 0xba, 0xa6, - 0xc6, 0xae, 0x2e, 0x86, 0x9a, 0x4e, 0x33, 0x96, 0x2e, 0xc2, 0xb0, 0x2c, 0xf6, 0xa6, 0x7e, 0x11, - 0xb6, 0xf8, 0x0f, 0x5b, 0x6f, 0xee, 0xd8, 0x55, 0xdd, 0xdc, 0xb9, 0xaf, 0x9b, 0x74, 0xee, 0x3d, - 0x50, 0x73, 0xb8, 0xa0, 0x24, 0x88, 0xdd, 0x69, 0x75, 0x2b, 0x55, 0x35, 0x4f, 0xe7, 0x6f, 0x0c, - 0xde, 0xae, 0x35, 0xd5, 0x02, 0x2e, 0xcf, 0x14, 0x36, 0xb2, 0xa5, 0xe5, 0x0b, 0xe5, 0x77, 0x15, - 0xd8, 0xb4, 0xbc, 0xc3, 0xa1, 0x33, 0x99, 0x8e, 0x5d, 0x7d, 0x70, 0xe8, 0x8f, 0xbd, 0xc9, 0xd1, - 0xb1, 0x35, 0xf5, 0x26, 0x2e, 0xb9, 0x09, 0x2f, 0x5a, 0xb5, 0xbd, 0xa6, 0xde, 0xa1, 0xcb, 0x4b, - 0xaf, 0xef, 0xb5, 0xcc, 0x5a, 0xa7, 0xda, 0xb0, 0xad, 0x6e, 0x2d, 0x35, 0xf3, 0xae, 0xc1, 0xf3, - 0xb3, 0x51, 0xeb, 0xc6, 0x9e, 0x5e, 0x79, 0xa0, 0x2a, 0xf3, 0x19, 0x6e, 0xeb, 0x75, 0xbd, 0x59, - 0x31, 0x76, 0xec, 0xfd, 0x5b, 0x6a, 0x8e, 0xbc, 0x08, 0x57, 0x67, 0xa3, 0xee, 0xd6, 0xda, 0x16, - 0x45, 0xcb, 0xcf, 0xff, 0x6e, 0xd5, 0x6a, 0x50, 0xac, 0x42, 0xf9, 0x8f, 0x14, 0xd8, 0x9a, 0x15, - 0xdd, 0x8b, 0x5c, 0x07, 0xcd, 0x68, 0x76, 0x4c, 0xbd, 0xb6, 0x63, 0x57, 0x4c, 0x63, 0xc7, 0x68, - 0x76, 0x6a, 0x7a, 0xdd, 0xb2, 0xad, 0x56, 0x97, 0xce, 0xa6, 0xc8, 0xf4, 0xe1, 0x05, 0xb8, 0x32, - 0x07, 0xaf, 0x55, 0xdb, 0xa9, 0xa8, 0x0a, 0xb9, 0x05, 0x2f, 0xcf, 0x41, 0xb2, 0x1e, 0x58, 0x1d, - 0xa3, 0x21, 0x97, 0xa8, 0x39, 0xdc, 0xb0, 0xb2, 0x83, 0x1b, 0xd1, 0xd6, 0x61, 0xc9, 0xfc, 0x8a, - 0x5d, 0x85, 0x4b, 0x33, 0xb1, 0x78, 0xb5, 0x5e, 0x80, 0x2b, 0x33, 0x51, 0x58, 0xa5, 0xd4, 0x5c, - 0xb9, 0x02, 0xe7, 0x67, 0x47, 0x8b, 0xa1, 0xe7, 0x45, 0x7c, 0xc8, 0x8b, 0x50, 0xd8, 0xa1, 0x47, - 0x54, 0x2c, 0xbd, 0x49, 0xd9, 0x03, 0x35, 0x19, 0xf0, 0x21, 0x65, 0x2c, 0x63, 0x76, 0x9b, 0x4d, - 0x76, 0x9e, 0xad, 0x43, 0xa9, 0xd5, 0xa9, 0x1a, 0x26, 0x4f, 0x10, 0x83, 0x19, 0x61, 0xba, 0x4d, - 0xba, 0x82, 0x5b, 0x66, 0xed, 0xb3, 0x78, 0xb0, 0x6d, 0xc1, 0x19, 0xab, 0xae, 0x57, 0xee, 0xd9, - 0xcd, 0x56, 0xc7, 0xae, 0x35, 0xed, 0x4a, 0x55, 0x6f, 0x36, 0x8d, 0xba, 0x0a, 0x38, 0xaa, 0xb3, - 0x9c, 0x3c, 0xc9, 0x07, 0xe1, 0x46, 0xeb, 0x5e, 0x47, 0xb7, 0xdb, 0xf5, 0xee, 0x5e, 0xad, 0x69, - 0x5b, 0x0f, 0x9a, 0x15, 0x21, 0x84, 0x55, 0xd2, 0x7b, 0xff, 0x0d, 0xb8, 0x36, 0x17, 0x3b, 0x4a, - 0xe5, 0x72, 0x1d, 0xb4, 0xb9, 0x98, 0xbc, 0x21, 0xe5, 0x1f, 0x2b, 0x70, 0x61, 0xce, 0x63, 0x36, - 0x79, 0x19, 0x6e, 0x56, 0x0d, 0x7d, 0xa7, 0x6e, 0x58, 0x16, 0xee, 0x58, 0x74, 0x50, 0x98, 0x51, - 0x4d, 0xe6, 0xce, 0x7e, 0x13, 0x5e, 0x9c, 0x8f, 0x1e, 0xc9, 0x08, 0x37, 0xe0, 0xda, 0x7c, 0x54, - 0x2e, 0x33, 0xe4, 0x48, 0x19, 0xae, 0xcf, 0xc7, 0x0c, 0x65, 0x8d, 0x7c, 0xf9, 0xb7, 0x14, 0x38, - 0x97, 0xad, 0x51, 0xa2, 0x75, 0xab, 0x35, 0xad, 0x8e, 0x5e, 0xaf, 0xdb, 0x6d, 0xdd, 0xd4, 0x1b, - 0xb6, 0xd1, 0x34, 0x5b, 0xf5, 0x7a, 0xd6, 0x19, 0x7b, 0x0d, 0x9e, 0x9f, 0x8d, 0x6a, 0x55, 0xcc, - 0x5a, 0x9b, 0x1e, 0x23, 0x1a, 0x5c, 0x9e, 0x8d, 0x65, 0xd4, 0x2a, 0x86, 0x9a, 0xdb, 0x7e, 0xf3, - 0x87, 0xff, 0x70, 0xf9, 0xd4, 0x0f, 0xdf, 0xbd, 0xac, 0xfc, 0xe4, 0xdd, 0xcb, 0xca, 0xdf, 0xbf, - 0x7b, 0x59, 0xf9, 0xec, 0x4b, 0x27, 0xcb, 0x82, 0x86, 0x17, 0x90, 0x47, 0x8b, 0x78, 0x55, 0x7a, - 0xf5, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x64, 0x7a, 0x4b, 0x16, 0xcb, 0xc0, 0x01, 0x00, + // 30581 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xfd, 0x7d, 0x70, 0x1c, 0x49, + 0x76, 0x20, 0x86, 0x4f, 0x77, 0xe3, 0xa3, 0xf1, 0xf0, 0xd5, 0x48, 0x80, 0x24, 0x88, 0x99, 0x61, + 0x73, 0x6a, 0x66, 0x38, 0xe4, 0xec, 0x0c, 0xb9, 0x04, 0x77, 0xb8, 0x3b, 0x3b, 0x5f, 0xdb, 0xe8, + 0x06, 0x89, 0x26, 0x41, 0x00, 0x53, 0x0d, 0x10, 0x3b, 0xda, 0x8f, 0xda, 0x42, 0x77, 0x02, 0xa8, + 0x41, 0x77, 0x57, 0x6f, 0x55, 0x35, 0x41, 0x68, 0x4f, 0xbf, 0xd3, 0xd7, 0x9e, 0x7e, 0x0a, 0x59, + 0x9f, 0x27, 0x9d, 0x74, 0x0e, 0x9d, 0xac, 0x90, 0xef, 0x7c, 0x8a, 0x73, 0x48, 0x71, 0x96, 0x2c, + 0xfb, 0x6c, 0x85, 0x65, 0xc9, 0x21, 0xcb, 0xb2, 0xe2, 0xe2, 0xa4, 0x38, 0x9f, 0xed, 0xf0, 0xfa, + 0x0c, 0x59, 0x96, 0xff, 0x70, 0x20, 0xc2, 0x11, 0x92, 0x2f, 0xc2, 0x11, 0x5e, 0x87, 0xee, 0x1c, + 0xf9, 0x32, 0xb3, 0x2a, 0xb3, 0xaa, 0xba, 0xd1, 0x98, 0xe1, 0xe8, 0xc4, 0x0d, 0xfd, 0x43, 0xa2, + 0x5f, 0xbe, 0xf7, 0xb2, 0xf2, 0xfb, 0xe5, 0xcb, 0xf7, 0x01, 0x2f, 0x04, 0xb4, 0x49, 0x3b, 0xae, + 0x17, 0xdc, 0x68, 0xd2, 0x3d, 0xbb, 0x7e, 0x74, 0x23, 0x38, 0xea, 0x50, 0x9f, 0xff, 0x7b, 0xbd, + 0xe3, 0xb9, 0x81, 0x4b, 0x86, 0xf1, 0xc7, 0xc2, 0xdc, 0x9e, 0xbb, 0xe7, 0x22, 0xe4, 0x06, 0xfb, + 0x8b, 0x17, 0x2e, 0x5c, 0xda, 0x73, 0xdd, 0xbd, 0x26, 0xbd, 0x81, 0xbf, 0x76, 0xba, 0xbb, 0x37, + 0x1a, 0x5d, 0xcf, 0x0e, 0x1c, 0xb7, 0x2d, 0xca, 0x8b, 0xf1, 0xf2, 0xc0, 0x69, 0x51, 0x3f, 0xb0, + 0x5b, 0x9d, 0x5e, 0x0c, 0x0e, 0x3d, 0xbb, 0xd3, 0xa1, 0x9e, 0xa8, 0x7d, 0xe1, 0x5a, 0xf8, 0x81, + 0x76, 0x10, 0x30, 0x4a, 0xc6, 0xfc, 0xc6, 0xa3, 0x9b, 0xea, 0x4f, 0x81, 0x7a, 0xbb, 0x47, 0x5b, + 0xbc, 0xae, 0x1f, 0xd0, 0x86, 0xd5, 0xa0, 0x8f, 0x9c, 0x3a, 0xb5, 0x3c, 0xfa, 0xf5, 0xae, 0xe3, + 0xd1, 0x16, 0x6d, 0x07, 0x82, 0xee, 0xf5, 0x74, 0x3a, 0xf9, 0x21, 0xb1, 0x2f, 0x32, 0x7e, 0x21, + 0x07, 0x63, 0xf7, 0x29, 0xed, 0x94, 0x9a, 0xce, 0x23, 0x4a, 0x5e, 0x84, 0xa1, 0x35, 0xbb, 0x45, + 0xe7, 0x33, 0x97, 0x33, 0x57, 0xc7, 0x96, 0xa6, 0x4f, 0x8e, 0x8b, 0xe3, 0x3e, 0xf5, 0x1e, 0x51, + 0xcf, 0x6a, 0xdb, 0x2d, 0x6a, 0x62, 0x21, 0xf9, 0x14, 0x8c, 0xb1, 0xff, 0xfd, 0x8e, 0x5d, 0xa7, + 0xf3, 0x59, 0xc4, 0x9c, 0x3c, 0x39, 0x2e, 0x8e, 0xb5, 0x25, 0xd0, 0x8c, 0xca, 0x49, 0x15, 0x46, + 0x97, 0x1f, 0x77, 0x1c, 0x8f, 0xfa, 0xf3, 0x43, 0x97, 0x33, 0x57, 0xc7, 0x17, 0x17, 0xae, 0xf3, + 0x3e, 0xba, 0x2e, 0xfb, 0xe8, 0xfa, 0xa6, 0xec, 0xc4, 0xa5, 0xd9, 0xdf, 0x3f, 0x2e, 0x3e, 0x73, + 0x72, 0x5c, 0x1c, 0xa5, 0x9c, 0xe4, 0x27, 0xfe, 0xb8, 0x98, 0x31, 0x25, 0x3d, 0x79, 0x1b, 0x86, + 0x36, 0x8f, 0x3a, 0x74, 0x7e, 0xec, 0x72, 0xe6, 0xea, 0xd4, 0xe2, 0xa5, 0xeb, 0x7c, 0x58, 0xc3, + 0x8f, 0x8f, 0xfe, 0x62, 0x58, 0x4b, 0xf9, 0x93, 0xe3, 0xe2, 0x10, 0x43, 0x31, 0x91, 0x8a, 0xbc, + 0x0e, 0x23, 0x2b, 0xae, 0x1f, 0x54, 0x2b, 0xf3, 0x80, 0x9f, 0x7c, 0xee, 0xe4, 0xb8, 0x38, 0xb3, + 0xef, 0xfa, 0x81, 0xe5, 0x34, 0x5e, 0x73, 0x5b, 0x4e, 0x40, 0x5b, 0x9d, 0xe0, 0xc8, 0x14, 0x48, + 0xc6, 0x63, 0x98, 0xd4, 0xf8, 0x91, 0x71, 0x18, 0xdd, 0x5a, 0xbb, 0xbf, 0xb6, 0xbe, 0xbd, 0x56, + 0x78, 0x86, 0xe4, 0x61, 0x68, 0x6d, 0xbd, 0xb2, 0x5c, 0xc8, 0x90, 0x51, 0xc8, 0x95, 0x36, 0x36, + 0x0a, 0x59, 0x32, 0x01, 0xf9, 0x4a, 0x69, 0xb3, 0xb4, 0x54, 0xaa, 0x2d, 0x17, 0x72, 0x64, 0x16, + 0xa6, 0xb7, 0xab, 0x6b, 0x95, 0xf5, 0xed, 0x9a, 0x55, 0x59, 0xae, 0xdd, 0xdf, 0x5c, 0xdf, 0x28, + 0x0c, 0x91, 0x29, 0x80, 0xfb, 0x5b, 0x4b, 0xcb, 0xe6, 0xda, 0xf2, 0xe6, 0x72, 0xad, 0x30, 0x4c, + 0xe6, 0xa0, 0x20, 0x49, 0xac, 0xda, 0xb2, 0xf9, 0xb0, 0x5a, 0x5e, 0x2e, 0x8c, 0xdc, 0x1b, 0xca, + 0xe7, 0x0a, 0x43, 0xe6, 0xe8, 0x2a, 0xb5, 0x7d, 0x5a, 0xad, 0x18, 0xff, 0x7e, 0x0e, 0xf2, 0x0f, + 0x68, 0x60, 0x37, 0xec, 0xc0, 0x26, 0xcf, 0x69, 0xe3, 0x83, 0x4d, 0x54, 0x06, 0xe6, 0xc5, 0xe4, + 0xc0, 0x0c, 0x9f, 0x1c, 0x17, 0x33, 0xaf, 0xab, 0x03, 0xf2, 0x16, 0x8c, 0x57, 0xa8, 0x5f, 0xf7, + 0x9c, 0x0e, 0x9b, 0x6c, 0xf3, 0x39, 0x44, 0xbb, 0x78, 0x72, 0x5c, 0x3c, 0xd7, 0x88, 0xc0, 0x4a, + 0x87, 0xa8, 0xd8, 0xa4, 0x0a, 0x23, 0xab, 0xf6, 0x0e, 0x6d, 0xfa, 0xf3, 0xc3, 0x97, 0x73, 0x57, + 0xc7, 0x17, 0x9f, 0x15, 0x83, 0x20, 0x3f, 0xf0, 0x3a, 0x2f, 0x5d, 0x6e, 0x07, 0xde, 0xd1, 0xd2, + 0xdc, 0xc9, 0x71, 0xb1, 0xd0, 0x44, 0x80, 0xda, 0xc1, 0x1c, 0x85, 0xd4, 0xa2, 0x89, 0x31, 0x72, + 0xea, 0xc4, 0x78, 0xfe, 0xf7, 0x8f, 0x8b, 0x19, 0x36, 0x60, 0x62, 0x62, 0x44, 0xfc, 0xf4, 0x29, + 0xb2, 0x08, 0x79, 0x93, 0x3e, 0x72, 0x7c, 0xd6, 0xb2, 0x3c, 0xb6, 0xec, 0xfc, 0xc9, 0x71, 0x91, + 0x78, 0x02, 0xa6, 0x7c, 0x46, 0x88, 0xb7, 0xf0, 0x26, 0x8c, 0x2b, 0x5f, 0x4d, 0x0a, 0x90, 0x3b, + 0xa0, 0x47, 0xbc, 0x87, 0x4d, 0xf6, 0x27, 0x99, 0x83, 0xe1, 0x47, 0x76, 0xb3, 0x2b, 0xba, 0xd4, + 0xe4, 0x3f, 0x3e, 0x9f, 0xfd, 0x5c, 0xe6, 0xde, 0x50, 0x7e, 0xb4, 0x90, 0x37, 0xb3, 0xd5, 0x8a, + 0xf1, 0x53, 0x43, 0x90, 0x37, 0x5d, 0xbe, 0x80, 0xc9, 0x35, 0x18, 0xae, 0x05, 0x76, 0x20, 0x87, + 0x69, 0xf6, 0xe4, 0xb8, 0x38, 0xcd, 0x16, 0x37, 0x55, 0xea, 0xe7, 0x18, 0x0c, 0x75, 0x63, 0xdf, + 0xf6, 0xe5, 0x70, 0x21, 0x6a, 0x87, 0x01, 0x54, 0x54, 0xc4, 0x20, 0x57, 0x60, 0xe8, 0x81, 0xdb, + 0xa0, 0x62, 0xc4, 0xc8, 0xc9, 0x71, 0x71, 0xaa, 0xe5, 0x36, 0x54, 0x44, 0x2c, 0x27, 0xaf, 0xc1, + 0x58, 0xb9, 0xeb, 0x79, 0xb4, 0xcd, 0xe6, 0xfa, 0x10, 0x22, 0x4f, 0x9d, 0x1c, 0x17, 0xa1, 0xce, + 0x81, 0x96, 0xd3, 0x30, 0x23, 0x04, 0x36, 0x0c, 0xb5, 0xc0, 0xf6, 0x02, 0xda, 0x98, 0x1f, 0x1e, + 0x68, 0x18, 0xd8, 0xfa, 0x9c, 0xf1, 0x39, 0x49, 0x7c, 0x18, 0x04, 0x27, 0xb2, 0x02, 0xe3, 0x77, + 0x3d, 0xbb, 0x4e, 0x37, 0xa8, 0xe7, 0xb8, 0x0d, 0x1c, 0xdf, 0xdc, 0xd2, 0x95, 0x93, 0xe3, 0xe2, + 0xf9, 0x3d, 0x06, 0xb6, 0x3a, 0x08, 0x8f, 0xa8, 0xbf, 0x7d, 0x5c, 0xcc, 0x57, 0xc4, 0x56, 0x6b, + 0xaa, 0xa4, 0xe4, 0x6b, 0x6c, 0x70, 0xfc, 0x00, 0xbb, 0x96, 0x36, 0xe6, 0x47, 0x4f, 0xfd, 0x44, + 0x43, 0x7c, 0xe2, 0xf9, 0xa6, 0xed, 0x07, 0x96, 0xc7, 0xe9, 0x62, 0xdf, 0xa9, 0xb2, 0x24, 0xeb, + 0x90, 0xaf, 0xd5, 0xf7, 0x69, 0xa3, 0xdb, 0xa4, 0x38, 0x65, 0xc6, 0x17, 0x2f, 0x88, 0x49, 0x2d, + 0xc7, 0x53, 0x16, 0x2f, 0x2d, 0x08, 0xde, 0xc4, 0x17, 0x10, 0x75, 0x3e, 0x49, 0xac, 0xcf, 0xe7, + 0x7f, 0xee, 0x17, 0x8b, 0xcf, 0x7c, 0xef, 0xbf, 0xbc, 0xfc, 0x8c, 0xf1, 0x9f, 0x66, 0xa1, 0x10, + 0x67, 0x42, 0x76, 0x61, 0x72, 0xab, 0xd3, 0xb0, 0x03, 0x5a, 0x6e, 0x3a, 0xb4, 0x1d, 0xf8, 0x38, + 0x49, 0xfa, 0xb7, 0xe9, 0x25, 0x51, 0xef, 0x7c, 0x17, 0x09, 0xad, 0x3a, 0xa7, 0x8c, 0xb5, 0x4a, + 0x67, 0x1b, 0xd5, 0x53, 0xc3, 0x0d, 0xdc, 0xc7, 0x19, 0x76, 0xb6, 0x7a, 0xf8, 0xd6, 0xdf, 0xa3, + 0x1e, 0xc1, 0x56, 0x4c, 0xa0, 0x76, 0x63, 0xe7, 0x08, 0x67, 0xe6, 0xe0, 0x13, 0x88, 0x91, 0xa4, + 0x4c, 0x20, 0x06, 0x36, 0xfe, 0xf7, 0x0c, 0x4c, 0x99, 0xd4, 0x77, 0xbb, 0x5e, 0x9d, 0xae, 0x50, + 0xbb, 0x41, 0x3d, 0x36, 0xfd, 0xef, 0x3b, 0xed, 0x86, 0x58, 0x53, 0x38, 0xfd, 0x0f, 0x9c, 0xb6, + 0xba, 0x75, 0x63, 0x39, 0xf9, 0x34, 0x8c, 0xd6, 0xba, 0x3b, 0x88, 0x9a, 0x8d, 0x76, 0x00, 0xbf, + 0xbb, 0x63, 0xc5, 0xd0, 0x25, 0x1a, 0xb9, 0x01, 0xa3, 0x0f, 0xa9, 0xe7, 0x47, 0xbb, 0x21, 0x1e, + 0x0d, 0x8f, 0x38, 0x48, 0x25, 0x10, 0x58, 0xe4, 0x6e, 0xb4, 0x23, 0x8b, 0x43, 0x6d, 0x3a, 0xb6, + 0x0f, 0x46, 0x53, 0xa5, 0x25, 0x20, 0xea, 0x54, 0x91, 0x58, 0xc6, 0x4f, 0x66, 0xa1, 0x50, 0xb1, + 0x03, 0x7b, 0xc7, 0xf6, 0x45, 0x7f, 0x3e, 0xbc, 0xc5, 0xf6, 0x78, 0xa5, 0xa1, 0xb8, 0xc7, 0xb3, + 0x2f, 0xff, 0xc8, 0xcd, 0x7b, 0x39, 0xde, 0xbc, 0x71, 0x76, 0xc2, 0x8a, 0xe6, 0x45, 0x8d, 0x7a, + 0xe7, 0xf4, 0x46, 0x15, 0x44, 0xa3, 0xf2, 0xb2, 0x51, 0x51, 0x53, 0xc8, 0x3b, 0x30, 0x54, 0xeb, + 0xd0, 0xba, 0xd8, 0x44, 0xe4, 0xb9, 0xa0, 0x37, 0x8e, 0x21, 0x3c, 0xbc, 0xb5, 0x34, 0x21, 0xd8, + 0x0c, 0xf9, 0x1d, 0x5a, 0x37, 0x91, 0x4c, 0x59, 0x34, 0xff, 0x24, 0x07, 0x73, 0x69, 0x64, 0x6a, + 0x3b, 0x46, 0xfa, 0xb4, 0xe3, 0x2a, 0xe4, 0xd9, 0x11, 0xce, 0x8e, 0x45, 0xdc, 0x2e, 0xc6, 0x96, + 0x26, 0xd8, 0x27, 0xef, 0x0b, 0x98, 0x19, 0x96, 0x92, 0x17, 0x43, 0x89, 0x20, 0x1f, 0xf1, 0x13, + 0x12, 0x81, 0x94, 0x03, 0xd8, 0x58, 0xcb, 0x25, 0x8c, 0x82, 0x43, 0xd4, 0x2d, 0x12, 0x1c, 0x8d, + 0xb5, 0x27, 0x20, 0xda, 0x31, 0x23, 0x0f, 0x85, 0x65, 0xc8, 0xcb, 0x66, 0xcd, 0x4f, 0x20, 0xa3, + 0x99, 0x58, 0x27, 0x3d, 0xbc, 0xc5, 0x07, 0xb3, 0x21, 0x7e, 0xab, 0x6c, 0x24, 0x0e, 0xb9, 0x05, + 0xf9, 0x0d, 0xcf, 0x7d, 0x7c, 0x54, 0xad, 0xf8, 0xf3, 0x93, 0x97, 0x73, 0x57, 0xc7, 0x96, 0x2e, + 0x9c, 0x1c, 0x17, 0x67, 0x3b, 0x0c, 0x66, 0x39, 0x0d, 0xf5, 0xa4, 0x0d, 0x11, 0xef, 0x0d, 0xe5, + 0x33, 0x85, 0xec, 0xbd, 0xa1, 0x7c, 0xb6, 0x90, 0xe3, 0xe2, 0xc5, 0xbd, 0xa1, 0xfc, 0x50, 0x61, + 0xf8, 0xde, 0x50, 0x7e, 0x18, 0x05, 0x8e, 0xb1, 0x02, 0xdc, 0x1b, 0xca, 0x8f, 0x17, 0x26, 0xb4, + 0xd3, 0x1e, 0x19, 0x04, 0x6e, 0xdd, 0x6d, 0x9a, 0xb9, 0x2d, 0xb3, 0x6a, 0x8e, 0x94, 0x4b, 0x65, + 0xea, 0x05, 0x66, 0xae, 0xb4, 0x5d, 0x33, 0x27, 0x2b, 0x47, 0x6d, 0xbb, 0xe5, 0xd4, 0xf9, 0xd1, + 0x69, 0xe6, 0xee, 0x96, 0x37, 0x8c, 0x12, 0x4c, 0x45, 0x6d, 0x59, 0x75, 0xfc, 0x80, 0xdc, 0x80, + 0x31, 0x09, 0x61, 0x1b, 0x5d, 0x2e, 0xb5, 0xd5, 0x66, 0x84, 0x63, 0xfc, 0x5e, 0x16, 0x20, 0x2a, + 0x79, 0x4a, 0xd7, 0xc2, 0x67, 0xb5, 0xb5, 0x70, 0x2e, 0xbe, 0x16, 0x7a, 0xae, 0x02, 0xf2, 0x1e, + 0x8c, 0x30, 0xb1, 0xa0, 0x2b, 0x45, 0xa2, 0x0b, 0x71, 0x52, 0x2c, 0x7c, 0x78, 0x6b, 0x69, 0x4a, + 0x10, 0x8f, 0xf8, 0x08, 0x31, 0x05, 0x99, 0xb2, 0x8c, 0x7e, 0x61, 0x34, 0x1a, 0x0c, 0xb1, 0x80, + 0xae, 0x42, 0x38, 0xa0, 0xa2, 0x43, 0x71, 0x65, 0x74, 0xe4, 0x20, 0x87, 0xa5, 0xe4, 0x22, 0xb0, + 0x01, 0x17, 0x9d, 0x3a, 0x7a, 0x72, 0x5c, 0xcc, 0x75, 0x3d, 0x07, 0x27, 0x01, 0xb9, 0x01, 0x62, + 0x1a, 0x88, 0x0e, 0x64, 0xb3, 0x6f, 0xa6, 0x6e, 0x5b, 0x75, 0xea, 0x05, 0x51, 0x8f, 0xcf, 0x67, + 0xe4, 0x6c, 0x21, 0x1d, 0xd0, 0xa7, 0xca, 0xfc, 0x10, 0x4e, 0x83, 0xab, 0xa9, 0xbd, 0x72, 0x5d, + 0x43, 0xe5, 0x62, 0xe4, 0x65, 0x79, 0x2a, 0x35, 0x78, 0x99, 0x95, 0x10, 0x29, 0xf5, 0x0a, 0xc8, + 0x2d, 0x60, 0x33, 0x54, 0xf4, 0x3e, 0x88, 0x7a, 0x4a, 0xdb, 0xb5, 0xa5, 0x73, 0x82, 0xd3, 0xa4, + 0x7d, 0xa8, 0x92, 0x33, 0x6c, 0xf2, 0x16, 0xb0, 0x29, 0x2c, 0xfa, 0x9d, 0x08, 0xa2, 0xbb, 0xe5, + 0x8d, 0x72, 0xd3, 0xed, 0x36, 0x6a, 0xef, 0xaf, 0x46, 0xc4, 0x7b, 0xf5, 0x8e, 0x4a, 0x7c, 0xb7, + 0xbc, 0x41, 0xde, 0x82, 0xe1, 0xd2, 0x77, 0x77, 0x3d, 0x2a, 0xe4, 0x93, 0x09, 0x59, 0x27, 0x83, + 0x2d, 0x5d, 0x10, 0x84, 0xd3, 0x36, 0xfb, 0xa9, 0xca, 0x75, 0x58, 0xce, 0x6a, 0xde, 0x5c, 0xad, + 0x09, 0xd9, 0x83, 0xc4, 0xba, 0x65, 0x73, 0x55, 0xf9, 0xec, 0x40, 0x6b, 0x35, 0xa3, 0x22, 0x37, + 0x20, 0x5b, 0xaa, 0xe0, 0x8d, 0x68, 0x7c, 0x71, 0x4c, 0x56, 0x5b, 0x59, 0x9a, 0x13, 0x24, 0x13, + 0xb6, 0xba, 0x0c, 0xb2, 0xa5, 0x0a, 0x59, 0x82, 0xe1, 0x07, 0x47, 0xb5, 0xf7, 0x57, 0xc5, 0x66, + 0x36, 0x2b, 0xe7, 0x35, 0x83, 0xad, 0xe3, 0xb2, 0xf7, 0xa3, 0x2f, 0x6e, 0x1d, 0xf9, 0x5f, 0x6f, + 0xaa, 0x5f, 0x8c, 0x68, 0x64, 0x03, 0xc6, 0x4a, 0x8d, 0x96, 0xd3, 0xde, 0xf2, 0xa9, 0x37, 0x3f, + 0x8e, 0x7c, 0xe6, 0x63, 0xdf, 0x1d, 0x96, 0x2f, 0xcd, 0x9f, 0x1c, 0x17, 0xe7, 0x6c, 0xf6, 0xd3, + 0xea, 0xfa, 0xd4, 0x53, 0xb8, 0x45, 0x4c, 0xc8, 0x06, 0xc0, 0x03, 0xb7, 0xbd, 0xe7, 0x96, 0x82, + 0xa6, 0xed, 0xc7, 0xb6, 0xc7, 0xa8, 0x20, 0x14, 0x1f, 0xce, 0xb5, 0x18, 0xcc, 0xb2, 0x19, 0x50, + 0x61, 0xa8, 0xf0, 0x20, 0x77, 0x60, 0x64, 0xdd, 0xb3, 0xeb, 0x4d, 0x3a, 0x3f, 0x89, 0xdc, 0xe6, + 0x04, 0x37, 0x0e, 0x94, 0x2d, 0x9d, 0x17, 0x0c, 0x0b, 0x2e, 0x82, 0xd5, 0x6b, 0x0a, 0x47, 0x5c, + 0xd8, 0x06, 0x92, 0x9c, 0x93, 0x29, 0x97, 0x84, 0x4f, 0xa9, 0x97, 0x84, 0x68, 0xd1, 0x97, 0xdd, + 0x56, 0xcb, 0x6e, 0x37, 0x90, 0xf6, 0xe1, 0xa2, 0x72, 0x77, 0x30, 0xbe, 0x0e, 0x33, 0x89, 0xce, + 0x3a, 0xe5, 0x7e, 0xf7, 0x2e, 0x4c, 0x57, 0xe8, 0xae, 0xdd, 0x6d, 0x06, 0xe1, 0x49, 0xc2, 0x97, + 0x28, 0xde, 0xb4, 0x1a, 0xbc, 0xc8, 0x92, 0xc7, 0x87, 0x19, 0x47, 0x36, 0xde, 0x81, 0x49, 0xad, + 0xf9, 0xec, 0xaa, 0x50, 0xea, 0x36, 0x9c, 0x00, 0x07, 0x32, 0x13, 0x5d, 0x15, 0x6c, 0x06, 0xc4, + 0xe1, 0x32, 0x23, 0x04, 0xe3, 0xef, 0xab, 0xd2, 0x8a, 0xd8, 0x89, 0xd8, 0xb5, 0x5a, 0xec, 0x07, + 0x99, 0x48, 0x76, 0x4a, 0xec, 0x07, 0xe1, 0x6e, 0x70, 0x8d, 0xaf, 0xcd, 0x6c, 0x62, 0x6d, 0x8e, + 0x8b, 0x91, 0xc8, 0xd9, 0x87, 0x3e, 0x5f, 0x91, 0xe1, 0x4c, 0xcd, 0x7d, 0xf4, 0x99, 0xfa, 0x1e, + 0x4c, 0x3c, 0xb0, 0xdb, 0xf6, 0x1e, 0x6d, 0xb0, 0x16, 0xf0, 0xbd, 0x67, 0x6c, 0xe9, 0xd9, 0x93, + 0xe3, 0xe2, 0x85, 0x16, 0x87, 0x63, 0x2b, 0xd5, 0x49, 0xa4, 0x11, 0x90, 0x9b, 0x72, 0x65, 0x0f, + 0xa7, 0xac, 0xec, 0x49, 0x51, 0xfb, 0x30, 0xae, 0x6c, 0xb1, 0x9e, 0x8d, 0xdf, 0x1e, 0xc3, 0x36, + 0x92, 0xd7, 0x60, 0xc4, 0xa4, 0x7b, 0xec, 0xa8, 0xc9, 0x44, 0x83, 0xe4, 0x21, 0x44, 0xed, 0x18, + 0x8e, 0x83, 0x72, 0x06, 0x6d, 0xf8, 0xfb, 0xce, 0x6e, 0x20, 0x7a, 0x27, 0x94, 0x33, 0x04, 0x58, + 0x91, 0x33, 0x04, 0x44, 0xbf, 0xce, 0x72, 0x18, 0xdb, 0xfd, 0xcc, 0x4a, 0x4d, 0x74, 0x9a, 0xec, + 0x61, 0xb3, 0xa2, 0x6c, 0x23, 0x9e, 0x26, 0x25, 0x30, 0x6c, 0x72, 0x1b, 0xc6, 0x4a, 0xf5, 0xba, + 0xdb, 0x55, 0xee, 0x8c, 0x7c, 0xdd, 0x72, 0xa0, 0xae, 0x22, 0x89, 0x50, 0x49, 0x0d, 0xc6, 0x97, + 0xd9, 0x45, 0xcb, 0x29, 0xdb, 0xf5, 0x7d, 0xd9, 0x49, 0x72, 0x0f, 0x53, 0x4a, 0xa2, 0x95, 0x4b, + 0x11, 0x58, 0x67, 0x40, 0x55, 0xc9, 0xa0, 0xe0, 0x92, 0x4d, 0x18, 0xaf, 0xd1, 0xba, 0x47, 0x83, + 0x5a, 0xe0, 0x7a, 0x34, 0xb6, 0x25, 0x2b, 0x25, 0x4b, 0x97, 0xe4, 0x5d, 0xcf, 0x47, 0xa0, 0xe5, + 0x33, 0xa8, 0xca, 0x55, 0x41, 0xe6, 0x42, 0x7b, 0xcb, 0xf5, 0x8e, 0x2a, 0x4b, 0x62, 0x9b, 0x8e, + 0xce, 0x74, 0x0e, 0x56, 0x85, 0x76, 0x06, 0x69, 0xec, 0xe8, 0x42, 0x3b, 0xc7, 0xc2, 0x91, 0xaa, + 0xd4, 0x50, 0xb6, 0x12, 0x9b, 0xf6, 0x74, 0xd4, 0xcb, 0x08, 0x56, 0x46, 0xaa, 0xe1, 0xa3, 0x64, + 0xa6, 0x8d, 0x94, 0xc0, 0x22, 0x1d, 0x20, 0x72, 0xd4, 0xb8, 0xa0, 0xdb, 0xa4, 0xbe, 0x2f, 0xf6, + 0xf2, 0x8b, 0xb1, 0xc1, 0x8f, 0x10, 0x96, 0x5e, 0x16, 0xcc, 0x9f, 0x97, 0xd3, 0x40, 0xdc, 0xd3, + 0x58, 0xa1, 0x52, 0x4f, 0x0a, 0x6f, 0xf2, 0x26, 0xc0, 0xf2, 0xe3, 0x80, 0x7a, 0x6d, 0xbb, 0x19, + 0xea, 0xc1, 0x50, 0xf5, 0x43, 0x05, 0x54, 0x1f, 0x68, 0x05, 0x99, 0x94, 0x61, 0xb2, 0xe4, 0xfb, + 0xdd, 0x16, 0x35, 0xdd, 0x26, 0x2d, 0x99, 0x6b, 0xb8, 0xef, 0x8f, 0x2d, 0x3d, 0x7f, 0x72, 0x5c, + 0xbc, 0x68, 0x63, 0x81, 0xe5, 0xb9, 0x4d, 0x6a, 0xd9, 0x9e, 0x3a, 0xbb, 0x75, 0x1a, 0xb2, 0x0e, + 0xb0, 0xde, 0xa1, 0xed, 0x1a, 0xb5, 0xbd, 0xfa, 0x7e, 0x6c, 0x9b, 0x8f, 0x0a, 0x96, 0x9e, 0x13, + 0x2d, 0x9c, 0x73, 0x3b, 0xb4, 0xed, 0x23, 0x4c, 0xfd, 0xaa, 0x08, 0x93, 0x6c, 0xc3, 0x74, 0xb5, + 0xf4, 0x60, 0xc3, 0x6d, 0x3a, 0xf5, 0x23, 0x21, 0x39, 0x4d, 0xa1, 0x76, 0xf0, 0xbc, 0xe0, 0x1a, + 0x2b, 0xe5, 0xdb, 0x93, 0x63, 0xb7, 0xac, 0x0e, 0x42, 0x2d, 0x21, 0x3f, 0xc5, 0xb9, 0x90, 0x0f, + 0xd8, 0x1c, 0xf4, 0x99, 0x30, 0xb8, 0x69, 0xef, 0xf9, 0xf3, 0xd3, 0x9a, 0xb6, 0xab, 0xb4, 0x5d, + 0xbb, 0xae, 0x94, 0x72, 0x31, 0x65, 0x81, 0x4f, 0x44, 0x84, 0x5a, 0x81, 0xbd, 0xe7, 0xeb, 0x13, + 0x31, 0xc4, 0x26, 0xf7, 0x00, 0x2a, 0x6e, 0xbd, 0xdb, 0xa2, 0xed, 0xa0, 0xb2, 0x34, 0x5f, 0xd0, + 0xaf, 0x02, 0x61, 0x41, 0xb4, 0xb5, 0x35, 0xdc, 0xba, 0x36, 0x13, 0x15, 0xea, 0x85, 0x77, 0xa1, + 0x10, 0xff, 0x90, 0x33, 0x2a, 0xb0, 0x26, 0x0b, 0x53, 0x4a, 0xeb, 0x97, 0x1f, 0x3b, 0x7e, 0xe0, + 0x1b, 0xdf, 0xd0, 0x56, 0x20, 0xdb, 0x1d, 0xee, 0xd3, 0xa3, 0x0d, 0x8f, 0xee, 0x3a, 0x8f, 0xc5, + 0x66, 0x86, 0xbb, 0xc3, 0x01, 0x3d, 0xb2, 0x3a, 0x08, 0x55, 0x77, 0x87, 0x10, 0x95, 0x7c, 0x06, + 0xf2, 0xf7, 0x1f, 0xd4, 0xee, 0xd3, 0xa3, 0x6a, 0x45, 0x1c, 0x54, 0x9c, 0xac, 0xe5, 0x5b, 0x8c, + 0x54, 0x9b, 0x6b, 0x21, 0xa6, 0xb1, 0x14, 0xed, 0x84, 0xac, 0xe6, 0x72, 0xb3, 0xeb, 0x07, 0xd4, + 0xab, 0x56, 0xd4, 0x9a, 0xeb, 0x1c, 0x18, 0xdb, 0x97, 0x42, 0x54, 0xe3, 0xdf, 0x64, 0x71, 0x17, + 0x64, 0x13, 0xbe, 0xda, 0xf6, 0x03, 0xbb, 0x5d, 0xa7, 0x21, 0x03, 0x9c, 0xf0, 0x8e, 0x80, 0xc6, + 0x26, 0x7c, 0x84, 0xac, 0x57, 0x9d, 0x1d, 0xb8, 0x6a, 0x56, 0xa5, 0xd4, 0x5c, 0x54, 0x2b, 0xaa, + 0x7a, 0xd5, 0x13, 0xd0, 0x58, 0x95, 0x11, 0x32, 0xb9, 0x02, 0xa3, 0xd5, 0xd2, 0x83, 0x52, 0x37, + 0xd8, 0xc7, 0x3d, 0x38, 0xcf, 0xe5, 0x73, 0x36, 0x5b, 0xed, 0x6e, 0xb0, 0x6f, 0xca, 0x42, 0x72, + 0x03, 0xef, 0x3d, 0x6d, 0x1a, 0x70, 0x35, 0xac, 0x38, 0x74, 0x7d, 0x0e, 0x8a, 0x5d, 0x7b, 0x18, + 0x88, 0xbc, 0x0a, 0xc3, 0x0f, 0x37, 0xca, 0xd5, 0x8a, 0xb8, 0x38, 0xe3, 0x49, 0xf4, 0xa8, 0x53, + 0xd7, 0xbf, 0x84, 0xa3, 0x90, 0x65, 0x98, 0xaa, 0xd1, 0x7a, 0xd7, 0x73, 0x82, 0xa3, 0xbb, 0x9e, + 0xdb, 0xed, 0xf8, 0xf3, 0xa3, 0x58, 0x07, 0xae, 0x74, 0x5f, 0x94, 0x58, 0x7b, 0x58, 0xa4, 0x50, + 0xc7, 0x88, 0x8c, 0xdf, 0xc9, 0x44, 0xdb, 0x24, 0xb9, 0xa2, 0x89, 0x35, 0xa8, 0xbb, 0x61, 0x62, + 0x8d, 0xaa, 0xbb, 0x41, 0x01, 0xc7, 0x04, 0x52, 0xee, 0xfa, 0x81, 0xdb, 0x5a, 0x6e, 0x37, 0x3a, + 0xae, 0xd3, 0x0e, 0x90, 0x8a, 0x77, 0xbe, 0x71, 0x72, 0x5c, 0xbc, 0x54, 0xc7, 0x52, 0x8b, 0x8a, + 0x62, 0x2b, 0xc6, 0x25, 0x85, 0xfa, 0x63, 0x8c, 0x87, 0xf1, 0x07, 0x59, 0xed, 0x78, 0x63, 0x9f, + 0x67, 0xd2, 0x4e, 0xd3, 0xa9, 0xe3, 0x8d, 0x1e, 0x1b, 0x1a, 0xce, 0x2a, 0xfc, 0x3c, 0x2f, 0x2a, + 0xe5, 0x3d, 0xa4, 0xf3, 0x4e, 0xa1, 0x26, 0x5f, 0x80, 0x09, 0x26, 0x69, 0x88, 0x9f, 0xfe, 0x7c, + 0x16, 0x3b, 0xfb, 0x39, 0xd4, 0xc2, 0xf9, 0xd4, 0x0b, 0xd9, 0x68, 0x22, 0x8a, 0x4a, 0x41, 0x1a, + 0x30, 0xbf, 0xe9, 0xd9, 0x6d, 0xdf, 0x09, 0x96, 0xdb, 0x75, 0xef, 0x08, 0x25, 0xa3, 0xe5, 0xb6, + 0xbd, 0xd3, 0xa4, 0x0d, 0x6c, 0x6e, 0x7e, 0xe9, 0xea, 0xc9, 0x71, 0xf1, 0xa5, 0x80, 0xe3, 0x58, + 0x34, 0x44, 0xb2, 0x28, 0xc7, 0x52, 0x38, 0xf7, 0xe4, 0xc4, 0x24, 0x29, 0xd9, 0xad, 0xf8, 0x08, + 0xc3, 0x85, 0x04, 0x94, 0xa4, 0xc2, 0xd1, 0x60, 0x7b, 0x98, 0xfa, 0x99, 0x2a, 0x81, 0xf1, 0x7f, + 0x67, 0xa2, 0x03, 0x98, 0xbc, 0x0d, 0xe3, 0x62, 0xc5, 0x28, 0xf3, 0x02, 0x77, 0x50, 0xb9, 0xbc, + 0x62, 0x23, 0xab, 0xa2, 0xb3, 0x7b, 0x7f, 0xa9, 0xbc, 0xaa, 0xcc, 0x0d, 0xbc, 0xf7, 0xdb, 0xf5, + 0x66, 0x9c, 0x4a, 0xa2, 0xb1, 0x49, 0xb0, 0xb9, 0x5a, 0xd3, 0x7b, 0x05, 0x27, 0x41, 0xd0, 0xf4, + 0x53, 0xba, 0x41, 0x41, 0xfe, 0xf8, 0x0d, 0xff, 0x1f, 0x33, 0x69, 0xe7, 0x3c, 0x59, 0x82, 0xc9, + 0x6d, 0xd7, 0x3b, 0xc0, 0xf1, 0x55, 0x3a, 0x01, 0x47, 0xfe, 0x50, 0x16, 0xc4, 0x1b, 0xa4, 0x93, + 0xa8, 0xdf, 0xa6, 0xf4, 0x86, 0xfe, 0x6d, 0x31, 0x0e, 0x1a, 0x01, 0x1b, 0x87, 0x90, 0x63, 0xb8, + 0x3a, 0x70, 0x1c, 0xa2, 0x4f, 0xd0, 0xa6, 0xb0, 0x8a, 0x6e, 0xfc, 0x17, 0x19, 0xf5, 0x3c, 0x67, + 0x9d, 0x5c, 0x71, 0x5b, 0xb6, 0xd3, 0x56, 0x9a, 0xc3, 0x1f, 0x96, 0x10, 0x1a, 0xff, 0x12, 0x05, + 0x99, 0xdc, 0x82, 0x3c, 0xff, 0x15, 0xee, 0xb5, 0xa8, 0xd5, 0x12, 0x84, 0xfa, 0x41, 0x21, 0x11, + 0x13, 0x23, 0x93, 0x3b, 0xeb, 0xc8, 0xfc, 0x76, 0x46, 0x3d, 0x8a, 0x3f, 0xea, 0x61, 0x13, 0x3b, + 0x64, 0xb2, 0x67, 0x39, 0x64, 0x3e, 0x76, 0x13, 0xbe, 0x37, 0x03, 0xe3, 0x8a, 0x96, 0x82, 0xb5, + 0x61, 0xc3, 0x73, 0x3f, 0xa4, 0xf5, 0x40, 0x6f, 0x43, 0x87, 0x03, 0x63, 0x6d, 0x08, 0x51, 0x3f, + 0x46, 0x1b, 0x8c, 0x3f, 0xcf, 0x88, 0x3b, 0xd2, 0xc0, 0xdb, 0xbc, 0xbe, 0x25, 0x67, 0xcf, 0x72, + 0x44, 0x7e, 0x01, 0x86, 0x4d, 0xda, 0x70, 0x7c, 0x71, 0xbf, 0x99, 0x51, 0xef, 0x63, 0x58, 0x10, + 0xc9, 0x4d, 0x1e, 0xfb, 0xa9, 0x9e, 0x6f, 0x58, 0xce, 0x04, 0xd9, 0xaa, 0x7f, 0xa7, 0x49, 0x1f, + 0x3b, 0x7c, 0x31, 0x8a, 0xa3, 0x16, 0x8f, 0x37, 0xc7, 0xb7, 0x76, 0x59, 0x89, 0x90, 0xa8, 0xd5, + 0x85, 0xa7, 0xd1, 0x18, 0x1f, 0x00, 0x44, 0x55, 0x92, 0xfb, 0x50, 0x10, 0xb3, 0xc1, 0x69, 0xef, + 0x71, 0x41, 0x4a, 0xf4, 0x41, 0xf1, 0xe4, 0xb8, 0xf8, 0x6c, 0x3d, 0x2c, 0x13, 0x52, 0xa7, 0xc2, + 0x37, 0x41, 0x68, 0xfc, 0xc3, 0x2c, 0x64, 0x4b, 0x38, 0x20, 0xf7, 0xe9, 0x51, 0x60, 0xef, 0xdc, + 0x71, 0x9a, 0xda, 0x62, 0x3a, 0x40, 0xa8, 0xb5, 0xeb, 0x68, 0xea, 0x0a, 0x05, 0x99, 0x2d, 0xa6, + 0xfb, 0xde, 0xce, 0x1b, 0x48, 0xa8, 0x2c, 0xa6, 0x03, 0x6f, 0xe7, 0x8d, 0x38, 0x59, 0x88, 0x48, + 0x0c, 0x18, 0xe1, 0x0b, 0x4b, 0xcc, 0x41, 0x38, 0x39, 0x2e, 0x8e, 0xf0, 0xf5, 0x67, 0x8a, 0x12, + 0x72, 0x11, 0x72, 0xb5, 0x8d, 0x35, 0xb1, 0x03, 0xa2, 0x5a, 0xd0, 0xef, 0xb4, 0x4d, 0x06, 0x63, + 0x75, 0xae, 0x56, 0x4a, 0x1b, 0xa8, 0x08, 0x18, 0x8e, 0xea, 0x6c, 0x36, 0xec, 0x4e, 0x5c, 0x15, + 0x10, 0x22, 0x92, 0x77, 0x60, 0xfc, 0x7e, 0xa5, 0xbc, 0xe2, 0xfa, 0x7c, 0xf7, 0x1a, 0x89, 0x26, + 0xff, 0x41, 0xa3, 0x6e, 0xa1, 0x26, 0x3e, 0x7e, 0x0c, 0x28, 0xf8, 0xc6, 0x37, 0xb3, 0x30, 0xae, + 0xe8, 0xc9, 0xc8, 0x67, 0xc4, 0x03, 0x69, 0x46, 0xbb, 0x01, 0x28, 0x18, 0xac, 0x94, 0x2b, 0x55, + 0x5a, 0x6e, 0x83, 0x8a, 0xe7, 0xd2, 0x48, 0x81, 0x91, 0x1d, 0x44, 0x81, 0xf1, 0x26, 0x00, 0x9f, + 0x03, 0xf8, 0xc9, 0x8a, 0x38, 0xa1, 0xd8, 0x49, 0xa8, 0xe3, 0x12, 0x21, 0x93, 0x87, 0x30, 0xbb, + 0xe9, 0x75, 0xfd, 0xa0, 0x76, 0xe4, 0x07, 0xb4, 0xc5, 0xb8, 0x6d, 0xb8, 0x6e, 0x53, 0xcc, 0xbf, + 0x97, 0x4e, 0x8e, 0x8b, 0x97, 0xd1, 0xb8, 0xc3, 0xf2, 0xb1, 0x1c, 0x3f, 0xc0, 0xea, 0xb8, 0xae, + 0xaa, 0xd6, 0x48, 0x63, 0x60, 0x98, 0x30, 0xa1, 0x2a, 0x45, 0xd8, 0xc9, 0x22, 0x1e, 0x93, 0x84, + 0xaa, 0x5b, 0x39, 0x59, 0xc4, 0x57, 0x26, 0x1f, 0xb7, 0x74, 0x12, 0xe3, 0x33, 0xaa, 0x42, 0x6e, + 0xd0, 0x85, 0x6d, 0x7c, 0x7f, 0x26, 0xda, 0x46, 0x1e, 0xde, 0x24, 0x6f, 0xc1, 0x08, 0x7f, 0xbc, + 0x13, 0x6f, 0x9c, 0xe7, 0xc2, 0x4b, 0xad, 0xfa, 0xb2, 0xc7, 0x35, 0xe1, 0x7f, 0xc4, 0x1f, 0xf8, + 0x9f, 0x31, 0x05, 0x49, 0xa8, 0x44, 0xd7, 0xf5, 0x69, 0x92, 0x3b, 0xaa, 0x8b, 0x6f, 0xa6, 0x29, + 0xd1, 0x8d, 0xdf, 0x1d, 0x82, 0x29, 0x1d, 0x4d, 0x7d, 0xe1, 0xcb, 0x0c, 0xf4, 0xc2, 0xf7, 0x05, + 0xc8, 0xb3, 0xfe, 0x70, 0xea, 0x54, 0x4a, 0x64, 0x2f, 0xe1, 0xd3, 0x82, 0x80, 0x69, 0x2f, 0xd7, + 0xc0, 0x87, 0x83, 0xdd, 0x71, 0xcd, 0x90, 0x8a, 0x2c, 0x2a, 0xcf, 0x50, 0xb9, 0x48, 0x48, 0x91, + 0xcf, 0x50, 0xea, 0x7a, 0x08, 0x1f, 0xa4, 0x5e, 0x87, 0x11, 0x26, 0xdf, 0x87, 0x2a, 0x18, 0xfc, + 0x4a, 0x26, 0xfa, 0xc7, 0x4c, 0x54, 0x38, 0x12, 0xd9, 0x86, 0xfc, 0xaa, 0xed, 0x07, 0x35, 0x4a, + 0xdb, 0x03, 0xbc, 0xdd, 0x17, 0x45, 0x57, 0xcd, 0xe2, 0xc3, 0xb8, 0x4f, 0x69, 0x3b, 0xf6, 0xf8, + 0x1a, 0x32, 0x23, 0x5f, 0x01, 0x28, 0xbb, 0xed, 0xc0, 0x73, 0x9b, 0xab, 0xee, 0xde, 0xfc, 0x08, + 0xde, 0x7d, 0x2f, 0xc5, 0x06, 0x20, 0x42, 0xe0, 0xd7, 0xdf, 0x50, 0xc1, 0x53, 0xe7, 0x05, 0x56, + 0xd3, 0xdd, 0x53, 0xd7, 0x41, 0x84, 0x4f, 0xee, 0x40, 0x41, 0x2a, 0x16, 0xb6, 0x3a, 0x7b, 0x1e, + 0x4e, 0x90, 0xd1, 0x48, 0xf2, 0xa0, 0x8f, 0x03, 0xab, 0x2b, 0xe0, 0xea, 0x4e, 0x19, 0xa7, 0x21, + 0x5f, 0x86, 0x0b, 0x71, 0x98, 0x1c, 0xe5, 0x7c, 0x24, 0x93, 0xab, 0xec, 0x52, 0xe6, 0x7d, 0x2f, + 0x16, 0xc6, 0xb7, 0xb3, 0x70, 0xa1, 0x47, 0x63, 0xd9, 0x7a, 0xc0, 0xe3, 0x5a, 0x59, 0x0f, 0xb1, + 0x53, 0x9a, 0xdb, 0x1c, 0x5d, 0x86, 0xac, 0x38, 0xe0, 0x86, 0x96, 0x0a, 0x27, 0xc7, 0xc5, 0x09, + 0x6d, 0x1c, 0xb3, 0xd5, 0x0a, 0xb9, 0x07, 0x43, 0x6c, 0x88, 0x06, 0x78, 0x3a, 0x97, 0x3a, 0xa5, + 0xa9, 0xc0, 0x51, 0xa7, 0x0f, 0x0e, 0x1d, 0xf2, 0x20, 0x9f, 0x81, 0xdc, 0xe6, 0xe6, 0x2a, 0xce, + 0x9d, 0x1c, 0xb6, 0x7d, 0x32, 0x08, 0x9a, 0xda, 0x54, 0x9d, 0x64, 0xb4, 0xd7, 0x43, 0x4b, 0x0b, + 0x86, 0x4e, 0xbe, 0x18, 0x33, 0xe9, 0x79, 0xb5, 0xff, 0x40, 0x0f, 0x6e, 0xe1, 0xf3, 0x31, 0x0c, + 0x6b, 0x8c, 0x9f, 0xcf, 0x46, 0x6b, 0xf8, 0x8e, 0xd3, 0x0c, 0xa8, 0x47, 0x16, 0xf8, 0x92, 0x8c, + 0x84, 0x33, 0x33, 0xfc, 0x4d, 0xe6, 0xa3, 0xf5, 0xcd, 0x59, 0x85, 0x0b, 0xf9, 0x55, 0x65, 0x21, + 0xe7, 0x70, 0x21, 0x4f, 0xf5, 0x5c, 0xb2, 0xaf, 0xa6, 0xcc, 0x4b, 0x5c, 0x88, 0x29, 0x73, 0xef, + 0x25, 0x98, 0x5c, 0x73, 0x97, 0x1f, 0x07, 0x21, 0x22, 0x5b, 0x80, 0x79, 0x53, 0x07, 0x32, 0x8e, + 0xeb, 0xcd, 0x06, 0xf5, 0x36, 0xf7, 0xed, 0xb6, 0xf6, 0x76, 0x6d, 0x26, 0xe0, 0x0c, 0x77, 0x8d, + 0x1e, 0xea, 0xb8, 0xa3, 0x1c, 0x37, 0x0e, 0x37, 0xbe, 0x2f, 0x2b, 0x3b, 0xe3, 0xe1, 0xe2, 0x53, + 0xfa, 0x46, 0xfa, 0x86, 0xf6, 0x46, 0x3a, 0x1b, 0x6a, 0x77, 0xc3, 0x07, 0xff, 0xc5, 0x53, 0xec, + 0x04, 0xfe, 0xfe, 0x08, 0x4c, 0xa8, 0xe8, 0xac, 0x1f, 0x4a, 0x8d, 0x86, 0xa7, 0xf6, 0x83, 0xdd, + 0x68, 0x78, 0x26, 0x42, 0x35, 0xb3, 0x80, 0x5c, 0x5f, 0xb3, 0x80, 0xaf, 0xc2, 0x58, 0xb9, 0xd5, + 0xd0, 0x1e, 0x2b, 0x8d, 0x94, 0xcf, 0xbb, 0x1e, 0x22, 0xf1, 0xb5, 0x10, 0x2a, 0x2d, 0xeb, 0xad, + 0x46, 0xf2, 0x89, 0x32, 0x62, 0xa9, 0x59, 0x14, 0x0c, 0x7f, 0x1c, 0x8b, 0x82, 0xdb, 0x30, 0xb6, + 0xe5, 0xd3, 0xcd, 0x6e, 0xbb, 0x4d, 0x9b, 0x38, 0xad, 0xf2, 0x5c, 0xd6, 0xef, 0xfa, 0xd4, 0x0a, + 0x10, 0xaa, 0x7e, 0x40, 0x88, 0xaa, 0x0e, 0xf0, 0x68, 0x9f, 0x01, 0xbe, 0x05, 0xf9, 0x0d, 0x4a, + 0x3d, 0xec, 0xd3, 0xf1, 0x48, 0xa4, 0xeb, 0x50, 0xea, 0x59, 0xac, 0x63, 0x35, 0x4b, 0x03, 0x81, + 0xa8, 0x99, 0x27, 0x4c, 0x0c, 0x68, 0x9e, 0x40, 0x5e, 0x80, 0x89, 0x4e, 0x77, 0xa7, 0xe9, 0xd4, + 0x91, 0xaf, 0xb0, 0x6b, 0x30, 0xc7, 0x39, 0x8c, 0xb1, 0xf5, 0xc9, 0x17, 0x61, 0x12, 0xef, 0x38, + 0xe1, 0x94, 0x9b, 0xd2, 0x5e, 0xf5, 0xb4, 0x32, 0x2e, 0xe9, 0xd4, 0x19, 0xc8, 0x4a, 0x31, 0xbf, + 0xd1, 0x19, 0x91, 0x7b, 0x30, 0xba, 0xe7, 0x04, 0xd6, 0x7e, 0x77, 0x67, 0x7e, 0x5a, 0xb3, 0x5d, + 0xb9, 0xeb, 0x04, 0x2b, 0xdd, 0x1d, 0x3e, 0xe4, 0x21, 0x6b, 0xdc, 0xf1, 0xf6, 0x9c, 0x60, 0xbf, + 0xab, 0xaa, 0x64, 0x47, 0xf6, 0x10, 0x77, 0xa1, 0x06, 0x53, 0xfa, 0xac, 0x78, 0x02, 0x0f, 0x85, + 0xa1, 0xd9, 0x46, 0xbe, 0x30, 0x76, 0x6f, 0x28, 0x0f, 0x85, 0x71, 0x6e, 0xb0, 0x61, 0xc2, 0x46, + 0xd8, 0x3f, 0x26, 0xb9, 0xdf, 0xdd, 0xa1, 0x5e, 0x9b, 0x06, 0xd4, 0x17, 0x17, 0x0a, 0xdf, 0x1c, + 0x2a, 0x75, 0x3a, 0xbe, 0xf1, 0x1f, 0x67, 0x61, 0xb4, 0xb4, 0x5d, 0xab, 0xb6, 0x77, 0x5d, 0x7c, + 0xee, 0x0b, 0x5f, 0x79, 0xd4, 0xe7, 0xbe, 0xf0, 0x95, 0x47, 0x7d, 0xdb, 0xb9, 0x91, 0x72, 0x25, + 0x44, 0x8b, 0x60, 0xe5, 0x4a, 0xa8, 0x5d, 0x66, 0xa3, 0x07, 0xaf, 0xdc, 0x00, 0x0f, 0x5e, 0xa1, + 0x4e, 0x72, 0xe8, 0x74, 0x9d, 0xe4, 0x5b, 0x30, 0x5e, 0x6d, 0x07, 0x74, 0xcf, 0x8b, 0x56, 0x4d, + 0x78, 0x3d, 0x0d, 0xc1, 0xea, 0x35, 0x41, 0xc1, 0x66, 0x53, 0x92, 0xeb, 0x41, 0x43, 0xfd, 0x27, + 0x4e, 0x49, 0xae, 0x2e, 0x8d, 0xe9, 0x16, 0x24, 0xa2, 0x51, 0x89, 0xcd, 0x37, 0x69, 0x54, 0xc0, + 0x05, 0xd9, 0xa9, 0xe8, 0x21, 0x80, 0x75, 0xec, 0xd2, 0x4c, 0xba, 0x51, 0x81, 0xf1, 0xb7, 0x33, + 0x30, 0x97, 0x36, 0x8d, 0xc8, 0xbb, 0x30, 0xe1, 0x7a, 0x7b, 0x76, 0xdb, 0xf9, 0x6e, 0xde, 0x22, + 0x45, 0x01, 0xa6, 0xc2, 0xd5, 0x6b, 0xbf, 0x0a, 0x67, 0x1d, 0xa2, 0xb4, 0x5c, 0xbf, 0xaf, 0xa7, + 0x76, 0x88, 0x02, 0x36, 0x7e, 0x28, 0x0b, 0xe3, 0xa5, 0x4e, 0xe7, 0x29, 0x37, 0x38, 0xfb, 0x9c, + 0x76, 0x80, 0xc8, 0xdb, 0x5e, 0xd8, 0xae, 0x81, 0x6c, 0xcd, 0x7e, 0x35, 0x0b, 0xd3, 0x31, 0x0a, + 0xf5, 0xeb, 0x33, 0x03, 0x9a, 0x99, 0x65, 0x07, 0x34, 0x33, 0xcb, 0x0d, 0x66, 0x66, 0x36, 0xf4, + 0x71, 0x0e, 0x85, 0x57, 0x20, 0x57, 0xea, 0x74, 0xe2, 0xcf, 0xd5, 0x9d, 0xce, 0xc3, 0x5b, 0xfc, + 0xc6, 0x6e, 0x77, 0x3a, 0x26, 0xc3, 0xd0, 0x76, 0xea, 0x91, 0x01, 0x77, 0x6a, 0xe3, 0x75, 0x18, + 0x43, 0x5e, 0x68, 0xdc, 0x75, 0x19, 0x70, 0x8b, 0x11, 0x76, 0x5d, 0x5a, 0x5d, 0x62, 0xf3, 0xf9, + 0x7f, 0x33, 0x30, 0x8c, 0xbf, 0x9f, 0xd2, 0x39, 0xb6, 0xa8, 0xcd, 0xb1, 0x82, 0x32, 0xc7, 0x06, + 0x99, 0x5d, 0xff, 0x28, 0x07, 0x50, 0x5e, 0x37, 0x6b, 0x5c, 0xb1, 0x43, 0xee, 0xc0, 0xb4, 0xdd, + 0x6c, 0xba, 0x87, 0xb4, 0x61, 0xb9, 0x9e, 0xb3, 0xe7, 0xb4, 0x79, 0xcf, 0xc9, 0x37, 0x54, 0xbd, + 0x48, 0x7d, 0x59, 0x11, 0x45, 0xeb, 0xbc, 0x44, 0xe5, 0xd3, 0xa2, 0xc1, 0xbe, 0xdb, 0x90, 0x57, + 0x54, 0x8d, 0x8f, 0x28, 0x4a, 0xe1, 0xf3, 0x80, 0x97, 0xa8, 0x7c, 0xf6, 0xf1, 0xca, 0x2d, 0x25, + 0x64, 0x8d, 0x8f, 0x28, 0x4a, 0xe1, 0xc3, 0xef, 0xe9, 0x3e, 0x59, 0x85, 0x19, 0x84, 0x58, 0x75, + 0x8f, 0x36, 0x68, 0x3b, 0x70, 0xec, 0xa6, 0x2f, 0x94, 0x1a, 0xa8, 0xfe, 0x4a, 0x14, 0xaa, 0x97, + 0x3a, 0x2c, 0x2c, 0x47, 0x65, 0xe4, 0x3a, 0x8c, 0xb6, 0xec, 0xc7, 0x96, 0xbd, 0xc7, 0xad, 0x09, + 0x26, 0xf9, 0x25, 0x58, 0x80, 0xd4, 0x63, 0xa4, 0x65, 0x3f, 0x2e, 0xed, 0x51, 0xd6, 0x0a, 0xfa, + 0xb8, 0xe3, 0xfa, 0x4a, 0x2b, 0x46, 0xa2, 0x56, 0xc4, 0x8a, 0xd4, 0x56, 0x88, 0x22, 0xd1, 0x0a, + 0xe3, 0x57, 0x32, 0xf0, 0x6c, 0x15, 0xbf, 0x22, 0x38, 0x2a, 0xd3, 0x76, 0x40, 0xbd, 0x0d, 0xea, + 0xb5, 0x1c, 0x7c, 0x5b, 0xad, 0xd1, 0x80, 0xbc, 0x08, 0xb9, 0x92, 0xb9, 0x26, 0xe6, 0x2f, 0xdf, + 0xef, 0xb5, 0x97, 0x6e, 0x56, 0x1a, 0xea, 0x49, 0xb2, 0xa7, 0x28, 0x40, 0x4b, 0x30, 0x51, 0xf2, + 0x7d, 0x67, 0xaf, 0xdd, 0xe2, 0x56, 0xfa, 0x39, 0xed, 0x2d, 0x5d, 0xc0, 0x13, 0x9a, 0x7b, 0x95, + 0xc4, 0xf8, 0x4f, 0x32, 0x30, 0x53, 0xea, 0x74, 0xf4, 0x4f, 0xd6, 0xed, 0x38, 0x32, 0x83, 0xdb, + 0x71, 0x38, 0x30, 0xa5, 0x35, 0x97, 0x4f, 0xa9, 0x48, 0xf0, 0xed, 0xd3, 0x33, 0xfc, 0xb3, 0x3b, + 0x21, 0xc8, 0xf2, 0xf5, 0x47, 0xc8, 0x18, 0x63, 0xe3, 0xdf, 0x1b, 0xc5, 0x3d, 0x44, 0xec, 0xb6, + 0xc2, 0xd2, 0x30, 0x93, 0x62, 0x69, 0xf8, 0x26, 0x28, 0x12, 0x8e, 0x7a, 0xc4, 0x29, 0xb2, 0xa2, + 0xaa, 0x61, 0x88, 0x90, 0xc9, 0x41, 0xdc, 0xe6, 0x30, 0x87, 0xad, 0x79, 0x31, 0xbe, 0x80, 0x9f, + 0x88, 0xb9, 0xe1, 0x0a, 0x90, 0x6a, 0x1b, 0x1f, 0x46, 0x69, 0xed, 0xc0, 0xe9, 0x3c, 0xa4, 0x9e, + 0xb3, 0x7b, 0x24, 0x16, 0x00, 0x76, 0xbe, 0x23, 0x4a, 0x2d, 0xff, 0xc0, 0xe9, 0x58, 0x8f, 0xb0, + 0xdc, 0x4c, 0xa1, 0x21, 0xef, 0xc1, 0xa8, 0x49, 0x0f, 0x3d, 0x27, 0x90, 0x96, 0x34, 0x53, 0xa1, + 0xc2, 0x0c, 0xa1, 0x7c, 0x2d, 0x78, 0xfc, 0x87, 0xba, 0x2b, 0x8a, 0x72, 0xb2, 0xc8, 0x85, 0x14, + 0x6e, 0x31, 0x33, 0x19, 0xb5, 0xb6, 0xb4, 0x5d, 0xeb, 0x25, 0xa3, 0x90, 0x6b, 0x30, 0x8c, 0x92, + 0x8e, 0xb8, 0x0b, 0xa0, 0x07, 0x0a, 0xca, 0xce, 0xaa, 0x18, 0x86, 0x18, 0xe4, 0x12, 0x40, 0xf8, + 0xf2, 0xe8, 0xcf, 0xe7, 0x51, 0x4a, 0x57, 0x20, 0x71, 0x31, 0x6d, 0xec, 0x4c, 0x62, 0xda, 0x2a, + 0x14, 0x4c, 0xee, 0xcc, 0xd6, 0x28, 0x75, 0xf0, 0x79, 0xcb, 0x9f, 0x07, 0x5c, 0xc9, 0x97, 0x4f, + 0x8e, 0x8b, 0xcf, 0x09, 0x47, 0xb7, 0x86, 0x65, 0x77, 0xf8, 0xab, 0x98, 0xb6, 0x8d, 0xc4, 0x29, + 0xc9, 0x9b, 0x30, 0xc4, 0xb6, 0x5e, 0x61, 0x9d, 0x28, 0x9f, 0x09, 0xa2, 0xdd, 0x98, 0x2f, 0xce, + 0xba, 0xab, 0xed, 0x09, 0x48, 0x42, 0x2c, 0x98, 0xd2, 0xa7, 0xbb, 0x30, 0x54, 0x99, 0x8f, 0xfa, + 0x53, 0x2f, 0x17, 0x6f, 0x07, 0x02, 0x66, 0xd5, 0x11, 0xa8, 0xae, 0x80, 0xd8, 0x22, 0x5d, 0x86, + 0xfc, 0x66, 0x79, 0x63, 0xc3, 0xf5, 0x02, 0x7e, 0xd5, 0x89, 0x4e, 0x16, 0x06, 0x33, 0xed, 0xf6, + 0x1e, 0xe5, 0x67, 0x71, 0x50, 0xef, 0x58, 0x1d, 0x86, 0xa6, 0x9e, 0xc5, 0x92, 0xf4, 0x93, 0xb3, + 0x4c, 0xfc, 0xd5, 0x2c, 0xbc, 0x18, 0x4a, 0x45, 0xeb, 0x5e, 0xad, 0xf4, 0x60, 0xb5, 0xda, 0xd8, + 0x10, 0x6a, 0x92, 0x0d, 0xcf, 0x7d, 0xe4, 0x34, 0xa8, 0xf7, 0xf0, 0xe6, 0x29, 0x67, 0xfa, 0x2a, + 0x5f, 0xe6, 0xfc, 0x8d, 0x25, 0xab, 0xd9, 0x70, 0x29, 0xc2, 0xa7, 0xd8, 0x9e, 0x3a, 0x9d, 0xc4, + 0x93, 0xcb, 0xca, 0x33, 0x66, 0xc4, 0x80, 0x7c, 0x7f, 0x06, 0xce, 0xa7, 0x7f, 0x88, 0x50, 0x9d, + 0x15, 0xe5, 0x15, 0xbd, 0xc7, 0xd7, 0x2e, 0xbd, 0x72, 0x72, 0x5c, 0x7c, 0xd1, 0xb7, 0x5b, 0x4d, + 0xcb, 0x69, 0xf0, 0xda, 0x9c, 0x3a, 0xb5, 0x3a, 0x02, 0x41, 0xab, 0xb7, 0x47, 0x4d, 0x9f, 0x07, + 0x79, 0xb4, 0xcf, 0x67, 0x96, 0x00, 0xf2, 0x52, 0x8d, 0x6d, 0xfc, 0x46, 0x06, 0x94, 0x25, 0x98, + 0x37, 0x69, 0xc3, 0xf1, 0x68, 0x3d, 0x10, 0xc7, 0xbb, 0xf0, 0x40, 0xe3, 0xb0, 0x98, 0xc9, 0x1e, + 0xc2, 0xc8, 0xbb, 0x30, 0x2a, 0x8e, 0x21, 0xb1, 0xed, 0xca, 0xa5, 0x2b, 0x14, 0xe4, 0xdc, 0x55, + 0x31, 0x71, 0x84, 0x49, 0x22, 0xb6, 0xeb, 0xdf, 0xdb, 0xde, 0x2c, 0x37, 0x6d, 0xa7, 0xe5, 0x8b, + 0xb3, 0x04, 0xbb, 0xf5, 0xc3, 0xc3, 0xc0, 0xaa, 0x23, 0x54, 0xdd, 0xf5, 0x43, 0x54, 0xe3, 0xae, + 0xd4, 0xcf, 0x9f, 0x62, 0x77, 0x5a, 0x84, 0xe1, 0x87, 0x91, 0x9e, 0x6e, 0x69, 0xec, 0xe4, 0xb8, + 0xc8, 0xa7, 0x8b, 0xc9, 0xe1, 0x06, 0x85, 0xb1, 0x70, 0xea, 0x32, 0x5e, 0xec, 0x07, 0xf2, 0x9a, + 0xe4, 0xbc, 0xd8, 0x24, 0x36, 0x11, 0xca, 0x44, 0xbd, 0xe5, 0x76, 0x03, 0x11, 0xb2, 0x88, 0x80, + 0xdd, 0x43, 0xdb, 0x0d, 0x9c, 0xe9, 0x6a, 0xeb, 0x04, 0x9a, 0x22, 0x50, 0xfd, 0x48, 0x06, 0xa6, + 0xf4, 0x69, 0x4b, 0xae, 0xc3, 0x88, 0x70, 0x32, 0xcb, 0xa0, 0xda, 0x93, 0x71, 0x1b, 0xe1, 0xee, + 0x65, 0x9a, 0x53, 0x99, 0xc0, 0x62, 0x72, 0xa3, 0xe0, 0x20, 0x84, 0x26, 0x94, 0x1b, 0xeb, 0x1c, + 0x64, 0xca, 0x32, 0x62, 0xb0, 0xab, 0xac, 0xdf, 0x6d, 0x06, 0xea, 0x6b, 0x98, 0x87, 0x10, 0x53, + 0x94, 0x18, 0x65, 0x18, 0xe1, 0x5b, 0x6b, 0xcc, 0xac, 0x2e, 0x73, 0x06, 0xb3, 0x3a, 0xe3, 0x38, + 0x03, 0x50, 0xab, 0xad, 0xdc, 0xa7, 0x47, 0x1b, 0xb6, 0x83, 0xe7, 0x37, 0x3f, 0xc6, 0xee, 0x8b, + 0x35, 0x3c, 0x21, 0x9e, 0x6f, 0xf9, 0x91, 0x77, 0x40, 0x8f, 0xb4, 0xe7, 0x5b, 0x89, 0x8a, 0x67, + 0xa5, 0xe7, 0x3c, 0xb2, 0x03, 0xca, 0x08, 0xb3, 0x48, 0xc8, 0xcf, 0x4a, 0x0e, 0x8d, 0x51, 0x2a, + 0xc8, 0xe4, 0x2b, 0x30, 0x15, 0xfd, 0x0a, 0x1f, 0xa1, 0xa7, 0xc2, 0x7d, 0x42, 0x2f, 0x5c, 0xba, + 0x74, 0x72, 0x5c, 0x5c, 0x50, 0xb8, 0xc6, 0x9f, 0xa7, 0x63, 0xcc, 0x8c, 0x5f, 0xca, 0xa0, 0xe9, + 0x85, 0x6c, 0xe0, 0x15, 0x18, 0x0a, 0x8d, 0x85, 0x27, 0xc4, 0x26, 0xac, 0x3f, 0xb4, 0x61, 0x39, + 0x13, 0xb7, 0xa2, 0x96, 0xe0, 0xd1, 0xa5, 0xb7, 0x80, 0x95, 0x92, 0xbb, 0x30, 0x3a, 0xd0, 0x37, + 0xe3, 0x14, 0x4b, 0xf9, 0x56, 0x49, 0x8d, 0xa3, 0x70, 0x6f, 0x7b, 0xf3, 0x3b, 0x77, 0x14, 0x7e, + 0x3c, 0x0b, 0xd3, 0xac, 0x5f, 0x4b, 0xdd, 0x60, 0xdf, 0xf5, 0x9c, 0xe0, 0xe8, 0xa9, 0xd5, 0x1b, + 0xbf, 0xad, 0x5d, 0xc9, 0x16, 0xe4, 0x61, 0xa6, 0xb6, 0x6d, 0x20, 0xf5, 0xf1, 0x3f, 0x1d, 0x86, + 0xd9, 0x14, 0x2a, 0xf2, 0x9a, 0xf6, 0xb4, 0x33, 0x2f, 0x9d, 0xc8, 0xbf, 0x7d, 0x5c, 0x9c, 0x90, + 0xe8, 0x9b, 0x91, 0x53, 0xf9, 0xa2, 0x6e, 0xc7, 0xc4, 0x7b, 0x0a, 0x5f, 0x7a, 0x54, 0x3b, 0x26, + 0xdd, 0x7a, 0xe9, 0x1a, 0x0c, 0x9b, 0x6e, 0x93, 0x4a, 0xdb, 0x3d, 0x14, 0xb8, 0x3c, 0x06, 0xd0, + 0x6c, 0x15, 0x18, 0x80, 0xac, 0xc0, 0x28, 0xfb, 0xe3, 0x81, 0xdd, 0x11, 0xaf, 0x70, 0x24, 0x54, + 0x0a, 0x20, 0xb4, 0xe3, 0xb4, 0xf7, 0x54, 0xbd, 0x40, 0x93, 0x5a, 0x2d, 0xbb, 0xa3, 0x49, 0x86, + 0x1c, 0x51, 0xd3, 0x2f, 0xe4, 0x7b, 0xeb, 0x17, 0x32, 0xa7, 0xea, 0x17, 0x76, 0x01, 0x6a, 0xce, + 0x5e, 0xdb, 0x69, 0xef, 0x95, 0x9a, 0x7b, 0xc2, 0x15, 0xff, 0x5a, 0xef, 0x51, 0xb8, 0x1e, 0x21, + 0xe3, 0xc4, 0x7d, 0x16, 0x9f, 0xca, 0x39, 0xcc, 0xb2, 0x9b, 0x7b, 0x9a, 0xcb, 0x90, 0xc2, 0x99, + 0xac, 0x01, 0x94, 0xea, 0x81, 0xf3, 0x88, 0x4d, 0x61, 0x5f, 0x88, 0x71, 0xf2, 0x93, 0xcb, 0xa5, + 0xfb, 0xf4, 0x08, 0xaf, 0x1e, 0xf2, 0xd1, 0xd1, 0x46, 0x54, 0xb6, 0x12, 0x34, 0x7f, 0x90, 0x88, + 0x03, 0xe9, 0xc0, 0xb9, 0x52, 0xa3, 0xe1, 0xb0, 0x36, 0xd8, 0xcd, 0x4d, 0x1e, 0x44, 0x01, 0x59, + 0x4f, 0xa4, 0xb3, 0xbe, 0x26, 0x58, 0xbf, 0x60, 0x87, 0x54, 0x96, 0x8c, 0xbd, 0x10, 0xab, 0x26, + 0x9d, 0xb1, 0x51, 0x83, 0x29, 0xbd, 0xf1, 0x7a, 0x08, 0x81, 0x09, 0xc8, 0x9b, 0xb5, 0x92, 0x55, + 0x5b, 0x29, 0xdd, 0x2c, 0x64, 0x48, 0x01, 0x26, 0xc4, 0xaf, 0x45, 0x6b, 0xf1, 0x8d, 0xdb, 0x85, + 0xac, 0x06, 0x79, 0xe3, 0xe6, 0x62, 0x21, 0xb7, 0x90, 0x9d, 0xcf, 0xc4, 0xbc, 0xf7, 0x46, 0x0b, + 0x79, 0xae, 0x12, 0x36, 0x7e, 0x2d, 0x03, 0x79, 0xf9, 0xed, 0xe4, 0x36, 0xe4, 0x6a, 0xb5, 0x95, + 0x98, 0xbf, 0x5d, 0x74, 0xca, 0xf0, 0xfd, 0xd4, 0xf7, 0x55, 0xa3, 0x6a, 0x46, 0xc0, 0xe8, 0x36, + 0x57, 0x6b, 0x42, 0x06, 0x91, 0x74, 0xd1, 0xe6, 0xcd, 0xe9, 0x52, 0x9c, 0x90, 0x6e, 0x43, 0xee, + 0xde, 0xf6, 0xa6, 0xb8, 0x64, 0x49, 0xba, 0x68, 0x3f, 0xe5, 0x74, 0x1f, 0x1e, 0xaa, 0xbb, 0x3c, + 0x23, 0x30, 0x4c, 0x18, 0x57, 0x26, 0x32, 0x3f, 0x74, 0x5b, 0x6e, 0xe8, 0x37, 0x2f, 0x0e, 0x5d, + 0x06, 0x31, 0x45, 0x09, 0x13, 0x45, 0x56, 0xdd, 0xba, 0xdd, 0x14, 0xa7, 0x37, 0x8a, 0x22, 0x4d, + 0x06, 0x30, 0x39, 0xdc, 0xf8, 0x9d, 0x0c, 0x14, 0x50, 0x60, 0x43, 0xa3, 0x68, 0xf7, 0x80, 0xb6, + 0x1f, 0xde, 0x24, 0xaf, 0xcb, 0x25, 0x97, 0x09, 0x15, 0x5d, 0xc3, 0xb8, 0xe4, 0x62, 0x6f, 0x81, + 0x62, 0xd9, 0x29, 0xa1, 0x09, 0xb2, 0x83, 0xbb, 0x34, 0x9f, 0x12, 0x9a, 0xa0, 0x08, 0xc3, 0xf8, + 0x39, 0x62, 0x73, 0xc4, 0x2f, 0x0f, 0x18, 0xc0, 0xe4, 0x70, 0x65, 0x6f, 0xfa, 0xc9, 0x6c, 0xa2, + 0x0d, 0x8b, 0xdf, 0x51, 0x6e, 0xc1, 0x7a, 0xe3, 0x06, 0xda, 0xaf, 0x3f, 0x80, 0xb9, 0x78, 0x97, + 0xa0, 0x12, 0xb2, 0x04, 0xd3, 0x3a, 0x5c, 0xea, 0x23, 0x2f, 0xa4, 0xd6, 0xf5, 0x70, 0xd1, 0x8c, + 0xe3, 0x1b, 0xff, 0x5b, 0x06, 0xc6, 0xf0, 0x4f, 0xb3, 0xdb, 0x44, 0xe3, 0xb4, 0xd2, 0x76, 0x4d, + 0xa8, 0x46, 0x54, 0x61, 0xce, 0x3e, 0xf4, 0x2d, 0xa1, 0x47, 0xd1, 0xf6, 0x98, 0x10, 0x59, 0x90, + 0xf2, 0xf7, 0x0d, 0xa9, 0x94, 0x0b, 0x49, 0xf9, 0x43, 0x88, 0x1f, 0x23, 0x15, 0xc8, 0x68, 0xd2, + 0xba, 0x5d, 0x63, 0xd3, 0x4f, 0xb5, 0x16, 0x41, 0x3a, 0xb7, 0xa9, 0x9b, 0xb4, 0x72, 0x34, 0x34, + 0x16, 0xd9, 0xae, 0x95, 0xcc, 0x35, 0xcd, 0x58, 0x84, 0x7d, 0xa3, 0xa6, 0x97, 0x12, 0x48, 0xc6, + 0xcf, 0x8f, 0xc7, 0x3b, 0x50, 0x1c, 0x78, 0x67, 0x5c, 0x1b, 0x6f, 0xc1, 0x70, 0xa9, 0xd9, 0x74, + 0x0f, 0xc5, 0x2e, 0x21, 0x6f, 0xae, 0x61, 0xff, 0xf1, 0xf3, 0x0c, 0xd5, 0x7a, 0x9a, 0xab, 0x23, + 0x03, 0x90, 0x32, 0x8c, 0x95, 0xb6, 0x6b, 0xd5, 0x6a, 0x65, 0x73, 0x93, 0xbb, 0x75, 0xe5, 0x96, + 0x5e, 0x96, 0xfd, 0xe3, 0x38, 0x0d, 0x2b, 0x6e, 0xaf, 0x10, 0xc9, 0xef, 0x11, 0x1d, 0x79, 0x07, + 0xe0, 0x9e, 0xeb, 0xb4, 0xb9, 0x1a, 0x53, 0x34, 0x9e, 0xdd, 0xc0, 0xc7, 0x3f, 0x74, 0x9d, 0xb6, + 0xd0, 0x7b, 0xb2, 0x6f, 0x8f, 0x90, 0x4c, 0xe5, 0x6f, 0xd6, 0xd3, 0x4b, 0x2e, 0x37, 0x38, 0x1b, + 0x8e, 0x7a, 0x7a, 0xc7, 0x4d, 0xe8, 0xdb, 0x24, 0x1a, 0x69, 0xc1, 0x74, 0xad, 0xbb, 0xb7, 0x47, + 0xd9, 0xce, 0x2e, 0xf4, 0x49, 0x23, 0xe2, 0x2a, 0x1d, 0x06, 0xd3, 0xe1, 0xf7, 0x11, 0x76, 0x19, + 0xf2, 0x97, 0x5e, 0x63, 0x13, 0xf9, 0x5b, 0xc7, 0x45, 0x61, 0x07, 0xc1, 0x44, 0x35, 0x5f, 0xd2, + 0x27, 0xb5, 0x49, 0x71, 0xde, 0x64, 0x1d, 0x46, 0xf8, 0x9b, 0x91, 0x70, 0x53, 0x7a, 0xa1, 0xcf, + 0xa2, 0xe1, 0x88, 0xbd, 0x5e, 0x25, 0x79, 0x29, 0xd9, 0x86, 0x7c, 0xd9, 0xf1, 0xea, 0x4d, 0x5a, + 0xae, 0x8a, 0xb3, 0xff, 0xc5, 0x3e, 0x2c, 0x25, 0x2a, 0xef, 0x97, 0x3a, 0xfe, 0xaa, 0x3b, 0xaa, + 0x2c, 0x20, 0x31, 0xc8, 0xdf, 0xce, 0xc0, 0xb3, 0xe1, 0xd7, 0x97, 0xf6, 0x68, 0x3b, 0x78, 0x60, + 0x07, 0xf5, 0x7d, 0xea, 0x89, 0x5e, 0x1a, 0xeb, 0xd7, 0x4b, 0x9f, 0x4f, 0xf4, 0xd2, 0xd5, 0xa8, + 0x97, 0x6c, 0xc6, 0xcc, 0x6a, 0x71, 0x6e, 0xc9, 0x3e, 0xeb, 0x57, 0x2b, 0xb1, 0x00, 0xa2, 0xd7, + 0x50, 0xe1, 0xe6, 0xfa, 0x72, 0x9f, 0x06, 0x47, 0xc8, 0xc2, 0x3d, 0x25, 0xfc, 0xad, 0xd9, 0x57, + 0x86, 0x50, 0x72, 0x5f, 0xfa, 0x04, 0x72, 0xa9, 0xe4, 0x72, 0x1f, 0xde, 0xdc, 0x4f, 0x70, 0xb6, + 0x8f, 0xf7, 0x2f, 0x1f, 0xed, 0x55, 0x7b, 0x47, 0x08, 0x22, 0xa7, 0x8c, 0xf6, 0xaa, 0x1d, 0x8d, + 0x76, 0xd3, 0x8e, 0x8f, 0xf6, 0xaa, 0xbd, 0x43, 0xca, 0xdc, 0x91, 0x99, 0x7b, 0xbd, 0x5e, 0xea, + 0xc7, 0xad, 0xbc, 0xc1, 0x4f, 0xe6, 0x14, 0x87, 0xe6, 0x2f, 0xc1, 0x58, 0xad, 0x63, 0xd7, 0x69, + 0xd3, 0xd9, 0x0d, 0xc4, 0x53, 0xfb, 0x4b, 0x7d, 0x58, 0x85, 0xb8, 0xe2, 0x69, 0x55, 0xfe, 0x54, + 0xaf, 0x49, 0x21, 0x0e, 0xfb, 0xc2, 0xcd, 0x8d, 0x07, 0xe2, 0xb5, 0xbd, 0xdf, 0x17, 0x6e, 0x6e, + 0x3c, 0x10, 0x32, 0x47, 0xa7, 0xa5, 0xc9, 0x1c, 0x1b, 0x0f, 0x48, 0x07, 0xa6, 0x36, 0xa9, 0xe7, + 0xd9, 0xbb, 0xae, 0xd7, 0xe2, 0xfa, 0x4b, 0xee, 0x49, 0x75, 0xad, 0x1f, 0x3f, 0x8d, 0x80, 0xab, + 0xed, 0x02, 0x09, 0xb3, 0xe2, 0x4a, 0xcf, 0x18, 0x7f, 0xd6, 0x27, 0x4b, 0x4e, 0xb0, 0xd3, 0xad, + 0x1f, 0xd0, 0x60, 0x7e, 0xe6, 0xd4, 0x3e, 0x09, 0x71, 0x79, 0x9f, 0xec, 0xc8, 0x9f, 0x6a, 0x9f, + 0x84, 0x38, 0xc6, 0x6f, 0xe6, 0xe0, 0x42, 0x8f, 0x2e, 0x20, 0x6b, 0x72, 0xcb, 0xcd, 0x68, 0x5a, + 0xec, 0x1e, 0xe8, 0xd7, 0x4f, 0xdd, 0x85, 0x57, 0xa1, 0xb0, 0x7c, 0x1f, 0x65, 0x75, 0xfe, 0x90, + 0x53, 0x2e, 0xc9, 0xc3, 0x0a, 0x35, 0xad, 0xf4, 0x00, 0x2d, 0x4f, 0xe5, 0x03, 0x50, 0x5d, 0x73, + 0xb1, 0x4e, 0x50, 0x2e, 0x7c, 0x5f, 0x16, 0x86, 0xf0, 0xe0, 0x8c, 0x05, 0x96, 0xca, 0x9c, 0x29, + 0xb0, 0xd4, 0x17, 0x60, 0x62, 0xf9, 0x3e, 0xbf, 0x49, 0xaf, 0xd8, 0xfe, 0xbe, 0xd8, 0xd6, 0xd1, + 0x90, 0x83, 0x1e, 0x58, 0xe2, 0xe2, 0xbd, 0x6f, 0x6b, 0x32, 0xab, 0x46, 0x41, 0xb6, 0x60, 0x96, + 0x7f, 0x9b, 0xb3, 0xeb, 0xd4, 0x79, 0x7c, 0x1a, 0xc7, 0x6e, 0x8a, 0x3d, 0xfe, 0xc5, 0x93, 0xe3, + 0x62, 0x91, 0x1e, 0xa0, 0x4d, 0xad, 0x28, 0xb7, 0x7c, 0x44, 0x50, 0x8d, 0x6b, 0x53, 0xe8, 0xd5, + 0xa0, 0x19, 0xe6, 0x18, 0x56, 0xc8, 0x6a, 0x63, 0x75, 0x33, 0x5c, 0x8e, 0x64, 0xfc, 0xd9, 0x30, + 0x2c, 0xf4, 0xde, 0x9e, 0xc9, 0xfb, 0xfa, 0x00, 0x5e, 0x39, 0x75, 0x43, 0x3f, 0x7d, 0x0c, 0xbf, + 0x08, 0x73, 0xcb, 0xed, 0x80, 0x7a, 0x1d, 0xcf, 0x91, 0x61, 0x52, 0x56, 0x5c, 0x5f, 0xda, 0x30, + 0xa3, 0x31, 0x31, 0x0d, 0xcb, 0x85, 0x6e, 0x15, 0x2d, 0xaa, 0x15, 0x56, 0xa9, 0x1c, 0xc8, 0x32, + 0x4c, 0x29, 0xf0, 0x66, 0x77, 0x4f, 0x7d, 0x9d, 0x52, 0x79, 0x36, 0xbb, 0xaa, 0x81, 0x67, 0x8c, + 0x08, 0xed, 0xa4, 0xd9, 0x95, 0xb1, 0x7e, 0x6f, 0xfb, 0x7e, 0x4d, 0x0c, 0x27, 0xb7, 0x93, 0x46, + 0xa8, 0xf5, 0xe1, 0xe1, 0x81, 0xb6, 0xbf, 0x46, 0xc8, 0x0b, 0xbf, 0x94, 0x13, 0x33, 0xea, 0x45, + 0xc8, 0xd5, 0xba, 0x3b, 0xea, 0x9b, 0x9b, 0xaf, 0x1d, 0x70, 0xac, 0x94, 0x7c, 0x0e, 0xc0, 0xa4, + 0x1d, 0xd7, 0x77, 0x02, 0xd7, 0x3b, 0x52, 0x1d, 0xf5, 0xbc, 0x10, 0xaa, 0xfb, 0x12, 0x48, 0x28, + 0x59, 0x81, 0xe9, 0xe8, 0xd7, 0xfa, 0x61, 0x5b, 0xe8, 0x92, 0xc7, 0xb8, 0x76, 0x25, 0x22, 0xb7, + 0x5c, 0x56, 0xa6, 0x1e, 0xd9, 0x31, 0x32, 0xb2, 0x08, 0xf9, 0x6d, 0xd7, 0x3b, 0xd8, 0x65, 0x63, + 0x3c, 0x14, 0x09, 0x15, 0x87, 0x02, 0xa6, 0x1e, 0x9e, 0x12, 0x8f, 0x2d, 0x97, 0xe5, 0xf6, 0x23, + 0xc7, 0x73, 0xf1, 0x45, 0x4f, 0xb5, 0x69, 0xa1, 0x11, 0x58, 0x73, 0x91, 0x8e, 0xc0, 0xe4, 0x1a, + 0x0c, 0x97, 0xea, 0x81, 0xeb, 0x09, 0x83, 0x16, 0x3e, 0x53, 0x18, 0x40, 0x9b, 0x29, 0x0c, 0xc0, + 0x3a, 0xd1, 0xa4, 0xbb, 0xe2, 0x75, 0x07, 0x3b, 0xd1, 0xa3, 0xbb, 0x9a, 0xff, 0x37, 0xdd, 0x65, + 0x42, 0x91, 0x49, 0x77, 0x51, 0xf1, 0xa1, 0x85, 0x4d, 0xdb, 0x4d, 0xa8, 0xcc, 0x04, 0x9a, 0xf1, + 0xfb, 0x63, 0x3d, 0xa7, 0x3c, 0x3b, 0x85, 0xce, 0x36, 0xe5, 0x57, 0xed, 0x01, 0xa6, 0xfc, 0x6b, + 0xa1, 0x87, 0x82, 0x1a, 0xf4, 0x00, 0x21, 0xea, 0x31, 0xc8, 0x71, 0x16, 0x7e, 0x39, 0x7f, 0x96, + 0x49, 0x24, 0x3a, 0x29, 0x3b, 0x68, 0x27, 0xe5, 0x06, 0xea, 0x24, 0xb2, 0x04, 0x93, 0x61, 0xe0, + 0xbd, 0x0d, 0x3b, 0xd0, 0xb6, 0xb5, 0x30, 0x5a, 0xa2, 0xd5, 0xb1, 0x03, 0x75, 0x5b, 0xd3, 0x49, + 0xc8, 0xdb, 0x30, 0x2e, 0xdc, 0x74, 0x90, 0xc3, 0x70, 0x64, 0x29, 0x24, 0x7d, 0x7a, 0x62, 0xf4, + 0x2a, 0x3a, 0x5b, 0xcd, 0x1b, 0x4e, 0x87, 0x36, 0x9d, 0x36, 0xad, 0xe1, 0x63, 0x85, 0x98, 0x31, + 0xfc, 0xd1, 0x56, 0x94, 0x58, 0xfc, 0x1d, 0x43, 0xd3, 0x1f, 0x6a, 0x44, 0xf1, 0xc9, 0x3a, 0x7a, + 0xa6, 0xc9, 0xca, 0xed, 0x14, 0xbd, 0x55, 0x77, 0xcf, 0x91, 0x96, 0xd9, 0xd2, 0x4e, 0xd1, 0xb3, + 0x9a, 0x0c, 0x1a, 0xb3, 0x53, 0xe4, 0xa8, 0xec, 0x86, 0xc3, 0x7e, 0x54, 0x2b, 0xe2, 0x25, 0x11, + 0x6f, 0x38, 0x48, 0xa4, 0x9b, 0xc3, 0x73, 0x24, 0x59, 0xcd, 0x72, 0xcb, 0x76, 0x9a, 0xc2, 0xb7, + 0x3d, 0xaa, 0x86, 0x32, 0x68, 0xbc, 0x1a, 0x44, 0x25, 0x75, 0x98, 0x30, 0xe9, 0xee, 0x86, 0xe7, + 0x06, 0xb4, 0x1e, 0xd0, 0x86, 0x90, 0xea, 0xe4, 0xc5, 0x66, 0xc9, 0x75, 0xb9, 0xc4, 0xba, 0xf4, + 0xfa, 0xef, 0x1f, 0x17, 0x33, 0xdf, 0x3a, 0x2e, 0x02, 0x03, 0x71, 0x5f, 0x8b, 0x93, 0xe3, 0xe2, + 0x05, 0x36, 0xfe, 0x1d, 0x49, 0xac, 0x9e, 0x4e, 0x2a, 0x53, 0xf2, 0x0d, 0xb6, 0x5f, 0x87, 0x5d, + 0x12, 0x55, 0x36, 0xd1, 0xa3, 0xb2, 0x37, 0x52, 0x2b, 0x2b, 0x2a, 0xbd, 0x9d, 0x5a, 0x69, 0x6a, + 0x25, 0xe4, 0x1d, 0x18, 0x2f, 0x57, 0xcb, 0x6e, 0x7b, 0xd7, 0xd9, 0xab, 0xad, 0x94, 0x50, 0x34, + 0x14, 0x7e, 0x36, 0x75, 0xc7, 0xaa, 0x23, 0xdc, 0xf2, 0xf7, 0x6d, 0xcd, 0xdd, 0x32, 0xc2, 0x27, + 0x77, 0x61, 0x4a, 0xfe, 0x34, 0xe9, 0xee, 0x96, 0x59, 0x45, 0x89, 0x50, 0x3a, 0x37, 0x85, 0x1c, + 0x58, 0x47, 0x74, 0x3d, 0xf5, 0xa6, 0x10, 0x23, 0x63, 0x93, 0xb1, 0x42, 0x3b, 0x4d, 0xf7, 0x88, + 0x7d, 0xde, 0xa6, 0x43, 0x3d, 0x94, 0x01, 0xc5, 0x64, 0x6c, 0x84, 0x25, 0x56, 0xe0, 0xe8, 0xef, + 0xa7, 0x3a, 0x11, 0x59, 0x83, 0x19, 0x31, 0xc5, 0x1f, 0x3a, 0xbe, 0xb3, 0xe3, 0x34, 0x9d, 0xe0, + 0x08, 0xa5, 0x3f, 0x21, 0xc0, 0xc8, 0x75, 0xf1, 0x28, 0x2c, 0x55, 0x98, 0x25, 0x49, 0x8d, 0x5f, + 0xcb, 0xc2, 0x73, 0xfd, 0x6e, 0x42, 0xa4, 0xa6, 0x6f, 0x66, 0x57, 0x07, 0xb8, 0x3d, 0x9d, 0xbe, + 0x9d, 0x2d, 0xc3, 0xd4, 0xba, 0x62, 0xd2, 0x17, 0x9a, 0x58, 0x62, 0x67, 0xa8, 0xc6, 0x7e, 0xfa, + 0x6c, 0x8f, 0x11, 0x2d, 0x3c, 0x12, 0xdb, 0xdc, 0x47, 0x75, 0xfc, 0xbb, 0x0d, 0x63, 0x65, 0xb7, + 0x1d, 0xd0, 0xc7, 0x41, 0xcc, 0xcd, 0x9d, 0x03, 0xe3, 0x4e, 0x8f, 0x12, 0xd5, 0xf8, 0x37, 0x59, + 0x78, 0xbe, 0xef, 0x55, 0x80, 0x6c, 0xea, 0xbd, 0x76, 0x6d, 0x90, 0xfb, 0xc3, 0xe9, 0xdd, 0xb6, + 0x98, 0xb0, 0xbb, 0x3b, 0xd5, 0xaf, 0x66, 0xe1, 0xbf, 0xcb, 0x88, 0x4e, 0xfa, 0x34, 0x8c, 0x62, + 0x55, 0x61, 0x17, 0x71, 0x2d, 0x19, 0xee, 0xc2, 0x8e, 0xae, 0x25, 0xe3, 0x68, 0xe4, 0x16, 0xe4, + 0xcb, 0x76, 0xb3, 0xa9, 0x04, 0x01, 0x40, 0x69, 0xbe, 0x8e, 0xb0, 0x98, 0xf1, 0xa8, 0x44, 0x64, + 0xb2, 0x0f, 0xff, 0x5b, 0x39, 0x2b, 0x70, 0xb3, 0x14, 0x64, 0xb1, 0xe3, 0x42, 0x41, 0xc6, 0xd0, + 0xa1, 0x75, 0x37, 0x74, 0x33, 0xe6, 0xa1, 0x43, 0x19, 0x40, 0x0b, 0x1d, 0xca, 0x00, 0xc6, 0xaf, + 0xe7, 0xe0, 0x52, 0xff, 0xfb, 0x2c, 0xd9, 0xd2, 0x87, 0xe0, 0xd5, 0x81, 0x6e, 0xc1, 0xa7, 0x8f, + 0x81, 0x0c, 0xc4, 0xcb, 0x3b, 0xe4, 0x6a, 0xd2, 0xfd, 0xe5, 0xdb, 0xc7, 0x45, 0xc5, 0x22, 0xf9, + 0x9e, 0xeb, 0xb4, 0x95, 0x37, 0x93, 0xaf, 0x6b, 0x92, 0x21, 0x7f, 0xbd, 0xbf, 0x3d, 0xd8, 0x97, + 0x45, 0x74, 0x7c, 0x5f, 0x19, 0x54, 0xa2, 0xfc, 0x3c, 0x14, 0xe2, 0xa4, 0xe4, 0x0a, 0x0c, 0xe1, + 0x07, 0x28, 0x3e, 0x3c, 0x31, 0x0e, 0x58, 0xbe, 0xf0, 0x40, 0xcc, 0x1d, 0x8c, 0x8b, 0x80, 0xf6, + 0x00, 0xba, 0x6e, 0x50, 0xc4, 0x45, 0xe0, 0xe6, 0x04, 0x49, 0xfd, 0x60, 0x8c, 0xc8, 0xf8, 0x8b, + 0x0c, 0x5c, 0xec, 0xa9, 0x29, 0x20, 0x1b, 0xfa, 0x80, 0xbd, 0x7c, 0x9a, 0x6a, 0xe1, 0xd4, 0xb1, + 0x5a, 0xf8, 0x51, 0x39, 0xf7, 0xdf, 0x85, 0x89, 0x5a, 0x77, 0x27, 0x7e, 0x3f, 0xe3, 0x51, 0x4b, + 0x14, 0xb8, 0x7a, 0x82, 0xa9, 0xf8, 0xac, 0xfd, 0xd2, 0xe0, 0x41, 0x18, 0x00, 0x29, 0x56, 0x87, + 0xa1, 0xe3, 0x6e, 0x32, 0x2e, 0x84, 0x4e, 0x64, 0xfc, 0x6a, 0x36, 0xfd, 0xa2, 0x7b, 0xb7, 0xbc, + 0x71, 0x96, 0x8b, 0xee, 0xdd, 0xf2, 0xc6, 0xe9, 0x6d, 0xff, 0xaf, 0x64, 0xdb, 0xf1, 0x61, 0x56, + 0xec, 0x78, 0x52, 0xd1, 0x29, 0x1e, 0x66, 0xe5, 0xee, 0xe8, 0xeb, 0x0f, 0xb3, 0x12, 0x99, 0xbc, + 0x01, 0x63, 0xab, 0x2e, 0x0f, 0xd9, 0x20, 0x5b, 0xcc, 0x3d, 0x5b, 0x25, 0x50, 0xdd, 0x1e, 0x43, + 0x4c, 0x76, 0xb7, 0xd0, 0x07, 0x5e, 0x1a, 0x57, 0xe2, 0xdd, 0x22, 0x36, 0x5d, 0x74, 0x75, 0xa0, + 0x4e, 0x66, 0xfc, 0x47, 0xc3, 0x60, 0x9c, 0xae, 0xcc, 0x20, 0x1f, 0xe8, 0x7d, 0x77, 0x7d, 0x60, + 0x35, 0xc8, 0x40, 0x5b, 0x6e, 0xa9, 0xdb, 0x70, 0x68, 0xbb, 0xae, 0xc7, 0x5b, 0x10, 0x30, 0x75, + 0x0b, 0x94, 0x78, 0x1f, 0xc5, 0xfd, 0x71, 0xe1, 0xbf, 0xc9, 0x45, 0x4b, 0x2d, 0x76, 0x34, 0x66, + 0x3e, 0xc2, 0xd1, 0x48, 0xee, 0x43, 0x41, 0x85, 0x28, 0x2f, 0xb4, 0x28, 0xb9, 0x68, 0x8c, 0x62, + 0x1f, 0x95, 0x20, 0xd4, 0xcf, 0xd7, 0xdc, 0xe0, 0xe7, 0x6b, 0x24, 0xbe, 0x63, 0xfd, 0x43, 0x49, + 0xf1, 0x3d, 0xee, 0xe2, 0xac, 0xa0, 0xcb, 0xf8, 0x0c, 0xbe, 0x38, 0xb4, 0x86, 0xf5, 0xf8, 0x0c, + 0x29, 0x07, 0x97, 0x8a, 0x2e, 0x43, 0x4c, 0xe0, 0x4f, 0xc5, 0xc3, 0x3a, 0x0c, 0x31, 0xc1, 0xe9, + 0xd3, 0x42, 0x4c, 0x84, 0x24, 0xec, 0x00, 0x34, 0xbb, 0x6d, 0x1e, 0xa3, 0x7a, 0x34, 0x3a, 0x00, + 0xbd, 0x6e, 0xdb, 0x8a, 0xc7, 0xa9, 0x0e, 0x11, 0x8d, 0x7f, 0x32, 0x94, 0x2e, 0x1c, 0x84, 0xfa, + 0xae, 0xb3, 0x08, 0x07, 0x21, 0xd1, 0x27, 0x33, 0x53, 0xb7, 0x60, 0x56, 0xda, 0xe7, 0x49, 0x43, + 0xaf, 0x2d, 0x73, 0x55, 0x0c, 0x31, 0xea, 0x8d, 0x42, 0xcb, 0x3e, 0x69, 0x2c, 0x66, 0x75, 0x3d, + 0x4d, 0x6f, 0x94, 0x42, 0xbf, 0xf0, 0x1b, 0x52, 0x2d, 0xa6, 0x0e, 0xc2, 0xd6, 0x56, 0x38, 0x97, + 0x63, 0x83, 0xd0, 0xed, 0x6a, 0xc3, 0xa8, 0x93, 0xf0, 0xbd, 0x57, 0xaa, 0x1c, 0x90, 0x89, 0x22, + 0x2b, 0x2a, 0x8a, 0x8a, 0x18, 0x97, 0x18, 0x11, 0xd9, 0x83, 0x8b, 0x91, 0x28, 0xad, 0xdc, 0x14, + 0x90, 0x23, 0x6f, 0xf0, 0xb5, 0x93, 0xe3, 0xe2, 0xcb, 0x8a, 0x28, 0xae, 0x5e, 0x38, 0x62, 0xdc, + 0x7b, 0xf3, 0x62, 0xfb, 0xed, 0x92, 0x67, 0xb7, 0xeb, 0xfb, 0xca, 0x9c, 0xc7, 0xfd, 0x76, 0x07, + 0xa1, 0x09, 0x27, 0xf9, 0x08, 0xd9, 0xf8, 0xd1, 0x2c, 0x4c, 0xf1, 0xb3, 0x9a, 0xbf, 0xce, 0x3d, + 0xb5, 0x2f, 0x9f, 0x6f, 0x69, 0x2f, 0x9f, 0x32, 0x9e, 0x9b, 0xda, 0xb4, 0x81, 0xde, 0x3d, 0xf7, + 0x81, 0x24, 0x69, 0x88, 0x09, 0x13, 0x2a, 0xb4, 0xff, 0x93, 0xe7, 0xcd, 0x28, 0xf4, 0x9f, 0x10, + 0x95, 0xf0, 0xdd, 0xd9, 0x37, 0x35, 0x1e, 0xc6, 0x8f, 0x64, 0x61, 0x52, 0xb1, 0x53, 0x79, 0x6a, + 0x3b, 0xfe, 0xf3, 0x5a, 0xc7, 0xcf, 0x87, 0x1e, 0x82, 0x61, 0xcb, 0x06, 0xea, 0xf7, 0x2e, 0xcc, + 0x24, 0x48, 0xe2, 0xe6, 0x3e, 0x99, 0x41, 0xcc, 0x7d, 0x5e, 0x4b, 0xc6, 0x11, 0xe3, 0xe1, 0xf8, + 0xc3, 0xa8, 0x32, 0x6a, 0xe0, 0xb2, 0x1f, 0xcf, 0xc2, 0x9c, 0xf8, 0x85, 0x81, 0x37, 0xb9, 0xb0, + 0xfa, 0xd4, 0x8e, 0x45, 0x49, 0x1b, 0x8b, 0xa2, 0x3e, 0x16, 0x4a, 0x03, 0x7b, 0x0f, 0x89, 0xf1, + 0x83, 0x00, 0xf3, 0xbd, 0x08, 0x06, 0x76, 0xc4, 0x8f, 0x5c, 0x13, 0xb3, 0x03, 0xb8, 0x26, 0xae, + 0x42, 0x01, 0xab, 0x12, 0xa1, 0xf5, 0xfc, 0x2d, 0xb3, 0x2a, 0x3a, 0x09, 0xf5, 0x0b, 0x3c, 0x3a, + 0xaa, 0x08, 0xf5, 0xe7, 0xc7, 0x74, 0x1e, 0x09, 0x4a, 0xf2, 0x4b, 0x19, 0x98, 0x42, 0xe0, 0xf2, + 0x23, 0xda, 0x0e, 0x90, 0xd9, 0x90, 0xf0, 0x59, 0x0b, 0x1f, 0x46, 0x6b, 0x81, 0xe7, 0xb4, 0xf7, + 0xc4, 0xcb, 0xe8, 0x8e, 0x78, 0x19, 0x7d, 0x9b, 0xbf, 0xe8, 0x5e, 0xaf, 0xbb, 0xad, 0x1b, 0x7b, + 0x9e, 0xfd, 0xc8, 0xe1, 0x26, 0x58, 0x76, 0xf3, 0x46, 0x94, 0x45, 0xa6, 0xe3, 0xc4, 0xf2, 0xbb, + 0x08, 0x56, 0xf8, 0xea, 0xcc, 0x3f, 0x94, 0x62, 0xb5, 0x71, 0xd5, 0x8c, 0xfe, 0x45, 0xe4, 0xbb, + 0xe0, 0x02, 0x0f, 0x78, 0xc5, 0x6e, 0xf8, 0x4e, 0xbb, 0xeb, 0x76, 0xfd, 0x25, 0xbb, 0x7e, 0xc0, + 0xc4, 0x7c, 0xee, 0x59, 0x8c, 0x2d, 0xaf, 0x87, 0x85, 0xd6, 0x0e, 0x2f, 0xd5, 0x22, 0x29, 0xa4, + 0x33, 0x20, 0x2b, 0x30, 0xc3, 0x8b, 0x4a, 0xdd, 0xc0, 0xad, 0xd5, 0xed, 0xa6, 0xd3, 0xde, 0x43, + 0x59, 0x22, 0xcf, 0x45, 0x19, 0xbb, 0x1b, 0xb8, 0x96, 0xcf, 0xe1, 0xaa, 0xa6, 0x26, 0x41, 0x44, + 0xaa, 0x30, 0x6d, 0x52, 0xbb, 0xf1, 0xc0, 0x7e, 0x5c, 0xb6, 0x3b, 0x76, 0xdd, 0x09, 0x78, 0x04, + 0xce, 0x1c, 0x17, 0xe8, 0x3c, 0x6a, 0x37, 0xac, 0x96, 0xfd, 0xd8, 0xaa, 0x8b, 0x42, 0x5d, 0x65, + 0xaf, 0xd1, 0x85, 0xac, 0x9c, 0x76, 0xc8, 0x6a, 0x2c, 0xce, 0xca, 0x69, 0xf7, 0x66, 0x15, 0xd1, + 0x49, 0x56, 0x9b, 0xb6, 0xb7, 0x47, 0x03, 0x6e, 0x28, 0x0d, 0x97, 0x33, 0x57, 0x33, 0x0a, 0xab, + 0x00, 0xcb, 0x2c, 0x34, 0x9a, 0x8e, 0xb3, 0x52, 0xe8, 0xd8, 0xcc, 0xdb, 0xf6, 0x9c, 0x80, 0xaa, + 0x2d, 0x1c, 0xc7, 0xcf, 0xc2, 0xfe, 0x47, 0x13, 0xf3, 0x5e, 0x4d, 0x4c, 0x50, 0x46, 0xdc, 0x94, + 0x46, 0x4e, 0x24, 0xb8, 0xa5, 0xb7, 0x32, 0x41, 0x19, 0x72, 0x53, 0xdb, 0x39, 0x89, 0xed, 0x54, + 0xb8, 0xf5, 0x68, 0x68, 0x82, 0x92, 0xac, 0xb1, 0x4e, 0x0b, 0x98, 0xdc, 0xe4, 0xb6, 0x85, 0x05, + 0xf7, 0x14, 0x7e, 0xda, 0x4b, 0xc2, 0x0c, 0xb1, 0xe0, 0xc9, 0x62, 0x2b, 0xc5, 0x9e, 0x3b, 0x4e, + 0x4c, 0xfe, 0x06, 0x4c, 0x6f, 0xf9, 0xf4, 0x4e, 0x75, 0xa3, 0x26, 0xe3, 0x63, 0xa1, 0x72, 0x71, + 0x6a, 0xf1, 0xe6, 0x29, 0x9b, 0xce, 0x75, 0x95, 0x06, 0x93, 0xb2, 0xf0, 0x71, 0xeb, 0xfa, 0xd4, + 0xda, 0x75, 0x3a, 0x7e, 0x18, 0x6c, 0x50, 0x1d, 0xb7, 0x58, 0x55, 0xc6, 0x0a, 0xcc, 0x24, 0xd8, + 0x90, 0x29, 0x00, 0x06, 0xb4, 0xb6, 0xd6, 0x6a, 0xcb, 0x9b, 0x85, 0x67, 0x48, 0x01, 0x26, 0xf0, + 0xf7, 0xf2, 0x5a, 0x69, 0x69, 0x75, 0xb9, 0x52, 0xc8, 0x90, 0x19, 0x98, 0x44, 0x48, 0xa5, 0x5a, + 0xe3, 0xa0, 0x2c, 0x0f, 0xc9, 0x6f, 0x16, 0xf8, 0xd2, 0x0d, 0xd8, 0x02, 0xc0, 0x33, 0xc5, 0xf8, + 0xbb, 0x59, 0xb8, 0x28, 0x8f, 0x15, 0x1a, 0x30, 0xc1, 0xd1, 0x69, 0xef, 0x3d, 0xe5, 0xa7, 0xc3, + 0x1d, 0xed, 0x74, 0x78, 0x29, 0x76, 0x52, 0xc7, 0x5a, 0xd9, 0xe7, 0x88, 0xf8, 0xed, 0x31, 0x78, + 0xbe, 0x2f, 0x15, 0x79, 0x9f, 0x9d, 0xe6, 0x0e, 0x6d, 0x07, 0xd5, 0x46, 0x93, 0x6e, 0x3a, 0x2d, + 0xea, 0x76, 0x03, 0xe1, 0x31, 0xf0, 0x22, 0xea, 0xf3, 0xb0, 0xd0, 0x72, 0x1a, 0x4d, 0x6a, 0x05, + 0xbc, 0x58, 0x9b, 0x6e, 0x49, 0x6a, 0xc6, 0x32, 0x4c, 0x10, 0x55, 0x6d, 0x07, 0xd4, 0x7b, 0x84, + 0x56, 0x89, 0x21, 0xcb, 0x03, 0x4a, 0x3b, 0x96, 0xcd, 0x4a, 0x2d, 0x47, 0x14, 0xeb, 0x2c, 0x13, + 0xd4, 0xe4, 0x8e, 0xc2, 0xb2, 0xcc, 0x6e, 0xff, 0x0f, 0xec, 0xc7, 0xc2, 0x4c, 0x4a, 0xc4, 0x5b, + 0x0d, 0x59, 0x72, 0x77, 0xbe, 0x96, 0xfd, 0xd8, 0x4c, 0x92, 0x90, 0xaf, 0xc0, 0x39, 0x71, 0x00, + 0x89, 0xe0, 0x2d, 0xb2, 0xc5, 0x3c, 0x34, 0xcc, 0x2b, 0x27, 0xc7, 0xc5, 0x0b, 0x32, 0x52, 0xad, + 0x0c, 0xd7, 0x93, 0xd6, 0xea, 0x74, 0x2e, 0x64, 0x93, 0x1d, 0xc8, 0xb1, 0xee, 0x78, 0x40, 0x7d, + 0x5f, 0xfa, 0x6c, 0x8a, 0x9b, 0xb1, 0xda, 0x99, 0x56, 0x8b, 0x97, 0x9b, 0x3d, 0x29, 0xc9, 0x0a, + 0x4c, 0x6d, 0xd3, 0x1d, 0x75, 0x7c, 0x46, 0xc2, 0xad, 0xaa, 0x70, 0x48, 0x77, 0x7a, 0x0f, 0x4e, + 0x8c, 0x8e, 0x38, 0xf8, 0x3e, 0xf0, 0xf8, 0x68, 0xd5, 0xf1, 0x03, 0xda, 0xa6, 0x1e, 0x06, 0x05, + 0x1b, 0xc5, 0xcd, 0x60, 0x3e, 0x92, 0x90, 0xf5, 0xf2, 0xa5, 0x17, 0x4e, 0x8e, 0x8b, 0xcf, 0x73, + 0xe7, 0xe7, 0xa6, 0x80, 0x5b, 0xb1, 0xf4, 0x4a, 0x49, 0xae, 0xe4, 0x6b, 0x30, 0x6d, 0xba, 0xdd, + 0xc0, 0x69, 0xef, 0xd5, 0x02, 0xcf, 0x0e, 0xe8, 0x1e, 0x3f, 0x90, 0xa2, 0xe8, 0x63, 0xb1, 0x52, + 0xf1, 0xb4, 0xcc, 0x81, 0x96, 0x2f, 0xa0, 0xda, 0x89, 0xa0, 0x13, 0x90, 0xaf, 0xc2, 0x14, 0x0f, + 0xdb, 0x11, 0x56, 0x30, 0xa6, 0xa5, 0x86, 0xd0, 0x0b, 0x1f, 0xde, 0x14, 0x56, 0x2d, 0x08, 0x4d, + 0xab, 0x20, 0xc6, 0x8d, 0x7c, 0x49, 0x74, 0xd6, 0x86, 0xd3, 0xde, 0x0b, 0xa7, 0x31, 0x60, 0xcf, + 0xbf, 0x1e, 0x75, 0x49, 0x87, 0x7d, 0xae, 0x9c, 0xc6, 0x3d, 0x4c, 0xf4, 0x92, 0x7c, 0x48, 0x00, + 0xcf, 0x97, 0x7c, 0xdf, 0xf1, 0x03, 0xe1, 0x57, 0xb3, 0xfc, 0x98, 0xd6, 0xbb, 0x0c, 0x99, 0x5d, + 0x6f, 0xa9, 0xc7, 0xed, 0xba, 0x87, 0x97, 0xae, 0x9f, 0x1c, 0x17, 0x5f, 0xb5, 0x11, 0xd1, 0x12, + 0xae, 0x38, 0x16, 0x95, 0xa8, 0xd6, 0x21, 0xc7, 0x55, 0xda, 0xd0, 0x9f, 0x29, 0xf9, 0x2a, 0x9c, + 0x2f, 0xdb, 0x3e, 0xad, 0xb6, 0x7d, 0xda, 0xf6, 0x9d, 0xc0, 0x79, 0x44, 0x45, 0xa7, 0xe2, 0xe1, + 0x97, 0xc7, 0x44, 0x54, 0x46, 0xdd, 0xf6, 0xd9, 0xc2, 0x0c, 0x51, 0x2c, 0x31, 0x28, 0x4a, 0x35, + 0x3d, 0xb8, 0x10, 0x13, 0xa6, 0x6a, 0xb5, 0x95, 0x8a, 0x63, 0x87, 0xeb, 0x6a, 0x12, 0xfb, 0xeb, + 0x55, 0x54, 0xed, 0xf9, 0xfb, 0x56, 0xc3, 0xb1, 0xc3, 0x05, 0xd5, 0xa3, 0xb3, 0x62, 0x1c, 0x8c, + 0xe3, 0x0c, 0x14, 0xe2, 0x43, 0x49, 0xbe, 0x08, 0x63, 0xdc, 0xbe, 0x8d, 0xfa, 0xfb, 0x22, 0xf2, + 0x84, 0x34, 0x97, 0x0a, 0xe1, 0x3a, 0x91, 0x70, 0xa7, 0xe3, 0xd6, 0x73, 0x54, 0xb5, 0x96, 0x41, + 0x77, 0x3a, 0x49, 0x44, 0x1a, 0x30, 0xc1, 0x47, 0x8b, 0x62, 0xe8, 0x41, 0x61, 0xe6, 0xfc, 0x82, + 0xba, 0x3a, 0x44, 0x51, 0x8c, 0x3f, 0xbe, 0x1a, 0x8a, 0x39, 0xc1, 0x11, 0xb4, 0x2a, 0x34, 0xae, + 0x4b, 0x00, 0x79, 0x49, 0x68, 0x5c, 0x84, 0x0b, 0x3d, 0xbe, 0xd9, 0x78, 0x84, 0x96, 0x04, 0x3d, + 0x6a, 0x24, 0x5f, 0x84, 0x39, 0x24, 0x2c, 0xbb, 0xed, 0x36, 0xad, 0x07, 0xb8, 0x1d, 0x49, 0xed, + 0x7b, 0x8e, 0x5b, 0xba, 0xf0, 0xf6, 0xd6, 0x43, 0x04, 0x2b, 0xae, 0x84, 0x4f, 0xe5, 0x60, 0xfc, + 0x6c, 0x16, 0xe6, 0xc5, 0x0e, 0x67, 0xd2, 0xba, 0xeb, 0x35, 0x9e, 0xfe, 0x13, 0x75, 0x59, 0x3b, + 0x51, 0x5f, 0x0c, 0xc3, 0x16, 0xa5, 0x35, 0xb2, 0xcf, 0x81, 0xfa, 0xab, 0x19, 0x78, 0xae, 0x1f, + 0x11, 0xeb, 0x9d, 0x30, 0xd4, 0xe2, 0x58, 0x22, 0xa4, 0x62, 0x07, 0x66, 0x71, 0x40, 0xcb, 0xfb, + 0xb4, 0x7e, 0xe0, 0xaf, 0xb8, 0x7e, 0x80, 0x9e, 0x16, 0xd9, 0x1e, 0x6f, 0xdd, 0xaf, 0xa5, 0xbe, + 0x75, 0x9f, 0xe7, 0xb3, 0xac, 0x8e, 0x3c, 0x78, 0x30, 0xc8, 0x03, 0x7a, 0xe4, 0x9b, 0x69, 0xac, + 0xd1, 0x62, 0xbe, 0xd4, 0x0d, 0xf6, 0x37, 0x3c, 0xba, 0x4b, 0x3d, 0xda, 0xae, 0xd3, 0xef, 0x30, + 0x8b, 0x79, 0xbd, 0x71, 0x03, 0x69, 0x30, 0x7e, 0x77, 0x12, 0xe6, 0xd2, 0xc8, 0x58, 0xbf, 0x28, + 0x97, 0xe6, 0x78, 0x9e, 0xcc, 0x6f, 0x66, 0x60, 0xa2, 0x46, 0xeb, 0x6e, 0xbb, 0x71, 0x07, 0x2d, + 0x8a, 0x44, 0xef, 0xd8, 0x5c, 0x68, 0x60, 0x70, 0x6b, 0x37, 0x66, 0x6a, 0xf4, 0xed, 0xe3, 0xe2, + 0x17, 0x06, 0xbb, 0xab, 0xd6, 0x5d, 0x0c, 0x17, 0x14, 0x60, 0x1e, 0x87, 0xb0, 0x0a, 0xfe, 0x35, + 0xa6, 0x56, 0x2d, 0x59, 0x82, 0x49, 0xb1, 0x60, 0x5d, 0x35, 0xd6, 0x26, 0x8f, 0xed, 0x24, 0x0b, + 0x12, 0xca, 0x6b, 0x8d, 0x84, 0xdc, 0x82, 0xdc, 0xd6, 0xe2, 0x1d, 0x31, 0x0a, 0x32, 0x17, 0xc6, + 0xd6, 0xe2, 0x1d, 0x54, 0x88, 0xb1, 0x4b, 0xc6, 0x64, 0x77, 0x51, 0x33, 0xf3, 0xd9, 0x5a, 0xbc, + 0x43, 0xfe, 0x26, 0x9c, 0xab, 0x38, 0xbe, 0xa8, 0x82, 0x7b, 0x6f, 0x34, 0xd0, 0x67, 0x71, 0xa4, + 0xc7, 0xfc, 0xfd, 0x6c, 0xea, 0xfc, 0x7d, 0xa1, 0x11, 0x32, 0xb1, 0xb8, 0x6b, 0x48, 0x23, 0x1e, + 0x53, 0x34, 0xbd, 0x1e, 0xf2, 0x21, 0x4c, 0xa1, 0x3a, 0x1b, 0x1d, 0x5a, 0x30, 0x1a, 0xfc, 0x68, + 0x8f, 0x9a, 0x3f, 0x9d, 0x5a, 0xf3, 0x02, 0x8f, 0xb8, 0x81, 0x6e, 0x31, 0x18, 0x39, 0x5e, 0xbb, + 0xf7, 0x6b, 0x9c, 0xc9, 0x3d, 0x98, 0x16, 0x02, 0xd8, 0xfa, 0xee, 0xe6, 0x3e, 0xad, 0xd8, 0x47, + 0xc2, 0x42, 0x07, 0xef, 0x74, 0x42, 0x6a, 0xb3, 0xdc, 0x5d, 0x2b, 0xd8, 0xa7, 0x56, 0xc3, 0xd6, + 0x44, 0x95, 0x18, 0x21, 0xf9, 0x06, 0x8c, 0xaf, 0xba, 0x75, 0x26, 0x7b, 0xe3, 0xde, 0xc0, 0x8d, + 0x76, 0x3e, 0xc0, 0x5c, 0x8c, 0x1c, 0x1c, 0x13, 0xa8, 0xbe, 0x7d, 0x5c, 0x7c, 0xeb, 0xac, 0xd3, + 0x46, 0xa9, 0xc0, 0x54, 0x6b, 0x23, 0x65, 0xc8, 0x6f, 0xd3, 0x1d, 0xd6, 0xda, 0x78, 0x9e, 0x36, + 0x09, 0x16, 0x36, 0x79, 0xe2, 0x97, 0x66, 0x93, 0x27, 0x60, 0xc4, 0x83, 0x19, 0xec, 0x9f, 0x0d, + 0xdb, 0xf7, 0x0f, 0x5d, 0xaf, 0x81, 0x09, 0x39, 0x7a, 0xd9, 0x03, 0x2d, 0xa6, 0x76, 0xfe, 0x73, + 0xbc, 0xf3, 0x3b, 0x0a, 0x07, 0x55, 0x84, 0x4c, 0xb0, 0x27, 0x5f, 0x83, 0x29, 0x11, 0xbd, 0xe0, + 0xc1, 0x9d, 0x12, 0xae, 0x84, 0x09, 0xcd, 0xf3, 0x53, 0x2f, 0xe4, 0x72, 0xaa, 0x08, 0x86, 0x20, + 0x75, 0x50, 0x56, 0x6b, 0xd7, 0xd6, 0xd5, 0xfe, 0x2a, 0x09, 0xd9, 0x80, 0xf1, 0x0a, 0x66, 0x0b, + 0x46, 0xef, 0x34, 0x61, 0x19, 0x1e, 0x26, 0x9a, 0x8a, 0x4a, 0xb8, 0x36, 0x46, 0x24, 0x16, 0x46, + 0x5f, 0x37, 0xdd, 0x5a, 0x37, 0x44, 0x24, 0xb7, 0x21, 0x57, 0xad, 0x6c, 0x08, 0xc3, 0xf0, 0x99, + 0x30, 0x46, 0xc8, 0x86, 0x4c, 0xcb, 0x83, 0x16, 0x74, 0x4e, 0x43, 0x33, 0x2b, 0xaf, 0x56, 0x36, + 0xc8, 0x2e, 0x4c, 0x62, 0x07, 0xac, 0x50, 0x9b, 0xf7, 0xed, 0x74, 0x8f, 0xbe, 0xbd, 0x9e, 0xda, + 0xb7, 0xf3, 0xbc, 0x6f, 0xf7, 0x05, 0xb5, 0x96, 0x67, 0x44, 0x65, 0xcb, 0x84, 0x5a, 0x91, 0xfb, + 0x48, 0x66, 0xc7, 0xd8, 0x5c, 0x45, 0x0b, 0x21, 0x21, 0xd4, 0xca, 0x54, 0x49, 0x61, 0xba, 0x8e, + 0x9e, 0x7e, 0x27, 0x49, 0x3e, 0xe4, 0xf3, 0x30, 0xb4, 0x7e, 0x10, 0xd8, 0xc2, 0x04, 0x5c, 0xf6, + 0x23, 0x03, 0xc9, 0xe6, 0xa3, 0x1e, 0xd2, 0x3d, 0xd0, 0xa2, 0xce, 0x21, 0x0d, 0x1b, 0x8a, 0x15, + 0xdb, 0x6b, 0x1c, 0xda, 0x1e, 0xba, 0x08, 0xcf, 0x6a, 0x2c, 0x94, 0x12, 0x3e, 0x14, 0xfb, 0x02, + 0x10, 0xf3, 0x1b, 0x56, 0x59, 0x90, 0xef, 0x82, 0x8b, 0xbe, 0xb3, 0xd7, 0xb6, 0x83, 0xae, 0x47, + 0x2d, 0xbb, 0xb9, 0xe7, 0x7a, 0x4e, 0xb0, 0xdf, 0xb2, 0xfc, 0xae, 0x13, 0xd0, 0xf9, 0x39, 0x2d, + 0x53, 0x72, 0x4d, 0xe2, 0x95, 0x24, 0x5a, 0x8d, 0x61, 0x99, 0x17, 0xfc, 0xf4, 0x02, 0xf2, 0x25, + 0x98, 0x54, 0xb7, 0x64, 0x7f, 0xfe, 0xdc, 0xe5, 0xdc, 0xd5, 0xa9, 0xf0, 0xea, 0x11, 0xdf, 0xc2, + 0x65, 0x84, 0x61, 0xe5, 0x8c, 0xf0, 0xf5, 0x08, 0xc3, 0x0a, 0xaf, 0x30, 0xf7, 0x20, 0x29, 0xcc, + 0x9a, 0x33, 0x62, 0xc6, 0x8a, 0x5e, 0x7e, 0x70, 0xa7, 0x64, 0x8e, 0x6e, 0x54, 0x1f, 0xd6, 0x9a, + 0x6e, 0x60, 0xfc, 0x67, 0x19, 0xdc, 0xc4, 0xc9, 0xab, 0x18, 0x4a, 0x2a, 0x7c, 0x3f, 0x43, 0x0d, + 0xae, 0xdd, 0x89, 0x85, 0xa7, 0xe7, 0x28, 0xe4, 0x35, 0x18, 0xb9, 0x63, 0xd7, 0x65, 0x18, 0x1b, + 0x81, 0xbc, 0x8b, 0x10, 0x55, 0xdd, 0xcb, 0x71, 0x98, 0x84, 0xc9, 0x27, 0x77, 0x29, 0x4a, 0xc2, + 0x5d, 0x2e, 0xc9, 0x07, 0x7b, 0x94, 0x30, 0xc5, 0xa2, 0x50, 0xb2, 0x74, 0xc7, 0xec, 0xe2, 0x53, + 0x39, 0x18, 0x7f, 0x96, 0x89, 0x76, 0x25, 0xf2, 0x0a, 0x0c, 0x99, 0x1b, 0xe1, 0xf7, 0x73, 0xb7, + 0xdf, 0xd8, 0xe7, 0x23, 0x02, 0xf9, 0x12, 0x9c, 0x53, 0xf8, 0x24, 0x8c, 0xf4, 0x5f, 0x46, 0xaf, + 0x54, 0xe5, 0x4b, 0xd2, 0x2d, 0xf5, 0xd3, 0x79, 0xa0, 0x38, 0x1d, 0x15, 0x54, 0x68, 0xdb, 0xe1, + 0xbc, 0x95, 0xc6, 0xaa, 0xbc, 0x1b, 0x88, 0x10, 0x6f, 0x6c, 0x1a, 0x07, 0xee, 0x94, 0x6a, 0xfc, + 0x56, 0x46, 0xdb, 0x6d, 0xc2, 0xac, 0xc5, 0x99, 0x53, 0xb2, 0x16, 0xbf, 0x09, 0x50, 0xea, 0x06, + 0xee, 0x72, 0xdb, 0x73, 0x9b, 0x5c, 0x8f, 0x22, 0x32, 0x34, 0xa0, 0x76, 0x98, 0x22, 0x58, 0xf3, + 0x9d, 0x0b, 0x91, 0x53, 0xfd, 0x19, 0x72, 0x1f, 0xd5, 0x9f, 0xc1, 0xf8, 0x83, 0x8c, 0xb6, 0x46, + 0x99, 0x9c, 0x28, 0xa6, 0xa2, 0x6a, 0x33, 0xd6, 0x71, 0x1e, 0x59, 0x7e, 0xd3, 0xd5, 0x02, 0x56, + 0x08, 0x34, 0xf2, 0xff, 0xcf, 0xc0, 0x79, 0xee, 0x18, 0xb0, 0xd6, 0x6d, 0xed, 0x50, 0xef, 0xa1, + 0xdd, 0x74, 0x1a, 0x51, 0xa0, 0xbe, 0xc8, 0x80, 0x50, 0xa9, 0x26, 0x1d, 0x9f, 0x5f, 0x55, 0xb9, + 0xa3, 0x82, 0xd5, 0xc6, 0x42, 0xeb, 0x51, 0x58, 0xaa, 0x5e, 0x55, 0xd3, 0xe9, 0x8d, 0x5f, 0xcb, + 0xc0, 0x0b, 0xa7, 0xd6, 0x42, 0x6e, 0xc0, 0xa8, 0x4c, 0x8d, 0x91, 0xc1, 0x8e, 0x47, 0x4b, 0xdb, + 0x64, 0x5a, 0x0c, 0x89, 0x45, 0xbe, 0x0c, 0xe7, 0x54, 0x56, 0x9b, 0x9e, 0xed, 0xa8, 0x09, 0x28, + 0x52, 0xbe, 0x3a, 0x60, 0x28, 0x71, 0x69, 0x2d, 0x9d, 0x89, 0xf1, 0xff, 0x64, 0x94, 0x3c, 0xe6, + 0x4f, 0xa9, 0x14, 0x7f, 0x5b, 0x93, 0xe2, 0x65, 0x98, 0xd2, 0xb0, 0x55, 0xac, 0x2c, 0xf5, 0xe6, + 0x35, 0xad, 0x58, 0x8c, 0x23, 0xe0, 0x87, 0xb2, 0x30, 0xbe, 0xe5, 0x53, 0x8f, 0x3f, 0xe5, 0x7e, + 0x67, 0x05, 0x6b, 0x0c, 0xdb, 0x35, 0x50, 0x38, 0xbd, 0x3f, 0xc9, 0xa0, 0x8a, 0x5f, 0xa5, 0x60, + 0xbd, 0xa1, 0xe4, 0x2e, 0xc4, 0xde, 0xc0, 0xac, 0x85, 0x08, 0xe5, 0xc1, 0xc5, 0x56, 0xf5, 0x34, + 0xa6, 0x98, 0xcb, 0x76, 0x95, 0x7c, 0x01, 0x86, 0xb7, 0x50, 0x61, 0xa9, 0x87, 0xd9, 0x08, 0xf9, + 0x63, 0x21, 0xdf, 0xa4, 0xbb, 0xbe, 0x1e, 0x79, 0x8e, 0x13, 0x92, 0x1a, 0x8c, 0x96, 0x3d, 0x8a, + 0x59, 0xc9, 0x87, 0x06, 0x77, 0x12, 0xaf, 0x73, 0x92, 0xb8, 0x93, 0xb8, 0xe0, 0x64, 0xfc, 0x4c, + 0x16, 0x48, 0xd4, 0x46, 0x4c, 0xc1, 0xe5, 0x3f, 0xb5, 0x83, 0xfe, 0x9e, 0x36, 0xe8, 0xcf, 0x27, + 0x06, 0x9d, 0x37, 0x6f, 0xa0, 0xb1, 0xff, 0x9d, 0x0c, 0x9c, 0x4f, 0x27, 0x24, 0x2f, 0xc2, 0xc8, + 0xfa, 0xe6, 0x86, 0x8c, 0xd4, 0x22, 0x9a, 0xe2, 0x76, 0x50, 0x5b, 0x60, 0x8a, 0x22, 0xf2, 0x3a, + 0x8c, 0xbc, 0x6f, 0x96, 0xd9, 0x39, 0xa4, 0x24, 0x79, 0xf8, 0xba, 0x67, 0xd5, 0xf5, 0xa3, 0x48, + 0x20, 0xa9, 0x63, 0x9b, 0x7b, 0x62, 0x63, 0xfb, 0xe3, 0x59, 0x98, 0x2e, 0xd5, 0xeb, 0xd4, 0xf7, + 0x99, 0xb4, 0x43, 0xfd, 0xe0, 0xa9, 0x1d, 0xd8, 0xf4, 0x18, 0x2c, 0x5a, 0xdb, 0x06, 0x1a, 0xd5, + 0xdf, 0xcb, 0xc0, 0x39, 0x49, 0xf5, 0xc8, 0xa1, 0x87, 0x9b, 0xfb, 0x1e, 0xf5, 0xf7, 0xdd, 0x66, + 0x63, 0xe0, 0x4c, 0x32, 0x4c, 0xd0, 0xc3, 0xf0, 0xf0, 0xea, 0xbb, 0xfe, 0x2e, 0x42, 0x34, 0x41, + 0x8f, 0x87, 0x90, 0xbf, 0x01, 0xa3, 0xa5, 0x4e, 0xc7, 0x73, 0x1f, 0xf1, 0x65, 0x2f, 0x62, 0x4b, + 0xda, 0x1c, 0xa4, 0xf9, 0xd8, 0x73, 0x10, 0xfb, 0x8c, 0x0a, 0x6d, 0xf3, 0x60, 0x7e, 0x93, 0xfc, + 0x33, 0x1a, 0xb4, 0xad, 0xca, 0xe2, 0x58, 0x6e, 0xd4, 0x80, 0x6c, 0x78, 0x6e, 0xcb, 0x0d, 0x68, + 0x83, 0xb7, 0x07, 0x43, 0x13, 0x9c, 0x1a, 0x54, 0x6b, 0xd3, 0x09, 0x9a, 0x5a, 0x50, 0xad, 0x80, + 0x01, 0x4c, 0x0e, 0x37, 0xfe, 0xaf, 0x61, 0x98, 0x50, 0x7b, 0x87, 0x18, 0x3c, 0x3d, 0x84, 0xeb, + 0xa9, 0xf1, 0x31, 0x6c, 0x84, 0x98, 0xa2, 0x24, 0x0a, 0x2e, 0x93, 0x3d, 0x35, 0xb8, 0xcc, 0x36, + 0x4c, 0x6e, 0x78, 0x2e, 0x06, 0xc1, 0xc4, 0xf7, 0x4a, 0xb1, 0x15, 0xce, 0x2a, 0xf7, 0x4e, 0x36, + 0x90, 0xf8, 0x22, 0x8a, 0x92, 0x7d, 0x47, 0x60, 0x63, 0xd2, 0x44, 0x4d, 0xeb, 0xa2, 0xf1, 0xe1, + 0xc6, 0x16, 0xb6, 0x2f, 0x22, 0xd9, 0x86, 0xc6, 0x16, 0x0c, 0xa2, 0x1b, 0x5b, 0x30, 0x88, 0xba, + 0xd6, 0x86, 0x9f, 0xd4, 0x5a, 0x23, 0x3f, 0x93, 0x81, 0xf1, 0x52, 0xbb, 0x2d, 0x82, 0xd6, 0x9c, + 0xe2, 0xaf, 0xff, 0x65, 0x61, 0x6f, 0xf1, 0xd6, 0x47, 0xb2, 0xb7, 0x40, 0xb9, 0xc5, 0x47, 0x49, + 0x35, 0xaa, 0x50, 0xbd, 0xad, 0x29, 0xdf, 0x41, 0xde, 0x82, 0x42, 0x38, 0xc9, 0xab, 0xed, 0x06, + 0x7d, 0x4c, 0x79, 0x7a, 0xbd, 0x49, 0x11, 0x59, 0x5b, 0x95, 0x4c, 0xe3, 0x88, 0x64, 0x13, 0xc0, + 0x0e, 0x67, 0x57, 0x2c, 0x4f, 0x68, 0x72, 0xfa, 0x09, 0xe9, 0x19, 0x7f, 0xe3, 0x93, 0x96, 0x2a, + 0x3d, 0x47, 0x7c, 0x48, 0x0b, 0xa6, 0x79, 0x92, 0xce, 0x5a, 0x60, 0x7b, 0x01, 0x26, 0xa3, 0x80, + 0x53, 0xc7, 0xe1, 0x15, 0xa1, 0x3f, 0x7b, 0x56, 0xa4, 0xfe, 0xf4, 0x19, 0xad, 0x95, 0x92, 0x99, + 0x22, 0xce, 0x9b, 0xc7, 0x31, 0x37, 0x2f, 0x24, 0xbf, 0x97, 0x4f, 0xfa, 0x1f, 0xcf, 0xc0, 0x79, + 0x75, 0xd2, 0xd7, 0xba, 0x3b, 0x22, 0x78, 0x28, 0xb9, 0x0e, 0x63, 0x62, 0x4e, 0x86, 0x97, 0xa8, + 0x64, 0x4e, 0x8d, 0x08, 0x85, 0x2c, 0xb3, 0x69, 0xc8, 0x78, 0x08, 0xa9, 0x7b, 0x36, 0xb6, 0x4f, + 0xb1, 0xa2, 0x28, 0x01, 0xb4, 0x87, 0xbf, 0xf5, 0xf9, 0xc9, 0x20, 0xc6, 0xbb, 0x30, 0xa3, 0x8f, + 0x44, 0x8d, 0x06, 0xe4, 0x1a, 0x8c, 0xca, 0xe1, 0xcb, 0xa4, 0x0f, 0x9f, 0x2c, 0x37, 0xb6, 0x81, + 0x24, 0xe8, 0x7d, 0x34, 0x8c, 0x62, 0xf7, 0x53, 0x6e, 0xb8, 0x27, 0x9f, 0x25, 0x13, 0x88, 0x4b, + 0xb3, 0xe2, 0xfb, 0xc6, 0x35, 0xc7, 0x04, 0x0c, 0xa4, 0xfa, 0xcf, 0xa7, 0x61, 0x36, 0x65, 0xcf, + 0x3d, 0x45, 0x26, 0x2a, 0xea, 0x1b, 0xc4, 0x58, 0x18, 0xee, 0x43, 0x6e, 0x0b, 0xef, 0xc2, 0xf0, + 0xa9, 0xdb, 0x01, 0x77, 0x4b, 0x89, 0xed, 0x02, 0x9c, 0xec, 0x13, 0x91, 0x8b, 0xd4, 0x88, 0x3c, + 0xc3, 0x4f, 0x2c, 0x22, 0xcf, 0x12, 0x4c, 0x8a, 0x56, 0x89, 0xed, 0x4a, 0x31, 0x8f, 0xf6, 0x78, + 0x81, 0x95, 0xd8, 0xb6, 0x74, 0x12, 0xce, 0xc3, 0x77, 0x9b, 0x8f, 0xa8, 0xe0, 0x31, 0xaa, 0xf2, + 0xc0, 0x82, 0x54, 0x1e, 0x0a, 0x09, 0xf9, 0x0f, 0x31, 0x41, 0x20, 0x42, 0xd4, 0x3d, 0x2b, 0xdf, + 0x6f, 0xcf, 0x6a, 0x3c, 0x99, 0x3d, 0xeb, 0x79, 0xf9, 0x8d, 0xe9, 0x7b, 0x57, 0xca, 0x67, 0x91, + 0x5f, 0xce, 0xc0, 0x0c, 0x0f, 0x0b, 0xa3, 0x7e, 0x6c, 0xdf, 0x50, 0x1f, 0xf5, 0x27, 0xf3, 0xb1, + 0xcf, 0x89, 0xc4, 0x58, 0xe9, 0xdf, 0x9a, 0xfc, 0x28, 0xf2, 0x5d, 0x00, 0xe1, 0x8a, 0xe2, 0xc1, + 0x64, 0xc7, 0x17, 0x9f, 0x4b, 0xd9, 0x05, 0x42, 0xa4, 0x28, 0x89, 0x47, 0x10, 0xd2, 0x69, 0x69, + 0x21, 0x43, 0x28, 0xf9, 0x9b, 0x30, 0xc7, 0xd6, 0x4b, 0x08, 0x11, 0x41, 0xac, 0xe6, 0xc7, 0xb1, + 0x96, 0xcf, 0xf4, 0x96, 0x89, 0xae, 0xa7, 0x91, 0xf1, 0xd0, 0xc3, 0x51, 0x86, 0xee, 0x40, 0x8d, + 0x77, 0x91, 0x5a, 0x11, 0xc6, 0x86, 0xc3, 0xaf, 0xe7, 0x89, 0x36, 0x7a, 0xec, 0x6f, 0x17, 0xe5, + 0x5a, 0xe0, 0xfb, 0x9b, 0xaf, 0x7b, 0x29, 0x23, 0x88, 0xbc, 0x0f, 0x24, 0x8c, 0xa7, 0xc2, 0x61, + 0x54, 0x26, 0xe1, 0xe0, 0xea, 0xe6, 0x28, 0x2e, 0x8b, 0x27, 0x8b, 0xd5, 0x49, 0x92, 0x24, 0x26, + 0x14, 0xe6, 0x44, 0xa3, 0x19, 0x54, 0x66, 0xef, 0xf3, 0xe7, 0xa7, 0xb4, 0x10, 0x61, 0x51, 0x49, + 0x94, 0xca, 0x5b, 0x49, 0x01, 0xa8, 0xa9, 0x9c, 0xd2, 0xd8, 0x91, 0xdb, 0x30, 0x86, 0xae, 0xc2, + 0x2b, 0xd2, 0xdc, 0x4b, 0x98, 0x9e, 0xa0, 0x53, 0xb1, 0xb5, 0xaf, 0x1b, 0x6d, 0x45, 0xa8, 0xec, + 0x3a, 0x50, 0xf1, 0x8e, 0xcc, 0x6e, 0x1b, 0x95, 0xc2, 0x42, 0xdf, 0xd1, 0xf0, 0x8e, 0x2c, 0xaf, + 0xab, 0xfb, 0x92, 0x23, 0x12, 0xf9, 0x1a, 0x8c, 0x3f, 0xb0, 0x1f, 0x4b, 0x9d, 0xb0, 0x50, 0xfc, + 0xf6, 0xdb, 0x81, 0x0c, 0xd9, 0x9a, 0x96, 0xfd, 0xd8, 0x6a, 0x74, 0xe3, 0x81, 0x8f, 0x71, 0x1b, + 0x52, 0x59, 0x92, 0xaf, 0x00, 0x28, 0x9a, 0x6a, 0x72, 0x6a, 0x05, 0x2f, 0xc8, 0xc0, 0x77, 0xa9, + 0x1a, 0x6c, 0xe4, 0xaf, 0x30, 0x8c, 0x49, 0x0e, 0x73, 0x9f, 0x9c, 0xe4, 0x70, 0xee, 0x93, 0x93, + 0x1c, 0xf8, 0x43, 0x09, 0x1f, 0x7b, 0xdc, 0xc1, 0x8f, 0xe6, 0xcf, 0x9f, 0x5a, 0xdb, 0x73, 0xd2, + 0x98, 0x10, 0x8f, 0x82, 0xa3, 0x58, 0x15, 0x31, 0x7e, 0x0b, 0x3b, 0x70, 0xb1, 0xe7, 0xe2, 0x4c, + 0x09, 0xac, 0x7c, 0x43, 0x0f, 0xac, 0x7c, 0xb1, 0xd7, 0x21, 0xee, 0xeb, 0xd9, 0x5c, 0x66, 0x0b, + 0x73, 0xbd, 0xe5, 0x9f, 0x6f, 0x65, 0x63, 0x87, 0xba, 0xb8, 0xba, 0xf0, 0x4c, 0x62, 0xbd, 0xa4, + 0x9e, 0x2c, 0x26, 0x8f, 0xe6, 0xc7, 0xbe, 0x12, 0x7b, 0x9e, 0x1d, 0xfb, 0xaa, 0xd8, 0x80, 0x02, + 0xc0, 0xc7, 0x3d, 0xdf, 0xdf, 0x86, 0x29, 0x9e, 0xef, 0xf5, 0x3e, 0x3d, 0x3a, 0x74, 0xbd, 0x06, + 0xcf, 0x91, 0x24, 0xa4, 0xfc, 0x44, 0xb2, 0xf6, 0x18, 0x2e, 0xa9, 0x48, 0xff, 0xd6, 0x61, 0xac, + 0xfd, 0x62, 0xea, 0x3e, 0xc9, 0x10, 0xfa, 0xb9, 0xbe, 0x92, 0x37, 0x42, 0x51, 0x90, 0x7a, 0x6a, + 0x4e, 0x17, 0x4f, 0x02, 0x53, 0x24, 0x42, 0xea, 0x19, 0xff, 0x32, 0x07, 0x84, 0xd7, 0x54, 0xb6, + 0x3b, 0x36, 0x7a, 0x7f, 0x3b, 0x18, 0xcf, 0xa9, 0x20, 0x70, 0xec, 0x9d, 0x26, 0x55, 0x83, 0xa1, + 0x09, 0x03, 0xde, 0xb0, 0xcc, 0x8a, 0x5f, 0xa5, 0x12, 0x84, 0x3d, 0x36, 0xd3, 0xec, 0xc7, 0xd9, + 0x4c, 0xbf, 0x06, 0xcf, 0x96, 0x3a, 0x98, 0x38, 0x5a, 0xd6, 0x72, 0xc7, 0xf5, 0xe4, 0xd4, 0xd5, + 0xfc, 0x0a, 0xed, 0x10, 0x2d, 0xf1, 0xa5, 0xfd, 0x58, 0x28, 0x92, 0x10, 0x9b, 0x97, 0x9d, 0x40, + 0x8d, 0x53, 0x21, 0x25, 0xa1, 0x0e, 0x96, 0xa4, 0x48, 0x42, 0x9c, 0x44, 0xf2, 0x70, 0x3c, 0x29, + 0x09, 0x61, 0x46, 0xb4, 0x88, 0x87, 0xe3, 0xd1, 0x1e, 0xd2, 0x54, 0x48, 0x42, 0xde, 0x86, 0xf1, + 0x52, 0x37, 0x70, 0x05, 0x63, 0x61, 0x79, 0x1e, 0xd9, 0x88, 0x8b, 0x4f, 0xd1, 0x2e, 0x57, 0x11, + 0xba, 0xf1, 0xa7, 0x39, 0xb8, 0x98, 0x1c, 0x5e, 0x51, 0x1a, 0xae, 0x8f, 0xcc, 0x29, 0xeb, 0x23, + 0x6d, 0x36, 0x64, 0xa3, 0x6c, 0x16, 0x4f, 0x62, 0x36, 0xf0, 0xfc, 0xd3, 0x1f, 0x71, 0x36, 0xd4, + 0x60, 0x5c, 0x3d, 0x51, 0x87, 0x3e, 0xea, 0x89, 0xaa, 0x72, 0x21, 0xd7, 0x60, 0x98, 0x87, 0xe7, + 0x18, 0x8e, 0x1e, 0xa7, 0xe2, 0x91, 0x39, 0x38, 0x06, 0xf9, 0xff, 0xc1, 0x65, 0xbe, 0x27, 0xc5, + 0x1b, 0xbb, 0x74, 0x24, 0x39, 0x8a, 0x81, 0x5b, 0x3c, 0x39, 0x2e, 0x5e, 0xe7, 0xca, 0x18, 0x2b, + 0xd1, 0x6d, 0xd6, 0xce, 0x91, 0x25, 0xbf, 0x4c, 0xa9, 0xe4, 0x54, 0xde, 0x46, 0x19, 0x2e, 0x8a, + 0xd2, 0xc8, 0x31, 0x5c, 0x16, 0xb2, 0x41, 0x3e, 0x88, 0xf4, 0x69, 0x38, 0xc8, 0x31, 0x55, 0x19, + 0x96, 0x63, 0xe6, 0x6a, 0x25, 0xab, 0xf0, 0xeb, 0x69, 0x7e, 0x3d, 0x3c, 0x32, 0x38, 0x07, 0xeb, + 0x2e, 0x3d, 0x52, 0x6b, 0x97, 0x4d, 0xd5, 0xda, 0x49, 0xb5, 0x4f, 0x2e, 0x55, 0xed, 0x53, 0x81, + 0xe9, 0x5a, 0x77, 0x47, 0xd6, 0x1d, 0xf7, 0x09, 0xf5, 0xbb, 0x3b, 0x69, 0xbd, 0x12, 0x27, 0x31, + 0x7e, 0x38, 0x0b, 0x13, 0x1b, 0xcd, 0xee, 0x9e, 0xd3, 0xae, 0xd8, 0x81, 0xfd, 0xd4, 0x2a, 0x12, + 0xdf, 0xd4, 0x14, 0x89, 0xa1, 0xfb, 0x5a, 0xd8, 0xb0, 0x81, 0xb4, 0x88, 0x3f, 0x9d, 0x81, 0xe9, + 0x88, 0x84, 0x1f, 0xd6, 0x2b, 0x30, 0xc4, 0x7e, 0x88, 0xeb, 0xf5, 0xe5, 0x04, 0x63, 0x9e, 0xca, + 0x32, 0xfc, 0x4b, 0xa8, 0xf6, 0xf4, 0x3c, 0x71, 0xc8, 0x61, 0xe1, 0xb3, 0x30, 0x16, 0xb1, 0x3d, + 0x4b, 0x0a, 0xcb, 0x5f, 0xcf, 0x40, 0x21, 0xde, 0x12, 0x72, 0x1f, 0x46, 0x19, 0x27, 0x87, 0xca, + 0x9b, 0xff, 0x4b, 0x3d, 0xda, 0x7c, 0x5d, 0xa0, 0xf1, 0xcf, 0xc3, 0xce, 0xa7, 0x1c, 0x62, 0x4a, + 0x0e, 0x0b, 0x26, 0x4c, 0xa8, 0x58, 0x29, 0x5f, 0xf7, 0x9a, 0x2e, 0xa1, 0x9c, 0x4f, 0xef, 0x07, + 0x2d, 0xf1, 0xa6, 0xf6, 0xd5, 0x42, 0xf8, 0xb8, 0xa2, 0x4d, 0xae, 0xd4, 0x55, 0x85, 0x93, 0x66, + 0x31, 0xca, 0x89, 0xa0, 0xce, 0xb3, 0x94, 0x09, 0x1d, 0xe2, 0x91, 0xd7, 0x60, 0x84, 0xd7, 0xa7, + 0x26, 0x8d, 0xeb, 0x20, 0x44, 0x95, 0xc4, 0x39, 0x8e, 0xf1, 0xf7, 0x72, 0x70, 0x3e, 0xfa, 0xbc, + 0xad, 0x4e, 0xc3, 0x0e, 0xe8, 0x86, 0xed, 0xd9, 0x2d, 0xff, 0x94, 0x15, 0x70, 0x35, 0xf1, 0x69, + 0x98, 0xae, 0x4b, 0x7e, 0x9a, 0xf2, 0x41, 0x46, 0xec, 0x83, 0x50, 0xcb, 0xca, 0x3f, 0x48, 0x7e, + 0x06, 0xb9, 0x0f, 0xb9, 0x1a, 0x0d, 0xc4, 0xde, 0x7b, 0x25, 0xd1, 0xab, 0xea, 0x77, 0x5d, 0xaf, + 0xd1, 0x80, 0x0f, 0x22, 0x8f, 0x3d, 0xa5, 0x05, 0x00, 0x64, 0x5c, 0xc8, 0x36, 0x8c, 0x2c, 0x3f, + 0xee, 0xd0, 0x7a, 0x20, 0x12, 0xb0, 0x5e, 0xeb, 0xcf, 0x8f, 0xe3, 0x2a, 0xf9, 0x57, 0x29, 0x02, + 0xd4, 0xce, 0xe2, 0x28, 0x0b, 0xb7, 0x21, 0x2f, 0x2b, 0x3f, 0xcb, 0xcc, 0x5d, 0x78, 0x13, 0xc6, + 0x95, 0x4a, 0xce, 0x34, 0xe9, 0x7f, 0x81, 0xed, 0xab, 0x6e, 0x53, 0xe6, 0x6c, 0x5d, 0x4e, 0xc8, + 0x8a, 0x4a, 0xc6, 0x2b, 0x2e, 0x2b, 0x5a, 0x07, 0xa2, 0xa8, 0x8f, 0xd0, 0x58, 0x85, 0xe9, 0xda, + 0x81, 0xd3, 0x89, 0x82, 0xd1, 0x6a, 0x27, 0x32, 0x66, 0xd5, 0x11, 0xaa, 0x81, 0xf8, 0x89, 0x1c, + 0xa7, 0x33, 0xfe, 0x22, 0x03, 0x23, 0xec, 0xaf, 0x87, 0xb7, 0x9f, 0xd2, 0x2d, 0xf3, 0x96, 0xb6, + 0x65, 0xce, 0x28, 0xf1, 0xe0, 0x71, 0xe3, 0xb8, 0x7d, 0xca, 0x66, 0x79, 0x2c, 0x06, 0x88, 0x23, + 0x93, 0xbb, 0x30, 0x2a, 0x8c, 0x96, 0x84, 0x7d, 0xb9, 0x1a, 0x60, 0x5e, 0x9a, 0x33, 0x85, 0x3a, + 0x04, 0xb7, 0x13, 0x57, 0xba, 0x48, 0x6a, 0x26, 0xd7, 0xcb, 0xb0, 0xc0, 0x5a, 0xa6, 0x6f, 0x17, + 0x1d, 0x02, 0x79, 0x78, 0x74, 0x25, 0x37, 0x7f, 0x0f, 0xff, 0xfd, 0x92, 0x78, 0x6f, 0xc9, 0xf5, + 0x63, 0x72, 0x5e, 0x26, 0x42, 0x4e, 0x7d, 0x8a, 0x69, 0xc1, 0xf9, 0x5a, 0x6d, 0x05, 0x0d, 0x1c, + 0x37, 0x5c, 0x2f, 0xb8, 0xe3, 0x7a, 0x87, 0x36, 0xda, 0x2f, 0xa3, 0x0e, 0x51, 0xb1, 0x72, 0x48, + 0x33, 0x3b, 0x7b, 0x25, 0xd5, 0xec, 0xac, 0x8f, 0x25, 0x84, 0xd1, 0x86, 0x0b, 0xb5, 0xda, 0x0a, + 0x0f, 0x4e, 0xfe, 0x97, 0x51, 0xdf, 0xaf, 0x67, 0x60, 0xa6, 0x56, 0x5b, 0x89, 0x55, 0xb5, 0x2a, + 0xa3, 0xa2, 0x67, 0xb4, 0xa7, 0xd6, 0xf4, 0x8e, 0xc0, 0x51, 0xc8, 0x70, 0x09, 0xaf, 0xae, 0x05, + 0xc0, 0xe4, 0x4c, 0xc8, 0x46, 0x18, 0x87, 0x3d, 0xab, 0xf9, 0x1c, 0xf4, 0x68, 0x28, 0xea, 0xd0, + 0x85, 0xc7, 0x1e, 0x2b, 0xd5, 0x75, 0xe8, 0x0c, 0x62, 0xfc, 0xd7, 0xe7, 0x79, 0xa4, 0x77, 0x39, + 0x5b, 0xde, 0x81, 0x09, 0x41, 0x8f, 0x86, 0xf9, 0xc2, 0xea, 0xe4, 0x22, 0xdb, 0x20, 0x77, 0x39, + 0x9c, 0x47, 0x00, 0xfe, 0xf6, 0x71, 0x71, 0x88, 0x75, 0x8d, 0xa9, 0xa1, 0x93, 0x75, 0x98, 0x7c, + 0x60, 0x3f, 0x56, 0x14, 0x26, 0xdc, 0xed, 0xea, 0x1a, 0xdb, 0x55, 0x5a, 0xf6, 0xe3, 0x01, 0xcc, + 0xfa, 0x74, 0x7a, 0x72, 0x00, 0x53, 0x7a, 0x9b, 0xc4, 0x0c, 0x4c, 0x8e, 0xd8, 0xcd, 0xd4, 0x11, + 0xbb, 0xd8, 0x71, 0xbd, 0xc0, 0xda, 0x0d, 0xc9, 0xb5, 0xac, 0x06, 0x31, 0xd6, 0xe4, 0x1d, 0x98, + 0x51, 0xc2, 0x8c, 0xde, 0x71, 0xbd, 0x96, 0x2d, 0x2f, 0x5c, 0xf8, 0x8a, 0x80, 0xd6, 0x4a, 0xbb, + 0x08, 0x36, 0x93, 0x98, 0xe4, 0x4b, 0x69, 0xae, 0x6c, 0xc3, 0x91, 0x6d, 0x63, 0x8a, 0x2b, 0x5b, + 0x2f, 0xdb, 0xc6, 0xa4, 0x53, 0xdb, 0x5e, 0x3f, 0xdb, 0xe7, 0x3c, 0x6f, 0xfd, 0x40, 0xb6, 0xcd, + 0xe1, 0xc8, 0xf5, 0xb0, 0x71, 0x5e, 0x84, 0xdc, 0xd2, 0xc6, 0x1d, 0x7c, 0xfb, 0x92, 0x66, 0x5a, + 0xed, 0x7d, 0xbb, 0x5d, 0xc7, 0x8b, 0x90, 0xf0, 0x38, 0x50, 0x0f, 0xca, 0xa5, 0x8d, 0x3b, 0xc4, + 0x86, 0x59, 0xcc, 0x25, 0x17, 0x7c, 0xf1, 0xe6, 0x4d, 0x65, 0xa8, 0xf2, 0xf8, 0x69, 0x37, 0xc4, + 0xa7, 0x15, 0x31, 0x13, 0x5d, 0x60, 0x3d, 0xbe, 0x79, 0x33, 0x75, 0x40, 0xc2, 0x0f, 0x4b, 0xe3, + 0xc5, 0x0e, 0xac, 0x07, 0xf6, 0xe3, 0xc8, 0x51, 0xc4, 0x17, 0x4e, 0xc1, 0xcf, 0xcb, 0xa9, 0x15, + 0x39, 0x99, 0x68, 0x07, 0x96, 0x4e, 0xc4, 0xee, 0xb1, 0xd1, 0x04, 0xf3, 0x85, 0x3b, 0xd5, 0x82, + 0x54, 0x08, 0x4a, 0xcf, 0x71, 0xf5, 0x32, 0xa6, 0xa0, 0x93, 0xad, 0xf0, 0x36, 0xce, 0x6f, 0xb3, + 0x22, 0xfb, 0xf2, 0x0d, 0xf5, 0x36, 0xce, 0xd5, 0x70, 0x5a, 0xb3, 0xa6, 0x43, 0x15, 0x0e, 0xf7, + 0x9c, 0x31, 0x75, 0x2e, 0xc9, 0x4b, 0xfe, 0xc4, 0xd9, 0x2f, 0xf9, 0x14, 0x86, 0x56, 0xdd, 0xfa, + 0x81, 0x08, 0x00, 0xf8, 0x3e, 0xdb, 0x85, 0x9b, 0x6e, 0xfd, 0xe0, 0xc9, 0xd9, 0x74, 0x23, 0x7b, + 0xb2, 0xc6, 0x3e, 0x95, 0xcd, 0x02, 0xd1, 0x27, 0xc2, 0x4e, 0x78, 0x2e, 0xbc, 0xe5, 0x2a, 0x65, + 0x5c, 0x1e, 0xe5, 0x93, 0x46, 0x76, 0xad, 0xa9, 0x93, 0x13, 0x0a, 0x85, 0x0a, 0xf5, 0x0f, 0x02, + 0xb7, 0x53, 0x6e, 0x3a, 0x9d, 0x1d, 0xd7, 0xf6, 0x64, 0xb8, 0xe8, 0x81, 0xf7, 0xe4, 0x06, 0xa7, + 0xb7, 0xea, 0x92, 0x81, 0x99, 0x60, 0x49, 0xbe, 0x04, 0x53, 0x6c, 0x72, 0x2f, 0x3f, 0x0e, 0x68, + 0x9b, 0x8f, 0xfc, 0x0c, 0x4a, 0x74, 0x73, 0x4a, 0x7e, 0x94, 0xb0, 0x90, 0xcf, 0x29, 0x5c, 0xec, + 0x34, 0x24, 0xd0, 0x82, 0x27, 0x6a, 0xac, 0x48, 0x03, 0xe6, 0x1f, 0xd8, 0x8f, 0x95, 0x3c, 0xcf, + 0xca, 0x24, 0x25, 0x38, 0xc1, 0xae, 0x9e, 0x1c, 0x17, 0x5f, 0x62, 0x13, 0x2c, 0x8a, 0x60, 0xde, + 0x63, 0xbe, 0xf6, 0xe4, 0x44, 0xbe, 0x01, 0x17, 0x44, 0xb3, 0x2a, 0x98, 0x9b, 0xcc, 0xf5, 0x8e, + 0x6a, 0xfb, 0x36, 0xfa, 0x88, 0xcd, 0xf6, 0xe8, 0xb0, 0x1b, 0xe9, 0x5b, 0xa2, 0xec, 0xb0, 0x86, + 0xe4, 0x63, 0xf9, 0x9c, 0x91, 0xd9, 0xab, 0x06, 0xf2, 0x21, 0x4c, 0xf1, 0x07, 0xbf, 0x15, 0xd7, + 0x0f, 0x50, 0x59, 0x33, 0x77, 0x36, 0xc7, 0x07, 0xfe, 0x8a, 0xc8, 0x9d, 0x85, 0x62, 0xca, 0x9d, + 0x18, 0x67, 0xf2, 0x16, 0x8c, 0x6f, 0x38, 0x6d, 0x1e, 0xde, 0xb4, 0xba, 0x81, 0x8a, 0x6b, 0x71, + 0x02, 0x75, 0x9c, 0xb6, 0x25, 0x35, 0x26, 0x9d, 0x70, 0xbb, 0x50, 0xb1, 0xc9, 0x36, 0x8c, 0xd7, + 0x6a, 0x2b, 0x77, 0x1c, 0x26, 0x97, 0x74, 0xa4, 0x1e, 0x3a, 0xf9, 0x95, 0x2f, 0xa6, 0x7e, 0xe5, + 0xa4, 0xef, 0xef, 0x5b, 0xbb, 0x4e, 0x93, 0x5a, 0x75, 0xb7, 0x73, 0x64, 0xaa, 0x9c, 0x52, 0x9c, + 0x01, 0x2e, 0x3c, 0x61, 0x67, 0x80, 0x2a, 0x4c, 0x2b, 0xe6, 0xb9, 0x68, 0x9a, 0x3b, 0x1f, 0xc5, + 0xc4, 0x52, 0x8d, 0xff, 0xe3, 0xee, 0xaf, 0x71, 0x3a, 0xe9, 0x05, 0x70, 0xf1, 0xac, 0x5e, 0x00, + 0x0e, 0xcc, 0xf0, 0xc1, 0x10, 0xf3, 0x00, 0x47, 0x7a, 0xa1, 0x47, 0x1f, 0x5e, 0x4b, 0xed, 0xc3, + 0x59, 0x31, 0xd2, 0x72, 0x92, 0xe1, 0x03, 0x77, 0x92, 0x2b, 0xd9, 0x05, 0x22, 0x80, 0x76, 0x60, + 0xef, 0xd8, 0x3e, 0xc5, 0xba, 0x9e, 0xed, 0x51, 0xd7, 0x4b, 0xa9, 0x75, 0x4d, 0xc9, 0xba, 0x76, + 0x78, 0x35, 0x29, 0x1c, 0x49, 0x5b, 0xd6, 0x23, 0xe7, 0x17, 0x76, 0xec, 0x73, 0x9a, 0x8e, 0x3b, + 0x89, 0xc0, 0xc3, 0x4b, 0xc5, 0x27, 0x6d, 0xbc, 0xdf, 0x53, 0x38, 0x93, 0xc7, 0x70, 0x3e, 0xf9, + 0x15, 0x58, 0xe7, 0xf3, 0x58, 0xe7, 0xf3, 0x5a, 0x9d, 0x71, 0x24, 0x3e, 0x6f, 0xf4, 0x66, 0xc5, + 0x6b, 0xed, 0xc1, 0x9f, 0xfc, 0x60, 0x06, 0x2e, 0x3c, 0xb8, 0x53, 0xc2, 0x8c, 0xa5, 0x0e, 0x8f, + 0x76, 0x17, 0xba, 0x0d, 0x5f, 0x12, 0xef, 0x20, 0xf1, 0xf7, 0x18, 0x29, 0x71, 0xe0, 0x56, 0xc1, + 0x44, 0xf7, 0x17, 0x5b, 0xbb, 0x36, 0x4f, 0x84, 0x2a, 0x58, 0xa4, 0xf8, 0x16, 0xff, 0xdc, 0x1f, + 0x17, 0x33, 0x66, 0xaf, 0xaa, 0x48, 0x13, 0x16, 0xf4, 0x6e, 0x91, 0x7e, 0x1a, 0xfb, 0xb4, 0xd9, + 0x9c, 0x2f, 0xe2, 0x8c, 0x7e, 0xed, 0xe4, 0xb8, 0x78, 0x35, 0xd1, 0xbb, 0xa1, 0xef, 0x07, 0xc3, + 0x54, 0x1a, 0xdc, 0x87, 0x1f, 0x69, 0xa5, 0x08, 0xdd, 0xf3, 0x97, 0xb5, 0xf8, 0x42, 0x89, 0xf2, + 0xa5, 0x97, 0x85, 0x44, 0xf2, 0x3c, 0x5b, 0xef, 0x3d, 0x05, 0x44, 0x33, 0xc9, 0xf9, 0xde, 0x50, + 0x7e, 0xb2, 0x30, 0x95, 0xe2, 0x14, 0x61, 0xfc, 0x76, 0x36, 0x76, 0x30, 0x92, 0x2a, 0x8c, 0x8a, + 0xf9, 0xde, 0xf3, 0x92, 0xf1, 0x7c, 0xea, 0xac, 0x1e, 0x15, 0x4b, 0xc7, 0x94, 0xf4, 0xe4, 0x90, + 0xb1, 0xc2, 0x46, 0x8b, 0x1b, 0xef, 0x57, 0xf8, 0xb9, 0x87, 0x20, 0xed, 0x84, 0xaf, 0x9c, 0xdd, + 0xd9, 0x4f, 0xf7, 0x25, 0xc5, 0xa3, 0x5e, 0xd6, 0x46, 0x0e, 0x78, 0xba, 0xaa, 0x5c, 0xe8, 0x2f, + 0xa6, 0xe7, 0xa6, 0x7a, 0x62, 0x15, 0xb2, 0x5a, 0x8c, 0xdf, 0xca, 0xc0, 0xa4, 0x76, 0xb2, 0x92, + 0xdb, 0x8a, 0x3b, 0x64, 0x14, 0x21, 0x40, 0xc3, 0xc1, 0xcd, 0x36, 0xee, 0x28, 0x79, 0x5b, 0x78, + 0x36, 0x64, 0x7b, 0xd3, 0xe1, 0x62, 0x8b, 0x7b, 0xc7, 0xf6, 0xd7, 0x0f, 0x87, 0xb9, 0x36, 0x87, + 0x7a, 0xe4, 0xda, 0xfc, 0x87, 0x45, 0x98, 0xd2, 0x6f, 0xc4, 0xe4, 0x35, 0x18, 0x41, 0xdd, 0xbc, + 0x54, 0xaf, 0xa0, 0x5a, 0x08, 0xd5, 0xf7, 0x9a, 0xbb, 0x0b, 0xc7, 0x21, 0x2f, 0x03, 0x84, 0x26, + 0xe6, 0xf2, 0x65, 0x6a, 0xf8, 0xe4, 0xb8, 0x98, 0x79, 0xdd, 0x54, 0x0a, 0xc8, 0x57, 0x01, 0xd6, + 0xdc, 0x06, 0x0d, 0x13, 0x28, 0xf7, 0xb1, 0xef, 0x78, 0x25, 0x91, 0xca, 0xe5, 0x5c, 0xdb, 0x6d, + 0xd0, 0x64, 0xde, 0x16, 0x85, 0x23, 0xf9, 0x3c, 0x0c, 0x9b, 0xdd, 0x26, 0x95, 0x2f, 0x18, 0xe3, + 0xf2, 0x84, 0xeb, 0x36, 0x69, 0xa4, 0x27, 0xf0, 0xba, 0x71, 0xd3, 0x45, 0x06, 0x20, 0xef, 0xf1, + 0x14, 0x2f, 0x22, 0x0e, 0xe9, 0x70, 0xf4, 0x56, 0xa7, 0x48, 0x3e, 0x89, 0x48, 0xa4, 0x0a, 0x09, + 0x59, 0x87, 0x51, 0xf5, 0x91, 0x49, 0xf1, 0xab, 0x57, 0x1f, 0x22, 0x15, 0xa5, 0x83, 0xc8, 0xbc, + 0x1c, 0x7f, 0x7f, 0x92, 0x5c, 0xc8, 0xdb, 0x30, 0xc6, 0xd8, 0xb3, 0x9d, 0xc3, 0x17, 0xb7, 0x1a, + 0x7c, 0x91, 0x53, 0x3e, 0x88, 0xed, 0x3e, 0x5a, 0xb4, 0xd0, 0x90, 0x80, 0x7c, 0x09, 0x73, 0xe5, + 0x8a, 0xae, 0xee, 0x6b, 0xf7, 0x73, 0x25, 0xd1, 0xd5, 0x98, 0x3c, 0x37, 0xd1, 0xd3, 0x11, 0x3f, + 0xb2, 0x17, 0x86, 0x75, 0x1b, 0x24, 0x2d, 0xcf, 0xab, 0x89, 0x0a, 0xe6, 0x65, 0xa4, 0xb2, 0x64, + 0x22, 0x6c, 0x8d, 0x2f, 0xe9, 0x40, 0x21, 0x12, 0x2a, 0x45, 0x5d, 0xd0, 0xaf, 0xae, 0xd7, 0x13, + 0x75, 0xa9, 0x03, 0x98, 0xa8, 0x2e, 0xc1, 0x9d, 0x34, 0x60, 0x4a, 0x1e, 0x50, 0xa2, 0xbe, 0xf1, + 0x7e, 0xf5, 0xbd, 0x9c, 0xa8, 0x6f, 0xb6, 0xb1, 0x93, 0xac, 0x27, 0xc6, 0x93, 0xbc, 0x0d, 0x93, + 0x12, 0xc2, 0xd3, 0x52, 0x4f, 0x44, 0x79, 0x7d, 0x1b, 0x3b, 0x89, 0x64, 0xd4, 0x3a, 0xb2, 0x4a, + 0xcd, 0x67, 0xc7, 0xa4, 0x46, 0x1d, 0x9f, 0x15, 0x3a, 0x32, 0xf9, 0x00, 0xc6, 0xab, 0x2d, 0xd6, + 0x10, 0xb7, 0x6d, 0x07, 0x54, 0x78, 0x5c, 0x4a, 0x1b, 0x26, 0xa5, 0x44, 0x99, 0xaa, 0x3c, 0xe1, + 0x76, 0x54, 0xa4, 0x25, 0xdc, 0x8e, 0xc0, 0xac, 0xf3, 0xf8, 0xab, 0xa2, 0x98, 0xc3, 0xd2, 0x1b, + 0xf3, 0xf9, 0x14, 0x3b, 0x22, 0x85, 0xbd, 0x88, 0x39, 0xc9, 0xa0, 0xf2, 0x55, 0x2f, 0x16, 0xef, + 0x57, 0xe5, 0x49, 0xde, 0x81, 0x71, 0x91, 0xb1, 0xac, 0x64, 0xae, 0xf9, 0xf3, 0x05, 0x6c, 0x3c, + 0x46, 0x91, 0x90, 0xc9, 0xcd, 0x2c, 0xdb, 0x8b, 0x19, 0xcc, 0x46, 0xf8, 0xe4, 0x8b, 0x30, 0xb7, + 0xed, 0xb4, 0x1b, 0xee, 0xa1, 0x2f, 0x8e, 0x29, 0xb1, 0xd1, 0xcd, 0x44, 0xee, 0x6a, 0x87, 0xbc, + 0x3c, 0x94, 0x05, 0x13, 0x1b, 0x5f, 0x2a, 0x07, 0xf2, 0x3d, 0x09, 0xce, 0x7c, 0x06, 0x91, 0x7e, + 0x33, 0x68, 0x31, 0x31, 0x83, 0x92, 0xd5, 0xc7, 0xa7, 0x53, 0x6a, 0x35, 0xc4, 0x05, 0xa2, 0x9f, + 0xef, 0xf7, 0x5c, 0xa7, 0x3d, 0x3f, 0x8b, 0x7b, 0xe1, 0xb3, 0xf1, 0xb8, 0x0d, 0x88, 0x27, 0x12, + 0x97, 0x1b, 0x27, 0xc7, 0xc5, 0x4b, 0x71, 0x99, 0xff, 0x43, 0x57, 0x7b, 0x2e, 0x49, 0x61, 0x4d, + 0x3e, 0x80, 0x09, 0xf6, 0x7f, 0xa8, 0x94, 0x98, 0xd3, 0x2c, 0x4f, 0x15, 0x4c, 0x51, 0x0f, 0x8e, + 0x11, 0xa6, 0x54, 0x4b, 0xd1, 0x57, 0x68, 0xac, 0xc8, 0x9b, 0x00, 0x4c, 0x6c, 0x12, 0xdb, 0xf1, + 0xb9, 0x28, 0xbc, 0x32, 0x4a, 0x5d, 0xc9, 0x8d, 0x38, 0x42, 0x26, 0x6f, 0xc3, 0x38, 0xfb, 0x55, + 0xeb, 0x36, 0x5c, 0xb6, 0x36, 0xce, 0x23, 0x2d, 0x77, 0x7e, 0x65, 0xb4, 0x3e, 0x87, 0x6b, 0xce, + 0xaf, 0x11, 0x3a, 0x59, 0x81, 0x69, 0x0c, 0x83, 0x2d, 0x02, 0xb0, 0x3a, 0xd4, 0x9f, 0xbf, 0xa0, + 0x58, 0x43, 0xb0, 0x22, 0xcb, 0x09, 0xcb, 0xd4, 0xbb, 0x4c, 0x8c, 0x8c, 0xf8, 0x30, 0x9b, 0x7c, + 0x4e, 0xf6, 0xe7, 0xe7, 0xb1, 0x93, 0xa4, 0x04, 0x9f, 0xc4, 0xe0, 0xfb, 0x31, 0x1b, 0x11, 0x65, + 0xe3, 0x92, 0x8f, 0x4a, 0x6a, 0x85, 0x69, 0xdc, 0x89, 0x09, 0xe4, 0x6e, 0x79, 0x23, 0x1e, 0x27, + 0xfa, 0x22, 0xb6, 0x00, 0x87, 0x79, 0xaf, 0x1e, 0x65, 0x2a, 0x4f, 0x89, 0x15, 0x9d, 0x42, 0x4d, + 0xbe, 0x1b, 0xce, 0xc9, 0x1d, 0x44, 0x14, 0x89, 0x79, 0xbd, 0x70, 0xc6, 0x9d, 0xb8, 0xb1, 0x13, + 0x56, 0x9d, 0x98, 0xd2, 0xe9, 0x55, 0x10, 0x1b, 0xc6, 0x71, 0x58, 0x45, 0x8d, 0xcf, 0xf6, 0xab, + 0xf1, 0x6a, 0xa2, 0xc6, 0xf3, 0x38, 0x51, 0x92, 0x95, 0xa9, 0x3c, 0xc9, 0x12, 0x4c, 0x8a, 0x75, + 0x24, 0x66, 0xdb, 0x73, 0xd8, 0x5b, 0xa8, 0xc4, 0x92, 0x2b, 0x30, 0x31, 0xe1, 0x74, 0x12, 0x75, + 0x47, 0xe6, 0x8f, 0x49, 0xcf, 0x6b, 0x3b, 0x72, 0xfc, 0x0d, 0x49, 0x47, 0x66, 0x3b, 0x52, 0x24, + 0xc5, 0x2c, 0x3f, 0xee, 0x78, 0x42, 0x45, 0x75, 0x29, 0xca, 0xbc, 0xa4, 0x08, 0x3f, 0x16, 0x0d, + 0x31, 0xd4, 0x2d, 0x21, 0x8d, 0x03, 0xd9, 0x82, 0xd9, 0xf0, 0xd4, 0x56, 0x18, 0x17, 0xa3, 0x48, + 0xc4, 0xd1, 0x51, 0x9f, 0xce, 0x37, 0x8d, 0x9e, 0xd8, 0x70, 0x41, 0x3b, 0xa7, 0x15, 0xd6, 0x97, + 0x91, 0x35, 0x66, 0xc6, 0xd7, 0x0f, 0xf9, 0x74, 0xf6, 0xbd, 0xf8, 0x90, 0x0f, 0x61, 0x21, 0x7e, + 0x36, 0x2b, 0xb5, 0xbc, 0x80, 0xb5, 0xbc, 0x7a, 0x72, 0x5c, 0xbc, 0x92, 0x38, 0xde, 0xd3, 0x2b, + 0xea, 0xc3, 0x8d, 0x7c, 0x15, 0xe6, 0xf5, 0xf3, 0x59, 0xa9, 0xc9, 0xc0, 0x9a, 0x70, 0xe9, 0x84, + 0x07, 0x7b, 0x7a, 0x0d, 0x3d, 0x79, 0x90, 0x00, 0x8a, 0xa9, 0xb3, 0x5b, 0xa9, 0xe6, 0xc5, 0xa8, + 0x41, 0x89, 0x55, 0x92, 0x5e, 0xdd, 0x69, 0x2c, 0xc9, 0x21, 0x5c, 0x4a, 0x3b, 0x26, 0x94, 0x4a, + 0x5f, 0x0a, 0x95, 0xc0, 0x9f, 0x4a, 0x3f, 0x72, 0xd2, 0x6b, 0x3e, 0x85, 0x2d, 0xf9, 0x12, 0x9c, + 0x53, 0xd6, 0x97, 0x52, 0xdf, 0xcb, 0x58, 0x1f, 0x3a, 0x9b, 0xab, 0x0b, 0x33, 0xbd, 0x96, 0x74, + 0x1e, 0xa4, 0x05, 0xb3, 0xb2, 0xe1, 0xa8, 0x6d, 0x17, 0x47, 0xcf, 0x15, 0x6d, 0x57, 0x4d, 0x62, + 0x2c, 0x5d, 0x16, 0xbb, 0xea, 0x7c, 0x63, 0xc7, 0xea, 0x44, 0x84, 0xea, 0x4c, 0x4f, 0xe1, 0x4b, + 0x56, 0x60, 0xa4, 0xb6, 0x51, 0xbd, 0x73, 0x67, 0x79, 0xfe, 0x15, 0xac, 0x41, 0x7a, 0xa6, 0x71, + 0xa0, 0x76, 0x69, 0x12, 0xe6, 0x8a, 0x1d, 0x67, 0x77, 0x57, 0x7b, 0xb0, 0xe2, 0xa8, 0xe4, 0x7b, + 0xd0, 0x50, 0x90, 0xed, 0xa8, 0x25, 0xdf, 0x77, 0xf6, 0x30, 0xb2, 0xb5, 0x3f, 0xff, 0xaa, 0xf6, + 0xde, 0x2f, 0xa3, 0x7e, 0x97, 0x31, 0x29, 0x5a, 0x02, 0x9d, 0x4b, 0x9b, 0xec, 0xfe, 0x2f, 0x76, + 0x6e, 0xcb, 0x8e, 0x58, 0xa9, 0x9b, 0x78, 0xb2, 0x22, 0xd6, 0x6f, 0x7b, 0x4e, 0x60, 0xed, 0x77, + 0xb5, 0xe6, 0xcf, 0x7f, 0x4a, 0x8b, 0xf2, 0xcc, 0x53, 0xc5, 0x29, 0xbd, 0xf6, 0x92, 0xa8, 0xf0, + 0x39, 0x7e, 0x5b, 0xee, 0xd1, 0x73, 0x33, 0x7b, 0x31, 0x3a, 0x9f, 0xfc, 0x40, 0x06, 0xce, 0x6f, + 0xbb, 0xde, 0x41, 0xd3, 0xb5, 0x1b, 0xb2, 0x55, 0x62, 0x0f, 0x7f, 0xad, 0xdf, 0x1e, 0xfe, 0x99, + 0xc4, 0x1e, 0x6e, 0x1c, 0x0a, 0x36, 0x56, 0x18, 0x34, 0x3d, 0xb1, 0x9f, 0xf7, 0xa8, 0x8a, 0x7c, + 0x0f, 0x5c, 0x4e, 0x2f, 0x51, 0x26, 0xe5, 0xeb, 0x38, 0x29, 0x6f, 0x9e, 0x1c, 0x17, 0x5f, 0xef, + 0x55, 0x53, 0xfa, 0x04, 0x3d, 0x95, 0xf5, 0xbd, 0xa1, 0xfc, 0xd5, 0xc2, 0xb5, 0x7b, 0x43, 0xf9, + 0x6b, 0x85, 0x57, 0xcd, 0xe7, 0x6a, 0xa5, 0x07, 0xab, 0xd5, 0x86, 0x3c, 0x5c, 0x65, 0x5c, 0x77, + 0x4e, 0x63, 0x5e, 0xe9, 0x57, 0x1a, 0x71, 0x34, 0xfe, 0x4e, 0x06, 0x8a, 0xa7, 0x4c, 0x12, 0x76, + 0x9e, 0x45, 0x23, 0x51, 0xa3, 0x81, 0x1a, 0x1d, 0x3e, 0x1a, 0x3f, 0x4b, 0x37, 0x1b, 0xd1, 0x49, + 0xd0, 0xad, 0x51, 0xa4, 0x24, 0x51, 0xbc, 0x5b, 0x93, 0xa9, 0x48, 0x24, 0x96, 0xb1, 0x0a, 0x85, + 0xf8, 0xe4, 0x21, 0x9f, 0x83, 0x49, 0x35, 0x21, 0x82, 0x54, 0x25, 0xf0, 0x50, 0x26, 0xde, 0x9e, + 0x76, 0x20, 0x6a, 0x88, 0xc6, 0x2f, 0x64, 0x60, 0x36, 0x65, 0x85, 0x91, 0x2b, 0x30, 0x84, 0x19, + 0xcb, 0x14, 0xab, 0xa1, 0x58, 0xa6, 0x32, 0x2c, 0x27, 0x9f, 0x86, 0xd1, 0xca, 0x5a, 0xad, 0x56, + 0x5a, 0x93, 0xca, 0x08, 0x7e, 0x10, 0xb7, 0x7d, 0xcb, 0xb7, 0x75, 0x63, 0x03, 0x81, 0x46, 0x5e, + 0x87, 0x91, 0xea, 0x06, 0x12, 0x70, 0xdb, 0x57, 0x6c, 0xaf, 0xd3, 0x89, 0xe3, 0x0b, 0x24, 0xe3, + 0x47, 0x33, 0x40, 0x92, 0xdb, 0x05, 0xb9, 0x09, 0xe3, 0xea, 0xa6, 0xc4, 0xdb, 0x8b, 0x2f, 0xb0, + 0xca, 0xc2, 0x31, 0x55, 0x1c, 0x52, 0x81, 0x61, 0xcc, 0x35, 0x1b, 0x5a, 0x39, 0xa4, 0x2e, 0x8b, + 0x0b, 0x89, 0x65, 0x31, 0x8c, 0x99, 0x6c, 0x4d, 0x4e, 0x6c, 0xfc, 0x5e, 0x06, 0x48, 0xba, 0xed, + 0xe2, 0x40, 0x56, 0x56, 0x6f, 0x28, 0xd1, 0x11, 0xd4, 0x9c, 0x44, 0x61, 0x42, 0x39, 0x55, 0x0d, + 0x10, 0xc5, 0x51, 0xb8, 0xa2, 0xa9, 0x9d, 0x7a, 0xbb, 0xd4, 0x5e, 0x83, 0xe1, 0x87, 0xd4, 0xdb, + 0x91, 0x66, 0xdd, 0x68, 0x0a, 0xfa, 0x88, 0x01, 0x54, 0x35, 0x0c, 0x62, 0x18, 0x7f, 0x9a, 0x81, + 0xb9, 0xb4, 0x3b, 0xca, 0x29, 0x9e, 0xaf, 0x46, 0xcc, 0x69, 0x17, 0x2d, 0xac, 0xb8, 0x9d, 0x68, + 0xe8, 0xaa, 0x5b, 0x84, 0x61, 0xd6, 0x58, 0x39, 0xc2, 0xa8, 0x06, 0x63, 0xbd, 0xe1, 0x9b, 0x1c, + 0xce, 0x10, 0x78, 0x1c, 0xc0, 0x21, 0x0c, 0x21, 0x89, 0x08, 0x38, 0xbb, 0x4d, 0x0e, 0x67, 0x08, + 0x0f, 0xdc, 0x06, 0x95, 0xea, 0x21, 0x44, 0x68, 0x31, 0x80, 0xc9, 0xe1, 0xe4, 0x0a, 0x8c, 0xae, + 0xb7, 0x57, 0xa9, 0xfd, 0x48, 0xe6, 0xc5, 0x40, 0x8b, 0x30, 0xb7, 0x6d, 0x35, 0x19, 0xcc, 0x94, + 0x85, 0xc6, 0x4f, 0x67, 0x60, 0x26, 0x71, 0x3d, 0x3a, 0xdd, 0xb9, 0xb7, 0xbf, 0x97, 0xdd, 0x20, + 0xed, 0xe3, 0x9f, 0x3f, 0x94, 0xfe, 0xf9, 0xc6, 0x7f, 0x3b, 0x02, 0x17, 0x7a, 0x68, 0xab, 0x22, + 0x2f, 0xe0, 0xcc, 0xa9, 0x5e, 0xc0, 0x5f, 0x86, 0xc9, 0x72, 0xd3, 0x76, 0x5a, 0xfe, 0xa6, 0x1b, + 0x7d, 0x71, 0xe4, 0x4c, 0x84, 0x65, 0xc2, 0x0f, 0x22, 0xf4, 0x3a, 0xb9, 0x58, 0x47, 0x0a, 0x2b, + 0x70, 0x93, 0xc2, 0xb2, 0xc6, 0x2c, 0xe1, 0x87, 0x9b, 0xfb, 0x2b, 0xe2, 0x87, 0xab, 0x7b, 0x86, + 0x0d, 0x3d, 0x51, 0xcf, 0xb0, 0x74, 0x9b, 0xef, 0xe1, 0x8f, 0xe3, 0x01, 0x50, 0x86, 0x49, 0x6e, + 0x12, 0x57, 0xf2, 0xf9, 0x20, 0x8d, 0x24, 0xcc, 0xe8, 0x6c, 0x3f, 0x39, 0x16, 0x1a, 0x0d, 0x59, + 0xd1, 0xbd, 0x98, 0x46, 0xf1, 0xcd, 0xf8, 0x4a, 0x6f, 0x2f, 0x25, 0xcd, 0x56, 0x44, 0xf3, 0x56, + 0xfa, 0x06, 0xcc, 0xa5, 0x5d, 0x77, 0xe7, 0xf3, 0x9a, 0xb5, 0x6d, 0x4f, 0x2b, 0xed, 0xc1, 0x2f, + 0xcd, 0x07, 0xa9, 0x97, 0x66, 0xe9, 0x5d, 0x3e, 0xa6, 0x85, 0x8d, 0xee, 0xb1, 0x16, 0x38, 0x6e, + 0x7f, 0x1f, 0x74, 0xe3, 0xcb, 0xf0, 0x7c, 0x5f, 0x72, 0xf2, 0x96, 0x16, 0xc5, 0xe8, 0x95, 0x64, + 0x14, 0xa3, 0x6f, 0x1f, 0x17, 0x67, 0x34, 0xcf, 0xd0, 0x07, 0xa1, 0xc2, 0xdf, 0xf8, 0xe9, 0xac, + 0xee, 0xd3, 0xfc, 0x57, 0x71, 0xa1, 0x5e, 0x83, 0xe1, 0xed, 0x7d, 0xea, 0xc9, 0xe3, 0x01, 0x3f, + 0xe4, 0x90, 0x01, 0xd4, 0x0f, 0x41, 0x0c, 0x72, 0x07, 0xa6, 0x36, 0xf8, 0xc4, 0x95, 0xb3, 0x71, + 0x28, 0xd2, 0xb9, 0x74, 0x84, 0x66, 0x30, 0x65, 0x3a, 0xc6, 0xa8, 0x8c, 0xbb, 0xb1, 0x4e, 0x17, + 0x31, 0x98, 0xb8, 0x67, 0x14, 0x17, 0x20, 0xa6, 0x22, 0x6f, 0xb3, 0x68, 0xb3, 0x35, 0x63, 0x50, + 0x63, 0x17, 0x2e, 0xf5, 0x65, 0xc4, 0xce, 0x6d, 0xe8, 0x84, 0xbf, 0x62, 0x96, 0xd7, 0x7d, 0x49, + 0x4d, 0x85, 0xce, 0xf8, 0x06, 0x4c, 0xa8, 0xbd, 0x8c, 0x47, 0x10, 0xfb, 0x2d, 0x66, 0x05, 0x3f, + 0x82, 0x18, 0xc0, 0xe4, 0xf0, 0xe8, 0x2d, 0x27, 0x9b, 0xfe, 0x96, 0x13, 0x0d, 0x7f, 0xee, 0xb4, + 0xe1, 0x67, 0x95, 0xe3, 0x0e, 0xa7, 0x54, 0x8e, 0xbf, 0xd5, 0xca, 0x31, 0xc8, 0x92, 0xc9, 0xe1, + 0x4f, 0xb4, 0xf2, 0xdf, 0x95, 0x89, 0xd4, 0xd0, 0xf1, 0x4a, 0x2e, 0xf7, 0x4c, 0x94, 0x0d, 0x2d, + 0x6d, 0xf5, 0x46, 0x98, 0x91, 0x4c, 0x91, 0x3d, 0x4d, 0xa6, 0x38, 0xcb, 0x44, 0x44, 0xb9, 0x97, + 0x0f, 0xe9, 0x50, 0x24, 0x07, 0xda, 0x09, 0x6b, 0x17, 0x89, 0x65, 0xfc, 0x5c, 0x06, 0xce, 0xa5, + 0xea, 0xcc, 0x59, 0xad, 0x5c, 0x39, 0xaf, 0xac, 0xc3, 0xb8, 0x66, 0x9e, 0x63, 0x9c, 0x25, 0xc2, + 0xc6, 0xe0, 0x6d, 0x31, 0x5e, 0x80, 0xb1, 0xf0, 0xc5, 0x96, 0xcc, 0xc9, 0xa1, 0x43, 0xbb, 0x48, + 0xf9, 0xf0, 0x57, 0x03, 0x60, 0x5f, 0xf0, 0x44, 0x4d, 0xab, 0x8d, 0xdf, 0xcd, 0xf2, 0x24, 0xbb, + 0x4f, 0x6d, 0xb8, 0xdc, 0x74, 0x7b, 0x68, 0xd6, 0xa4, 0xde, 0x41, 0x72, 0xc9, 0x32, 0x8c, 0xd4, + 0x02, 0x3b, 0xe8, 0xca, 0xc0, 0x20, 0xb3, 0x2a, 0x19, 0x16, 0x3c, 0x5c, 0x8c, 0x42, 0x43, 0xf8, + 0x08, 0xd1, 0xb4, 0x04, 0x08, 0x51, 0xcc, 0xaa, 0xff, 0x30, 0x03, 0x13, 0x2a, 0x31, 0xf9, 0x00, + 0xa6, 0x64, 0x08, 0x50, 0x1e, 0x2e, 0x45, 0x3c, 0x2f, 0x4b, 0x53, 0x30, 0x19, 0x02, 0x54, 0x0d, + 0xaf, 0xa2, 0xe1, 0xab, 0x5b, 0x75, 0x47, 0x45, 0x26, 0x0d, 0x20, 0xad, 0x5d, 0xdb, 0x3a, 0xa4, + 0xf6, 0x01, 0xf5, 0x03, 0x8b, 0x9b, 0xec, 0x88, 0x57, 0x68, 0xc9, 0xfe, 0xc1, 0x9d, 0x12, 0xb7, + 0xd6, 0x61, 0x23, 0x21, 0x62, 0xb9, 0x26, 0x68, 0xd4, 0xa7, 0xb5, 0xd6, 0xae, 0xbd, 0xcd, 0x0b, + 0x39, 0x9d, 0xf1, 0x67, 0x23, 0x7c, 0xba, 0x89, 0x98, 0xc1, 0x3b, 0x30, 0xb5, 0x5e, 0xad, 0x94, + 0x15, 0x45, 0xbb, 0x9e, 0x72, 0x6a, 0xf9, 0x71, 0x40, 0xbd, 0xb6, 0xdd, 0x94, 0xf7, 0xdd, 0xe8, + 0x08, 0x72, 0x9d, 0x46, 0x3d, 0x5d, 0x09, 0x1f, 0xe3, 0xc8, 0xea, 0xe0, 0x37, 0xeb, 0xb0, 0x8e, + 0xec, 0x80, 0x75, 0xf8, 0x76, 0xab, 0xd9, 0xa3, 0x0e, 0x9d, 0x23, 0xd9, 0xc7, 0xab, 0xef, 0x7e, + 0x77, 0x47, 0xa9, 0x25, 0xd7, 0xbf, 0x96, 0x17, 0x45, 0x2d, 0xcf, 0x0a, 0xb5, 0x4a, 0x6a, 0x3d, + 0x09, 0xae, 0xd1, 0x3e, 0x31, 0x74, 0xea, 0x3e, 0xf1, 0xb7, 0x32, 0x30, 0xc2, 0xc5, 0x57, 0x31, + 0x8d, 0x7b, 0x08, 0xc8, 0xdb, 0x4f, 0x46, 0x40, 0x2e, 0xe0, 0x39, 0xa1, 0x4d, 0x68, 0x5e, 0x46, + 0x2a, 0xb1, 0x75, 0x21, 0xbd, 0x01, 0xf0, 0xc9, 0x8c, 0x97, 0x9c, 0xbe, 0x2c, 0x48, 0x35, 0x0a, + 0xd6, 0x31, 0x7a, 0xaa, 0x87, 0xb6, 0x0c, 0x70, 0x32, 0x2a, 0x82, 0x75, 0xe8, 0x21, 0x3a, 0x56, + 0x61, 0x4c, 0x84, 0x00, 0x59, 0x3a, 0x12, 0x0f, 0xe3, 0x05, 0xcd, 0xb4, 0xa9, 0xb1, 0x74, 0x14, + 0x89, 0xe6, 0x22, 0x88, 0x88, 0xb5, 0x73, 0xa4, 0xe5, 0x2c, 0x96, 0x88, 0x64, 0x9d, 0xe7, 0xf2, + 0xe4, 0x31, 0x95, 0xf5, 0x34, 0x0a, 0x21, 0x5c, 0x04, 0x17, 0x93, 0x71, 0x04, 0x52, 0x42, 0x28, + 0x47, 0x3c, 0xc8, 0x2a, 0x14, 0xd0, 0x1c, 0x8e, 0x36, 0xf8, 0xaa, 0xa9, 0x56, 0x78, 0x98, 0x09, + 0x61, 0xd2, 0x1c, 0xf0, 0x32, 0xb1, 0xdc, 0x62, 0xfe, 0x97, 0x09, 0x4a, 0xe3, 0xa7, 0xb2, 0x50, + 0x88, 0xcf, 0x3e, 0xf2, 0x36, 0x8c, 0x87, 0x31, 0xad, 0x43, 0x0f, 0x70, 0x7c, 0x20, 0x8b, 0x82, + 0x60, 0xeb, 0x19, 0x20, 0x15, 0x74, 0xb2, 0x08, 0x79, 0xb6, 0x88, 0xe3, 0xd9, 0x92, 0xbb, 0x02, + 0xa6, 0x7a, 0x64, 0x49, 0x3c, 0x52, 0x83, 0x59, 0xb6, 0x68, 0x6a, 0x4e, 0x7b, 0xaf, 0x49, 0x57, + 0xdd, 0x3d, 0xb7, 0x1b, 0x44, 0x09, 0x11, 0xf9, 0x05, 0xc6, 0x6e, 0x35, 0xb5, 0x62, 0x3d, 0x1d, + 0x62, 0x0a, 0xb5, 0x92, 0xcb, 0x7d, 0x68, 0x80, 0x5c, 0xee, 0xca, 0xce, 0xfa, 0xc7, 0x59, 0x18, + 0x57, 0xa6, 0x1f, 0xb9, 0x06, 0xf9, 0xaa, 0xbf, 0xea, 0xd6, 0x0f, 0xc2, 0x60, 0x95, 0x93, 0x27, + 0xc7, 0xc5, 0x31, 0xc7, 0xb7, 0x9a, 0x08, 0x34, 0xc3, 0x62, 0xb2, 0x04, 0x93, 0xfc, 0x2f, 0x99, + 0x9c, 0x24, 0x1b, 0xe9, 0xd6, 0x38, 0xb2, 0x4c, 0x4b, 0xa2, 0x6e, 0xb6, 0x1a, 0x09, 0xf9, 0x0a, + 0x00, 0x07, 0x60, 0x78, 0x83, 0xdc, 0xe0, 0x81, 0x19, 0x44, 0x05, 0x29, 0x81, 0x0d, 0x14, 0x86, + 0xe4, 0x6b, 0x3c, 0x64, 0xb6, 0x5c, 0x2e, 0x43, 0x83, 0x47, 0x96, 0x60, 0xfc, 0xad, 0xf4, 0x00, + 0x37, 0x2a, 0x4b, 0x91, 0x4f, 0x68, 0xc1, 0xa4, 0x75, 0xf7, 0x11, 0xf5, 0x8e, 0x4a, 0x01, 0x22, + 0x2a, 0x18, 0xc6, 0xff, 0x94, 0x51, 0x16, 0x19, 0x59, 0xc3, 0x7c, 0xe0, 0x7c, 0x02, 0x09, 0x93, + 0xb2, 0xf0, 0x8a, 0x21, 0xe1, 0x26, 0xdd, 0x5d, 0x7a, 0x56, 0x58, 0xb7, 0xcd, 0x86, 0xd3, 0x30, + 0x96, 0x27, 0x9c, 0x03, 0xc9, 0x17, 0x60, 0x08, 0xbb, 0x2e, 0x7b, 0x6a, 0xd3, 0xe4, 0x29, 0x3f, + 0xc4, 0xfa, 0x0c, 0x1b, 0x82, 0x94, 0xe4, 0xd3, 0xc2, 0x71, 0x9b, 0x77, 0xfe, 0x94, 0x72, 0x54, + 0xb3, 0xef, 0x08, 0x8f, 0xf7, 0x28, 0xc6, 0x91, 0x32, 0x7b, 0xfe, 0x4e, 0x16, 0x0a, 0xf1, 0xa5, + 0x4d, 0xde, 0x83, 0x09, 0x79, 0xfc, 0xae, 0xd8, 0x22, 0xb3, 0xc6, 0x84, 0xc8, 0x6c, 0x21, 0xcf, + 0xe0, 0x7d, 0x5b, 0x35, 0x41, 0x33, 0x35, 0x02, 0x26, 0x0b, 0x6d, 0x8a, 0x98, 0x83, 0xca, 0xa2, + 0x0a, 0xdc, 0xa0, 0x13, 0x8b, 0xd4, 0x2c, 0xd1, 0xc8, 0x1b, 0x90, 0x7b, 0x70, 0xa7, 0x24, 0x1c, + 0xfc, 0x0a, 0xf1, 0x43, 0x9a, 0x5b, 0xca, 0xea, 0x76, 0xbb, 0x0c, 0x9f, 0xac, 0x2a, 0x41, 0xcd, + 0x47, 0x34, 0x73, 0x43, 0x09, 0x0e, 0x1b, 0x77, 0x7a, 0x74, 0xf3, 0x7b, 0x43, 0xf9, 0x5c, 0x61, + 0x48, 0x84, 0xe9, 0xfd, 0xe7, 0x39, 0x18, 0x0b, 0xeb, 0x27, 0x44, 0x75, 0x9b, 0xe6, 0x2e, 0xd2, + 0xe4, 0x22, 0xe4, 0xa5, 0x74, 0x27, 0xfc, 0xfc, 0x46, 0x7d, 0x21, 0xd9, 0xcd, 0x83, 0x14, 0xe3, + 0xf8, 0xae, 0x60, 0xca, 0x9f, 0xe4, 0x26, 0x84, 0x32, 0x5a, 0x2f, 0x61, 0x6e, 0x88, 0x0d, 0x98, + 0x19, 0xa2, 0x91, 0x29, 0xc8, 0x3a, 0x3c, 0xf4, 0xdb, 0x98, 0x99, 0x75, 0x1a, 0xe4, 0x3d, 0xc8, + 0xdb, 0x8d, 0x06, 0x6d, 0x58, 0xb6, 0xb4, 0xcd, 0xea, 0x37, 0x69, 0xf2, 0x8c, 0x1b, 0x3f, 0x33, + 0x90, 0xaa, 0x14, 0x90, 0x12, 0x8c, 0x35, 0x6d, 0x6e, 0xed, 0xd9, 0x18, 0xe0, 0x00, 0x8a, 0x38, + 0xe4, 0x19, 0xd9, 0x96, 0x4f, 0x1b, 0xe4, 0x15, 0x18, 0x62, 0xa3, 0x29, 0x4e, 0x1c, 0x29, 0x54, + 0xb2, 0xc1, 0xe4, 0x1d, 0xb6, 0xf2, 0x8c, 0x89, 0x08, 0xe4, 0x25, 0xc8, 0x75, 0x17, 0x77, 0xc5, + 0x59, 0x52, 0x88, 0x12, 0x0c, 0x84, 0x68, 0xac, 0x98, 0xdc, 0x82, 0xfc, 0xa1, 0x1e, 0x9b, 0xfe, + 0x5c, 0x6c, 0x18, 0x43, 0xfc, 0x10, 0x91, 0xbc, 0x02, 0x39, 0xdf, 0x77, 0x85, 0x41, 0xd3, 0x6c, + 0x68, 0x65, 0xba, 0x1e, 0x8e, 0x1a, 0xe3, 0xee, 0xfb, 0xee, 0x52, 0x1e, 0x46, 0xf8, 0x01, 0x63, + 0x5c, 0x02, 0x88, 0xbe, 0x31, 0xe9, 0xb7, 0x69, 0x7c, 0x05, 0xc6, 0xc2, 0x6f, 0x23, 0xcf, 0x03, + 0x1c, 0xd0, 0x23, 0x6b, 0xdf, 0x6e, 0x37, 0x9a, 0x5c, 0x3a, 0x9d, 0x30, 0xc7, 0x0e, 0xe8, 0xd1, + 0x0a, 0x02, 0xc8, 0x05, 0x18, 0xed, 0xb0, 0xe1, 0x17, 0x73, 0x7c, 0xc2, 0x1c, 0xe9, 0x74, 0x77, + 0xd8, 0x54, 0x9e, 0x87, 0x51, 0xd4, 0xb3, 0x8a, 0x15, 0x39, 0x69, 0xca, 0x9f, 0xc6, 0x9f, 0xe7, + 0x30, 0x85, 0x93, 0xd2, 0x20, 0xf2, 0x22, 0x4c, 0xd6, 0x3d, 0x8a, 0x67, 0x99, 0xcd, 0x24, 0x34, + 0x51, 0xcf, 0x44, 0x04, 0xac, 0x36, 0xc8, 0x15, 0x98, 0xee, 0x74, 0x77, 0x9a, 0x4e, 0x9d, 0xd5, + 0x66, 0xd5, 0x77, 0x44, 0xce, 0x89, 0x09, 0x73, 0x92, 0x83, 0xef, 0xd3, 0xa3, 0xf2, 0x0e, 0xc6, + 0x36, 0x2c, 0xa8, 0xa1, 0xa9, 0x83, 0x30, 0xb9, 0xbe, 0x39, 0xad, 0xc0, 0xd1, 0x36, 0xf3, 0x3c, + 0x8c, 0xd8, 0xf6, 0x5e, 0xd7, 0xe1, 0x31, 0xc8, 0x26, 0x4c, 0xf1, 0x8b, 0x7c, 0x0a, 0x66, 0xa2, + 0x68, 0xe9, 0xb2, 0x19, 0xc3, 0xd8, 0x8c, 0x42, 0x58, 0x50, 0xe6, 0x70, 0xf2, 0x3a, 0x10, 0xb5, + 0x3e, 0x77, 0xe7, 0x43, 0x5a, 0xe7, 0x73, 0x72, 0xc2, 0x9c, 0x51, 0x4a, 0xd6, 0xb1, 0x80, 0xbc, + 0x00, 0x13, 0x1e, 0xf5, 0x51, 0x3a, 0xc4, 0x6e, 0xc3, 0x0c, 0x87, 0xe6, 0xb8, 0x84, 0xb1, 0xbe, + 0xbb, 0x0a, 0x05, 0xa5, 0x3b, 0x30, 0xfa, 0x37, 0x4f, 0xb7, 0x60, 0x4e, 0x45, 0x70, 0xb3, 0x53, + 0x6d, 0x90, 0x2f, 0xc2, 0x82, 0x82, 0xc9, 0x93, 0x2d, 0x5a, 0xb4, 0xe9, 0xec, 0x39, 0x3b, 0x4d, + 0x2a, 0xe6, 0x5b, 0x72, 0x56, 0x87, 0x57, 0x48, 0x73, 0x3e, 0xa2, 0xe6, 0x69, 0x18, 0x97, 0x05, + 0x2d, 0x59, 0x85, 0xb9, 0x18, 0x67, 0xda, 0xb0, 0xba, 0x9d, 0x9e, 0x41, 0xff, 0x22, 0x9e, 0x44, + 0xe7, 0x49, 0x1b, 0x5b, 0x1d, 0xe3, 0x1b, 0x30, 0xa1, 0xce, 0x49, 0xd6, 0x09, 0xaa, 0x5c, 0x22, + 0x66, 0xdf, 0x78, 0x08, 0xab, 0xb2, 0x7b, 0xe1, 0x54, 0x84, 0x82, 0x83, 0xc8, 0xb7, 0x97, 0xc9, + 0x10, 0x8a, 0x43, 0xf8, 0x02, 0x4c, 0x34, 0x1c, 0xbf, 0xd3, 0xb4, 0x8f, 0xac, 0x28, 0x8b, 0xb8, + 0x39, 0x2e, 0x60, 0xa8, 0xf8, 0x59, 0x82, 0x99, 0xc4, 0x3e, 0xa8, 0x48, 0x1a, 0x7c, 0x5f, 0xef, + 0x2f, 0x69, 0x18, 0x6d, 0x98, 0x50, 0xcf, 0xb5, 0x53, 0x92, 0xa3, 0x9c, 0xc7, 0x30, 0x3c, 0x7c, + 0xd3, 0x1f, 0x39, 0x39, 0x2e, 0x66, 0x9d, 0x06, 0x06, 0xdf, 0xb9, 0x0a, 0x79, 0x29, 0xb1, 0x09, + 0x41, 0x09, 0x1f, 0x13, 0xe4, 0xd3, 0xa4, 0x19, 0x96, 0x1a, 0xaf, 0xc0, 0xa8, 0x38, 0xba, 0xfa, + 0x3f, 0x21, 0x18, 0xdf, 0xcc, 0xc2, 0xb4, 0x49, 0xd9, 0xc6, 0x4a, 0x79, 0x46, 0xa4, 0xa7, 0xf6, + 0x8a, 0x9e, 0x1e, 0x2e, 0x56, 0x6b, 0x5b, 0x9f, 0x5c, 0x44, 0xbf, 0x92, 0x81, 0xd9, 0x14, 0xdc, + 0x8f, 0x94, 0x8b, 0xf7, 0x36, 0x8c, 0x55, 0x1c, 0xbb, 0x59, 0x6a, 0x34, 0xc2, 0x98, 0x3c, 0x28, + 0xe7, 0x63, 0xc2, 0x2e, 0x9b, 0x41, 0x55, 0x21, 0x26, 0x44, 0x25, 0xaf, 0x8a, 0x49, 0x11, 0x65, + 0xb2, 0xc7, 0x49, 0xf1, 0xed, 0xe3, 0x22, 0xf0, 0x6f, 0xda, 0x0c, 0xa7, 0x08, 0x86, 0x70, 0xe6, + 0xc0, 0xc8, 0xaf, 0xea, 0xa9, 0x1d, 0xba, 0xf4, 0x10, 0xce, 0xf1, 0xe6, 0x0d, 0x94, 0x8e, 0xe8, + 0xc7, 0xb2, 0x70, 0x3e, 0x9d, 0xf0, 0xa3, 0xa6, 0x55, 0xc6, 0x44, 0x50, 0x4a, 0xd8, 0x79, 0x4c, + 0xab, 0xcc, 0xb3, 0x46, 0x21, 0x7e, 0x84, 0x40, 0x76, 0x61, 0x72, 0xd5, 0xf6, 0x83, 0x15, 0x6a, + 0x7b, 0xc1, 0x0e, 0xb5, 0x83, 0x01, 0x24, 0x79, 0x69, 0x4d, 0x31, 0x8f, 0xc2, 0xc4, 0xbe, 0xa4, + 0x8c, 0xc9, 0xda, 0x3a, 0xdb, 0x70, 0xa2, 0x0c, 0x0d, 0x30, 0x51, 0xbe, 0x0e, 0xd3, 0x35, 0xda, + 0xb2, 0x3b, 0xfb, 0xae, 0x27, 0xe3, 0x25, 0x5c, 0x87, 0xc9, 0x10, 0x94, 0x3a, 0x5b, 0xf4, 0x62, + 0x0d, 0x5f, 0xe9, 0x88, 0x68, 0x2b, 0xd1, 0x8b, 0x8d, 0xbf, 0x9b, 0x85, 0x0b, 0xa5, 0xba, 0x30, + 0x0d, 0x15, 0x05, 0xd2, 0x82, 0xfd, 0x13, 0xae, 0x9b, 0xdc, 0x80, 0xb1, 0x07, 0xf6, 0xe3, 0x55, + 0x6a, 0xfb, 0xd4, 0x17, 0x49, 0x2d, 0xb9, 0xd8, 0x6b, 0x3f, 0x8e, 0x1e, 0x7f, 0xcc, 0x08, 0x47, + 0x55, 0x23, 0x0c, 0x7d, 0x4c, 0x35, 0x82, 0x01, 0x23, 0x2b, 0x6e, 0xb3, 0x21, 0xce, 0x7a, 0xf1, + 0xe2, 0xbc, 0x8f, 0x10, 0x53, 0x94, 0x18, 0x7f, 0x9a, 0x81, 0xa9, 0xf0, 0x8b, 0xf1, 0x13, 0x3e, + 0xf1, 0x2e, 0xb9, 0x02, 0xa3, 0x58, 0x51, 0x98, 0x7d, 0x1f, 0x0f, 0x8d, 0x26, 0xc5, 0xd4, 0x84, + 0x0d, 0x53, 0x16, 0xaa, 0x3d, 0x31, 0xfc, 0xf1, 0x7a, 0xc2, 0xf8, 0x47, 0xf8, 0x98, 0xad, 0xb6, + 0x92, 0x9d, 0x44, 0xca, 0x87, 0x64, 0x06, 0xfc, 0x90, 0xec, 0x13, 0x1b, 0x92, 0x5c, 0xcf, 0x21, + 0xf9, 0xa1, 0x2c, 0x8c, 0x87, 0x1f, 0xfb, 0x1d, 0x96, 0xfb, 0x20, 0x6c, 0xd7, 0x40, 0x31, 0x8e, + 0x6a, 0xca, 0x5e, 0x21, 0x42, 0x09, 0x7d, 0x01, 0x46, 0xc4, 0x62, 0xca, 0xc4, 0x2c, 0xb9, 0x63, + 0xa3, 0xbb, 0x34, 0x25, 0x58, 0x8f, 0xe0, 0x80, 0xfa, 0xa6, 0xa0, 0xc3, 0x20, 0x52, 0xdb, 0x74, + 0x47, 0xd8, 0x36, 0x3c, 0xb5, 0x67, 0x54, 0x7a, 0x10, 0xa9, 0xa8, 0x61, 0x03, 0x9d, 0x4e, 0xff, + 0x2c, 0x0f, 0x85, 0x38, 0xc9, 0xe9, 0xd9, 0x25, 0x36, 0xba, 0x3b, 0xfc, 0xaa, 0xc2, 0xb3, 0x4b, + 0x74, 0xba, 0x3b, 0x26, 0x83, 0xa1, 0xe9, 0x93, 0xe7, 0x3c, 0xc2, 0x56, 0x4f, 0x08, 0xd3, 0x27, + 0xcf, 0x79, 0xa4, 0x99, 0x3e, 0x79, 0xce, 0x23, 0x54, 0x24, 0xac, 0xd6, 0x30, 0xc0, 0x02, 0xde, + 0x53, 0x84, 0x22, 0xa1, 0xe9, 0xc7, 0x33, 0xc5, 0x49, 0x34, 0x76, 0x54, 0x2e, 0x51, 0xdb, 0x13, + 0x99, 0x10, 0xc4, 0x76, 0x86, 0x47, 0xe5, 0x0e, 0x82, 0xad, 0x80, 0xc1, 0x4d, 0x15, 0x89, 0x34, + 0x81, 0x28, 0x3f, 0xe5, 0x02, 0x3e, 0xfd, 0x6e, 0x2d, 0xad, 0x30, 0xe7, 0x54, 0xd6, 0x96, 0xba, + 0x9a, 0x53, 0xf8, 0x3e, 0x49, 0xed, 0xef, 0x86, 0x08, 0xef, 0x8a, 0x0a, 0xa4, 0xfc, 0xa9, 0xcc, + 0x64, 0x60, 0x18, 0xe0, 0xe1, 0x5f, 0x43, 0x35, 0x52, 0xc4, 0x84, 0xbc, 0x0b, 0xe3, 0x6a, 0xd8, + 0x0c, 0x1e, 0xdc, 0xe1, 0x39, 0x1e, 0x4f, 0xb3, 0x47, 0x76, 0x61, 0x95, 0x80, 0xec, 0xc0, 0x85, + 0xb2, 0xdb, 0xf6, 0xbb, 0x2d, 0x19, 0xb9, 0x33, 0x8a, 0x48, 0x0e, 0x38, 0x14, 0xe8, 0x83, 0x5f, + 0x17, 0x28, 0x22, 0x4a, 0x83, 0x74, 0x93, 0xd1, 0x2f, 0x20, 0xbd, 0x18, 0x91, 0x4d, 0x18, 0x47, + 0x0d, 0xaa, 0x30, 0x79, 0x1c, 0xd7, 0xb7, 0x8d, 0xa8, 0xa4, 0xc2, 0x16, 0x06, 0x8f, 0x1a, 0x67, + 0xb7, 0x9a, 0xd2, 0x4b, 0x43, 0xd5, 0x04, 0x2b, 0xc8, 0xe4, 0x2b, 0x30, 0xc5, 0xaf, 0x68, 0xdb, + 0x74, 0x87, 0xcf, 0x9d, 0x09, 0x4d, 0x13, 0xa1, 0x17, 0xf2, 0xc7, 0x7c, 0xa1, 0xb7, 0x3e, 0xa4, + 0x3b, 0x7c, 0xec, 0x35, 0x1f, 0x29, 0x0d, 0x9f, 0x6c, 0xc1, 0xec, 0x8a, 0xed, 0x73, 0xa0, 0x12, + 0xff, 0x60, 0x12, 0x35, 0xb4, 0x68, 0xbb, 0xbe, 0x6f, 0xfb, 0x52, 0x11, 0x9e, 0x1a, 0xef, 0x20, + 0x8d, 0x9e, 0x7c, 0x33, 0x03, 0xf3, 0x9a, 0x9e, 0x5c, 0xd8, 0x99, 0xb5, 0x68, 0x3b, 0x40, 0x67, + 0xa8, 0xa9, 0xc5, 0xa2, 0x14, 0x4a, 0x7b, 0xa0, 0xf1, 0x21, 0x89, 0xa9, 0xe2, 0xbd, 0xa8, 0x5c, + 0x35, 0x0a, 0xef, 0xc5, 0x43, 0x2c, 0x54, 0x5c, 0xd3, 0xd3, 0xfa, 0x42, 0x8d, 0xad, 0x6b, 0x89, + 0x66, 0xdc, 0x8e, 0xf7, 0xb7, 0x50, 0x74, 0x65, 0x42, 0x45, 0xd7, 0x1c, 0x0c, 0x63, 0xaf, 0xca, + 0x28, 0x5a, 0xf8, 0xc3, 0xf8, 0xb4, 0xba, 0x0f, 0x09, 0xb1, 0xb0, 0xef, 0x3e, 0x64, 0xfc, 0xf7, + 0x23, 0x30, 0x1d, 0x9b, 0x16, 0xe2, 0x9e, 0x9a, 0x49, 0xdc, 0x53, 0x6b, 0x00, 0x5c, 0xd5, 0x3b, + 0xa0, 0x4e, 0x56, 0x3a, 0x62, 0x8e, 0x0b, 0x37, 0xea, 0x70, 0x4d, 0x29, 0x6c, 0x18, 0x53, 0xbe, + 0x62, 0x07, 0xd4, 0x91, 0x87, 0x4c, 0xf9, 0xa2, 0x57, 0x98, 0x46, 0x6c, 0x48, 0x11, 0x86, 0x31, + 0x7e, 0xae, 0xea, 0x07, 0xeb, 0x30, 0x80, 0xc9, 0xe1, 0xe4, 0x45, 0x18, 0x61, 0x42, 0x54, 0xb5, + 0x22, 0x36, 0x41, 0x3c, 0x5b, 0x98, 0x94, 0xc5, 0x24, 0x16, 0x51, 0x44, 0x6e, 0xc3, 0x04, 0xff, + 0x4b, 0x84, 0xd9, 0x19, 0xd1, 0x8d, 0x1f, 0x2d, 0xa7, 0x21, 0x23, 0xed, 0x68, 0x78, 0xec, 0x76, + 0x51, 0xeb, 0xa2, 0x5a, 0xa7, 0x5a, 0x11, 0x21, 0xdd, 0xf1, 0x76, 0xe1, 0x73, 0x20, 0xab, 0x22, + 0x42, 0x60, 0xb2, 0x8c, 0xf0, 0x46, 0xc9, 0xe3, 0x9d, 0x12, 0x65, 0x19, 0xee, 0x85, 0x62, 0x8a, + 0x12, 0x72, 0x8d, 0xbf, 0xc4, 0xa0, 0x58, 0xc8, 0x33, 0x63, 0xe2, 0xbb, 0x05, 0x2a, 0x26, 0x50, + 0x36, 0x0c, 0x8b, 0x59, 0xe5, 0xec, 0xef, 0xe5, 0x96, 0xed, 0x34, 0xc5, 0xb6, 0x82, 0x95, 0x23, + 0x2e, 0x65, 0x50, 0x33, 0x42, 0x20, 0x6f, 0xc3, 0x14, 0xfb, 0x51, 0x76, 0x5b, 0x2d, 0xb7, 0x8d, + 0xec, 0xc7, 0xa3, 0x40, 0x7a, 0x48, 0x52, 0xc7, 0x22, 0x5e, 0x4b, 0x0c, 0x97, 0x9d, 0x27, 0xf8, + 0xca, 0xdb, 0xe5, 0x6f, 0x44, 0x13, 0xd1, 0x79, 0x82, 0xa4, 0x3e, 0x87, 0x9b, 0x2a, 0x12, 0x79, + 0x13, 0x26, 0xd9, 0xcf, 0xbb, 0xce, 0x23, 0xca, 0x2b, 0x9c, 0x8c, 0xcc, 0x1b, 0x90, 0x6a, 0x8f, + 0x95, 0xf0, 0xfa, 0x74, 0x4c, 0xf2, 0x3e, 0x9c, 0x43, 0x4e, 0x75, 0xb7, 0x43, 0x1b, 0xa5, 0xdd, + 0x5d, 0xa7, 0xe9, 0x70, 0x6b, 0x34, 0x1e, 0x50, 0x06, 0x75, 0xf0, 0xbc, 0x62, 0xc4, 0xb0, 0xec, + 0x08, 0xc5, 0x4c, 0xa7, 0x24, 0xdb, 0x50, 0x28, 0x77, 0xfd, 0xc0, 0x6d, 0x95, 0x82, 0xc0, 0x73, + 0x76, 0xba, 0x01, 0xf5, 0xe7, 0xa7, 0xb5, 0xb0, 0x2b, 0x6c, 0x71, 0x84, 0x85, 0x5c, 0x1f, 0x54, + 0x47, 0x0a, 0xcb, 0x0e, 0x49, 0xcc, 0x04, 0x13, 0xe3, 0x5f, 0x64, 0x60, 0x52, 0x23, 0x25, 0x6f, + 0xc0, 0xc4, 0x1d, 0xcf, 0xa1, 0xed, 0x46, 0xf3, 0x48, 0xb9, 0xa8, 0xe2, 0x2d, 0x66, 0x57, 0xc0, + 0x79, 0xab, 0x35, 0xb4, 0x50, 0xcf, 0x93, 0x4d, 0x35, 0x15, 0xbd, 0xc1, 0xdd, 0xb1, 0xc5, 0x04, + 0xcd, 0x45, 0x71, 0xa0, 0x70, 0x82, 0x8a, 0xd9, 0xa9, 0xa0, 0x90, 0x77, 0x60, 0x84, 0xbf, 0x07, + 0x0b, 0xbb, 0xc5, 0x8b, 0x69, 0xcd, 0xe4, 0xae, 0xff, 0x38, 0x11, 0xd1, 0xe8, 0xc7, 0x37, 0x05, + 0x91, 0xf1, 0x33, 0x19, 0x20, 0x49, 0xd4, 0x53, 0xf4, 0x5e, 0xa7, 0x1a, 0x13, 0x7d, 0x21, 0x5c, + 0x8d, 0x39, 0x4d, 0x67, 0xce, 0x6a, 0xe2, 0x05, 0xbc, 0xe3, 0xc5, 0xaa, 0x53, 0x15, 0x71, 0xbc, + 0xd8, 0xf8, 0xc1, 0x2c, 0x40, 0x84, 0x4d, 0x3e, 0xc7, 0x13, 0xa1, 0xbd, 0xdf, 0xb5, 0x9b, 0xce, + 0xae, 0xa3, 0xc7, 0xed, 0x45, 0x26, 0x5f, 0x97, 0x25, 0xa6, 0x8e, 0x48, 0xde, 0x83, 0xe9, 0xda, + 0x86, 0x4e, 0xab, 0x98, 0xc5, 0xfb, 0x1d, 0x2b, 0x46, 0x1e, 0xc7, 0x46, 0xfb, 0x64, 0x75, 0x34, + 0xb8, 0x7d, 0x32, 0x1f, 0x08, 0x51, 0xc2, 0x36, 0x96, 0xda, 0x86, 0xb0, 0xfc, 0x6f, 0x84, 0xaf, + 0x9a, 0xf8, 0x75, 0x7e, 0xc7, 0xea, 0x08, 0x97, 0x00, 0xb6, 0x4f, 0x68, 0x78, 0x51, 0x47, 0x0e, + 0xf7, 0x70, 0xef, 0xff, 0x59, 0x54, 0xfb, 0xb5, 0xdc, 0x80, 0x0a, 0x6d, 0xc7, 0x53, 0x7b, 0xef, + 0x89, 0x8c, 0x09, 0x86, 0x35, 0xaf, 0x65, 0xad, 0x75, 0xc2, 0x60, 0xe6, 0x56, 0x74, 0x49, 0xe1, + 0x66, 0x05, 0x29, 0x36, 0x36, 0xff, 0x20, 0x03, 0xe7, 0x52, 0x69, 0xc9, 0x75, 0x80, 0x48, 0xa7, + 0x24, 0x7a, 0x09, 0x77, 0xcc, 0x28, 0xfa, 0x91, 0xa9, 0x60, 0x90, 0x2f, 0xc7, 0xb5, 0x41, 0xa7, + 0x1f, 0x84, 0x0b, 0x32, 0xe8, 0xa0, 0xae, 0x0d, 0x4a, 0xd1, 0x01, 0x19, 0xbf, 0x92, 0x83, 0x19, + 0x25, 0xb8, 0x12, 0xff, 0xd6, 0x53, 0xec, 0xc5, 0x0f, 0x60, 0x82, 0xb5, 0xc6, 0xa9, 0x0b, 0xb7, + 0x1b, 0x6e, 0xf8, 0xf2, 0x6a, 0xc2, 0xef, 0x54, 0x70, 0xbb, 0xae, 0x22, 0xf3, 0x50, 0xa0, 0xb8, + 0x75, 0xe2, 0x83, 0x44, 0x3d, 0xe9, 0x72, 0xa3, 0x31, 0x27, 0x3e, 0x4c, 0x56, 0x8e, 0xda, 0x76, + 0x2b, 0xac, 0x8d, 0x1b, 0xc0, 0x7c, 0xaa, 0x67, 0x6d, 0x1a, 0x36, 0xaf, 0x2e, 0xf2, 0xd0, 0xe2, + 0x65, 0x29, 0xc1, 0x01, 0x34, 0xaa, 0x85, 0xf7, 0x60, 0x26, 0xf1, 0xd1, 0x67, 0x8a, 0x4a, 0xba, + 0x0d, 0x24, 0xf9, 0x1d, 0x29, 0x1c, 0x3e, 0xa5, 0xc7, 0xbc, 0x3d, 0x17, 0x3e, 0x5e, 0xb7, 0x5a, + 0x76, 0xbb, 0xc1, 0xcd, 0x69, 0x16, 0xd5, 0x98, 0xa5, 0x3f, 0x9b, 0x55, 0x7d, 0x7f, 0x9f, 0xf6, + 0x55, 0xf7, 0x05, 0xed, 0x36, 0x7c, 0xa9, 0xd7, 0x98, 0x0e, 0xa4, 0x75, 0xf8, 0x56, 0x0e, 0x2e, + 0xf4, 0xa0, 0x24, 0x47, 0xf1, 0x49, 0xc4, 0xb5, 0x10, 0x37, 0xfb, 0x57, 0xf8, 0x24, 0xa6, 0x12, + 0xf9, 0x1c, 0x8f, 0xfe, 0x51, 0x77, 0xdb, 0xbb, 0xce, 0x9e, 0xb8, 0x7f, 0xa3, 0x1a, 0xff, 0x20, + 0x84, 0xc6, 0xc3, 0x7e, 0x70, 0x28, 0x79, 0x0f, 0x86, 0xd1, 0xf1, 0x3b, 0x16, 0xde, 0x91, 0x61, + 0x20, 0x5c, 0x09, 0x50, 0xca, 0x7e, 0x6a, 0x01, 0x4a, 0x19, 0x80, 0x7c, 0x16, 0x72, 0xa5, 0xed, + 0x9a, 0x18, 0x97, 0x29, 0x95, 0x7c, 0xbb, 0x16, 0xa5, 0x6f, 0xb1, 0xb5, 0x3c, 0x2b, 0x8c, 0x82, + 0x11, 0xde, 0x2d, 0x6f, 0x88, 0x51, 0x51, 0x09, 0xef, 0x96, 0x37, 0x22, 0xc2, 0xbd, 0xba, 0x16, + 0x2c, 0xeb, 0x6e, 0x79, 0xe3, 0x93, 0x9b, 0xf6, 0xff, 0x4e, 0x96, 0x87, 0x2c, 0xe1, 0x0d, 0x7b, + 0x0f, 0x26, 0xb4, 0x98, 0xe4, 0x99, 0x48, 0x1e, 0x0b, 0xe3, 0xc7, 0xc7, 0x2c, 0x86, 0x34, 0x02, + 0x99, 0x08, 0x89, 0xfd, 0x46, 0x89, 0x57, 0x35, 0xb6, 0x09, 0x39, 0xa0, 0x4c, 0x1c, 0x4f, 0x84, + 0x14, 0x92, 0x90, 0x5b, 0x90, 0xdf, 0xa4, 0x6d, 0xbb, 0x1d, 0x84, 0x0a, 0x51, 0x34, 0x2e, 0x0e, + 0x10, 0xa6, 0x4b, 0x0d, 0x21, 0x22, 0x1a, 0xc2, 0x76, 0x77, 0xfc, 0xba, 0xe7, 0x60, 0x68, 0xa3, + 0xf0, 0x2c, 0xe6, 0x86, 0xb0, 0x4a, 0x89, 0xce, 0x20, 0x46, 0x64, 0xfc, 0x6c, 0x06, 0x46, 0xc5, + 0x40, 0xf2, 0x04, 0x76, 0x7b, 0xd1, 0x59, 0x22, 0x9c, 0x07, 0xf6, 0x9c, 0xb8, 0xf3, 0xc0, 0x1e, + 0x8f, 0x1f, 0x34, 0x26, 0x1c, 0xeb, 0xc2, 0xa7, 0x41, 0x9c, 0x8d, 0xd2, 0xed, 0x53, 0xcf, 0x4f, + 0x16, 0xa2, 0x0e, 0xea, 0x90, 0x65, 0xfc, 0x3d, 0xf1, 0x65, 0x77, 0xcb, 0x1b, 0x64, 0x11, 0xf2, + 0xab, 0x2e, 0x0f, 0x85, 0xa5, 0x66, 0x23, 0x6e, 0x0a, 0x98, 0xda, 0x41, 0x12, 0x8f, 0x7d, 0xdf, + 0x86, 0xe7, 0x8a, 0xbb, 0x8c, 0xf2, 0x7d, 0x1d, 0x0e, 0x8c, 0x7d, 0x5f, 0x88, 0x3a, 0xf0, 0xf7, + 0xd1, 0x94, 0x4d, 0xe2, 0xe1, 0x2d, 0xcc, 0x10, 0x73, 0x4f, 0x75, 0x74, 0x13, 0x45, 0x72, 0xa7, + 0x58, 0xe8, 0xb5, 0x53, 0x3c, 0xbc, 0x65, 0xa6, 0x50, 0xe1, 0xbb, 0x5a, 0x04, 0xae, 0x51, 0xef, + 0xd1, 0x53, 0xbc, 0x4b, 0xa7, 0xbf, 0xab, 0xc5, 0x9b, 0x37, 0xd0, 0x26, 0xfd, 0x87, 0x59, 0x38, + 0x9f, 0x4e, 0xa8, 0xb6, 0x25, 0xd3, 0xa7, 0x2d, 0x57, 0x21, 0xbf, 0xe2, 0xfa, 0x81, 0x62, 0x24, + 0x88, 0xea, 0xff, 0x7d, 0x01, 0x33, 0xc3, 0x52, 0x76, 0xe7, 0x66, 0x7f, 0x87, 0xcb, 0x13, 0xf9, + 0x61, 0xa0, 0x0e, 0x76, 0xe7, 0xe6, 0x45, 0xe4, 0x2e, 0xe4, 0x4d, 0xe1, 0x68, 0x15, 0xeb, 0x1a, + 0x09, 0x0e, 0xa5, 0x29, 0xe2, 0x09, 0x88, 0x16, 0x1a, 0x5e, 0xc0, 0x48, 0x09, 0x46, 0xc5, 0xe8, + 0xc7, 0x9e, 0x8e, 0x53, 0xa6, 0x8c, 0x9e, 0xad, 0x41, 0xd2, 0xb1, 0x1d, 0x05, 0x1f, 0x01, 0xab, + 0x15, 0xe9, 0x33, 0x85, 0x3b, 0x0a, 0x7f, 0x24, 0xd4, 0xed, 0x31, 0x43, 0x44, 0xe3, 0x9b, 0x59, + 0x00, 0xa9, 0xb5, 0x79, 0x6a, 0x67, 0xd8, 0x67, 0xb5, 0x19, 0xa6, 0xd8, 0x1b, 0x0d, 0x9e, 0x70, + 0x79, 0x1d, 0xcd, 0x79, 0x06, 0x4f, 0xb7, 0x5c, 0x84, 0xe1, 0xcd, 0x48, 0xa1, 0x25, 0x5c, 0x52, + 0x50, 0x1d, 0xcd, 0xe1, 0xc6, 0x0e, 0xcc, 0xdd, 0xa5, 0x41, 0xa4, 0xde, 0x92, 0x4f, 0x8f, 0xfd, + 0xd9, 0xbe, 0x06, 0x63, 0x02, 0x3f, 0xdc, 0xbf, 0xb8, 0x2e, 0x46, 0xc4, 0xbe, 0x41, 0x5d, 0x8c, + 0x44, 0x60, 0xbb, 0x51, 0x85, 0x36, 0x69, 0x40, 0x3f, 0xd9, 0x6a, 0x6a, 0x40, 0x78, 0x53, 0xb0, + 0x65, 0x83, 0xd5, 0x70, 0x6a, 0xff, 0x3c, 0x84, 0x73, 0xe1, 0xb7, 0x3f, 0x49, 0xbe, 0x37, 0xd8, + 0x95, 0x52, 0x24, 0x3a, 0x88, 0x38, 0xf6, 0xb1, 0x3d, 0x79, 0x0c, 0x0b, 0x92, 0x60, 0xdb, 0x09, + 0x0d, 0x27, 0x07, 0xa2, 0x25, 0x6f, 0xc3, 0xb8, 0x42, 0x23, 0x02, 0xf5, 0xa3, 0x9a, 0xfa, 0xd0, + 0x09, 0xf6, 0x2d, 0x9f, 0xc3, 0x55, 0x35, 0xb5, 0x82, 0x6e, 0x7c, 0x09, 0x9e, 0x0d, 0xdd, 0x86, + 0x52, 0xaa, 0x8e, 0x31, 0xcf, 0x9c, 0x8d, 0xf9, 0x5a, 0xd4, 0xac, 0x6a, 0x3b, 0xf4, 0x8c, 0x96, + 0xbc, 0x89, 0xda, 0x2c, 0xd1, 0x98, 0xe7, 0x12, 0xbe, 0xd6, 0x8a, 0x4b, 0xb5, 0xf1, 0x96, 0xf2, + 0xb1, 0x29, 0x0c, 0x35, 0xe2, 0x4c, 0x9c, 0xf8, 0x9b, 0x59, 0x98, 0x5e, 0xaf, 0x56, 0xca, 0xa1, + 0xf5, 0xd1, 0x77, 0x58, 0x3a, 0x68, 0xad, 0x6d, 0xbd, 0xf7, 0x1b, 0x63, 0x0b, 0x66, 0x63, 0xdd, + 0x80, 0xa2, 0xc3, 0xbb, 0xdc, 0xe1, 0x24, 0x04, 0x4b, 0xb1, 0xe1, 0x7c, 0x1a, 0xfb, 0x87, 0xb7, + 0xcc, 0x18, 0xb6, 0xf1, 0x9f, 0x43, 0x8c, 0xaf, 0xd8, 0xc2, 0x5e, 0x83, 0xb1, 0xaa, 0xef, 0x77, + 0xa9, 0xb7, 0x65, 0xae, 0xaa, 0xaa, 0x02, 0x07, 0x81, 0x56, 0xd7, 0x6b, 0x9a, 0x11, 0x02, 0xb9, + 0x06, 0x79, 0x11, 0x24, 0x5d, 0xee, 0x09, 0xa8, 0xb5, 0x0d, 0x63, 0xac, 0x9b, 0x61, 0x31, 0x79, + 0x03, 0x26, 0xf8, 0xdf, 0x7c, 0xb6, 0x89, 0x0e, 0x47, 0xe5, 0xa0, 0x40, 0xe7, 0xb3, 0xd3, 0xd4, + 0xd0, 0xc8, 0xab, 0x90, 0x2b, 0x95, 0x4d, 0xa1, 0x0e, 0x12, 0x72, 0xa3, 0x67, 0x71, 0x9d, 0x9d, + 0x76, 0x89, 0x28, 0x9b, 0x4c, 0xfa, 0x93, 0xc1, 0x26, 0x84, 0x26, 0x1b, 0x67, 0x80, 0xd4, 0x36, + 0xc5, 0x0e, 0x33, 0x84, 0x91, 0x1b, 0x30, 0x5a, 0xe1, 0x26, 0x73, 0x42, 0x8f, 0xcd, 0x73, 0x1d, + 0x72, 0x90, 0x16, 0x5c, 0x81, 0x83, 0xc8, 0x35, 0x99, 0xa1, 0x2d, 0x1f, 0xf9, 0xad, 0xf4, 0x48, + 0xc3, 0xf6, 0x1a, 0x8c, 0x88, 0x50, 0xe2, 0x63, 0x4a, 0xee, 0x96, 0x78, 0x08, 0x71, 0x81, 0x93, + 0x74, 0x60, 0x85, 0x27, 0xe9, 0xc0, 0xba, 0x03, 0x17, 0xee, 0xa2, 0xf6, 0x46, 0x0f, 0x88, 0xb5, + 0x65, 0x56, 0x85, 0x3e, 0x1c, 0x9f, 0x81, 0xb8, 0x82, 0x27, 0x1e, 0x53, 0xcb, 0xea, 0x7a, 0x6a, + 0xea, 0xde, 0x5e, 0x8c, 0xc8, 0x17, 0x61, 0x2e, 0xad, 0x48, 0x68, 0xcd, 0x31, 0xf4, 0x53, 0x7a, + 0x05, 0x6a, 0xe8, 0xa7, 0x34, 0x0e, 0x64, 0x15, 0x0a, 0x1c, 0x5e, 0x6a, 0xb4, 0x9c, 0x36, 0xd7, + 0xfc, 0x73, 0xad, 0x3a, 0x3a, 0x92, 0x08, 0xae, 0x36, 0x2b, 0xe4, 0x2f, 0x00, 0x9a, 0xeb, 0x51, + 0x8c, 0x92, 0xfc, 0x44, 0x86, 0xdd, 0xe6, 0x78, 0xe0, 0xed, 0x2d, 0x73, 0xd5, 0x17, 0x61, 0x03, + 0xcf, 0x47, 0x5e, 0x45, 0xb5, 0xc0, 0x73, 0xda, 0x7b, 0xc2, 0xad, 0x68, 0x53, 0xb8, 0x15, 0xbd, + 0xfd, 0x91, 0xdc, 0x8a, 0x38, 0x2b, 0xff, 0xe4, 0xb8, 0x38, 0xe1, 0x89, 0x3a, 0x71, 0x15, 0x69, + 0x5f, 0xc0, 0xba, 0x0e, 0x7d, 0x6b, 0xb7, 0xda, 0x3c, 0xec, 0x2f, 0x6d, 0xf0, 0x46, 0x4e, 0xe3, + 0x0e, 0x8e, 0x5d, 0x87, 0x39, 0x41, 0xac, 0x6e, 0x88, 0x90, 0x68, 0x68, 0x2a, 0x07, 0x76, 0xf1, + 0x94, 0xae, 0x2b, 0xdc, 0x1b, 0xb7, 0x10, 0x5d, 0x3c, 0xa5, 0x9f, 0x8b, 0x85, 0xd3, 0x48, 0x9d, + 0x3c, 0x1a, 0x09, 0xb9, 0x01, 0x23, 0x0f, 0xec, 0xc7, 0xa5, 0x3d, 0x2a, 0x72, 0x7b, 0x4e, 0xca, + 0xed, 0x0f, 0x81, 0x4b, 0xf9, 0x3f, 0xe2, 0xbe, 0x0e, 0xcf, 0x98, 0x02, 0x8d, 0x7c, 0x6f, 0x06, + 0xce, 0xf3, 0x65, 0x2c, 0x5b, 0x59, 0xa3, 0x41, 0xc0, 0xfa, 0x41, 0xc4, 0x0f, 0xbc, 0x1c, 0x19, + 0x6c, 0xa7, 0xe3, 0xa1, 0xe7, 0xbd, 0x21, 0x76, 0x86, 0xb0, 0xe3, 0x7c, 0x51, 0xaa, 0x05, 0x62, + 0x4e, 0xa5, 0x27, 0x9b, 0x30, 0xfe, 0xe0, 0x4e, 0x29, 0xac, 0x96, 0x47, 0x67, 0x2f, 0xa6, 0xed, + 0x8e, 0x0a, 0x5a, 0x9a, 0xa7, 0x81, 0xca, 0x46, 0x78, 0x07, 0x7c, 0x56, 0xf6, 0x07, 0x79, 0x5d, + 0x75, 0x45, 0xcd, 0xa1, 0xf4, 0x3c, 0xda, 0xb2, 0x1f, 0x5b, 0xf6, 0x1e, 0xd5, 0x5e, 0xc9, 0x85, + 0xf6, 0xfa, 0xa7, 0x33, 0x70, 0xb1, 0x67, 0x93, 0xc9, 0x6d, 0xb8, 0x60, 0x73, 0x07, 0x6b, 0x6b, + 0x3f, 0x08, 0x3a, 0xbe, 0x25, 0xaf, 0x18, 0xc2, 0x79, 0xd5, 0x3c, 0x27, 0x8a, 0x57, 0x58, 0xa9, + 0xbc, 0x75, 0xf8, 0xe4, 0x3d, 0x78, 0xce, 0x69, 0xfb, 0xb4, 0xde, 0xf5, 0xa8, 0x25, 0x19, 0xd4, + 0x9d, 0x86, 0x67, 0x79, 0x76, 0x7b, 0x4f, 0x7a, 0xe2, 0x9a, 0x17, 0x25, 0x8e, 0x70, 0xe2, 0x2e, + 0x3b, 0x0d, 0xcf, 0x44, 0x04, 0xe3, 0x5f, 0x64, 0x60, 0xbe, 0x57, 0x97, 0x90, 0x79, 0x18, 0xa5, + 0x4a, 0x9e, 0x96, 0xbc, 0x29, 0x7f, 0x92, 0x67, 0x21, 0xda, 0xe9, 0xc5, 0xe9, 0x9f, 0xaf, 0x8b, + 0x9c, 0x19, 0x68, 0xda, 0xae, 0xee, 0xeb, 0xc2, 0x40, 0x79, 0xa2, 0xae, 0xee, 0xee, 0xcf, 0x03, + 0x44, 0xdb, 0x39, 0x57, 0x4c, 0x98, 0x63, 0x76, 0xdd, 0xe3, 0x2b, 0x8f, 0x9c, 0x87, 0x11, 0xbe, + 0x5d, 0x0a, 0xff, 0x07, 0xf1, 0x8b, 0x9d, 0xdb, 0xa2, 0x93, 0x71, 0x9f, 0xcf, 0x2d, 0x4d, 0x68, + 0x9d, 0x3d, 0xd2, 0xc2, 0xc1, 0x31, 0x7e, 0x72, 0x92, 0x8b, 0x10, 0xa5, 0x6e, 0xb0, 0x2f, 0x85, + 0x8e, 0xc5, 0x34, 0x7f, 0x31, 0x6e, 0x4b, 0xa9, 0xd8, 0x65, 0xeb, 0x5e, 0x62, 0xf2, 0xed, 0x27, + 0x9b, 0xfa, 0xf6, 0xf3, 0x1a, 0x8c, 0x95, 0xf7, 0x69, 0xfd, 0x20, 0x74, 0xc2, 0xc9, 0x0b, 0xe5, + 0x3a, 0x03, 0xf2, 0x90, 0xe8, 0x11, 0x02, 0xb9, 0x01, 0x80, 0x6e, 0xaa, 0x5c, 0x22, 0x55, 0xd2, + 0x9a, 0xa0, 0x57, 0xab, 0x30, 0x4f, 0x51, 0x50, 0x90, 0x7d, 0xcd, 0xbc, 0xa3, 0xda, 0xb3, 0x70, + 0xf6, 0xbe, 0xb7, 0x2b, 0xd0, 0x23, 0x04, 0xd6, 0x3c, 0x65, 0x5f, 0x11, 0xa7, 0x60, 0x21, 0xb1, + 0xf9, 0xa8, 0x48, 0xe4, 0x3a, 0x8c, 0x6d, 0x48, 0x47, 0x02, 0x3c, 0x04, 0x27, 0x90, 0x02, 0x22, + 0xa7, 0x83, 0xf9, 0x8c, 0x19, 0xa1, 0x90, 0xcf, 0xc2, 0x68, 0x99, 0x7a, 0xc1, 0xe6, 0xe6, 0x2a, + 0x1a, 0x9d, 0xf0, 0xec, 0x1f, 0x79, 0xcc, 0xd4, 0x10, 0x04, 0xcd, 0x6f, 0x1f, 0x17, 0x27, 0x03, + 0xa7, 0x45, 0xc3, 0xa8, 0xe6, 0xa6, 0xc4, 0x26, 0x4b, 0x50, 0xe0, 0xcf, 0xe2, 0xd1, 0xdd, 0x03, + 0x4f, 0xc6, 0x3c, 0x3f, 0xa7, 0xc5, 0x1b, 0xfa, 0x21, 0xdd, 0x09, 0xf3, 0x54, 0x24, 0xf0, 0xc9, + 0xb2, 0x4c, 0xef, 0xa2, 0x36, 0x13, 0x22, 0x65, 0x58, 0x7c, 0xc7, 0x60, 0xad, 0x4d, 0x52, 0x90, + 0x12, 0x4c, 0x96, 0xdd, 0x56, 0xc7, 0x0e, 0x1c, 0xcc, 0x83, 0x79, 0x24, 0x0e, 0x41, 0x54, 0xe8, + 0xd5, 0xd5, 0x02, 0xed, 0x44, 0x55, 0x0b, 0xc8, 0x1d, 0x98, 0x32, 0xdd, 0x2e, 0x1b, 0x26, 0x79, + 0x0b, 0xe7, 0xe7, 0x1c, 0x9a, 0x86, 0x78, 0xac, 0x84, 0x1d, 0xcb, 0xe2, 0xca, 0xad, 0x45, 0x80, + 0xd5, 0xa8, 0xc8, 0x5a, 0xca, 0x73, 0x88, 0x7a, 0xb8, 0xa9, 0xd9, 0x2a, 0x12, 0xcc, 0x52, 0x5e, + 0x52, 0x6e, 0xc1, 0x78, 0xad, 0xb6, 0xbe, 0x49, 0xfd, 0xe0, 0x4e, 0xd3, 0x3d, 0xc4, 0xb3, 0x2d, + 0x2f, 0x92, 0xab, 0xf9, 0xae, 0x15, 0x50, 0x3f, 0xb0, 0x76, 0x9b, 0xee, 0xa1, 0xa9, 0x62, 0x91, + 0xaf, 0xb2, 0xfe, 0x50, 0x24, 0x41, 0x11, 0xeb, 0xb6, 0x9f, 0xb0, 0x8a, 0x27, 0x48, 0xb4, 0x68, + 0x98, 0xc8, 0xaa, 0x77, 0x96, 0x82, 0x8e, 0x3e, 0x65, 0x9e, 0xfb, 0xf8, 0xa8, 0xd4, 0x68, 0x78, + 0xd4, 0xf7, 0xc5, 0x21, 0xc4, 0x7d, 0xca, 0x50, 0xd9, 0x60, 0xf3, 0x02, 0xcd, 0xa7, 0x4c, 0x21, + 0x20, 0x3f, 0x9c, 0x81, 0x73, 0xaa, 0xb7, 0x09, 0x2e, 0x17, 0x34, 0x73, 0xe1, 0x47, 0xd2, 0xeb, + 0xd7, 0xe5, 0x21, 0x7c, 0x5d, 0x41, 0xbb, 0xfe, 0xe8, 0xe6, 0xf5, 0x52, 0xf4, 0xb3, 0x26, 0x89, + 0x30, 0x6e, 0x5f, 0x31, 0x95, 0x9f, 0x96, 0x9b, 0x68, 0xce, 0x4e, 0x21, 0x26, 0x65, 0x26, 0xa9, + 0xb1, 0x19, 0x85, 0x86, 0x53, 0xd5, 0x0d, 0x3c, 0xd3, 0x84, 0x46, 0x55, 0xcc, 0x3f, 0x6e, 0x62, + 0xe5, 0x74, 0x74, 0x81, 0x4c, 0xa1, 0x21, 0x55, 0x98, 0xe6, 0x00, 0xb6, 0x2d, 0xf0, 0x34, 0x4f, + 0xb3, 0x51, 0xa2, 0x09, 0xc1, 0x06, 0xdf, 0xfa, 0x31, 0xd5, 0x93, 0x1a, 0x9c, 0x35, 0x46, 0x47, + 0xde, 0x83, 0x29, 0x8c, 0xa1, 0x1f, 0xad, 0xd7, 0x39, 0x5c, 0xc5, 0x18, 0x63, 0x56, 0x94, 0xc4, + 0x3c, 0xef, 0x26, 0x7c, 0x7f, 0x3f, 0x5a, 0xd1, 0xef, 0xc1, 0x14, 0xda, 0xea, 0x44, 0x0c, 0xce, + 0x45, 0x0c, 0x44, 0x49, 0x9c, 0x41, 0xd0, 0xf4, 0x23, 0x06, 0x3f, 0x95, 0x81, 0x8b, 0xac, 0xa2, + 0xf4, 0x11, 0x3a, 0xff, 0x51, 0x46, 0x08, 0xa3, 0x6e, 0xf6, 0xe4, 0xa9, 0x8a, 0xa3, 0xbe, 0xbf, + 0x9f, 0xc6, 0x01, 0x3f, 0x8a, 0x7d, 0x7c, 0xfa, 0x47, 0x5d, 0xf8, 0xc8, 0x1f, 0xd5, 0x93, 0xa7, + 0xfa, 0x51, 0x41, 0xd3, 0x4f, 0xe3, 0x80, 0xd7, 0xda, 0x5a, 0xe9, 0xc1, 0x6a, 0x74, 0x37, 0xfb, + 0xce, 0x72, 0x5b, 0xd1, 0xda, 0xd6, 0xc7, 0x6d, 0x65, 0x8b, 0x7b, 0x51, 0x2b, 0xdd, 0x20, 0xaf, + 0xb5, 0x1a, 0x38, 0x7e, 0xad, 0x8d, 0xd1, 0x98, 0x31, 0x6c, 0xe3, 0x97, 0x20, 0xc6, 0x57, 0x98, + 0xaa, 0x1a, 0x30, 0xc2, 0x6f, 0xad, 0xa2, 0x93, 0xd1, 0x66, 0x81, 0xdf, 0x69, 0x4d, 0x51, 0x42, + 0x2e, 0x42, 0xae, 0x56, 0x5b, 0x17, 0x9d, 0x8c, 0x06, 0xab, 0xbe, 0xef, 0x9a, 0x0c, 0xc6, 0x46, + 0x08, 0xad, 0x50, 0x95, 0x9c, 0x04, 0xec, 0xbc, 0x33, 0x11, 0xca, 0xfa, 0x5b, 0xde, 0x21, 0x87, + 0xa2, 0xfe, 0x16, 0x77, 0xc8, 0xe8, 0xe6, 0x58, 0x86, 0xf9, 0x92, 0xef, 0x53, 0x8f, 0x4d, 0x08, + 0x61, 0xdc, 0xe8, 0x89, 0x7b, 0x8e, 0x38, 0xd8, 0xb1, 0x52, 0xbb, 0xee, 0x9b, 0x3d, 0x11, 0xc9, + 0x55, 0xc8, 0x97, 0xba, 0x0d, 0x87, 0xb6, 0xeb, 0x5a, 0x58, 0x36, 0x5b, 0xc0, 0xcc, 0xb0, 0x94, + 0xbc, 0x0f, 0xe7, 0x62, 0x11, 0x18, 0x45, 0x0f, 0x8c, 0x46, 0x7b, 0xaf, 0xbc, 0x87, 0x45, 0x06, + 0x19, 0xbc, 0x4b, 0xd2, 0x29, 0x49, 0x09, 0x0a, 0xcb, 0xe8, 0xa6, 0x55, 0xa1, 0xfc, 0x6d, 0xc8, + 0xf5, 0xb8, 0x7f, 0x1e, 0xbf, 0x35, 0x8b, 0x38, 0x93, 0x8d, 0xb0, 0xd0, 0x4c, 0xa0, 0x93, 0xfb, + 0x30, 0x1b, 0x87, 0xb1, 0x13, 0x9c, 0x5f, 0x90, 0x71, 0xbf, 0x49, 0x70, 0xc1, 0x33, 0x3c, 0x8d, + 0x8a, 0xec, 0xc0, 0x4c, 0x64, 0x90, 0xa4, 0x5f, 0x9b, 0xa5, 0x9d, 0x73, 0x58, 0x2e, 0xaf, 0xce, + 0xcf, 0x8a, 0xc9, 0x38, 0x1b, 0x19, 0x37, 0x85, 0xd7, 0x67, 0x33, 0xc9, 0x8e, 0x34, 0x60, 0xaa, + 0xe6, 0xec, 0xb5, 0x9d, 0xf6, 0xde, 0x7d, 0x7a, 0xb4, 0x61, 0x3b, 0x9e, 0xb0, 0x38, 0x95, 0xf6, + 0xe4, 0x25, 0xff, 0xa8, 0xd5, 0xa2, 0x81, 0x87, 0x1b, 0x21, 0x2b, 0x47, 0x1f, 0x74, 0x76, 0x1d, + 0x5a, 0xf0, 0x39, 0x1d, 0xba, 0x6d, 0x76, 0x6c, 0x47, 0x13, 0x02, 0x74, 0x9e, 0x9a, 0xea, 0x62, + 0x62, 0x40, 0xd5, 0x45, 0x13, 0x66, 0x96, 0xdb, 0x75, 0xef, 0x08, 0x9f, 0xe8, 0xe4, 0xc7, 0x4d, + 0x9e, 0xf2, 0x71, 0x2f, 0x89, 0x8f, 0x7b, 0xce, 0x96, 0x33, 0x2c, 0xed, 0xf3, 0x92, 0x8c, 0x49, + 0x0d, 0x66, 0xf0, 0xe2, 0x50, 0xad, 0x6c, 0x54, 0xdb, 0x4e, 0xe0, 0xd8, 0x01, 0x6d, 0x08, 0xe1, + 0x22, 0xcc, 0xe4, 0xc2, 0xaf, 0xa8, 0x4e, 0xa3, 0x63, 0x39, 0x12, 0x45, 0x65, 0x9a, 0xa0, 0xef, + 0x77, 0x4f, 0x9c, 0xfe, 0x4b, 0xba, 0x27, 0x56, 0x61, 0x3a, 0x1e, 0xca, 0xa1, 0x10, 0x9d, 0xc3, + 0x3e, 0x16, 0xb1, 0xe3, 0xdc, 0xed, 0xa2, 0x30, 0xa9, 0x25, 0x4f, 0x8d, 0x05, 0x71, 0x88, 0x5d, + 0x39, 0x67, 0xb4, 0x2b, 0xa7, 0xb6, 0x2b, 0x9d, 0xe1, 0xca, 0x49, 0x36, 0x00, 0xee, 0xb8, 0x5e, + 0x9d, 0x96, 0xd0, 0x3f, 0x9a, 0x68, 0xf9, 0xae, 0x18, 0xd3, 0xa8, 0x90, 0xaf, 0x9f, 0x5d, 0xf6, + 0xdb, 0x8a, 0xbb, 0xb9, 0x2b, 0x3c, 0x8c, 0x1f, 0xc9, 0xc2, 0x7c, 0xaf, 0xcf, 0xe9, 0x73, 0xdd, + 0xfb, 0x14, 0x24, 0x57, 0xb8, 0xb8, 0xf6, 0x15, 0x68, 0x7c, 0x9d, 0x2f, 0x42, 0xfa, 0x42, 0x16, + 0xd7, 0xc0, 0xd9, 0x38, 0xc1, 0x96, 0xd7, 0x24, 0xb7, 0x61, 0x5c, 0xf9, 0x78, 0xdc, 0x4b, 0x7b, + 0x35, 0xd5, 0x84, 0xdd, 0xf0, 0x6f, 0x76, 0x4d, 0xe4, 0xfb, 0x96, 0xbc, 0x26, 0xf2, 0x5f, 0xa4, + 0xc0, 0x5d, 0xc4, 0x47, 0xb8, 0x15, 0x80, 0xef, 0xbb, 0x84, 0x00, 0xee, 0xdb, 0x7c, 0x0b, 0x34, + 0xf1, 0x6f, 0xe3, 0x37, 0x26, 0xf8, 0x89, 0xac, 0xde, 0x12, 0x7b, 0xd9, 0x07, 0xc7, 0x6e, 0x8f, + 0xd9, 0xb3, 0xdc, 0x1e, 0x73, 0xa7, 0xdf, 0x1e, 0x87, 0x4e, 0xbb, 0x3d, 0xc6, 0xae, 0x77, 0xc3, + 0x67, 0xbe, 0xde, 0x8d, 0x9c, 0xe9, 0x7a, 0x37, 0x7a, 0xa6, 0xeb, 0x9d, 0x76, 0x53, 0xcd, 0x9f, + 0x76, 0x53, 0xfd, 0xeb, 0xcb, 0xe0, 0xd3, 0x7a, 0x19, 0x4c, 0x13, 0xf1, 0xce, 0x74, 0x19, 0xfc, + 0xa1, 0x9e, 0x77, 0xb9, 0xc2, 0x47, 0x11, 0xca, 0x5f, 0x1c, 0xe0, 0x2e, 0x37, 0xe8, 0x4d, 0x6e, + 0xe6, 0xc9, 0xdc, 0xe4, 0xc8, 0x13, 0xbb, 0xc9, 0xcd, 0x7e, 0xdc, 0x9b, 0xdc, 0xdc, 0x93, 0xbc, + 0xc9, 0x9d, 0xfb, 0xab, 0x78, 0x93, 0x3b, 0xff, 0x6f, 0xe7, 0x26, 0xf7, 0x37, 0xa0, 0x10, 0x17, + 0x2e, 0x4f, 0x8f, 0x7a, 0xfc, 0xc4, 0x42, 0x4e, 0x32, 0xd1, 0x37, 0x2e, 0xdc, 0x91, 0x1b, 0x00, + 0x1b, 0x9e, 0xf3, 0xc8, 0x0e, 0xe8, 0x7d, 0x69, 0xfd, 0x26, 0x22, 0x76, 0x73, 0x28, 0x1b, 0x79, + 0x53, 0x41, 0x09, 0xef, 0x35, 0xd9, 0xb4, 0x7b, 0x8d, 0xf1, 0xc3, 0x59, 0x98, 0xe1, 0x71, 0xdb, + 0x9e, 0xfe, 0x47, 0xd8, 0x77, 0xb5, 0xdb, 0xea, 0x73, 0x51, 0x8e, 0x00, 0xb5, 0x75, 0x7d, 0x9e, + 0x61, 0xbf, 0x02, 0xe7, 0x12, 0x5d, 0x81, 0x37, 0xd6, 0x8a, 0x8c, 0x98, 0x97, 0xb8, 0xb3, 0xce, + 0xa7, 0x57, 0xf2, 0xf0, 0x96, 0x99, 0xa0, 0x30, 0xfe, 0x7c, 0x28, 0xc1, 0x5f, 0x3c, 0xc8, 0xaa, + 0x4f, 0xac, 0x99, 0xb3, 0x3d, 0xb1, 0x66, 0x07, 0x7b, 0x62, 0x8d, 0x09, 0x15, 0xb9, 0x41, 0x84, + 0x8a, 0xf7, 0x61, 0x72, 0x93, 0xda, 0x2d, 0x7f, 0xd3, 0x15, 0x09, 0xa7, 0xb8, 0xaf, 0x85, 0x0c, + 0x88, 0xc7, 0xca, 0xe4, 0x85, 0x2b, 0xb4, 0x19, 0x0d, 0x18, 0x01, 0x3b, 0x06, 0x79, 0x06, 0x2a, + 0x53, 0xe7, 0xa0, 0xde, 0xa2, 0x87, 0xfb, 0xdc, 0xa2, 0x6b, 0x30, 0x21, 0xe8, 0xa2, 0x50, 0xcf, + 0xd1, 0x75, 0x8f, 0x15, 0x21, 0x5c, 0xd6, 0x1e, 0x66, 0xc3, 0x0f, 0x6b, 0xe7, 0x37, 0x3d, 0x8d, + 0x09, 0xeb, 0x82, 0xe5, 0x76, 0xa3, 0xe3, 0x3a, 0x6d, 0xec, 0x82, 0xd1, 0xa8, 0x0b, 0xa8, 0x00, + 0xf3, 0x2e, 0x50, 0x90, 0xc8, 0xdb, 0x30, 0x55, 0xda, 0xa8, 0xaa, 0x64, 0xf9, 0xe8, 0x95, 0xd7, + 0xee, 0x38, 0x96, 0x46, 0x1a, 0xc3, 0xed, 0x77, 0xf3, 0x19, 0xfb, 0xcb, 0xb9, 0xf9, 0x18, 0xff, + 0x74, 0x52, 0x2e, 0xef, 0x4f, 0xf6, 0x81, 0x44, 0x7f, 0xf2, 0xc8, 0x9d, 0xf1, 0xc9, 0x63, 0xe8, + 0x34, 0x41, 0x52, 0x93, 0x6f, 0x87, 0xcf, 0x24, 0xdf, 0x8e, 0x7c, 0xec, 0xe7, 0x8b, 0xd1, 0x33, + 0x4a, 0xac, 0xb1, 0xb5, 0x96, 0x1f, 0x64, 0xad, 0xa5, 0x4a, 0xb9, 0x63, 0x1f, 0x5f, 0xca, 0x85, + 0x33, 0x4b, 0xb9, 0xb5, 0xc8, 0x77, 0x79, 0xfc, 0x54, 0x97, 0x90, 0xe7, 0x85, 0x56, 0x60, 0x26, + 0x3d, 0x0a, 0x5f, 0xe8, 0xc5, 0xfc, 0x1d, 0x25, 0x3a, 0x7f, 0x2d, 0x5d, 0x74, 0xee, 0x7f, 0xde, + 0x9c, 0x49, 0x78, 0xfe, 0xe1, 0x27, 0x2b, 0x3c, 0x3f, 0xd9, 0x87, 0x90, 0xbf, 0x16, 0x9f, 0xff, + 0x5a, 0x7c, 0x1e, 0x4c, 0x7c, 0x26, 0xeb, 0x40, 0xec, 0x6e, 0xb0, 0x4f, 0xdb, 0x81, 0x53, 0xc7, + 0xa8, 0xb4, 0x6c, 0x88, 0xf1, 0x55, 0x46, 0xac, 0xd7, 0x64, 0xa9, 0xba, 0x5e, 0xb5, 0x52, 0xf4, + 0xf3, 0xf6, 0x70, 0xbd, 0x6e, 0xdb, 0x5e, 0x1b, 0xf5, 0x58, 0x37, 0x60, 0x54, 0xc6, 0x35, 0xcd, + 0x44, 0x2a, 0xea, 0x64, 0x40, 0x53, 0x89, 0x45, 0x16, 0x21, 0x2f, 0x89, 0xd5, 0x44, 0x3b, 0x87, + 0x02, 0xa6, 0x85, 0x8c, 0x14, 0x30, 0xe3, 0x3f, 0x18, 0x92, 0x67, 0x02, 0xfb, 0x84, 0x0d, 0xdb, + 0xb3, 0x5b, 0x98, 0x83, 0x2f, 0x5c, 0xb2, 0xca, 0x6d, 0x20, 0xb6, 0xca, 0x63, 0xbe, 0x02, 0x3a, + 0xc9, 0x47, 0x0a, 0x4c, 0x1b, 0xa5, 0x39, 0xce, 0x0d, 0x90, 0xe6, 0xf8, 0x4d, 0x2d, 0x47, 0xf0, + 0x50, 0x94, 0x94, 0x92, 0xed, 0x93, 0xfd, 0xb3, 0x03, 0xdf, 0x56, 0x93, 0xf9, 0x0e, 0x47, 0x61, + 0xc2, 0x90, 0xb2, 0x4f, 0x1a, 0xdf, 0xf0, 0x7a, 0x33, 0x72, 0x96, 0x90, 0xcf, 0xa3, 0xff, 0x56, + 0x43, 0x3e, 0x2f, 0x03, 0x88, 0xb3, 0x3b, 0xb2, 0x77, 0x78, 0x19, 0xb7, 0x13, 0x61, 0xf7, 0x1c, + 0x04, 0xcd, 0x1e, 0x39, 0x41, 0x14, 0x42, 0xe3, 0x0f, 0x08, 0xcc, 0xd4, 0x6a, 0xeb, 0x15, 0xc7, + 0xde, 0x6b, 0xbb, 0x7e, 0xe0, 0xd4, 0xab, 0xed, 0x5d, 0x97, 0xc9, 0xf6, 0xe1, 0xf9, 0xa2, 0x04, + 0xeb, 0x8d, 0xce, 0x96, 0xb0, 0x98, 0xdd, 0x1d, 0x97, 0x3d, 0x4f, 0x2a, 0x5c, 0xf9, 0xdd, 0x91, + 0x32, 0x80, 0xc9, 0xe1, 0x4c, 0x7c, 0xae, 0x75, 0x31, 0x54, 0x86, 0x30, 0x42, 0x41, 0xf1, 0xd9, + 0xe7, 0x20, 0x53, 0x96, 0x11, 0x9a, 0x9c, 0xb0, 0xe2, 0x3a, 0x75, 0x41, 0x0b, 0x1c, 0x1d, 0x15, + 0xf3, 0xd5, 0x28, 0xa4, 0x1b, 0xdc, 0x87, 0x3b, 0x08, 0x57, 0x4d, 0xec, 0x12, 0x6b, 0xe0, 0x08, + 0xce, 0x69, 0x4e, 0xd4, 0x83, 0xbe, 0xce, 0xbc, 0x2a, 0xc4, 0x75, 0x03, 0x63, 0x76, 0xa4, 0x3c, + 0xd1, 0xa8, 0x49, 0xf5, 0x52, 0x6b, 0x60, 0x07, 0xe4, 0xf3, 0xa9, 0x25, 0xe1, 0xea, 0x1e, 0xd7, + 0x82, 0x77, 0x2b, 0x9b, 0x06, 0x4f, 0x1f, 0xd8, 0xab, 0x6a, 0x2b, 0x65, 0x2b, 0xe8, 0x5f, 0x13, + 0xf9, 0xcd, 0x0c, 0x5c, 0xd0, 0x30, 0xc2, 0xfd, 0xcf, 0x0f, 0xe3, 0x8b, 0xa4, 0xce, 0xeb, 0x0f, + 0x9f, 0xcc, 0xbc, 0x7e, 0x51, 0x6f, 0x4b, 0xb4, 0x43, 0xab, 0x6d, 0xe8, 0xf5, 0x85, 0xe4, 0x11, + 0xcc, 0x60, 0x91, 0x7c, 0x29, 0x62, 0x73, 0x56, 0x3c, 0x30, 0xcd, 0x45, 0x9f, 0xcd, 0x03, 0x03, + 0x60, 0x0a, 0xf8, 0xc5, 0x6f, 0x1d, 0x17, 0x27, 0x35, 0x74, 0x19, 0x0e, 0xdb, 0x8a, 0x9e, 0x9b, + 0x9c, 0xf6, 0xae, 0xab, 0xe5, 0xf7, 0x8f, 0x57, 0x41, 0xfe, 0xcb, 0x0c, 0x7f, 0x9f, 0xe0, 0xcd, + 0xb8, 0xe3, 0xb9, 0xad, 0xb0, 0x5c, 0xda, 0x6a, 0xf6, 0xe8, 0xb6, 0xe6, 0x93, 0xe9, 0xb6, 0x97, + 0xf1, 0x93, 0xf9, 0x9e, 0x60, 0xed, 0x7a, 0x6e, 0x2b, 0xfa, 0x7c, 0xb5, 0xe3, 0x7a, 0x7e, 0x24, + 0xf9, 0xbe, 0x0c, 0x5c, 0xd4, 0xd4, 0xa4, 0x6a, 0x6e, 0x12, 0x11, 0x7e, 0x61, 0x36, 0x0c, 0xcc, + 0x12, 0x15, 0x2d, 0x5d, 0x17, 0xf3, 0xff, 0x0a, 0x7e, 0x81, 0x12, 0x07, 0x94, 0x21, 0x59, 0x2d, + 0x8e, 0xa5, 0x7c, 0x42, 0xef, 0x5a, 0x88, 0x03, 0x33, 0x68, 0xb6, 0xa3, 0xd9, 0x14, 0xcf, 0xf5, + 0xb6, 0x29, 0x0e, 0xb3, 0x0e, 0x61, 0x46, 0x82, 0xde, 0x86, 0xc5, 0x49, 0xae, 0xe4, 0x7b, 0xe0, + 0x62, 0x02, 0x18, 0xae, 0xb6, 0x73, 0x3d, 0x57, 0xdb, 0xa7, 0x4e, 0x8e, 0x8b, 0xaf, 0xa4, 0xd5, + 0x96, 0xb6, 0xd2, 0x7a, 0xd7, 0x40, 0x6c, 0x80, 0xa8, 0x50, 0xc8, 0x33, 0xe9, 0x13, 0xf4, 0x53, + 0x62, 0x7e, 0x28, 0xf8, 0x6c, 0x2f, 0x57, 0xbe, 0x41, 0x3d, 0xf2, 0x22, 0x24, 0x42, 0x61, 0x42, + 0xc9, 0xc6, 0x70, 0x24, 0xac, 0x47, 0x7a, 0x54, 0xf2, 0xad, 0xe3, 0xa2, 0x86, 0xcd, 0x6e, 0x58, + 0x6a, 0x9a, 0x07, 0x4d, 0x7c, 0x54, 0x11, 0xc9, 0xaf, 0x67, 0x60, 0x8e, 0x01, 0xa2, 0x49, 0x25, + 0x1a, 0x35, 0xdf, 0x6f, 0xd6, 0xef, 0x3f, 0x99, 0x59, 0xff, 0x02, 0x7e, 0xa3, 0x3a, 0xeb, 0x13, + 0x5d, 0x92, 0xfa, 0x71, 0x38, 0xdb, 0x35, 0x0b, 0x31, 0x6d, 0xb6, 0x5f, 0x1c, 0x60, 0xb6, 0xf3, + 0x01, 0x38, 0x7d, 0xb6, 0xf7, 0xac, 0x85, 0x6c, 0xc2, 0x84, 0xb8, 0x5c, 0xf1, 0x0e, 0xbb, 0xa4, + 0xc5, 0x85, 0x56, 0x8b, 0xf8, 0x8d, 0x57, 0x24, 0xab, 0x48, 0xb4, 0x50, 0xe3, 0x42, 0xda, 0x30, + 0xcb, 0x7f, 0xeb, 0xca, 0xae, 0x62, 0x4f, 0x65, 0xd7, 0x55, 0xd1, 0xa2, 0xcb, 0x82, 0x7f, 0x4c, + 0xe7, 0xa5, 0xc6, 0x73, 0x4a, 0x61, 0x4c, 0x3a, 0x40, 0x34, 0x30, 0x5f, 0xb4, 0x97, 0xfb, 0xab, + 0xb8, 0x5e, 0x11, 0x75, 0x16, 0xe3, 0x75, 0xc6, 0x57, 0x6e, 0x0a, 0x6f, 0x62, 0xc3, 0xb4, 0x80, + 0xba, 0x07, 0x94, 0xef, 0xf0, 0x2f, 0x68, 0x11, 0xb5, 0x62, 0xa5, 0xfc, 0x56, 0x26, 0x6b, 0xc2, + 0x88, 0x67, 0xb1, 0x0d, 0x3d, 0xce, 0x8f, 0xac, 0xc3, 0x4c, 0xa9, 0xd3, 0x69, 0x3a, 0xb4, 0x81, + 0xad, 0x34, 0xbb, 0xac, 0x4d, 0x46, 0x94, 0xef, 0xcd, 0xe6, 0x85, 0xe2, 0xaa, 0xe8, 0x75, 0x63, + 0xdb, 0x4d, 0x82, 0xd6, 0xf8, 0xa1, 0x4c, 0xe2, 0xa3, 0xc9, 0x6b, 0x30, 0x86, 0x3f, 0x94, 0x20, + 0x2d, 0xa8, 0x33, 0xe2, 0x9f, 0x88, 0xda, 0xa8, 0x08, 0x81, 0x09, 0x4b, 0x6a, 0xa0, 0xc6, 0x1c, + 0x17, 0x96, 0x84, 0xa2, 0x22, 0x52, 0x4d, 0x14, 0xa5, 0xaf, 0x47, 0x2e, 0x12, 0xba, 0xd0, 0xd7, + 0x43, 0x78, 0x78, 0x18, 0xff, 0x38, 0xab, 0x4f, 0x3b, 0x72, 0x55, 0x91, 0xdb, 0x95, 0x50, 0x91, + 0x52, 0x6e, 0x57, 0xa4, 0xf5, 0x7f, 0x90, 0x81, 0xd9, 0x75, 0x25, 0x51, 0xe8, 0xa6, 0x8b, 0xe3, + 0xd2, 0x3f, 0x75, 0xe6, 0x93, 0x4a, 0x01, 0xa8, 0x66, 0x28, 0x65, 0x33, 0x05, 0xa7, 0x8c, 0x99, + 0xf6, 0x3d, 0xe8, 0x3d, 0x87, 0x1f, 0xa6, 0x64, 0x62, 0xe4, 0xe8, 0x1c, 0x7e, 0xc6, 0xd4, 0x15, + 0xc6, 0x8f, 0x65, 0x61, 0x5c, 0x59, 0x31, 0xe4, 0x33, 0x30, 0xa1, 0x56, 0xab, 0x2a, 0x1c, 0xd5, + 0xaf, 0x34, 0x35, 0x2c, 0xd4, 0x38, 0x52, 0xbb, 0xa5, 0x69, 0x1c, 0xd9, 0xba, 0x40, 0xe8, 0x19, + 0x6f, 0x42, 0xef, 0xa5, 0xdc, 0x84, 0x70, 0x96, 0x2b, 0x1a, 0xa3, 0xbe, 0xf7, 0xa1, 0xb7, 0x93, + 0xf7, 0x21, 0x54, 0x5e, 0x29, 0xf4, 0xbd, 0x6f, 0x45, 0xc6, 0x4f, 0x66, 0xa0, 0x10, 0x5f, 0xd3, + 0x9f, 0x48, 0xaf, 0x9c, 0xe1, 0x75, 0xe9, 0x47, 0xb3, 0x61, 0xe6, 0x16, 0xe9, 0x42, 0xfc, 0xb4, + 0x9a, 0x29, 0xbe, 0xa3, 0x3d, 0xfc, 0x3c, 0xab, 0x47, 0xc3, 0x53, 0x83, 0x6f, 0xa4, 0x87, 0xc0, + 0x1c, 0xfa, 0xb9, 0x5f, 0x2c, 0x3e, 0x63, 0x7c, 0x00, 0x73, 0xf1, 0xee, 0xc0, 0xc7, 0x9f, 0x12, + 0x4c, 0xeb, 0xf0, 0x78, 0xde, 0xa7, 0x38, 0x95, 0x19, 0xc7, 0x37, 0xfe, 0x28, 0x1b, 0xe7, 0x2d, + 0x4c, 0x16, 0xd9, 0x1e, 0xa5, 0x1a, 0xe2, 0x88, 0x3d, 0x8a, 0x83, 0x4c, 0x59, 0x76, 0x96, 0x7c, + 0x6b, 0xa1, 0x23, 0x6c, 0x2e, 0xdd, 0x11, 0x96, 0xdc, 0x8e, 0x59, 0x69, 0x2b, 0x51, 0x9b, 0x0e, + 0xe9, 0x8e, 0x15, 0x59, 0x6a, 0xc7, 0x8c, 0xb3, 0xcb, 0x30, 0xa7, 0x85, 0x20, 0x97, 0xf4, 0xc3, + 0x91, 0xae, 0x3f, 0xc0, 0x02, 0x4e, 0x9c, 0x8a, 0x4c, 0x56, 0x60, 0x94, 0x7d, 0xe6, 0x03, 0xbb, + 0x23, 0xde, 0x74, 0x48, 0xe8, 0x16, 0xdf, 0x0c, 0xef, 0x87, 0x8a, 0x67, 0x7c, 0x93, 0x32, 0x09, + 0x41, 0x9d, 0x58, 0x02, 0xd1, 0xf8, 0x57, 0x19, 0xb6, 0xfe, 0xeb, 0x07, 0xdf, 0x61, 0x49, 0xdb, + 0x58, 0x93, 0xfa, 0x58, 0xd4, 0xfe, 0x49, 0x96, 0xe7, 0xe2, 0x11, 0xd3, 0xe7, 0x4d, 0x18, 0xd9, + 0xb4, 0xbd, 0x3d, 0x91, 0x32, 0x5b, 0xe7, 0xc2, 0x0b, 0xa2, 0x98, 0x52, 0x01, 0xfe, 0x36, 0x05, + 0x81, 0xaa, 0x3a, 0xcb, 0x0e, 0xa4, 0x3a, 0x53, 0xde, 0x05, 0x72, 0x4f, 0xec, 0x5d, 0xe0, 0xbb, + 0xc2, 0xb4, 0x3b, 0xa5, 0x60, 0x80, 0x08, 0xd7, 0x97, 0xe3, 0x59, 0xae, 0x12, 0xb1, 0xc8, 0x23, + 0x76, 0xe4, 0xb6, 0x9a, 0x37, 0x4b, 0xf1, 0x2d, 0x3d, 0x25, 0x43, 0x96, 0xf1, 0x27, 0x39, 0xde, + 0xc7, 0xa2, 0xa3, 0xae, 0x68, 0x7e, 0xe7, 0xb8, 0x4e, 0x62, 0x7a, 0x4a, 0xee, 0x81, 0x7e, 0x05, + 0x86, 0xd8, 0xdc, 0x14, 0xbd, 0x89, 0x78, 0x6c, 0xfe, 0xaa, 0x78, 0xac, 0x9c, 0xad, 0x65, 0x3c, + 0x93, 0xd4, 0x84, 0x88, 0x78, 0x6c, 0xa9, 0x6b, 0x19, 0x31, 0xc8, 0x55, 0x18, 0x5a, 0x73, 0x1b, + 0x32, 0x92, 0xfa, 0x1c, 0x46, 0x1f, 0xd1, 0x32, 0xae, 0xce, 0x67, 0x4c, 0xc4, 0x60, 0x6d, 0x0d, + 0xf3, 0x4f, 0xa8, 0x6d, 0x6d, 0xed, 0xda, 0xc9, 0x44, 0x77, 0x4a, 0xd2, 0x9b, 0x65, 0x98, 0xda, + 0x76, 0xda, 0x0d, 0xf7, 0xd0, 0xaf, 0x50, 0xff, 0x20, 0x70, 0x3b, 0xc2, 0xde, 0x18, 0xb5, 0xfb, + 0x87, 0xbc, 0xc4, 0x6a, 0xf0, 0x22, 0xf5, 0x59, 0x46, 0x27, 0x22, 0x4b, 0x30, 0xa9, 0x45, 0x70, + 0x15, 0x8f, 0xab, 0xa8, 0x0d, 0xd5, 0xe3, 0xbf, 0xaa, 0xda, 0x50, 0x8d, 0x84, 0x9d, 0xe7, 0xe2, + 0xfb, 0x95, 0x27, 0xd6, 0xc4, 0xb7, 0x0b, 0x1c, 0x72, 0x0b, 0xf2, 0x3c, 0xcc, 0x47, 0xb5, 0xa2, + 0x3e, 0x93, 0xf9, 0x08, 0x8b, 0x85, 0xc9, 0x91, 0x88, 0x4a, 0x58, 0x87, 0x4f, 0x43, 0x41, 0x6c, + 0x49, 0x51, 0xae, 0xf6, 0xe7, 0x60, 0xa8, 0x5c, 0xad, 0x98, 0xea, 0x36, 0x52, 0x77, 0x1a, 0x9e, + 0x89, 0x50, 0xf4, 0xea, 0x5b, 0xa3, 0xc1, 0xa1, 0xeb, 0x1d, 0x98, 0xd4, 0x0f, 0x3c, 0x87, 0xe7, + 0xd3, 0xc4, 0x85, 0xf8, 0x19, 0xf2, 0x36, 0x0c, 0xa3, 0xe1, 0x6b, 0xec, 0x64, 0x88, 0xd7, 0xb1, + 0x34, 0x29, 0x26, 0xf0, 0x30, 0x5a, 0xd1, 0x9a, 0x9c, 0x88, 0xbc, 0x09, 0x43, 0x15, 0xda, 0x3e, + 0x8a, 0xa5, 0xfa, 0x4b, 0x10, 0x87, 0x1b, 0x42, 0x83, 0xb6, 0x8f, 0x4c, 0x24, 0x31, 0x7e, 0x32, + 0x0b, 0xe7, 0x52, 0x3e, 0xeb, 0xe1, 0x67, 0x9e, 0xd2, 0x5d, 0x71, 0x49, 0xdb, 0x15, 0xe5, 0xfb, + 0x78, 0xcf, 0x8e, 0x4f, 0xdd, 0x24, 0x7f, 0x3e, 0x03, 0x17, 0xf4, 0x09, 0x2a, 0x2c, 0xdd, 0x1f, + 0xde, 0x22, 0x6f, 0xc1, 0xc8, 0x0a, 0xb5, 0x1b, 0x54, 0xe6, 0xf5, 0x3a, 0x17, 0x06, 0xe4, 0xe3, + 0x31, 0x0c, 0x78, 0x21, 0x67, 0x1b, 0x79, 0xbc, 0x72, 0x28, 0xa9, 0x88, 0x8f, 0xe3, 0xe2, 0xbb, + 0x21, 0xe3, 0x89, 0xa4, 0x55, 0xd5, 0xc7, 0xca, 0xe4, 0x5b, 0x19, 0x78, 0xb6, 0x0f, 0x0d, 0x1b, + 0x38, 0x36, 0xf4, 0xea, 0xc0, 0xe1, 0x89, 0x8a, 0x50, 0xf2, 0x2e, 0x4c, 0x6f, 0x0a, 0xf1, 0x5f, + 0x0e, 0x47, 0x36, 0x5a, 0x2f, 0xf2, 0x66, 0x60, 0xc9, 0x71, 0x89, 0x23, 0x6b, 0x81, 0x6e, 0x72, + 0x7d, 0x03, 0xdd, 0xa8, 0x71, 0x63, 0x86, 0x06, 0x8d, 0x1b, 0xf3, 0x01, 0xcc, 0xe9, 0x6d, 0x13, + 0xe1, 0x7b, 0xa3, 0xa8, 0x39, 0x99, 0xde, 0x51, 0x73, 0xfa, 0x06, 0x09, 0x35, 0x7e, 0x2c, 0x03, + 0x05, 0x9d, 0xf7, 0xc7, 0x1d, 0xcf, 0x77, 0xb4, 0xf1, 0x7c, 0x36, 0x7d, 0x3c, 0x7b, 0x0f, 0xe4, + 0xff, 0x99, 0x89, 0x37, 0x76, 0xa0, 0x11, 0x34, 0x60, 0xa4, 0xe2, 0xb6, 0x6c, 0xa7, 0xad, 0xa6, + 0xfe, 0x6f, 0x20, 0xc4, 0x14, 0x25, 0x83, 0x05, 0x19, 0xba, 0x0c, 0xc3, 0x6b, 0x6e, 0xbb, 0x54, + 0x11, 0x26, 0xc5, 0xc8, 0xa7, 0xed, 0xb6, 0x2d, 0xbb, 0x61, 0xf2, 0x02, 0xb2, 0x0a, 0x50, 0xab, + 0x7b, 0x94, 0xb6, 0x6b, 0xce, 0x77, 0xd3, 0x98, 0xa4, 0xc1, 0x7a, 0xa8, 0xd9, 0xc5, 0x8d, 0x85, + 0x3f, 0x9d, 0x22, 0xa2, 0xe5, 0x3b, 0xdf, 0xad, 0xee, 0xb7, 0x0a, 0x3d, 0xae, 0x2b, 0x11, 0x87, + 0x2d, 0x36, 0x0e, 0x37, 0x3f, 0x89, 0x75, 0x95, 0x5a, 0x15, 0xf6, 0xf0, 0xcd, 0xd4, 0xe1, 0xf8, + 0xc3, 0x0c, 0x3c, 0xdb, 0x87, 0xe6, 0x09, 0x8c, 0xca, 0x5f, 0x76, 0x87, 0x53, 0x80, 0x88, 0x08, + 0x33, 0x29, 0x3b, 0x8d, 0x80, 0xe7, 0xea, 0x9b, 0x14, 0x99, 0x94, 0x19, 0x40, 0xcb, 0xa4, 0xcc, + 0x00, 0xec, 0x2c, 0x5d, 0xa1, 0xce, 0xde, 0x3e, 0x37, 0x0f, 0x9b, 0xe4, 0x7b, 0xc3, 0x3e, 0x42, + 0xd4, 0xb3, 0x94, 0xe3, 0x18, 0xff, 0x7a, 0x18, 0x2e, 0x9a, 0x74, 0xcf, 0x61, 0xf7, 0x92, 0x2d, + 0xdf, 0x69, 0xef, 0x69, 0x71, 0x77, 0x8c, 0xd8, 0xca, 0x15, 0x49, 0x2a, 0x18, 0x24, 0x9c, 0x89, + 0xd7, 0x20, 0xcf, 0xc4, 0x10, 0x65, 0xf1, 0xe2, 0x1b, 0x17, 0x13, 0x56, 0x44, 0x60, 0x67, 0x59, + 0x4c, 0x5e, 0x15, 0x62, 0x92, 0x92, 0x46, 0x88, 0x89, 0x49, 0xdf, 0x3e, 0x2e, 0x42, 0xed, 0xc8, + 0x0f, 0x28, 0x5e, 0x91, 0x85, 0xa8, 0x14, 0xde, 0x65, 0x86, 0x7a, 0xdc, 0x65, 0x1e, 0xc0, 0x5c, + 0xa9, 0xc1, 0x4f, 0x47, 0xbb, 0xb9, 0xe1, 0x39, 0xed, 0xba, 0xd3, 0xb1, 0x9b, 0xf2, 0x7e, 0x8e, + 0xbd, 0x6c, 0x87, 0xe5, 0x56, 0x27, 0x44, 0x30, 0x53, 0xc9, 0x58, 0x33, 0x2a, 0x6b, 0x35, 0x0c, + 0x4f, 0x23, 0x9e, 0x2f, 0xb1, 0x19, 0x8d, 0xb6, 0x8f, 0xad, 0xf0, 0xcd, 0xb0, 0x18, 0x6f, 0x51, + 0x68, 0x10, 0xb0, 0xb9, 0x5a, 0x8b, 0x5c, 0xaa, 0x79, 0x96, 0x03, 0x6e, 0x58, 0x10, 0x34, 0x7d, + 0x34, 0xc5, 0xd4, 0xf0, 0x22, 0xba, 0x5a, 0x6d, 0x85, 0xd1, 0xe5, 0x13, 0x74, 0xbe, 0xbf, 0xaf, + 0xd2, 0x71, 0x3c, 0x72, 0x83, 0x4d, 0x85, 0x96, 0x1b, 0x50, 0x9c, 0xc2, 0x63, 0xd1, 0x9d, 0xcb, + 0x43, 0x28, 0xbf, 0x73, 0x29, 0x28, 0xe4, 0x6d, 0x98, 0x5d, 0x2e, 0x2f, 0x4a, 0xa5, 0x73, 0xc5, + 0xad, 0x77, 0xd1, 0x10, 0x00, 0xb0, 0x3e, 0x1c, 0x43, 0x5a, 0x5f, 0x64, 0xbb, 0x49, 0x1a, 0x1a, + 0xb9, 0x02, 0xa3, 0xd5, 0x0a, 0xef, 0xfb, 0x71, 0x35, 0x95, 0x97, 0xb0, 0xcc, 0x92, 0x85, 0x64, + 0x3d, 0xba, 0x14, 0x4c, 0x9c, 0x2a, 0xbd, 0x5f, 0x1c, 0xe0, 0x42, 0xf0, 0x26, 0x4c, 0x2e, 0xb9, + 0x41, 0xb5, 0xed, 0x07, 0x76, 0xbb, 0x4e, 0xab, 0x15, 0x35, 0xae, 0xf6, 0x8e, 0x1b, 0x58, 0x8e, + 0x28, 0x61, 0x5f, 0xae, 0x63, 0x92, 0xcf, 0x21, 0xe9, 0x5d, 0xda, 0xa6, 0x5e, 0x14, 0x4f, 0x7b, + 0x98, 0xf7, 0x2d, 0x23, 0xdd, 0x0b, 0x4b, 0x4c, 0x1d, 0x51, 0xa4, 0x19, 0xe3, 0xc9, 0x41, 0xcb, + 0x6e, 0x83, 0xfa, 0x7c, 0xb7, 0xf8, 0x0e, 0x4a, 0x33, 0xa6, 0xb4, 0xad, 0xcf, 0x0e, 0xfa, 0xef, + 0x62, 0x9a, 0xb1, 0x04, 0x2e, 0xf9, 0x1c, 0x0c, 0xe3, 0x4f, 0x21, 0xdd, 0xce, 0xa6, 0xb0, 0x8d, + 0x24, 0xdb, 0x3a, 0xc3, 0x34, 0x39, 0x01, 0xa9, 0xc2, 0xa8, 0xb8, 0x58, 0x9d, 0x25, 0x59, 0x8e, + 0xb8, 0xa1, 0xf1, 0x99, 0x21, 0xe8, 0x8d, 0x06, 0x4c, 0xa8, 0x15, 0xb2, 0x15, 0xb1, 0x62, 0xfb, + 0xfb, 0xb4, 0xc1, 0x7e, 0x89, 0x3c, 0x77, 0xb8, 0x22, 0xf6, 0x11, 0x6a, 0xb1, 0xef, 0x30, 0x15, + 0x14, 0x76, 0xa6, 0x56, 0xfd, 0x2d, 0x5f, 0x7c, 0x8a, 0x50, 0xb5, 0x38, 0xa8, 0xb6, 0x6b, 0x98, + 0xa2, 0xc8, 0xf8, 0x2e, 0x98, 0x5b, 0xeb, 0x36, 0x9b, 0xf6, 0x4e, 0x93, 0xca, 0x3c, 0x28, 0x98, + 0x70, 0x7c, 0x09, 0x86, 0x6b, 0x4a, 0x0a, 0xf3, 0x30, 0x17, 0xa5, 0x82, 0x83, 0x46, 0xb0, 0x19, + 0x0c, 0x15, 0x14, 0x4b, 0x5e, 0xce, 0x49, 0x8d, 0xdf, 0xcf, 0xc0, 0x9c, 0x34, 0x17, 0xf0, 0xec, + 0xfa, 0x41, 0x98, 0xc7, 0xfe, 0x8a, 0x36, 0xd7, 0x70, 0xc2, 0xc6, 0xa6, 0x11, 0x9f, 0x75, 0xf7, + 0xe4, 0x47, 0xe8, 0x02, 0x4b, 0xda, 0x07, 0x9f, 0xf6, 0x31, 0xe4, 0x6d, 0x18, 0x17, 0xc7, 0xa3, + 0x12, 0xe0, 0x12, 0xa3, 0x88, 0x89, 0xeb, 0x5e, 0xdc, 0x78, 0x45, 0x45, 0x47, 0x59, 0x4c, 0x6f, + 0xca, 0xc7, 0x95, 0x01, 0xd2, 0x65, 0x31, 0xbd, 0x8e, 0x3e, 0x53, 0xf7, 0xb7, 0xc7, 0xe3, 0x7d, + 0x2b, 0xe6, 0xee, 0x6d, 0x35, 0xa4, 0x5d, 0x26, 0xba, 0x19, 0x47, 0x21, 0xed, 0xd4, 0x9b, 0x71, + 0x88, 0x1a, 0x8e, 0x49, 0xf6, 0x94, 0x31, 0x79, 0x57, 0x8e, 0x49, 0xae, 0xf7, 0xc4, 0x98, 0xed, + 0x33, 0x0e, 0xb5, 0x68, 0x85, 0x0c, 0x0d, 0xa4, 0x56, 0x79, 0x06, 0x63, 0xf7, 0x73, 0x92, 0xf8, + 0x2e, 0x2a, 0x38, 0xa9, 0xba, 0x9a, 0xe1, 0xc1, 0x99, 0x9e, 0xb2, 0x35, 0x7f, 0x1e, 0x26, 0x4a, + 0x41, 0x60, 0xd7, 0xf7, 0x69, 0xa3, 0xc2, 0xb6, 0x27, 0x25, 0xfa, 0x96, 0x2d, 0xe0, 0xea, 0x1b, + 0x9b, 0x8a, 0xcb, 0xa3, 0xc9, 0xda, 0xbe, 0x30, 0xa6, 0x0d, 0xa3, 0xc9, 0x32, 0x88, 0x1e, 0x4d, + 0x96, 0x41, 0xc8, 0x0d, 0x18, 0xad, 0xb6, 0x1f, 0x39, 0xac, 0x4f, 0x78, 0x00, 0x2e, 0xd4, 0x4d, + 0x39, 0x1c, 0xa4, 0x6e, 0xae, 0x02, 0x8b, 0xbc, 0xa9, 0x5c, 0x6a, 0xc6, 0x22, 0x05, 0x06, 0x57, + 0x79, 0x85, 0x11, 0x76, 0xd4, 0x0b, 0x4b, 0x78, 0xcb, 0xb9, 0x0d, 0xa3, 0x52, 0x93, 0x09, 0x91, + 0xd2, 0x42, 0x50, 0x26, 0x03, 0x56, 0x48, 0x64, 0xcc, 0x49, 0xae, 0xe4, 0xeb, 0x1b, 0x57, 0x72, + 0x92, 0x2b, 0xf9, 0xfa, 0xb4, 0x9c, 0xe4, 0x4a, 0xe6, 0xbe, 0x50, 0x09, 0x34, 0x71, 0xaa, 0x12, + 0xe8, 0x21, 0x4c, 0x6c, 0xd8, 0x5e, 0xe0, 0x30, 0x19, 0xa5, 0x1d, 0xf8, 0xf3, 0x93, 0x9a, 0xde, + 0x54, 0x29, 0x5a, 0xba, 0x24, 0xf3, 0x62, 0x77, 0x14, 0x7c, 0x3d, 0x81, 0x73, 0x04, 0x4f, 0x37, + 0xa5, 0x9d, 0xfa, 0x38, 0xa6, 0xb4, 0xd8, 0xa9, 0xa8, 0x2b, 0x9b, 0x8e, 0x34, 0x32, 0x78, 0x69, + 0x89, 0x29, 0xcc, 0x42, 0x44, 0xf2, 0x65, 0x98, 0x60, 0x7f, 0x6f, 0xb8, 0x4d, 0xa7, 0xee, 0x50, + 0x7f, 0xbe, 0x80, 0x8d, 0xbb, 0x94, 0xba, 0xfa, 0x11, 0xe9, 0xa8, 0x46, 0x03, 0xbe, 0x80, 0x91, + 0x71, 0x5c, 0x09, 0xae, 0x71, 0x23, 0xef, 0xc1, 0x04, 0x9b, 0x7d, 0x3b, 0xb6, 0xcf, 0x45, 0xd3, + 0x99, 0xc8, 0x18, 0xba, 0x21, 0xe0, 0x89, 0x80, 0xce, 0x2a, 0x01, 0x3b, 0xe6, 0x4b, 0x1d, 0xbe, + 0x41, 0x12, 0x65, 0xb6, 0x77, 0x12, 0x9b, 0xa3, 0x44, 0x23, 0x5f, 0x80, 0x89, 0x52, 0xa7, 0x13, + 0xed, 0x38, 0xb3, 0x8a, 0x22, 0xac, 0xd3, 0xb1, 0x52, 0x77, 0x1d, 0x8d, 0x22, 0xbe, 0x31, 0xcf, + 0x9d, 0x69, 0x63, 0x26, 0xaf, 0x87, 0xd2, 0xfa, 0xb9, 0x48, 0xab, 0x2b, 0x2e, 0x8e, 0x9a, 0xe8, + 0xcf, 0x05, 0xf7, 0x32, 0x4c, 0x72, 0x35, 0xa7, 0x94, 0x66, 0xce, 0x27, 0x56, 0x4f, 0x8a, 0x50, + 0xa3, 0xd3, 0x90, 0x65, 0x98, 0xe2, 0xde, 0xde, 0x4d, 0x11, 0x69, 0x7b, 0xfe, 0x02, 0xae, 0x5a, + 0xe4, 0xc2, 0x9d, 0xc4, 0x9b, 0x98, 0x80, 0xc5, 0xd6, 0xb8, 0xc4, 0x88, 0x8c, 0x3f, 0xcd, 0xc0, + 0x85, 0x1e, 0x23, 0x1e, 0xc6, 0x61, 0xce, 0xf4, 0x8f, 0xc3, 0xcc, 0x76, 0x0e, 0x5d, 0x2b, 0x82, + 0xed, 0x17, 0x52, 0x96, 0x3a, 0x5e, 0x52, 0xde, 0x72, 0x81, 0x88, 0x1c, 0x47, 0xa2, 0xea, 0x7b, + 0x2e, 0xaa, 0x66, 0x73, 0xc9, 0x43, 0x48, 0xe0, 0xf1, 0x8f, 0x5a, 0x32, 0x4e, 0x8e, 0x8b, 0x97, + 0x44, 0x0a, 0xa5, 0x70, 0x58, 0x3f, 0x74, 0xb5, 0x15, 0x9c, 0xc2, 0xda, 0x38, 0xce, 0xc0, 0xb8, + 0xb2, 0x0e, 0xc9, 0x65, 0xc5, 0x0b, 0xb9, 0xc0, 0x93, 0x70, 0x29, 0x1c, 0xb2, 0xfc, 0x24, 0xc2, + 0x45, 0x95, 0x3d, 0x5d, 0x01, 0xfd, 0x80, 0x89, 0x42, 0x4a, 0xac, 0xea, 0x96, 0xa6, 0x2d, 0x36, + 0xb1, 0x1c, 0xd3, 0xf9, 0xdb, 0x7e, 0x50, 0xaa, 0x07, 0xce, 0x23, 0x3a, 0xc0, 0xa1, 0x13, 0xa5, + 0xf3, 0xb7, 0xfd, 0xc0, 0xb2, 0x91, 0x2c, 0x91, 0xce, 0x3f, 0x64, 0x68, 0x7c, 0x7f, 0x06, 0x60, + 0xab, 0x5a, 0xc6, 0x60, 0xf3, 0x1f, 0x57, 0x28, 0x48, 0x0f, 0xe0, 0x2b, 0xb9, 0xf7, 0x11, 0x07, + 0xfe, 0x87, 0x0c, 0x4c, 0xe9, 0x68, 0xe4, 0x5d, 0x98, 0xae, 0xd5, 0x3d, 0xb7, 0xd9, 0xdc, 0xb1, + 0xeb, 0x07, 0xab, 0x4e, 0x9b, 0xf2, 0xd0, 0xa9, 0xc3, 0xfc, 0x2c, 0xf2, 0xc3, 0x22, 0xab, 0xc9, + 0xca, 0xcc, 0x38, 0x32, 0xf9, 0x81, 0x0c, 0x4c, 0xd6, 0xf6, 0xdd, 0xc3, 0x30, 0xda, 0xa9, 0x18, + 0x90, 0xaf, 0xb0, 0xb5, 0xed, 0xef, 0xbb, 0x87, 0x51, 0x06, 0x4f, 0xcd, 0x56, 0xf4, 0x9d, 0xc1, + 0x9e, 0xf1, 0xeb, 0x2e, 0xde, 0x64, 0x02, 0xff, 0xba, 0x56, 0x89, 0xa9, 0xd7, 0x69, 0xfc, 0x45, + 0x06, 0xc6, 0xf1, 0xce, 0xd3, 0x6c, 0xa2, 0xcc, 0xf5, 0x9d, 0x94, 0x0e, 0x32, 0x6c, 0x57, 0x9f, + 0x81, 0x7d, 0x03, 0xa6, 0x63, 0x68, 0xc4, 0x80, 0x91, 0x1a, 0x06, 0x18, 0x50, 0x15, 0x14, 0x3c, + 0xe4, 0x80, 0x29, 0x4a, 0x8c, 0x65, 0x85, 0xec, 0xe1, 0x4d, 0x7c, 0xd6, 0x5d, 0x04, 0x70, 0x24, + 0x48, 0xde, 0x6c, 0x48, 0xfc, 0x4b, 0x1e, 0xde, 0x34, 0x15, 0x2c, 0x63, 0x0d, 0x46, 0x6a, 0xae, + 0x17, 0x2c, 0x1d, 0xf1, 0xcb, 0x44, 0x85, 0xfa, 0x75, 0xf5, 0xdd, 0xd6, 0xc1, 0xb7, 0x92, 0xba, + 0x29, 0x8a, 0x48, 0x11, 0x86, 0xef, 0x38, 0xb4, 0xd9, 0x50, 0xed, 0x79, 0x77, 0x19, 0xc0, 0xe4, + 0x70, 0x76, 0xe1, 0x3a, 0x1f, 0xe5, 0x64, 0x89, 0x0c, 0x87, 0x3f, 0xee, 0xba, 0x29, 0x6b, 0xfd, + 0xfb, 0x42, 0x98, 0x07, 0x21, 0x59, 0x53, 0x9f, 0xae, 0xfe, 0xc7, 0x19, 0x58, 0xe8, 0x4d, 0xa2, + 0xda, 0x22, 0x67, 0xfa, 0xd8, 0x22, 0xbf, 0x1c, 0x7f, 0x67, 0x44, 0x34, 0xf1, 0xce, 0x18, 0xbd, + 0x2e, 0x56, 0xd0, 0x14, 0xbc, 0x4e, 0x65, 0x22, 0x96, 0xcb, 0x7d, 0xbe, 0x19, 0x11, 0xf9, 0x30, + 0x07, 0x48, 0x63, 0x0a, 0x5a, 0xe3, 0xb7, 0x86, 0xe0, 0x62, 0x4f, 0x0a, 0xb2, 0xa2, 0xa4, 0x77, + 0x9a, 0x0a, 0x13, 0xcb, 0xf4, 0xc4, 0xbf, 0x8e, 0xff, 0xa2, 0xb5, 0x5f, 0xdc, 0xdb, 0x6d, 0x3d, + 0x4c, 0xeb, 0x93, 0x45, 0x5e, 0x9f, 0x3a, 0x95, 0x17, 0x47, 0x47, 0x66, 0x90, 0xcc, 0xf0, 0x83, + 0x7e, 0x91, 0x34, 0xb0, 0x9d, 0xa6, 0xaf, 0x2e, 0xbb, 0x06, 0x07, 0x99, 0xb2, 0x2c, 0x32, 0x10, + 0x1f, 0x4a, 0x37, 0x10, 0x37, 0xfe, 0x75, 0x06, 0xc6, 0xc2, 0xcf, 0x26, 0x0b, 0x70, 0x7e, 0xd3, + 0x2c, 0x95, 0x97, 0xad, 0xcd, 0x0f, 0x36, 0x96, 0xad, 0xad, 0xb5, 0xda, 0xc6, 0x72, 0xb9, 0x7a, + 0xa7, 0xba, 0x5c, 0x29, 0x3c, 0x43, 0x66, 0x60, 0x72, 0x6b, 0xed, 0xfe, 0xda, 0xfa, 0xf6, 0x9a, + 0xb5, 0x6c, 0x9a, 0xeb, 0x66, 0x21, 0x43, 0x26, 0x61, 0xcc, 0x5c, 0x2a, 0x95, 0xad, 0xb5, 0xf5, + 0xca, 0x72, 0x21, 0x4b, 0x0a, 0x30, 0x51, 0x5e, 0x5f, 0x5b, 0x5b, 0x2e, 0x6f, 0x56, 0x1f, 0x56, + 0x37, 0x3f, 0x28, 0xe4, 0x08, 0x81, 0x29, 0x44, 0xd8, 0x30, 0xab, 0x6b, 0xe5, 0xea, 0x46, 0x69, + 0xb5, 0x30, 0xc4, 0x60, 0x0c, 0x5f, 0x81, 0x0d, 0x87, 0x8c, 0xee, 0x6f, 0x2d, 0x2d, 0x17, 0x46, + 0x18, 0x0a, 0xfb, 0x4b, 0x41, 0x19, 0x65, 0xd5, 0x23, 0x4a, 0xa5, 0xb4, 0x59, 0x5a, 0x2a, 0xd5, + 0x96, 0x0b, 0x79, 0x72, 0x01, 0x66, 0x35, 0x90, 0xb5, 0xba, 0x7e, 0xb7, 0xba, 0x56, 0x18, 0x23, + 0x73, 0x50, 0x08, 0x61, 0x95, 0x25, 0x6b, 0xab, 0xb6, 0x6c, 0x16, 0x20, 0x0e, 0x5d, 0x2b, 0x3d, + 0x58, 0x2e, 0x8c, 0x1b, 0xef, 0x70, 0x3f, 0x44, 0xde, 0xd5, 0xe4, 0x3c, 0x90, 0xda, 0x66, 0x69, + 0x73, 0xab, 0x16, 0x6b, 0xfc, 0x38, 0x8c, 0xd6, 0xb6, 0xca, 0xe5, 0xe5, 0x5a, 0xad, 0x90, 0x21, + 0x00, 0x23, 0x77, 0x4a, 0xd5, 0xd5, 0xe5, 0x4a, 0x21, 0x6b, 0xfc, 0x44, 0x06, 0x66, 0xa4, 0x04, + 0x28, 0x1f, 0x8d, 0x3e, 0xe6, 0x5a, 0x7c, 0x57, 0xbb, 0xd8, 0x4a, 0x27, 0xb1, 0x58, 0x25, 0x7d, + 0x96, 0xe1, 0xcf, 0x67, 0xe0, 0x5c, 0x2a, 0x36, 0xf9, 0x00, 0x0a, 0xf2, 0x0b, 0x1e, 0xd8, 0x41, + 0x7d, 0x3f, 0xda, 0xc7, 0x2e, 0xc5, 0x6a, 0x89, 0xa1, 0x71, 0xb5, 0x66, 0x94, 0x70, 0x3a, 0xc1, + 0x66, 0xf0, 0x74, 0x08, 0xc6, 0xcf, 0x65, 0xe0, 0x42, 0x8f, 0x6a, 0x48, 0x19, 0x46, 0xc2, 0xc4, + 0x38, 0x7d, 0x0c, 0xde, 0xe6, 0xbe, 0x75, 0x5c, 0x14, 0x88, 0x98, 0xa1, 0x17, 0xff, 0x32, 0x47, + 0xc2, 0x4c, 0x37, 0x98, 0x6e, 0x86, 0x77, 0xdf, 0xc5, 0x58, 0xcf, 0x8b, 0x9a, 0x4a, 0xdb, 0xb5, + 0xa5, 0x71, 0xd1, 0x77, 0x39, 0xfb, 0xd0, 0xc7, 0x7c, 0x33, 0xc6, 0x4f, 0x67, 0x98, 0x70, 0x17, + 0x47, 0x64, 0x32, 0x6f, 0xc9, 0xf7, 0xbb, 0x2d, 0x6a, 0xba, 0x4d, 0x5a, 0x32, 0xd7, 0xc4, 0xb1, + 0x81, 0xd2, 0xaa, 0x8d, 0x05, 0x78, 0xad, 0xb0, 0x6c, 0xaf, 0xad, 0xbd, 0x56, 0xab, 0x34, 0xe4, + 0x4d, 0x80, 0xe5, 0xc7, 0x01, 0xf5, 0xda, 0x76, 0x33, 0x8c, 0x11, 0xc3, 0x23, 0x5b, 0x09, 0xa8, + 0x2e, 0x6f, 0x2b, 0xc8, 0xc6, 0xdf, 0xca, 0xc0, 0x84, 0xb8, 0x34, 0x95, 0x9a, 0xd4, 0x0b, 0x3e, + 0xde, 0xf4, 0x7a, 0x53, 0x9b, 0x5e, 0xa1, 0x7f, 0x87, 0xc2, 0x9f, 0x15, 0xa7, 0xce, 0xac, 0x7f, + 0x96, 0x81, 0x42, 0x1c, 0x91, 0xbc, 0x0b, 0xf9, 0x1a, 0x7d, 0x44, 0x3d, 0x27, 0x38, 0x12, 0x1b, + 0xa5, 0x4c, 0x21, 0xc8, 0x71, 0x44, 0x19, 0x9f, 0x0f, 0xbe, 0xf8, 0x65, 0x86, 0x34, 0x83, 0xee, + 0xf7, 0x8a, 0xda, 0x23, 0xf7, 0xa4, 0xd4, 0x1e, 0xc6, 0xff, 0x9a, 0x85, 0x0b, 0x77, 0x69, 0xa0, + 0xb6, 0x29, 0x34, 0x2f, 0xf8, 0xf4, 0x60, 0xed, 0x52, 0x5a, 0x32, 0x0f, 0xa3, 0x58, 0x24, 0xc7, + 0xd7, 0x94, 0x3f, 0xc9, 0x52, 0x38, 0xaf, 0x73, 0x5a, 0x8e, 0xb2, 0x1e, 0x75, 0x5f, 0x57, 0xb2, + 0x16, 0x85, 0xd3, 0xfa, 0x0a, 0x4c, 0x61, 0x58, 0xfe, 0x2e, 0x5b, 0x0e, 0xb4, 0x21, 0xd4, 0x3f, + 0x79, 0x33, 0x06, 0x25, 0xaf, 0x42, 0x81, 0x41, 0x4a, 0xf5, 0x83, 0xb6, 0x7b, 0xd8, 0xa4, 0x8d, + 0x3d, 0xda, 0xc0, 0x63, 0x3d, 0x6f, 0x26, 0xe0, 0x92, 0xe7, 0x56, 0x9b, 0x5f, 0xdd, 0x68, 0x03, + 0x75, 0x34, 0x82, 0x67, 0x04, 0x5d, 0x78, 0x13, 0xc6, 0x3f, 0x62, 0x06, 0x32, 0xe3, 0x7f, 0xce, + 0xc0, 0x1c, 0x36, 0x4e, 0xa9, 0x58, 0x66, 0x87, 0x95, 0xbd, 0xa5, 0x24, 0xe5, 0xb1, 0x19, 0x48, + 0x5f, 0x0a, 0x61, 0x2f, 0x46, 0x3a, 0xa1, 0xec, 0x00, 0x3a, 0xa1, 0xda, 0x59, 0x32, 0xe1, 0x0f, + 0xa8, 0xd2, 0xba, 0x37, 0x94, 0xcf, 0x15, 0x86, 0xa2, 0x21, 0x37, 0x7e, 0x20, 0x0b, 0xa3, 0x26, + 0xc5, 0x14, 0xe1, 0xe4, 0x0a, 0x8c, 0xae, 0xb9, 0x01, 0xf5, 0x1f, 0x68, 0xf9, 0xe0, 0xdb, 0x0c, + 0x64, 0xb5, 0x1a, 0xa6, 0x2c, 0x64, 0x13, 0x7e, 0xc3, 0x73, 0x1b, 0xdd, 0x7a, 0xa0, 0x4e, 0xf8, + 0x0e, 0x07, 0x99, 0xb2, 0x8c, 0xbc, 0x06, 0x63, 0x82, 0x73, 0xf8, 0xa8, 0x8b, 0xb6, 0xcb, 0x1e, + 0x0d, 0x53, 0xcc, 0x47, 0x08, 0x28, 0xd3, 0x72, 0x01, 0x63, 0x48, 0x91, 0x69, 0x13, 0x32, 0x83, + 0x14, 0xd5, 0x87, 0xfb, 0x88, 0xea, 0x9f, 0x86, 0x91, 0x92, 0xef, 0xd3, 0x40, 0x46, 0x51, 0x98, + 0x08, 0xc3, 0xc6, 0xf9, 0x34, 0xe0, 0x8c, 0x6d, 0x2c, 0x37, 0x05, 0x9e, 0xf1, 0xaf, 0xb2, 0x30, + 0x8c, 0x7f, 0xe2, 0x93, 0xa9, 0x57, 0xdf, 0xd7, 0x9e, 0x4c, 0xbd, 0xfa, 0xbe, 0x89, 0x50, 0x72, + 0x13, 0x35, 0x15, 0x32, 0x7f, 0x94, 0x68, 0x3d, 0xaa, 0xe0, 0x1b, 0x11, 0xd8, 0x54, 0x71, 0xc2, + 0x17, 0xfe, 0x5c, 0x6a, 0xec, 0x94, 0xf3, 0x90, 0x5d, 0xaf, 0x89, 0x16, 0x63, 0x44, 0x2e, 0xd7, + 0x37, 0xb3, 0xeb, 0x35, 0xec, 0x8d, 0x95, 0xd2, 0xe2, 0x1b, 0xb7, 0x45, 0x43, 0x79, 0x6f, 0xec, + 0xdb, 0x8b, 0x6f, 0xdc, 0x36, 0x45, 0x09, 0xeb, 0x5f, 0xfc, 0x66, 0x7c, 0x78, 0xe5, 0x3e, 0xff, + 0xd8, 0xbf, 0xd8, 0x36, 0x7c, 0x64, 0x35, 0x23, 0x04, 0xb2, 0x08, 0xe3, 0x22, 0xd6, 0x04, 0xe2, + 0x2b, 0xb1, 0x20, 0x44, 0x2c, 0x0a, 0x4e, 0xa1, 0x22, 0xf1, 0x27, 0x38, 0x31, 0x40, 0x32, 0xcb, + 0xad, 0x78, 0x82, 0x93, 0x43, 0xe8, 0x9b, 0x0a, 0x0a, 0xfb, 0x24, 0xfe, 0x86, 0x17, 0xf9, 0xf2, + 0x4f, 0x29, 0x41, 0x0b, 0x30, 0xcd, 0x42, 0x88, 0x60, 0xfc, 0x72, 0x16, 0xf2, 0x1b, 0xcd, 0xee, + 0x9e, 0xd3, 0x7e, 0x78, 0x93, 0x10, 0xc0, 0x6b, 0x9c, 0xcc, 0xc3, 0xc1, 0xfe, 0x26, 0x17, 0x21, + 0x2f, 0x6f, 0x6e, 0x72, 0x43, 0xf2, 0xc5, 0xad, 0x6d, 0x1e, 0xe4, 0xb8, 0x8b, 0xd0, 0x6b, 0xf2, + 0x27, 0xb9, 0x09, 0xe1, 0xfd, 0xab, 0xd7, 0x45, 0x6d, 0x88, 0x2d, 0x16, 0x33, 0x44, 0x23, 0xaf, + 0x03, 0x1e, 0x12, 0xe2, 0xf2, 0x20, 0x15, 0xda, 0xfc, 0xd3, 0x84, 0x9c, 0xc2, 0x49, 0x10, 0x8d, + 0xdc, 0x02, 0x31, 0x31, 0x45, 0x36, 0xf5, 0x73, 0x3a, 0x01, 0xcf, 0x4f, 0x29, 0x49, 0x04, 0x2a, + 0x79, 0x1b, 0xc6, 0xeb, 0x1e, 0xc5, 0x57, 0x47, 0xbb, 0x19, 0x25, 0x49, 0x57, 0x29, 0xcb, 0x51, + 0xf9, 0xc3, 0x9b, 0xa6, 0x8a, 0x6e, 0xfc, 0x2f, 0x79, 0x98, 0x50, 0xbf, 0x87, 0x98, 0x30, 0xeb, + 0x37, 0xd9, 0xdd, 0x5d, 0x18, 0x9b, 0x75, 0xb0, 0x50, 0x1c, 0xa7, 0x97, 0xf5, 0x0f, 0x62, 0x78, + 0xdc, 0xf2, 0x4c, 0x06, 0xc9, 0x58, 0x79, 0xc6, 0x9c, 0xf1, 0x23, 0x30, 0xc7, 0x23, 0x25, 0xc8, + 0xbb, 0x1d, 0x7f, 0x8f, 0xb6, 0x1d, 0xf9, 0xde, 0xf2, 0xa2, 0xc6, 0x68, 0x5d, 0x14, 0x26, 0x78, + 0x85, 0x64, 0xe4, 0x0d, 0x18, 0x71, 0x3b, 0xb4, 0x6d, 0x3b, 0xe2, 0x8c, 0x7b, 0x36, 0xc6, 0x80, + 0xb6, 0x4b, 0x55, 0x85, 0x50, 0x20, 0x93, 0x1b, 0x30, 0xe4, 0x1e, 0x84, 0xe3, 0x75, 0x51, 0x27, + 0x3a, 0x08, 0x6c, 0x85, 0x04, 0x11, 0x19, 0xc1, 0x87, 0x76, 0x6b, 0x57, 0x8c, 0x98, 0x4e, 0x70, + 0xcf, 0x6e, 0xed, 0xaa, 0x04, 0x0c, 0x91, 0xbc, 0x07, 0xd0, 0xb1, 0xf7, 0xa8, 0x67, 0x35, 0xba, + 0xc1, 0x91, 0x18, 0xb7, 0x4b, 0x1a, 0xd9, 0x06, 0x2b, 0xae, 0x74, 0x83, 0x23, 0x85, 0x76, 0xac, + 0x23, 0x81, 0xa4, 0x04, 0xd0, 0xb2, 0x83, 0x80, 0x7a, 0x2d, 0x57, 0x58, 0xfb, 0x45, 0x41, 0x10, + 0x39, 0x83, 0x07, 0x61, 0xb1, 0xc2, 0x41, 0x21, 0xc2, 0x8f, 0x76, 0x3c, 0x5b, 0xe4, 0xb4, 0x8f, + 0x7d, 0xb4, 0xe3, 0x69, 0xad, 0x64, 0x88, 0xe4, 0x73, 0x30, 0xda, 0x70, 0xfc, 0xba, 0xeb, 0x35, + 0x44, 0xf4, 0x94, 0xe7, 0x34, 0x9a, 0x0a, 0x2f, 0x53, 0xc8, 0x24, 0x3a, 0xfb, 0x5a, 0x11, 0x04, + 0x75, 0xcd, 0x3d, 0x44, 0x35, 0x7f, 0xfc, 0x6b, 0x6b, 0x61, 0xb1, 0xfa, 0xb5, 0x11, 0x11, 0x1b, + 0xca, 0x3d, 0x27, 0x68, 0xda, 0x3b, 0xe2, 0x9d, 0x5b, 0x1f, 0xca, 0xbb, 0x58, 0xa4, 0x0e, 0x25, + 0x47, 0x26, 0x6f, 0x42, 0x9e, 0xb6, 0x03, 0xcf, 0xb6, 0x9c, 0x86, 0x70, 0xaa, 0xd4, 0x3f, 0x9a, + 0x1d, 0xc0, 0x76, 0xb5, 0xa2, 0x7e, 0x34, 0xe2, 0x57, 0x1b, 0xac, 0x7f, 0xfc, 0xba, 0xd3, 0x12, + 0xbe, 0x90, 0x7a, 0xff, 0xd4, 0xca, 0xd5, 0x07, 0x6a, 0xff, 0x30, 0x44, 0xf2, 0x2e, 0x8c, 0xb2, + 0xf5, 0xdb, 0x70, 0xf7, 0x44, 0x40, 0x0a, 0x43, 0xef, 0x1f, 0x5e, 0x96, 0x98, 0xae, 0x92, 0x88, + 0x2d, 0x64, 0xfb, 0xd0, 0xb7, 0x9c, 0xba, 0x08, 0x32, 0xa1, 0x2f, 0xc7, 0xd2, 0x76, 0xad, 0x5a, + 0x56, 0xc8, 0x86, 0xed, 0x43, 0xbf, 0x5a, 0x27, 0x8b, 0x30, 0x8c, 0x29, 0x2a, 0x44, 0x20, 0x4c, + 0x9d, 0x06, 0x93, 0x53, 0xa8, 0x34, 0x88, 0xca, 0x06, 0xb2, 0xe5, 0xa3, 0x7b, 0x89, 0x48, 0x14, + 0xa1, 0xf7, 0xc9, 0x83, 0x1a, 0xfa, 0x9c, 0xa8, 0x9f, 0x28, 0xd0, 0xd9, 0x27, 0xb6, 0x69, 0x60, + 0x39, 0x5f, 0x17, 0xa9, 0x1e, 0xf4, 0xea, 0xd6, 0x68, 0x50, 0x7d, 0x5f, 0xad, 0xae, 0x4d, 0x83, + 0xea, 0xd7, 0xc9, 0x25, 0x80, 0xe8, 0xe9, 0x9f, 0x3f, 0xd4, 0x98, 0x0a, 0xe4, 0xf3, 0x43, 0xff, + 0xc7, 0x2f, 0x16, 0x33, 0x4b, 0x00, 0x79, 0x19, 0x56, 0xc7, 0x58, 0x85, 0x8b, 0x3d, 0x37, 0x0b, + 0x72, 0x0d, 0x0a, 0xbb, 0xb6, 0x50, 0x15, 0xd6, 0xf7, 0xed, 0x76, 0x9b, 0x36, 0xc5, 0x36, 0x3d, + 0x2d, 0xe1, 0x65, 0x0e, 0xe6, 0x9c, 0x8d, 0xf7, 0x60, 0x2e, 0x6d, 0x96, 0x90, 0x17, 0x60, 0x42, + 0x8d, 0x20, 0x24, 0x98, 0x8c, 0xdb, 0x1d, 0x47, 0xc6, 0x10, 0x12, 0x0c, 0x7e, 0x33, 0x03, 0xcf, + 0xf5, 0xdb, 0x73, 0xc8, 0xc2, 0xff, 0xc7, 0xde, 0xb7, 0xc4, 0x38, 0x72, 0x9c, 0x07, 0x6f, 0x93, + 0x9c, 0x19, 0xce, 0x37, 0xaf, 0x9e, 0xda, 0xc7, 0x8c, 0xf6, 0xa9, 0x6d, 0xad, 0xd6, 0xbb, 0x94, + 0x25, 0x6b, 0x57, 0xbf, 0x2c, 0xad, 0x6d, 0xd9, 0xee, 0xe1, 0xf4, 0x0c, 0xb9, 0xcb, 0x97, 0xbb, + 0xc9, 0x59, 0xaf, 0xd7, 0x76, 0xbb, 0x97, 0xec, 0x99, 0x69, 0x8b, 0xc3, 0xa6, 0xd9, 0xa4, 0xd6, + 0x63, 0xfc, 0xc0, 0x6f, 0xe3, 0x47, 0x6c, 0x20, 0x2f, 0x27, 0x4e, 0x82, 0x08, 0xb9, 0xf8, 0x10, + 0x21, 0xc8, 0xc1, 0xd7, 0x00, 0x41, 0x7c, 0xf2, 0xcd, 0x80, 0x61, 0xc0, 0x40, 0x6e, 0x4e, 0xa0, + 0x24, 0x02, 0x12, 0x20, 0x8f, 0x5b, 0x90, 0x1c, 0x7c, 0x0a, 0xea, 0xab, 0xaa, 0xee, 0xea, 0x07, + 0xb9, 0xb3, 0x96, 0x94, 0xc4, 0x80, 0x4f, 0x33, 0xfc, 0xea, 0xab, 0xaf, 0xeb, 0x5d, 0x5f, 0x7d, + 0x4f, 0x28, 0x0e, 0x47, 0x9e, 0x8f, 0xbc, 0x2d, 0x4f, 0xd1, 0x20, 0x7e, 0x63, 0xf6, 0x05, 0x64, + 0xc2, 0xc6, 0xce, 0x01, 0xf7, 0x0a, 0x31, 0x17, 0x11, 0xd2, 0x76, 0x0e, 0x02, 0xf2, 0x02, 0xac, + 0xf7, 0xdc, 0x7d, 0x67, 0xd2, 0x1f, 0xdb, 0x41, 0xf7, 0xd0, 0xed, 0xa1, 0xdf, 0x16, 0x5a, 0xfb, + 0x99, 0x2a, 0x2f, 0xb0, 0x04, 0x3c, 0xd5, 0xe2, 0xb9, 0x29, 0x2d, 0xbe, 0x5b, 0x28, 0x2a, 0x6a, + 0xce, 0x44, 0xf3, 0x2a, 0xed, 0x9b, 0x39, 0xd8, 0x9c, 0xb6, 0xc9, 0xc8, 0x1b, 0x59, 0x63, 0xc0, + 0xb4, 0x1d, 0x32, 0x5c, 0xd6, 0x76, 0x48, 0x5f, 0x23, 0xb7, 0x21, 0xf4, 0xba, 0x7a, 0x52, 0x04, + 0x05, 0x01, 0xa3, 0x75, 0x86, 0x4e, 0x10, 0x3c, 0xa6, 0xe7, 0x48, 0x5e, 0x8a, 0xc2, 0xcb, 0x61, + 0x72, 0x1d, 0x01, 0x23, 0xaf, 0x01, 0x74, 0xfb, 0x7e, 0xe0, 0xa2, 0x51, 0x01, 0x67, 0x50, 0x98, + 0x2d, 0x79, 0x08, 0x95, 0xb5, 0xc8, 0x08, 0x2d, 0xfb, 0x3d, 0x97, 0x4f, 0xa0, 0x03, 0x1b, 0x53, + 0x4e, 0x55, 0x3a, 0x3d, 0x51, 0x4a, 0x7b, 0x91, 0x20, 0x6b, 0x12, 0x26, 0xb6, 0x4f, 0x8e, 0x78, + 0x6e, 0xda, 0x1a, 0x39, 0x06, 0x92, 0x3e, 0x3a, 0x29, 0x75, 0x6e, 0x11, 0x3d, 0x19, 0x85, 0xd4, + 0x19, 0xa4, 0x33, 0xea, 0x93, 0x2b, 0xb0, 0x24, 0x12, 0x60, 0xd2, 0x07, 0x00, 0x23, 0x0e, 0x1c, + 0x74, 0xcf, 0xc5, 0xc5, 0x83, 0x61, 0x56, 0xd1, 0xb7, 0x8e, 0xb3, 0x16, 0x8b, 0x08, 0x69, 0x1f, + 0x0f, 0x45, 0xef, 0x2e, 0x8a, 0xf5, 0x1d, 0xbf, 0xd0, 0x78, 0xe9, 0x1f, 0x29, 0x62, 0xfa, 0xd3, + 0x37, 0xc2, 0x93, 0xda, 0x47, 0x00, 0x5d, 0x9b, 0x78, 0xc3, 0xf0, 0x7f, 0xca, 0xea, 0x88, 0x5d, + 0xc7, 0x59, 0x1d, 0xfe, 0x93, 0x5c, 0x87, 0xb5, 0x11, 0x33, 0x7e, 0x1d, 0xfb, 0x7c, 0x3c, 0x59, + 0xb2, 0x91, 0x15, 0x06, 0x6e, 0xfb, 0x38, 0xa6, 0xbc, 0x5d, 0x77, 0xc3, 0x01, 0x93, 0x2e, 0x48, + 0xf2, 0x12, 0x2c, 0xd2, 0x0b, 0x12, 0xc3, 0xf3, 0x24, 0x7c, 0x2a, 0x10, 0x0f, 0xd9, 0x0d, 0xb3, + 0xf8, 0x55, 0xfe, 0x3f, 0xa7, 0xf5, 0x76, 0x4e, 0x10, 0x93, 0xaf, 0x67, 0xb2, 0x01, 0x0b, 0xfe, + 0xe8, 0x40, 0xea, 0xda, 0xbc, 0x3f, 0x3a, 0xa0, 0xfd, 0xba, 0x01, 0x2a, 0x73, 0xf1, 0x61, 0xa1, + 0x16, 0x82, 0xe3, 0x01, 0x7b, 0xbf, 0x17, 0xcd, 0x55, 0x06, 0xc7, 0x2c, 0xff, 0xc7, 0x83, 0x2e, + 0xc5, 0x0c, 0x02, 0xdf, 0x96, 0xa3, 0x72, 0xf1, 0x6e, 0xaf, 0x06, 0x81, 0x1f, 0x85, 0xe7, 0xea, + 0x91, 0x2d, 0x58, 0xa1, 0x74, 0xc2, 0xd8, 0x60, 0x9c, 0x7b, 0xb8, 0x94, 0xe6, 0x1e, 0x8e, 0x07, + 0x5d, 0xd1, 0x44, 0x73, 0x39, 0x90, 0x7e, 0x91, 0x7b, 0xa0, 0x4a, 0x6c, 0x16, 0xfa, 0x7c, 0x26, + 0x0c, 0xb1, 0x23, 0x32, 0x12, 0x7b, 0x56, 0x1d, 0xec, 0xfb, 0xe6, 0x5a, 0x37, 0x0e, 0xe0, 0x43, + 0xf3, 0x7d, 0x45, 0x9c, 0xa5, 0x19, 0x95, 0x88, 0x06, 0x2b, 0x87, 0x4e, 0x60, 0x07, 0xc1, 0x11, + 0x33, 0x2c, 0xe3, 0xd1, 0x88, 0x97, 0x0e, 0x9d, 0xc0, 0x0a, 0x8e, 0x44, 0xb6, 0x93, 0xb3, 0x14, + 0xc7, 0x77, 0x26, 0xe3, 0x43, 0x5b, 0x66, 0x1a, 0xd9, 0x88, 0x9d, 0x3e, 0x74, 0x82, 0x26, 0x2d, + 0x93, 0x68, 0x93, 0x6b, 0xb0, 0x8a, 0x74, 0xbb, 0x9e, 0x20, 0x8c, 0xe1, 0x32, 0xcc, 0x65, 0x4a, + 0xb8, 0xeb, 0x31, 0xca, 0xbc, 0x85, 0xff, 0x9c, 0x83, 0x73, 0xd9, 0xa3, 0x83, 0xcb, 0x93, 0x8e, + 0x29, 0x3a, 0xf6, 0xf1, 0xb6, 0x2d, 0x52, 0x08, 0x0b, 0x75, 0x92, 0x35, 0x39, 0xb9, 0xcc, 0xc9, + 0x29, 0xc1, 0x3a, 0x12, 0xe2, 0xec, 0x69, 0xdf, 0x0b, 0xc6, 0x3c, 0x82, 0x87, 0xb9, 0x46, 0x0b, + 0xd8, 0x79, 0x5e, 0xa3, 0x60, 0xf2, 0x3c, 0xac, 0x8a, 0x13, 0xd9, 0x7f, 0x3c, 0xa0, 0x1f, 0x66, + 0xc7, 0xf1, 0x0a, 0x87, 0x36, 0x11, 0x48, 0xce, 0xc2, 0xbc, 0x33, 0x1c, 0xd2, 0x4f, 0xb2, 0x53, + 0x78, 0xce, 0x19, 0x0e, 0x59, 0x46, 0x1e, 0x74, 0x63, 0xb4, 0xf7, 0xd1, 0xb4, 0x88, 0xdb, 0x31, + 0x9a, 0xcb, 0x08, 0x64, 0xe6, 0x46, 0x01, 0xdd, 0xf7, 0xb4, 0xae, 0x40, 0x59, 0x40, 0x14, 0x70, + 0x86, 0x21, 0xc2, 0x33, 0x50, 0x14, 0x4a, 0x6e, 0xe6, 0x8d, 0x61, 0x2e, 0x38, 0x5c, 0xc1, 0xfd, + 0x2a, 0x6c, 0xf4, 0xbc, 0x00, 0x17, 0x2f, 0xeb, 0xd2, 0x70, 0xc8, 0x1d, 0x27, 0x59, 0x64, 0x5f, + 0xf3, 0x0c, 0x2f, 0xa6, 0x23, 0xa9, 0x0f, 0x87, 0xcc, 0x7d, 0x92, 0x8f, 0xf5, 0xeb, 0xb0, 0xc6, + 0xd9, 0x34, 0x7e, 0x45, 0x62, 0x5b, 0xf8, 0x06, 0xa6, 0xef, 0x27, 0x9e, 0x03, 0x09, 0x38, 0xa8, + 0xda, 0x13, 0x35, 0xff, 0x56, 0x81, 0xb3, 0x99, 0x7c, 0x1e, 0xf9, 0x0a, 0x30, 0x3f, 0xb1, 0xb1, + 0x6f, 0x8f, 0xdc, 0xae, 0x37, 0xf4, 0x30, 0xf0, 0x06, 0x93, 0x83, 0xde, 0x9e, 0xc5, 0x21, 0xa2, + 0xcf, 0x59, 0xdb, 0x37, 0xc3, 0x4a, 0x4c, 0x40, 0xa3, 0x8e, 0x12, 0xe0, 0xf3, 0x0f, 0xe1, 0x6c, + 0x26, 0x6a, 0x86, 0xe0, 0xe4, 0xa3, 0xf1, 0x0c, 0xd4, 0x42, 0xb3, 0x95, 0xe8, 0xb4, 0x24, 0x50, + 0xe1, 0xdd, 0xfb, 0x51, 0xd8, 0xbd, 0x04, 0x47, 0x48, 0x8c, 0xe4, 0xbe, 0xce, 0x7a, 0xd4, 0x88, + 0x4a, 0xd3, 0xb7, 0xf6, 0x43, 0x38, 0xcb, 0x17, 0xdf, 0xc1, 0xc8, 0x19, 0x1e, 0x46, 0xe4, 0x58, + 0x43, 0x3f, 0x92, 0x45, 0x8e, 0xad, 0xca, 0x5d, 0x8a, 0x1f, 0x52, 0x3d, 0xed, 0xa4, 0x81, 0xbc, + 0x0f, 0xdf, 0xca, 0x89, 0xad, 0x9e, 0xd1, 0x9c, 0x8c, 0x65, 0xad, 0x64, 0x2d, 0xeb, 0x93, 0xef, + 0xa9, 0x06, 0x10, 0xf9, 0xb0, 0x62, 0xa2, 0x52, 0x6e, 0x85, 0x25, 0x98, 0x7b, 0xde, 0x10, 0xe9, + 0x68, 0xb0, 0x58, 0x06, 0xd0, 0xf5, 0x6e, 0x12, 0x44, 0x2e, 0xc0, 0x62, 0x98, 0x64, 0x9b, 0x5f, + 0x1c, 0x45, 0x06, 0xa8, 0xf6, 0xc8, 0xb3, 0xb0, 0xcc, 0xf8, 0xf8, 0xd8, 0x9e, 0x03, 0x84, 0xe9, + 0x74, 0xe3, 0x89, 0x31, 0x50, 0xe0, 0xd9, 0x27, 0x8d, 0x21, 0xb9, 0x0f, 0xe7, 0xd0, 0x16, 0x24, + 0xf0, 0xc3, 0x69, 0xb0, 0xbb, 0x4e, 0xf7, 0xd0, 0xe5, 0xab, 0x56, 0xcb, 0x9c, 0x8c, 0xe1, 0xd0, + 0xb2, 0x9a, 0xd2, 0x3c, 0x0c, 0x87, 0x56, 0xe0, 0x8b, 0xdf, 0x65, 0x5a, 0x9d, 0xb7, 0xa1, 0x07, + 0x17, 0x66, 0xd4, 0x94, 0x0e, 0x0e, 0x45, 0x3e, 0x38, 0x6e, 0x80, 0xba, 0xef, 0xf6, 0x28, 0x4f, + 0xec, 0xf6, 0xb0, 0x69, 0x6f, 0xdd, 0x66, 0x69, 0xe5, 0xcd, 0xd5, 0x10, 0x6e, 0x05, 0xfe, 0xde, + 0x6d, 0xfe, 0x95, 0x23, 0x71, 0xe5, 0xc9, 0x6f, 0x11, 0xf2, 0x12, 0x9c, 0x4e, 0x04, 0x35, 0x89, + 0xbc, 0xe4, 0xcd, 0x75, 0x5a, 0x14, 0x0f, 0x81, 0x75, 0x15, 0x96, 0xc5, 0xaa, 0x18, 0x85, 0xce, + 0x73, 0xe6, 0x12, 0x87, 0xd1, 0x5d, 0xc7, 0x3f, 0x37, 0x11, 0x9d, 0xca, 0x7c, 0xc6, 0x9c, 0x80, + 0x97, 0x26, 0x2f, 0x02, 0x09, 0xf9, 0xf6, 0xf0, 0xa0, 0xe0, 0x1f, 0x5c, 0x17, 0x25, 0xe1, 0x0e, + 0xe7, 0x9f, 0xfd, 0xbb, 0x02, 0x9c, 0xce, 0x78, 0xff, 0xd0, 0x47, 0x80, 0x37, 0x18, 0xbb, 0x07, + 0xec, 0x09, 0x21, 0x77, 0x72, 0x4d, 0x82, 0x73, 0xa1, 0xd6, 0x3c, 0x4b, 0x9b, 0xce, 0xbf, 0xc5, + 0x7f, 0xd1, 0xc3, 0xc3, 0x19, 0x09, 0x79, 0x0d, 0xfd, 0x97, 0x54, 0x61, 0x1d, 0x73, 0x41, 0x04, + 0x9e, 0x8f, 0x29, 0x25, 0x90, 0x09, 0x29, 0xc4, 0x5e, 0x48, 0xd8, 0x8a, 0x96, 0x84, 0x44, 0xb9, + 0x10, 0x53, 0x1d, 0x26, 0x20, 0xe4, 0x93, 0x70, 0x5e, 0xba, 0x6b, 0xec, 0xc4, 0xce, 0x43, 0xf3, + 0x78, 0x73, 0xc3, 0x09, 0x6f, 0x9d, 0xed, 0xd8, 0x1e, 0xdc, 0x82, 0xcb, 0x38, 0x89, 0x5e, 0x6f, + 0x68, 0xa7, 0x92, 0x87, 0x60, 0x57, 0x59, 0xb4, 0xfd, 0xf3, 0x14, 0xab, 0xda, 0x1b, 0x26, 0xf2, + 0x88, 0x60, 0xaf, 0x6b, 0x99, 0xbb, 0x73, 0x01, 0x77, 0xe7, 0x25, 0xb9, 0x33, 0x27, 0xda, 0x9b, + 0x07, 0xb0, 0x1e, 0x72, 0x4a, 0xe1, 0xb5, 0x55, 0x8c, 0xa5, 0x50, 0x47, 0x62, 0x82, 0x6f, 0x62, + 0xf7, 0x18, 0x73, 0xf0, 0x4f, 0x55, 0x94, 0xc3, 0x58, 0x4c, 0x62, 0x15, 0x02, 0xf2, 0x55, 0x20, + 0xec, 0xfa, 0x8c, 0x7d, 0x09, 0xd2, 0x5f, 0x12, 0xba, 0x19, 0xfe, 0x25, 0x96, 0xa1, 0x32, 0x55, + 0x53, 0x0e, 0x9f, 0x85, 0xa5, 0xd2, 0xb7, 0xf8, 0x0a, 0xfb, 0x0d, 0x05, 0x4e, 0x67, 0x50, 0x24, + 0x1a, 0xe4, 0xc4, 0x16, 0x4d, 0xdb, 0x05, 0x55, 0x4e, 0x99, 0x39, 0xaf, 0x47, 0xee, 0x00, 0x60, + 0x66, 0xc7, 0x91, 0x7b, 0xe0, 0x7e, 0x5d, 0x4e, 0x6b, 0x1f, 0x41, 0x63, 0x75, 0x16, 0x51, 0xd6, + 0x4a, 0xc1, 0xfc, 0xd1, 0xbb, 0x08, 0x0b, 0xde, 0xa0, 0xdb, 0x9f, 0xf4, 0x5c, 0xed, 0x07, 0xa2, + 0x1d, 0xf1, 0x31, 0x24, 0x6d, 0xe0, 0x0a, 0x39, 0x3e, 0xde, 0xd7, 0xa7, 0x8f, 0xb7, 0xac, 0xe7, + 0xe0, 0xe1, 0x18, 0x10, 0x20, 0x4b, 0xf3, 0x19, 0xe4, 0x7d, 0x68, 0x20, 0xf8, 0xb0, 0x3d, 0x84, + 0xb3, 0x99, 0x7b, 0x81, 0xb2, 0x2e, 0x68, 0xd7, 0x17, 0x71, 0xdd, 0x0b, 0xf4, 0x37, 0x65, 0xbb, + 0xaf, 0xc2, 0xf2, 0x23, 0xd7, 0x19, 0xb9, 0x23, 0xce, 0x13, 0xf2, 0xc3, 0x86, 0xc1, 0x64, 0x96, + 0xb0, 0x17, 0xdf, 0xf4, 0x5c, 0x84, 0x49, 0xea, 0x70, 0x9a, 0x4d, 0xb1, 0x77, 0x84, 0xcf, 0x0c, + 0x2e, 0xf6, 0x54, 0x62, 0x8c, 0x36, 0x56, 0x41, 0xa6, 0xa7, 0x8a, 0x58, 0xac, 0xb6, 0xb9, 0x7e, + 0x90, 0x04, 0xd1, 0xbb, 0xe2, 0x5c, 0x36, 0x36, 0xd9, 0x82, 0x25, 0x46, 0x9c, 0x3d, 0x38, 0x99, + 0xbe, 0xea, 0xea, 0xcc, 0x2f, 0x94, 0xd1, 0xdc, 0x3d, 0x08, 0xff, 0xa7, 0x9c, 0x20, 0x9a, 0x06, + 0xd8, 0x47, 0xb2, 0x3a, 0xce, 0x5c, 0x46, 0x20, 0x57, 0xc3, 0x69, 0x7f, 0xad, 0x88, 0xae, 0xc6, + 0x64, 0x35, 0xf4, 0xd0, 0x0a, 0xdc, 0x81, 0x50, 0x49, 0x2e, 0x9a, 0xfc, 0xd7, 0x53, 0x1e, 0xa2, + 0xe4, 0x35, 0x58, 0xa6, 0x64, 0x0f, 0x26, 0x03, 0x76, 0x98, 0xe5, 0x63, 0x61, 0xa2, 0xea, 0xac, + 0x88, 0x4e, 0x5b, 0xe5, 0x94, 0xb9, 0x74, 0x14, 0xfd, 0xa4, 0xef, 0xb0, 0xe0, 0x68, 0x3c, 0x94, + 0x8f, 0x40, 0x21, 0xb7, 0xb6, 0xea, 0xed, 0x16, 0xaf, 0x52, 0xa4, 0x38, 0xd1, 0x3b, 0x6c, 0x6b, + 0x9e, 0x49, 0xae, 0xb5, 0x17, 0x60, 0x49, 0xa2, 0x4d, 0x3b, 0xc3, 0x1c, 0xb9, 0x44, 0x67, 0xd8, + 0x2f, 0x3e, 0xd9, 0x8f, 0xa0, 0x28, 0x48, 0xd2, 0x07, 0xe7, 0xa1, 0x1f, 0x88, 0xeb, 0x03, 0xff, + 0xa7, 0x30, 0x3a, 0xca, 0xd8, 0xc9, 0x39, 0x13, 0xff, 0x47, 0x2e, 0x65, 0xec, 0xd0, 0x97, 0x66, + 0x3f, 0xb0, 0x87, 0x68, 0x10, 0x18, 0x3e, 0xcb, 0x28, 0xbc, 0xdd, 0x0f, 0x98, 0x99, 0x20, 0xff, + 0xc6, 0x5f, 0x86, 0xec, 0x5d, 0x42, 0xb8, 0x35, 0xed, 0x36, 0x8e, 0x31, 0x23, 0xb9, 0x34, 0x33, + 0xc2, 0xc2, 0xff, 0xf0, 0x9a, 0xec, 0xcb, 0x80, 0x30, 0x64, 0x46, 0xa4, 0x3b, 0xa7, 0x10, 0xbb, + 0x73, 0x24, 0x69, 0x4f, 0x34, 0x7b, 0x8c, 0x97, 0x11, 0xd2, 0x9e, 0xe4, 0x0d, 0xf8, 0x4e, 0xb8, + 0x42, 0x62, 0xe2, 0x35, 0xfa, 0x2c, 0x63, 0x4f, 0x32, 0x9e, 0x34, 0x3a, 0x71, 0xf5, 0x9e, 0xc6, + 0x42, 0x96, 0x52, 0x2a, 0xbc, 0x82, 0x9f, 0x2c, 0xcd, 0x20, 0x2f, 0xc3, 0x99, 0x30, 0xcd, 0x69, + 0xf0, 0xa6, 0x37, 0xb4, 0x31, 0xd1, 0xed, 0x31, 0x7f, 0x2c, 0x11, 0x51, 0x66, 0xbd, 0xe9, 0x0d, + 0xf7, 0xb0, 0x84, 0x37, 0xf3, 0xcf, 0x72, 0x42, 0x46, 0xb6, 0xe5, 0xfb, 0xe3, 0x60, 0x3c, 0x72, + 0x86, 0x31, 0x05, 0x02, 0x39, 0x82, 0x67, 0xb0, 0x49, 0xb7, 0x31, 0xf1, 0x8c, 0x3f, 0x12, 0x81, + 0x71, 0xc2, 0x0d, 0xb6, 0x74, 0xfb, 0x63, 0xf1, 0x47, 0xae, 0x4e, 0xb1, 0x75, 0x19, 0x99, 0xee, + 0x2b, 0x89, 0x6a, 0xe5, 0x94, 0xb9, 0xc1, 0x68, 0xa6, 0xb0, 0x48, 0x25, 0xe3, 0xac, 0x49, 0x6a, + 0x10, 0xb6, 0xa2, 0x83, 0x27, 0x4e, 0x55, 0x3e, 0x92, 0xc8, 0xa7, 0x61, 0xd1, 0xeb, 0xc9, 0xf9, + 0x55, 0x93, 0xb2, 0xeb, 0x6a, 0x8f, 0xc5, 0x78, 0x8f, 0x68, 0xd0, 0xad, 0xe1, 0x71, 0xe8, 0xd6, + 0x4a, 0x4c, 0xd5, 0xa2, 0x6d, 0x09, 0x71, 0x4c, 0xba, 0x1a, 0x59, 0x8d, 0xee, 0x1c, 0xbc, 0x5f, + 0xf0, 0x14, 0x88, 0xa2, 0xcc, 0x9b, 0xfc, 0x97, 0xf6, 0x7f, 0xe1, 0xc6, 0x49, 0xc7, 0x88, 0x9e, + 0x18, 0x53, 0x06, 0x7c, 0x91, 0x05, 0x78, 0x8d, 0x8f, 0xdb, 0x55, 0x90, 0x83, 0x64, 0x7b, 0x62, + 0x89, 0x08, 0x58, 0x67, 0xe4, 0x69, 0xff, 0x96, 0x87, 0xd5, 0xb8, 0x72, 0x89, 0xbc, 0x00, 0x05, + 0xe9, 0xa0, 0xdc, 0xc8, 0xd0, 0x40, 0xe1, 0xf1, 0x88, 0x48, 0x27, 0x3a, 0x18, 0xc9, 0x5d, 0x58, + 0x45, 0x73, 0x57, 0xbc, 0xcd, 0xc7, 0x1e, 0x57, 0x59, 0xce, 0xd6, 0x3a, 0x17, 0x7f, 0xfc, 0xee, + 0x95, 0x53, 0xa8, 0x60, 0x5e, 0xa6, 0x75, 0xe9, 0xc5, 0x48, 0x0b, 0x25, 0xdd, 0x41, 0x61, 0xba, + 0xee, 0x80, 0x77, 0x65, 0x8a, 0xee, 0x60, 0x6e, 0x86, 0xee, 0x20, 0xaa, 0x29, 0xeb, 0x0e, 0x50, + 0x83, 0xb4, 0x30, 0x4d, 0x83, 0x14, 0xd5, 0x61, 0x1a, 0xa4, 0x48, 0xf6, 0x5f, 0x9c, 0x2a, 0xfb, + 0x8f, 0xea, 0x70, 0xd9, 0x7f, 0x24, 0x8d, 0x5f, 0x9c, 0x2a, 0x8d, 0x97, 0x2a, 0x31, 0x69, 0xfc, + 0x35, 0x3e, 0xb0, 0x23, 0xe7, 0xb1, 0x8d, 0x23, 0xce, 0x99, 0x49, 0x1c, 0x32, 0xd3, 0x79, 0x8c, + 0x76, 0x6c, 0x94, 0x31, 0xe1, 0xc6, 0x6f, 0xda, 0x0f, 0x13, 0x07, 0x90, 0x98, 0xf3, 0xe7, 0x61, + 0x95, 0xdd, 0xc3, 0x3c, 0x70, 0x30, 0xbb, 0x88, 0x57, 0xcc, 0x15, 0x01, 0x65, 0x42, 0x9a, 0x8f, + 0xc0, 0x5a, 0x88, 0xc6, 0xe5, 0x14, 0xe8, 0x13, 0x6b, 0x86, 0xb5, 0x79, 0x80, 0x27, 0x99, 0xde, + 0x88, 0x87, 0x50, 0x8a, 0xd1, 0x63, 0xf1, 0x75, 0x5e, 0x04, 0x12, 0xa1, 0x85, 0xa6, 0xc0, 0x05, + 0x44, 0x5d, 0x0f, 0x51, 0x43, 0x7b, 0xdd, 0x3f, 0x50, 0x12, 0xd2, 0xff, 0x0f, 0xab, 0xf9, 0x2f, + 0x40, 0xf8, 0x75, 0x9b, 0x4b, 0x70, 0x45, 0x0f, 0x54, 0x51, 0xd0, 0xe2, 0x70, 0xed, 0x20, 0x29, + 0x6d, 0xf8, 0x90, 0x5a, 0xa5, 0xfd, 0x28, 0x1f, 0x93, 0x8c, 0x8a, 0xcf, 0x50, 0xfe, 0x26, 0xf0, + 0x6d, 0x3e, 0xc5, 0xfc, 0xf8, 0xbd, 0x3a, 0x65, 0x99, 0x72, 0xe3, 0x47, 0xcb, 0x6a, 0x9a, 0x10, + 0x04, 0xbe, 0xb0, 0x85, 0xb4, 0xd9, 0x2b, 0x5a, 0x62, 0xba, 0x05, 0x39, 0x76, 0xd6, 0x96, 0x66, + 0x93, 0x13, 0xa2, 0x29, 0xba, 0x4b, 0xf1, 0x35, 0x1d, 0xfe, 0x12, 0x1f, 0xe8, 0x00, 0x2a, 0x12, + 0x82, 0x38, 0xf1, 0x7c, 0x86, 0xbc, 0x24, 0x45, 0x1c, 0x47, 0x09, 0x29, 0xab, 0x13, 0xf1, 0xaf, + 0x20, 0x6b, 0xc0, 0x32, 0xca, 0x25, 0x05, 0xc1, 0x42, 0x86, 0xae, 0x2e, 0xdd, 0xf9, 0x72, 0xb5, + 0x6e, 0x2e, 0xd1, 0x7a, 0x82, 0xcc, 0x21, 0x3c, 0x23, 0x4b, 0x13, 0xe3, 0x8d, 0x9c, 0x13, 0xe1, + 0xbe, 0x67, 0x8e, 0x40, 0x24, 0x74, 0xc4, 0xa6, 0x9e, 0x73, 0xe2, 0x00, 0x8e, 0xa6, 0x1d, 0xc2, + 0xf9, 0xe9, 0x53, 0x32, 0x23, 0x95, 0x5c, 0xc4, 0xda, 0xe4, 0x64, 0xd6, 0x46, 0x96, 0x2d, 0xe6, + 0x63, 0xb2, 0x45, 0xed, 0x4f, 0xf3, 0xf0, 0xdc, 0x09, 0xa6, 0x6b, 0xc6, 0x37, 0x3f, 0x1b, 0x67, + 0x9c, 0x73, 0x31, 0x69, 0x10, 0x25, 0xca, 0xef, 0x84, 0xe3, 0x41, 0x77, 0x0a, 0xdb, 0xfc, 0x15, + 0x58, 0x63, 0x07, 0x3f, 0xb3, 0x5f, 0xde, 0x9f, 0xf4, 0x4f, 0x70, 0xf2, 0x5f, 0x10, 0xce, 0x96, + 0x89, 0xaa, 0x78, 0x19, 0xe0, 0x79, 0x67, 0x85, 0x30, 0xd2, 0x86, 0x25, 0x44, 0xdb, 0x77, 0xbc, + 0xfe, 0x89, 0xbc, 0xfe, 0x84, 0x2b, 0xa7, 0x5c, 0x8d, 0xb9, 0x5d, 0x50, 0xc0, 0x0e, 0xfe, 0x26, + 0xd7, 0x61, 0x6d, 0x30, 0x39, 0xa2, 0x2c, 0x21, 0x5b, 0x0b, 0xdc, 0x4c, 0x6c, 0xce, 0x5c, 0x19, + 0x4c, 0x8e, 0xf4, 0xe1, 0x10, 0xa7, 0x14, 0xed, 0xc9, 0xd6, 0x29, 0x1e, 0xdb, 0xb5, 0x02, 0x73, + 0x1e, 0x31, 0x29, 0x01, 0xb6, 0x6f, 0x39, 0xee, 0x19, 0x60, 0xd6, 0xc5, 0x3c, 0x95, 0x1e, 0xfb, + 0xa1, 0xfd, 0x67, 0x4e, 0xc8, 0xb8, 0xa6, 0xaf, 0xfb, 0x5f, 0x4f, 0x51, 0xc6, 0x14, 0xdd, 0x00, + 0x95, 0x0e, 0x7d, 0x74, 0xa8, 0x84, 0x73, 0xb4, 0x3a, 0x98, 0x1c, 0x85, 0x63, 0x27, 0x0f, 0xfc, + 0xbc, 0x3c, 0xf0, 0xaf, 0x09, 0x19, 0x58, 0xe6, 0xf1, 0x30, 0x7d, 0xc8, 0x29, 0xc7, 0x74, 0xfd, + 0x64, 0x87, 0xc0, 0xaf, 0xe7, 0x2d, 0x63, 0xde, 0x12, 0xea, 0x92, 0xb9, 0x94, 0xba, 0x24, 0x63, + 0xef, 0xcd, 0x67, 0xed, 0xbd, 0x94, 0x72, 0x66, 0x21, 0x43, 0x39, 0x93, 0xb9, 0x41, 0x8b, 0x4f, + 0xd8, 0xa0, 0x8b, 0xf2, 0x3a, 0xf9, 0xa7, 0x9c, 0xe0, 0x98, 0xe2, 0x4f, 0xa0, 0x87, 0x70, 0x5a, + 0x3c, 0x81, 0xd8, 0xcd, 0x11, 0xe9, 0xdc, 0x96, 0x6e, 0xdf, 0xcc, 0x7a, 0xfc, 0x20, 0x5a, 0xc6, + 0x03, 0x65, 0x9d, 0x3f, 0x7b, 0xa2, 0xf2, 0xff, 0x3d, 0x0f, 0x1e, 0xf2, 0x00, 0xce, 0x61, 0x22, + 0x8a, 0xae, 0xac, 0x2d, 0xb4, 0x47, 0xee, 0x3e, 0x5f, 0x0f, 0x57, 0x53, 0xcf, 0x03, 0xaf, 0x2b, + 0x35, 0xc7, 0x74, 0xf7, 0x2b, 0xa7, 0xcc, 0x33, 0x41, 0x06, 0x3c, 0xf9, 0x96, 0xfa, 0x81, 0x02, + 0xda, 0x93, 0xc7, 0x0b, 0x9f, 0xbd, 0xc9, 0x01, 0xa7, 0xcf, 0x5e, 0x69, 0xf4, 0x9e, 0x83, 0x95, + 0x91, 0xbb, 0x3f, 0x72, 0x83, 0xc3, 0x98, 0x6c, 0x6a, 0x99, 0x03, 0xc5, 0xc0, 0x88, 0xe8, 0xb5, + 0x4f, 0xf5, 0x18, 0x11, 0x95, 0xb4, 0x9d, 0xf0, 0x89, 0x9c, 0x39, 0x0f, 0x74, 0x35, 0xc9, 0x0d, + 0x64, 0x3f, 0xee, 0x16, 0x8a, 0x39, 0x35, 0x6f, 0xf2, 0x18, 0xbb, 0xfb, 0x5e, 0xdf, 0xd5, 0xfe, + 0x4a, 0x11, 0x1c, 0x41, 0xd6, 0xe0, 0x91, 0x87, 0x92, 0xd5, 0x7f, 0x3e, 0xc5, 0x86, 0x64, 0x55, + 0x39, 0x89, 0xe0, 0xb0, 0xf6, 0x01, 0x09, 0x0e, 0xef, 0x08, 0xd3, 0x41, 0x7a, 0xe6, 0xed, 0xdd, + 0x22, 0x37, 0x61, 0x81, 0x59, 0x0b, 0x8a, 0xe6, 0xae, 0xc5, 0x9a, 0xbb, 0x77, 0xcb, 0x14, 0xe5, + 0xda, 0xdb, 0xa1, 0x2e, 0x3b, 0xd5, 0x89, 0xbd, 0x5b, 0xe4, 0xb5, 0x93, 0x59, 0xf1, 0x17, 0x85, + 0x15, 0x7f, 0x68, 0xc1, 0xff, 0x7a, 0xcc, 0x82, 0xff, 0xda, 0xec, 0xd1, 0xe2, 0x16, 0x08, 0x2c, + 0x6e, 0x69, 0x14, 0xcf, 0xee, 0xe7, 0x39, 0xb8, 0x34, 0xb3, 0x06, 0xb9, 0x08, 0x45, 0xbd, 0x55, + 0x6d, 0x47, 0xf3, 0x4b, 0xf7, 0x8c, 0x80, 0x90, 0x5d, 0x58, 0xdc, 0x72, 0x02, 0xaf, 0x4b, 0x97, + 0x71, 0xa6, 0x4a, 0x30, 0x45, 0x36, 0x44, 0xaf, 0x9c, 0x32, 0xa3, 0xba, 0xc4, 0x86, 0x75, 0xdc, + 0x0b, 0xb1, 0x1c, 0x75, 0xf9, 0x0c, 0xf1, 0x4a, 0x8a, 0x60, 0xaa, 0x1a, 0x3d, 0x67, 0x52, 0x40, + 0xf2, 0x08, 0x88, 0x65, 0x55, 0xca, 0xee, 0x68, 0xcc, 0xc5, 0x0e, 0x63, 0x2f, 0x34, 0x09, 0x7f, + 0xf9, 0x09, 0x63, 0x97, 0xaa, 0x57, 0x39, 0x65, 0x66, 0x50, 0x4b, 0x6e, 0xf3, 0xb7, 0x04, 0xbf, + 0x33, 0x7d, 0x10, 0x9e, 0x22, 0x26, 0xf4, 0x0d, 0x28, 0xb6, 0x84, 0xfd, 0x91, 0xe4, 0x5a, 0x23, + 0x6c, 0x8d, 0xcc, 0xb0, 0x54, 0xfb, 0x6d, 0x45, 0xc8, 0x59, 0x9e, 0x3c, 0x58, 0x52, 0x0a, 0xc1, + 0xde, 0xec, 0x14, 0x82, 0xbd, 0x5f, 0x32, 0x85, 0xa0, 0xe6, 0xc1, 0xcd, 0x13, 0x0f, 0x2c, 0xf9, + 0x14, 0xa8, 0x98, 0x6d, 0xcd, 0x91, 0x26, 0x89, 0xed, 0xaf, 0xf5, 0x30, 0x49, 0x40, 0x85, 0xa7, + 0xb4, 0x34, 0xd7, 0xba, 0xf1, 0xda, 0xda, 0x9f, 0xf3, 0xe4, 0x10, 0xd5, 0x5e, 0x2b, 0xa1, 0x5c, + 0x7a, 0xbf, 0xde, 0x58, 0x46, 0x6c, 0xb3, 0x3d, 0x27, 0x65, 0xbb, 0x4d, 0x7f, 0x6b, 0xba, 0x53, + 0x96, 0xb4, 0xf3, 0xfe, 0x38, 0x0f, 0x17, 0x67, 0x55, 0xcf, 0xcc, 0xa7, 0xaf, 0x3c, 0x5d, 0x3e, + 0xfd, 0x9b, 0x50, 0x64, 0xb0, 0xd0, 0xd5, 0x08, 0xe7, 0x96, 0x57, 0xa5, 0x73, 0x2b, 0x8a, 0xc9, + 0x73, 0x30, 0xaf, 0x97, 0xad, 0x28, 0xc5, 0x23, 0xfa, 0x04, 0x38, 0xdd, 0x00, 0xad, 0xcd, 0x79, + 0x11, 0xf9, 0x72, 0x3a, 0xab, 0x29, 0xcf, 0xed, 0x78, 0x41, 0x1a, 0x90, 0x54, 0xde, 0x16, 0x6c, + 0x6f, 0x94, 0x67, 0x84, 0x87, 0xee, 0x37, 0xd3, 0x19, 0x52, 0x35, 0x98, 0x6f, 0x8d, 0xdc, 0xc0, + 0x1d, 0xcb, 0xf6, 0xfa, 0x43, 0x84, 0x98, 0xbc, 0x84, 0x5b, 0xd3, 0x3b, 0xc7, 0x2c, 0x78, 0xca, + 0xbc, 0x1c, 0xd0, 0x0a, 0xcd, 0xef, 0x29, 0xd8, 0x94, 0x50, 0x68, 0x85, 0x9a, 0x33, 0x19, 0x74, + 0x0f, 0x3b, 0x66, 0x8d, 0x73, 0x4e, 0xac, 0x42, 0x1f, 0xa1, 0xb4, 0x83, 0x81, 0x29, 0xa1, 0x68, + 0xdf, 0x51, 0xe0, 0x4c, 0x56, 0x3f, 0xc8, 0x45, 0x28, 0x0c, 0x32, 0x13, 0xb8, 0x0e, 0x58, 0xcc, + 0x87, 0x25, 0x54, 0x9f, 0xed, 0xfb, 0xa3, 0x23, 0x67, 0x2c, 0x7b, 0x35, 0x48, 0x60, 0x13, 0x15, + 0x6f, 0x3b, 0xf8, 0x3f, 0xb9, 0x22, 0xae, 0x9c, 0x7c, 0x2a, 0xe5, 0x2b, 0xfe, 0xd1, 0x74, 0x80, + 0x6a, 0xaf, 0xd5, 0x1c, 0xb2, 0xbc, 0x21, 0xaf, 0x40, 0x81, 0x36, 0x2b, 0xb1, 0x7a, 0xe9, 0xfa, + 0xd1, 0xeb, 0x35, 0x8e, 0xc4, 0x5a, 0x15, 0x38, 0x47, 0x7d, 0x13, 0x91, 0xb5, 0xfb, 0xb0, 0x1a, + 0xc7, 0x20, 0x46, 0x3c, 0x74, 0xf4, 0xd2, 0x6d, 0x95, 0x53, 0xda, 0xf2, 0x7d, 0xe6, 0x59, 0xb7, + 0xf5, 0xcc, 0xcf, 0xdf, 0xbd, 0x02, 0xf4, 0x27, 0xab, 0x93, 0x15, 0x5a, 0x5a, 0xfb, 0x6e, 0x0e, + 0xce, 0x44, 0xc1, 0x3c, 0xc4, 0x1e, 0xfa, 0x95, 0xf5, 0x2c, 0xd7, 0x63, 0x9e, 0xcf, 0x82, 0x6f, + 0x4c, 0x77, 0x70, 0x86, 0xc3, 0xe5, 0x2e, 0x6c, 0x4e, 0xc3, 0x27, 0x2f, 0xc0, 0x22, 0xc6, 0x7f, + 0x1b, 0x3a, 0x5d, 0x57, 0x3e, 0x66, 0x07, 0x02, 0x68, 0x46, 0xe5, 0xda, 0x4f, 0x15, 0x38, 0xcf, + 0xfd, 0xc1, 0xea, 0x8e, 0x37, 0x40, 0xfd, 0x4d, 0xd7, 0xfd, 0x60, 0x22, 0x23, 0xec, 0xc6, 0xce, + 0xb1, 0xe7, 0xe3, 0x6e, 0x7f, 0xa9, 0xaf, 0x4d, 0xef, 0x2d, 0xb9, 0x89, 0x31, 0x0d, 0xb9, 0xe5, + 0x4c, 0x81, 0x45, 0xa2, 0x19, 0x50, 0x80, 0x1c, 0x89, 0x06, 0x31, 0xb4, 0xff, 0x07, 0x97, 0x67, + 0x7f, 0x80, 0x7c, 0x09, 0x56, 0x30, 0x49, 0x5f, 0x67, 0x78, 0x30, 0x72, 0x7a, 0xae, 0x90, 0xec, + 0x09, 0x01, 0xb4, 0x5c, 0xc6, 0x42, 0x34, 0xf2, 0xc8, 0x28, 0x07, 0x98, 0xfe, 0x8f, 0x57, 0x8a, + 0x39, 0x5d, 0xca, 0xd4, 0xb4, 0x6f, 0x2a, 0x40, 0xd2, 0x34, 0xc8, 0xc7, 0x61, 0xb9, 0xd3, 0x2e, + 0x5b, 0x63, 0x67, 0x34, 0xae, 0xf8, 0x93, 0x11, 0x8f, 0x8f, 0xc8, 0x02, 0x65, 0x8c, 0xbb, 0x36, + 0xd3, 0xd4, 0x1d, 0xfa, 0x93, 0x91, 0x19, 0xc3, 0xc3, 0x64, 0x70, 0xae, 0xfb, 0x66, 0xcf, 0x39, + 0x8e, 0x27, 0x83, 0xe3, 0xb0, 0x58, 0x32, 0x38, 0x0e, 0xd3, 0xde, 0x51, 0xe0, 0x82, 0x30, 0x88, + 0xee, 0x65, 0xb4, 0xa5, 0x8c, 0xe1, 0xa0, 0x46, 0x22, 0x20, 0xf7, 0x2c, 0x0e, 0x7d, 0x5d, 0x44, + 0x4c, 0xc3, 0x06, 0x22, 0xab, 0xce, 0xea, 0x92, 0xcf, 0x42, 0xc1, 0x1a, 0xfb, 0xc3, 0x13, 0x84, + 0x4c, 0x53, 0xc3, 0x19, 0x1d, 0xfb, 0x43, 0x24, 0x81, 0x35, 0x35, 0x17, 0xce, 0xc8, 0x8d, 0x13, + 0x2d, 0x26, 0x75, 0x58, 0xe0, 0xb1, 0x31, 0x13, 0xb6, 0x46, 0x33, 0xfa, 0xb4, 0xb5, 0x26, 0xe2, + 0xb2, 0xf1, 0x80, 0xd0, 0xa6, 0xa0, 0xa1, 0xfd, 0xae, 0x02, 0x4b, 0x94, 0xb1, 0xc1, 0x47, 0xe9, + 0xfb, 0x5d, 0xd2, 0x71, 0x3e, 0x58, 0x98, 0xce, 0x85, 0xe4, 0x4f, 0x74, 0x1b, 0xbf, 0x0a, 0x6b, + 0x89, 0x0a, 0x44, 0xc3, 0x88, 0x3c, 0x7d, 0xaf, 0xeb, 0xb0, 0xdc, 0x52, 0xcc, 0xec, 0x2c, 0x06, + 0xd3, 0x7e, 0x53, 0x81, 0x33, 0xcd, 0x37, 0xc7, 0x0e, 0x53, 0xa8, 0x9b, 0x93, 0xbe, 0xd8, 0xef, + 0x94, 0x59, 0x13, 0x96, 0xf5, 0x2c, 0x5a, 0x08, 0x63, 0xd6, 0x38, 0xcc, 0x0c, 0x4b, 0x49, 0x05, + 0x8a, 0xfc, 0x7e, 0x09, 0x78, 0x1c, 0xe7, 0xcb, 0x92, 0x6c, 0x24, 0x22, 0xcc, 0x91, 0x68, 0x4f, + 0xf0, 0x08, 0xe3, 0x75, 0xcc, 0xb0, 0xb6, 0xf6, 0xef, 0x0a, 0x6c, 0x4c, 0xa9, 0x43, 0xde, 0x80, + 0x39, 0xf4, 0x64, 0xe6, 0xb3, 0x77, 0x71, 0xca, 0x27, 0xc6, 0xdd, 0xc3, 0xbd, 0x5b, 0xec, 0x22, + 0x3a, 0xa2, 0x3f, 0x4c, 0x56, 0x8b, 0x3c, 0x84, 0x45, 0xbd, 0xd7, 0xe3, 0xaf, 0xb3, 0x5c, 0xec, + 0x75, 0x36, 0xe5, 0x8b, 0x2f, 0x85, 0xf8, 0xec, 0x75, 0xc6, 0x7c, 0xea, 0x7a, 0x3d, 0x9b, 0x7b, + 0x69, 0x47, 0xf4, 0xce, 0x7f, 0x0a, 0x56, 0xe3, 0xc8, 0x4f, 0xe5, 0x58, 0xfa, 0xb6, 0x02, 0x6a, + 0xbc, 0x0d, 0x1f, 0x4e, 0x44, 0xb9, 0xac, 0x69, 0x7e, 0xc2, 0xa2, 0xfa, 0xfd, 0x1c, 0x9c, 0xcd, + 0x1c, 0x61, 0xf2, 0x22, 0xcc, 0xeb, 0xc3, 0x61, 0x75, 0x9b, 0xaf, 0x2a, 0xce, 0x21, 0xa1, 0xd0, + 0x3b, 0xf6, 0x78, 0x65, 0x48, 0xe4, 0x15, 0x28, 0x32, 0xbb, 0x8d, 0x6d, 0x71, 0xe0, 0x60, 0x88, + 0x2c, 0x6e, 0x54, 0x12, 0x8f, 0xa8, 0x2c, 0x10, 0xc9, 0x0e, 0xac, 0xf2, 0xe0, 0x52, 0x68, 0xb9, + 0x13, 0xa6, 0xf6, 0xc0, 0xec, 0x23, 0x42, 0x92, 0xce, 0x8c, 0x7d, 0x62, 0x67, 0x67, 0xa2, 0x16, + 0xa9, 0x81, 0x8a, 0x34, 0x65, 0x4a, 0x2c, 0xac, 0xb3, 0x64, 0xbc, 0x34, 0x85, 0x56, 0xaa, 0x66, + 0x38, 0x5d, 0x7a, 0x10, 0x78, 0x07, 0x83, 0x23, 0x77, 0x30, 0xfe, 0xf0, 0xa6, 0x2b, 0xfa, 0xc6, + 0x89, 0xa6, 0xeb, 0x0f, 0x0b, 0x6c, 0x33, 0x27, 0xab, 0x51, 0x8e, 0x46, 0x8a, 0xe4, 0x8f, 0x1c, + 0x0d, 0x7d, 0x9f, 0xf1, 0xf0, 0x49, 0xdb, 0xb0, 0xc0, 0xc2, 0x5a, 0x89, 0x9d, 0x71, 0x29, 0xb3, + 0x09, 0x0c, 0x67, 0xef, 0x16, 0x63, 0x5f, 0x98, 0x4b, 0x75, 0x60, 0x8a, 0xaa, 0x64, 0x0f, 0x96, + 0xca, 0x7d, 0xd7, 0x19, 0x4c, 0x86, 0xed, 0x93, 0x29, 0x8d, 0x37, 0x79, 0x5f, 0x96, 0xbb, 0xac, + 0x1a, 0x2a, 0x9b, 0xf1, 0x24, 0x97, 0x09, 0x91, 0x76, 0xe8, 0x65, 0x59, 0x40, 0xc1, 0xeb, 0xcb, + 0x33, 0xc6, 0x27, 0x09, 0xc4, 0x7a, 0x71, 0x17, 0x62, 0xee, 0x86, 0x69, 0xc3, 0x6a, 0xcd, 0x09, + 0xc6, 0xed, 0x91, 0x33, 0x08, 0x30, 0x1c, 0xee, 0x09, 0xc2, 0x05, 0x5e, 0x10, 0xa9, 0xde, 0x51, + 0x64, 0x3a, 0x0e, 0xab, 0x32, 0x81, 0x6c, 0x9c, 0x1c, 0xe5, 0x97, 0x76, 0xbc, 0x81, 0xd3, 0xf7, + 0xbe, 0x21, 0x9c, 0xd1, 0x19, 0xbf, 0xb4, 0x2f, 0x80, 0x66, 0x54, 0xae, 0x7d, 0x31, 0x35, 0x6f, + 0xac, 0x95, 0x4b, 0xb0, 0xc0, 0x43, 0x95, 0xb0, 0xd0, 0x1d, 0x2d, 0xa3, 0xb1, 0x5d, 0x6d, 0xec, + 0xaa, 0x0a, 0x59, 0x05, 0x68, 0x99, 0xcd, 0xb2, 0x61, 0x59, 0xf4, 0x77, 0x8e, 0xfe, 0xe6, 0x71, + 0x3d, 0x76, 0x3a, 0x35, 0x35, 0x2f, 0x85, 0xf6, 0x28, 0x68, 0x3f, 0x51, 0xe0, 0x5c, 0xf6, 0x54, + 0x92, 0x36, 0x60, 0x70, 0x17, 0x6e, 0x3e, 0xf0, 0xf1, 0x99, 0xf3, 0x9e, 0x09, 0x4e, 0x06, 0x89, + 0x19, 0xb3, 0xe0, 0x23, 0x39, 0xa1, 0xfb, 0x62, 0xde, 0xcc, 0x5e, 0xcf, 0xcc, 0x79, 0x3d, 0xad, + 0x0c, 0x9b, 0xd3, 0x68, 0xc4, 0xbb, 0xba, 0x06, 0x4b, 0x7a, 0xab, 0x55, 0xab, 0x96, 0xf5, 0x76, + 0xb5, 0xd9, 0x50, 0x15, 0xb2, 0x08, 0x73, 0xbb, 0x66, 0xb3, 0xd3, 0x52, 0x73, 0xda, 0xf7, 0x14, + 0x58, 0xa9, 0x46, 0x96, 0xa6, 0xef, 0x77, 0xf3, 0x7d, 0x22, 0xb6, 0xf9, 0x36, 0xc3, 0x30, 0x48, + 0xe1, 0x07, 0x4e, 0xb4, 0xf3, 0xde, 0xcb, 0xc1, 0x7a, 0xaa, 0x0e, 0xb1, 0x60, 0x41, 0xbf, 0x6f, + 0x35, 0xab, 0xdb, 0x65, 0xde, 0xb2, 0x2b, 0x91, 0x21, 0x1b, 0x26, 0xc6, 0x4b, 0x7d, 0x85, 0x85, + 0x0e, 0x78, 0x1c, 0xd8, 0xbe, 0xd7, 0xeb, 0xc6, 0x2c, 0x18, 0x05, 0x25, 0xbc, 0xc9, 0xbe, 0x31, + 0x19, 0xb9, 0x48, 0x36, 0x17, 0x93, 0xeb, 0x86, 0xf0, 0x34, 0x61, 0x34, 0x8e, 0x74, 0x68, 0x79, + 0x9a, 0x74, 0x44, 0x8f, 0x34, 0x60, 0x7e, 0xd7, 0x1b, 0x57, 0x26, 0x8f, 0xf8, 0xfe, 0xbd, 0x1c, + 0xa5, 0x49, 0xab, 0x4c, 0x1e, 0xa5, 0xc9, 0xa2, 0xc8, 0x92, 0x85, 0xf9, 0x8a, 0x91, 0xe4, 0x54, + 0x92, 0xde, 0xce, 0x85, 0xa7, 0xf2, 0x76, 0xde, 0x5a, 0x81, 0x25, 0xfe, 0x86, 0xc2, 0xe7, 0xc9, + 0x8f, 0x14, 0xd8, 0x9c, 0x36, 0x72, 0xf4, 0x59, 0x16, 0x8f, 0x6a, 0x72, 0x2e, 0xcc, 0xa3, 0x13, + 0x0f, 0x67, 0x22, 0xd0, 0xc8, 0x67, 0x60, 0x89, 0x59, 0x69, 0x59, 0xaf, 0x74, 0xcc, 0x2a, 0x5f, + 0xae, 0x97, 0xfe, 0xe5, 0xdd, 0x2b, 0x1b, 0xdc, 0xb0, 0x2b, 0x78, 0xc5, 0x9e, 0x8c, 0xbc, 0x58, + 0xce, 0x11, 0xb9, 0x06, 0xe5, 0xa2, 0x9d, 0x49, 0xcf, 0x73, 0xc5, 0x1b, 0x42, 0x44, 0x7e, 0xe0, + 0x30, 0xf9, 0x4e, 0x13, 0x30, 0xed, 0xdb, 0x0a, 0x9c, 0x9f, 0x3e, 0x4d, 0xf4, 0x9e, 0x6c, 0x33, + 0x63, 0x37, 0x11, 0x7b, 0x01, 0xef, 0xc9, 0xd0, 0x22, 0x4e, 0xa6, 0x29, 0x10, 0x69, 0x25, 0x2e, + 0xe1, 0x12, 0x42, 0x12, 0x39, 0x71, 0x7e, 0xbc, 0x92, 0x40, 0xd4, 0x1e, 0xc0, 0xc6, 0x94, 0x49, + 0x25, 0x9f, 0xce, 0xcc, 0xce, 0x85, 0xae, 0x89, 0x72, 0x76, 0xae, 0x58, 0x9a, 0x47, 0x09, 0xae, + 0xfd, 0x6b, 0x0e, 0xce, 0xd1, 0xdd, 0xd5, 0x77, 0x83, 0x40, 0x8f, 0x12, 0x59, 0xd3, 0x53, 0xf1, + 0x35, 0x98, 0x3f, 0x7c, 0x3a, 0x51, 0x31, 0x43, 0x27, 0x04, 0xf0, 0xc6, 0x12, 0x0e, 0x71, 0xf4, + 0x7f, 0x72, 0x15, 0x40, 0x4a, 0x65, 0x9e, 0xc7, 0x38, 0xc8, 0xb9, 0x4d, 0xc5, 0x5c, 0x1c, 0x86, + 0x09, 0xcb, 0x5f, 0x87, 0x39, 0x94, 0xa7, 0xf0, 0xbb, 0x43, 0xf0, 0xfc, 0xd9, 0xad, 0x43, 0x69, + 0x8b, 0xc9, 0x2a, 0x90, 0x8f, 0x01, 0x44, 0x29, 0x64, 0xf8, 0xe5, 0x20, 0xe4, 0x0c, 0x61, 0x16, + 0x19, 0x73, 0xf1, 0x68, 0xdf, 0xe1, 0x79, 0x59, 0x4a, 0xb0, 0x2e, 0x46, 0x7c, 0x28, 0xc2, 0xa7, + 0x72, 0x2d, 0xe6, 0x1a, 0x2b, 0xa8, 0x0e, 0x45, 0x08, 0xd5, 0x6b, 0xa9, 0x4c, 0xee, 0x18, 0x45, + 0x3d, 0x91, 0xae, 0xfd, 0x5a, 0x2a, 0x5d, 0x7b, 0x91, 0x61, 0xc9, 0x39, 0xd9, 0xb5, 0x7f, 0xcc, + 0xc1, 0xe2, 0x7d, 0xca, 0x95, 0xa1, 0xac, 0x61, 0xb6, 0xec, 0xe2, 0x36, 0x2c, 0xd5, 0x7c, 0x87, + 0xab, 0x8b, 0xb8, 0x1f, 0x19, 0xb3, 0xb1, 0xee, 0xfb, 0x8e, 0xd0, 0x3c, 0x05, 0xa6, 0x8c, 0xf4, + 0x84, 0xc0, 0x15, 0x77, 0x61, 0x9e, 0xa9, 0xef, 0xb8, 0x18, 0x4d, 0xf0, 0xe5, 0x61, 0x8b, 0x5e, + 0x62, 0xc5, 0x92, 0x86, 0x83, 0xa9, 0x00, 0x65, 0x26, 0x91, 0x1b, 0x5c, 0x4b, 0x92, 0x95, 0xb9, + 0x93, 0x49, 0x56, 0xa4, 0xa0, 0x97, 0xf3, 0x27, 0x09, 0x7a, 0x79, 0xfe, 0x0e, 0x2c, 0x49, 0xed, + 0x79, 0x2a, 0x36, 0xfd, 0x5b, 0x39, 0x58, 0xc1, 0x5e, 0x85, 0xb6, 0x3c, 0xbf, 0x9a, 0x72, 0xa2, + 0x4f, 0xc4, 0xe4, 0x44, 0x9b, 0xf2, 0x7c, 0xb1, 0x9e, 0xcd, 0x10, 0x10, 0xdd, 0x85, 0xf5, 0x14, + 0x22, 0x79, 0x15, 0xe6, 0x68, 0xf3, 0xc5, 0xbb, 0x5a, 0x4d, 0xae, 0x80, 0x28, 0x40, 0x3a, 0xed, + 0x78, 0x60, 0x32, 0x6c, 0xed, 0x3f, 0x14, 0x58, 0xe6, 0xf9, 0x89, 0x06, 0xfb, 0xfe, 0x13, 0x87, + 0xf3, 0x7a, 0x72, 0x38, 0x59, 0x18, 0x26, 0x3e, 0x9c, 0xff, 0xdd, 0x83, 0x78, 0x27, 0x36, 0x88, + 0x1b, 0x61, 0xb8, 0x54, 0xd1, 0x9d, 0x19, 0x63, 0xf8, 0x43, 0x0c, 0x20, 0x1e, 0x47, 0x24, 0x5f, + 0x86, 0xc5, 0x86, 0xfb, 0x38, 0xf6, 0x3c, 0xbd, 0x3e, 0x85, 0xe8, 0x4b, 0x21, 0x22, 0xdb, 0x53, + 0xcc, 0xed, 0xc1, 0x7d, 0x6c, 0xa7, 0x34, 0x87, 0x11, 0x49, 0xfa, 0x42, 0x8d, 0x57, 0x7b, 0x9a, + 0xa5, 0xcf, 0x9d, 0xda, 0x31, 0xb2, 0xd8, 0x77, 0xf2, 0x00, 0x91, 0x3f, 0x30, 0xdd, 0x80, 0x31, + 0xa3, 0x09, 0x21, 0xd9, 0x47, 0x90, 0xbc, 0xc6, 0x85, 0x2d, 0xc5, 0x75, 0x2e, 0x81, 0xce, 0x4d, + 0x0f, 0x67, 0x8b, 0xb2, 0xe8, 0x32, 0x77, 0x40, 0xed, 0xb9, 0x7d, 0x87, 0x9d, 0xed, 0xf9, 0xad, + 0x6b, 0x18, 0xbd, 0x3c, 0x84, 0x4e, 0xc9, 0x4b, 0x8f, 0x6e, 0xaa, 0xdb, 0x14, 0x21, 0xe5, 0x63, + 0x5f, 0x78, 0x3a, 0x1f, 0xfb, 0x16, 0x2c, 0x7a, 0x83, 0xb7, 0xdc, 0xc1, 0xd8, 0x1f, 0x1d, 0xa3, + 0xd8, 0x3d, 0x92, 0xe7, 0xd1, 0x21, 0xa8, 0x8a, 0x32, 0x36, 0x0f, 0x78, 0xe7, 0x86, 0xf8, 0xf2, + 0x34, 0x84, 0xc0, 0x30, 0x46, 0xc0, 0x9c, 0x3a, 0x7f, 0xb7, 0x50, 0x9c, 0x57, 0x17, 0xee, 0x16, + 0x8a, 0x45, 0x75, 0xf1, 0x6e, 0xa1, 0xb8, 0xa8, 0x82, 0x29, 0xe9, 0xcc, 0x42, 0x9d, 0x98, 0xa4, + 0xc6, 0x8a, 0xab, 0xa8, 0xb4, 0x5f, 0xe4, 0x80, 0xa4, 0x9b, 0x41, 0x3e, 0x01, 0x4b, 0xec, 0x80, + 0xb5, 0x47, 0xc1, 0xd7, 0xb8, 0x23, 0x08, 0x8b, 0xcf, 0x26, 0x81, 0xe5, 0xf8, 0x6c, 0x0c, 0x6c, + 0x06, 0x5f, 0xeb, 0x93, 0x2f, 0xc1, 0x69, 0x1c, 0xde, 0xa1, 0x3b, 0xf2, 0xfc, 0x9e, 0x8d, 0xc1, + 0xb4, 0x9d, 0x3e, 0xcf, 0x21, 0xfb, 0x22, 0x26, 0x3b, 0x4f, 0x17, 0x4f, 0x99, 0x06, 0x74, 0xfb, + 0x6d, 0x21, 0x66, 0x8b, 0x21, 0x92, 0x36, 0xa8, 0x72, 0xfd, 0xfd, 0x49, 0xbf, 0xcf, 0x67, 0xb6, + 0x44, 0x5f, 0xf4, 0xc9, 0xb2, 0x29, 0x84, 0x57, 0x23, 0xc2, 0x3b, 0x93, 0x7e, 0x9f, 0xbc, 0x06, + 0xe0, 0x0f, 0xec, 0x23, 0x2f, 0x08, 0x98, 0x32, 0x27, 0x74, 0x05, 0x8a, 0xa0, 0xf2, 0x64, 0xf8, + 0x83, 0x3a, 0x03, 0x92, 0xff, 0x03, 0x18, 0xd6, 0x05, 0xe3, 0x1d, 0x31, 0x6b, 0x24, 0x9e, 0xe6, + 0x49, 0x00, 0xe3, 0x01, 0x11, 0x0e, 0x5c, 0xcb, 0xfb, 0x86, 0x70, 0xca, 0xfb, 0x02, 0xac, 0x73, + 0x7b, 0xe9, 0xfb, 0xde, 0xf8, 0x90, 0x3f, 0x25, 0xde, 0xcf, 0x3b, 0x44, 0x7a, 0x4b, 0xfc, 0x4d, + 0x01, 0x40, 0xbf, 0x6f, 0x89, 0x50, 0x82, 0x37, 0x61, 0x8e, 0x3e, 0x90, 0x84, 0xa0, 0x05, 0xc5, + 0xd4, 0x48, 0x57, 0x16, 0x53, 0x23, 0x06, 0xdd, 0x8d, 0x26, 0xba, 0x3b, 0x08, 0x21, 0x0b, 0xee, + 0x46, 0xe6, 0x01, 0x11, 0x0b, 0xe5, 0xce, 0xb1, 0x48, 0x0d, 0x20, 0x0a, 0xee, 0xc7, 0x59, 0xfe, + 0xf5, 0x28, 0x4a, 0x16, 0x2f, 0xe0, 0xe9, 0x64, 0xa2, 0x00, 0x81, 0xf2, 0xf2, 0x89, 0xd0, 0xc8, + 0x3d, 0x28, 0xb4, 0x9d, 0xd0, 0xff, 0x7e, 0x4a, 0xc8, 0xc3, 0x67, 0x79, 0x8e, 0xdf, 0x28, 0xec, + 0xe1, 0xea, 0xd8, 0x89, 0xa5, 0x42, 0x47, 0x22, 0xc4, 0x80, 0xf9, 0x96, 0x33, 0x72, 0x8e, 0x82, + 0x69, 0xa1, 0x72, 0x59, 0xa9, 0x08, 0x90, 0x8f, 0x40, 0x99, 0xa7, 0x60, 0xc5, 0xe4, 0x36, 0xe4, + 0x2d, 0xab, 0xce, 0x03, 0xfd, 0xac, 0x44, 0xcf, 0x2f, 0xcb, 0xaa, 0x33, 0xbd, 0x6f, 0x10, 0x1c, + 0x49, 0xd5, 0x28, 0x32, 0xf9, 0x24, 0x2c, 0x49, 0x4c, 0x31, 0x0f, 0x91, 0x85, 0x63, 0x20, 0x79, + 0x38, 0xca, 0x87, 0x86, 0x84, 0x4d, 0x6a, 0xa0, 0xde, 0x9b, 0x3c, 0x72, 0xf5, 0xe1, 0x10, 0x5d, + 0x9f, 0xdf, 0x72, 0x47, 0x8c, 0x6d, 0x2b, 0x46, 0xb1, 0xe5, 0xd1, 0x7b, 0xa5, 0x27, 0x4a, 0x65, + 0x61, 0x53, 0xb2, 0x26, 0x69, 0xc1, 0xba, 0xe5, 0x8e, 0x27, 0x43, 0x66, 0x5f, 0xb3, 0xe3, 0x8f, + 0xe8, 0xfb, 0x86, 0x05, 0xd4, 0xc2, 0x30, 0xdc, 0x01, 0x2d, 0x14, 0x46, 0x4d, 0xfb, 0xfe, 0x28, + 0xf1, 0xd6, 0x49, 0x57, 0xd6, 0x5c, 0x79, 0xca, 0xe9, 0xad, 0x1a, 0x7f, 0x35, 0xe1, 0xad, 0x2a, + 0x5e, 0x4d, 0xd1, 0x5b, 0xe9, 0x63, 0x19, 0x41, 0x1f, 0x51, 0x33, 0x28, 0x05, 0x7d, 0x8c, 0x85, + 0x7a, 0x7c, 0xa7, 0x20, 0xc5, 0x1d, 0xe6, 0x73, 0xf1, 0x06, 0xc0, 0x5d, 0xdf, 0x1b, 0xd4, 0xdd, + 0xf1, 0xa1, 0xdf, 0x93, 0x62, 0x4f, 0x2e, 0x7d, 0xd5, 0xf7, 0x06, 0xf6, 0x11, 0x82, 0x7f, 0xf1, + 0xee, 0x15, 0x09, 0xc9, 0x94, 0xfe, 0x27, 0x1f, 0x85, 0x45, 0xfa, 0xab, 0x1d, 0x59, 0x09, 0x31, + 0x99, 0x2c, 0xd6, 0x66, 0xd9, 0x79, 0x22, 0x04, 0x72, 0x07, 0xf3, 0x51, 0x79, 0xc3, 0xb1, 0xc4, + 0xbc, 0x8a, 0xe4, 0x53, 0xde, 0x70, 0x9c, 0x0c, 0x25, 0x2f, 0x21, 0x93, 0x4a, 0xd8, 0x74, 0x91, + 0x42, 0x8e, 0xa7, 0xbd, 0x42, 0xc1, 0x23, 0x5f, 0x6b, 0xb6, 0x88, 0x61, 0x2d, 0x3b, 0x55, 0x26, + 0xaa, 0x61, 0x23, 0xac, 0xca, 0x36, 0xd3, 0x14, 0x71, 0xa6, 0x96, 0x35, 0x22, 0x38, 0xec, 0xd9, + 0x5d, 0x04, 0xc7, 0x1a, 0x11, 0x22, 0x93, 0x2d, 0x58, 0x63, 0x3c, 0x7e, 0x98, 0x8a, 0x96, 0xb3, + 0xb8, 0x78, 0xb6, 0x45, 0xb9, 0x6a, 0xe5, 0xcf, 0x27, 0x2a, 0x90, 0x1d, 0x98, 0xc3, 0xb7, 0x26, + 0xf7, 0x86, 0xb8, 0x20, 0x8b, 0x09, 0x92, 0xfb, 0x08, 0xcf, 0x15, 0x14, 0x10, 0xc8, 0xe7, 0x0a, + 0xa2, 0x92, 0xcf, 0x03, 0x18, 0x83, 0x91, 0xdf, 0xef, 0x63, 0x94, 0xf5, 0x62, 0xcc, 0x95, 0x95, + 0xd3, 0x41, 0x2a, 0x11, 0x12, 0x8f, 0x08, 0x8a, 0xbf, 0xed, 0x44, 0x2c, 0x76, 0x89, 0x96, 0x56, + 0x85, 0x79, 0xb6, 0x19, 0x31, 0x63, 0x01, 0xcf, 0xc1, 0x24, 0xc5, 0xbb, 0x67, 0x19, 0x0b, 0x38, + 0x3c, 0x9d, 0xb1, 0x40, 0xaa, 0xa0, 0xdd, 0x83, 0x33, 0x59, 0x1d, 0x8b, 0xbd, 0x8e, 0x95, 0x93, + 0xbe, 0x8e, 0xbf, 0x9f, 0x87, 0x65, 0xa4, 0x26, 0x4e, 0x61, 0x1d, 0x56, 0xac, 0xc9, 0xa3, 0x30, + 0x9c, 0x9f, 0x38, 0x8d, 0xb1, 0x7d, 0x81, 0x5c, 0x20, 0xeb, 0xf0, 0x62, 0x35, 0x88, 0x01, 0xab, + 0xe2, 0x26, 0xd8, 0x15, 0x9e, 0x03, 0x61, 0xb2, 0x00, 0xe1, 0x50, 0x91, 0x4e, 0xc5, 0x9d, 0xa8, + 0x14, 0xdd, 0x07, 0xf9, 0xa7, 0xb9, 0x0f, 0x0a, 0x27, 0xba, 0x0f, 0x1e, 0xc2, 0xb2, 0xf8, 0x1a, + 0x9e, 0xe4, 0x73, 0xef, 0xef, 0x24, 0x8f, 0x11, 0x23, 0xb5, 0xf0, 0x44, 0x9f, 0x9f, 0x79, 0xa2, + 0xa3, 0x62, 0x54, 0xec, 0xb2, 0x21, 0xc2, 0xd2, 0x07, 0x3b, 0xe6, 0xaa, 0xdd, 0x2d, 0xb7, 0x7e, + 0x89, 0x5b, 0xf2, 0x55, 0x58, 0xac, 0xf9, 0x42, 0x27, 0x26, 0x29, 0x23, 0xfa, 0x02, 0x28, 0xb3, + 0x0b, 0x21, 0x66, 0x78, 0xbb, 0xe5, 0x3f, 0x88, 0xdb, 0xed, 0x0e, 0x00, 0x77, 0x49, 0x89, 0x72, + 0x4c, 0xe2, 0x96, 0x11, 0x51, 0x89, 0xe2, 0x3a, 0x11, 0x09, 0x99, 0x9e, 0x4e, 0xdc, 0xdc, 0x46, + 0xef, 0x76, 0xfd, 0xc9, 0x60, 0x1c, 0x4b, 0xca, 0x2e, 0xbc, 0xd6, 0x1d, 0x5e, 0x26, 0x1f, 0x0f, + 0x89, 0x6a, 0x1f, 0xec, 0x84, 0x90, 0xcf, 0x85, 0xc6, 0x8f, 0x0b, 0xb3, 0x46, 0x48, 0x4b, 0x8d, + 0xd0, 0x54, 0x93, 0x47, 0xed, 0x27, 0x8a, 0x9c, 0xa9, 0xe5, 0x97, 0x98, 0xea, 0xd7, 0x01, 0x42, + 0xa3, 0x04, 0x31, 0xd7, 0xa1, 0x9b, 0x38, 0x83, 0xca, 0xa3, 0x1c, 0xe1, 0x4a, 0xbd, 0xc9, 0x7f, + 0x50, 0xbd, 0x69, 0xc3, 0x52, 0xf3, 0xcd, 0xb1, 0x13, 0x59, 0xb1, 0x80, 0x15, 0x72, 0xb2, 0x78, + 0x32, 0xe5, 0xb7, 0x9e, 0xc7, 0xbb, 0x21, 0xe2, 0x83, 0xa7, 0xb0, 0xc0, 0x52, 0x45, 0xed, 0x2f, + 0x14, 0x58, 0x93, 0x43, 0x6d, 0x1c, 0x0f, 0xba, 0xe4, 0xd3, 0x2c, 0x70, 0xb4, 0x12, 0x7b, 0xb2, + 0x48, 0x48, 0xf4, 0xc8, 0x3d, 0x1e, 0x74, 0x19, 0x03, 0xe4, 0x3c, 0x96, 0x1b, 0x4b, 0x2b, 0x92, + 0x47, 0xb0, 0xdc, 0xf2, 0xfb, 0x7d, 0xca, 0xd6, 0x8c, 0xde, 0xe2, 0x0f, 0x00, 0x4a, 0x28, 0xa9, + 0x1a, 0x11, 0x0d, 0xda, 0x7a, 0x8e, 0xbf, 0x73, 0x37, 0x86, 0xf4, 0xbc, 0xf7, 0x78, 0xbd, 0x88, + 0xec, 0xdb, 0xe8, 0x1a, 0x28, 0xd3, 0xd4, 0x7e, 0xa6, 0x00, 0x49, 0x37, 0x49, 0x3e, 0xb2, 0x94, + 0xff, 0x01, 0x16, 0x36, 0xc1, 0xfa, 0x15, 0x9e, 0x86, 0xf5, 0x2b, 0xfd, 0x9e, 0x02, 0x6b, 0x55, + 0xbd, 0xce, 0x73, 0xb7, 0x30, 0x0d, 0xce, 0x55, 0xb8, 0x54, 0xd5, 0xeb, 0x76, 0xab, 0x59, 0xab, + 0x96, 0x1f, 0xd8, 0x99, 0x21, 0xd9, 0x2f, 0xc1, 0x33, 0x69, 0x94, 0x48, 0xd3, 0x73, 0x11, 0x36, + 0xd3, 0xc5, 0x22, 0x6c, 0x7b, 0x76, 0x65, 0x11, 0xe1, 0x3d, 0x5f, 0xfa, 0x0c, 0xac, 0x89, 0x10, + 0xe5, 0xed, 0x9a, 0x85, 0x49, 0x50, 0xd6, 0x60, 0x69, 0xcf, 0x30, 0xab, 0x3b, 0x0f, 0xec, 0x9d, + 0x4e, 0xad, 0xa6, 0x9e, 0x22, 0x2b, 0xb0, 0xc8, 0x01, 0x65, 0x5d, 0x55, 0xc8, 0x32, 0x14, 0xab, + 0x0d, 0xcb, 0x28, 0x77, 0x4c, 0x43, 0xcd, 0x95, 0x3e, 0x03, 0xab, 0xad, 0x91, 0xf7, 0x96, 0x33, + 0x76, 0xef, 0xb9, 0xc7, 0xa8, 0xa8, 0x59, 0x80, 0xbc, 0xa9, 0xdf, 0x57, 0x4f, 0x11, 0x80, 0xf9, + 0xd6, 0xbd, 0xb2, 0x75, 0xeb, 0x96, 0xaa, 0x90, 0x25, 0x58, 0xd8, 0x2d, 0xb7, 0xec, 0x7b, 0x75, + 0x4b, 0xcd, 0xd1, 0x1f, 0xfa, 0x7d, 0x0b, 0x7f, 0xe4, 0x4b, 0x2f, 0xc3, 0x3a, 0x32, 0x24, 0x35, + 0x2f, 0x18, 0xbb, 0x03, 0x77, 0x84, 0x6d, 0x58, 0x86, 0xa2, 0xe5, 0xd2, 0x93, 0x64, 0xec, 0xb2, + 0x06, 0xd4, 0x27, 0xfd, 0xb1, 0x37, 0xec, 0xbb, 0x5f, 0x57, 0x95, 0xd2, 0x1d, 0x58, 0x33, 0xfd, + 0xc9, 0xd8, 0x1b, 0x1c, 0x58, 0x63, 0x8a, 0x71, 0x70, 0x4c, 0xce, 0xc2, 0x7a, 0xa7, 0xa1, 0xd7, + 0xb7, 0xaa, 0xbb, 0x9d, 0x66, 0xc7, 0xb2, 0xeb, 0x7a, 0xbb, 0x5c, 0x61, 0x6a, 0xa2, 0x7a, 0xd3, + 0x6a, 0xdb, 0xa6, 0x51, 0x36, 0x1a, 0x6d, 0x55, 0x29, 0x7d, 0x17, 0x65, 0x2b, 0x5d, 0x7f, 0xd0, + 0xdb, 0x71, 0xba, 0x63, 0x7f, 0x84, 0x0d, 0xd6, 0xe0, 0xb2, 0x65, 0x94, 0x9b, 0x8d, 0x6d, 0x7b, + 0x47, 0x2f, 0xb7, 0x9b, 0x66, 0x56, 0x4e, 0x80, 0xf3, 0x70, 0x2e, 0x03, 0xa7, 0xd9, 0x6e, 0xa9, + 0x0a, 0xb9, 0x02, 0x17, 0x32, 0xca, 0xee, 0x1b, 0x5b, 0x7a, 0xa7, 0x5d, 0x69, 0xa8, 0xb9, 0x29, + 0x95, 0x2d, 0xab, 0xa9, 0xe6, 0x4b, 0xbf, 0xa5, 0xc0, 0x6a, 0x27, 0xe0, 0x26, 0xe7, 0x1d, 0x74, + 0xb0, 0x7d, 0x16, 0x2e, 0x76, 0x2c, 0xc3, 0xb4, 0xdb, 0xcd, 0x7b, 0x46, 0xc3, 0xee, 0x58, 0xfa, + 0x6e, 0xb2, 0x35, 0x57, 0xe0, 0x82, 0x84, 0x61, 0x1a, 0xe5, 0xe6, 0x9e, 0x61, 0xda, 0x2d, 0xdd, + 0xb2, 0xee, 0x37, 0xcd, 0x6d, 0x55, 0xa1, 0x5f, 0xcc, 0x40, 0xa8, 0xef, 0xe8, 0xac, 0x35, 0xb1, + 0xb2, 0x86, 0x71, 0x5f, 0xaf, 0xd9, 0x5b, 0xcd, 0xb6, 0x9a, 0x2f, 0xd5, 0xe9, 0xfd, 0x8e, 0x91, + 0xb9, 0x99, 0x65, 0x61, 0x11, 0x0a, 0x8d, 0x66, 0xc3, 0x48, 0x2a, 0x17, 0x97, 0xa1, 0xa8, 0xb7, + 0x5a, 0x66, 0x73, 0x0f, 0x97, 0x18, 0xc0, 0xfc, 0xb6, 0xd1, 0xa0, 0x2d, 0xcb, 0xd3, 0x92, 0x96, + 0xd9, 0xac, 0x37, 0xdb, 0xc6, 0xb6, 0x5a, 0x28, 0x99, 0x62, 0x0b, 0x0b, 0xa2, 0x5d, 0x9f, 0x69, + 0xf2, 0xb6, 0x8d, 0x1d, 0xbd, 0x53, 0x6b, 0xf3, 0x29, 0x7a, 0x60, 0x9b, 0xc6, 0xe7, 0x3a, 0x86, + 0xd5, 0xb6, 0x54, 0x85, 0xa8, 0xb0, 0xdc, 0x30, 0x8c, 0x6d, 0xcb, 0x36, 0x8d, 0xbd, 0xaa, 0x71, + 0x5f, 0xcd, 0x51, 0x9a, 0xec, 0x7f, 0xfa, 0x85, 0xd2, 0x3b, 0x0a, 0x10, 0x16, 0xd5, 0x5c, 0xa4, + 0xca, 0xc2, 0x15, 0x73, 0x19, 0xce, 0x57, 0xe8, 0x54, 0x63, 0xd7, 0xea, 0xcd, 0xed, 0xe4, 0x90, + 0x9d, 0x03, 0x92, 0x28, 0x6f, 0xee, 0xec, 0xa8, 0x0a, 0xb9, 0x00, 0xa7, 0x13, 0xf0, 0x6d, 0xb3, + 0xd9, 0x52, 0x73, 0xe7, 0x73, 0x45, 0x85, 0x6c, 0xa4, 0x0a, 0xef, 0x19, 0x46, 0x4b, 0xcd, 0xd3, + 0x29, 0x4a, 0x14, 0x88, 0x2d, 0xc1, 0xaa, 0x17, 0x4a, 0xdf, 0x56, 0xe0, 0x1c, 0x6b, 0xa6, 0xd8, + 0x5f, 0x61, 0x53, 0x2f, 0xc2, 0x26, 0xcf, 0xd5, 0x90, 0xd5, 0xd0, 0x33, 0xa0, 0xc6, 0x4a, 0x59, + 0x33, 0xcf, 0xc2, 0x7a, 0x0c, 0x8a, 0xed, 0xc8, 0xd1, 0xd3, 0x23, 0x06, 0xde, 0x32, 0xac, 0xb6, + 0x6d, 0xec, 0xec, 0x34, 0xcd, 0x36, 0x6b, 0x48, 0xbe, 0xa4, 0xc1, 0x7a, 0xd9, 0x1d, 0x8d, 0xe9, + 0xd3, 0x6b, 0x10, 0x78, 0xfe, 0x00, 0x9b, 0xb0, 0x02, 0x8b, 0xc6, 0xe7, 0xdb, 0x46, 0xc3, 0xaa, + 0x36, 0x1b, 0xea, 0xa9, 0xd2, 0xc5, 0x04, 0x8e, 0xd8, 0xc7, 0x96, 0x55, 0x51, 0x4f, 0x95, 0x1c, + 0x58, 0x11, 0x86, 0xd7, 0x6c, 0x55, 0x5c, 0x86, 0xf3, 0x62, 0xad, 0xe1, 0x89, 0x92, 0xec, 0xc2, + 0x26, 0x9c, 0x49, 0x97, 0x1b, 0x6d, 0x55, 0xa1, 0xb3, 0x90, 0x28, 0xa1, 0xf0, 0x5c, 0xe9, 0xff, + 0x2b, 0xb0, 0x12, 0x2a, 0x4d, 0x50, 0x4c, 0x7b, 0x05, 0x2e, 0xd4, 0x77, 0x74, 0x7b, 0xdb, 0xd8, + 0xab, 0x96, 0x0d, 0xfb, 0x5e, 0xb5, 0xb1, 0x9d, 0xf8, 0xc8, 0x33, 0x70, 0x36, 0x03, 0x01, 0xbf, + 0xb2, 0x09, 0x67, 0x92, 0x45, 0x6d, 0xba, 0x55, 0x73, 0x74, 0xe8, 0x93, 0x25, 0xe1, 0x3e, 0xcd, + 0x97, 0xf6, 0x60, 0xd5, 0xd2, 0xeb, 0xb5, 0x1d, 0x7f, 0xd4, 0x75, 0xf5, 0xc9, 0xf8, 0x70, 0x40, + 0x2e, 0xc0, 0xc6, 0x4e, 0xd3, 0x2c, 0x1b, 0x36, 0xa2, 0x24, 0x5a, 0x70, 0x1a, 0xd6, 0xe4, 0xc2, + 0x07, 0x06, 0x5d, 0xbe, 0x04, 0x56, 0x65, 0x60, 0xa3, 0xa9, 0xe6, 0x4a, 0x5f, 0x84, 0xe5, 0x58, + 0xc6, 0xcc, 0x0d, 0x38, 0x2d, 0xff, 0x6e, 0xb9, 0x83, 0x9e, 0x37, 0x38, 0x50, 0x4f, 0x25, 0x0b, + 0xcc, 0xc9, 0x60, 0x40, 0x0b, 0x70, 0x3f, 0xcb, 0x05, 0x6d, 0x77, 0x74, 0xe4, 0x0d, 0x9c, 0xb1, + 0xdb, 0x53, 0x73, 0xa5, 0x97, 0x60, 0x25, 0x16, 0xa7, 0x9f, 0x4e, 0x5c, 0xad, 0xc9, 0x0f, 0xe0, + 0xba, 0xb1, 0x5d, 0xed, 0xd4, 0xd5, 0x39, 0xba, 0x93, 0x2b, 0xd5, 0xdd, 0x8a, 0x0a, 0xa5, 0xef, + 0x29, 0xf4, 0x9d, 0x81, 0xd9, 0xb7, 0xea, 0x3b, 0xba, 0x98, 0x6a, 0xba, 0xcc, 0x58, 0xf6, 0x0f, + 0xc3, 0xb2, 0x98, 0x4e, 0xfd, 0x22, 0x6c, 0xf2, 0x1f, 0xb6, 0xde, 0xd8, 0xb6, 0x2b, 0xba, 0xb9, + 0x7d, 0x5f, 0x37, 0xe9, 0xda, 0x7b, 0xa0, 0xe6, 0x70, 0x43, 0x49, 0x10, 0xbb, 0xdd, 0xec, 0x94, + 0x2b, 0x6a, 0x9e, 0xae, 0xdf, 0x18, 0xbc, 0x55, 0x6d, 0xa8, 0x05, 0xdc, 0x9e, 0x29, 0x6c, 0x24, + 0x4b, 0xcb, 0xe7, 0x4a, 0xef, 0x29, 0xb0, 0x61, 0x79, 0x07, 0x03, 0x67, 0x3c, 0x19, 0xb9, 0x7a, + 0xff, 0xc0, 0x1f, 0x79, 0xe3, 0xc3, 0x23, 0x6b, 0xe2, 0x8d, 0x5d, 0x72, 0x13, 0x9e, 0xb7, 0xaa, + 0xbb, 0x0d, 0xbd, 0x4d, 0xb7, 0x97, 0x5e, 0xdb, 0x6d, 0x9a, 0xd5, 0x76, 0xa5, 0x6e, 0x5b, 0x9d, + 0x6a, 0x6a, 0xe5, 0x5d, 0x83, 0x67, 0xa7, 0xa3, 0xd6, 0x8c, 0x5d, 0xbd, 0xfc, 0x40, 0x55, 0x66, + 0x13, 0xdc, 0xd2, 0x6b, 0x7a, 0xa3, 0x6c, 0x6c, 0xdb, 0x7b, 0xb7, 0xd4, 0x1c, 0x79, 0x1e, 0xae, + 0x4e, 0x47, 0xdd, 0xa9, 0xb6, 0x2c, 0x8a, 0x96, 0x9f, 0xfd, 0xdd, 0x8a, 0x55, 0xa7, 0x58, 0x85, + 0xd2, 0x9f, 0x28, 0xb0, 0x39, 0x2d, 0xee, 0x1a, 0xb9, 0x0e, 0x9a, 0xd1, 0x68, 0x9b, 0x7a, 0x75, + 0xdb, 0x2e, 0x9b, 0xc6, 0xb6, 0xd1, 0x68, 0x57, 0xf5, 0x9a, 0x65, 0x5b, 0xcd, 0x0e, 0x5d, 0x4d, + 0x91, 0xe9, 0xc3, 0x73, 0x70, 0x65, 0x06, 0x5e, 0xb3, 0xba, 0x5d, 0x56, 0x15, 0x72, 0x0b, 0x5e, + 0x9c, 0x81, 0x64, 0x3d, 0xb0, 0xda, 0x46, 0x5d, 0x2e, 0x51, 0x73, 0x78, 0x60, 0x65, 0x87, 0x9d, + 0xa2, 0xbd, 0xc3, 0x92, 0xd9, 0x0d, 0xbb, 0x0a, 0x97, 0xa6, 0x62, 0xf1, 0x66, 0x3d, 0x07, 0x57, + 0xa6, 0xa2, 0xb0, 0x46, 0xa9, 0xb9, 0x52, 0x19, 0xce, 0x4f, 0x8f, 0xe3, 0x43, 0xef, 0x8b, 0xf8, + 0x94, 0x17, 0xa1, 0xb0, 0x4d, 0xaf, 0xa8, 0x58, 0xb6, 0x9a, 0x92, 0x07, 0x6a, 0x32, 0xc6, 0x45, + 0xca, 0x58, 0xc6, 0xec, 0x34, 0x1a, 0xec, 0x3e, 0x5b, 0x83, 0xa5, 0x66, 0xbb, 0x62, 0x98, 0x3c, + 0xdf, 0x0f, 0x26, 0xf8, 0xe9, 0x34, 0xe8, 0x0e, 0x6e, 0x9a, 0xd5, 0x2f, 0xe0, 0xc5, 0xb6, 0x09, + 0x67, 0xac, 0x9a, 0x5e, 0xbe, 0x67, 0x37, 0x9a, 0x6d, 0xbb, 0xda, 0xb0, 0xcb, 0x15, 0xbd, 0xd1, + 0x30, 0x6a, 0x2a, 0xe0, 0xac, 0x4e, 0x73, 0xf2, 0x24, 0x1f, 0x85, 0x1b, 0xcd, 0x7b, 0x6d, 0xdd, + 0x6e, 0xd5, 0x3a, 0xbb, 0xd5, 0x86, 0x6d, 0x3d, 0x68, 0x94, 0x05, 0x13, 0x56, 0x4e, 0x9f, 0xfd, + 0x37, 0xe0, 0xda, 0x4c, 0xec, 0x28, 0x33, 0xcf, 0x75, 0xd0, 0x66, 0x62, 0xf2, 0x8e, 0x94, 0x7e, + 0xaa, 0xc0, 0x85, 0x19, 0xca, 0x6c, 0xf2, 0x22, 0xdc, 0xac, 0x18, 0xfa, 0x76, 0xcd, 0xb0, 0x2c, + 0x3c, 0xb1, 0xe8, 0xa4, 0x30, 0xa3, 0x9a, 0xcc, 0x93, 0xfd, 0x26, 0x3c, 0x3f, 0x1b, 0x3d, 0xe2, + 0x11, 0x6e, 0xc0, 0xb5, 0xd9, 0xa8, 0x9c, 0x67, 0xc8, 0x91, 0x12, 0x5c, 0x9f, 0x8d, 0x19, 0xf2, + 0x1a, 0xf9, 0xd2, 0xef, 0x28, 0x70, 0x2e, 0x5b, 0xa2, 0x44, 0xdb, 0x56, 0x6d, 0x58, 0x6d, 0xbd, + 0x56, 0xb3, 0x5b, 0xba, 0xa9, 0xd7, 0x6d, 0xa3, 0x61, 0x36, 0x6b, 0xb5, 0xac, 0x3b, 0xf6, 0x1a, + 0x3c, 0x3b, 0x1d, 0xd5, 0x2a, 0x9b, 0xd5, 0x16, 0xbd, 0x46, 0x34, 0xb8, 0x3c, 0x1d, 0xcb, 0xa8, + 0x96, 0x0d, 0x35, 0xb7, 0xf5, 0xc6, 0x8f, 0xff, 0xe1, 0xf2, 0xa9, 0x1f, 0xbf, 0x77, 0x59, 0xf9, + 0xd9, 0x7b, 0x97, 0x95, 0xbf, 0x7f, 0xef, 0xb2, 0xf2, 0x85, 0x17, 0x4e, 0x96, 0xd4, 0x0e, 0x1f, + 0x20, 0x8f, 0xe6, 0xf1, 0xa9, 0xf4, 0xca, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x77, 0xde, 0xcd, + 0x5e, 0x9a, 0xc2, 0x01, 0x00, } func (this *PluginSpecV1) Equal(that interface{}) bool { @@ -24413,6 +24544,30 @@ func (this *PluginSpecV1_Msteams) Equal(that interface{}) bool { } return true } +func (this *PluginSpecV1_NetIq) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PluginSpecV1_NetIq) + if !ok { + that2, ok := that.(PluginSpecV1_NetIq) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.NetIq.Equal(that1.NetIq) { + return false + } + return true +} func (this *PluginSlackAccessSettings) Equal(that interface{}) bool { if that == nil { return this == nil @@ -25492,6 +25647,39 @@ func (this *PluginMSTeamsSettings) Equal(that interface{}) bool { } return true } +func (this *PluginNetIQSettings) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PluginNetIQSettings) + if !ok { + that2, ok := that.(PluginNetIQSettings) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.OauthIssuerEndpoint != that1.OauthIssuerEndpoint { + return false + } + if this.ApiEndpoint != that1.ApiEndpoint { + return false + } + if this.InsecureSkipVerify != that1.InsecureSkipVerify { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} func (this *PluginStaticCredentialsRef) Equal(that interface{}) bool { if that == nil { return this == nil @@ -45290,6 +45478,29 @@ func (m *PluginSpecV1_Msteams) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *PluginSpecV1_NetIq) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginSpecV1_NetIq) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.NetIq != nil { + { + size, err := m.NetIq.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } + return len(dAtA) - i, nil +} func (m *PluginSlackAccessSettings) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -46857,6 +47068,57 @@ func (m *PluginMSTeamsSettings) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PluginNetIQSettings) 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 *PluginNetIQSettings) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginNetIQSettings) 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.InsecureSkipVerify { + i-- + if m.InsecureSkipVerify { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.ApiEndpoint) > 0 { + i -= len(m.ApiEndpoint) + copy(dAtA[i:], m.ApiEndpoint) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ApiEndpoint))) + i-- + dAtA[i] = 0x12 + } + if len(m.OauthIssuerEndpoint) > 0 { + i -= len(m.OauthIssuerEndpoint) + copy(dAtA[i:], m.OauthIssuerEndpoint) + i = encodeVarintTypes(dAtA, i, uint64(len(m.OauthIssuerEndpoint))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *PluginBootstrapCredentialsV1) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -47078,12 +47340,12 @@ func (m *PluginStatusV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n360, err360 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSyncTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSyncTime):]) - if err360 != nil { - return 0, err360 + n361, err361 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSyncTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSyncTime):]) + if err361 != nil { + return 0, err361 } - i -= n360 - i = encodeVarintTypes(dAtA, i, uint64(n360)) + i -= n361 + i = encodeVarintTypes(dAtA, i, uint64(n361)) i-- dAtA[i] = 0x1a if len(m.ErrorMessage) > 0 { @@ -47185,6 +47447,74 @@ func (m *PluginStatusV1_AwsIc) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *PluginStatusV1_NetIq) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginStatusV1_NetIq) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.NetIq != nil { + { + size, err := m.NetIq.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + return len(dAtA) - i, nil +} +func (m *PluginNetIQStatusV1) 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 *PluginNetIQStatusV1) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginNetIQStatusV1) 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.ImportedResources != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ImportedResources)) + i-- + dAtA[i] = 0x20 + } + if m.ImportedRoles != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ImportedRoles)) + i-- + dAtA[i] = 0x18 + } + if m.ImportedGroups != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ImportedGroups)) + i-- + dAtA[i] = 0x10 + } + if m.ImportedUsers != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ImportedUsers)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *PluginGitlabStatusV1) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -47444,22 +47774,22 @@ func (m *PluginOktaStatusDetailsAppGroupSync) MarshalToSizedBuffer(dAtA []byte) dAtA[i] = 0x28 } if m.LastFailed != nil { - n370, err370 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err370 != nil { - return 0, err370 + n372, err372 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err372 != nil { + return 0, err372 } - i -= n370 - i = encodeVarintTypes(dAtA, i, uint64(n370)) + i -= n372 + i = encodeVarintTypes(dAtA, i, uint64(n372)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n371, err371 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err371 != nil { - return 0, err371 + n373, err373 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err373 != nil { + return 0, err373 } - i -= n371 - i = encodeVarintTypes(dAtA, i, uint64(n371)) + i -= n373 + i = encodeVarintTypes(dAtA, i, uint64(n373)) i-- dAtA[i] = 0x1a } @@ -47518,22 +47848,22 @@ func (m *PluginOktaStatusDetailsUsersSync) MarshalToSizedBuffer(dAtA []byte) (in dAtA[i] = 0x28 } if m.LastFailed != nil { - n372, err372 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err372 != nil { - return 0, err372 + n374, err374 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err374 != nil { + return 0, err374 } - i -= n372 - i = encodeVarintTypes(dAtA, i, uint64(n372)) + i -= n374 + i = encodeVarintTypes(dAtA, i, uint64(n374)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n373, err373 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err373 != nil { - return 0, err373 + n375, err375 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err375 != nil { + return 0, err375 } - i -= n373 - i = encodeVarintTypes(dAtA, i, uint64(n373)) + i -= n375 + i = encodeVarintTypes(dAtA, i, uint64(n375)) i-- dAtA[i] = 0x1a } @@ -47652,22 +47982,22 @@ func (m *PluginOktaStatusDetailsAccessListsSync) MarshalToSizedBuffer(dAtA []byt } } if m.LastFailed != nil { - n374, err374 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err374 != nil { - return 0, err374 + n376, err376 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err376 != nil { + return 0, err376 } - i -= n374 - i = encodeVarintTypes(dAtA, i, uint64(n374)) + i -= n376 + i = encodeVarintTypes(dAtA, i, uint64(n376)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n375, err375 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err375 != nil { - return 0, err375 + n377, err377 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err377 != nil { + return 0, err377 } - i -= n375 - i = encodeVarintTypes(dAtA, i, uint64(n375)) + i -= n377 + i = encodeVarintTypes(dAtA, i, uint64(n377)) i-- dAtA[i] = 0x1a } @@ -47833,12 +48163,12 @@ func (m *PluginOAuth2AccessTokenCredentials) MarshalToSizedBuffer(dAtA []byte) ( i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n380, err380 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err380 != nil { - return 0, err380 + n382, err382 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err382 != nil { + return 0, err382 } - i -= n380 - i = encodeVarintTypes(dAtA, i, uint64(n380)) + i -= n382 + i = encodeVarintTypes(dAtA, i, uint64(n382)) i-- dAtA[i] = 0x1a if len(m.RefreshToken) > 0 { @@ -48780,20 +49110,20 @@ func (m *ScheduledAgentUpgradeWindow) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n395, err395 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) - if err395 != nil { - return 0, err395 + n397, err397 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) + if err397 != nil { + return 0, err397 } - i -= n395 - i = encodeVarintTypes(dAtA, i, uint64(n395)) + i -= n397 + i = encodeVarintTypes(dAtA, i, uint64(n397)) i-- dAtA[i] = 0x12 - n396, err396 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) - if err396 != nil { - return 0, err396 + n398, err398 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) + if err398 != nil { + return 0, err398 } - i -= n396 - i = encodeVarintTypes(dAtA, i, uint64(n396)) + i -= n398 + i = encodeVarintTypes(dAtA, i, uint64(n398)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -49220,12 +49550,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x30 } - n403, err403 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) - if err403 != nil { - return 0, err403 + n405, err405 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) + if err405 != nil { + return 0, err405 } - i -= n403 - i = encodeVarintTypes(dAtA, i, uint64(n403)) + i -= n405 + i = encodeVarintTypes(dAtA, i, uint64(n405)) i-- dAtA[i] = 0x2a if m.Status != 0 { @@ -49233,12 +49563,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x20 } - n404, err404 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) - if err404 != nil { - return 0, err404 + n406, err406 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) + if err406 != nil { + return 0, err406 } - i -= n404 - i = encodeVarintTypes(dAtA, i, uint64(n404)) + i -= n406 + i = encodeVarintTypes(dAtA, i, uint64(n406)) i-- dAtA[i] = 0x1a if len(m.Targets) > 0 { @@ -50748,12 +51078,12 @@ func (m *AccessGraphSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n429, err429 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) - if err429 != nil { - return 0, err429 + n431, err431 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) + if err431 != nil { + return 0, err431 } - i -= n429 - i = encodeVarintTypes(dAtA, i, uint64(n429)) + i -= n431 + i = encodeVarintTypes(dAtA, i, uint64(n431)) i-- dAtA[i] = 0x12 if len(m.AWS) > 0 { @@ -59712,6 +60042,18 @@ func (m *PluginSpecV1_Msteams) Size() (n int) { } return n } +func (m *PluginSpecV1_NetIq) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NetIq != nil { + l = m.NetIq.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} func (m *PluginSlackAccessSettings) Size() (n int) { if m == nil { return 0 @@ -60462,6 +60804,29 @@ func (m *PluginMSTeamsSettings) Size() (n int) { return n } +func (m *PluginNetIQSettings) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OauthIssuerEndpoint) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.ApiEndpoint) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.InsecureSkipVerify { + n += 2 + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *PluginBootstrapCredentialsV1) Size() (n int) { if m == nil { return 0 @@ -60629,6 +60994,42 @@ func (m *PluginStatusV1_AwsIc) Size() (n int) { } return n } +func (m *PluginStatusV1_NetIq) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NetIq != nil { + l = m.NetIq.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} +func (m *PluginNetIQStatusV1) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ImportedUsers != 0 { + n += 1 + sovTypes(uint64(m.ImportedUsers)) + } + if m.ImportedGroups != 0 { + n += 1 + sovTypes(uint64(m.ImportedGroups)) + } + if m.ImportedRoles != 0 { + n += 1 + sovTypes(uint64(m.ImportedRoles)) + } + if m.ImportedResources != 0 { + n += 1 + sovTypes(uint64(m.ImportedResources)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *PluginGitlabStatusV1) Size() (n int) { if m == nil { return 0 @@ -120207,6 +120608,41 @@ func (m *PluginSpecV1) Unmarshal(dAtA []byte) error { } m.Settings = &PluginSpecV1_Msteams{v} iNdEx = postIndex + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetIq", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &PluginNetIQSettings{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Settings = &PluginSpecV1_NetIq{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -124513,6 +124949,141 @@ func (m *PluginMSTeamsSettings) Unmarshal(dAtA []byte) error { } return nil } +func (m *PluginNetIQSettings) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginNetIQSettings: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginNetIQSettings: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OauthIssuerEndpoint", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OauthIssuerEndpoint = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApiEndpoint", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ApiEndpoint = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InsecureSkipVerify", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.InsecureSkipVerify = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PluginBootstrapCredentialsV1) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -125184,6 +125755,168 @@ func (m *PluginStatusV1) Unmarshal(dAtA []byte) error { } m.Details = &PluginStatusV1_AwsIc{v} iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetIq", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &PluginNetIQStatusV1{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Details = &PluginStatusV1_NetIq{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PluginNetIQStatusV1) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginNetIQStatusV1: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginNetIQStatusV1: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ImportedUsers", wireType) + } + m.ImportedUsers = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ImportedUsers |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ImportedGroups", wireType) + } + m.ImportedGroups = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ImportedGroups |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ImportedRoles", wireType) + } + m.ImportedRoles = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ImportedRoles |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ImportedResources", wireType) + } + m.ImportedResources = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ImportedResources |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/api/utils/prompt/confirmation.go b/api/utils/prompt/confirmation.go index 5d3cb19739c03..a8fb2d07e0f3b 100644 --- a/api/utils/prompt/confirmation.go +++ b/api/utils/prompt/confirmation.go @@ -21,6 +21,7 @@ import ( "context" "fmt" "io" + urlpkg "net/url" "strings" "github.com/gravitational/trace" @@ -108,3 +109,45 @@ func Password(ctx context.Context, out io.Writer, in SecureReader, question stri } return string(answer), nil // passwords not trimmed } + +// URLOptions are options for the URL prompt. +type URLOptions func(*urlOptions) + +type urlOptions struct { + urlValidator func(*urlpkg.URL) error +} + +// WithURLValidator sets a custom URL validator for the URL prompt. +func WithURLValidator(validator func(*urlpkg.URL) error) URLOptions { + return func(opts *urlOptions) { + opts.urlValidator = validator + } +} + +// URL prompts the user for a URL. The prompt is written to out and the answer. +func URL(ctx context.Context, out io.Writer, in Reader, question string, opts ...URLOptions) (string, error) { + url, err := Input(ctx, out, in, question) + if err != nil { + return "", trace.Wrap(err, "failed reading prompt response") + } + + url = strings.TrimSpace(url) + + u, err := urlpkg.Parse(url) + if err != nil { + return "", trace.Wrap(err, "invalid URL") + } + + opt := &urlOptions{} + for _, o := range opts { + o(opt) + } + + if opt.urlValidator != nil { + if err := opt.urlValidator(u); err != nil { + return "", trace.Wrap(err, "failed to verify url") + } + } + + return url, nil +} diff --git a/api/utils/prompt/context_reader_test.go b/api/utils/prompt/context_reader_test.go index 8e6fae75e2098..adc5c3ee8dd24 100644 --- a/api/utils/prompt/context_reader_test.go +++ b/api/utils/prompt/context_reader_test.go @@ -17,12 +17,17 @@ limitations under the License. package prompt import ( + "bytes" "context" "io" + "net/http" + "net/http/httptest" + urlpkg "net/url" "os" "testing" "time" + "github.com/gravitational/trace" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/term" @@ -271,3 +276,82 @@ func (t *fakeTerm) Restore(fd int, oldState *term.State) error { t.restoreCalled = true return nil } + +func TestURL(t *testing.T) { + pr, pw := io.Pipe() + t.Cleanup(func() { pr.Close() }) + t.Cleanup(func() { pw.Close() }) + httpSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("hello")) + })) + t.Cleanup(httpSrv.Close) + + write := func(t *testing.T, s string) { + t.Helper() + _, err := pw.Write([]byte(s)) + assert.NoError(t, err, "Write failed") + } + + ctx := context.Background() + cr := NewContextReader(pr) + + t.Run("simple read", func(t *testing.T) { + go write(t, httpSrv.URL) + out := &bytes.Buffer{} + gotURL, err := URL(ctx, out, cr, "Enter URL") + require.NoError(t, err) + require.Equal(t, httpSrv.URL, gotURL) + require.Equal(t, "Enter URL: ", out.String()) + }) + + t.Run("read with validator", func(t *testing.T) { + go write(t, httpSrv.URL) + out := &bytes.Buffer{} + + gotURL, err := URL(ctx, out, cr, "Enter URL", WithURLValidator(func(u *urlpkg.URL) error { + rspBody, err := doHTTPCall(ctx, u.String()) + if err != nil { + return trace.Wrap(err) + } + if rspBody != "hello" { + return trace.BadParameter("unexpected response body: %q", rspBody) + } + return nil + })) + require.NoError(t, err) + require.Equal(t, httpSrv.URL, gotURL) + require.Equal(t, "Enter URL: ", out.String()) + }) + + t.Run("read with failed validator", func(t *testing.T) { + go write(t, httpSrv.URL) + out := &bytes.Buffer{} + + _, err := URL(ctx, out, cr, "Enter URL", WithURLValidator(func(u *urlpkg.URL) error { + rspBody, err := doHTTPCall(ctx, u.String()) + if err != nil { + return trace.Wrap(err) + } + if rspBody != "notHello" { + return trace.BadParameter("unexpected response body: %q", rspBody) + } + return nil + })) + require.Error(t, err) + }) +} + +func doHTTPCall(ctx context.Context, u string) (string, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) + if err != nil { + return "", trace.Wrap(err) + } + rsp, err := http.DefaultClient.Do(req) + if err != nil { + return "", trace.Wrap(err) + } + defer rsp.Body.Close() + defer io.Copy(io.Discard, rsp.Body) + b, err := io.ReadAll(rsp.Body) + return string(b), trace.Wrap(err) +} diff --git a/gen/proto/go/accessgraph/v1alpha/access_graph_service.pb.go b/gen/proto/go/accessgraph/v1alpha/access_graph_service.pb.go index 1e751856eb604..a8c4176608eda 100644 --- a/gen/proto/go/accessgraph/v1alpha/access_graph_service.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/access_graph_service.pb.go @@ -1347,6 +1347,178 @@ func (*EntraEventsStreamResponse) Descriptor() ([]byte, []int) { return file_accessgraph_v1alpha_access_graph_service_proto_rawDescGZIP(), []int{20} } +// NetIQEventsStreamRequest is a request to send commands to the NetIQ importer +type NetIQEventsStreamRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Operation: + // + // *NetIQEventsStreamRequest_Sync + // *NetIQEventsStreamRequest_Upsert + // *NetIQEventsStreamRequest_Delete + Operation isNetIQEventsStreamRequest_Operation `protobuf_oneof:"operation"` +} + +func (x *NetIQEventsStreamRequest) Reset() { + *x = NetIQEventsStreamRequest{} + mi := &file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQEventsStreamRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQEventsStreamRequest) ProtoMessage() {} + +func (x *NetIQEventsStreamRequest) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQEventsStreamRequest.ProtoReflect.Descriptor instead. +func (*NetIQEventsStreamRequest) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_access_graph_service_proto_rawDescGZIP(), []int{21} +} + +func (m *NetIQEventsStreamRequest) GetOperation() isNetIQEventsStreamRequest_Operation { + if m != nil { + return m.Operation + } + return nil +} + +func (x *NetIQEventsStreamRequest) GetSync() *NetIQSyncOperation { + if x, ok := x.GetOperation().(*NetIQEventsStreamRequest_Sync); ok { + return x.Sync + } + return nil +} + +func (x *NetIQEventsStreamRequest) GetUpsert() *NetIQResourceList { + if x, ok := x.GetOperation().(*NetIQEventsStreamRequest_Upsert); ok { + return x.Upsert + } + return nil +} + +func (x *NetIQEventsStreamRequest) GetDelete() *NetIQResourceList { + if x, ok := x.GetOperation().(*NetIQEventsStreamRequest_Delete); ok { + return x.Delete + } + return nil +} + +type isNetIQEventsStreamRequest_Operation interface { + isNetIQEventsStreamRequest_Operation() +} + +type NetIQEventsStreamRequest_Sync struct { + // sync is a command to sync the access graph with the NetIQ state. + Sync *NetIQSyncOperation `protobuf:"bytes,1,opt,name=sync,proto3,oneof"` +} + +type NetIQEventsStreamRequest_Upsert struct { + // upsert is a command to put a resource into the access graph or update it. + Upsert *NetIQResourceList `protobuf:"bytes,2,opt,name=upsert,proto3,oneof"` +} + +type NetIQEventsStreamRequest_Delete struct { + // delete is a command to delete a resource from the access graph when it's deleted. + Delete *NetIQResourceList `protobuf:"bytes,3,opt,name=delete,proto3,oneof"` +} + +func (*NetIQEventsStreamRequest_Sync) isNetIQEventsStreamRequest_Operation() {} + +func (*NetIQEventsStreamRequest_Upsert) isNetIQEventsStreamRequest_Operation() {} + +func (*NetIQEventsStreamRequest_Delete) isNetIQEventsStreamRequest_Operation() {} + +// NetIQSyncOperation is a command that Teleport sends to the access graph service +// at the end of the sync process. +type NetIQSyncOperation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NetIQSyncOperation) Reset() { + *x = NetIQSyncOperation{} + mi := &file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQSyncOperation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQSyncOperation) ProtoMessage() {} + +func (x *NetIQSyncOperation) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQSyncOperation.ProtoReflect.Descriptor instead. +func (*NetIQSyncOperation) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_access_graph_service_proto_rawDescGZIP(), []int{22} +} + +// NetIQEventsStreamResponse is a response from NetIQEventsStream +type NetIQEventsStreamResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NetIQEventsStreamResponse) Reset() { + *x = NetIQEventsStreamResponse{} + mi := &file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQEventsStreamResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQEventsStreamResponse) ProtoMessage() {} + +func (x *NetIQEventsStreamResponse) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQEventsStreamResponse.ProtoReflect.Descriptor instead. +func (*NetIQEventsStreamResponse) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_access_graph_service_proto_rawDescGZIP(), []int{23} +} + var File_accessgraph_v1alpha_access_graph_service_proto protoreflect.FileDescriptor var file_accessgraph_v1alpha_access_graph_service_proto_rawDesc = []byte{ @@ -1364,25 +1536,54 @@ var file_accessgraph_v1alpha_access_graph_service_proto_rawDesc = []byte{ 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2f, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x61, 0x63, 0x63, 0x65, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x24, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x71, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x6f, 0x64, 0x65, - 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x67, - 0x65, 0x52, 0x05, 0x65, 0x64, 0x67, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, - 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, - 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x22, 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xaa, 0x03, - 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, + 0x6e, 0x65, 0x74, 0x69, 0x71, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x24, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x71, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, + 0x67, 0x65, 0x52, 0x05, 0x65, 0x64, 0x67, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, + 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, + 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x22, 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xaa, + 0x03, 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, + 0x12, 0x3b, 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x41, 0x0a, + 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x5b, 0x0a, 0x14, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, + 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x6f, 0x0a, + 0x1b, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x48, 0x00, 0x52, 0x18, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x42, 0x0b, + 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xac, 0x03, 0x0a, 0x15, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, @@ -1408,177 +1609,175 @@ var file_accessgraph_v1alpha_access_graph_service_proto_rawDesc = []byte{ 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x18, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x42, 0x0b, 0x0a, - 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xac, 0x03, 0x0a, 0x15, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x3b, - 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, + 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x79, + 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x0a, 0x16, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, + 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x6f, 0x0a, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x58, + 0x0a, 0x13, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x48, 0x00, 0x52, 0x11, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, + 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x22, 0x54, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x5f, + 0x70, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x43, + 0x61, 0x50, 0x65, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x0a, 0x11, 0x52, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1e, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x5f, 0x70, 0x65, 0x6d, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x61, 0x50, 0x65, 0x6d, + 0x22, 0x14, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe2, 0x01, 0x0a, 0x16, 0x41, 0x57, 0x53, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3b, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x3e, + 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x3e, + 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x0b, + 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x41, + 0x57, 0x53, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x19, 0x0a, 0x17, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xee, 0x01, 0x0a, 0x19, 0x47, + 0x69, 0x74, 0x6c, 0x61, 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, 0x74, + 0x6c, 0x61, 0x62, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x41, 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, + 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, + 0x69, 0x74, 0x6c, 0x61, 0x62, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x41, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x5b, - 0x0a, 0x14, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x5f, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x6f, 0x0a, 0x1b, 0x65, - 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x48, 0x00, 0x52, 0x18, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x42, 0x0b, 0x0a, 0x09, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x79, 0x6e, - 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x5b, 0x0a, 0x16, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x05, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x6f, 0x0a, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, - 0x13, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x48, 0x00, 0x52, 0x11, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x22, 0x54, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x5f, 0x70, - 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x61, - 0x50, 0x65, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x0a, 0x11, 0x52, 0x65, - 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1e, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x5f, 0x70, 0x65, 0x6d, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x61, 0x50, 0x65, 0x6d, 0x22, - 0x14, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe2, 0x01, 0x0a, 0x16, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, + 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x0b, + 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, 0x1a, 0x47, + 0x69, 0x74, 0x6c, 0x61, 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x18, 0x45, 0x6e, + 0x74, 0x72, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, + 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x40, 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, + 0x61, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x40, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, + 0x74, 0x72, 0x61, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1b, 0x0a, 0x19, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x18, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x3b, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x3e, 0x0a, - 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x3e, 0x0a, - 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x0b, 0x0a, - 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x41, 0x57, - 0x53, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, - 0x0a, 0x17, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xee, 0x01, 0x0a, 0x19, 0x47, 0x69, - 0x74, 0x6c, 0x61, 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, - 0x61, 0x62, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x41, 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, - 0x74, 0x6c, 0x61, 0x62, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x41, 0x0a, 0x06, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12, + 0x40, 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, + 0x74, 0x12, 0x40, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x14, 0x0a, 0x12, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x53, 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1b, 0x0a, 0x19, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x32, 0xa3, 0x08, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x21, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x07, 0x47, 0x65, + 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x0b, 0x0a, - 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, 0x1a, 0x47, 0x69, - 0x74, 0x6c, 0x61, 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x74, - 0x72, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x53, - 0x79, 0x6e, 0x63, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, - 0x73, 0x79, 0x6e, 0x63, 0x12, 0x40, 0x0a, 0x06, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, - 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x40, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, - 0x72, 0x61, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, - 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1b, 0x0a, 0x19, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x32, 0xab, 0x07, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, - 0x70, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x21, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x07, 0x47, 0x65, 0x74, - 0x46, 0x69, 0x6c, 0x65, 0x12, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, - 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x65, 0x0a, 0x0c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, - 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x63, 0x63, 0x65, + 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x65, 0x0a, 0x0c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x12, 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x6d, 0x0a, 0x0e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x12, 0x2a, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x6d, 0x0a, 0x0e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x12, 0x2a, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x12, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, - 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x12, 0x26, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, - 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, - 0x0f, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x12, 0x2b, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x12, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x5d, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x12, 0x26, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x79, 0x0a, - 0x12, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x12, 0x2e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x76, 0x0a, 0x11, 0x45, 0x6e, 0x74, 0x72, - 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2d, 0x2e, + 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x43, 0x41, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, + 0x0a, 0x0f, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x12, 0x2b, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x57, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x79, + 0x0a, 0x12, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, + 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, + 0x62, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x76, 0x0a, 0x11, 0x45, 0x6e, 0x74, + 0x72, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2d, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, - 0x42, 0x57, 0x5a, 0x55, 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, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, + 0x01, 0x12, 0x76, 0x0a, 0x11, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2d, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, + 0x49, 0x51, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, + 0x51, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x57, 0x5a, 0x55, 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, 0x67, + 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1593,7 +1792,7 @@ func file_accessgraph_v1alpha_access_graph_service_proto_rawDescGZIP() []byte { return file_accessgraph_v1alpha_access_graph_service_proto_rawDescData } -var file_accessgraph_v1alpha_access_graph_service_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_accessgraph_v1alpha_access_graph_service_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_accessgraph_v1alpha_access_graph_service_proto_goTypes = []any{ (*QueryRequest)(nil), // 0: accessgraph.v1alpha.QueryRequest (*QueryResponse)(nil), // 1: accessgraph.v1alpha.QueryResponse @@ -1616,66 +1815,75 @@ var file_accessgraph_v1alpha_access_graph_service_proto_goTypes = []any{ (*GitlabEventsStreamResponse)(nil), // 18: accessgraph.v1alpha.GitlabEventsStreamResponse (*EntraEventsStreamRequest)(nil), // 19: accessgraph.v1alpha.EntraEventsStreamRequest (*EntraEventsStreamResponse)(nil), // 20: accessgraph.v1alpha.EntraEventsStreamResponse - (*Node)(nil), // 21: accessgraph.v1alpha.Node - (*Edge)(nil), // 22: accessgraph.v1alpha.Edge - (*ResourceList)(nil), // 23: accessgraph.v1alpha.ResourceList - (*ResourceHeaderList)(nil), // 24: accessgraph.v1alpha.ResourceHeaderList - (*AccessListsMembers)(nil), // 25: accessgraph.v1alpha.AccessListsMembers - (*ExcludeAccessListsMembers)(nil), // 26: accessgraph.v1alpha.ExcludeAccessListsMembers - (*AccessPathChanged)(nil), // 27: accessgraph.v1alpha.AccessPathChanged - (*AWSResourceList)(nil), // 28: accessgraph.v1alpha.AWSResourceList - (*GitlabSyncOperation)(nil), // 29: accessgraph.v1alpha.GitlabSyncOperation - (*GitlabResourceList)(nil), // 30: accessgraph.v1alpha.GitlabResourceList - (*EntraSyncOperation)(nil), // 31: accessgraph.v1alpha.EntraSyncOperation - (*EntraResourceList)(nil), // 32: accessgraph.v1alpha.EntraResourceList + (*NetIQEventsStreamRequest)(nil), // 21: accessgraph.v1alpha.NetIQEventsStreamRequest + (*NetIQSyncOperation)(nil), // 22: accessgraph.v1alpha.NetIQSyncOperation + (*NetIQEventsStreamResponse)(nil), // 23: accessgraph.v1alpha.NetIQEventsStreamResponse + (*Node)(nil), // 24: accessgraph.v1alpha.Node + (*Edge)(nil), // 25: accessgraph.v1alpha.Edge + (*ResourceList)(nil), // 26: accessgraph.v1alpha.ResourceList + (*ResourceHeaderList)(nil), // 27: accessgraph.v1alpha.ResourceHeaderList + (*AccessListsMembers)(nil), // 28: accessgraph.v1alpha.AccessListsMembers + (*ExcludeAccessListsMembers)(nil), // 29: accessgraph.v1alpha.ExcludeAccessListsMembers + (*AccessPathChanged)(nil), // 30: accessgraph.v1alpha.AccessPathChanged + (*AWSResourceList)(nil), // 31: accessgraph.v1alpha.AWSResourceList + (*GitlabSyncOperation)(nil), // 32: accessgraph.v1alpha.GitlabSyncOperation + (*GitlabResourceList)(nil), // 33: accessgraph.v1alpha.GitlabResourceList + (*EntraSyncOperation)(nil), // 34: accessgraph.v1alpha.EntraSyncOperation + (*EntraResourceList)(nil), // 35: accessgraph.v1alpha.EntraResourceList + (*NetIQResourceList)(nil), // 36: accessgraph.v1alpha.NetIQResourceList } var file_accessgraph_v1alpha_access_graph_service_proto_depIdxs = []int32{ - 21, // 0: accessgraph.v1alpha.QueryResponse.nodes:type_name -> accessgraph.v1alpha.Node - 22, // 1: accessgraph.v1alpha.QueryResponse.edges:type_name -> accessgraph.v1alpha.Edge + 24, // 0: accessgraph.v1alpha.QueryResponse.nodes:type_name -> accessgraph.v1alpha.Node + 25, // 1: accessgraph.v1alpha.QueryResponse.edges:type_name -> accessgraph.v1alpha.Edge 6, // 2: accessgraph.v1alpha.EventsStreamRequest.sync:type_name -> accessgraph.v1alpha.SyncOperation - 23, // 3: accessgraph.v1alpha.EventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.ResourceList - 24, // 4: accessgraph.v1alpha.EventsStreamRequest.delete:type_name -> accessgraph.v1alpha.ResourceHeaderList - 25, // 5: accessgraph.v1alpha.EventsStreamRequest.access_lists_members:type_name -> accessgraph.v1alpha.AccessListsMembers - 26, // 6: accessgraph.v1alpha.EventsStreamRequest.exclude_access_list_members:type_name -> accessgraph.v1alpha.ExcludeAccessListsMembers + 26, // 3: accessgraph.v1alpha.EventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.ResourceList + 27, // 4: accessgraph.v1alpha.EventsStreamRequest.delete:type_name -> accessgraph.v1alpha.ResourceHeaderList + 28, // 5: accessgraph.v1alpha.EventsStreamRequest.access_lists_members:type_name -> accessgraph.v1alpha.AccessListsMembers + 29, // 6: accessgraph.v1alpha.EventsStreamRequest.exclude_access_list_members:type_name -> accessgraph.v1alpha.ExcludeAccessListsMembers 6, // 7: accessgraph.v1alpha.EventsStreamV2Request.sync:type_name -> accessgraph.v1alpha.SyncOperation - 23, // 8: accessgraph.v1alpha.EventsStreamV2Request.upsert:type_name -> accessgraph.v1alpha.ResourceList - 24, // 9: accessgraph.v1alpha.EventsStreamV2Request.delete:type_name -> accessgraph.v1alpha.ResourceHeaderList - 25, // 10: accessgraph.v1alpha.EventsStreamV2Request.access_lists_members:type_name -> accessgraph.v1alpha.AccessListsMembers - 26, // 11: accessgraph.v1alpha.EventsStreamV2Request.exclude_access_list_members:type_name -> accessgraph.v1alpha.ExcludeAccessListsMembers + 26, // 8: accessgraph.v1alpha.EventsStreamV2Request.upsert:type_name -> accessgraph.v1alpha.ResourceList + 27, // 9: accessgraph.v1alpha.EventsStreamV2Request.delete:type_name -> accessgraph.v1alpha.ResourceHeaderList + 28, // 10: accessgraph.v1alpha.EventsStreamV2Request.access_lists_members:type_name -> accessgraph.v1alpha.AccessListsMembers + 29, // 11: accessgraph.v1alpha.EventsStreamV2Request.exclude_access_list_members:type_name -> accessgraph.v1alpha.ExcludeAccessListsMembers 9, // 12: accessgraph.v1alpha.EventsStreamV2Response.event:type_name -> accessgraph.v1alpha.AuditEvent - 27, // 13: accessgraph.v1alpha.AuditEvent.access_path_changed:type_name -> accessgraph.v1alpha.AccessPathChanged + 30, // 13: accessgraph.v1alpha.AuditEvent.access_path_changed:type_name -> accessgraph.v1alpha.AccessPathChanged 15, // 14: accessgraph.v1alpha.AWSEventsStreamRequest.sync:type_name -> accessgraph.v1alpha.AWSSyncOperation - 28, // 15: accessgraph.v1alpha.AWSEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.AWSResourceList - 28, // 16: accessgraph.v1alpha.AWSEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.AWSResourceList - 29, // 17: accessgraph.v1alpha.GitlabEventsStreamRequest.sync:type_name -> accessgraph.v1alpha.GitlabSyncOperation - 30, // 18: accessgraph.v1alpha.GitlabEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.GitlabResourceList - 30, // 19: accessgraph.v1alpha.GitlabEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.GitlabResourceList - 31, // 20: accessgraph.v1alpha.EntraEventsStreamRequest.sync:type_name -> accessgraph.v1alpha.EntraSyncOperation - 32, // 21: accessgraph.v1alpha.EntraEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.EntraResourceList - 32, // 22: accessgraph.v1alpha.EntraEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.EntraResourceList - 0, // 23: accessgraph.v1alpha.AccessGraphService.Query:input_type -> accessgraph.v1alpha.QueryRequest - 2, // 24: accessgraph.v1alpha.AccessGraphService.GetFile:input_type -> accessgraph.v1alpha.GetFileRequest - 4, // 25: accessgraph.v1alpha.AccessGraphService.EventsStream:input_type -> accessgraph.v1alpha.EventsStreamRequest - 5, // 26: accessgraph.v1alpha.AccessGraphService.EventsStreamV2:input_type -> accessgraph.v1alpha.EventsStreamV2Request - 10, // 27: accessgraph.v1alpha.AccessGraphService.Register:input_type -> accessgraph.v1alpha.RegisterRequest - 12, // 28: accessgraph.v1alpha.AccessGraphService.ReplaceCAs:input_type -> accessgraph.v1alpha.ReplaceCAsRequest - 14, // 29: accessgraph.v1alpha.AccessGraphService.AWSEventsStream:input_type -> accessgraph.v1alpha.AWSEventsStreamRequest - 17, // 30: accessgraph.v1alpha.AccessGraphService.GitlabEventsStream:input_type -> accessgraph.v1alpha.GitlabEventsStreamRequest - 19, // 31: accessgraph.v1alpha.AccessGraphService.EntraEventsStream:input_type -> accessgraph.v1alpha.EntraEventsStreamRequest - 1, // 32: accessgraph.v1alpha.AccessGraphService.Query:output_type -> accessgraph.v1alpha.QueryResponse - 3, // 33: accessgraph.v1alpha.AccessGraphService.GetFile:output_type -> accessgraph.v1alpha.GetFileResponse - 7, // 34: accessgraph.v1alpha.AccessGraphService.EventsStream:output_type -> accessgraph.v1alpha.EventsStreamResponse - 8, // 35: accessgraph.v1alpha.AccessGraphService.EventsStreamV2:output_type -> accessgraph.v1alpha.EventsStreamV2Response - 11, // 36: accessgraph.v1alpha.AccessGraphService.Register:output_type -> accessgraph.v1alpha.RegisterResponse - 13, // 37: accessgraph.v1alpha.AccessGraphService.ReplaceCAs:output_type -> accessgraph.v1alpha.ReplaceCAsResponse - 16, // 38: accessgraph.v1alpha.AccessGraphService.AWSEventsStream:output_type -> accessgraph.v1alpha.AWSEventsStreamResponse - 18, // 39: accessgraph.v1alpha.AccessGraphService.GitlabEventsStream:output_type -> accessgraph.v1alpha.GitlabEventsStreamResponse - 20, // 40: accessgraph.v1alpha.AccessGraphService.EntraEventsStream:output_type -> accessgraph.v1alpha.EntraEventsStreamResponse - 32, // [32:41] is the sub-list for method output_type - 23, // [23:32] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 31, // 15: accessgraph.v1alpha.AWSEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.AWSResourceList + 31, // 16: accessgraph.v1alpha.AWSEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.AWSResourceList + 32, // 17: accessgraph.v1alpha.GitlabEventsStreamRequest.sync:type_name -> accessgraph.v1alpha.GitlabSyncOperation + 33, // 18: accessgraph.v1alpha.GitlabEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.GitlabResourceList + 33, // 19: accessgraph.v1alpha.GitlabEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.GitlabResourceList + 34, // 20: accessgraph.v1alpha.EntraEventsStreamRequest.sync:type_name -> accessgraph.v1alpha.EntraSyncOperation + 35, // 21: accessgraph.v1alpha.EntraEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.EntraResourceList + 35, // 22: accessgraph.v1alpha.EntraEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.EntraResourceList + 22, // 23: accessgraph.v1alpha.NetIQEventsStreamRequest.sync:type_name -> accessgraph.v1alpha.NetIQSyncOperation + 36, // 24: accessgraph.v1alpha.NetIQEventsStreamRequest.upsert:type_name -> accessgraph.v1alpha.NetIQResourceList + 36, // 25: accessgraph.v1alpha.NetIQEventsStreamRequest.delete:type_name -> accessgraph.v1alpha.NetIQResourceList + 0, // 26: accessgraph.v1alpha.AccessGraphService.Query:input_type -> accessgraph.v1alpha.QueryRequest + 2, // 27: accessgraph.v1alpha.AccessGraphService.GetFile:input_type -> accessgraph.v1alpha.GetFileRequest + 4, // 28: accessgraph.v1alpha.AccessGraphService.EventsStream:input_type -> accessgraph.v1alpha.EventsStreamRequest + 5, // 29: accessgraph.v1alpha.AccessGraphService.EventsStreamV2:input_type -> accessgraph.v1alpha.EventsStreamV2Request + 10, // 30: accessgraph.v1alpha.AccessGraphService.Register:input_type -> accessgraph.v1alpha.RegisterRequest + 12, // 31: accessgraph.v1alpha.AccessGraphService.ReplaceCAs:input_type -> accessgraph.v1alpha.ReplaceCAsRequest + 14, // 32: accessgraph.v1alpha.AccessGraphService.AWSEventsStream:input_type -> accessgraph.v1alpha.AWSEventsStreamRequest + 17, // 33: accessgraph.v1alpha.AccessGraphService.GitlabEventsStream:input_type -> accessgraph.v1alpha.GitlabEventsStreamRequest + 19, // 34: accessgraph.v1alpha.AccessGraphService.EntraEventsStream:input_type -> accessgraph.v1alpha.EntraEventsStreamRequest + 21, // 35: accessgraph.v1alpha.AccessGraphService.NetIQEventsStream:input_type -> accessgraph.v1alpha.NetIQEventsStreamRequest + 1, // 36: accessgraph.v1alpha.AccessGraphService.Query:output_type -> accessgraph.v1alpha.QueryResponse + 3, // 37: accessgraph.v1alpha.AccessGraphService.GetFile:output_type -> accessgraph.v1alpha.GetFileResponse + 7, // 38: accessgraph.v1alpha.AccessGraphService.EventsStream:output_type -> accessgraph.v1alpha.EventsStreamResponse + 8, // 39: accessgraph.v1alpha.AccessGraphService.EventsStreamV2:output_type -> accessgraph.v1alpha.EventsStreamV2Response + 11, // 40: accessgraph.v1alpha.AccessGraphService.Register:output_type -> accessgraph.v1alpha.RegisterResponse + 13, // 41: accessgraph.v1alpha.AccessGraphService.ReplaceCAs:output_type -> accessgraph.v1alpha.ReplaceCAsResponse + 16, // 42: accessgraph.v1alpha.AccessGraphService.AWSEventsStream:output_type -> accessgraph.v1alpha.AWSEventsStreamResponse + 18, // 43: accessgraph.v1alpha.AccessGraphService.GitlabEventsStream:output_type -> accessgraph.v1alpha.GitlabEventsStreamResponse + 20, // 44: accessgraph.v1alpha.AccessGraphService.EntraEventsStream:output_type -> accessgraph.v1alpha.EntraEventsStreamResponse + 23, // 45: accessgraph.v1alpha.AccessGraphService.NetIQEventsStream:output_type -> accessgraph.v1alpha.NetIQEventsStreamResponse + 36, // [36:46] is the sub-list for method output_type + 26, // [26:36] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_access_graph_service_proto_init() } @@ -1688,6 +1896,7 @@ func file_accessgraph_v1alpha_access_graph_service_proto_init() { file_accessgraph_v1alpha_events_proto_init() file_accessgraph_v1alpha_gitlab_proto_init() file_accessgraph_v1alpha_graph_proto_init() + file_accessgraph_v1alpha_netiq_proto_init() file_accessgraph_v1alpha_resources_proto_init() file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[4].OneofWrappers = []any{ (*EventsStreamRequest_Sync)(nil), @@ -1724,13 +1933,18 @@ func file_accessgraph_v1alpha_access_graph_service_proto_init() { (*EntraEventsStreamRequest_Upsert)(nil), (*EntraEventsStreamRequest_Delete)(nil), } + file_accessgraph_v1alpha_access_graph_service_proto_msgTypes[21].OneofWrappers = []any{ + (*NetIQEventsStreamRequest_Sync)(nil), + (*NetIQEventsStreamRequest_Upsert)(nil), + (*NetIQEventsStreamRequest_Delete)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_accessgraph_v1alpha_access_graph_service_proto_rawDesc, NumEnums: 0, - NumMessages: 21, + NumMessages: 24, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/proto/go/accessgraph/v1alpha/access_graph_service_grpc.pb.go b/gen/proto/go/accessgraph/v1alpha/access_graph_service_grpc.pb.go index 25084921269d9..6ac7cb8f4de55 100644 --- a/gen/proto/go/accessgraph/v1alpha/access_graph_service_grpc.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/access_graph_service_grpc.pb.go @@ -45,6 +45,7 @@ const ( AccessGraphService_AWSEventsStream_FullMethodName = "/accessgraph.v1alpha.AccessGraphService/AWSEventsStream" AccessGraphService_GitlabEventsStream_FullMethodName = "/accessgraph.v1alpha.AccessGraphService/GitlabEventsStream" AccessGraphService_EntraEventsStream_FullMethodName = "/accessgraph.v1alpha.AccessGraphService/EntraEventsStream" + AccessGraphService_NetIQEventsStream_FullMethodName = "/accessgraph.v1alpha.AccessGraphService/NetIQEventsStream" ) // AccessGraphServiceClient is the client API for AccessGraphService service. @@ -92,6 +93,8 @@ type AccessGraphServiceClient interface { GitlabEventsStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[GitlabEventsStreamRequest, GitlabEventsStreamResponse], error) // EntraEventsStream is a stream of commands to the Entra ID SSO importer. EntraEventsStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[EntraEventsStreamRequest, EntraEventsStreamResponse], error) + // NetIQEventsStream is a stream of commands to the NetIQ importer. + NetIQEventsStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[NetIQEventsStreamRequest, NetIQEventsStreamResponse], error) } type accessGraphServiceClient struct { @@ -207,6 +210,19 @@ func (c *accessGraphServiceClient) EntraEventsStream(ctx context.Context, opts . // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type AccessGraphService_EntraEventsStreamClient = grpc.BidiStreamingClient[EntraEventsStreamRequest, EntraEventsStreamResponse] +func (c *accessGraphServiceClient) NetIQEventsStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[NetIQEventsStreamRequest, NetIQEventsStreamResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AccessGraphService_ServiceDesc.Streams[5], AccessGraphService_NetIQEventsStream_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[NetIQEventsStreamRequest, NetIQEventsStreamResponse]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type AccessGraphService_NetIQEventsStreamClient = grpc.BidiStreamingClient[NetIQEventsStreamRequest, NetIQEventsStreamResponse] + // AccessGraphServiceServer is the server API for AccessGraphService service. // All implementations must embed UnimplementedAccessGraphServiceServer // for forward compatibility. @@ -252,6 +268,8 @@ type AccessGraphServiceServer interface { GitlabEventsStream(grpc.BidiStreamingServer[GitlabEventsStreamRequest, GitlabEventsStreamResponse]) error // EntraEventsStream is a stream of commands to the Entra ID SSO importer. EntraEventsStream(grpc.BidiStreamingServer[EntraEventsStreamRequest, EntraEventsStreamResponse]) error + // NetIQEventsStream is a stream of commands to the NetIQ importer. + NetIQEventsStream(grpc.BidiStreamingServer[NetIQEventsStreamRequest, NetIQEventsStreamResponse]) error mustEmbedUnimplementedAccessGraphServiceServer() } @@ -289,6 +307,9 @@ func (UnimplementedAccessGraphServiceServer) GitlabEventsStream(grpc.BidiStreami func (UnimplementedAccessGraphServiceServer) EntraEventsStream(grpc.BidiStreamingServer[EntraEventsStreamRequest, EntraEventsStreamResponse]) error { return status.Errorf(codes.Unimplemented, "method EntraEventsStream not implemented") } +func (UnimplementedAccessGraphServiceServer) NetIQEventsStream(grpc.BidiStreamingServer[NetIQEventsStreamRequest, NetIQEventsStreamResponse]) error { + return status.Errorf(codes.Unimplemented, "method NetIQEventsStream not implemented") +} func (UnimplementedAccessGraphServiceServer) mustEmbedUnimplementedAccessGraphServiceServer() {} func (UnimplementedAccessGraphServiceServer) testEmbeddedByValue() {} @@ -417,6 +438,13 @@ func _AccessGraphService_EntraEventsStream_Handler(srv interface{}, stream grpc. // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type AccessGraphService_EntraEventsStreamServer = grpc.BidiStreamingServer[EntraEventsStreamRequest, EntraEventsStreamResponse] +func _AccessGraphService_NetIQEventsStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(AccessGraphServiceServer).NetIQEventsStream(&grpc.GenericServerStream[NetIQEventsStreamRequest, NetIQEventsStreamResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type AccessGraphService_NetIQEventsStreamServer = grpc.BidiStreamingServer[NetIQEventsStreamRequest, NetIQEventsStreamResponse] + // AccessGraphService_ServiceDesc is the grpc.ServiceDesc for AccessGraphService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -470,6 +498,12 @@ var AccessGraphService_ServiceDesc = grpc.ServiceDesc{ ServerStreams: true, ClientStreams: true, }, + { + StreamName: "NetIQEventsStream", + Handler: _AccessGraphService_NetIQEventsStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, }, Metadata: "accessgraph/v1alpha/access_graph_service.proto", } diff --git a/gen/proto/go/accessgraph/v1alpha/netiq.pb.go b/gen/proto/go/accessgraph/v1alpha/netiq.pb.go new file mode 100644 index 0000000000000..5038d9db6f143 --- /dev/null +++ b/gen/proto/go/accessgraph/v1alpha/netiq.pb.go @@ -0,0 +1,1324 @@ +// +// 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 . + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: accessgraph/v1alpha/netiq.proto + +package accessgraphv1alpha + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// RoleRecipientType is the type of the recipient. +type RoleRecipientType int32 + +const ( + // ROLE_RECIPIENT_TYPE_UNSPECIFIED is a unspecified role recipient type. + RoleRecipientType_ROLE_RECIPIENT_TYPE_UNSPECIFIED RoleRecipientType = 0 + // ROLE_RECIPIENT_TYPE_USER represents a user being member of a role. + RoleRecipientType_ROLE_RECIPIENT_TYPE_USER RoleRecipientType = 1 + // ROLE_RECIPIENT_TYPE_GROUP represents a group being member of a role. + RoleRecipientType_ROLE_RECIPIENT_TYPE_GROUP RoleRecipientType = 2 +) + +// Enum value maps for RoleRecipientType. +var ( + RoleRecipientType_name = map[int32]string{ + 0: "ROLE_RECIPIENT_TYPE_UNSPECIFIED", + 1: "ROLE_RECIPIENT_TYPE_USER", + 2: "ROLE_RECIPIENT_TYPE_GROUP", + } + RoleRecipientType_value = map[string]int32{ + "ROLE_RECIPIENT_TYPE_UNSPECIFIED": 0, + "ROLE_RECIPIENT_TYPE_USER": 1, + "ROLE_RECIPIENT_TYPE_GROUP": 2, + } +) + +func (x RoleRecipientType) Enum() *RoleRecipientType { + p := new(RoleRecipientType) + *p = x + return p +} + +func (x RoleRecipientType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RoleRecipientType) Descriptor() protoreflect.EnumDescriptor { + return file_accessgraph_v1alpha_netiq_proto_enumTypes[0].Descriptor() +} + +func (RoleRecipientType) Type() protoreflect.EnumType { + return &file_accessgraph_v1alpha_netiq_proto_enumTypes[0] +} + +func (x RoleRecipientType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RoleRecipientType.Descriptor instead. +func (RoleRecipientType) EnumDescriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{0} +} + +// NetIQResourceList is a request that contains resources to be sync. +type NetIQResourceList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // resources is a list of NetIQ resources to sync. + Resources []*NetIQObject `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` +} + +func (x *NetIQResourceList) Reset() { + *x = NetIQResourceList{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQResourceList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQResourceList) ProtoMessage() {} + +func (x *NetIQResourceList) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQResourceList.ProtoReflect.Descriptor instead. +func (*NetIQResourceList) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{0} +} + +func (x *NetIQResourceList) GetResources() []*NetIQObject { + if x != nil { + return x.Resources + } + return nil +} + +// NetIQObject represents a NetIQ resource +type NetIQObject struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Object: + // + // *NetIQObject_Group + // *NetIQObject_GroupMember + // *NetIQObject_Resource + // *NetIQObject_Role + // *NetIQObject_ParentRoleRef + // *NetIQObject_User + // *NetIQObject_ResourceRoleRef + // *NetIQObject_RoleMemberRef + Object isNetIQObject_Object `protobuf_oneof:"object"` +} + +func (x *NetIQObject) Reset() { + *x = NetIQObject{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQObject) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQObject) ProtoMessage() {} + +func (x *NetIQObject) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQObject.ProtoReflect.Descriptor instead. +func (*NetIQObject) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{1} +} + +func (m *NetIQObject) GetObject() isNetIQObject_Object { + if m != nil { + return m.Object + } + return nil +} + +func (x *NetIQObject) GetGroup() *NetIQGroup { + if x, ok := x.GetObject().(*NetIQObject_Group); ok { + return x.Group + } + return nil +} + +func (x *NetIQObject) GetGroupMember() *NetIQGroupMember { + if x, ok := x.GetObject().(*NetIQObject_GroupMember); ok { + return x.GroupMember + } + return nil +} + +func (x *NetIQObject) GetResource() *NetIQResource { + if x, ok := x.GetObject().(*NetIQObject_Resource); ok { + return x.Resource + } + return nil +} + +func (x *NetIQObject) GetRole() *NetIQRole { + if x, ok := x.GetObject().(*NetIQObject_Role); ok { + return x.Role + } + return nil +} + +func (x *NetIQObject) GetParentRoleRef() *NetIQRoleRef { + if x, ok := x.GetObject().(*NetIQObject_ParentRoleRef); ok { + return x.ParentRoleRef + } + return nil +} + +func (x *NetIQObject) GetUser() *NetIQUser { + if x, ok := x.GetObject().(*NetIQObject_User); ok { + return x.User + } + return nil +} + +func (x *NetIQObject) GetResourceRoleRef() *NetIQResourceAssignmentRef { + if x, ok := x.GetObject().(*NetIQObject_ResourceRoleRef); ok { + return x.ResourceRoleRef + } + return nil +} + +func (x *NetIQObject) GetRoleMemberRef() *NetIQMemberAssignmentRef { + if x, ok := x.GetObject().(*NetIQObject_RoleMemberRef); ok { + return x.RoleMemberRef + } + return nil +} + +type isNetIQObject_Object interface { + isNetIQObject_Object() +} + +type NetIQObject_Group struct { + // group represents a NetIQ group in an organization. + Group *NetIQGroup `protobuf:"bytes,1,opt,name=group,proto3,oneof"` +} + +type NetIQObject_GroupMember struct { + // group_member represents a NetIQ group member. + GroupMember *NetIQGroupMember `protobuf:"bytes,2,opt,name=group_member,json=groupMember,proto3,oneof"` +} + +type NetIQObject_Resource struct { + // resource represents a NetIQ resource. + Resource *NetIQResource `protobuf:"bytes,3,opt,name=resource,proto3,oneof"` +} + +type NetIQObject_Role struct { + // role represents a role with certain access levels to a resource. + Role *NetIQRole `protobuf:"bytes,4,opt,name=role,proto3,oneof"` +} + +type NetIQObject_ParentRoleRef struct { + // parent_role_ref represents a parent relationship between roles. + ParentRoleRef *NetIQRoleRef `protobuf:"bytes,5,opt,name=parent_role_ref,json=parentRoleRef,proto3,oneof"` +} + +type NetIQObject_User struct { + // user represents a NetIQ user. + User *NetIQUser `protobuf:"bytes,6,opt,name=user,proto3,oneof"` +} + +type NetIQObject_ResourceRoleRef struct { + // resource_role_ref represents a resource assignment to a role. + ResourceRoleRef *NetIQResourceAssignmentRef `protobuf:"bytes,7,opt,name=resource_role_ref,json=resourceRoleRef,proto3,oneof"` +} + +type NetIQObject_RoleMemberRef struct { + // role_member_ref represents a member being member of a role. + RoleMemberRef *NetIQMemberAssignmentRef `protobuf:"bytes,8,opt,name=role_member_ref,json=roleMemberRef,proto3,oneof"` +} + +func (*NetIQObject_Group) isNetIQObject_Object() {} + +func (*NetIQObject_GroupMember) isNetIQObject_Object() {} + +func (*NetIQObject_Resource) isNetIQObject_Object() {} + +func (*NetIQObject_Role) isNetIQObject_Object() {} + +func (*NetIQObject_ParentRoleRef) isNetIQObject_Object() {} + +func (*NetIQObject_User) isNetIQObject_Object() {} + +func (*NetIQObject_ResourceRoleRef) isNetIQObject_Object() {} + +func (*NetIQObject_RoleMemberRef) isNetIQObject_Object() {} + +// NetIQGroup represents a NetIQ group +type NetIQGroup struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the group name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // id is the universal identifier for the group. + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // description is the group description. + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *NetIQGroup) Reset() { + *x = NetIQGroup{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQGroup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQGroup) ProtoMessage() {} + +func (x *NetIQGroup) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQGroup.ProtoReflect.Descriptor instead. +func (*NetIQGroup) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{2} +} + +func (x *NetIQGroup) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NetIQGroup) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NetIQGroup) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +// NetIQGroupMember represents a NetIQ group member +type NetIQGroupMember struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // group_id is the group id. + GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + // user_id is the universal identifier for the user. + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // is_group_assignment is a flag that determines whether the member is a group assignment. + IsGroupAssignment bool `protobuf:"varint,3,opt,name=is_group_assignment,json=isGroupAssignment,proto3" json:"is_group_assignment,omitempty"` +} + +func (x *NetIQGroupMember) Reset() { + *x = NetIQGroupMember{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQGroupMember) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQGroupMember) ProtoMessage() {} + +func (x *NetIQGroupMember) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQGroupMember.ProtoReflect.Descriptor instead. +func (*NetIQGroupMember) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{3} +} + +func (x *NetIQGroupMember) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *NetIQGroupMember) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *NetIQGroupMember) GetIsGroupAssignment() bool { + if x != nil { + return x.IsGroupAssignment + } + return false +} + +// NetIQResource represents a NetIQ resource +type NetIQResource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the resource name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // id is the universal identifier for the resource. + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // description is the project description. + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // categories is the list of categories the resource belongs to. + Categories []*NetIQCategory `protobuf:"bytes,4,rep,name=categories,proto3" json:"categories,omitempty"` +} + +func (x *NetIQResource) Reset() { + *x = NetIQResource{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQResource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQResource) ProtoMessage() {} + +func (x *NetIQResource) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQResource.ProtoReflect.Descriptor instead. +func (*NetIQResource) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{4} +} + +func (x *NetIQResource) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NetIQResource) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NetIQResource) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *NetIQResource) GetCategories() []*NetIQCategory { + if x != nil { + return x.Categories + } + return nil +} + +// NetIQCategory is a resource category. +type NetIQCategory struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the resource name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // id is the universal identifier for the category. + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *NetIQCategory) Reset() { + *x = NetIQCategory{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQCategory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQCategory) ProtoMessage() {} + +func (x *NetIQCategory) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQCategory.ProtoReflect.Descriptor instead. +func (*NetIQCategory) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{5} +} + +func (x *NetIQCategory) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NetIQCategory) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// NetIQRole represents a NetIQ role +type NetIQRole struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the resource name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // id is the universal identifier for the role. + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // description is the project description. + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // categories is the list of categories the resource belongs to. + Categories []*NetIQCategory `protobuf:"bytes,4,rep,name=categories,proto3" json:"categories,omitempty"` + Level *NetIQRole_RoleLevel `protobuf:"bytes,5,opt,name=level,proto3" json:"level,omitempty"` +} + +func (x *NetIQRole) Reset() { + *x = NetIQRole{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQRole) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQRole) ProtoMessage() {} + +func (x *NetIQRole) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQRole.ProtoReflect.Descriptor instead. +func (*NetIQRole) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{6} +} + +func (x *NetIQRole) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NetIQRole) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NetIQRole) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *NetIQRole) GetCategories() []*NetIQCategory { + if x != nil { + return x.Categories + } + return nil +} + +func (x *NetIQRole) GetLevel() *NetIQRole_RoleLevel { + if x != nil { + return x.Level + } + return nil +} + +// NetIQRoleRef represents a NetIQ Role reference. +type NetIQRoleRef struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // child_role_id is the group id of a role that is a child role of parent_role_id. + ChildRoleId string `protobuf:"bytes,1,opt,name=child_role_id,json=childRoleId,proto3" json:"child_role_id,omitempty"` + // parent_role_id is the universal identifier for the role that is parent to child_role_id. + ParentRoleId string `protobuf:"bytes,2,opt,name=parent_role_id,json=parentRoleId,proto3" json:"parent_role_id,omitempty"` + // level is the level of the role. + Level int32 `protobuf:"varint,3,opt,name=level,proto3" json:"level,omitempty"` + // request_description is the description of the request. + RequestDescription string `protobuf:"bytes,4,opt,name=request_description,json=requestDescription,proto3" json:"request_description,omitempty"` +} + +func (x *NetIQRoleRef) Reset() { + *x = NetIQRoleRef{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQRoleRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQRoleRef) ProtoMessage() {} + +func (x *NetIQRoleRef) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQRoleRef.ProtoReflect.Descriptor instead. +func (*NetIQRoleRef) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{7} +} + +func (x *NetIQRoleRef) GetChildRoleId() string { + if x != nil { + return x.ChildRoleId + } + return "" +} + +func (x *NetIQRoleRef) GetParentRoleId() string { + if x != nil { + return x.ParentRoleId + } + return "" +} + +func (x *NetIQRoleRef) GetLevel() int32 { + if x != nil { + return x.Level + } + return 0 +} + +func (x *NetIQRoleRef) GetRequestDescription() string { + if x != nil { + return x.RequestDescription + } + return "" +} + +// NetIQUser represents a NetIQ user. +type NetIQUser struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // id is the id of the user. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // email is the user's email. + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // name is the user's name. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + // is_disabled indicates if a user is disabled. + IsDisabled bool `protobuf:"varint,4,opt,name=is_disabled,json=isDisabled,proto3" json:"is_disabled,omitempty"` +} + +func (x *NetIQUser) Reset() { + *x = NetIQUser{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQUser) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQUser) ProtoMessage() {} + +func (x *NetIQUser) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQUser.ProtoReflect.Descriptor instead. +func (*NetIQUser) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{8} +} + +func (x *NetIQUser) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NetIQUser) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *NetIQUser) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NetIQUser) GetIsDisabled() bool { + if x != nil { + return x.IsDisabled + } + return false +} + +// NetIQResourceAssignmentRef represents a NetIQ resource assignment reference. +type NetIQResourceAssignmentRef struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // role_id is the group id of a role that is assigned to resource_id. + RoleId string `protobuf:"bytes,1,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + // resource_id is the universal identifier for the resource that is assigned to role_id. + ResourceId string `protobuf:"bytes,2,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"` + // mapping_description is the description of the mapping. + MappingDescription string `protobuf:"bytes,4,opt,name=mapping_description,json=mappingDescription,proto3" json:"mapping_description,omitempty"` + // status_code is the status code of the role assignment. + StatusCode uint32 `protobuf:"varint,5,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"` +} + +func (x *NetIQResourceAssignmentRef) Reset() { + *x = NetIQResourceAssignmentRef{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQResourceAssignmentRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQResourceAssignmentRef) ProtoMessage() {} + +func (x *NetIQResourceAssignmentRef) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQResourceAssignmentRef.ProtoReflect.Descriptor instead. +func (*NetIQResourceAssignmentRef) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{9} +} + +func (x *NetIQResourceAssignmentRef) GetRoleId() string { + if x != nil { + return x.RoleId + } + return "" +} + +func (x *NetIQResourceAssignmentRef) GetResourceId() string { + if x != nil { + return x.ResourceId + } + return "" +} + +func (x *NetIQResourceAssignmentRef) GetMappingDescription() string { + if x != nil { + return x.MappingDescription + } + return "" +} + +func (x *NetIQResourceAssignmentRef) GetStatusCode() uint32 { + if x != nil { + return x.StatusCode + } + return 0 +} + +// NetIQMemberAssignmentRef represents a NetIQ resource assignment reference. +type NetIQMemberAssignmentRef struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // role_id is the group id of a role that user_id is member of. + RoleId string `protobuf:"bytes,1,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + // dn is the universal identifier for the user that is member of role_id. + Dn string `protobuf:"bytes,2,opt,name=dn,proto3" json:"dn,omitempty"` + // recipient_type identifies the recipient provenance. + RecipientType RoleRecipientType `protobuf:"varint,3,opt,name=recipient_type,json=recipientType,proto3,enum=accessgraph.v1alpha.RoleRecipientType" json:"recipient_type,omitempty"` + // recipient_type_subcontainer is the sub container of the recipient type. + RecipientTypeSubcontainer string `protobuf:"bytes,4,opt,name=recipient_type_subcontainer,json=recipientTypeSubcontainer,proto3" json:"recipient_type_subcontainer,omitempty"` + // status_code is the status code of the role assignment. + StatusCode uint32 `protobuf:"varint,5,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"` + // StatusDstatus_displayisplay is the display of the status. + StatusDisplay string `protobuf:"bytes,6,opt,name=status_display,json=statusDisplay,proto3" json:"status_display,omitempty"` + // effective_date is the effective date of the role assignment. + EffectiveDate *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=effective_date,json=effectiveDate,proto3" json:"effective_date,omitempty"` + // expiry_date is the expiry date of the role assignment. + ExpiryDate *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=expiry_date,json=expiryDate,proto3" json:"expiry_date,omitempty"` + // description is the description of the role assignment. + Description string `protobuf:"bytes,9,opt,name=description,proto3" json:"description,omitempty"` + // grant is a flag that determines whether the role assignment is granted. + Grant bool `protobuf:"varint,10,opt,name=grant,proto3" json:"grant,omitempty"` +} + +func (x *NetIQMemberAssignmentRef) Reset() { + *x = NetIQMemberAssignmentRef{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQMemberAssignmentRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQMemberAssignmentRef) ProtoMessage() {} + +func (x *NetIQMemberAssignmentRef) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQMemberAssignmentRef.ProtoReflect.Descriptor instead. +func (*NetIQMemberAssignmentRef) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{10} +} + +func (x *NetIQMemberAssignmentRef) GetRoleId() string { + if x != nil { + return x.RoleId + } + return "" +} + +func (x *NetIQMemberAssignmentRef) GetDn() string { + if x != nil { + return x.Dn + } + return "" +} + +func (x *NetIQMemberAssignmentRef) GetRecipientType() RoleRecipientType { + if x != nil { + return x.RecipientType + } + return RoleRecipientType_ROLE_RECIPIENT_TYPE_UNSPECIFIED +} + +func (x *NetIQMemberAssignmentRef) GetRecipientTypeSubcontainer() string { + if x != nil { + return x.RecipientTypeSubcontainer + } + return "" +} + +func (x *NetIQMemberAssignmentRef) GetStatusCode() uint32 { + if x != nil { + return x.StatusCode + } + return 0 +} + +func (x *NetIQMemberAssignmentRef) GetStatusDisplay() string { + if x != nil { + return x.StatusDisplay + } + return "" +} + +func (x *NetIQMemberAssignmentRef) GetEffectiveDate() *timestamppb.Timestamp { + if x != nil { + return x.EffectiveDate + } + return nil +} + +func (x *NetIQMemberAssignmentRef) GetExpiryDate() *timestamppb.Timestamp { + if x != nil { + return x.ExpiryDate + } + return nil +} + +func (x *NetIQMemberAssignmentRef) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *NetIQMemberAssignmentRef) GetGrant() bool { + if x != nil { + return x.Grant + } + return false +} + +// RoleLevel represents the role level. +type NetIQRole_RoleLevel struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the name of the role level. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // level is the level of the role level. + Level int32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + // cn is the common name. + Cn string `protobuf:"bytes,3,opt,name=cn,proto3" json:"cn,omitempty"` +} + +func (x *NetIQRole_RoleLevel) Reset() { + *x = NetIQRole_RoleLevel{} + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetIQRole_RoleLevel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetIQRole_RoleLevel) ProtoMessage() {} + +func (x *NetIQRole_RoleLevel) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_netiq_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetIQRole_RoleLevel.ProtoReflect.Descriptor instead. +func (*NetIQRole_RoleLevel) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_netiq_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *NetIQRole_RoleLevel) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NetIQRole_RoleLevel) GetLevel() int32 { + if x != nil { + return x.Level + } + return 0 +} + +func (x *NetIQRole_RoleLevel) GetCn() string { + if x != nil { + return x.Cn + } + return "" +} + +var File_accessgraph_v1alpha_netiq_proto protoreflect.FileDescriptor + +var file_accessgraph_v1alpha_netiq_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2f, 0x6e, 0x65, 0x74, 0x69, 0x71, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x13, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x53, 0x0a, 0x11, 0x4e, 0x65, 0x74, 0x49, 0x51, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x09, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xcf, 0x04, 0x0a, + 0x0b, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x37, 0x0a, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x4a, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x40, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x6f, 0x6c, + 0x65, 0x48, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, + 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x12, 0x34, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, + 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x5d, 0x0a, 0x11, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x72, 0x65, + 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, + 0x74, 0x49, 0x51, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x12, 0x57, 0x0a, 0x0f, 0x72, + 0x6f, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x6f, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x65, 0x66, 0x42, 0x08, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x52, + 0x0a, 0x0a, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x76, 0x0a, 0x10, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, + 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x73, + 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x0d, 0x4e, + 0x65, 0x74, 0x49, 0x51, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, + 0x49, 0x51, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x0d, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x43, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x9c, 0x02, 0x0a, 0x09, + 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x42, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x43, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x69, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x6f, + 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, + 0x76, 0x65, 0x6c, 0x1a, 0x45, 0x0a, 0x09, 0x52, 0x6f, 0x6c, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x63, 0x6e, 0x22, 0x9f, 0x01, 0x0a, 0x0c, 0x4e, + 0x65, 0x74, 0x49, 0x51, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x12, 0x22, 0x0a, 0x0d, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, + 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, + 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2f, 0x0a, 0x13, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x66, 0x0a, 0x09, + 0x4e, 0x65, 0x74, 0x49, 0x51, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x44, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x22, 0xa8, 0x01, 0x0a, 0x1a, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x66, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2f, 0x0a, + 0x13, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x22, + 0xd2, 0x03, 0x0a, 0x18, 0x4e, 0x65, 0x74, 0x49, 0x51, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x17, 0x0a, 0x07, + 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, + 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x64, 0x6e, 0x12, 0x4d, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x3e, 0x0a, 0x1b, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x72, 0x65, 0x63, 0x69, 0x70, + 0x69, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x41, 0x0a, 0x0e, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, + 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, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, + 0x3b, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x08, + 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, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x44, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, + 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x67, + 0x72, 0x61, 0x6e, 0x74, 0x2a, 0x75, 0x0a, 0x11, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x4c, + 0x45, 0x5f, 0x52, 0x45, 0x43, 0x49, 0x50, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, + 0x0a, 0x18, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x49, 0x50, 0x49, 0x45, 0x4e, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, + 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x49, 0x50, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x02, 0x42, 0x57, 0x5a, 0x55, 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, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_accessgraph_v1alpha_netiq_proto_rawDescOnce sync.Once + file_accessgraph_v1alpha_netiq_proto_rawDescData = file_accessgraph_v1alpha_netiq_proto_rawDesc +) + +func file_accessgraph_v1alpha_netiq_proto_rawDescGZIP() []byte { + file_accessgraph_v1alpha_netiq_proto_rawDescOnce.Do(func() { + file_accessgraph_v1alpha_netiq_proto_rawDescData = protoimpl.X.CompressGZIP(file_accessgraph_v1alpha_netiq_proto_rawDescData) + }) + return file_accessgraph_v1alpha_netiq_proto_rawDescData +} + +var file_accessgraph_v1alpha_netiq_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_accessgraph_v1alpha_netiq_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_accessgraph_v1alpha_netiq_proto_goTypes = []any{ + (RoleRecipientType)(0), // 0: accessgraph.v1alpha.RoleRecipientType + (*NetIQResourceList)(nil), // 1: accessgraph.v1alpha.NetIQResourceList + (*NetIQObject)(nil), // 2: accessgraph.v1alpha.NetIQObject + (*NetIQGroup)(nil), // 3: accessgraph.v1alpha.NetIQGroup + (*NetIQGroupMember)(nil), // 4: accessgraph.v1alpha.NetIQGroupMember + (*NetIQResource)(nil), // 5: accessgraph.v1alpha.NetIQResource + (*NetIQCategory)(nil), // 6: accessgraph.v1alpha.NetIQCategory + (*NetIQRole)(nil), // 7: accessgraph.v1alpha.NetIQRole + (*NetIQRoleRef)(nil), // 8: accessgraph.v1alpha.NetIQRoleRef + (*NetIQUser)(nil), // 9: accessgraph.v1alpha.NetIQUser + (*NetIQResourceAssignmentRef)(nil), // 10: accessgraph.v1alpha.NetIQResourceAssignmentRef + (*NetIQMemberAssignmentRef)(nil), // 11: accessgraph.v1alpha.NetIQMemberAssignmentRef + (*NetIQRole_RoleLevel)(nil), // 12: accessgraph.v1alpha.NetIQRole.RoleLevel + (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp +} +var file_accessgraph_v1alpha_netiq_proto_depIdxs = []int32{ + 2, // 0: accessgraph.v1alpha.NetIQResourceList.resources:type_name -> accessgraph.v1alpha.NetIQObject + 3, // 1: accessgraph.v1alpha.NetIQObject.group:type_name -> accessgraph.v1alpha.NetIQGroup + 4, // 2: accessgraph.v1alpha.NetIQObject.group_member:type_name -> accessgraph.v1alpha.NetIQGroupMember + 5, // 3: accessgraph.v1alpha.NetIQObject.resource:type_name -> accessgraph.v1alpha.NetIQResource + 7, // 4: accessgraph.v1alpha.NetIQObject.role:type_name -> accessgraph.v1alpha.NetIQRole + 8, // 5: accessgraph.v1alpha.NetIQObject.parent_role_ref:type_name -> accessgraph.v1alpha.NetIQRoleRef + 9, // 6: accessgraph.v1alpha.NetIQObject.user:type_name -> accessgraph.v1alpha.NetIQUser + 10, // 7: accessgraph.v1alpha.NetIQObject.resource_role_ref:type_name -> accessgraph.v1alpha.NetIQResourceAssignmentRef + 11, // 8: accessgraph.v1alpha.NetIQObject.role_member_ref:type_name -> accessgraph.v1alpha.NetIQMemberAssignmentRef + 6, // 9: accessgraph.v1alpha.NetIQResource.categories:type_name -> accessgraph.v1alpha.NetIQCategory + 6, // 10: accessgraph.v1alpha.NetIQRole.categories:type_name -> accessgraph.v1alpha.NetIQCategory + 12, // 11: accessgraph.v1alpha.NetIQRole.level:type_name -> accessgraph.v1alpha.NetIQRole.RoleLevel + 0, // 12: accessgraph.v1alpha.NetIQMemberAssignmentRef.recipient_type:type_name -> accessgraph.v1alpha.RoleRecipientType + 13, // 13: accessgraph.v1alpha.NetIQMemberAssignmentRef.effective_date:type_name -> google.protobuf.Timestamp + 13, // 14: accessgraph.v1alpha.NetIQMemberAssignmentRef.expiry_date:type_name -> google.protobuf.Timestamp + 15, // [15:15] is the sub-list for method output_type + 15, // [15:15] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name +} + +func init() { file_accessgraph_v1alpha_netiq_proto_init() } +func file_accessgraph_v1alpha_netiq_proto_init() { + if File_accessgraph_v1alpha_netiq_proto != nil { + return + } + file_accessgraph_v1alpha_netiq_proto_msgTypes[1].OneofWrappers = []any{ + (*NetIQObject_Group)(nil), + (*NetIQObject_GroupMember)(nil), + (*NetIQObject_Resource)(nil), + (*NetIQObject_Role)(nil), + (*NetIQObject_ParentRoleRef)(nil), + (*NetIQObject_User)(nil), + (*NetIQObject_ResourceRoleRef)(nil), + (*NetIQObject_RoleMemberRef)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_accessgraph_v1alpha_netiq_proto_rawDesc, + NumEnums: 1, + NumMessages: 12, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_accessgraph_v1alpha_netiq_proto_goTypes, + DependencyIndexes: file_accessgraph_v1alpha_netiq_proto_depIdxs, + EnumInfos: file_accessgraph_v1alpha_netiq_proto_enumTypes, + MessageInfos: file_accessgraph_v1alpha_netiq_proto_msgTypes, + }.Build() + File_accessgraph_v1alpha_netiq_proto = out.File + file_accessgraph_v1alpha_netiq_proto_rawDesc = nil + file_accessgraph_v1alpha_netiq_proto_goTypes = nil + file_accessgraph_v1alpha_netiq_proto_depIdxs = nil +} diff --git a/proto/accessgraph/v1alpha/access_graph_service.proto b/proto/accessgraph/v1alpha/access_graph_service.proto index 979e781290c94..f032b2397ec02 100644 --- a/proto/accessgraph/v1alpha/access_graph_service.proto +++ b/proto/accessgraph/v1alpha/access_graph_service.proto @@ -25,6 +25,7 @@ import "accessgraph/v1alpha/entra.proto"; import "accessgraph/v1alpha/events.proto"; import "accessgraph/v1alpha/gitlab.proto"; import "accessgraph/v1alpha/graph.proto"; +import "accessgraph/v1alpha/netiq.proto"; import "accessgraph/v1alpha/resources.proto"; option go_package = "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha;accessgraphv1alpha"; @@ -86,6 +87,9 @@ service AccessGraphService { // EntraEventsStream is a stream of commands to the Entra ID SSO importer. rpc EntraEventsStream(stream EntraEventsStreamRequest) returns (stream EntraEventsStreamResponse); + + // NetIQEventsStream is a stream of commands to the NetIQ importer. + rpc NetIQEventsStream(stream NetIQEventsStreamRequest) returns (stream NetIQEventsStreamResponse); } // QueryRequest is a request to query the access graph. @@ -265,3 +269,22 @@ message EntraEventsStreamRequest { // EntraEventsStreamResponse is the response from GitlabEventsStream. message EntraEventsStreamResponse {} + +// NetIQEventsStreamRequest is a request to send commands to the NetIQ importer +message NetIQEventsStreamRequest { + oneof operation { + // sync is a command to sync the access graph with the NetIQ state. + NetIQSyncOperation sync = 1; + // upsert is a command to put a resource into the access graph or update it. + NetIQResourceList upsert = 2; + // delete is a command to delete a resource from the access graph when it's deleted. + NetIQResourceList delete = 3; + } +} + +// NetIQSyncOperation is a command that Teleport sends to the access graph service +// at the end of the sync process. +message NetIQSyncOperation {} + +// NetIQEventsStreamResponse is a response from NetIQEventsStream +message NetIQEventsStreamResponse {} diff --git a/proto/accessgraph/v1alpha/netiq.proto b/proto/accessgraph/v1alpha/netiq.proto new file mode 100644 index 0000000000000..eb108781bbaaa --- /dev/null +++ b/proto/accessgraph/v1alpha/netiq.proto @@ -0,0 +1,187 @@ +/* + * 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 . + */ + +syntax = "proto3"; + +package accessgraph.v1alpha; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha;accessgraphv1alpha"; + +// NetIQResourceList is a request that contains resources to be sync. +message NetIQResourceList { + // resources is a list of NetIQ resources to sync. + repeated NetIQObject resources = 1; +} + +// NetIQObject represents a NetIQ resource +message NetIQObject { + oneof object { + // group represents a NetIQ group in an organization. + NetIQGroup group = 1; + // group_member represents a NetIQ group member. + NetIQGroupMember group_member = 2; + // resource represents a NetIQ resource. + NetIQResource resource = 3; + // role represents a role with certain access levels to a resource. + NetIQRole role = 4; + // parent_role_ref represents a parent relationship between roles. + NetIQRoleRef parent_role_ref = 5; + // user represents a NetIQ user. + NetIQUser user = 6; + // resource_role_ref represents a resource assignment to a role. + NetIQResourceAssignmentRef resource_role_ref = 7; + //role_member_ref represents a member being member of a role. + NetIQMemberAssignmentRef role_member_ref = 8; + } +} + +// NetIQGroup represents a NetIQ group +message NetIQGroup { + // name is the group name. + string name = 1; + // id is the universal identifier for the group. + string id = 2; + // description is the group description. + string description = 3; +} + +// NetIQGroupMember represents a NetIQ group member +message NetIQGroupMember { + // group_id is the group id. + string group_id = 1; + // user_id is the universal identifier for the user. + string user_id = 2; + // is_group_assignment is a flag that determines whether the member is a group assignment. + bool is_group_assignment = 3; +} + +// NetIQResource represents a NetIQ resource +message NetIQResource { + // name is the resource name. + string name = 1; + // id is the universal identifier for the resource. + string id = 2; + // description is the project description. + string description = 3; + + // categories is the list of categories the resource belongs to. + repeated NetIQCategory categories = 4; +} + +// NetIQCategory is a resource category. +message NetIQCategory { + // name is the resource name. + string name = 1; + // id is the universal identifier for the category. + string id = 2; +} + +// NetIQRole represents a NetIQ role +message NetIQRole { + // name is the resource name. + string name = 1; + // id is the universal identifier for the role. + string id = 2; + // description is the project description. + string description = 3; + // categories is the list of categories the resource belongs to. + repeated NetIQCategory categories = 4; + + // RoleLevel represents the role level. + message RoleLevel { + // name is the name of the role level. + string name = 1; + // level is the level of the role level. + int32 level = 2; + // cn is the common name. + string cn = 3; + } + RoleLevel level = 5; +} + +// NetIQRoleRef represents a NetIQ Role reference. +message NetIQRoleRef { + // child_role_id is the group id of a role that is a child role of parent_role_id. + string child_role_id = 1; + // parent_role_id is the universal identifier for the role that is parent to child_role_id. + string parent_role_id = 2; + // level is the level of the role. + int32 level = 3; + // request_description is the description of the request. + string request_description = 4; +} + +// NetIQUser represents a NetIQ user. +message NetIQUser { + // id is the id of the user. + string id = 1; + // email is the user's email. + string email = 2; + // name is the user's name. + string name = 3; + // is_disabled indicates if a user is disabled. + bool is_disabled = 4; +} + +// NetIQResourceAssignmentRef represents a NetIQ resource assignment reference. +message NetIQResourceAssignmentRef { + // role_id is the group id of a role that is assigned to resource_id. + string role_id = 1; + // resource_id is the universal identifier for the resource that is assigned to role_id. + string resource_id = 2; + // mapping_description is the description of the mapping. + string mapping_description = 4; + // status_code is the status code of the role assignment. + uint32 status_code = 5; +} + +// NetIQMemberAssignmentRef represents a NetIQ resource assignment reference. +message NetIQMemberAssignmentRef { + // role_id is the group id of a role that user_id is member of. + string role_id = 1; + // dn is the universal identifier for the user that is member of role_id. + string dn = 2; + // recipient_type identifies the recipient provenance. + RoleRecipientType recipient_type = 3; + // recipient_type_subcontainer is the sub container of the recipient type. + string recipient_type_subcontainer = 4; + // status_code is the status code of the role assignment. + uint32 status_code = 5; + // StatusDstatus_displayisplay is the display of the status. + string status_display = 6; + // effective_date is the effective date of the role assignment. + google.protobuf.Timestamp effective_date = 7; + // expiry_date is the expiry date of the role assignment. + google.protobuf.Timestamp expiry_date = 8; + // description is the description of the role assignment. + string description = 9; + // grant is a flag that determines whether the role assignment is granted. + bool grant = 10; +} + +// RoleRecipientType is the type of the recipient. +enum RoleRecipientType { + // ROLE_RECIPIENT_TYPE_UNSPECIFIED is a unspecified role recipient type. + ROLE_RECIPIENT_TYPE_UNSPECIFIED = 0; + // ROLE_RECIPIENT_TYPE_USER represents a user being member of a role. + ROLE_RECIPIENT_TYPE_USER = 1; + // ROLE_RECIPIENT_TYPE_GROUP represents a group being member of a role. + ROLE_RECIPIENT_TYPE_GROUP = 2; +} diff --git a/tool/tctl/common/plugin/netiq.go b/tool/tctl/common/plugin/netiq.go new file mode 100644 index 0000000000000..66bdb891317a1 --- /dev/null +++ b/tool/tctl/common/plugin/netiq.go @@ -0,0 +1,520 @@ +/* + * Teleport + * Copyright (C) 2025 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 plugin + +import ( + "context" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "strings" + + "github.com/alecthomas/kingpin/v2" + "github.com/fatih/color" + "github.com/gravitational/trace" + + "github.com/gravitational/teleport" + "github.com/gravitational/teleport/api" + pluginspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/plugins/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/prompt" + "github.com/gravitational/teleport/lib/defaults" +) + +var ( + boldGreen = color.New(color.Bold, color.FgGreen).SprintFunc() + netIQStep1Template = bold("Step 1: Configure IDM OSP address") + ` + +Please provide the IDM OSP address to configure the integration. +For example, 'https://idm.example.com/osp' or 'https://osp.idm.example.com'. +` + netIQStep2Template = bold("Step 2: Configure IDM API address") + ` +Please provide the IDM API (IDMProv or IDM Identity Applications) address to configure the integration. +For example, 'https://idm.example.com/IDMProv' or 'https://idmapps.idm.example.com'. +` + netIQStep3Template = bold("Step 3: Configure IDM OSP OAuth Client") + ` + +The easiest way to register a new OAuth client with OSP (IDM Authorization Server) is to edit the ` + bold("ism-configuration.properties") + ` file by hand. +The file is located in the ` + bold("osp-path/tomcat/conf/") + ` directory. +To use an OAuth client with OSP, you must configure the following properties: +` + boldGreen(` com.example..clientID = + com.example..clientPass = +`) + ` + +If you prefer to store the client secret in a secure way, you can run the following command: + + ` + boldGreen(`java -jar /opt/netiq/idm/apps/tomcat/lib/obscurity-*jar `) + ` + +Then, copy the output and paste it into the ` + boldGreen(`com.example..clientPass`) + ` property as shown below: +` + boldGreen(` com.example..clientID = + com.example..clientPass._attr_obscurity = ENCRYPT + com.example..clientPass = +`) + ` + +After configuring the OAuth client, please restart OSP to apply the changes and type 'continue' to proceed. + +` + netIQStep4Template = bold("Step 4: Input Client ID and Client Secret") + ` + +With the values used in Step 2, please copy and paste the following information: +` + netIQStep5Template = bold("Step 5: Input IDM User and Password") + ` + +Please provide the IDM user to configure the integration. +This user must have permissions to access the IDM API and retrieve users, groups, roles +and resources. Use the following format: ` + bold("cn=uaadmin,ou=sa,o=data") + `. +` +) + +type netIQArgs struct { + cmd *kingpin.CmdClause + insecureSkipVerify bool +} + +func (p *PluginsCommand) initInstallNetIQ(parent *kingpin.CmdClause) { + p.install.netIQ.cmd = parent.Command("netiq", "Install an Access Graph NetIQ integration.") + cmd := p.install.netIQ.cmd + cmd.Flag("insecure-skip-verify", "Skip verification of the NetIQ server's SSL certificate.").BoolVar(&p.install.netIQ.insecureSkipVerify) +} + +type netIQSettings struct { + apiURL string + ospURL string + identityVaultUser string + identityVaultPassword string + oAuthClientID string + oAuthClientSecret string + insecureSkipVerify bool +} + +func (p *PluginsCommand) netIQSetupGuide(ctx context.Context) (netIQSettings, error) { + settings := netIQSettings{} + var err error + + settings.ospURL, err = promptForURL( + ctx, + os.Stdout, + netIQStep1Template, + "Please enter the IDM OSP address", + p.install.netIQ.insecureSkipVerify, + func(ctx context.Context, s *url.URL, b bool) error { + _, err := checkNetIQOSPAddress(ctx, s.String(), b) + return trace.Wrap(err) + }) + if err != nil { + return netIQSettings{}, trace.Wrap(err) + } + + settings.apiURL, err = promptForURL( + ctx, + os.Stdout, + netIQStep2Template, + "Please enter the IDM API address", + p.install.netIQ.insecureSkipVerify, + func(ctx context.Context, u *url.URL, b bool) error { + return checkUnauthenticatedNetIQAPIAddress(ctx, u.String(), b) + }) + if err != nil { + return netIQSettings{}, trace.Wrap(err) + } + + if err := promptForContinue(ctx, os.Stdout, netIQStep3Template); err != nil { + return netIQSettings{}, err + } + + settings.oAuthClientID, err = promptForInput(ctx, os.Stdout, netIQStep4Template, "Enter the OAuth ClientID") + if err != nil { + return netIQSettings{}, trace.Wrap(err) + } + + settings.oAuthClientSecret, err = promptForPassword(ctx, os.Stdout, "Enter the OAuth Client Secret") + if err != nil { + return netIQSettings{}, trace.Wrap(err) + } + + settings.identityVaultUser, err = promptForInput(ctx, os.Stdout, netIQStep5Template, "Enter the IDM User") + if err != nil { + return netIQSettings{}, trace.Wrap(err) + } + + settings.identityVaultPassword, err = promptForPassword(ctx, os.Stdout, "Enter the IDM User Password") + if err != nil { + return netIQSettings{}, trace.Wrap(err) + } + + settings.insecureSkipVerify = p.install.netIQ.insecureSkipVerify + + // Validate the NetIQ settings. + if err := checkAuthenticatedNetIQAPIAddress(ctx, settings); err != nil { + return netIQSettings{}, trace.Wrap(err) + } + return settings, nil +} + +func (p *PluginsCommand) InstallNetIQ(ctx context.Context, args installPluginArgs) error { + settings, err := p.netIQSetupGuide(ctx) + if err != nil { + if errors.Is(err, errCancel) { + return nil + } + return trace.Wrap(err) + } + + plugin, err := createNetIQPlugin(&settings) + if err != nil { + return trace.Wrap(err, "failed to create NetIQ plugin") + } + + creds, err := getNetIQPluginCredentials(settings) + if err != nil { + return trace.Wrap(err, "failed to get NetIQ plugin credentials") + } + + createPluginRequest := &pluginspb.CreatePluginRequest{ + Plugin: plugin, + StaticCredentialsList: creds, + CredentialLabels: map[string]string{ + netIQOrgURLLabel: settings.apiURL, + }, + } + + if _, err = args.plugins.CreatePlugin(ctx, createPluginRequest); err != nil { + return trace.Wrap(err, "failed to create NetIQ plugin") + } + + fmt.Println("NetIQ plugin has been successfully installed.") + + return nil +} + +func promptForURL(ctx context.Context, out io.Writer, template, promptT string, insecureSkipVerify bool, checkFunc func(context.Context, *url.URL, bool) error) (string, error) { + fmt.Fprintf(out, "\n%s", template) + + return prompt.URL( + ctx, + out, + prompt.Stdin(), + promptT, + prompt.WithURLValidator( + func(u *url.URL) error { + if err := checkFunc(ctx, u, insecureSkipVerify); err != nil { + fmt.Fprintf(out, "Invalid address: %v\n", err) + return trace.Wrap(err) + } + return nil + }, + ), + ) +} + +func promptForContinue(ctx context.Context, out io.Writer, template string) error { + fmt.Fprintf(out, "\n%s", template) + op, err := prompt.PickOne( + ctx, + out, + prompt.Stdin(), + "Type 'continue' to proceed, 'exit' to quit", + []string{"continue", "exit"}, + ) + if err != nil { + return trace.Wrap(err) + } + if op == "exit" { + return errCancel + } + return nil +} + +func promptForPassword(ctx context.Context, out io.Writer, promptMsg string) (string, error) { + return prompt.Password( + ctx, out, prompt.Stdin(), + promptMsg, + ) +} + +func promptForInput(ctx context.Context, out io.Writer, template, promptT string) (string, error) { + if template != "" { + fmt.Fprintf(out, "\n%s", template) + } + return prompt.Input(ctx, out, prompt.Stdin(), promptT) +} + +func checkNetIQOSPAddress(ctx context.Context, ospURL string, insecureSkipVerify bool) (string, error) { + var tokenAddr string + err := checkNetIQAddress( + ctx, + ospURL, + "/a/idm/auth/oauth2/.well-known/openid-configuration", + insecureSkipVerify, + func(r *http.Response) error { + type openIDConfig struct { + Token string `json:"token_endpoint"` + } + out := openIDConfig{} + if err := json.NewDecoder(r.Body).Decode(&out); err != nil || out.Token == "" { + return trace.BadParameter("invalid OSP address") + } + tokenAddr = out.Token + return nil + }, + ) + return tokenAddr, trace.Wrap(err) +} + +// checkUnauthenticatedNetIQAPIAddress checks if the NetIQ API address is reachable and serves the expected content. +func checkUnauthenticatedNetIQAPIAddress(ctx context.Context, apiAddr string, insecureSkipVerify bool) error { + return checkNetIQAddress( + ctx, + apiAddr, + "rest/access/info/version", + insecureSkipVerify, + // API endpoints are protected so we are ensuring that the endpoint + // is reachable and doesn't return 404. + func(r *http.Response) error { + if r.StatusCode != http.StatusUnauthorized { + return trace.BadParameter("invalid API address") + } + return nil + }, + ) +} + +func checkAuthenticatedNetIQAPIAddress(ctx context.Context, data netIQSettings) error { + tokenUrl, err := checkNetIQOSPAddress(ctx, data.ospURL, data.insecureSkipVerify) + if err != nil { + return trace.Wrap(err) + } + + q := url.Values{} + q.Add("grant_type", "password") + q.Add("username", data.identityVaultUser) + q.Add("password", data.identityVaultPassword) + + // validate API credentials + rsp, err := doRequest( + ctx, + tokenUrl, + http.MethodPost, + data.insecureSkipVerify, + withBody(strings.NewReader(q.Encode())), + withBasicAuth(data.oAuthClientID, data.oAuthClientSecret), + withHeader("Content-Type", "application/x-www-form-urlencoded"), + ) + + if err != nil { + return trace.Wrap(err) + } + + defer rsp.Body.Close() + defer io.Copy(io.Discard, rsp.Body) + + // tokenResponse represents the response from the OSP(NetIQ authorization service) token endpoint + // when requesting an access token. + type tokenResponse struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in"` + } + var token tokenResponse + if err := json.NewDecoder(rsp.Body).Decode(&token); err != nil { + return trace.Wrap(err, "failed to decode response") + } + + return checkNetIQAddress( + ctx, + data.apiURL, + "rest/access/info/version", + data.insecureSkipVerify, + // API endpoints are protected so we are ensuring that the endpoint + // is reachable and doesn't return 404. + func(r *http.Response) error { + switch r.StatusCode { + case http.StatusUnauthorized: + return trace.BadParameter("invalid API credentials") + case http.StatusOK: + return nil + default: + return trace.BadParameter("invalid API address") + } + }, + withHeader("Authorization", fmt.Sprintf("%s %s", token.TokenType, token.AccessToken)), + ) +} + +func checkNetIQAddress(ctx context.Context, addr, path string, insecureSkipVerify bool, validation func(*http.Response) error, opts ...doRequestOptions) error { + u, err := url.Parse(addr) + if err != nil { + return trace.Wrap(err, "invalid address") + } + u = u.JoinPath(path) + rsp, err := doRequest(ctx, u.String(), http.MethodGet, insecureSkipVerify, opts...) + if err != nil { + return trace.Wrap(err, "failed to check address") + } + defer rsp.Body.Close() + defer io.Copy(io.Discard, rsp.Body) + + if err := validation(rsp); err != nil { + return trace.Wrap(err, "failed to validate address") + } + + return nil +} + +type doRequestOptions func(*http.Request) error + +func withBasicAuth(user, password string) doRequestOptions { + return func(req *http.Request) error { + req.SetBasicAuth(user, password) + return nil + } +} + +func withBody(body io.Reader) doRequestOptions { + return func(req *http.Request) error { + req.Body = io.NopCloser(body) + return nil + } +} + +func withHeader(key, value string) doRequestOptions { + return func(req *http.Request) error { + req.Header.Set(key, value) + return nil + } +} + +func doRequest(ctx context.Context, url, method string, insecureSkipVerify bool, opts ...doRequestOptions) (*http.Response, error) { + req, err := http.NewRequestWithContext(ctx, method, url, nil) + if err != nil { + return nil, trace.Wrap(err) + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", fmt.Sprintf("%s/%s", teleport.ComponentTCTL, api.Version)) + + for _, opt := range opts { + if err := opt(req); err != nil { + return nil, trace.Wrap(err) + } + } + + transport, err := defaults.Transport() + if err != nil { + return nil, trace.Wrap(err) + } + if transport.TLSClientConfig == nil { + transport.TLSClientConfig = &tls.Config{} + } + transport.TLSClientConfig.InsecureSkipVerify = insecureSkipVerify + client := &http.Client{ + Transport: transport, + } + return client.Do(req) +} + +func getNetIQPluginCredentials(req netIQSettings) ([]*types.PluginStaticCredentialsV1, error) { + var out []*types.PluginStaticCredentialsV1 + if req.oAuthClientID != "" { + out = append(out, buildOAuthCredentials(req.oAuthClientID, req.oAuthClientSecret)) + } + if req.identityVaultUser != "" { + out = append(out, buildBasicAuthCredentials(req.identityVaultUser, req.identityVaultPassword)) + } + return out, nil +} + +const ( + // netIQOrgURLLabel is the label for which NetIQ instance object belongs to. + netIQOrgURLLabel = "netiq/org" + // credPurposeLabel is the label for the purpose of the credential. + credPurposeLabel = "netiq/purpose" + // credPurposeNetIQOauth is the purpose for the NetIQ OAuth client ID and secret. + credPurposeNetIQOauth = "oauth-client-id-secret" + // credPurposeNetIQAuth is the purpose for the NetIQ Identity Vault user and password. + credPurposeNetIQAuth = "netiq-auth" +) + +func buildOAuthCredentials(clientID, clientSecret string) *types.PluginStaticCredentialsV1 { + return &types.PluginStaticCredentialsV1{ + ResourceHeader: types.ResourceHeader{ + Metadata: types.Metadata{ + Name: types.PluginTypeNetIQ + "-oauth", + Labels: map[string]string{ + credPurposeLabel: credPurposeNetIQOauth, + }, + }, + }, + Spec: &types.PluginStaticCredentialsSpecV1{ + Credentials: &types.PluginStaticCredentialsSpecV1_OAuthClientSecret{ + OAuthClientSecret: &types.PluginStaticCredentialsOAuthClientSecret{ + ClientId: clientID, + ClientSecret: clientSecret, + }, + }, + }, + } +} + +func buildBasicAuthCredentials(user, password string) *types.PluginStaticCredentialsV1 { + return &types.PluginStaticCredentialsV1{ + ResourceHeader: types.ResourceHeader{ + Metadata: types.Metadata{ + Name: types.PluginTypeNetIQ + "-basic-auth", + Labels: map[string]string{ + credPurposeLabel: credPurposeNetIQAuth, + }, + }, + }, + Spec: &types.PluginStaticCredentialsSpecV1{ + Credentials: &types.PluginStaticCredentialsSpecV1_BasicAuth{ + BasicAuth: &types.PluginStaticCredentialsBasicAuth{ + Username: user, + Password: password, + }, + }, + }, + } +} + +func createNetIQPlugin(params *netIQSettings) (*types.PluginV1, error) { + return &types.PluginV1{ + SubKind: types.PluginSubkindAccessGraph, + Metadata: types.Metadata{ + Labels: map[string]string{ + types.TeleportNamespace + "/hosted-plugin": "true", + }, + Name: types.PluginTypeNetIQ, + }, + Spec: types.PluginSpecV1{ + Settings: &types.PluginSpecV1_NetIq{ + NetIq: &types.PluginNetIQSettings{ + OauthIssuerEndpoint: params.ospURL, + ApiEndpoint: params.apiURL, + InsecureSkipVerify: params.insecureSkipVerify, + }, + }, + }, + }, nil +} diff --git a/tool/tctl/common/plugin/plugins_command.go b/tool/tctl/common/plugin/plugins_command.go index b6c6ed57d85a1..b5edc45405d23 100644 --- a/tool/tctl/common/plugin/plugins_command.go +++ b/tool/tctl/common/plugin/plugins_command.go @@ -56,6 +56,7 @@ type pluginInstallArgs struct { okta oktaArgs scim scimArgs entraID entraArgs + netIQ netIQArgs } type scimArgs struct { @@ -102,6 +103,7 @@ func (p *PluginsCommand) initInstall(parent *kingpin.CmdClause, config *servicec p.initInstallOkta(p.install.cmd) p.initInstallSCIM(p.install.cmd) p.initInstallEntra(p.install.cmd) + p.initInstallNetIQ(p.install.cmd) } func (p *PluginsCommand) initInstallSCIM(parent *kingpin.CmdClause) { @@ -326,6 +328,8 @@ func (p *PluginsCommand) TryRun(ctx context.Context, cmd string, clientFunc comm commandFunc = p.InstallSCIM case p.install.entraID.cmd.FullCommand(): commandFunc = p.InstallEntra + case p.install.netIQ.cmd.FullCommand(): + commandFunc = p.InstallNetIQ case p.delete.cmd.FullCommand(): commandFunc = p.Delete default: From 844f2c08c8f0735ca5958c080db184f20a404694 Mon Sep 17 00:00:00 2001 From: Forrest <30576607+fspmarshall@users.noreply.github.com> Date: Wed, 29 Jan 2025 14:26:36 -0800 Subject: [PATCH 10/27] [v17] backport common decision service elements (#51612) * Add initial Decision (aka PDP) protos (#49875) * Clone protos from fspmarshall/pdp-work-02 * Use decisionpb as the Go package alias * Update DecisionService docs * Split identity protos into separate files * Update Metadata docs * Split metadata into separate files * Update Resource docs * Update database access docs and fields * Update SSH access docs and fields * Ignore breaking changes on decision protos * Update generated protos * Use teleport.trait.v1.Trait * Document mutual dependency between "ResourceID" types * nit: s/ResourceID/ResourceId * nit: Use the correct CamelCase field name in comments * Update generated protos * Add RouteToApp.target_port * Update generated protos * Update comments on TLSIdentity / tlsca.Identity * Update generated protos * Add the decisionv1.Service boilerplate (#49912) * Add the decisionv1.Service boilerplate * Wire decisionv1.Service to auth.GRPCServer * Wire decisionpb.DecisionServiceClient to client.Client * Add basic service testing * Add conversions to/from decisionpb.TLSIdentity (#50308) * Add conversions to/from decisionpb.TLSIdentity * Map timestamppb.Timestamp{} to 0-0-0 0:0.0 (instead of unix epoch) * Document that slices are not deep-copied * Add EvaluateDatabaseAccessRequest.database (#50481) * Add EvaluateDatabaseAccessRequest.database * Update generated protos --------- Co-authored-by: Alan Parra --- api/client/client.go | 7 + .../decision/v1alpha1/database_access.pb.go | 417 +++++++ .../decision/v1alpha1/decision_service.pb.go | 119 ++ .../v1alpha1/decision_service_grpc.pb.go | 199 ++++ .../decision/v1alpha1/denial_metadata.pb.go | 188 ++++ .../v1alpha1/enforcement_feature.pb.go | 151 +++ .../decision/v1alpha1/permit_metadata.pb.go | 176 +++ .../decision/v1alpha1/request_metadata.pb.go | 229 ++++ .../teleport/decision/v1alpha1/resource.pb.go | 176 +++ .../decision/v1alpha1/ssh_access.pb.go | 599 ++++++++++ .../decision/v1alpha1/ssh_identity.pb.go | 138 +++ .../decision/v1alpha1/tls_identity.pb.go | 1002 +++++++++++++++++ .../decision/v1alpha1/database_access.proto | 53 + .../decision/v1alpha1/decision_service.proto | 40 + .../decision/v1alpha1/denial_metadata.proto | 38 + .../v1alpha1/enforcement_feature.proto | 26 + .../decision/v1alpha1/permit_metadata.proto | 34 + .../decision/v1alpha1/request_metadata.proto | 44 + .../teleport/decision/v1alpha1/resource.proto | 37 + .../decision/v1alpha1/ssh_access.proto | 75 ++ .../decision/v1alpha1/ssh_identity.proto | 24 + .../decision/v1alpha1/tls_identity.proto | 249 ++++ api/proto/teleport/legacy/types/types.proto | 1 + api/types/types.pb.go | 1 + buf.yaml | 3 + lib/auth/grpcserver.go | 10 + lib/decision/decisionv1/decision_service.go | 48 + .../decisionv1/decision_service_test.go | 45 + lib/decision/decisionv1/env_test.go | 74 ++ lib/decision/tls_identity.go | 278 +++++ lib/decision/tls_identity_test.go | 171 +++ lib/tlsca/ca.go | 4 +- 32 files changed, 4655 insertions(+), 1 deletion(-) create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/database_access.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/decision_service.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/decision_service_grpc.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/denial_metadata.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/enforcement_feature.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/permit_metadata.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/request_metadata.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/resource.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/ssh_access.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go create mode 100644 api/gen/proto/go/teleport/decision/v1alpha1/tls_identity.pb.go create mode 100644 api/proto/teleport/decision/v1alpha1/database_access.proto create mode 100644 api/proto/teleport/decision/v1alpha1/decision_service.proto create mode 100644 api/proto/teleport/decision/v1alpha1/denial_metadata.proto create mode 100644 api/proto/teleport/decision/v1alpha1/enforcement_feature.proto create mode 100644 api/proto/teleport/decision/v1alpha1/permit_metadata.proto create mode 100644 api/proto/teleport/decision/v1alpha1/request_metadata.proto create mode 100644 api/proto/teleport/decision/v1alpha1/resource.proto create mode 100644 api/proto/teleport/decision/v1alpha1/ssh_access.proto create mode 100644 api/proto/teleport/decision/v1alpha1/ssh_identity.proto create mode 100644 api/proto/teleport/decision/v1alpha1/tls_identity.proto create mode 100644 lib/decision/decisionv1/decision_service.go create mode 100644 lib/decision/decisionv1/decision_service_test.go create mode 100644 lib/decision/decisionv1/env_test.go create mode 100644 lib/decision/tls_identity.go create mode 100644 lib/decision/tls_identity_test.go diff --git a/api/client/client.go b/api/client/client.go index edb8e8c09d95c..2daddc81d9777 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -74,6 +74,7 @@ import ( crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" discoveryconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1" dynamicwindowsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dynamicwindows/v1" @@ -5324,3 +5325,9 @@ func (c *Client) ProvisioningServiceClient() provisioningv1.ProvisioningServiceC func (c *Client) IntegrationsClient() integrationpb.IntegrationServiceClient { return c.integrationsClient() } + +// DecisionClient returns an unadorned DecisionService client using the +// underlying Auth gRPC connection. +func (c *Client) DecisionClient() decisionpb.DecisionServiceClient { + return decisionpb.NewDecisionServiceClient(c.conn) +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/database_access.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/database_access.pb.go new file mode 100644 index 0000000000000..3c6d0e0cc39c2 --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/database_access.pb.go @@ -0,0 +1,417 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/database_access.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// EvaluateDatabaseAccessRequest describes a request to evaluate whether or not +// a given database access attempt should be permitted. +type EvaluateDatabaseAccessRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *RequestMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + TlsIdentity *TLSIdentity `protobuf:"bytes,2,opt,name=tls_identity,json=tlsIdentity,proto3" json:"tls_identity,omitempty"` + Database *Resource `protobuf:"bytes,3,opt,name=database,proto3" json:"database,omitempty"` +} + +func (x *EvaluateDatabaseAccessRequest) Reset() { + *x = EvaluateDatabaseAccessRequest{} + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EvaluateDatabaseAccessRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluateDatabaseAccessRequest) ProtoMessage() {} + +func (x *EvaluateDatabaseAccessRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EvaluateDatabaseAccessRequest.ProtoReflect.Descriptor instead. +func (*EvaluateDatabaseAccessRequest) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_database_access_proto_rawDescGZIP(), []int{0} +} + +func (x *EvaluateDatabaseAccessRequest) GetMetadata() *RequestMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *EvaluateDatabaseAccessRequest) GetTlsIdentity() *TLSIdentity { + if x != nil { + return x.TlsIdentity + } + return nil +} + +func (x *EvaluateDatabaseAccessRequest) GetDatabase() *Resource { + if x != nil { + return x.Database + } + return nil +} + +// EvaluateDatabaseAccessResponse describes the result of a database access +// evaluation. +type EvaluateDatabaseAccessResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Result: + // + // *EvaluateDatabaseAccessResponse_Permit + // *EvaluateDatabaseAccessResponse_Denial + Result isEvaluateDatabaseAccessResponse_Result `protobuf_oneof:"result"` +} + +func (x *EvaluateDatabaseAccessResponse) Reset() { + *x = EvaluateDatabaseAccessResponse{} + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EvaluateDatabaseAccessResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluateDatabaseAccessResponse) ProtoMessage() {} + +func (x *EvaluateDatabaseAccessResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EvaluateDatabaseAccessResponse.ProtoReflect.Descriptor instead. +func (*EvaluateDatabaseAccessResponse) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_database_access_proto_rawDescGZIP(), []int{1} +} + +func (m *EvaluateDatabaseAccessResponse) GetResult() isEvaluateDatabaseAccessResponse_Result { + if m != nil { + return m.Result + } + return nil +} + +func (x *EvaluateDatabaseAccessResponse) GetPermit() *DatabaseAccessPermit { + if x, ok := x.GetResult().(*EvaluateDatabaseAccessResponse_Permit); ok { + return x.Permit + } + return nil +} + +func (x *EvaluateDatabaseAccessResponse) GetDenial() *DatabaseAccessDenial { + if x, ok := x.GetResult().(*EvaluateDatabaseAccessResponse_Denial); ok { + return x.Denial + } + return nil +} + +type isEvaluateDatabaseAccessResponse_Result interface { + isEvaluateDatabaseAccessResponse_Result() +} + +type EvaluateDatabaseAccessResponse_Permit struct { + Permit *DatabaseAccessPermit `protobuf:"bytes,1,opt,name=permit,proto3,oneof"` +} + +type EvaluateDatabaseAccessResponse_Denial struct { + Denial *DatabaseAccessDenial `protobuf:"bytes,2,opt,name=denial,proto3,oneof"` +} + +func (*EvaluateDatabaseAccessResponse_Permit) isEvaluateDatabaseAccessResponse_Result() {} + +func (*EvaluateDatabaseAccessResponse_Denial) isEvaluateDatabaseAccessResponse_Result() {} + +// DatabaseAccessPermit describes the parameters/constraints of a permissible +// database access attempt. +type DatabaseAccessPermit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *PermitMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *DatabaseAccessPermit) Reset() { + *x = DatabaseAccessPermit{} + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DatabaseAccessPermit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DatabaseAccessPermit) ProtoMessage() {} + +func (x *DatabaseAccessPermit) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DatabaseAccessPermit.ProtoReflect.Descriptor instead. +func (*DatabaseAccessPermit) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_database_access_proto_rawDescGZIP(), []int{2} +} + +func (x *DatabaseAccessPermit) GetMetadata() *PermitMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +// DatabaseAccessDenial describes a database access denial. +type DatabaseAccessDenial struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *DenialMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *DatabaseAccessDenial) Reset() { + *x = DatabaseAccessDenial{} + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DatabaseAccessDenial) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DatabaseAccessDenial) ProtoMessage() {} + +func (x *DatabaseAccessDenial) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_database_access_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DatabaseAccessDenial.ProtoReflect.Descriptor instead. +func (*DatabaseAccessDenial) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_database_access_proto_rawDescGZIP(), []int{3} +} + +func (x *DatabaseAccessDenial) GetMetadata() *DenialMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +var File_teleport_decision_v1alpha1_database_access_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_database_access_proto_rawDesc = []byte{ + 0x0a, 0x30, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x30, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x69, 0x61, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x30, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x2d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x74, 0x6c, 0x73, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xf6, 0x01, 0x0a, 0x1d, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4a, 0x0a, 0x0c, 0x74, 0x6c, + 0x73, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x4c, + 0x53, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x74, 0x6c, 0x73, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x40, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, + 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0xc2, 0x01, 0x0a, 0x1e, 0x45, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x06, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x12, 0x4a, 0x0a, 0x06, 0x64, 0x65, 0x6e, 0x69, 0x61, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x44, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6e, + 0x69, 0x61, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x5e, 0x0a, + 0x14, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x74, 0x12, 0x46, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5e, 0x0a, + 0x14, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x44, + 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x12, 0x46, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x5a, 0x5a, + 0x58, 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, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_teleport_decision_v1alpha1_database_access_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_database_access_proto_rawDescData = file_teleport_decision_v1alpha1_database_access_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_database_access_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_database_access_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_database_access_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_database_access_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_database_access_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_database_access_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_decision_v1alpha1_database_access_proto_goTypes = []any{ + (*EvaluateDatabaseAccessRequest)(nil), // 0: teleport.decision.v1alpha1.EvaluateDatabaseAccessRequest + (*EvaluateDatabaseAccessResponse)(nil), // 1: teleport.decision.v1alpha1.EvaluateDatabaseAccessResponse + (*DatabaseAccessPermit)(nil), // 2: teleport.decision.v1alpha1.DatabaseAccessPermit + (*DatabaseAccessDenial)(nil), // 3: teleport.decision.v1alpha1.DatabaseAccessDenial + (*RequestMetadata)(nil), // 4: teleport.decision.v1alpha1.RequestMetadata + (*TLSIdentity)(nil), // 5: teleport.decision.v1alpha1.TLSIdentity + (*Resource)(nil), // 6: teleport.decision.v1alpha1.Resource + (*PermitMetadata)(nil), // 7: teleport.decision.v1alpha1.PermitMetadata + (*DenialMetadata)(nil), // 8: teleport.decision.v1alpha1.DenialMetadata +} +var file_teleport_decision_v1alpha1_database_access_proto_depIdxs = []int32{ + 4, // 0: teleport.decision.v1alpha1.EvaluateDatabaseAccessRequest.metadata:type_name -> teleport.decision.v1alpha1.RequestMetadata + 5, // 1: teleport.decision.v1alpha1.EvaluateDatabaseAccessRequest.tls_identity:type_name -> teleport.decision.v1alpha1.TLSIdentity + 6, // 2: teleport.decision.v1alpha1.EvaluateDatabaseAccessRequest.database:type_name -> teleport.decision.v1alpha1.Resource + 2, // 3: teleport.decision.v1alpha1.EvaluateDatabaseAccessResponse.permit:type_name -> teleport.decision.v1alpha1.DatabaseAccessPermit + 3, // 4: teleport.decision.v1alpha1.EvaluateDatabaseAccessResponse.denial:type_name -> teleport.decision.v1alpha1.DatabaseAccessDenial + 7, // 5: teleport.decision.v1alpha1.DatabaseAccessPermit.metadata:type_name -> teleport.decision.v1alpha1.PermitMetadata + 8, // 6: teleport.decision.v1alpha1.DatabaseAccessDenial.metadata:type_name -> teleport.decision.v1alpha1.DenialMetadata + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_database_access_proto_init() } +func file_teleport_decision_v1alpha1_database_access_proto_init() { + if File_teleport_decision_v1alpha1_database_access_proto != nil { + return + } + file_teleport_decision_v1alpha1_denial_metadata_proto_init() + file_teleport_decision_v1alpha1_permit_metadata_proto_init() + file_teleport_decision_v1alpha1_request_metadata_proto_init() + file_teleport_decision_v1alpha1_resource_proto_init() + file_teleport_decision_v1alpha1_tls_identity_proto_init() + file_teleport_decision_v1alpha1_database_access_proto_msgTypes[1].OneofWrappers = []any{ + (*EvaluateDatabaseAccessResponse_Permit)(nil), + (*EvaluateDatabaseAccessResponse_Denial)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_database_access_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_database_access_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_database_access_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_database_access_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_database_access_proto = out.File + file_teleport_decision_v1alpha1_database_access_proto_rawDesc = nil + file_teleport_decision_v1alpha1_database_access_proto_goTypes = nil + file_teleport_decision_v1alpha1_database_access_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/decision_service.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/decision_service.pb.go new file mode 100644 index 0000000000000..7b1a122d64420 --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/decision_service.pb.go @@ -0,0 +1,119 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/decision_service.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_teleport_decision_v1alpha1_decision_service_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_decision_service_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, + 0x30, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x73, + 0x68, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xa6, + 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x11, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x53, + 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x53, 0x53, + 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x65, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x16, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x39, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x76, + 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_teleport_decision_v1alpha1_decision_service_proto_goTypes = []any{ + (*EvaluateSSHAccessRequest)(nil), // 0: teleport.decision.v1alpha1.EvaluateSSHAccessRequest + (*EvaluateDatabaseAccessRequest)(nil), // 1: teleport.decision.v1alpha1.EvaluateDatabaseAccessRequest + (*EvaluateSSHAccessResponse)(nil), // 2: teleport.decision.v1alpha1.EvaluateSSHAccessResponse + (*EvaluateDatabaseAccessResponse)(nil), // 3: teleport.decision.v1alpha1.EvaluateDatabaseAccessResponse +} +var file_teleport_decision_v1alpha1_decision_service_proto_depIdxs = []int32{ + 0, // 0: teleport.decision.v1alpha1.DecisionService.EvaluateSSHAccess:input_type -> teleport.decision.v1alpha1.EvaluateSSHAccessRequest + 1, // 1: teleport.decision.v1alpha1.DecisionService.EvaluateDatabaseAccess:input_type -> teleport.decision.v1alpha1.EvaluateDatabaseAccessRequest + 2, // 2: teleport.decision.v1alpha1.DecisionService.EvaluateSSHAccess:output_type -> teleport.decision.v1alpha1.EvaluateSSHAccessResponse + 3, // 3: teleport.decision.v1alpha1.DecisionService.EvaluateDatabaseAccess:output_type -> teleport.decision.v1alpha1.EvaluateDatabaseAccessResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_decision_service_proto_init() } +func file_teleport_decision_v1alpha1_decision_service_proto_init() { + if File_teleport_decision_v1alpha1_decision_service_proto != nil { + return + } + file_teleport_decision_v1alpha1_database_access_proto_init() + file_teleport_decision_v1alpha1_ssh_access_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_decision_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_teleport_decision_v1alpha1_decision_service_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_decision_service_proto_depIdxs, + }.Build() + File_teleport_decision_v1alpha1_decision_service_proto = out.File + file_teleport_decision_v1alpha1_decision_service_proto_rawDesc = nil + file_teleport_decision_v1alpha1_decision_service_proto_goTypes = nil + file_teleport_decision_v1alpha1_decision_service_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/decision_service_grpc.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/decision_service_grpc.pb.go new file mode 100644 index 0000000000000..620b4bf79887b --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/decision_service_grpc.pb.go @@ -0,0 +1,199 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: teleport/decision/v1alpha1/decision_service.proto + +package decisionpb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + DecisionService_EvaluateSSHAccess_FullMethodName = "/teleport.decision.v1alpha1.DecisionService/EvaluateSSHAccess" + DecisionService_EvaluateDatabaseAccess_FullMethodName = "/teleport.decision.v1alpha1.DecisionService/EvaluateDatabaseAccess" +) + +// DecisionServiceClient is the client API for DecisionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// DecisionService performs authorization decisions for Teleport. +// +// DecisionService acts the PDP (Policy Decision Point) for Teleport services, +// whereas the services themselves act as the PEP (Policy Enforcement Point). +// In other words, it calculates the outcome of an authorization request but +// does not enforce it - each Teleport service must do so. +// +// Evaluation responses carry all the data necessary for the enforcement of a +// decision. A successful evaluation carries a Permit, whereas a failed +// evaluation carries a Denial. +type DecisionServiceClient interface { + // EvaluateSSHAccess evaluates an SSH access attempt. + EvaluateSSHAccess(ctx context.Context, in *EvaluateSSHAccessRequest, opts ...grpc.CallOption) (*EvaluateSSHAccessResponse, error) + // EvaluateDatabaseAccess evaluate a database access attempt. + EvaluateDatabaseAccess(ctx context.Context, in *EvaluateDatabaseAccessRequest, opts ...grpc.CallOption) (*EvaluateDatabaseAccessResponse, error) +} + +type decisionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewDecisionServiceClient(cc grpc.ClientConnInterface) DecisionServiceClient { + return &decisionServiceClient{cc} +} + +func (c *decisionServiceClient) EvaluateSSHAccess(ctx context.Context, in *EvaluateSSHAccessRequest, opts ...grpc.CallOption) (*EvaluateSSHAccessResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(EvaluateSSHAccessResponse) + err := c.cc.Invoke(ctx, DecisionService_EvaluateSSHAccess_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *decisionServiceClient) EvaluateDatabaseAccess(ctx context.Context, in *EvaluateDatabaseAccessRequest, opts ...grpc.CallOption) (*EvaluateDatabaseAccessResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(EvaluateDatabaseAccessResponse) + err := c.cc.Invoke(ctx, DecisionService_EvaluateDatabaseAccess_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DecisionServiceServer is the server API for DecisionService service. +// All implementations must embed UnimplementedDecisionServiceServer +// for forward compatibility. +// +// DecisionService performs authorization decisions for Teleport. +// +// DecisionService acts the PDP (Policy Decision Point) for Teleport services, +// whereas the services themselves act as the PEP (Policy Enforcement Point). +// In other words, it calculates the outcome of an authorization request but +// does not enforce it - each Teleport service must do so. +// +// Evaluation responses carry all the data necessary for the enforcement of a +// decision. A successful evaluation carries a Permit, whereas a failed +// evaluation carries a Denial. +type DecisionServiceServer interface { + // EvaluateSSHAccess evaluates an SSH access attempt. + EvaluateSSHAccess(context.Context, *EvaluateSSHAccessRequest) (*EvaluateSSHAccessResponse, error) + // EvaluateDatabaseAccess evaluate a database access attempt. + EvaluateDatabaseAccess(context.Context, *EvaluateDatabaseAccessRequest) (*EvaluateDatabaseAccessResponse, error) + mustEmbedUnimplementedDecisionServiceServer() +} + +// UnimplementedDecisionServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedDecisionServiceServer struct{} + +func (UnimplementedDecisionServiceServer) EvaluateSSHAccess(context.Context, *EvaluateSSHAccessRequest) (*EvaluateSSHAccessResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EvaluateSSHAccess not implemented") +} +func (UnimplementedDecisionServiceServer) EvaluateDatabaseAccess(context.Context, *EvaluateDatabaseAccessRequest) (*EvaluateDatabaseAccessResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EvaluateDatabaseAccess not implemented") +} +func (UnimplementedDecisionServiceServer) mustEmbedUnimplementedDecisionServiceServer() {} +func (UnimplementedDecisionServiceServer) testEmbeddedByValue() {} + +// UnsafeDecisionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DecisionServiceServer will +// result in compilation errors. +type UnsafeDecisionServiceServer interface { + mustEmbedUnimplementedDecisionServiceServer() +} + +func RegisterDecisionServiceServer(s grpc.ServiceRegistrar, srv DecisionServiceServer) { + // If the following call pancis, it indicates UnimplementedDecisionServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&DecisionService_ServiceDesc, srv) +} + +func _DecisionService_EvaluateSSHAccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EvaluateSSHAccessRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DecisionServiceServer).EvaluateSSHAccess(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DecisionService_EvaluateSSHAccess_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DecisionServiceServer).EvaluateSSHAccess(ctx, req.(*EvaluateSSHAccessRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DecisionService_EvaluateDatabaseAccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EvaluateDatabaseAccessRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DecisionServiceServer).EvaluateDatabaseAccess(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DecisionService_EvaluateDatabaseAccess_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DecisionServiceServer).EvaluateDatabaseAccess(ctx, req.(*EvaluateDatabaseAccessRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// DecisionService_ServiceDesc is the grpc.ServiceDesc for DecisionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DecisionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "teleport.decision.v1alpha1.DecisionService", + HandlerType: (*DecisionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "EvaluateSSHAccess", + Handler: _DecisionService_EvaluateSSHAccess_Handler, + }, + { + MethodName: "EvaluateDatabaseAccess", + Handler: _DecisionService_EvaluateDatabaseAccess_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "teleport/decision/v1alpha1/decision_service.proto", +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/denial_metadata.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/denial_metadata.pb.go new file mode 100644 index 0000000000000..00eca04ec722b --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/denial_metadata.pb.go @@ -0,0 +1,188 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/denial_metadata.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Metadata for access denials. +type DenialMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // FeatureAssertions is a list of EnforcementFeature that the PEP (Policy + // Enforcement Point) *must* implement in order to correctly enforce the + // decision. Note that denials rarely need feature assertions since they + // typically "fail safe" anyway. + FeatureAssertions []EnforcementFeature `protobuf:"varint,1,rep,packed,name=feature_assertions,json=featureAssertions,proto3,enum=teleport.decision.v1alpha1.EnforcementFeature" json:"feature_assertions,omitempty"` + // PdpVersion is the version of the PDP (Policy Decision Point) that evaluated + // the decision request. + PdpVersion string `protobuf:"bytes,2,opt,name=pdp_version,json=pdpVersion,proto3" json:"pdp_version,omitempty"` + // UserMessage is a sanitized message safe for return to the subject identity + // of the decision request. + UserMessage string `protobuf:"bytes,3,opt,name=user_message,json=userMessage,proto3" json:"user_message,omitempty"` +} + +func (x *DenialMetadata) Reset() { + *x = DenialMetadata{} + mi := &file_teleport_decision_v1alpha1_denial_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DenialMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DenialMetadata) ProtoMessage() {} + +func (x *DenialMetadata) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_denial_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DenialMetadata.ProtoReflect.Descriptor instead. +func (*DenialMetadata) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *DenialMetadata) GetFeatureAssertions() []EnforcementFeature { + if x != nil { + return x.FeatureAssertions + } + return nil +} + +func (x *DenialMetadata) GetPdpVersion() string { + if x != nil { + return x.PdpVersion + } + return "" +} + +func (x *DenialMetadata) GetUserMessage() string { + if x != nil { + return x.UserMessage + } + return "" +} + +var File_teleport_decision_v1alpha1_denial_metadata_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_denial_metadata_proto_rawDesc = []byte{ + 0x0a, 0x30, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x6e, + 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x34, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x65, 0x6e, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5d, 0x0a, 0x12, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x52, 0x11, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, + 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x64, 0x70, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x64, 0x70, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x75, + 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescData = file_teleport_decision_v1alpha1_denial_metadata_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_denial_metadata_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_denial_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_decision_v1alpha1_denial_metadata_proto_goTypes = []any{ + (*DenialMetadata)(nil), // 0: teleport.decision.v1alpha1.DenialMetadata + (EnforcementFeature)(0), // 1: teleport.decision.v1alpha1.EnforcementFeature +} +var file_teleport_decision_v1alpha1_denial_metadata_proto_depIdxs = []int32{ + 1, // 0: teleport.decision.v1alpha1.DenialMetadata.feature_assertions:type_name -> teleport.decision.v1alpha1.EnforcementFeature + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_denial_metadata_proto_init() } +func file_teleport_decision_v1alpha1_denial_metadata_proto_init() { + if File_teleport_decision_v1alpha1_denial_metadata_proto != nil { + return + } + file_teleport_decision_v1alpha1_enforcement_feature_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_denial_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_denial_metadata_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_denial_metadata_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_denial_metadata_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_denial_metadata_proto = out.File + file_teleport_decision_v1alpha1_denial_metadata_proto_rawDesc = nil + file_teleport_decision_v1alpha1_denial_metadata_proto_goTypes = nil + file_teleport_decision_v1alpha1_denial_metadata_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/enforcement_feature.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/enforcement_feature.pb.go new file mode 100644 index 0000000000000..ec1cc0645977a --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/enforcement_feature.pb.go @@ -0,0 +1,151 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/enforcement_feature.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// EnforcementFeature represents PEP (Policy Enforcement Point) features. +type EnforcementFeature int32 + +const ( + // ENFORCEMENT_FEATURE_UNSPECIFIED is the default/unspecified value for + // EnforcementFeature. Asserting this feature has no effect. + EnforcementFeature_ENFORCEMENT_FEATURE_UNSPECIFIED EnforcementFeature = 0 +) + +// Enum value maps for EnforcementFeature. +var ( + EnforcementFeature_name = map[int32]string{ + 0: "ENFORCEMENT_FEATURE_UNSPECIFIED", + } + EnforcementFeature_value = map[string]int32{ + "ENFORCEMENT_FEATURE_UNSPECIFIED": 0, + } +) + +func (x EnforcementFeature) Enum() *EnforcementFeature { + p := new(EnforcementFeature) + *p = x + return p +} + +func (x EnforcementFeature) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (EnforcementFeature) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_decision_v1alpha1_enforcement_feature_proto_enumTypes[0].Descriptor() +} + +func (EnforcementFeature) Type() protoreflect.EnumType { + return &file_teleport_decision_v1alpha1_enforcement_feature_proto_enumTypes[0] +} + +func (x EnforcementFeature) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use EnforcementFeature.Descriptor instead. +func (EnforcementFeature) EnumDescriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescGZIP(), []int{0} +} + +var File_teleport_decision_v1alpha1_enforcement_feature_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDesc = []byte{ + 0x0a, 0x34, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x65, 0x6e, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2a, 0x39, 0x0a, 0x12, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x4e, 0x46, 0x4f, + 0x52, 0x43, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x42, 0x5a, 0x5a, + 0x58, 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, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescData = file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_enforcement_feature_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_decision_v1alpha1_enforcement_feature_proto_goTypes = []any{ + (EnforcementFeature)(0), // 0: teleport.decision.v1alpha1.EnforcementFeature +} +var file_teleport_decision_v1alpha1_enforcement_feature_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_enforcement_feature_proto_init() } +func file_teleport_decision_v1alpha1_enforcement_feature_proto_init() { + if File_teleport_decision_v1alpha1_enforcement_feature_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_enforcement_feature_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_enforcement_feature_proto_depIdxs, + EnumInfos: file_teleport_decision_v1alpha1_enforcement_feature_proto_enumTypes, + }.Build() + File_teleport_decision_v1alpha1_enforcement_feature_proto = out.File + file_teleport_decision_v1alpha1_enforcement_feature_proto_rawDesc = nil + file_teleport_decision_v1alpha1_enforcement_feature_proto_goTypes = nil + file_teleport_decision_v1alpha1_enforcement_feature_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/permit_metadata.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/permit_metadata.pb.go new file mode 100644 index 0000000000000..5b6779c587b63 --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/permit_metadata.pb.go @@ -0,0 +1,176 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/permit_metadata.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Metadata for access permits. +type PermitMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // FeatureAssertions is a list of EnforcementFeature that the PEP (Policy + // Enforcement Point) *must* implement in order to correctly enforce the + // decision. Note that where possible new features should be structured to + // "fail safe" rather than relying on feature assertions. + FeatureAssertions []EnforcementFeature `protobuf:"varint,1,rep,packed,name=feature_assertions,json=featureAssertions,proto3,enum=teleport.decision.v1alpha1.EnforcementFeature" json:"feature_assertions,omitempty"` + // PdpVersion is the version of the PDP (Policy Decision Point) that evaluated + // the decision request. + PdpVersion string `protobuf:"bytes,2,opt,name=pdp_version,json=pdpVersion,proto3" json:"pdp_version,omitempty"` +} + +func (x *PermitMetadata) Reset() { + *x = PermitMetadata{} + mi := &file_teleport_decision_v1alpha1_permit_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PermitMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermitMetadata) ProtoMessage() {} + +func (x *PermitMetadata) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_permit_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermitMetadata.ProtoReflect.Descriptor instead. +func (*PermitMetadata) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *PermitMetadata) GetFeatureAssertions() []EnforcementFeature { + if x != nil { + return x.FeatureAssertions + } + return nil +} + +func (x *PermitMetadata) GetPdpVersion() string { + if x != nil { + return x.PdpVersion + } + return "" +} + +var File_teleport_decision_v1alpha1_permit_metadata_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_permit_metadata_proto_rawDesc = []byte{ + 0x0a, 0x30, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x34, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x65, 0x6e, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x90, 0x01, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5d, 0x0a, 0x12, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x52, 0x11, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, + 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x64, 0x70, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x64, 0x70, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescData = file_teleport_decision_v1alpha1_permit_metadata_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_permit_metadata_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_permit_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_decision_v1alpha1_permit_metadata_proto_goTypes = []any{ + (*PermitMetadata)(nil), // 0: teleport.decision.v1alpha1.PermitMetadata + (EnforcementFeature)(0), // 1: teleport.decision.v1alpha1.EnforcementFeature +} +var file_teleport_decision_v1alpha1_permit_metadata_proto_depIdxs = []int32{ + 1, // 0: teleport.decision.v1alpha1.PermitMetadata.feature_assertions:type_name -> teleport.decision.v1alpha1.EnforcementFeature + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_permit_metadata_proto_init() } +func file_teleport_decision_v1alpha1_permit_metadata_proto_init() { + if File_teleport_decision_v1alpha1_permit_metadata_proto != nil { + return + } + file_teleport_decision_v1alpha1_enforcement_feature_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_permit_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_permit_metadata_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_permit_metadata_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_permit_metadata_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_permit_metadata_proto = out.File + file_teleport_decision_v1alpha1_permit_metadata_proto_rawDesc = nil + file_teleport_decision_v1alpha1_permit_metadata_proto_goTypes = nil + file_teleport_decision_v1alpha1_permit_metadata_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/request_metadata.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/request_metadata.pb.go new file mode 100644 index 0000000000000..56030be3fe56d --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/request_metadata.pb.go @@ -0,0 +1,229 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/request_metadata.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// DecisionFeature represents supported PDP (Policy Decision Point) features. +type DecisionFeature int32 + +const ( + // DECISION_FEATURE_UNSPECIFIED is the default/unspecified value for + // DecisionFeature. Asserting this feature has no effect. + DecisionFeature_DECISION_FEATURE_UNSPECIFIED DecisionFeature = 0 +) + +// Enum value maps for DecisionFeature. +var ( + DecisionFeature_name = map[int32]string{ + 0: "DECISION_FEATURE_UNSPECIFIED", + } + DecisionFeature_value = map[string]int32{ + "DECISION_FEATURE_UNSPECIFIED": 0, + } +) + +func (x DecisionFeature) Enum() *DecisionFeature { + p := new(DecisionFeature) + *p = x + return p +} + +func (x DecisionFeature) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DecisionFeature) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_decision_v1alpha1_request_metadata_proto_enumTypes[0].Descriptor() +} + +func (DecisionFeature) Type() protoreflect.EnumType { + return &file_teleport_decision_v1alpha1_request_metadata_proto_enumTypes[0] +} + +func (x DecisionFeature) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DecisionFeature.Descriptor instead. +func (DecisionFeature) EnumDescriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_request_metadata_proto_rawDescGZIP(), []int{0} +} + +// Metadata for evaluation requests. +type RequestMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // FeatureAssertions is a list of DecisionFeature that the PDP (Policy + // Decision Point) *must* implement in order to correctly evaluate the + // decision request. Note that changes that require new features in the PDP in + // order for it to understand a decision request are rare and should be + // avoided if possible. + FeatureAssertions []DecisionFeature `protobuf:"varint,1,rep,packed,name=feature_assertions,json=featureAssertions,proto3,enum=teleport.decision.v1alpha1.DecisionFeature" json:"feature_assertions,omitempty"` + // PepVersionHint is the *likely* version of the PEP that will enforce the + // decision. Not all decision requests can guarantee that the expected PEP + // (Policy Enforcement Point) version will actually be the version that ends + // up enforcing the decision. Hard compatibility requirements must be enforced + // via feature assertions so that PEPs can correctly reject decisions that + // they cannot enforce. + PepVersionHint string `protobuf:"bytes,2,opt,name=pep_version_hint,json=pepVersionHint,proto3" json:"pep_version_hint,omitempty"` +} + +func (x *RequestMetadata) Reset() { + *x = RequestMetadata{} + mi := &file_teleport_decision_v1alpha1_request_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequestMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestMetadata) ProtoMessage() {} + +func (x *RequestMetadata) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_request_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestMetadata.ProtoReflect.Descriptor instead. +func (*RequestMetadata) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_request_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *RequestMetadata) GetFeatureAssertions() []DecisionFeature { + if x != nil { + return x.FeatureAssertions + } + return nil +} + +func (x *RequestMetadata) GetPepVersionHint() string { + if x != nil { + return x.PepVersionHint + } + return "" +} + +var File_teleport_decision_v1alpha1_request_metadata_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_request_metadata_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, + 0x97, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x5a, 0x0a, 0x12, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x61, + 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x11, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x28, 0x0a, 0x10, 0x70, 0x65, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x68, + 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x65, 0x70, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x6e, 0x74, 0x2a, 0x33, 0x0a, 0x0f, 0x44, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x1c, + 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x42, 0x5a, + 0x5a, 0x58, 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, 0x64, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_request_metadata_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_request_metadata_proto_rawDescData = file_teleport_decision_v1alpha1_request_metadata_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_request_metadata_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_request_metadata_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_request_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_request_metadata_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_request_metadata_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_request_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_decision_v1alpha1_request_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_decision_v1alpha1_request_metadata_proto_goTypes = []any{ + (DecisionFeature)(0), // 0: teleport.decision.v1alpha1.DecisionFeature + (*RequestMetadata)(nil), // 1: teleport.decision.v1alpha1.RequestMetadata +} +var file_teleport_decision_v1alpha1_request_metadata_proto_depIdxs = []int32{ + 0, // 0: teleport.decision.v1alpha1.RequestMetadata.feature_assertions:type_name -> teleport.decision.v1alpha1.DecisionFeature + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_request_metadata_proto_init() } +func file_teleport_decision_v1alpha1_request_metadata_proto_init() { + if File_teleport_decision_v1alpha1_request_metadata_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_request_metadata_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_request_metadata_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_request_metadata_proto_depIdxs, + EnumInfos: file_teleport_decision_v1alpha1_request_metadata_proto_enumTypes, + MessageInfos: file_teleport_decision_v1alpha1_request_metadata_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_request_metadata_proto = out.File + file_teleport_decision_v1alpha1_request_metadata_proto_rawDesc = nil + file_teleport_decision_v1alpha1_request_metadata_proto_goTypes = nil + file_teleport_decision_v1alpha1_request_metadata_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/resource.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/resource.pb.go new file mode 100644 index 0000000000000..fa1bda927f62e --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/resource.pb.go @@ -0,0 +1,176 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/resource.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Resource is the conventional reference type used to refer to the "object" of +// an action that is being considered for an authorization decision. For +// example, a call to EvaluateSSHAccess would use the Resource type to reference +// the ssh node being accessed. +type Resource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Kind is the type of the resource. Required for requests that support + // multiple types, otherwise safe to omit. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // SubKind is the subtype of the resource. Usually not required as most + // resources don't have subkinds, or their subkinds do not have an effect on + // authorization decisions. + SubKind string `protobuf:"bytes,2,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + // Name is the unique name of the resource. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *Resource) Reset() { + *x = Resource{} + mi := &file_teleport_decision_v1alpha1_resource_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Resource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Resource) ProtoMessage() {} + +func (x *Resource) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_resource_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Resource.ProtoReflect.Descriptor instead. +func (*Resource) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_resource_proto_rawDescGZIP(), []int{0} +} + +func (x *Resource) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *Resource) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *Resource) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +var File_teleport_decision_v1alpha1_resource_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_resource_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x4d, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, + 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_resource_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_resource_proto_rawDescData = file_teleport_decision_v1alpha1_resource_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_resource_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_resource_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_resource_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_resource_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_resource_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_decision_v1alpha1_resource_proto_goTypes = []any{ + (*Resource)(nil), // 0: teleport.decision.v1alpha1.Resource +} +var file_teleport_decision_v1alpha1_resource_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_resource_proto_init() } +func file_teleport_decision_v1alpha1_resource_proto_init() { + if File_teleport_decision_v1alpha1_resource_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_resource_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_resource_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_resource_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_resource_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_resource_proto = out.File + file_teleport_decision_v1alpha1_resource_proto_rawDesc = nil + file_teleport_decision_v1alpha1_resource_proto_goTypes = nil + file_teleport_decision_v1alpha1_resource_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/ssh_access.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/ssh_access.pb.go new file mode 100644 index 0000000000000..0c70ef74ece7f --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/ssh_access.pb.go @@ -0,0 +1,599 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/ssh_access.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// EvaluateSSHAccessRequest describes a request to evaluate whether or not a +// given ssh access attempt should be permitted. +type EvaluateSSHAccessRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Metadata holds common authorization decision request fields. + Metadata *RequestMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // User describes the teleport user requesting access. + SshIdentity *SSHIdentity `protobuf:"bytes,2,opt,name=ssh_identity,json=sshIdentity,proto3" json:"ssh_identity,omitempty"` + // Node references the target node the user is attempting to access. + Node *Resource `protobuf:"bytes,3,opt,name=node,proto3" json:"node,omitempty"` +} + +func (x *EvaluateSSHAccessRequest) Reset() { + *x = EvaluateSSHAccessRequest{} + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EvaluateSSHAccessRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluateSSHAccessRequest) ProtoMessage() {} + +func (x *EvaluateSSHAccessRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EvaluateSSHAccessRequest.ProtoReflect.Descriptor instead. +func (*EvaluateSSHAccessRequest) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_access_proto_rawDescGZIP(), []int{0} +} + +func (x *EvaluateSSHAccessRequest) GetMetadata() *RequestMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *EvaluateSSHAccessRequest) GetSshIdentity() *SSHIdentity { + if x != nil { + return x.SshIdentity + } + return nil +} + +func (x *EvaluateSSHAccessRequest) GetNode() *Resource { + if x != nil { + return x.Node + } + return nil +} + +// EvaluateSSHAccessResponse describes the result of an SSH access evaluation. +type EvaluateSSHAccessResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Decision: + // + // *EvaluateSSHAccessResponse_Permit + // *EvaluateSSHAccessResponse_Denial + Decision isEvaluateSSHAccessResponse_Decision `protobuf_oneof:"decision"` +} + +func (x *EvaluateSSHAccessResponse) Reset() { + *x = EvaluateSSHAccessResponse{} + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EvaluateSSHAccessResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluateSSHAccessResponse) ProtoMessage() {} + +func (x *EvaluateSSHAccessResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EvaluateSSHAccessResponse.ProtoReflect.Descriptor instead. +func (*EvaluateSSHAccessResponse) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_access_proto_rawDescGZIP(), []int{1} +} + +func (m *EvaluateSSHAccessResponse) GetDecision() isEvaluateSSHAccessResponse_Decision { + if m != nil { + return m.Decision + } + return nil +} + +func (x *EvaluateSSHAccessResponse) GetPermit() *SSHAccessPermit { + if x, ok := x.GetDecision().(*EvaluateSSHAccessResponse_Permit); ok { + return x.Permit + } + return nil +} + +func (x *EvaluateSSHAccessResponse) GetDenial() *SSHAccessDenial { + if x, ok := x.GetDecision().(*EvaluateSSHAccessResponse_Denial); ok { + return x.Denial + } + return nil +} + +type isEvaluateSSHAccessResponse_Decision interface { + isEvaluateSSHAccessResponse_Decision() +} + +type EvaluateSSHAccessResponse_Permit struct { + Permit *SSHAccessPermit `protobuf:"bytes,1,opt,name=permit,proto3,oneof"` +} + +type EvaluateSSHAccessResponse_Denial struct { + Denial *SSHAccessDenial `protobuf:"bytes,2,opt,name=denial,proto3,oneof"` +} + +func (*EvaluateSSHAccessResponse_Permit) isEvaluateSSHAccessResponse_Decision() {} + +func (*EvaluateSSHAccessResponse_Denial) isEvaluateSSHAccessResponse_Decision() {} + +// SSHAccessPermit describes the parameters/constraints of a permissible SSH +// access attempt. +type SSHAccessPermit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *PermitMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + Logins []string `protobuf:"bytes,2,rep,name=logins,proto3" json:"logins,omitempty"` + ForwardAgent bool `protobuf:"varint,3,opt,name=forward_agent,json=forwardAgent,proto3" json:"forward_agent,omitempty"` + MaxSessionTtl *durationpb.Duration `protobuf:"bytes,4,opt,name=max_session_ttl,json=maxSessionTtl,proto3" json:"max_session_ttl,omitempty"` + PortForwarding bool `protobuf:"varint,5,opt,name=port_forwarding,json=portForwarding,proto3" json:"port_forwarding,omitempty"` + ClientIdleTimeout int64 `protobuf:"varint,6,opt,name=client_idle_timeout,json=clientIdleTimeout,proto3" json:"client_idle_timeout,omitempty"` + DisconnectExpiredCert bool `protobuf:"varint,7,opt,name=disconnect_expired_cert,json=disconnectExpiredCert,proto3" json:"disconnect_expired_cert,omitempty"` + Bpf []string `protobuf:"bytes,8,rep,name=bpf,proto3" json:"bpf,omitempty"` + X11Forwarding bool `protobuf:"varint,9,opt,name=x11_forwarding,json=x11Forwarding,proto3" json:"x11_forwarding,omitempty"` + MaxConnections int64 `protobuf:"varint,10,opt,name=max_connections,json=maxConnections,proto3" json:"max_connections,omitempty"` + MaxSessions int64 `protobuf:"varint,11,opt,name=max_sessions,json=maxSessions,proto3" json:"max_sessions,omitempty"` + Lock string `protobuf:"bytes,12,opt,name=lock,proto3" json:"lock,omitempty"` + CreateHostUser bool `protobuf:"varint,13,opt,name=create_host_user,json=createHostUser,proto3" json:"create_host_user,omitempty"` + SshFileCopy bool `protobuf:"varint,14,opt,name=ssh_file_copy,json=sshFileCopy,proto3" json:"ssh_file_copy,omitempty"` + CreateHostUserMode string `protobuf:"bytes,15,opt,name=create_host_user_mode,json=createHostUserMode,proto3" json:"create_host_user_mode,omitempty"` + CreateHostUserShell string `protobuf:"bytes,16,opt,name=create_host_user_shell,json=createHostUserShell,proto3" json:"create_host_user_shell,omitempty"` + HostGroups []string `protobuf:"bytes,17,rep,name=host_groups,json=hostGroups,proto3" json:"host_groups,omitempty"` + HostSudoers []string `protobuf:"bytes,18,rep,name=host_sudoers,json=hostSudoers,proto3" json:"host_sudoers,omitempty"` +} + +func (x *SSHAccessPermit) Reset() { + *x = SSHAccessPermit{} + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SSHAccessPermit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SSHAccessPermit) ProtoMessage() {} + +func (x *SSHAccessPermit) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SSHAccessPermit.ProtoReflect.Descriptor instead. +func (*SSHAccessPermit) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_access_proto_rawDescGZIP(), []int{2} +} + +func (x *SSHAccessPermit) GetMetadata() *PermitMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *SSHAccessPermit) GetLogins() []string { + if x != nil { + return x.Logins + } + return nil +} + +func (x *SSHAccessPermit) GetForwardAgent() bool { + if x != nil { + return x.ForwardAgent + } + return false +} + +func (x *SSHAccessPermit) GetMaxSessionTtl() *durationpb.Duration { + if x != nil { + return x.MaxSessionTtl + } + return nil +} + +func (x *SSHAccessPermit) GetPortForwarding() bool { + if x != nil { + return x.PortForwarding + } + return false +} + +func (x *SSHAccessPermit) GetClientIdleTimeout() int64 { + if x != nil { + return x.ClientIdleTimeout + } + return 0 +} + +func (x *SSHAccessPermit) GetDisconnectExpiredCert() bool { + if x != nil { + return x.DisconnectExpiredCert + } + return false +} + +func (x *SSHAccessPermit) GetBpf() []string { + if x != nil { + return x.Bpf + } + return nil +} + +func (x *SSHAccessPermit) GetX11Forwarding() bool { + if x != nil { + return x.X11Forwarding + } + return false +} + +func (x *SSHAccessPermit) GetMaxConnections() int64 { + if x != nil { + return x.MaxConnections + } + return 0 +} + +func (x *SSHAccessPermit) GetMaxSessions() int64 { + if x != nil { + return x.MaxSessions + } + return 0 +} + +func (x *SSHAccessPermit) GetLock() string { + if x != nil { + return x.Lock + } + return "" +} + +func (x *SSHAccessPermit) GetCreateHostUser() bool { + if x != nil { + return x.CreateHostUser + } + return false +} + +func (x *SSHAccessPermit) GetSshFileCopy() bool { + if x != nil { + return x.SshFileCopy + } + return false +} + +func (x *SSHAccessPermit) GetCreateHostUserMode() string { + if x != nil { + return x.CreateHostUserMode + } + return "" +} + +func (x *SSHAccessPermit) GetCreateHostUserShell() string { + if x != nil { + return x.CreateHostUserShell + } + return "" +} + +func (x *SSHAccessPermit) GetHostGroups() []string { + if x != nil { + return x.HostGroups + } + return nil +} + +func (x *SSHAccessPermit) GetHostSudoers() []string { + if x != nil { + return x.HostSudoers + } + return nil +} + +// SSHAccessDenial describes an SSH access denial. +type SSHAccessDenial struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *DenialMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *SSHAccessDenial) Reset() { + *x = SSHAccessDenial{} + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SSHAccessDenial) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SSHAccessDenial) ProtoMessage() {} + +func (x *SSHAccessDenial) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SSHAccessDenial.ProtoReflect.Descriptor instead. +func (*SSHAccessDenial) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_access_proto_rawDescGZIP(), []int{3} +} + +func (x *SSHAccessDenial) GetMetadata() *DenialMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +var File_teleport_decision_v1alpha1_ssh_access_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_ssh_access_proto_rawDesc = []byte{ + 0x0a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x73, 0x68, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x29, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe9, 0x01, 0x0a, 0x18, 0x45, + 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x4a, 0x0a, 0x0c, 0x73, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x53, 0x53, 0x48, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, + 0x0b, 0x73, 0x73, 0x68, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x38, 0x0a, 0x04, + 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0xb5, 0x01, 0x0a, 0x19, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x65, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x74, 0x48, 0x00, 0x52, 0x06, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x64, + 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x44, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6e, 0x69, + 0x61, 0x6c, 0x42, 0x0a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xfd, + 0x05, 0x0a, 0x0f, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x74, 0x12, 0x46, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x6f, + 0x67, 0x69, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x6f, 0x67, 0x69, + 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x74, 0x6c, 0x18, 0x04, 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, 0x0d, 0x6d, 0x61, 0x78, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x74, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6f, + 0x72, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x62, + 0x70, 0x66, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x62, 0x70, 0x66, 0x12, 0x25, 0x0a, + 0x0e, 0x78, 0x31, 0x31, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x78, 0x31, 0x31, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, + 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x68, + 0x6f, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x22, + 0x0a, 0x0d, 0x73, 0x73, 0x68, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x73, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x70, 0x79, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x68, 0x6f, 0x73, + 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x73, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x6f, + 0x73, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x68, + 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x64, 0x6f, 0x65, 0x72, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x53, 0x75, 0x64, 0x6f, 0x65, 0x72, 0x73, 0x22, 0x59, + 0x0a, 0x0f, 0x53, 0x53, 0x48, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x44, 0x65, 0x6e, 0x69, 0x61, + 0x6c, 0x12, 0x46, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_ssh_access_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_ssh_access_proto_rawDescData = file_teleport_decision_v1alpha1_ssh_access_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_ssh_access_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_ssh_access_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_ssh_access_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_ssh_access_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_ssh_access_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_decision_v1alpha1_ssh_access_proto_goTypes = []any{ + (*EvaluateSSHAccessRequest)(nil), // 0: teleport.decision.v1alpha1.EvaluateSSHAccessRequest + (*EvaluateSSHAccessResponse)(nil), // 1: teleport.decision.v1alpha1.EvaluateSSHAccessResponse + (*SSHAccessPermit)(nil), // 2: teleport.decision.v1alpha1.SSHAccessPermit + (*SSHAccessDenial)(nil), // 3: teleport.decision.v1alpha1.SSHAccessDenial + (*RequestMetadata)(nil), // 4: teleport.decision.v1alpha1.RequestMetadata + (*SSHIdentity)(nil), // 5: teleport.decision.v1alpha1.SSHIdentity + (*Resource)(nil), // 6: teleport.decision.v1alpha1.Resource + (*PermitMetadata)(nil), // 7: teleport.decision.v1alpha1.PermitMetadata + (*durationpb.Duration)(nil), // 8: google.protobuf.Duration + (*DenialMetadata)(nil), // 9: teleport.decision.v1alpha1.DenialMetadata +} +var file_teleport_decision_v1alpha1_ssh_access_proto_depIdxs = []int32{ + 4, // 0: teleport.decision.v1alpha1.EvaluateSSHAccessRequest.metadata:type_name -> teleport.decision.v1alpha1.RequestMetadata + 5, // 1: teleport.decision.v1alpha1.EvaluateSSHAccessRequest.ssh_identity:type_name -> teleport.decision.v1alpha1.SSHIdentity + 6, // 2: teleport.decision.v1alpha1.EvaluateSSHAccessRequest.node:type_name -> teleport.decision.v1alpha1.Resource + 2, // 3: teleport.decision.v1alpha1.EvaluateSSHAccessResponse.permit:type_name -> teleport.decision.v1alpha1.SSHAccessPermit + 3, // 4: teleport.decision.v1alpha1.EvaluateSSHAccessResponse.denial:type_name -> teleport.decision.v1alpha1.SSHAccessDenial + 7, // 5: teleport.decision.v1alpha1.SSHAccessPermit.metadata:type_name -> teleport.decision.v1alpha1.PermitMetadata + 8, // 6: teleport.decision.v1alpha1.SSHAccessPermit.max_session_ttl:type_name -> google.protobuf.Duration + 9, // 7: teleport.decision.v1alpha1.SSHAccessDenial.metadata:type_name -> teleport.decision.v1alpha1.DenialMetadata + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_ssh_access_proto_init() } +func file_teleport_decision_v1alpha1_ssh_access_proto_init() { + if File_teleport_decision_v1alpha1_ssh_access_proto != nil { + return + } + file_teleport_decision_v1alpha1_denial_metadata_proto_init() + file_teleport_decision_v1alpha1_permit_metadata_proto_init() + file_teleport_decision_v1alpha1_request_metadata_proto_init() + file_teleport_decision_v1alpha1_resource_proto_init() + file_teleport_decision_v1alpha1_ssh_identity_proto_init() + file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes[1].OneofWrappers = []any{ + (*EvaluateSSHAccessResponse_Permit)(nil), + (*EvaluateSSHAccessResponse_Denial)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_ssh_access_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_ssh_access_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_ssh_access_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_ssh_access_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_ssh_access_proto = out.File + file_teleport_decision_v1alpha1_ssh_access_proto_rawDesc = nil + file_teleport_decision_v1alpha1_ssh_access_proto_goTypes = nil + file_teleport_decision_v1alpha1_ssh_access_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go new file mode 100644 index 0000000000000..cefff7cdc1ffc --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go @@ -0,0 +1,138 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/ssh_identity.proto + +package decisionpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// SSHIdentity is the identity used for SSH connections. +type SSHIdentity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SSHIdentity) Reset() { + *x = SSHIdentity{} + mi := &file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SSHIdentity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SSHIdentity) ProtoMessage() {} + +func (x *SSHIdentity) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SSHIdentity.ProtoReflect.Descriptor instead. +func (*SSHIdentity) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP(), []int{0} +} + +var File_teleport_decision_v1alpha1_ssh_identity_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x73, 0x68, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x0d, 0x0a, 0x0b, 0x53, + 0x53, 0x48, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescData = file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_decision_v1alpha1_ssh_identity_proto_goTypes = []any{ + (*SSHIdentity)(nil), // 0: teleport.decision.v1alpha1.SSHIdentity +} +var file_teleport_decision_v1alpha1_ssh_identity_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_ssh_identity_proto_init() } +func file_teleport_decision_v1alpha1_ssh_identity_proto_init() { + if File_teleport_decision_v1alpha1_ssh_identity_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_ssh_identity_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_ssh_identity_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_ssh_identity_proto = out.File + file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc = nil + file_teleport_decision_v1alpha1_ssh_identity_proto_goTypes = nil + file_teleport_decision_v1alpha1_ssh_identity_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/tls_identity.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/tls_identity.pb.go new file mode 100644 index 0000000000000..587497ec5ae11 --- /dev/null +++ b/api/gen/proto/go/teleport/decision/v1alpha1/tls_identity.pb.go @@ -0,0 +1,1002 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/decision/v1alpha1/tls_identity.proto + +package decisionpb + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/trait/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// TLSIdentity is the identity used for TLS connections. +// Must be kept in sync with tlsca.Identity. +type TLSIdentity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Username is the name of the user (for end-users/bots) or the Host ID (for + // Teleport processes). + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + // Impersonator is a username of a user impersonating this user. + Impersonator string `protobuf:"bytes,2,opt,name=impersonator,proto3" json:"impersonator,omitempty"` + // Groups is a list of groups (Teleport roles) encoded in the identity. + Groups []string `protobuf:"bytes,3,rep,name=groups,proto3" json:"groups,omitempty"` + // SystemRoles is a list of system roles (e.g. auth, proxy, node, etc) used in + // "multi-role" certificates. Single-role certificates encode the system role + // in `Groups` for back-compat reasons. + SystemRoles []string `protobuf:"bytes,4,rep,name=system_roles,json=systemRoles,proto3" json:"system_roles,omitempty"` + // Usage is a list of usage restrictions encoded in the identity. + Usage []string `protobuf:"bytes,5,rep,name=usage,proto3" json:"usage,omitempty"` + // Principals is a list of Unix logins allowed. + Principals []string `protobuf:"bytes,6,rep,name=principals,proto3" json:"principals,omitempty"` + // KubernetesGroups is a list of Kubernetes groups allowed. + KubernetesGroups []string `protobuf:"bytes,7,rep,name=kubernetes_groups,json=kubernetesGroups,proto3" json:"kubernetes_groups,omitempty"` + // KubernetesUsers is a list of Kubernetes users allowed. + KubernetesUsers []string `protobuf:"bytes,8,rep,name=kubernetes_users,json=kubernetesUsers,proto3" json:"kubernetes_users,omitempty"` + // Expires specifies whenever the session will expire. + Expires *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=expires,proto3" json:"expires,omitempty"` + // RouteToCluster specifies the target cluster. + RouteToCluster string `protobuf:"bytes,10,opt,name=route_to_cluster,json=routeToCluster,proto3" json:"route_to_cluster,omitempty"` + // KubernetesCluster specifies the target kubernetes cluster for TLS + // identities. This can be empty on older Teleport clients. + KubernetesCluster string `protobuf:"bytes,11,opt,name=kubernetes_cluster,json=kubernetesCluster,proto3" json:"kubernetes_cluster,omitempty"` + // Traits hold claim data used to populate a role at runtime. + Traits []*v1.Trait `protobuf:"bytes,12,rep,name=traits,proto3" json:"traits,omitempty"` + // RouteToApp holds routing information for applications. Routing metadata + // allows Teleport web proxy to route HTTP requests to the appropriate cluster + // and Teleport application proxy within the cluster. + RouteToApp *RouteToApp `protobuf:"bytes,13,opt,name=route_to_app,json=routeToApp,proto3" json:"route_to_app,omitempty"` + // TeleportCluster is the name of the teleport cluster that this identity + // originated from. For TLS certs this may not be the same as cert issuer, in + // case of multi-hop requests that originate from a remote cluster. + TeleportCluster string `protobuf:"bytes,14,opt,name=teleport_cluster,json=teleportCluster,proto3" json:"teleport_cluster,omitempty"` + // RouteToDatabase contains routing information for databases. + RouteToDatabase *RouteToDatabase `protobuf:"bytes,15,opt,name=route_to_database,json=routeToDatabase,proto3" json:"route_to_database,omitempty"` + // DatabaseNames is a list of allowed database names. + DatabaseNames []string `protobuf:"bytes,16,rep,name=database_names,json=databaseNames,proto3" json:"database_names,omitempty"` + // DatabaseUsers is a list of allowed database users. + DatabaseUsers []string `protobuf:"bytes,17,rep,name=database_users,json=databaseUsers,proto3" json:"database_users,omitempty"` + // MfaVerified is the UUID of an MFA device when this Identity was + // confirmed immediately after an MFA check. + MfaVerified string `protobuf:"bytes,18,opt,name=mfa_verified,json=mfaVerified,proto3" json:"mfa_verified,omitempty"` + // PreviousIdentityExpires is the expiry time of the identity/cert that this + // identity/cert was derived from. It is used to determine a session's hard + // deadline in cases where both require_session_mfa and + // disconnect_expired_cert are enabled. + // See https://github.com/gravitational/teleport/issues/18544. + PreviousIdentityExpires *timestamppb.Timestamp `protobuf:"bytes,19,opt,name=previous_identity_expires,json=previousIdentityExpires,proto3" json:"previous_identity_expires,omitempty"` + // LoginIp is an observed IP of the client that this Identity represents. + LoginIp string `protobuf:"bytes,20,opt,name=login_ip,json=loginIp,proto3" json:"login_ip,omitempty"` + // PinnedIp is an IP the certificate is pinned to. + PinnedIp string `protobuf:"bytes,21,opt,name=pinned_ip,json=pinnedIp,proto3" json:"pinned_ip,omitempty"` + // AwsRoleArns is a list of allowed AWS role ARNs user can assume. + AwsRoleArns []string `protobuf:"bytes,22,rep,name=aws_role_arns,json=awsRoleArns,proto3" json:"aws_role_arns,omitempty"` + // AzureIdentities is a list of allowed Azure identities user can assume. + AzureIdentities []string `protobuf:"bytes,23,rep,name=azure_identities,json=azureIdentities,proto3" json:"azure_identities,omitempty"` + // GcpServiceAccounts is a list of allowed GCP service accounts that the user + // can assume. + GcpServiceAccounts []string `protobuf:"bytes,24,rep,name=gcp_service_accounts,json=gcpServiceAccounts,proto3" json:"gcp_service_accounts,omitempty"` + // ActiveRequests is a list of UUIDs of active requests for this Identity. + ActiveRequests []string `protobuf:"bytes,25,rep,name=active_requests,json=activeRequests,proto3" json:"active_requests,omitempty"` + // DisallowReissue is a flag that, if set, instructs the auth server to deny + // any attempts to reissue new certificates while authenticated with this + // certificate. + DisallowReissue bool `protobuf:"varint,26,opt,name=disallow_reissue,json=disallowReissue,proto3" json:"disallow_reissue,omitempty"` + // Renewable indicates that this identity is allowed to renew it's own + // credentials. This is only enabled for certificate renewal bots. + Renewable bool `protobuf:"varint,27,opt,name=renewable,proto3" json:"renewable,omitempty"` + // Generation counts the number of times this certificate has been renewed. + Generation uint64 `protobuf:"varint,28,opt,name=generation,proto3" json:"generation,omitempty"` + // BotName indicates the name of the Machine ID bot this identity was issued + // to, if any. + BotName string `protobuf:"bytes,29,opt,name=bot_name,json=botName,proto3" json:"bot_name,omitempty"` + // BotInstanceId is a unique identifier for Machine ID bots that is persisted + // through renewals. + BotInstanceId string `protobuf:"bytes,30,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` + // AllowedResourceIds lists the resources the identity should be allowed to + // access. + AllowedResourceIds []*ResourceId `protobuf:"bytes,31,rep,name=allowed_resource_ids,json=allowedResourceIds,proto3" json:"allowed_resource_ids,omitempty"` + // PrivateKeyPolicy is the private key policy supported by this identity. + PrivateKeyPolicy string `protobuf:"bytes,32,opt,name=private_key_policy,json=privateKeyPolicy,proto3" json:"private_key_policy,omitempty"` + // ConnectionDiagnosticId is used to add connection diagnostic messages when + // Testing a Connection. + ConnectionDiagnosticId string `protobuf:"bytes,33,opt,name=connection_diagnostic_id,json=connectionDiagnosticId,proto3" json:"connection_diagnostic_id,omitempty"` + // DeviceExtensions holds device-aware extensions for the identity. + DeviceExtensions *DeviceExtensions `protobuf:"bytes,34,opt,name=device_extensions,json=deviceExtensions,proto3" json:"device_extensions,omitempty"` + // UserType indicates if the User was created by an SSO Provider or locally. + UserType string `protobuf:"bytes,35,opt,name=user_type,json=userType,proto3" json:"user_type,omitempty"` +} + +func (x *TLSIdentity) Reset() { + *x = TLSIdentity{} + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TLSIdentity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TLSIdentity) ProtoMessage() {} + +func (x *TLSIdentity) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TLSIdentity.ProtoReflect.Descriptor instead. +func (*TLSIdentity) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_tls_identity_proto_rawDescGZIP(), []int{0} +} + +func (x *TLSIdentity) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *TLSIdentity) GetImpersonator() string { + if x != nil { + return x.Impersonator + } + return "" +} + +func (x *TLSIdentity) GetGroups() []string { + if x != nil { + return x.Groups + } + return nil +} + +func (x *TLSIdentity) GetSystemRoles() []string { + if x != nil { + return x.SystemRoles + } + return nil +} + +func (x *TLSIdentity) GetUsage() []string { + if x != nil { + return x.Usage + } + return nil +} + +func (x *TLSIdentity) GetPrincipals() []string { + if x != nil { + return x.Principals + } + return nil +} + +func (x *TLSIdentity) GetKubernetesGroups() []string { + if x != nil { + return x.KubernetesGroups + } + return nil +} + +func (x *TLSIdentity) GetKubernetesUsers() []string { + if x != nil { + return x.KubernetesUsers + } + return nil +} + +func (x *TLSIdentity) GetExpires() *timestamppb.Timestamp { + if x != nil { + return x.Expires + } + return nil +} + +func (x *TLSIdentity) GetRouteToCluster() string { + if x != nil { + return x.RouteToCluster + } + return "" +} + +func (x *TLSIdentity) GetKubernetesCluster() string { + if x != nil { + return x.KubernetesCluster + } + return "" +} + +func (x *TLSIdentity) GetTraits() []*v1.Trait { + if x != nil { + return x.Traits + } + return nil +} + +func (x *TLSIdentity) GetRouteToApp() *RouteToApp { + if x != nil { + return x.RouteToApp + } + return nil +} + +func (x *TLSIdentity) GetTeleportCluster() string { + if x != nil { + return x.TeleportCluster + } + return "" +} + +func (x *TLSIdentity) GetRouteToDatabase() *RouteToDatabase { + if x != nil { + return x.RouteToDatabase + } + return nil +} + +func (x *TLSIdentity) GetDatabaseNames() []string { + if x != nil { + return x.DatabaseNames + } + return nil +} + +func (x *TLSIdentity) GetDatabaseUsers() []string { + if x != nil { + return x.DatabaseUsers + } + return nil +} + +func (x *TLSIdentity) GetMfaVerified() string { + if x != nil { + return x.MfaVerified + } + return "" +} + +func (x *TLSIdentity) GetPreviousIdentityExpires() *timestamppb.Timestamp { + if x != nil { + return x.PreviousIdentityExpires + } + return nil +} + +func (x *TLSIdentity) GetLoginIp() string { + if x != nil { + return x.LoginIp + } + return "" +} + +func (x *TLSIdentity) GetPinnedIp() string { + if x != nil { + return x.PinnedIp + } + return "" +} + +func (x *TLSIdentity) GetAwsRoleArns() []string { + if x != nil { + return x.AwsRoleArns + } + return nil +} + +func (x *TLSIdentity) GetAzureIdentities() []string { + if x != nil { + return x.AzureIdentities + } + return nil +} + +func (x *TLSIdentity) GetGcpServiceAccounts() []string { + if x != nil { + return x.GcpServiceAccounts + } + return nil +} + +func (x *TLSIdentity) GetActiveRequests() []string { + if x != nil { + return x.ActiveRequests + } + return nil +} + +func (x *TLSIdentity) GetDisallowReissue() bool { + if x != nil { + return x.DisallowReissue + } + return false +} + +func (x *TLSIdentity) GetRenewable() bool { + if x != nil { + return x.Renewable + } + return false +} + +func (x *TLSIdentity) GetGeneration() uint64 { + if x != nil { + return x.Generation + } + return 0 +} + +func (x *TLSIdentity) GetBotName() string { + if x != nil { + return x.BotName + } + return "" +} + +func (x *TLSIdentity) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + +func (x *TLSIdentity) GetAllowedResourceIds() []*ResourceId { + if x != nil { + return x.AllowedResourceIds + } + return nil +} + +func (x *TLSIdentity) GetPrivateKeyPolicy() string { + if x != nil { + return x.PrivateKeyPolicy + } + return "" +} + +func (x *TLSIdentity) GetConnectionDiagnosticId() string { + if x != nil { + return x.ConnectionDiagnosticId + } + return "" +} + +func (x *TLSIdentity) GetDeviceExtensions() *DeviceExtensions { + if x != nil { + return x.DeviceExtensions + } + return nil +} + +func (x *TLSIdentity) GetUserType() string { + if x != nil { + return x.UserType + } + return "" +} + +// RouteToApp holds routing information for applications. +type RouteToApp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // SessionId is an ID used to identify application sessions created by this + // certificate. + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // PublicAddr (and ClusterName) are used to route requests issued with this + // certificate to the appropriate application proxy/cluster. + PublicAddr string `protobuf:"bytes,2,opt,name=public_addr,json=publicAddr,proto3" json:"public_addr,omitempty"` + // ClusterName (and PublicAddr) are used to route requests issued with this + // certificate to the appropriate application proxy/cluster. + ClusterName string `protobuf:"bytes,3,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` + // Name is the app name. + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // AwsRoleArn is the AWS role to assume when accessing AWS console. + AwsRoleArn string `protobuf:"bytes,5,opt,name=aws_role_arn,json=awsRoleArn,proto3" json:"aws_role_arn,omitempty"` + // AzureIdentity is the Azure identity to assume when accessing Azure API. + AzureIdentity string `protobuf:"bytes,6,opt,name=azure_identity,json=azureIdentity,proto3" json:"azure_identity,omitempty"` + // GcpServiceAccount is the GCP service account to assume when accessing GCP + // API. + GcpServiceAccount string `protobuf:"bytes,7,opt,name=gcp_service_account,json=gcpServiceAccount,proto3" json:"gcp_service_account,omitempty"` + // Uri is the URI of the app. This is the internal endpoint where the + // application is running and isn't user-facing. + Uri string `protobuf:"bytes,8,opt,name=uri,proto3" json:"uri,omitempty"` + // TargetPort is the port to which connections should be routed to. Used only + // for multi-port TCP apps. It is appended to the hostname from the URI in the + // app spec, since the URI from RouteToApp is not used as the source of truth + // for routing. + TargetPort int32 `protobuf:"varint,9,opt,name=target_port,json=targetPort,proto3" json:"target_port,omitempty"` +} + +func (x *RouteToApp) Reset() { + *x = RouteToApp{} + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RouteToApp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouteToApp) ProtoMessage() {} + +func (x *RouteToApp) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouteToApp.ProtoReflect.Descriptor instead. +func (*RouteToApp) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_tls_identity_proto_rawDescGZIP(), []int{1} +} + +func (x *RouteToApp) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *RouteToApp) GetPublicAddr() string { + if x != nil { + return x.PublicAddr + } + return "" +} + +func (x *RouteToApp) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *RouteToApp) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RouteToApp) GetAwsRoleArn() string { + if x != nil { + return x.AwsRoleArn + } + return "" +} + +func (x *RouteToApp) GetAzureIdentity() string { + if x != nil { + return x.AzureIdentity + } + return "" +} + +func (x *RouteToApp) GetGcpServiceAccount() string { + if x != nil { + return x.GcpServiceAccount + } + return "" +} + +func (x *RouteToApp) GetUri() string { + if x != nil { + return x.Uri + } + return "" +} + +func (x *RouteToApp) GetTargetPort() int32 { + if x != nil { + return x.TargetPort + } + return 0 +} + +// RouteToDatabase contains routing information for databases. +type RouteToDatabase struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ServiceName is the name of the Teleport database proxy service to route + // requests to. + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + // Protocol is the database protocol. + // + // It is embedded in identity so clients can understand what type of database + // this is without contacting server. + Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` + // Username is an optional database username to serve as a default username to + // connect as. + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + // Database is an optional database name to serve as a default database to + // connect to. + Database string `protobuf:"bytes,4,opt,name=database,proto3" json:"database,omitempty"` + // Roles is an optional list of database roles to use for a database session. + // This list should be a subset of allowed database roles. If not specified, + // Database Service will use all allowed database roles for this database. + Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"` +} + +func (x *RouteToDatabase) Reset() { + *x = RouteToDatabase{} + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RouteToDatabase) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouteToDatabase) ProtoMessage() {} + +func (x *RouteToDatabase) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouteToDatabase.ProtoReflect.Descriptor instead. +func (*RouteToDatabase) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_tls_identity_proto_rawDescGZIP(), []int{2} +} + +func (x *RouteToDatabase) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *RouteToDatabase) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *RouteToDatabase) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *RouteToDatabase) GetDatabase() string { + if x != nil { + return x.Database + } + return "" +} + +func (x *RouteToDatabase) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +// ResourceId is a unique identifier for a teleport resource. +// Must be kept in sync with types.ResourceID. +type ResourceId struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ClusterName is the name of the cluster the resource is in. + ClusterName string `protobuf:"bytes,1,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` + // Kind is the resource kind. + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + // Name is the name of the specific resource. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + // SubResourceName is the resource belonging to resource identified by "Name" + // that the user is allowed to access to. When granting access to a + // subresource, access to other resources is limited. Currently it just + // supports resources of Kind=pod and the format is the following + // "/". + SubResourceName string `protobuf:"bytes,4,opt,name=sub_resource_name,json=subResourceName,proto3" json:"sub_resource_name,omitempty"` +} + +func (x *ResourceId) Reset() { + *x = ResourceId{} + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResourceId) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceId) ProtoMessage() {} + +func (x *ResourceId) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceId.ProtoReflect.Descriptor instead. +func (*ResourceId) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_tls_identity_proto_rawDescGZIP(), []int{3} +} + +func (x *ResourceId) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *ResourceId) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *ResourceId) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ResourceId) GetSubResourceName() string { + if x != nil { + return x.SubResourceName + } + return "" +} + +// DeviceExtensions holds device-aware extensions for the identity. +type DeviceExtensions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // DeviceId is the trusted device identifier. + DeviceId string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"` + // AssetTag is the device inventory identifier. + AssetTag string `protobuf:"bytes,2,opt,name=asset_tag,json=assetTag,proto3" json:"asset_tag,omitempty"` + // CredentialId is the identifier for the credential used by the device to + // authenticate itself. + CredentialId string `protobuf:"bytes,3,opt,name=credential_id,json=credentialId,proto3" json:"credential_id,omitempty"` +} + +func (x *DeviceExtensions) Reset() { + *x = DeviceExtensions{} + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeviceExtensions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceExtensions) ProtoMessage() {} + +func (x *DeviceExtensions) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceExtensions.ProtoReflect.Descriptor instead. +func (*DeviceExtensions) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_tls_identity_proto_rawDescGZIP(), []int{4} +} + +func (x *DeviceExtensions) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *DeviceExtensions) GetAssetTag() string { + if x != nil { + return x.AssetTag + } + return "" +} + +func (x *DeviceExtensions) GetCredentialId() string { + if x != nil { + return x.CredentialId + } + return "" +} + +var File_teleport_decision_v1alpha1_tls_identity_proto protoreflect.FileDescriptor + +var file_teleport_decision_v1alpha1_tls_identity_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x74, 0x6c, 0x73, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, 0x0c, 0x0a, 0x0b, + 0x54, 0x4c, 0x53, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, + 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, + 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x2b, 0x0a, 0x11, + 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x65, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6b, 0x75, 0x62, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x55, + 0x73, 0x65, 0x72, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, + 0x09, 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, 0x28, 0x0a, 0x10, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x65, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x0c, 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, 0x12, 0x48, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, + 0x6f, 0x5f, 0x61, 0x70, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, + 0x41, 0x70, 0x70, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x41, 0x70, 0x70, 0x12, + 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x57, 0x0a, 0x11, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x52, 0x0f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x66, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x66, 0x61, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x12, 0x56, 0x0a, 0x19, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x73, 0x18, 0x13, 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, 0x17, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, + 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x69, 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x49, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x69, 0x6e, 0x6e, 0x65, + 0x64, 0x5f, 0x69, 0x70, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x69, 0x6e, 0x6e, + 0x65, 0x64, 0x49, 0x70, 0x12, 0x22, 0x0a, 0x0d, 0x61, 0x77, 0x73, 0x5f, 0x72, 0x6f, 0x6c, 0x65, + 0x5f, 0x61, 0x72, 0x6e, 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x77, 0x73, + 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x72, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x7a, 0x75, 0x72, + 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x17, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0f, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x67, 0x63, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x12, 0x67, 0x63, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x19, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x29, + 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x69, 0x73, 0x73, + 0x75, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x69, 0x73, 0x73, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x6e, + 0x65, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, + 0x6e, 0x65, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x73, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, + 0x52, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x64, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x38, 0x0a, 0x18, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x21, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x49, 0x64, 0x12, 0x59, 0x0a, 0x11, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x23, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x22, 0xaf, 0x02, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, + 0x41, 0x70, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x61, 0x77, + 0x73, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x61, 0x77, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x72, 0x6e, 0x12, 0x25, 0x0a, 0x0e, + 0x61, 0x7a, 0x75, 0x72, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x67, 0x63, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x67, 0x63, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x9e, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x54, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, + 0x62, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x71, 0x0a, + 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x54, 0x61, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, + 0x42, 0x5a, 0x5a, 0x58, 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, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_decision_v1alpha1_tls_identity_proto_rawDescOnce sync.Once + file_teleport_decision_v1alpha1_tls_identity_proto_rawDescData = file_teleport_decision_v1alpha1_tls_identity_proto_rawDesc +) + +func file_teleport_decision_v1alpha1_tls_identity_proto_rawDescGZIP() []byte { + file_teleport_decision_v1alpha1_tls_identity_proto_rawDescOnce.Do(func() { + file_teleport_decision_v1alpha1_tls_identity_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_decision_v1alpha1_tls_identity_proto_rawDescData) + }) + return file_teleport_decision_v1alpha1_tls_identity_proto_rawDescData +} + +var file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_teleport_decision_v1alpha1_tls_identity_proto_goTypes = []any{ + (*TLSIdentity)(nil), // 0: teleport.decision.v1alpha1.TLSIdentity + (*RouteToApp)(nil), // 1: teleport.decision.v1alpha1.RouteToApp + (*RouteToDatabase)(nil), // 2: teleport.decision.v1alpha1.RouteToDatabase + (*ResourceId)(nil), // 3: teleport.decision.v1alpha1.ResourceId + (*DeviceExtensions)(nil), // 4: teleport.decision.v1alpha1.DeviceExtensions + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + (*v1.Trait)(nil), // 6: teleport.trait.v1.Trait +} +var file_teleport_decision_v1alpha1_tls_identity_proto_depIdxs = []int32{ + 5, // 0: teleport.decision.v1alpha1.TLSIdentity.expires:type_name -> google.protobuf.Timestamp + 6, // 1: teleport.decision.v1alpha1.TLSIdentity.traits:type_name -> teleport.trait.v1.Trait + 1, // 2: teleport.decision.v1alpha1.TLSIdentity.route_to_app:type_name -> teleport.decision.v1alpha1.RouteToApp + 2, // 3: teleport.decision.v1alpha1.TLSIdentity.route_to_database:type_name -> teleport.decision.v1alpha1.RouteToDatabase + 5, // 4: teleport.decision.v1alpha1.TLSIdentity.previous_identity_expires:type_name -> google.protobuf.Timestamp + 3, // 5: teleport.decision.v1alpha1.TLSIdentity.allowed_resource_ids:type_name -> teleport.decision.v1alpha1.ResourceId + 4, // 6: teleport.decision.v1alpha1.TLSIdentity.device_extensions:type_name -> teleport.decision.v1alpha1.DeviceExtensions + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_teleport_decision_v1alpha1_tls_identity_proto_init() } +func file_teleport_decision_v1alpha1_tls_identity_proto_init() { + if File_teleport_decision_v1alpha1_tls_identity_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_decision_v1alpha1_tls_identity_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_decision_v1alpha1_tls_identity_proto_goTypes, + DependencyIndexes: file_teleport_decision_v1alpha1_tls_identity_proto_depIdxs, + MessageInfos: file_teleport_decision_v1alpha1_tls_identity_proto_msgTypes, + }.Build() + File_teleport_decision_v1alpha1_tls_identity_proto = out.File + file_teleport_decision_v1alpha1_tls_identity_proto_rawDesc = nil + file_teleport_decision_v1alpha1_tls_identity_proto_goTypes = nil + file_teleport_decision_v1alpha1_tls_identity_proto_depIdxs = nil +} diff --git a/api/proto/teleport/decision/v1alpha1/database_access.proto b/api/proto/teleport/decision/v1alpha1/database_access.proto new file mode 100644 index 0000000000000..cd852a45d0b6d --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/database_access.proto @@ -0,0 +1,53 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +import "teleport/decision/v1alpha1/denial_metadata.proto"; +import "teleport/decision/v1alpha1/permit_metadata.proto"; +import "teleport/decision/v1alpha1/request_metadata.proto"; +import "teleport/decision/v1alpha1/resource.proto"; +import "teleport/decision/v1alpha1/tls_identity.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// EvaluateDatabaseAccessRequest describes a request to evaluate whether or not +// a given database access attempt should be permitted. +message EvaluateDatabaseAccessRequest { + RequestMetadata metadata = 1; + TLSIdentity tls_identity = 2; + Resource database = 3; +} + +// EvaluateDatabaseAccessResponse describes the result of a database access +// evaluation. +message EvaluateDatabaseAccessResponse { + oneof result { + DatabaseAccessPermit permit = 1; + DatabaseAccessDenial denial = 2; + } +} + +// DatabaseAccessPermit describes the parameters/constraints of a permissible +// database access attempt. +message DatabaseAccessPermit { + PermitMetadata metadata = 1; +} + +// DatabaseAccessDenial describes a database access denial. +message DatabaseAccessDenial { + DenialMetadata metadata = 1; +} diff --git a/api/proto/teleport/decision/v1alpha1/decision_service.proto b/api/proto/teleport/decision/v1alpha1/decision_service.proto new file mode 100644 index 0000000000000..b5f98c7d5e33e --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/decision_service.proto @@ -0,0 +1,40 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +import "teleport/decision/v1alpha1/database_access.proto"; +import "teleport/decision/v1alpha1/ssh_access.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// DecisionService performs authorization decisions for Teleport. +// +// DecisionService acts the PDP (Policy Decision Point) for Teleport services, +// whereas the services themselves act as the PEP (Policy Enforcement Point). +// In other words, it calculates the outcome of an authorization request but +// does not enforce it - each Teleport service must do so. +// +// Evaluation responses carry all the data necessary for the enforcement of a +// decision. A successful evaluation carries a Permit, whereas a failed +// evaluation carries a Denial. +service DecisionService { + // EvaluateSSHAccess evaluates an SSH access attempt. + rpc EvaluateSSHAccess(EvaluateSSHAccessRequest) returns (EvaluateSSHAccessResponse); + + // EvaluateDatabaseAccess evaluate a database access attempt. + rpc EvaluateDatabaseAccess(EvaluateDatabaseAccessRequest) returns (EvaluateDatabaseAccessResponse); +} diff --git a/api/proto/teleport/decision/v1alpha1/denial_metadata.proto b/api/proto/teleport/decision/v1alpha1/denial_metadata.proto new file mode 100644 index 0000000000000..6c30f1fba49b5 --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/denial_metadata.proto @@ -0,0 +1,38 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +import "teleport/decision/v1alpha1/enforcement_feature.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// Metadata for access denials. +message DenialMetadata { + // FeatureAssertions is a list of EnforcementFeature that the PEP (Policy + // Enforcement Point) *must* implement in order to correctly enforce the + // decision. Note that denials rarely need feature assertions since they + // typically "fail safe" anyway. + repeated EnforcementFeature feature_assertions = 1; + + // PdpVersion is the version of the PDP (Policy Decision Point) that evaluated + // the decision request. + string pdp_version = 2; + + // UserMessage is a sanitized message safe for return to the subject identity + // of the decision request. + string user_message = 3; +} diff --git a/api/proto/teleport/decision/v1alpha1/enforcement_feature.proto b/api/proto/teleport/decision/v1alpha1/enforcement_feature.proto new file mode 100644 index 0000000000000..599a516a1ab92 --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/enforcement_feature.proto @@ -0,0 +1,26 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// EnforcementFeature represents PEP (Policy Enforcement Point) features. +enum EnforcementFeature { + // ENFORCEMENT_FEATURE_UNSPECIFIED is the default/unspecified value for + // EnforcementFeature. Asserting this feature has no effect. + ENFORCEMENT_FEATURE_UNSPECIFIED = 0; +} diff --git a/api/proto/teleport/decision/v1alpha1/permit_metadata.proto b/api/proto/teleport/decision/v1alpha1/permit_metadata.proto new file mode 100644 index 0000000000000..ba7f607a4c62d --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/permit_metadata.proto @@ -0,0 +1,34 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +import "teleport/decision/v1alpha1/enforcement_feature.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// Metadata for access permits. +message PermitMetadata { + // FeatureAssertions is a list of EnforcementFeature that the PEP (Policy + // Enforcement Point) *must* implement in order to correctly enforce the + // decision. Note that where possible new features should be structured to + // "fail safe" rather than relying on feature assertions. + repeated EnforcementFeature feature_assertions = 1; + + // PdpVersion is the version of the PDP (Policy Decision Point) that evaluated + // the decision request. + string pdp_version = 2; +} diff --git a/api/proto/teleport/decision/v1alpha1/request_metadata.proto b/api/proto/teleport/decision/v1alpha1/request_metadata.proto new file mode 100644 index 0000000000000..2059bd59d3407 --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/request_metadata.proto @@ -0,0 +1,44 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// Metadata for evaluation requests. +message RequestMetadata { + // FeatureAssertions is a list of DecisionFeature that the PDP (Policy + // Decision Point) *must* implement in order to correctly evaluate the + // decision request. Note that changes that require new features in the PDP in + // order for it to understand a decision request are rare and should be + // avoided if possible. + repeated DecisionFeature feature_assertions = 1; + + // PepVersionHint is the *likely* version of the PEP that will enforce the + // decision. Not all decision requests can guarantee that the expected PEP + // (Policy Enforcement Point) version will actually be the version that ends + // up enforcing the decision. Hard compatibility requirements must be enforced + // via feature assertions so that PEPs can correctly reject decisions that + // they cannot enforce. + string pep_version_hint = 2; +} + +// DecisionFeature represents supported PDP (Policy Decision Point) features. +enum DecisionFeature { + // DECISION_FEATURE_UNSPECIFIED is the default/unspecified value for + // DecisionFeature. Asserting this feature has no effect. + DECISION_FEATURE_UNSPECIFIED = 0; +} diff --git a/api/proto/teleport/decision/v1alpha1/resource.proto b/api/proto/teleport/decision/v1alpha1/resource.proto new file mode 100644 index 0000000000000..25b1e970ae114 --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/resource.proto @@ -0,0 +1,37 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// Resource is the conventional reference type used to refer to the "object" of +// an action that is being considered for an authorization decision. For +// example, a call to EvaluateSSHAccess would use the Resource type to reference +// the ssh node being accessed. +message Resource { + // Kind is the type of the resource. Required for requests that support + // multiple types, otherwise safe to omit. + string kind = 1; + + // SubKind is the subtype of the resource. Usually not required as most + // resources don't have subkinds, or their subkinds do not have an effect on + // authorization decisions. + string sub_kind = 2; + + // Name is the unique name of the resource. + string name = 3; +} diff --git a/api/proto/teleport/decision/v1alpha1/ssh_access.proto b/api/proto/teleport/decision/v1alpha1/ssh_access.proto new file mode 100644 index 0000000000000..df2685c529db5 --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/ssh_access.proto @@ -0,0 +1,75 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +import "google/protobuf/duration.proto"; +import "teleport/decision/v1alpha1/denial_metadata.proto"; +import "teleport/decision/v1alpha1/permit_metadata.proto"; +import "teleport/decision/v1alpha1/request_metadata.proto"; +import "teleport/decision/v1alpha1/resource.proto"; +import "teleport/decision/v1alpha1/ssh_identity.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// EvaluateSSHAccessRequest describes a request to evaluate whether or not a +// given ssh access attempt should be permitted. +message EvaluateSSHAccessRequest { + // Metadata holds common authorization decision request fields. + RequestMetadata metadata = 1; + + // User describes the teleport user requesting access. + SSHIdentity ssh_identity = 2; + + // Node references the target node the user is attempting to access. + Resource node = 3; +} + +// EvaluateSSHAccessResponse describes the result of an SSH access evaluation. +message EvaluateSSHAccessResponse { + oneof decision { + SSHAccessPermit permit = 1; + SSHAccessDenial denial = 2; + } +} + +// SSHAccessPermit describes the parameters/constraints of a permissible SSH +// access attempt. +message SSHAccessPermit { + PermitMetadata metadata = 1; + repeated string logins = 2; + bool forward_agent = 3; + google.protobuf.Duration max_session_ttl = 4; + bool port_forwarding = 5; + int64 client_idle_timeout = 6; + bool disconnect_expired_cert = 7; + repeated string bpf = 8; + bool x11_forwarding = 9; + int64 max_connections = 10; + int64 max_sessions = 11; + string lock = 12; + bool create_host_user = 13; + bool ssh_file_copy = 14; + string create_host_user_mode = 15; + string create_host_user_shell = 16; + repeated string host_groups = 17; + repeated string host_sudoers = 18; +} + +// SSHAccessDenial describes an SSH access denial. +message SSHAccessDenial { + DenialMetadata metadata = 1; +} diff --git a/api/proto/teleport/decision/v1alpha1/ssh_identity.proto b/api/proto/teleport/decision/v1alpha1/ssh_identity.proto new file mode 100644 index 0000000000000..01f4ea2af2d58 --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/ssh_identity.proto @@ -0,0 +1,24 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// SSHIdentity is the identity used for SSH connections. +message SSHIdentity { + // TBD +} diff --git a/api/proto/teleport/decision/v1alpha1/tls_identity.proto b/api/proto/teleport/decision/v1alpha1/tls_identity.proto new file mode 100644 index 0000000000000..4e36f3c8d380a --- /dev/null +++ b/api/proto/teleport/decision/v1alpha1/tls_identity.proto @@ -0,0 +1,249 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.decision.v1alpha1; + +import "google/protobuf/timestamp.proto"; +import "teleport/trait/v1/trait.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; + +// TLSIdentity is the identity used for TLS connections. +// Must be kept in sync with tlsca.Identity. +message TLSIdentity { + // Username is the name of the user (for end-users/bots) or the Host ID (for + // Teleport processes). + string username = 1; + + // Impersonator is a username of a user impersonating this user. + string impersonator = 2; + + // Groups is a list of groups (Teleport roles) encoded in the identity. + repeated string groups = 3; + + // SystemRoles is a list of system roles (e.g. auth, proxy, node, etc) used in + // "multi-role" certificates. Single-role certificates encode the system role + // in `Groups` for back-compat reasons. + repeated string system_roles = 4; + + // Usage is a list of usage restrictions encoded in the identity. + repeated string usage = 5; + + // Principals is a list of Unix logins allowed. + repeated string principals = 6; + + // KubernetesGroups is a list of Kubernetes groups allowed. + repeated string kubernetes_groups = 7; + + // KubernetesUsers is a list of Kubernetes users allowed. + repeated string kubernetes_users = 8; + + // Expires specifies whenever the session will expire. + google.protobuf.Timestamp expires = 9; + + // RouteToCluster specifies the target cluster. + string route_to_cluster = 10; + + // KubernetesCluster specifies the target kubernetes cluster for TLS + // identities. This can be empty on older Teleport clients. + string kubernetes_cluster = 11; + + // Traits hold claim data used to populate a role at runtime. + repeated teleport.trait.v1.Trait traits = 12; + + // RouteToApp holds routing information for applications. Routing metadata + // allows Teleport web proxy to route HTTP requests to the appropriate cluster + // and Teleport application proxy within the cluster. + RouteToApp route_to_app = 13; + + // TeleportCluster is the name of the teleport cluster that this identity + // originated from. For TLS certs this may not be the same as cert issuer, in + // case of multi-hop requests that originate from a remote cluster. + string teleport_cluster = 14; + + // RouteToDatabase contains routing information for databases. + RouteToDatabase route_to_database = 15; + + // DatabaseNames is a list of allowed database names. + repeated string database_names = 16; + + // DatabaseUsers is a list of allowed database users. + repeated string database_users = 17; + + // MfaVerified is the UUID of an MFA device when this Identity was + // confirmed immediately after an MFA check. + string mfa_verified = 18; + + // PreviousIdentityExpires is the expiry time of the identity/cert that this + // identity/cert was derived from. It is used to determine a session's hard + // deadline in cases where both require_session_mfa and + // disconnect_expired_cert are enabled. + // See https://github.com/gravitational/teleport/issues/18544. + google.protobuf.Timestamp previous_identity_expires = 19; + + // LoginIp is an observed IP of the client that this Identity represents. + string login_ip = 20; + + // PinnedIp is an IP the certificate is pinned to. + string pinned_ip = 21; + + // AwsRoleArns is a list of allowed AWS role ARNs user can assume. + repeated string aws_role_arns = 22; + + // AzureIdentities is a list of allowed Azure identities user can assume. + repeated string azure_identities = 23; + + // GcpServiceAccounts is a list of allowed GCP service accounts that the user + // can assume. + repeated string gcp_service_accounts = 24; + + // ActiveRequests is a list of UUIDs of active requests for this Identity. + repeated string active_requests = 25; + + // DisallowReissue is a flag that, if set, instructs the auth server to deny + // any attempts to reissue new certificates while authenticated with this + // certificate. + bool disallow_reissue = 26; + + // Renewable indicates that this identity is allowed to renew it's own + // credentials. This is only enabled for certificate renewal bots. + bool renewable = 27; + + // Generation counts the number of times this certificate has been renewed. + uint64 generation = 28; + + // BotName indicates the name of the Machine ID bot this identity was issued + // to, if any. + string bot_name = 29; + + // BotInstanceId is a unique identifier for Machine ID bots that is persisted + // through renewals. + string bot_instance_id = 30; + + // AllowedResourceIds lists the resources the identity should be allowed to + // access. + repeated ResourceId allowed_resource_ids = 31; + + // PrivateKeyPolicy is the private key policy supported by this identity. + string private_key_policy = 32; + + // ConnectionDiagnosticId is used to add connection diagnostic messages when + // Testing a Connection. + string connection_diagnostic_id = 33; + + // DeviceExtensions holds device-aware extensions for the identity. + DeviceExtensions device_extensions = 34; + + // UserType indicates if the User was created by an SSO Provider or locally. + string user_type = 35; +} + +// RouteToApp holds routing information for applications. +message RouteToApp { + // SessionId is an ID used to identify application sessions created by this + // certificate. + string session_id = 1; + + // PublicAddr (and ClusterName) are used to route requests issued with this + // certificate to the appropriate application proxy/cluster. + string public_addr = 2; + + // ClusterName (and PublicAddr) are used to route requests issued with this + // certificate to the appropriate application proxy/cluster. + string cluster_name = 3; + + // Name is the app name. + string name = 4; + + // AwsRoleArn is the AWS role to assume when accessing AWS console. + string aws_role_arn = 5; + + // AzureIdentity is the Azure identity to assume when accessing Azure API. + string azure_identity = 6; + + // GcpServiceAccount is the GCP service account to assume when accessing GCP + // API. + string gcp_service_account = 7; + + // Uri is the URI of the app. This is the internal endpoint where the + // application is running and isn't user-facing. + string uri = 8; + + // TargetPort is the port to which connections should be routed to. Used only + // for multi-port TCP apps. It is appended to the hostname from the URI in the + // app spec, since the URI from RouteToApp is not used as the source of truth + // for routing. + int32 target_port = 9; +} + +// RouteToDatabase contains routing information for databases. +message RouteToDatabase { + // ServiceName is the name of the Teleport database proxy service to route + // requests to. + string service_name = 1; + + // Protocol is the database protocol. + // + // It is embedded in identity so clients can understand what type of database + // this is without contacting server. + string protocol = 2; + + // Username is an optional database username to serve as a default username to + // connect as. + string username = 3; + + // Database is an optional database name to serve as a default database to + // connect to. + string database = 4; + + // Roles is an optional list of database roles to use for a database session. + // This list should be a subset of allowed database roles. If not specified, + // Database Service will use all allowed database roles for this database. + repeated string roles = 5; +} + +// ResourceId is a unique identifier for a teleport resource. +// Must be kept in sync with types.ResourceID. +message ResourceId { + // ClusterName is the name of the cluster the resource is in. + string cluster_name = 1; + + // Kind is the resource kind. + string kind = 2; + + // Name is the name of the specific resource. + string name = 3; + + // SubResourceName is the resource belonging to resource identified by "Name" + // that the user is allowed to access to. When granting access to a + // subresource, access to other resources is limited. Currently it just + // supports resources of Kind=pod and the format is the following + // "/". + string sub_resource_name = 4; +} + +// DeviceExtensions holds device-aware extensions for the identity. +message DeviceExtensions { + // DeviceId is the trusted device identifier. + string device_id = 1; + + // AssetTag is the device inventory identifier. + string asset_tag = 2; + + // CredentialId is the identifier for the credential used by the device to + // authenticate itself. + string credential_id = 3; +} diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 2c02db80ce69a..6f9f3a06eb22d 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -2806,6 +2806,7 @@ message RequestKubernetesResource { } // ResourceID is a unique identifier for a teleport resource. +// Must be kept in sync with teleport.decision.v1alpha1.ResourceId. message ResourceID { // ClusterName is the name of the cluster the resource is in. string ClusterName = 1 [(gogoproto.jsontag) = "cluster"]; diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 1922be6a9b089..39fb26f9e6173 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -7825,6 +7825,7 @@ func (m *RequestKubernetesResource) XXX_DiscardUnknown() { var xxx_messageInfo_RequestKubernetesResource proto.InternalMessageInfo // ResourceID is a unique identifier for a teleport resource. +// Must be kept in sync with teleport.decision.v1alpha1.ResourceId. type ResourceID struct { // ClusterName is the name of the cluster the resource is in. ClusterName string `protobuf:"bytes,1,opt,name=ClusterName,proto3" json:"cluster"` diff --git a/buf.yaml b/buf.yaml index bd4efff817af3..8f01bbe2dea21 100644 --- a/buf.yaml +++ b/buf.yaml @@ -81,6 +81,9 @@ breaking: - WIRE_JSON except: - FIELD_SAME_DEFAULT + ignore: + # TODO(codingllama): Remove ignore once the PDP API is stable. + - api/proto/teleport/decision/v1alpha1 ignore_only: RESERVED_ENUM_NO_DELETE: - api/proto/teleport/legacy/types/types.proto diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index ca920b5b2caa4..4fcc1ca927d2a 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -56,6 +56,7 @@ import ( crownjewelv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" dbobjectimportrulev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" discoveryconfigv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1" dynamicwindowsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dynamicwindows/v1" gitserverv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/gitserver/v1" @@ -109,6 +110,7 @@ import ( "github.com/gravitational/teleport/lib/auth/vnetconfig/vnetconfigv1" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/decision/decisionv1" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/httplib" @@ -5497,6 +5499,14 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { loginrulev1pb.RegisterLoginRuleServiceServer(server, loginrulev1.NotImplementedService{}) } + decisionService, err := decisionv1.NewService(decisionv1.ServiceConfig{ + Authorizer: cfg.Authorizer, + }) + if err != nil { + return nil, trace.Wrap(err) + } + decisionpb.RegisterDecisionServiceServer(server, decisionService) + return authServer, nil } diff --git a/lib/decision/decisionv1/decision_service.go b/lib/decision/decisionv1/decision_service.go new file mode 100644 index 0000000000000..d45fbf3caeefb --- /dev/null +++ b/lib/decision/decisionv1/decision_service.go @@ -0,0 +1,48 @@ +// 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 decisionv1 + +import ( + "github.com/gravitational/trace" + + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" + "github.com/gravitational/teleport/lib/authz" +) + +// ServiceConfig holds creation parameters for [Service]. +type ServiceConfig struct { + // Authorizer used by the service. + Authorizer authz.Authorizer +} + +// Service implements the teleport.decision.v1alpha1.DecisionService gRPC API. +type Service struct { + decisionpb.UnimplementedDecisionServiceServer + + authorizer authz.Authorizer +} + +// NewService creates a new [Service] instance. +func NewService(cfg ServiceConfig) (*Service, error) { + if cfg.Authorizer == nil { + return nil, trace.BadParameter("param Authorizer required") + } + + return &Service{ + authorizer: cfg.Authorizer, + }, nil +} diff --git a/lib/decision/decisionv1/decision_service_test.go b/lib/decision/decisionv1/decision_service_test.go new file mode 100644 index 0000000000000..72f92fcfbe8b7 --- /dev/null +++ b/lib/decision/decisionv1/decision_service_test.go @@ -0,0 +1,45 @@ +// 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 decisionv1_test + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/assert" + + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" +) + +func TestDecisionService_notImplemented(t *testing.T) { + t.Parallel() + + env := NewTestenv(t) + decisionClient := env.DecisionClient + ctx := context.Background() + + t.Run("EvaluateSSHAccess", func(t *testing.T) { + _, err := decisionClient.EvaluateSSHAccess(ctx, &decisionpb.EvaluateSSHAccessRequest{}) + assert.ErrorAs(t, err, new(*trace.NotImplementedError), "EvaluateSSHAccess error mismatch") + }) + + t.Run("EvaluateDatabaseAccess", func(t *testing.T) { + _, err := decisionClient.EvaluateDatabaseAccess(ctx, &decisionpb.EvaluateDatabaseAccessRequest{}) + assert.ErrorAs(t, err, new(*trace.NotImplementedError), "EvaluateDatabaseAccess error mismatch") + }) +} diff --git a/lib/decision/decisionv1/env_test.go b/lib/decision/decisionv1/env_test.go new file mode 100644 index 0000000000000..6211cdb0d94ca --- /dev/null +++ b/lib/decision/decisionv1/env_test.go @@ -0,0 +1,74 @@ +// 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 decisionv1_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/constants" + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/auth/authclient" +) + +// Testenv is a test environment for decisionv1.Service. +type Testenv struct { + TestServer *auth.TestServer + + // AuthAdminClient is an admin Auth client. + AuthAdminClient *authclient.Client + + // DecisionClient is an admin decision client. + // Created from AuthAdminClient. + DecisionClient decisionpb.DecisionServiceClient +} + +func NewTestenv(t *testing.T) *Testenv { + t.Helper() + + testServer, err := auth.NewTestServer(auth.TestServerConfig{ + Auth: auth.TestAuthServerConfig{ + Dir: t.TempDir(), + AuthPreferenceSpec: &types.AuthPreferenceSpecV2{ + SecondFactor: constants.SecondFactorOTP, // Required. + }, + }, + }) + require.NoError(t, err, "NewTestServer failed") + t.Cleanup(func() { + assert.NoError(t, + testServer.Shutdown(context.Background()), + "testServer.Shutdown failed") + }) + + adminClient, err := testServer.NewClient(auth.TestAdmin()) + require.NoError(t, err, "NewClient failed") + t.Cleanup(func() { + assert.NoError(t, adminClient.Close(), "adminClient.Close() failed") + }) + + return &Testenv{ + TestServer: testServer, + AuthAdminClient: adminClient, + DecisionClient: adminClient.DecisionClient(), + } +} diff --git a/lib/decision/tls_identity.go b/lib/decision/tls_identity.go new file mode 100644 index 0000000000000..d0cf1c7905eab --- /dev/null +++ b/lib/decision/tls_identity.go @@ -0,0 +1,278 @@ +// 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 decision + +import ( + "time" + + "google.golang.org/protobuf/types/known/timestamppb" + + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" + traitpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/trait/v1" + "github.com/gravitational/teleport/api/types" + apitrait "github.com/gravitational/teleport/api/types/trait" + apitraitconvert "github.com/gravitational/teleport/api/types/trait/convert/v1" + "github.com/gravitational/teleport/api/types/wrappers" + "github.com/gravitational/teleport/api/utils/keys" + "github.com/gravitational/teleport/lib/tlsca" +) + +// TLSIdentityToTLSCA transforms a [decisionpb.TLSIdentity] into its +// equivalent [tlsca.Identity]. +// Note that certain types, like slices, are not deep-copied. +func TLSIdentityToTLSCA(id *decisionpb.TLSIdentity) *tlsca.Identity { + if id == nil { + return nil + } + + return &tlsca.Identity{ + Username: id.Username, + Impersonator: id.Impersonator, + Groups: id.Groups, + SystemRoles: id.SystemRoles, + Usage: id.Usage, + Principals: id.Principals, + KubernetesGroups: id.KubernetesGroups, + KubernetesUsers: id.KubernetesUsers, + Expires: timestampToGoTime(id.Expires), + RouteToCluster: id.RouteToCluster, + KubernetesCluster: id.KubernetesCluster, + Traits: traitToWrappers(id.Traits), + RouteToApp: routeToAppFromProto(id.RouteToApp), + TeleportCluster: id.TeleportCluster, + RouteToDatabase: routeToDatabaseFromProto(id.RouteToDatabase), + DatabaseNames: id.DatabaseNames, + DatabaseUsers: id.DatabaseUsers, + MFAVerified: id.MfaVerified, + PreviousIdentityExpires: timestampToGoTime(id.PreviousIdentityExpires), + LoginIP: id.LoginIp, + PinnedIP: id.PinnedIp, + AWSRoleARNs: id.AwsRoleArns, + AzureIdentities: id.AzureIdentities, + GCPServiceAccounts: id.GcpServiceAccounts, + ActiveRequests: id.ActiveRequests, + DisallowReissue: id.DisallowReissue, + Renewable: id.Renewable, + Generation: id.Generation, + BotName: id.BotName, + BotInstanceID: id.BotInstanceId, + AllowedResourceIDs: resourceIDsToTypes(id.AllowedResourceIds), + PrivateKeyPolicy: keys.PrivateKeyPolicy(id.PrivateKeyPolicy), + ConnectionDiagnosticID: id.ConnectionDiagnosticId, + DeviceExtensions: deviceExtensionsFromProto(id.DeviceExtensions), + UserType: types.UserType(id.UserType), + } +} + +// TLSIdentityFromTLSCA transforms a [tlsca.Identity] into its equivalent +// [decisionpb.TLSIdentity]. +// Note that certain types, like slices, are not deep-copied. +func TLSIdentityFromTLSCA(id *tlsca.Identity) *decisionpb.TLSIdentity { + if id == nil { + return nil + } + + return &decisionpb.TLSIdentity{ + Username: id.Username, + Impersonator: id.Impersonator, + Groups: id.Groups, + SystemRoles: id.SystemRoles, + Usage: id.Usage, + Principals: id.Principals, + KubernetesGroups: id.KubernetesGroups, + KubernetesUsers: id.KubernetesUsers, + Expires: timestampFromGoTime(id.Expires), + RouteToCluster: id.RouteToCluster, + KubernetesCluster: id.KubernetesCluster, + Traits: traitFromWrappers(id.Traits), + RouteToApp: routeToAppToProto(&id.RouteToApp), + TeleportCluster: id.TeleportCluster, + RouteToDatabase: routeToDatabaseToProto(&id.RouteToDatabase), + DatabaseNames: id.DatabaseNames, + DatabaseUsers: id.DatabaseUsers, + MfaVerified: id.MFAVerified, + PreviousIdentityExpires: timestampFromGoTime(id.PreviousIdentityExpires), + LoginIp: id.LoginIP, + PinnedIp: id.PinnedIP, + AwsRoleArns: id.AWSRoleARNs, + AzureIdentities: id.AzureIdentities, + GcpServiceAccounts: id.GCPServiceAccounts, + ActiveRequests: id.ActiveRequests, + DisallowReissue: id.DisallowReissue, + Renewable: id.Renewable, + Generation: id.Generation, + BotName: id.BotName, + BotInstanceId: id.BotInstanceID, + AllowedResourceIds: resourceIDsFromTypes(id.AllowedResourceIDs), + PrivateKeyPolicy: string(id.PrivateKeyPolicy), + ConnectionDiagnosticId: id.ConnectionDiagnosticID, + DeviceExtensions: deviceExtensionsToProto(&id.DeviceExtensions), + UserType: string(id.UserType), + } +} + +func timestampToGoTime(t *timestamppb.Timestamp) time.Time { + // nil or "zero" Timestamps are mapped to Go's zero time (0-0-0 0:0.0) instead + // of unix epoch. The latter avoids problems with tooling (eg, Terraform) that + // sets structs to their defaults instead of using nil. + if t == nil || (t.Seconds == 0 && t.Nanos == 0) { + return time.Time{} + } + return t.AsTime() +} + +func timestampFromGoTime(t time.Time) *timestamppb.Timestamp { + if t.IsZero() { + return nil + } + return timestamppb.New(t) +} + +func traitToWrappers(traits []*traitpb.Trait) wrappers.Traits { + apiTraits := apitraitconvert.FromProto(traits) + return wrappers.Traits(apiTraits) +} + +func traitFromWrappers(traits wrappers.Traits) []*traitpb.Trait { + if len(traits) == 0 { + return nil + } + apiTraits := apitrait.Traits(traits) + return apitraitconvert.ToProto(apiTraits) +} + +func routeToAppFromProto(routeToApp *decisionpb.RouteToApp) tlsca.RouteToApp { + if routeToApp == nil { + return tlsca.RouteToApp{} + } + + return tlsca.RouteToApp{ + SessionID: routeToApp.SessionId, + PublicAddr: routeToApp.PublicAddr, + ClusterName: routeToApp.ClusterName, + Name: routeToApp.Name, + AWSRoleARN: routeToApp.AwsRoleArn, + AzureIdentity: routeToApp.AzureIdentity, + GCPServiceAccount: routeToApp.GcpServiceAccount, + URI: routeToApp.Uri, + TargetPort: int(routeToApp.TargetPort), + } +} + +func routeToAppToProto(routeToApp *tlsca.RouteToApp) *decisionpb.RouteToApp { + if routeToApp == nil { + return nil + } + + return &decisionpb.RouteToApp{ + SessionId: routeToApp.SessionID, + PublicAddr: routeToApp.PublicAddr, + ClusterName: routeToApp.ClusterName, + Name: routeToApp.Name, + AwsRoleArn: routeToApp.AWSRoleARN, + AzureIdentity: routeToApp.AzureIdentity, + GcpServiceAccount: routeToApp.GCPServiceAccount, + Uri: routeToApp.URI, + TargetPort: int32(routeToApp.TargetPort), + } +} + +func routeToDatabaseFromProto(routeToDatabase *decisionpb.RouteToDatabase) tlsca.RouteToDatabase { + if routeToDatabase == nil { + return tlsca.RouteToDatabase{} + } + + return tlsca.RouteToDatabase{ + ServiceName: routeToDatabase.ServiceName, + Protocol: routeToDatabase.Protocol, + Username: routeToDatabase.Username, + Database: routeToDatabase.Database, + Roles: routeToDatabase.Roles, + } +} + +func routeToDatabaseToProto(routeToDatabase *tlsca.RouteToDatabase) *decisionpb.RouteToDatabase { + if routeToDatabase == nil { + return nil + } + + return &decisionpb.RouteToDatabase{ + ServiceName: routeToDatabase.ServiceName, + Protocol: routeToDatabase.Protocol, + Username: routeToDatabase.Username, + Database: routeToDatabase.Database, + Roles: routeToDatabase.Roles, + } +} + +func resourceIDsToTypes(resourceIDs []*decisionpb.ResourceId) []types.ResourceID { + if len(resourceIDs) == 0 { + return nil + } + + ret := make([]types.ResourceID, len(resourceIDs)) + for i, r := range resourceIDs { + ret[i] = types.ResourceID{ + ClusterName: r.ClusterName, + Kind: r.Kind, + Name: r.Name, + SubResourceName: r.SubResourceName, + } + } + return ret +} + +func resourceIDsFromTypes(resourceIDs []types.ResourceID) []*decisionpb.ResourceId { + if len(resourceIDs) == 0 { + return nil + } + + ret := make([]*decisionpb.ResourceId, len(resourceIDs)) + for i, r := range resourceIDs { + ret[i] = &decisionpb.ResourceId{ + ClusterName: r.ClusterName, + Kind: r.Kind, + Name: r.Name, + SubResourceName: r.SubResourceName, + } + } + return ret +} + +func deviceExtensionsFromProto(exts *decisionpb.DeviceExtensions) tlsca.DeviceExtensions { + if exts == nil { + return tlsca.DeviceExtensions{} + } + + return tlsca.DeviceExtensions{ + DeviceID: exts.DeviceId, + AssetTag: exts.AssetTag, + CredentialID: exts.CredentialId, + } +} + +func deviceExtensionsToProto(exts *tlsca.DeviceExtensions) *decisionpb.DeviceExtensions { + if exts == nil { + return nil + } + + return &decisionpb.DeviceExtensions{ + DeviceId: exts.DeviceID, + AssetTag: exts.AssetTag, + CredentialId: exts.CredentialID, + } +} diff --git a/lib/decision/tls_identity_test.go b/lib/decision/tls_identity_test.go new file mode 100644 index 0000000000000..8ac417c3b47da --- /dev/null +++ b/lib/decision/tls_identity_test.go @@ -0,0 +1,171 @@ +// 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 decision_test + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" + + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" + traitpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/trait/v1" + "github.com/gravitational/teleport/lib/decision" + "github.com/gravitational/teleport/lib/tlsca" +) + +func TestTLSIdentity_roundtrip(t *testing.T) { + t.Parallel() + + minimalTLSIdentity := &decisionpb.TLSIdentity{ + // tlsca.Identity has no pointer fields, so these are always non-nil after + // copying. + RouteToApp: &decisionpb.RouteToApp{}, + RouteToDatabase: &decisionpb.RouteToDatabase{}, + DeviceExtensions: &decisionpb.DeviceExtensions{}, + } + + fullIdentity := &decisionpb.TLSIdentity{ + Username: "user", + Impersonator: "impersonator", + Groups: []string{"role1", "role2"}, + SystemRoles: []string{"system1", "system2"}, + Usage: []string{"usage1", "usage2"}, + Principals: []string{"login1", "login2"}, + KubernetesGroups: []string{"kgroup1", "kgroup2"}, + KubernetesUsers: []string{"kuser1", "kuser2"}, + Expires: timestamppb.Now(), + RouteToCluster: "route-to-cluster", + KubernetesCluster: "k8s-cluster", + Traits: []*traitpb.Trait{ + // Note: sorted by key on conversion. + {Key: "", Values: []string{"missingkey"}}, + {Key: "missingvalues", Values: nil}, + {Key: "trait1", Values: []string{"val1"}}, + {Key: "trait2", Values: []string{"val1", "val2"}}, + }, + RouteToApp: &decisionpb.RouteToApp{ + SessionId: "session-id", + PublicAddr: "public-addr", + ClusterName: "cluster-name", + Name: "name", + AwsRoleArn: "aws-role-arn", + AzureIdentity: "azure-id", + GcpServiceAccount: "gcp-service-account", + Uri: "uri", + TargetPort: 111, + }, + TeleportCluster: "teleport-cluster", + RouteToDatabase: &decisionpb.RouteToDatabase{ + ServiceName: "service-name", + Protocol: "protocol", + Username: "username", + Database: "database", + Roles: []string{"role1", "role2"}, + }, + DatabaseNames: []string{"db1", "db2"}, + DatabaseUsers: []string{"dbuser1", "dbuser2"}, + MfaVerified: "mfa-device-id", + PreviousIdentityExpires: timestamppb.Now(), + LoginIp: "login-ip", + PinnedIp: "pinned-ip", + AwsRoleArns: []string{"arn1", "arn2"}, + AzureIdentities: []string{"azure-id-1", "azure-id-2"}, + GcpServiceAccounts: []string{"gcp-account-1", "gcp-account-2"}, + ActiveRequests: []string{"accessrequest1", "accessrequest2"}, + DisallowReissue: true, + Renewable: true, + Generation: 112, + BotName: "bot-name", + BotInstanceId: "bot-instance-id", + AllowedResourceIds: []*decisionpb.ResourceId{ + { + ClusterName: "cluster1", + Kind: "kind1", + Name: "name1", + SubResourceName: "sub-resource1", + }, + { + ClusterName: "cluster2", + Kind: "kind2", + Name: "name2", + SubResourceName: "sub-resource2", + }, + }, + PrivateKeyPolicy: "private-key-policy", + ConnectionDiagnosticId: "connection-diag-id", + DeviceExtensions: &decisionpb.DeviceExtensions{ + DeviceId: "device-id", + AssetTag: "asset-tag", + CredentialId: "credential-id", + }, + UserType: "user-type", + } + + tests := []struct { + name string + start, want *decisionpb.TLSIdentity + }{ + { + name: "nil-to-nil", + start: nil, + want: nil, + }, + { + name: "zero-to-zero", + start: &decisionpb.TLSIdentity{}, + want: minimalTLSIdentity, + }, + { + name: "full identity", + start: fullIdentity, + want: fullIdentity, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := decision.TLSIdentityFromTLSCA( + decision.TLSIdentityToTLSCA(test.start), + ) + if diff := cmp.Diff(test.want, got, protocmp.Transform()); diff != "" { + t.Errorf("TLSIdentity conversion mismatch (-want +got)\n%s", diff) + } + }) + } + + t.Run("zero tlsca.Identity", func(t *testing.T) { + var id tlsca.Identity + got := decision.TLSIdentityFromTLSCA(&id) + want := minimalTLSIdentity + if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { + t.Errorf("TLSIdentity conversion mismatch (-want +got)\n%s", diff) + } + }) +} + +func TestTLSIdentityToTLSCA_zeroTimestamp(t *testing.T) { + t.Parallel() + + id := decision.TLSIdentityToTLSCA(&decisionpb.TLSIdentity{ + Expires: ×tamppb.Timestamp{}, + PreviousIdentityExpires: ×tamppb.Timestamp{}, + }) + assert.Zero(t, id.Expires, "id.Expires") + assert.Zero(t, id.PreviousIdentityExpires, "id.PreviousIdentityExpires") +} diff --git a/lib/tlsca/ca.go b/lib/tlsca/ca.go index 6b6fb020c0517..8d74400e233e8 100644 --- a/lib/tlsca/ca.go +++ b/lib/tlsca/ca.go @@ -113,8 +113,10 @@ type CertAuthority struct { } // Identity is an identity of the user or service, e.g. Proxy or Node +// Must be kept in sync with teleport.decision.v1alpha1.TLSIdentity. type Identity struct { - // Username is a username or name of the node connection + // Username is the name of the user (for end-users/bots) or the Host ID (for + // Teleport processes). Username string // Impersonator is a username of a user impersonating this user Impersonator string From 963e836e189cc3f9b421e997979b1c8a872cda04 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Wed, 29 Jan 2025 19:42:55 -0300 Subject: [PATCH 11/27] Revert "fix: Take TTL into account when renewing sessions (#49732)" (#51601) This reverts commit ec870e156a44e85998cee8049bdda167046a6196. --- .../src/services/websession/websession.ts | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/web/packages/teleport/src/services/websession/websession.ts b/web/packages/teleport/src/services/websession/websession.ts index 667a25fb6f916..5b4c5680afc0d 100644 --- a/web/packages/teleport/src/services/websession/websession.ts +++ b/web/packages/teleport/src/services/websession/websession.ts @@ -26,8 +26,9 @@ import { KeysEnum, storageService } from 'teleport/services/storageService'; import makeBearerToken from './makeBearerToken'; import { RenewSessionRequest } from './types'; -const MAX_RENEW_TOKEN_TIME = 180000; // 3m -const MIN_RENEW_TOKEN_TIME = 30000; // 30s +// Time to determine when to renew session which is +// when expiry time of token is less than 3 minutes. +const RENEW_TOKEN_TIME = 180 * 1000; const TOKEN_CHECKER_INTERVAL = 15 * 1000; // every 15 sec const logger = Logger.create('services/session'); @@ -145,14 +146,11 @@ const session = { return false; } - // Renew session if token expiry time is less than renewTime (with MIN_ and - // MAX_RENEW_TOKEN_TIME as floor and ceiling, respectively). + // Renew session if token expiry time is less than 3 minutes. // Browsers have js timer throttling behavior in inactive tabs that can go // up to 100s between timer calls from testing. 3 minutes seems to be a safe number // with extra padding. - let renewTime = Math.min(this._ttl() / 10, MAX_RENEW_TOKEN_TIME); - renewTime = Math.max(renewTime, MIN_RENEW_TOKEN_TIME); - return this._timeLeft() < renewTime; + return this._timeLeft() < RENEW_TOKEN_TIME; }, _renewToken(req: RenewSessionRequest = {}, signal?: AbortSignal) { @@ -216,21 +214,6 @@ const session = { return delta; }, - _ttl() { - const token = this._getBearerToken(); - if (!token) { - return 0; - } - - let { expiresIn, created } = token; - if (!created || !expiresIn) { - return 0; - } - - expiresIn = expiresIn * 1000; - return expiresIn; - }, - _shouldCheckStatus() { if (this._getIsRenewing()) { return false; From 02a21bbbf3fea02351065dbef520634d6be9f12c Mon Sep 17 00:00:00 2001 From: Marco Dinis Date: Thu, 30 Jan 2025 09:00:03 +0000 Subject: [PATCH 12/27] [v17] WebAPI: List Rules - add regions filter (#51596) * WebAPI: List Rules - add region prefix filter * change from prefix to list of regions --- lib/web/integrations.go | 93 ++++++++++++--------- lib/web/integrations_test.go | 153 ++++++++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 39 deletions(-) diff --git a/lib/web/integrations.go b/lib/web/integrations.go index c54b21fa5905a..b05b320db1577 100644 --- a/lib/web/integrations.go +++ b/lib/web/integrations.go @@ -348,6 +348,10 @@ func rulesWithIntegration(dc *discoveryconfig.DiscoveryConfig, matcherType strin // integrationDiscoveryRules returns the Discovery Rules that are using a given integration. // A Discovery Rule is just like a DiscoveryConfig Matcher, except that it breaks down by region. // So, if a Matcher exists for two regions, that will be represented as two Rules. +// Accepts the following query params: +// startKey: indicator for pagination, should be the value of the last reponse's `nextItem`, or absent for a the starting page +// resourceType: which resource type to return, one of ec2, eks, rds +// regions: only rules for regions listed are returned (omit query to include all regions) func (h *Handler) integrationDiscoveryRules(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (interface{}, error) { integrationName := p.ByName("name") if integrationName == "" { @@ -357,6 +361,7 @@ func (h *Handler) integrationDiscoveryRules(w http.ResponseWriter, r *http.Reque values := r.URL.Query() startKey := values.Get("startKey") resourceType := values.Get("resourceType") + regionsFilter := values["regions"] clt, err := sctx.GetUserClient(r.Context(), site) if err != nil { @@ -368,7 +373,7 @@ func (h *Handler) integrationDiscoveryRules(w http.ResponseWriter, r *http.Reque return nil, trace.Wrap(err) } - rules, err := collectAutoDiscoveryRules(r.Context(), ig.GetName(), startKey, resourceType, clt.DiscoveryConfigClient()) + rules, err := collectAutoDiscoveryRules(r.Context(), ig.GetName(), startKey, resourceType, regionsFilter, clt.DiscoveryConfigClient()) if err != nil { return nil, trace.Wrap(err) } @@ -377,7 +382,7 @@ func (h *Handler) integrationDiscoveryRules(w http.ResponseWriter, r *http.Reque } // collectAutoDiscoveryRules will iterate over all DiscoveryConfigs's Matchers and collect the Discovery Rules that exist in them for the given integration. -// It can also be filtered by Matcher Type (eg ec2, rds, eks) +// It can also be filtered by Matcher Type (eg ec2, rds, eks) and a regionsFilter list (eg, us-east-1, us-east-2) // A Discovery Rule is a close match to a DiscoveryConfig's Matcher, except that it will count as many rules as regions exist. // Eg if a DiscoveryConfig's Matcher has two regions, then it will output two (almost equal) Rules, one for each Region. func collectAutoDiscoveryRules( @@ -385,6 +390,7 @@ func collectAutoDiscoveryRules( integrationName string, nextPage string, resourceTypeFilter string, + regionsFilter []string, clt interface { ListDiscoveryConfigs(ctx context.Context, pageSize int, nextToken string) ([]*discoveryconfig.DiscoveryConfig, string, error) }, @@ -399,53 +405,66 @@ func collectAutoDiscoveryRules( return ret, trace.Wrap(err) } for _, dc := range discoveryConfigs { - lastSync := &dc.Status.LastSyncTime - if lastSync.IsZero() { - lastSync = nil + ret.Rules = append(ret.Rules, + collectAutoDiscoveryRulesFromDiscoveryConfig(dc, integrationName, resourceTypeFilter, regionsFilter)..., + ) + } + + ret.NextKey = nextToken + if nextToken == "" || len(ret.Rules) > maxPerPage { + break + } + + nextPage = nextToken + } + + return ret, nil +} + +func collectAutoDiscoveryRulesFromDiscoveryConfig(dc *discoveryconfig.DiscoveryConfig, integrationName, resourceTypeFilter string, regionsFilter []string) []ui.IntegrationDiscoveryRule { + var ret []ui.IntegrationDiscoveryRule + + lastSync := &dc.Status.LastSyncTime + if lastSync.IsZero() { + lastSync = nil + } + + for _, matcher := range dc.Spec.AWS { + if matcher.Integration != integrationName { + continue + } + + for _, resourceType := range matcher.Types { + if resourceTypeFilter != "" && resourceType != resourceTypeFilter { + continue } - for _, matcher := range dc.Spec.AWS { - if matcher.Integration != integrationName { + for _, region := range matcher.Regions { + if len(regionsFilter) > 0 && !slices.Contains(regionsFilter, region) { continue } - for _, resourceType := range matcher.Types { - if resourceTypeFilter != "" && resourceType != resourceTypeFilter { - continue - } - - for _, region := range matcher.Regions { - uiLables := make([]libui.Label, 0, len(matcher.Tags)) - for labelKey, labelValues := range matcher.Tags { - for _, labelValue := range labelValues { - uiLables = append(uiLables, libui.Label{ - Name: labelKey, - Value: labelValue, - }) - } - } - ret.Rules = append(ret.Rules, ui.IntegrationDiscoveryRule{ - ResourceType: resourceType, - Region: region, - LabelMatcher: uiLables, - DiscoveryConfig: dc.GetName(), - LastSync: lastSync, + uiLables := make([]libui.Label, 0, len(matcher.Tags)) + for labelKey, labelValues := range matcher.Tags { + for _, labelValue := range labelValues { + uiLables = append(uiLables, libui.Label{ + Name: labelKey, + Value: labelValue, }) } } + ret = append(ret, ui.IntegrationDiscoveryRule{ + ResourceType: resourceType, + Region: region, + LabelMatcher: uiLables, + DiscoveryConfig: dc.GetName(), + LastSync: lastSync, + }) } } - - ret.NextKey = nextToken - - if nextToken == "" || len(ret.Rules) > maxPerPage { - break - } - - nextPage = nextToken } - return ret, nil + return ret } // integrationsList returns a page of Integrations diff --git a/lib/web/integrations_test.go b/lib/web/integrations_test.go index ef2b42713e1c4..d7507d0e47365 100644 --- a/lib/web/integrations_test.go +++ b/lib/web/integrations_test.go @@ -314,7 +314,7 @@ func TestCollectAutoDiscoveryRules(t *testing.T) { discoveryConfigs: make([]*discoveryconfig.DiscoveryConfig, 0), } - gotRules, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", clt) + gotRules, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", nil, clt) require.NoError(t, err) expectedRules := ui.IntegrationDiscoveryRules{} require.Equal(t, expectedRules, gotRules) @@ -386,7 +386,7 @@ func TestCollectAutoDiscoveryRules(t *testing.T) { }, } - got, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", clt) + got, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", nil, clt) require.NoError(t, err) expectedRules := []ui.IntegrationDiscoveryRule{ { @@ -439,4 +439,153 @@ func TestCollectAutoDiscoveryRules(t *testing.T) { require.Empty(t, got.NextKey) require.ElementsMatch(t, expectedRules, got.Rules) }) + + t.Run("filters resource type", func(t *testing.T) { + syncTime := time.Now() + dcForEC2 := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"ec2"}, + Regions: []string{"us-east-1"}, + Tags: types.Labels{"*": []string{"*"}}, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + } + dcForRDS := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"rds"}, + Regions: []string{"us-east-1", "us-east-2"}, + Tags: types.Labels{ + "env": []string{"dev", "prod"}, + }, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + } + clt := &mockRelevantAWSRegionsClient{ + discoveryConfigs: []*discoveryconfig.DiscoveryConfig{ + dcForEC2, + dcForRDS, + }, + } + + got, err := collectAutoDiscoveryRules(ctx, integrationName, "", "ec2", nil, clt) + require.NoError(t, err) + expectedRules := []ui.IntegrationDiscoveryRule{ + { + ResourceType: "ec2", + Region: "us-east-1", + LabelMatcher: []libui.Label{ + {Name: "*", Value: "*"}, + }, + DiscoveryConfig: dcForEC2.GetName(), + LastSync: &syncTime, + }, + } + require.Empty(t, got.NextKey) + require.ElementsMatch(t, expectedRules, got.Rules) + }) + + t.Run("filters by region", func(t *testing.T) { + syncTime := time.Now() + dcForRDS := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"rds"}, + Regions: []string{"us-east-1", "us-east-2", "us-west-2"}, + Tags: types.Labels{ + "env": []string{"dev", "prod"}, + }, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + } + clt := &mockRelevantAWSRegionsClient{ + discoveryConfigs: []*discoveryconfig.DiscoveryConfig{ + dcForRDS, + }, + } + + got, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", []string{"us-east-1", "us-east-2"}, clt) + require.NoError(t, err) + expectedRules := []ui.IntegrationDiscoveryRule{ + { + ResourceType: "rds", + Region: "us-east-1", + LabelMatcher: []libui.Label{ + {Name: "env", Value: "dev"}, + {Name: "env", Value: "prod"}, + }, + DiscoveryConfig: dcForRDS.GetName(), + LastSync: &syncTime, + }, + { + ResourceType: "rds", + Region: "us-east-2", + LabelMatcher: []libui.Label{ + {Name: "env", Value: "dev"}, + {Name: "env", Value: "prod"}, + }, + DiscoveryConfig: dcForRDS.GetName(), + LastSync: &syncTime, + }, + } + require.Empty(t, got.NextKey) + require.ElementsMatch(t, expectedRules, got.Rules) + }) + + t.Run("pagination", func(t *testing.T) { + syncTime := time.Now() + totalRules := 1000 + + discoveryConfigs := make([]*discoveryconfig.DiscoveryConfig, 0, totalRules) + for range totalRules { + discoveryConfigs = append(discoveryConfigs, + &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"ec2"}, + Regions: []string{"us-east-1"}, + Tags: types.Labels{"*": []string{"*"}}, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + }, + ) + } + clt := &mockRelevantAWSRegionsClient{ + discoveryConfigs: discoveryConfigs, + } + + nextKey := "" + rulesCounter := 0 + for { + got, err := collectAutoDiscoveryRules(ctx, integrationName, nextKey, "", nil, clt) + require.NoError(t, err) + rulesCounter += len(got.Rules) + nextKey = got.NextKey + if nextKey == "" { + break + } + } + require.Equal(t, totalRules, rulesCounter) + }) } From b57c8a5b472eb49239d1ad5c652025d503331bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Skrz=C4=99tnicki?= Date: Thu, 30 Jan 2025 12:12:46 +0100 Subject: [PATCH 13/27] fix panic in CheckSAMLEntityDescriptor (#51634) --- lib/fixtures/fixtures.go | 13 +++++++++++++ lib/services/saml.go | 4 ++++ lib/services/saml_test.go | 14 +++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/fixtures/fixtures.go b/lib/fixtures/fixtures.go index deda7e0636165..fdca787901c0e 100644 --- a/lib/fixtures/fixtures.go +++ b/lib/fixtures/fixtures.go @@ -183,6 +183,19 @@ spec: pHM7WKwFyW1dvEDax3BGj9/cbKvpvcwR urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:1.1:nameid-format:unspecified` +const SAMLConnectorMissingIDPSSODescriptor = `kind: saml +version: v2 +metadata: + name: OktaSAML + namespace: default +spec: + acs: https://localhost:3080/v1/webapi/saml/acs + sso: https://dev-813354.oktapreview.com/app/gravitationaldev813354_teleportsaml_1/exkafftca6RqPVgyZ0h7/sso/saml + attributes_to_roles: + - {name: "groups", value: "Everyone", roles: ["admin"]} + entity_descriptor: | + ` + const ( TLSCACertPEM = apifixtures.TLSCACertPEM TLSCAKeyPEM = apifixtures.TLSCAKeyPEM diff --git a/lib/services/saml.go b/lib/services/saml.go index ad8e2dccaa36c..e6f3a83c49d23 100644 --- a/lib/services/saml.go +++ b/lib/services/saml.go @@ -213,6 +213,10 @@ func CheckSAMLEntityDescriptor(entityDescriptor string) ([]*x509.Certificate, er return nil, trace.Wrap(err, "failed to parse entity_descriptor") } + if metadata.IDPSSODescriptor == nil { + return nil, nil + } + var roots []*x509.Certificate for _, kd := range metadata.IDPSSODescriptor.KeyDescriptors { diff --git a/lib/services/saml_test.go b/lib/services/saml_test.go index 992661a274051..a90eb7d5ab526 100644 --- a/lib/services/saml_test.go +++ b/lib/services/saml_test.go @@ -58,12 +58,16 @@ func TestParseFromMetadata(t *testing.T) { func TestCheckSAMLEntityDescriptor(t *testing.T) { t.Parallel() - for name, input := range map[string]string{ - "without certificate padding": fixtures.SAMLOktaConnectorV2, - "with certificate padding": fixtures.SAMLOktaConnectorV2WithPadding, + for name, tt := range map[string]struct { + resource string + wantCerts int + }{ + "without certificate padding": {resource: fixtures.SAMLOktaConnectorV2, wantCerts: 1}, + "with certificate padding": {resource: fixtures.SAMLOktaConnectorV2WithPadding, wantCerts: 1}, + "missing IDPSSODescriptor": {resource: fixtures.SAMLConnectorMissingIDPSSODescriptor, wantCerts: 0}, } { t.Run(name, func(t *testing.T) { - decoder := kyaml.NewYAMLOrJSONDecoder(strings.NewReader(input), defaults.LookaheadBufSize) + decoder := kyaml.NewYAMLOrJSONDecoder(strings.NewReader(tt.resource), defaults.LookaheadBufSize) var raw UnknownResource err := decoder.Decode(&raw) require.NoError(t, err) @@ -74,7 +78,7 @@ func TestCheckSAMLEntityDescriptor(t *testing.T) { ed := oc.GetEntityDescriptor() certs, err := CheckSAMLEntityDescriptor(ed) require.NoError(t, err) - require.Len(t, certs, 1) + require.Len(t, certs, tt.wantCerts) }) } } From 4b93201a376661d3133f8329e2b9ddc73ac42efe Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Thu, 30 Jan 2025 10:51:13 -0300 Subject: [PATCH 14/27] docs: Instruct WSL device trust users to use tsh.exe (#51598) --- docs/pages/includes/device-trust/prereqs.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/pages/includes/device-trust/prereqs.mdx b/docs/pages/includes/device-trust/prereqs.mdx index 6447d7c6dd8cf..617e803ce871b 100644 --- a/docs/pages/includes/device-trust/prereqs.mdx +++ b/docs/pages/includes/device-trust/prereqs.mdx @@ -9,7 +9,11 @@ - A device with TPM 2.0. - A user with permissions to use the /dev/tpmrm0 device (typically done by assigning the `tss` group to the user). - - `tsh` v15.0.0 or newer. [Install tsh for Linux](../../installation.mdx#linux). + - The `tsh` client. [Install tsh for Linux](../../installation.mdx#linux). + + WSL users should use the Windows binary instead. + [Download the Windows tsh installer](../../installation.mdx#windows-tsh-and-tctl-clients-only). + - To authenticate a Web UI session you need [Teleport Connect]( ../../connect-your-client/teleport-connect.mdx#installation--upgrade) - Correct end-user IP propagation to your Teleport deployment: From c16ef827626617ee79d16d3ea5b6a994102872af Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 30 Jan 2025 16:20:34 +0000 Subject: [PATCH 15/27] kube: fix transport being incorrectly cached by kube service (#51652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #46899 introduced a subtle change in Kubernetes service behavior, where the direct transport—kube agent to Kubernetes API—is now cached for five hours. This disrupts auto-discovery because tokens are only valid for 15 minutes, while the HTTP transport that applies them remains valid for five hours. As a result, the Kubernetes service continues using the same expired token for 4 hours and 45 minutes. This PR resolves the issue by preventing token caching altogether. Fixes #51639 Signed-off-by: Tiago Silva --- lib/kube/proxy/kube_creds.go | 2 +- lib/kube/proxy/transport.go | 13 +++++++--- lib/kube/proxy/transport_test.go | 44 ++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/lib/kube/proxy/kube_creds.go b/lib/kube/proxy/kube_creds.go index 19fd6edb2bd69..9169326f09d2a 100644 --- a/lib/kube/proxy/kube_creds.go +++ b/lib/kube/proxy/kube_creds.go @@ -236,7 +236,7 @@ func newDynamicKubeCreds(ctx context.Context, cfg dynamicCredsConfig) (*dynamicK func (d *dynamicKubeCreds) getTLSConfig() *tls.Config { d.RLock() defer d.RUnlock() - return d.staticCreds.tlsConfig + return d.staticCreds.getTLSConfig() } func (d *dynamicKubeCreds) getTransportConfig() *transport.Config { diff --git a/lib/kube/proxy/transport.go b/lib/kube/proxy/transport.go index 87217b39a0a4b..5821bbd229553 100644 --- a/lib/kube/proxy/transport.go +++ b/lib/kube/proxy/transport.go @@ -59,6 +59,15 @@ type dialContextFunc func(context.Context, string, string) (net.Conn, error) // The transport is cached in the forwarder so that it can be reused for future // requests. If the transport is not cached, a new one is created and cached. func (f *Forwarder) transportForRequestWithImpersonation(sess *clusterSession) (http.RoundTripper, *tls.Config, error) { + // If the session has a kube API credentials, it means that the next hop is + // a Kubernetes API server. In this case, we can use the provided credentials + // to dial the next hop directly and never cache the transport. + if sess.kubeAPICreds != nil { + // If agent is running in agent mode, get the transport from the configured cluster + // credentials. + return sess.kubeAPICreds.getTransport(), sess.kubeAPICreds.getTLSConfig(), nil + } + // If the cluster is remote, the key is the teleport cluster name. // If the cluster is local, the key is the teleport cluster name and the kubernetes // cluster name: /. @@ -73,10 +82,6 @@ func (f *Forwarder) transportForRequestWithImpersonation(sess *clusterSession) ( if sess.teleportCluster.isRemote { // If the cluster is remote, create a new transport for the remote cluster. httpTransport, tlsConfig, err = f.newRemoteClusterTransport(sess.teleportCluster.name) - } else if sess.kubeAPICreds != nil { - // If agent is running in agent mode, get the transport from the configured cluster - // credentials. - httpTransport, tlsConfig = sess.kubeAPICreds.getTransport(), sess.kubeAPICreds.getTLSConfig() } else if f.cfg.ReverseTunnelSrv != nil { // If agent is running in proxy mode, create a new transport for the local cluster. httpTransport, tlsConfig, err = f.newLocalClusterTransport(sess.kubeClusterName) diff --git a/lib/kube/proxy/transport_test.go b/lib/kube/proxy/transport_test.go index 88af58d7649c4..2f057a74a263a 100644 --- a/lib/kube/proxy/transport_test.go +++ b/lib/kube/proxy/transport_test.go @@ -20,10 +20,12 @@ package proxy import ( "context" + "crypto/tls" "fmt" "net" "testing" + "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" @@ -137,3 +139,45 @@ func newKubeServerWithProxyIDs(t *testing.T, hostname, hostID string, proxyIds [ ks.Spec.ProxyIDs = proxyIds return ks } + +func TestDirectTransportNotCached(t *testing.T) { + t.Parallel() + + transportClients, err := utils.NewFnCache(utils.FnCacheConfig{ + TTL: transportCacheTTL, + Clock: clockwork.NewFakeClock(), + }) + require.NoError(t, err) + + forwarder := &Forwarder{ + ctx: context.Background(), + cachedTransport: transportClients, + } + + kubeAPICreds := &dynamicKubeCreds{ + staticCreds: &staticKubeCreds{ + tlsConfig: &tls.Config{ + ServerName: "localhost", + }, + }, + } + + clusterSess := &clusterSession{ + kubeAPICreds: kubeAPICreds, + authContext: authContext{ + kubeClusterName: "b", + teleportCluster: teleportClusterClient{ + name: "a", + }, + }, + } + + _, tlsConfig, err := forwarder.transportForRequestWithImpersonation(clusterSess) + require.NoError(t, err) + require.Equal(t, "localhost", tlsConfig.ServerName) + + kubeAPICreds.staticCreds.tlsConfig.ServerName = "example.com" + _, tlsConfig, err = forwarder.transportForRequestWithImpersonation(clusterSess) + require.NoError(t, err) + require.Equal(t, "example.com", tlsConfig.ServerName) +} From bb59d783168383fa10380a34b43f78b4092e941a Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Thu, 30 Jan 2025 13:35:13 -0300 Subject: [PATCH 16/27] [v17] fix: Randomly derive UUIDs from non-conformant session IDs (#51643) * Tests event with non-UUID session ID * Randomly derive UUIDs from non-conformant session IDs * nit: Use "" instead of `` * Link godoc references to Log.deriveSessionID * Mention UUIDv5 for derived IDs * Do not log the session ID * Rename test helper, move truncateEvents out of it --- lib/events/pgevents/pgevents.go | 65 +++++++++---- lib/events/pgevents/pgevents_test.go | 135 ++++++++++++++++++++++----- 2 files changed, 159 insertions(+), 41 deletions(-) diff --git a/lib/events/pgevents/pgevents.go b/lib/events/pgevents/pgevents.go index d0b18da2d3d73..0d30995927154 100644 --- a/lib/events/pgevents/pgevents.go +++ b/lib/events/pgevents/pgevents.go @@ -70,6 +70,14 @@ const ( ) const ( + // A note on "session_id uuid NOT NULL": + // + // Some session IDs aren't UUIDs. See [Log.deriveSessionID] for an example. + // The wiser choice of type would be "session_id text", ie, handling session + // IDs as an opaque identifier. + // + // If you are writing a new backend and stumbled on this comment, do not use + // a storage UUID type for session IDs. Use a string type. schemaV1Table = `CREATE TABLE events ( event_time timestamptz NOT NULL, event_id uuid NOT NULL, @@ -360,14 +368,6 @@ var _ events.AuditLogger = (*Log)(nil) // EmitAuditEvent implements [events.AuditLogger]. func (l *Log) EmitAuditEvent(ctx context.Context, event apievents.AuditEvent) error { ctx = context.WithoutCancel(ctx) - var sessionID uuid.UUID - if s := events.GetSessionID(event); s != "" { - u, err := uuid.Parse(s) - if err != nil { - return trace.Wrap(err) - } - sessionID = u - } eventJSON, err := utils.FastMarshal(event) if err != nil { @@ -375,6 +375,7 @@ func (l *Log) EmitAuditEvent(ctx context.Context, event apievents.AuditEvent) er } eventID := uuid.New() + sessionID := l.deriveSessionID(ctx, events.GetSessionID(event)) start := time.Now() // if an event with the same event_id exists, it means that we inserted it @@ -412,15 +413,6 @@ func (l *Log) searchEvents( eventTypes []string, cond *types.WhereExpr, sessionID string, limit int, order types.EventOrder, startKey string, ) ([]apievents.AuditEvent, string, error) { - var sessionUUID uuid.UUID - if sessionID != "" { - var err error - sessionUUID, err = uuid.Parse(sessionID) - if err != nil { - return nil, "", trace.Wrap(err) - } - } - if limit <= 0 { limit = defaults.EventsIterationLimit } @@ -447,6 +439,8 @@ func (l *Log) searchEvents( } } + sessionUUID := l.deriveSessionID(ctx, sessionID) + var qb strings.Builder qb.WriteString("DECLARE cur CURSOR FOR SELECT" + " events.event_time, events.event_id, events.event_data" + @@ -595,3 +589,40 @@ func (l *Log) GetEventExportChunks(ctx context.Context, req *auditlogpb.GetEvent func (l *Log) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { return l.searchEvents(ctx, req.From, req.To, events.SessionRecordingEvents, req.Cond, req.SessionID, req.Limit, req.Order, req.StartKey) } + +// sessionIDBase is a randomly-generated UUID used as the basis for deriving +// an UUID from session IDs. See [Log.deriveSessionID]. +var sessionIDBase = uuid.MustParse("e481e221-77b0-4b9e-be98-bc2e486b751b") + +func (l *Log) deriveSessionID(ctx context.Context, sessionID string) uuid.UUID { + if sessionID == "" { + return uuid.Nil // return zero UUID for backwards compat + } + + u, err := uuid.Parse(sessionID) + if err == nil { + return u + } + + // Some session IDs aren't UUIDs. For example, App session IDs are 32-byte + // values encoded as hex. Whether the assumption of UUIDs is philosophically + // correct is immaterial, what matters is that we do not drop the audit + // event. + // + // To avoid dropping the event while conforming to the existing schema we + // deterministically derive an UUID from the session ID. + // + // Note that derived IDs are UUIDv5 (instead of the usual UUIDv4 from + // uuid.Parse), so that could be used as a hint to which UUIDs are original or + // derived. + // + // * https://github.com/gravitational/teleport/blob/63537e3da5a22b61d9218863f1ed535a31d229ea/lib/auth/sessions.go#L521 + derived := uuid.NewSHA1(sessionIDBase, []byte(sessionID)) + + l.log.DebugContext(ctx, + "Failed to parse event session ID, using derived ID", + "error", err, + "derived_id", derived, + ) + return derived +} diff --git a/lib/events/pgevents/pgevents_test.go b/lib/events/pgevents/pgevents_test.go index 05c4934d7b7ad..8aeb66ee5ca7e 100644 --- a/lib/events/pgevents/pgevents_test.go +++ b/lib/events/pgevents/pgevents_test.go @@ -25,10 +25,17 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + apidefaults "github.com/gravitational/teleport/api/defaults" + "github.com/gravitational/teleport/api/types" + apievents "github.com/gravitational/teleport/api/types/events" pgcommon "github.com/gravitational/teleport/lib/backend/pgbk/common" + "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/events/test" "github.com/gravitational/teleport/lib/utils" ) @@ -38,52 +45,132 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } +// TELEPORT_TEST_PGEVENTS_URL is a connection string similar to the one used by +// "audit_events_uri" (in teleport.yaml). +// For example: "postgresql://teleport@localhost:5432/teleport_test1?sslcert=/path/to/cert.pem&sslkey=/path/to/key.pem&sslrootcert=/path/to/ca.pem&sslmode=verify-full" const urlEnvVar = "TELEPORT_TEST_PGEVENTS_URL" func TestPostgresEvents(t *testing.T) { - s, ok := os.LookupEnv(urlEnvVar) - if !ok { - t.Skipf("Missing %v environment variable.", urlEnvVar) - } - - u, err := url.Parse(s) - require.NoError(t, err) - - var cfg Config - require.NoError(t, cfg.SetFromURL(u)) + // Don't t.Parallel(), relies on the database backed by urlEnvVar. + log := newLogForTesting(t) - ctx, cancel := context.WithCancel(context.Background()) - t.Cleanup(cancel) + ctx := context.Background() - log, err := New(ctx, cfg) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, log.Close()) }) + truncateEvents := func(t *testing.T) { + _, err := log.pool.Exec(ctx, "TRUNCATE events") + require.NoError(t, err, "truncate events") + } suite := test.EventsSuite{ Log: log, Clock: clockwork.NewRealClock(), } - // the tests in the suite expect a blank slate each time - setup := func(t *testing.T) { - _, err := log.pool.Exec(ctx, "TRUNCATE events") - require.NoError(t, err) - } - t.Run("SessionEventsCRUD", func(t *testing.T) { - setup(t) + // The tests in the suite expect a blank slate each time. + truncateEvents(t) suite.SessionEventsCRUD(t) }) t.Run("EventPagination", func(t *testing.T) { - setup(t) + truncateEvents(t) suite.EventPagination(t) }) t.Run("SearchSessionEventsBySessionID", func(t *testing.T) { - setup(t) + truncateEvents(t) suite.SearchSessionEventsBySessionID(t) }) } +// TestLog_nonStandardSessionID tests for +// https://github.com/gravitational/teleport/issues/46207. +func TestLog_nonStandardSessionID(t *testing.T) { + // Don't t.Parallel(), relies on the database backed by urlEnvVar. + eventsLog := newLogForTesting(t) + + // Example app event. Only the session ID matters for the test, everything + // else is realistic but irrelevant here. + eventTime := time.Now() + appStartEvent := &apievents.AppSessionStart{ + Metadata: apievents.Metadata{ + Type: events.AppSessionStartEvent, + Code: events.AppSessionStartCode, + ClusterName: "zarq", + Time: eventTime, + }, + ServerMetadata: apievents.ServerMetadata{ + ServerVersion: "17.2.2", + ServerID: "18d877c6-c8ab-46fc-9806-b638c0d6c556", + ServerNamespace: apidefaults.Namespace, + }, + SessionMetadata: apievents.SessionMetadata{ + // IMPORTANT: not an UUID! + SessionID: "f8571503d72f35938ce5001b792baebcce3183719ae947fde1ed685f7848facc", + }, + UserMetadata: apievents.UserMetadata{ + User: "alpaca", + UserKind: apievents.UserKind_USER_KIND_HUMAN, + }, + PublicAddr: "dumper.zarq.dev", + AppMetadata: apievents.AppMetadata{ + AppURI: "http://127.0.0.1:52932", + AppPublicAddr: "dumper.zarq.dev", + AppName: "dumper", + }, + } + + ctx := context.Background() + + // Emit event with non-standard session ID. + require.NoError(t, + eventsLog.EmitAuditEvent(ctx, appStartEvent), + "emit audit event", + ) + + // Search event by the same (non-standard) session ID. + // SearchSessionEvents has a hard-coded list of eventTypes that excludes App + // events, so we must use searchEvents instead. + before := eventTime.Add(-1 * time.Second) + after := eventTime.Add(1 * time.Second) + appEvents, _, err := eventsLog.searchEvents(ctx, + before, // fromTime + after, // toTime + []string{appStartEvent.Metadata.Type}, // eventTypes + nil, // cond + appStartEvent.SessionID, + 2, // limit + types.EventOrderAscending, + "", // startKey + ) + require.NoError(t, err, "search session events") + want := []apievents.AuditEvent{appStartEvent} + if diff := cmp.Diff(want, appEvents, protocmp.Transform()); diff != "" { + t.Errorf("searchEvents mismatch (-want +got)\n%s", diff) + } +} + +func newLogForTesting(t *testing.T) *Log { + t.Helper() + + connString, ok := os.LookupEnv(urlEnvVar) + if !ok { + t.Skipf("Missing %v environment variable.", urlEnvVar) + } + u, err := url.Parse(connString) + require.NoError(t, err, "parse Postgres connString from %s", urlEnvVar) + + var cfg Config + require.NoError(t, cfg.SetFromURL(u), "cfg.SetFromURL") + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + eventsLog, err := New(ctx, cfg) + require.NoError(t, err, "create new Log") + t.Cleanup(func() { assert.NoError(t, eventsLog.Close(), "close events log") }) + + return eventsLog +} + func TestConfig(t *testing.T) { configs := map[string]*Config{ "postgres://foo#auth_mode=azure": { From 400cefaa488bced646b32dd480247a88810e3cd1 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:01:12 -0500 Subject: [PATCH 17/27] Prevent reauthentication for tilde prefix expansion errors (#51649) In https://github.com/gravitational/teleport/pull/24254 expansion of tilde prefixes(i.e. `tsh scp CHANGELOG.md root@host:~foo/`) was explicitly denied. However, because the error returned to the user is a trace.BadParameter error the reauthentication logic kicks in and attempts to resolve the issue with fresh credentials. This error is now caught and wrapped in a NonRetryableError to prevent the authentication logic from providing a weird UX. Updates https://github.com/gravitational/teleport/issues/22886. --- lib/client/client.go | 13 ++++++++++++- lib/sshutils/sftp/sftp.go | 16 +++++++++++++--- lib/sshutils/sftp/sftp_test.go | 3 +-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/client/client.go b/lib/client/client.go index f14a5a2df476d..23c50f2d3a459 100644 --- a/lib/client/client.go +++ b/lib/client/client.go @@ -724,7 +724,18 @@ func (c *NodeClient) TransferFiles(ctx context.Context, cfg *sftp.Config) error ) defer span.End() - return trace.Wrap(cfg.TransferFiles(ctx, c.Client.Client)) + if err := cfg.TransferFiles(ctx, c.Client.Client); err != nil { + // TODO(tross): DELETE IN 19.0.0 - Older versions of Teleport would return + // a trace.BadParameter error when ~user path expansion was rejected, and + // reauthentication logic is attempted on BadParameter errors. + if trace.IsBadParameter(err) && strings.Contains(err.Error(), "expanding remote ~user paths is not supported") { + return trace.Wrap(&NonRetryableError{Err: err}) + } + + return trace.Wrap(err) + } + + return nil } type netDialer interface { diff --git a/lib/sshutils/sftp/sftp.go b/lib/sshutils/sftp/sftp.go index 77bd23f3cda5a..d8390ba0308d7 100644 --- a/lib/sshutils/sftp/sftp.go +++ b/lib/sshutils/sftp/sftp.go @@ -331,7 +331,7 @@ func (c *Config) expandPaths(srcIsRemote, dstIsRemote bool) (err error) { for i, srcPath := range c.srcPaths { c.srcPaths[i], err = expandPath(srcPath) if err != nil { - return trace.Wrap(err, "error expanding %q", srcPath) + return trace.Wrap(err) } } } @@ -339,13 +339,23 @@ func (c *Config) expandPaths(srcIsRemote, dstIsRemote bool) (err error) { if dstIsRemote { c.dstPath, err = expandPath(c.dstPath) if err != nil { - return trace.Wrap(err, "error expanding %q", c.dstPath) + return trace.Wrap(err) } } return nil } +// PathExpansionError is an [error] indicating that +// path expansion was rejected. +type PathExpansionError struct { + path string +} + +func (p PathExpansionError) Error() string { + return fmt.Sprintf("expanding remote ~user paths is not supported, specify an absolute path instead of %q", p.path) +} + func expandPath(pathStr string) (string, error) { pfxLen, ok := homeDirPrefixLen(pathStr) if !ok { @@ -360,7 +370,7 @@ func expandPath(pathStr string) (string, error) { return ".", nil } if pfxLen == 1 && len(pathStr) > 1 { - return "", trace.BadParameter("expanding remote ~user paths is not supported, specify an absolute path instead") + return "", trace.Wrap(PathExpansionError{path: pathStr}) } // if an SFTP path is not absolute, it is assumed to start at the user's diff --git a/lib/sshutils/sftp/sftp_test.go b/lib/sshutils/sftp/sftp_test.go index 7be2b5ae0f9ab..85e203d3cbdab 100644 --- a/lib/sshutils/sftp/sftp_test.go +++ b/lib/sshutils/sftp/sftp_test.go @@ -34,7 +34,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/gravitational/trace" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/lib/utils" @@ -585,7 +584,7 @@ func TestHomeDirExpansion(t *testing.T) { name: "~user path", path: "~user/foo", errCheck: func(t require.TestingT, err error, i ...interface{}) { - require.True(t, trace.IsBadParameter(err)) + require.ErrorIs(t, err, PathExpansionError{path: "~user/foo"}) }, }, } From 51890cd4d87fe178e020fa4c3ee277225dd12c72 Mon Sep 17 00:00:00 2001 From: Noah Stride Date: Thu, 30 Jan 2025 17:14:43 +0000 Subject: [PATCH 18/27] [v17] Track usage by BotInstanceID (#51540) (#51658) * Track usage by BotInstanceID (#51540) * Add BotInstanceActivitySupport to usage reporting * Wire BotInstanceActivityReport into submitter * Share userActivityLock * Add test for bot instance * TestBotInstanceActivityReportSplitting * Use 15minute interval rather than hourly * Switch to compound key for botInstanceActivity map * ADjust lolck name * Regen --- gen/proto/go/prehog/v1/teleport.pb.go | 398 ++- gen/proto/go/prehog/v1alpha/teleport.pb.go | 3006 +++++++++-------- gen/proto/ts/prehog/v1/teleport_pb.ts | 265 +- gen/proto/ts/prehog/v1alpha/teleport_pb.ts | 50 +- lib/auth/auth.go | 1 + .../teleport/aggregating/reporter.go | 109 +- .../teleport/aggregating/reporter_test.go | 111 + .../teleport/aggregating/service.go | 125 +- .../teleport/aggregating/service_test.go | 31 +- .../teleport/aggregating/submitter.go | 36 +- lib/usagereporter/teleport/audit.go | 14 +- lib/usagereporter/teleport/types.go | 45 +- proto/prehog/v1/teleport.proto | 53 + proto/prehog/v1alpha/teleport.proto | 10 + 14 files changed, 2641 insertions(+), 1613 deletions(-) diff --git a/gen/proto/go/prehog/v1/teleport.pb.go b/gen/proto/go/prehog/v1/teleport.pb.go index 2705157164020..10618add2594d 100644 --- a/gen/proto/go/prehog/v1/teleport.pb.go +++ b/gen/proto/go/prehog/v1/teleport.pb.go @@ -619,6 +619,190 @@ func (x *ResourceKindPresenceReport) GetResourceIds() []uint64 { return nil } +// counters for bot instance activity coming from a specific auth server from a +// specific cluster. +// +// PostHog event: tp.bot_instance.activity +type BotInstanceActivityReport struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // randomly generated UUID for this specific report, 16 bytes (in string order) + // + // PostHog property: tp.report_uuid (in 8-4-4-4-12 string form) + ReportUuid []byte `protobuf:"bytes,1,opt,name=report_uuid,json=reportUuid,proto3" json:"report_uuid,omitempty"` + // cluster name, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.cluster_name (in base64) + ClusterName []byte `protobuf:"bytes,2,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` + // hostid of the auth that collected this report, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.reporter_hostid (in base64) + ReporterHostid []byte `protobuf:"bytes,3,opt,name=reporter_hostid,json=reporterHostid,proto3" json:"reporter_hostid,omitempty"` + // beginning of the time window for this data; ending is not specified but is + // intended to be at most 15 minutes + // + // PostHog timestamp (not a property, the ingest time is tp.report_time instead) + StartTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + // one set of counters for each bot instance + // + // PostHog property: tp.records (encoded as a map keyed by anonymized bot + // instance id, not as a list) + Records []*BotInstanceActivityRecord `protobuf:"bytes,5,rep,name=records,proto3" json:"records,omitempty"` +} + +func (x *BotInstanceActivityReport) Reset() { + *x = BotInstanceActivityReport{} + mi := &file_prehog_v1_teleport_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BotInstanceActivityReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BotInstanceActivityReport) ProtoMessage() {} + +func (x *BotInstanceActivityReport) ProtoReflect() protoreflect.Message { + mi := &file_prehog_v1_teleport_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BotInstanceActivityReport.ProtoReflect.Descriptor instead. +func (*BotInstanceActivityReport) Descriptor() ([]byte, []int) { + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{4} +} + +func (x *BotInstanceActivityReport) GetReportUuid() []byte { + if x != nil { + return x.ReportUuid + } + return nil +} + +func (x *BotInstanceActivityReport) GetClusterName() []byte { + if x != nil { + return x.ClusterName + } + return nil +} + +func (x *BotInstanceActivityReport) GetReporterHostid() []byte { + if x != nil { + return x.ReporterHostid + } + return nil +} + +func (x *BotInstanceActivityReport) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *BotInstanceActivityReport) GetRecords() []*BotInstanceActivityRecord { + if x != nil { + return x.Records + } + return nil +} + +// Records the activity for a single bot instance against a specific auth server +// from a specific cluster. +type BotInstanceActivityRecord struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The UUID of the BotInstance, anonymized using HMAC-SHA-256. + BotInstanceId []byte `protobuf:"bytes,1,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` + // The name of the user associated with the BotInstance, + // anonymized using HMAC-SHA-256. + // Enables correlation with the UserActivityRecord for the Bot. + BotUserName []byte `protobuf:"bytes,2,opt,name=bot_user_name,json=botUserName,proto3" json:"bot_user_name,omitempty"` + // counter of bot joins + BotJoins uint64 `protobuf:"varint,3,opt,name=bot_joins,json=botJoins,proto3" json:"bot_joins,omitempty"` + // counter of SPIFFE SVIDs issued + SpiffeSvidsIssued uint64 `protobuf:"varint,4,opt,name=spiffe_svids_issued,json=spiffeSvidsIssued,proto3" json:"spiffe_svids_issued,omitempty"` + // counter of certificates issued for this user + CertificatesIssued uint64 `protobuf:"varint,5,opt,name=certificates_issued,json=certificatesIssued,proto3" json:"certificates_issued,omitempty"` +} + +func (x *BotInstanceActivityRecord) Reset() { + *x = BotInstanceActivityRecord{} + mi := &file_prehog_v1_teleport_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BotInstanceActivityRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BotInstanceActivityRecord) ProtoMessage() {} + +func (x *BotInstanceActivityRecord) ProtoReflect() protoreflect.Message { + mi := &file_prehog_v1_teleport_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BotInstanceActivityRecord.ProtoReflect.Descriptor instead. +func (*BotInstanceActivityRecord) Descriptor() ([]byte, []int) { + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{5} +} + +func (x *BotInstanceActivityRecord) GetBotInstanceId() []byte { + if x != nil { + return x.BotInstanceId + } + return nil +} + +func (x *BotInstanceActivityRecord) GetBotUserName() []byte { + if x != nil { + return x.BotUserName + } + return nil +} + +func (x *BotInstanceActivityRecord) GetBotJoins() uint64 { + if x != nil { + return x.BotJoins + } + return 0 +} + +func (x *BotInstanceActivityRecord) GetSpiffeSvidsIssued() uint64 { + if x != nil { + return x.SpiffeSvidsIssued + } + return 0 +} + +func (x *BotInstanceActivityRecord) GetCertificatesIssued() uint64 { + if x != nil { + return x.CertificatesIssued + } + return 0 +} + type SubmitUsageReportsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -630,11 +814,13 @@ type SubmitUsageReportsRequest struct { UserActivity []*UserActivityReport `protobuf:"bytes,1,rep,name=user_activity,json=userActivity,proto3" json:"user_activity,omitempty"` // encoded as a separate tp.resource.counts PostHog event ResourcePresence []*ResourcePresenceReport `protobuf:"bytes,2,rep,name=resource_presence,json=resourcePresence,proto3" json:"resource_presence,omitempty"` + // encoded as a seperate tp.bot_instance.activity PostHog event + BotInstanceActivity []*BotInstanceActivityReport `protobuf:"bytes,3,rep,name=bot_instance_activity,json=botInstanceActivity,proto3" json:"bot_instance_activity,omitempty"` } func (x *SubmitUsageReportsRequest) Reset() { *x = SubmitUsageReportsRequest{} - mi := &file_prehog_v1_teleport_proto_msgTypes[4] + mi := &file_prehog_v1_teleport_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -646,7 +832,7 @@ func (x *SubmitUsageReportsRequest) String() string { func (*SubmitUsageReportsRequest) ProtoMessage() {} func (x *SubmitUsageReportsRequest) ProtoReflect() protoreflect.Message { - mi := &file_prehog_v1_teleport_proto_msgTypes[4] + mi := &file_prehog_v1_teleport_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -659,7 +845,7 @@ func (x *SubmitUsageReportsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitUsageReportsRequest.ProtoReflect.Descriptor instead. func (*SubmitUsageReportsRequest) Descriptor() ([]byte, []int) { - return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{4} + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{6} } func (x *SubmitUsageReportsRequest) GetUserActivity() []*UserActivityReport { @@ -676,6 +862,13 @@ func (x *SubmitUsageReportsRequest) GetResourcePresence() []*ResourcePresenceRep return nil } +func (x *SubmitUsageReportsRequest) GetBotInstanceActivity() []*BotInstanceActivityReport { + if x != nil { + return x.BotInstanceActivity + } + return nil +} + type SubmitUsageReportsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -689,7 +882,7 @@ type SubmitUsageReportsResponse struct { func (x *SubmitUsageReportsResponse) Reset() { *x = SubmitUsageReportsResponse{} - mi := &file_prehog_v1_teleport_proto_msgTypes[5] + mi := &file_prehog_v1_teleport_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -701,7 +894,7 @@ func (x *SubmitUsageReportsResponse) String() string { func (*SubmitUsageReportsResponse) ProtoMessage() {} func (x *SubmitUsageReportsResponse) ProtoReflect() protoreflect.Message { - mi := &file_prehog_v1_teleport_proto_msgTypes[5] + mi := &file_prehog_v1_teleport_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -714,7 +907,7 @@ func (x *SubmitUsageReportsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitUsageReportsResponse.ProtoReflect.Descriptor instead. func (*SubmitUsageReportsResponse) Descriptor() ([]byte, []int) { - return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{5} + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{7} } func (x *SubmitUsageReportsResponse) GetBatchUuid() []byte { @@ -815,63 +1008,99 @@ var file_prehog_v1_teleport_proto_rawDesc = []byte{ 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x06, - 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0xaf, 0x01, - 0x0a, 0x19, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0d, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, - 0x4e, 0x0a, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x73, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, - 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x10, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x22, - 0x3b, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x55, 0x75, 0x69, 0x64, 0x2a, 0x4d, 0x0a, 0x08, - 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, + 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0x83, 0x02, + 0x0a, 0x19, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x73, 0x74, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 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, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x2e, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x19, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6f, 0x74, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x62, 0x6f, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x62, 0x6f, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x62, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x70, + 0x69, 0x66, 0x66, 0x65, 0x5f, 0x73, 0x76, 0x69, 0x64, 0x73, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x53, + 0x76, 0x69, 0x64, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x22, 0x89, 0x02, 0x0a, 0x19, + 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0d, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x0c, 0x75, 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x4e, 0x0a, + 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, + 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x10, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x58, 0x0a, + 0x15, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x13, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x22, 0x3b, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x75, + 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x55, 0x75, 0x69, 0x64, 0x2a, 0x4d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, + 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x48, 0x55, 0x4d, 0x41, 0x4e, 0x10, 0x01, + 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x42, 0x4f, + 0x54, 0x10, 0x02, 0x2a, 0x87, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x48, 0x55, 0x4d, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x42, 0x4f, 0x54, 0x10, 0x02, 0x2a, 0x87, 0x02, 0x0a, 0x0c, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, - 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, - 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, - 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x03, - 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x21, 0x0a, - 0x1d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x57, - 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x05, - 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x10, 0x06, - 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x5f, 0x45, - 0x49, 0x43, 0x45, 0x10, 0x07, 0x32, 0x7f, 0x0a, 0x18, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x63, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, - 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xa6, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 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, 0x67, 0x65, 0x6e, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, - 0x58, 0x58, 0xaa, 0x02, 0x09, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, - 0x09, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x50, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0a, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, + 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, + 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x5f, + 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, + 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, + 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, + 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x5f, 0x45, 0x49, 0x43, 0x45, 0x10, 0x07, 0x32, 0x7f, 0x0a, + 0x18, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x12, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, + 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, + 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xa6, + 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x41, 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, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x2f, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x50, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x15, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x50, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -887,7 +1116,7 @@ func file_prehog_v1_teleport_proto_rawDescGZIP() []byte { } var file_prehog_v1_teleport_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_prehog_v1_teleport_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_prehog_v1_teleport_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_prehog_v1_teleport_proto_goTypes = []any{ (UserKind)(0), // 0: prehog.v1.UserKind (ResourceKind)(0), // 1: prehog.v1.ResourceKind @@ -895,26 +1124,31 @@ var file_prehog_v1_teleport_proto_goTypes = []any{ (*UserActivityRecord)(nil), // 3: prehog.v1.UserActivityRecord (*ResourcePresenceReport)(nil), // 4: prehog.v1.ResourcePresenceReport (*ResourceKindPresenceReport)(nil), // 5: prehog.v1.ResourceKindPresenceReport - (*SubmitUsageReportsRequest)(nil), // 6: prehog.v1.SubmitUsageReportsRequest - (*SubmitUsageReportsResponse)(nil), // 7: prehog.v1.SubmitUsageReportsResponse - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*BotInstanceActivityReport)(nil), // 6: prehog.v1.BotInstanceActivityReport + (*BotInstanceActivityRecord)(nil), // 7: prehog.v1.BotInstanceActivityRecord + (*SubmitUsageReportsRequest)(nil), // 8: prehog.v1.SubmitUsageReportsRequest + (*SubmitUsageReportsResponse)(nil), // 9: prehog.v1.SubmitUsageReportsResponse + (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp } var file_prehog_v1_teleport_proto_depIdxs = []int32{ - 8, // 0: prehog.v1.UserActivityReport.start_time:type_name -> google.protobuf.Timestamp - 3, // 1: prehog.v1.UserActivityReport.records:type_name -> prehog.v1.UserActivityRecord - 0, // 2: prehog.v1.UserActivityRecord.user_kind:type_name -> prehog.v1.UserKind - 8, // 3: prehog.v1.ResourcePresenceReport.start_time:type_name -> google.protobuf.Timestamp - 5, // 4: prehog.v1.ResourcePresenceReport.resource_kind_reports:type_name -> prehog.v1.ResourceKindPresenceReport - 1, // 5: prehog.v1.ResourceKindPresenceReport.resource_kind:type_name -> prehog.v1.ResourceKind - 2, // 6: prehog.v1.SubmitUsageReportsRequest.user_activity:type_name -> prehog.v1.UserActivityReport - 4, // 7: prehog.v1.SubmitUsageReportsRequest.resource_presence:type_name -> prehog.v1.ResourcePresenceReport - 6, // 8: prehog.v1.TeleportReportingService.SubmitUsageReports:input_type -> prehog.v1.SubmitUsageReportsRequest - 7, // 9: prehog.v1.TeleportReportingService.SubmitUsageReports:output_type -> prehog.v1.SubmitUsageReportsResponse - 9, // [9:10] is the sub-list for method output_type - 8, // [8:9] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 10, // 0: prehog.v1.UserActivityReport.start_time:type_name -> google.protobuf.Timestamp + 3, // 1: prehog.v1.UserActivityReport.records:type_name -> prehog.v1.UserActivityRecord + 0, // 2: prehog.v1.UserActivityRecord.user_kind:type_name -> prehog.v1.UserKind + 10, // 3: prehog.v1.ResourcePresenceReport.start_time:type_name -> google.protobuf.Timestamp + 5, // 4: prehog.v1.ResourcePresenceReport.resource_kind_reports:type_name -> prehog.v1.ResourceKindPresenceReport + 1, // 5: prehog.v1.ResourceKindPresenceReport.resource_kind:type_name -> prehog.v1.ResourceKind + 10, // 6: prehog.v1.BotInstanceActivityReport.start_time:type_name -> google.protobuf.Timestamp + 7, // 7: prehog.v1.BotInstanceActivityReport.records:type_name -> prehog.v1.BotInstanceActivityRecord + 2, // 8: prehog.v1.SubmitUsageReportsRequest.user_activity:type_name -> prehog.v1.UserActivityReport + 4, // 9: prehog.v1.SubmitUsageReportsRequest.resource_presence:type_name -> prehog.v1.ResourcePresenceReport + 6, // 10: prehog.v1.SubmitUsageReportsRequest.bot_instance_activity:type_name -> prehog.v1.BotInstanceActivityReport + 8, // 11: prehog.v1.TeleportReportingService.SubmitUsageReports:input_type -> prehog.v1.SubmitUsageReportsRequest + 9, // 12: prehog.v1.TeleportReportingService.SubmitUsageReports:output_type -> prehog.v1.SubmitUsageReportsResponse + 12, // [12:13] is the sub-list for method output_type + 11, // [11:12] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_prehog_v1_teleport_proto_init() } @@ -928,7 +1162,7 @@ func file_prehog_v1_teleport_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_prehog_v1_teleport_proto_rawDesc, NumEnums: 2, - NumMessages: 6, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/proto/go/prehog/v1alpha/teleport.pb.go b/gen/proto/go/prehog/v1alpha/teleport.pb.go index fc45802f91418..b8a734f93a883 100644 --- a/gen/proto/go/prehog/v1alpha/teleport.pb.go +++ b/gen/proto/go/prehog/v1alpha/teleport.pb.go @@ -1889,6 +1889,9 @@ type UserCertificateIssuedEvent struct { UsageDesktop bool `protobuf:"varint,7,opt,name=usage_desktop,json=usageDesktop,proto3" json:"usage_desktop,omitempty"` // the private key policy associated with these user certificates. PrivateKeyPolicy string `protobuf:"bytes,8,opt,name=private_key_policy,json=privateKeyPolicy,proto3" json:"private_key_policy,omitempty"` + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + BotInstanceId string `protobuf:"bytes,9,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` } func (x *UserCertificateIssuedEvent) Reset() { @@ -1977,6 +1980,13 @@ func (x *UserCertificateIssuedEvent) GetPrivateKeyPolicy() string { return "" } +func (x *UserCertificateIssuedEvent) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + // the issuance of a SPIFFE SVID // // PostHog event: tp.spiffe.svid.issued @@ -2006,6 +2016,9 @@ type SPIFFESVIDIssuedEvent struct { // Type of SVID issued. `x509` or `jwt` // PostHog property: tp.spiffe.svid_type SvidType string `protobuf:"bytes,6,opt,name=svid_type,json=svidType,proto3" json:"svid_type,omitempty"` + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + BotInstanceId string `protobuf:"bytes,7,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` } func (x *SPIFFESVIDIssuedEvent) Reset() { @@ -2080,6 +2093,13 @@ func (x *SPIFFESVIDIssuedEvent) GetSvidType() string { return "" } +func (x *SPIFFESVIDIssuedEvent) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + // UIBannerClickEvent is a usage event sent by the UI when the upgrade // banner is clicked. type UIBannerClickEvent struct { @@ -4207,6 +4227,8 @@ type BotJoinEvent struct { JoinTokenName string `protobuf:"bytes,3,opt,name=join_token_name,json=joinTokenName,proto3" json:"join_token_name,omitempty"` // user_name is the anonymised name of the Bot user. UserName string `protobuf:"bytes,4,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + // bot_instance_id is the anonymized instance id of the bot. + BotInstanceId string `protobuf:"bytes,5,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` } func (x *BotJoinEvent) Reset() { @@ -4267,6 +4289,13 @@ func (x *BotJoinEvent) GetUserName() string { return "" } +func (x *BotJoinEvent) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + // UICreateNewRoleClickEvent is an event that can be triggered during custom role creation type UICreateNewRoleClickEvent struct { state protoimpl.MessageState @@ -9523,7 +9552,7 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = []byte{ 0x0a, 0x17, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x41, 0x70, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xbf, 0x02, + 0x52, 0x0b, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xe7, 0x02, 0x0a, 0x1a, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -9543,23 +9572,28 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = []byte{ 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, - 0xef, 0x01, 0x0a, 0x15, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, 0x73, - 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, - 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, - 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x70, - 0x5f, 0x73, 0x61, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0b, 0x69, 0x70, 0x53, 0x61, 0x6e, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, - 0x0a, 0x0e, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x61, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x64, 0x6e, 0x73, 0x53, 0x61, 0x6e, 0x73, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x76, 0x69, 0x64, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x76, 0x69, 0x64, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x47, 0x0a, 0x12, 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x97, 0x02, 0x0a, 0x15, 0x53, 0x50, 0x49, 0x46, + 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, + 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x70, 0x5f, 0x73, 0x61, 0x6e, 0x73, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x69, 0x70, 0x53, 0x61, 0x6e, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x61, + 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, + 0x64, 0x6e, 0x73, 0x53, 0x61, 0x6e, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x76, 0x69, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x76, 0x69, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, + 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x22, 0x47, 0x0a, 0x12, 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, @@ -9970,7 +10004,7 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = []byte{ 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, - 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x0c, 0x42, 0x6f, 0x74, 0x4a, 0x6f, + 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x0c, 0x42, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, @@ -9979,1520 +10013,1522 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = []byte{ 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x55, 0x49, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x1d, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, - 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x3e, 0x0a, 0x1f, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, - 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x49, 0x0a, 0x2a, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, - 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x5e, 0x0a, 0x18, 0x55, - 0x49, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, - 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, 0x63, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x43, 0x54, 0x41, 0x52, 0x03, 0x63, 0x74, 0x61, 0x22, 0x66, 0x0a, 0x10, 0x4b, - 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x22, 0x38, 0x0a, 0x19, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, + 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x1d, 0x55, 0x49, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, + 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x0a, 0x1f, 0x55, 0x49, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x49, 0x0a, 0x2a, 0x55, 0x49, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, + 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x5e, 0x0a, 0x18, 0x55, 0x49, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, - 0x69, 0x6e, 0x64, 0x22, 0x77, 0x0a, 0x09, 0x53, 0x46, 0x54, 0x50, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, + 0x63, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x43, 0x54, 0x41, 0x52, 0x03, + 0x63, 0x74, 0x61, 0x22, 0x66, 0x0a, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, + 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x77, 0x0a, 0x09, 0x53, + 0x46, 0x54, 0x50, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xcb, 0x03, 0x0a, 0x12, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x68, 0x6f, 0x73, + 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x68, 0x6f, 0x73, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, + 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x6c, 0x69, 0x62, 0x63, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, + 0x6c, 0x69, 0x62, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x12, 0x35, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, + 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x72, 0x63, 0x68, + 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x5f, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, + 0x65, 0x72, 0x22, 0xd2, 0x01, 0x0a, 0x15, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, + 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xf0, 0x01, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x69, + 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, - 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, - 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xcb, 0x03, 0x0a, - 0x12, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, - 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x6f, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, - 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x68, 0x6f, - 0x73, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x67, 0x6c, 0x69, 0x62, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x6c, 0x69, 0x62, 0x63, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x11, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x16, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, - 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x72, 0x22, 0xd2, 0x01, 0x0a, 0x15, 0x41, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, - 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, - 0xf0, 0x01, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, + 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x55, 0x0a, 0x1a, 0x41, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x22, 0x55, 0x0a, 0x1a, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x18, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x11, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x24, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x15, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x18, 0x41, 0x73, - 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xbd, 0x01, - 0x0a, 0x11, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x24, 0x0a, - 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9b, 0x01, + 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, + 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xa4, 0x02, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, + 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x6f, + 0x6c, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x72, + 0x61, 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x12, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1a, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x6c, + 0x65, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, + 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x1b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, + 0x64, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x22, 0xaf, + 0x03, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x19, 0x64, + 0x61, 0x79, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, + 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, + 0x64, 0x61, 0x79, 0x73, 0x50, 0x61, 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x46, 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, 0x04, 0x20, 0x01, 0x28, 0x08, 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, 0x38, 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, 0x05, 0x20, 0x01, 0x28, 0x08, 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, 0x3c, 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, 0x06, 0x20, 0x01, 0x28, 0x08, 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, 0x12, 0x39, 0x0a, 0x19, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, + 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x16, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x4f, 0x66, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x22, 0xad, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, + 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x49, 0x64, + 0x22, 0x88, 0x01, 0x0a, 0x1f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, + 0x74, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, + 0x74, 0x73, 0x5f, 0x6e, 0x65, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x73, 0x4e, 0x65, 0x65, 0x64, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x22, 0x83, 0x01, 0x0a, 0x19, + 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x66, 0x0a, 0x1d, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x20, 0x55, 0x49, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x1b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x3f, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xe5, 0x01, 0x0a, 0x1c, 0x55, + 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x39, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x43, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x6c, 0x0a, 0x11, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x79, 0x0a, 0x17, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x11, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0xdd, 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, - 0x69, 0x6e, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x07, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x6f, 0x0a, 0x1d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x1b, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, 0x0a, 0x11, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, + 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0d, 0x6c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x52, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x7a, + 0x0a, 0x1a, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, + 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x4e, 0x0a, 0x15, 0x44, 0x65, + 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x14, 0x54, + 0x41, 0x47, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, - 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, - 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, - 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, - 0xa4, 0x02, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, - 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x41, - 0x0a, 0x1d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, - 0x64, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65, - 0x72, 0x69, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, - 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, - 0x69, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1b, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x22, 0xaf, 0x03, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x19, 0x64, 0x61, 0x79, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x74, - 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x64, 0x61, 0x79, 0x73, 0x50, 0x61, 0x73, 0x74, - 0x4e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x46, 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, 0x04, 0x20, 0x01, 0x28, 0x08, 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, 0x38, 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, 0x05, 0x20, 0x01, 0x28, 0x08, 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, - 0x3c, 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, 0x06, - 0x20, 0x01, 0x28, 0x08, 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, 0x12, 0x39, 0x0a, - 0x19, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x16, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x49, 0x64, 0x22, 0x88, 0x01, 0x0a, 0x1f, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x5f, 0x6e, 0x65, 0x65, 0x64, 0x5f, - 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4e, 0x65, 0x65, 0x64, 0x52, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x22, 0x83, 0x01, 0x0a, 0x19, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x39, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x66, 0x0a, 0x1d, 0x55, 0x49, 0x49, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x22, 0x69, 0x0a, 0x20, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x1b, - 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3f, 0x0a, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0xe5, 0x01, 0x0a, 0x1c, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x04, 0x73, 0x74, - 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x52, - 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x6c, 0x0a, 0x11, 0x45, 0x64, - 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, - 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x79, 0x0a, 0x17, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, - 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0xdd, - 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x66, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x52, 0x07, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x6f, 0x0a, - 0x1d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x1b, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, - 0x0a, 0x11, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0d, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, - 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x7a, 0x0a, 0x1a, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, - 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, - 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x4e, 0x0a, 0x15, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, - 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, - 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, - 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x63, 0x0a, 0x29, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, - 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, - 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x8d, - 0x01, 0x0a, 0x29, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x87, - 0x01, 0x0a, 0x1a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, - 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, - 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0xe8, 0x03, 0x0a, 0x17, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x57, 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x63, - 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x63, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x45, 0x6b, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, - 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x52, 0x64, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x28, - 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x33, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, - 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, - 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x61, 0x6d, - 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, - 0x69, 0x64, 0x63, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x21, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x24, 0x55, 0x49, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, - 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, - 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x22, 0x0a, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x27, 0x0a, 0x25, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0x63, 0x0a, 0x1c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, - 0x64, 0x61, 0x79, 0x73, 0x22, 0x64, 0x0a, 0x12, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x61, 0x0a, 0x13, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x75, 0x64, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x02, - 0x0a, 0x17, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, - 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x41, 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6e, 0x75, - 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, - 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x07, 0x6e, 0x75, 0x6d, 0x41, 0x70, 0x70, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, - 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x72, - 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x52, - 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, - 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x35, - 0x0a, 0x17, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x14, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x18, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, - 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, - 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0xe0, 0x01, 0x0a, 0x22, 0x44, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, - 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x14, 0x6e, 0x75, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x75, 0x0a, 0x1b, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0xa7, 0x50, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, - 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x73, 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x53, 0x4f, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x73, 0x73, 0x6f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x4e, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x4c, 0x0a, - 0x0f, 0x75, 0x69, 0x5f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x69, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, 0x0a, 0x29, - 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x5f, 0x67, 0x6f, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x47, 0x6f, 0x54, 0x6f, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, - 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, 0x69, 0x4f, - 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x6f, - 0x54, 0x6f, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6c, 0x69, 0x63, 0x6b, - 0x12, 0x82, 0x01, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, - 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, + 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, + 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x63, 0x0a, 0x29, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x17, + 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x29, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, + 0x6e, 0x53, 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, + 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x1a, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x22, 0xe8, 0x03, 0x0a, 0x17, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x41, 0x57, 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x63, 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x45, 0x63, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x6f, 0x6c, 0x65, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x6b, 0x73, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x72, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x64, 0x73, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x73, 0x33, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, + 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x61, 0x6d, 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x69, 0x64, 0x63, + 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, 0x69, 0x64, 0x63, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x21, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x96, 0x01, 0x0a, 0x24, 0x55, 0x49, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x44, 0x69, 0x66, + 0x66, 0x56, 0x69, 0x65, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x22, 0x0a, 0x20, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, + 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x27, + 0x0a, 0x25, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x63, 0x0a, 0x1c, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x22, 0x64, 0x0a, 0x12, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, + 0x61, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x22, 0x61, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, + 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x02, 0x0a, 0x17, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x41, + 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x75, 0x6d, + 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6e, 0x75, 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x70, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, 0x75, 0x6d, 0x41, 0x70, 0x70, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, + 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x17, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x9e, 0x01, + 0x0a, 0x18, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0xe0, + 0x01, 0x0a, 0x22, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x6e, + 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x6e, 0x75, 0x6d, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x75, 0x0a, 0x1b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x55, 0x73, 0x65, + 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x69, 0x73, 0x73, 0x75, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa7, 0x50, 0x0a, 0x12, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, + 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x73, + 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, - 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, - 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, - 0x69, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, - 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4c, 0x61, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, - 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x72, 0x65, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x53, - 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x87, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x6f, - 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, - 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, + 0x53, 0x53, 0x4f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x09, 0x73, 0x73, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x4e, 0x0a, 0x0f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x0d, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x4c, 0x0a, 0x0f, 0x75, 0x69, 0x5f, 0x62, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x69, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, + 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x67, 0x6f, 0x5f, 0x74, + 0x6f, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x6f, 0x54, 0x6f, 0x44, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x6f, 0x54, 0x6f, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x82, 0x01, 0x0a, 0x23, 0x75, 0x69, 0x5f, + 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, - 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x20, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, - 0x74, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, - 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, - 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, - 0x69, 0x6e, 0x75, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x1c, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x6f, - 0x0a, 0x1c, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, - 0x72, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, 0x69, 0x63, - 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x19, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, - 0x69, 0x63, 0x6b, 0x12, 0x63, 0x0a, 0x19, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x16, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6f, 0x0a, - 0x1d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x13, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x1a, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x4d, - 0x0a, 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, - 0x76, 0x32, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x56, 0x32, 0x12, 0x76, 0x0a, - 0x20, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7f, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x8f, 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, + 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, + 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, + 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x64, 0x64, + 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, + 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x74, 0x65, + 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, + 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, + 0x63, 0x6b, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, + 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, + 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x74, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, + 0x87, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, 0x5f, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, + 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x43, 0x6c, 0x69, 0x63, + 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x6f, 0x0a, 0x1c, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x79, + 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, + 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x70, + 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, + 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, + 0x70, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x72, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x72, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x50, + 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x19, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, + 0x73, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x63, 0x0a, 0x19, 0x75, + 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6f, 0x0a, 0x1d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, + 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x75, 0x73, 0x65, 0x72, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x76, 0x32, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x56, 0x32, 0x12, 0x76, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7f, 0x0a, + 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x4d, 0x54, 0x4c, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x24, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x8f, + 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x65, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x4d, - 0x74, 0x6c, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0xb8, 0x01, 0x0a, 0x38, 0x75, 0x69, 0x5f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, - 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x6f, - 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x31, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, - 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0xae, 0x01, 0x0a, 0x34, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x2e, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x95, 0x01, 0x0a, 0x2b, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x70, 0x72, 0x65, + 0x54, 0x4c, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x75, 0x69, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x4d, 0x74, 0x6c, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0xb8, 0x01, 0x0a, 0x38, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, + 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x31, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0xae, 0x01, 0x0a, 0x34, + 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x6b, + 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x41, 0x75, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x26, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x41, 0x75, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x9f, 0x01, 0x0a, - 0x2f, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, - 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x65, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x29, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, - 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x88, - 0x01, 0x0a, 0x26, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x70, - 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, - 0x69, 0x70, 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x22, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x79, 0x0a, 0x21, 0x75, 0x69, 0x5f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x69, 0x0a, 0x1b, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x42, 0x0a, 0x0b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x1f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x63, 0x0a, 0x18, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, - 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, - 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, - 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x70, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x73, - 0x61, 0x76, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, - 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x18, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, - 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x76, 0x0a, 0x1f, 0x75, 0x69, - 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, - 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x22, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, - 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, - 0x63, 0x6b, 0x12, 0x98, 0x01, 0x0a, 0x2b, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, - 0x63, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x25, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x45, 0x0a, - 0x0c, 0x6b, 0x75, 0x62, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x24, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x66, 0x74, 0x70, 0x18, 0x25, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x53, 0x46, 0x54, 0x50, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x04, 0x73, 0x66, 0x74, 0x70, 0x12, 0x56, 0x0a, 0x14, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x26, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x57, 0x0a, - 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, - 0x65, 0x61, 0x74, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, - 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x9c, 0x01, 0x0a, 0x2e, 0x75, 0x69, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x28, 0x75, 0x69, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x41, 0x77, 0x73, 0x4f, 0x69, 0x64, 0x63, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x83, 0x01, 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, - 0x64, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, - 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x44, 0x53, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x64, 0x73, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6b, 0x0a, 0x1d, 0x75, - 0x69, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, - 0x75, 0x69, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, - 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x54, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, - 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2b, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x73, - 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x79, - 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x75, 0x69, 0x49, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, - 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, - 0x0a, 0x13, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x69, - 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x11, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x62, 0x6f, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x42, 0x6f, 0x74, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x74, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x12, 0x7a, 0x0a, 0x1f, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, - 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x2e, 0x75, 0x69, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x95, 0x01, 0x0a, + 0x2b, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x75, 0x74, + 0x6f, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x41, 0x75, + 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x26, 0x75, 0x69, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x41, 0x75, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x9f, 0x01, 0x0a, 0x2f, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x49, 0x41, 0x4d, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x29, 0x75, 0x69, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x88, 0x01, 0x0a, 0x26, 0x75, 0x69, 0x5f, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, + 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x22, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, + 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x79, 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x5f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x69, 0x0a, 0x1b, + 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x0b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x6f, + 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0a, 0x72, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x63, 0x0a, 0x18, 0x75, + 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, - 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, - 0x6e, 0x61, 0x69, 0x72, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x51, 0x75, 0x65, - 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x12, 0x39, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x31, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x42, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x51, 0x0a, 0x10, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x64, - 0x0a, 0x17, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x19, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x17, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6e, 0x0a, 0x1c, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1a, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x5e, 0x0a, 0x15, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, + 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, + 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, + 0x12, 0x70, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, + 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x73, 0x61, 0x76, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, + 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, + 0x63, 0x6b, 0x12, 0x76, 0x0a, 0x1f, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, + 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, + 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x98, 0x01, 0x0a, 0x2b, 0x75, + 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, + 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x25, + 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, + 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x45, 0x0a, 0x0c, 0x6b, 0x75, 0x62, 0x65, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4b, 0x75, 0x62, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0b, 0x6b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x04, + 0x73, 0x66, 0x74, 0x70, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x46, 0x54, 0x50, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x66, 0x74, 0x70, 0x12, 0x56, 0x0a, + 0x14, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x12, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x57, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x27, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, + 0x62, 0x65, 0x61, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x9c, + 0x01, 0x0a, 0x2e, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x6f, + 0x69, 0x64, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x57, + 0x53, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x28, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x77, 0x73, 0x4f, 0x69, 0x64, + 0x63, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x83, 0x01, + 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x64, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, + 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x52, 0x44, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x64, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x6b, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x74, + 0x6f, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x61, + 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x54, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x79, 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2c, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x1d, 0x75, 0x69, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x13, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x62, + 0x6f, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x42, 0x6f, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x09, 0x62, 0x6f, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x7a, 0x0a, 0x1f, + 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, + 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, + 0x72, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x39, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, + 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x31, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x42, 0x6f, 0x74, 0x4a, + 0x6f, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4a, + 0x6f, 0x69, 0x6e, 0x12, 0x51, 0x0a, 0x10, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x64, 0x0a, 0x17, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, + 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x19, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x6e, 0x0a, 0x1c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, + 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x5e, 0x0a, 0x15, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x36, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x37, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, - 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x37, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x13, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, - 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x38, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x13, 0x6c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x6c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x3b, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x55, 0x0a, - 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0c, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, + 0x13, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x13, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x3a, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x55, + 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x68, - 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x12, 0x69, 0x0a, 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x73, 0x65, 0x72, - 0x18, 0x40, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x12, 0x81, 0x01, - 0x0a, 0x22, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x63, - 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x41, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x72, 0x65, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x3f, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x69, 0x0a, 0x1a, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x40, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, + 0x6f, 0x55, 0x73, 0x65, 0x72, 0x12, 0x81, 0x01, 0x0a, 0x22, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x63, 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x41, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x43, + 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x63, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x62, 0x0a, 0x17, 0x75, 0x69, 0x5f, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, + 0x65, 0x69, 0x63, 0x65, 0x18, 0x42, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x43, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x1e, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x63, 0x32, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x62, 0x0a, 0x17, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x65, 0x69, 0x63, 0x65, 0x18, 0x42, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x45, 0x49, 0x43, 0x45, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x14, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x45, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x17, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, - 0x18, 0x43, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x64, 0x0a, 0x17, 0x64, 0x65, 0x73, - 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, - 0x68, 0x61, 0x72, 0x65, 0x18, 0x44, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x6b, - 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, - 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, - 0x65, 0x0a, 0x1a, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x45, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x64, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x11, 0x74, 0x61, 0x67, 0x5f, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x46, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x54, 0x41, 0x47, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x74, 0x61, 0x67, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x86, 0x01, 0x0a, 0x23, 0x65, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x18, 0x47, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x6b, 0x0a, 0x1a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x18, 0x48, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x12, 0x4c, 0x0a, 0x0f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x18, 0x49, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0d, 0x61, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x59, - 0x0a, 0x15, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x66, 0x65, 0x74, 0x63, - 0x68, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, - 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x4b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x18, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x74, 0x0a, - 0x1d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x4d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x18, 0x6d, 0x66, 0x61, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, - 0x4e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4d, 0x46, 0x41, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x16, 0x6d, 0x66, 0x61, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x55, 0x0a, 0x12, 0x73, 0x70, 0x69, 0x66, 0x66, - 0x65, 0x5f, 0x73, 0x76, 0x69, 0x64, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x18, 0x4f, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, - 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x73, 0x70, - 0x69, 0x66, 0x66, 0x65, 0x53, 0x76, 0x69, 0x64, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x5c, - 0x0a, 0x15, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4f, - 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, - 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x5e, 0x0a, 0x15, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x51, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x7f, 0x0a, 0x21, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x52, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x84, 0x01, - 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x53, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x77, 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x65, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x54, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x45, 0x49, 0x43, 0x45, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x45, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, + 0x17, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x43, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x12, 0x64, 0x0a, 0x17, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x44, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x15, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, 0x65, 0x0a, 0x1a, 0x64, 0x65, 0x73, 0x6b, 0x74, + 0x6f, 0x70, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x45, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, + 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, + 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x52, + 0x0a, 0x11, 0x74, 0x61, 0x67, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x54, 0x41, 0x47, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x0f, 0x74, 0x61, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x86, 0x01, 0x0a, 0x23, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, + 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x61, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x47, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x35, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x6b, 0x0a, 0x1a, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x67, + 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x48, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, - 0x4b, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, - 0x6b, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7d, 0x0a, - 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x55, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x18, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x67, 0x69, 0x74, - 0x6c, 0x61, 0x62, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x18, 0x56, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, + 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x17, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x4c, 0x0a, 0x0f, 0x61, 0x75, 0x64, 0x69, + 0x74, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x49, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x59, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, + 0x4a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x4b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, - 0x62, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, - 0x63, 0x61, 0x6e, 0x12, 0x94, 0x01, 0x0a, 0x29, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, - 0x6e, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x57, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x2a, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x74, 0x0a, 0x1d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x4d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x18, 0x6d, + 0x66, 0x61, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x4e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4d, + 0x46, 0x41, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x6d, 0x66, 0x61, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x55, 0x0a, 0x12, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x73, 0x76, 0x69, 0x64, 0x5f, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x64, 0x18, 0x4f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x50, 0x49, + 0x46, 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x53, 0x76, 0x69, 0x64, + 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x15, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, + 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x12, 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x79, 0x6e, 0x63, 0x12, 0x5e, 0x0a, 0x15, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x51, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x13, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x7f, 0x0a, 0x21, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x52, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x84, 0x01, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x53, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x77, 0x0a, 0x21, + 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x75, 0x62, 0x65, + 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x54, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, 0x4b, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, 0x6b, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7d, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x55, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x18, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x5f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x5f, 0x73, 0x63, 0x61, 0x6e, + 0x18, 0x56, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x94, 0x01, 0x0a, 0x29, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x57, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, + 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x64, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, - 0x53, 0x63, 0x61, 0x6e, 0x53, 0x73, 0x68, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x5c, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x18, 0x59, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x57, - 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x77, 0x73, 0x53, 0x63, 0x61, 0x6e, - 0x12, 0x7b, 0x0a, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, - 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x78, 0x0a, - 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, - 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1b, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, - 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, 0x6f, 0x77, - 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x76, 0x69, 0x65, - 0x77, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, - 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1f, 0x75, 0x69, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, + 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, + 0x79, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x2a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, + 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, + 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x73, 0x68, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x5c, 0x0a, 0x15, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x73, + 0x63, 0x61, 0x6e, 0x18, 0x59, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x57, 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x41, 0x77, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x7b, 0x0a, 0x20, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x5a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x78, 0x0a, 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, + 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, + 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x1b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, + 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, + 0x86, 0x01, 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x5f, + 0x64, 0x69, 0x66, 0x66, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x55, 0x49, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, - 0x12, 0x67, 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x5d, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a, 0x0f, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x5e, 0x20, 0x01, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, + 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, 0x12, 0x67, 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x4c, 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x76, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x18, 0x60, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, + 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x49, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, + 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x52, 0x1c, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x13, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x54, 0x61, - 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x76, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x60, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x1c, 0x75, 0x69, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, - 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x52, 0x1c, - 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x15, 0x0a, 0x13, - 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, - 0x0a, 0x14, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, - 0x87, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, - 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, 0x5f, 0x53, 0x45, 0x52, - 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, - 0x45, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, - 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, - 0x4f, 0x50, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, - 0x53, 0x48, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, - 0x53, 0x48, 0x5f, 0x45, 0x49, 0x43, 0x45, 0x10, 0x07, 0x2a, 0x4d, 0x0a, 0x08, 0x55, 0x73, 0x65, - 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x48, 0x55, - 0x4d, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x42, 0x4f, 0x54, 0x10, 0x02, 0x2a, 0xc0, 0x0f, 0x0a, 0x10, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x0a, - 0x1d, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, - 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x01, 0x12, 0x20, - 0x0a, 0x1c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x02, - 0x12, 0x33, 0x0a, 0x2f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, - 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, - 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, - 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, - 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, - 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x53, 0x45, - 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x05, 0x12, 0x2b, 0x0a, 0x27, 0x44, - 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, - 0x45, 0x53, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x06, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, + 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x16, + 0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, + 0x0a, 0x15, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x87, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, + 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x41, 0x50, 0x50, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, + 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4b, + 0x55, 0x42, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x42, + 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, + 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, + 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, + 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x5f, 0x45, 0x49, 0x43, 0x45, 0x10, + 0x07, 0x2a, 0x4d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, + 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x48, 0x55, 0x4d, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, + 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x42, 0x4f, 0x54, 0x10, 0x02, + 0x2a, 0xc0, 0x0f, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, + 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, + 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x02, 0x12, 0x33, 0x0a, 0x2f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x52, 0x44, 0x53, - 0x10, 0x07, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x08, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, + 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x30, 0x0a, + 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, + 0x4c, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, + 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x4f, + 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, + 0x44, 0x10, 0x05, 0x12, 0x2b, 0x0a, 0x27, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, + 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x06, + 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, + 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x07, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x43, 0x50, 0x10, - 0x09, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, - 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x0a, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x52, 0x44, 0x53, 0x10, 0x0b, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x54, 0x54, 0x50, + 0x10, 0x08, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x09, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, + 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x0a, + 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, + 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x0b, 0x12, 0x30, + 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, + 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x44, 0x53, 0x48, 0x49, 0x46, 0x54, 0x10, 0x0c, + 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, + 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, + 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, - 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, - 0x44, 0x53, 0x48, 0x49, 0x46, 0x54, 0x10, 0x0c, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, + 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x2b, 0x0a, 0x27, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x30, - 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, - 0x49, 0x53, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0e, - 0x12, 0x2b, 0x0a, 0x27, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, - 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x0f, 0x12, 0x28, 0x0a, - 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, - 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, - 0x4c, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x10, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, - 0x47, 0x43, 0x50, 0x10, 0x11, 0x12, 0x3b, 0x0a, 0x37, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, + 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, + 0x47, 0x43, 0x50, 0x10, 0x0f, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, - 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x44, - 0x53, 0x48, 0x49, 0x46, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, - 0x10, 0x12, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, - 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, - 0x13, 0x12, 0x27, 0x0a, 0x23, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x4f, 0x44, 0x42, 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, + 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x10, 0x12, + 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, + 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x11, 0x12, 0x3b, 0x0a, + 0x37, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, + 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x44, 0x53, 0x48, 0x49, 0x46, 0x54, 0x5f, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x12, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x53, 0x53, 0x41, 0x4e, 0x44, - 0x52, 0x41, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x50, 0x41, 0x43, 0x45, 0x53, 0x10, 0x15, 0x12, 0x34, - 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x53, - 0x53, 0x41, 0x4e, 0x44, 0x52, 0x41, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, - 0x45, 0x44, 0x10, 0x16, 0x12, 0x38, 0x0a, 0x34, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, - 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, - 0x53, 0x45, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, 0x49, 0x43, 0x53, 0x45, 0x41, 0x52, 0x43, 0x48, - 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x17, 0x12, 0x30, - 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, - 0x49, 0x53, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, 0x49, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x18, - 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, - 0x45, 0x44, 0x49, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x44, 0x42, 0x10, 0x19, 0x12, - 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, - 0x44, 0x49, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, - 0x1a, 0x12, 0x38, 0x0a, 0x34, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, - 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x2a, 0x0a, 0x26, 0x44, - 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, - 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1c, 0x12, 0x2e, 0x0a, 0x2a, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, - 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1d, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, + 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x13, 0x12, 0x27, 0x0a, 0x23, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x4f, 0x44, 0x42, + 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, + 0x5f, 0x43, 0x41, 0x53, 0x53, 0x41, 0x4e, 0x44, 0x52, 0x41, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x50, + 0x41, 0x43, 0x45, 0x53, 0x10, 0x15, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x53, 0x53, 0x41, 0x4e, 0x44, 0x52, 0x41, 0x5f, 0x53, + 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x16, 0x12, 0x38, 0x0a, 0x34, + 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, + 0x49, 0x43, 0x53, 0x45, 0x41, 0x52, 0x43, 0x48, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, + 0x53, 0x54, 0x45, 0x44, 0x10, 0x17, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, + 0x49, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x18, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, + 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x4d, 0x45, 0x4d, + 0x4f, 0x52, 0x59, 0x44, 0x42, 0x10, 0x19, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, - 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x10, 0x1e, 0x12, 0x36, 0x0a, 0x32, 0x44, - 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x43, 0x4b, 0x52, 0x4f, - 0x41, 0x43, 0x48, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, - 0x44, 0x10, 0x1f, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, + 0x45, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x1a, 0x12, 0x38, 0x0a, 0x34, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x43, 0x4c, + 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, + 0x44, 0x10, 0x1b, 0x12, 0x2a, 0x0a, 0x26, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, + 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1c, 0x12, + 0x2e, 0x0a, 0x2a, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, + 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1d, 0x12, + 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, + 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, + 0x54, 0x10, 0x1e, 0x12, 0x36, 0x0a, 0x32, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, - 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x41, 0x54, 0x4c, 0x41, 0x53, 0x10, - 0x20, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x53, 0x4e, 0x4f, 0x57, 0x46, 0x4c, 0x41, 0x4b, 0x45, 0x10, 0x21, 0x12, 0x2c, 0x0a, 0x28, 0x44, + 0x45, 0x5f, 0x43, 0x4f, 0x43, 0x4b, 0x52, 0x4f, 0x41, 0x43, 0x48, 0x44, 0x42, 0x5f, 0x53, 0x45, + 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x1f, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x44, - 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, 0x22, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, + 0x42, 0x5f, 0x41, 0x54, 0x4c, 0x41, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, - 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, - 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x23, 0x12, - 0x37, 0x0a, 0x33, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, - 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, - 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x24, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x41, - 0x4d, 0x4c, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x25, - 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x43, 0x32, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, - 0x43, 0x45, 0x10, 0x26, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, - 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x57, 0x49, - 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x5f, 0x4e, 0x4f, - 0x4e, 0x5f, 0x41, 0x44, 0x10, 0x27, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, - 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, - 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x5f, 0x45, 0x4b, 0x53, 0x10, 0x28, 0x12, 0x2d, 0x0a, 0x29, + 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x46, 0x4c, 0x41, 0x4b, + 0x45, 0x10, 0x21, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x44, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, + 0x22, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, + 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, + 0x41, 0x53, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, + 0x49, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x23, 0x12, 0x37, 0x0a, 0x33, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, + 0x43, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x24, + 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x41, 0x4d, 0x4c, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x25, 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x43, + 0x32, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x26, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x57, - 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x10, 0x29, 0x2a, 0xa3, 0x01, 0x0a, 0x0e, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, - 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, + 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, + 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x10, 0x27, 0x12, 0x24, + 0x0a, 0x20, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x5f, 0x45, + 0x4b, 0x53, 0x10, 0x28, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, + 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, + 0x45, 0x10, 0x29, 0x2a, 0xa3, 0x01, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, - 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, - 0x04, 0x2a, 0xd4, 0x02, 0x0a, 0x03, 0x43, 0x54, 0x41, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x54, 0x41, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, - 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, - 0x43, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x56, 0x45, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x02, 0x12, - 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x52, 0x45, - 0x51, 0x55, 0x45, 0x53, 0x54, 0x53, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, - 0x50, 0x52, 0x45, 0x4d, 0x49, 0x55, 0x4d, 0x5f, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x10, - 0x04, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, - 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, - 0x41, 0x5f, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, 0x45, 0x5f, 0x42, 0x41, 0x4e, 0x4e, 0x45, 0x52, - 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, - 0x47, 0x5f, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x43, - 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, - 0x12, 0x19, 0x0a, 0x15, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4d, - 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x1e, 0x0a, 0x1a, 0x43, - 0x54, 0x41, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x41, 0x55, 0x44, 0x49, - 0x54, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x43, - 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x59, 0x4e, - 0x43, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x54, 0x41, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, - 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, - 0x41, 0x5f, 0x53, 0x43, 0x49, 0x4d, 0x10, 0x0d, 0x2a, 0x94, 0x09, 0x0a, 0x15, 0x49, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4b, 0x69, - 0x6e, 0x64, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x10, 0x01, 0x12, 0x24, - 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, - 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x4f, 0x49, - 0x44, 0x43, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x50, 0x41, 0x47, 0x45, 0x52, 0x44, 0x55, 0x54, 0x59, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x45, 0x4d, 0x41, 0x49, 0x4c, 0x10, 0x04, 0x12, 0x20, - 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, - 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4a, 0x49, 0x52, 0x41, 0x10, 0x05, - 0x12, 0x23, 0x0a, 0x1f, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x52, 0x44, 0x10, 0x06, 0x12, 0x26, 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, 0xd4, 0x02, 0x0a, 0x03, 0x43, 0x54, + 0x41, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x54, 0x41, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x55, + 0x54, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x53, 0x45, 0x53, + 0x53, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, + 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x53, 0x10, 0x03, + 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x55, 0x4d, 0x5f, + 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, + 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, + 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, + 0x45, 0x5f, 0x42, 0x41, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, + 0x41, 0x5f, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, + 0x59, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, + 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x54, 0x41, 0x5f, + 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, + 0x47, 0x10, 0x09, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x54, 0x41, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, + 0x4e, 0x41, 0x4c, 0x5f, 0x41, 0x55, 0x44, 0x49, 0x54, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, + 0x45, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x5f, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, + 0x54, 0x41, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x11, 0x0a, + 0x0d, 0x43, 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x5f, 0x53, 0x43, 0x49, 0x4d, 0x10, 0x0d, + 0x2a, 0x94, 0x09, 0x0a, 0x15, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, + 0x4c, 0x41, 0x43, 0x4b, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, + 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, + 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, + 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x52, 0x44, 0x55, 0x54, + 0x59, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x45, + 0x4d, 0x41, 0x49, 0x4c, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, + 0x44, 0x5f, 0x4a, 0x49, 0x52, 0x41, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x49, 0x4e, 0x54, 0x45, + 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, + 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x52, 0x44, 0x10, 0x06, 0x12, 0x26, 0x0a, + 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, + 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4d, + 0x4f, 0x53, 0x54, 0x10, 0x07, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4d, 0x4f, 0x53, 0x54, 0x10, 0x07, 0x12, 0x24, 0x0a, - 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, - 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x53, 0x5f, 0x54, 0x45, 0x41, 0x4d, - 0x53, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, - 0x50, 0x53, 0x47, 0x45, 0x4e, 0x49, 0x45, 0x10, 0x09, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x10, 0x0a, 0x12, 0x20, 0x0a, 0x1c, 0x49, + 0x5f, 0x4d, 0x53, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4a, 0x41, 0x4d, 0x46, 0x10, 0x0b, 0x12, 0x26, 0x0a, - 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, - 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, - 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x35, 0x0a, 0x31, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, 0x50, 0x53, 0x47, 0x45, 0x4e, 0x49, 0x45, 0x10, + 0x09, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, 0x4b, 0x54, + 0x41, 0x10, 0x0a, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4a, + 0x41, 0x4d, 0x46, 0x10, 0x0b, 0x12, 0x26, 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x48, - 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x0d, 0x12, 0x2f, 0x0a, 0x2b, - 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, - 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45, 0x43, 0x49, 0x10, 0x0e, 0x12, 0x2d, 0x0a, - 0x29, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, + 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x35, 0x0a, + 0x31, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, - 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x10, 0x0f, 0x12, 0x2e, 0x0a, 0x2a, - 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, - 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x4a, 0x45, 0x4e, 0x4b, 0x49, 0x4e, 0x53, 0x10, 0x10, 0x12, 0x2e, 0x0a, 0x2a, + 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x53, 0x10, 0x0d, 0x12, 0x2f, 0x0a, 0x2b, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, + 0x45, 0x43, 0x49, 0x10, 0x0e, 0x12, 0x2d, 0x0a, 0x29, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x4c, + 0x41, 0x42, 0x10, 0x0f, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x4a, 0x45, 0x4e, 0x4b, 0x49, + 0x4e, 0x53, 0x10, 0x10, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x4e, 0x53, 0x49, 0x42, + 0x4c, 0x45, 0x10, 0x11, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x10, 0x12, + 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, + 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x13, 0x12, 0x2c, 0x0a, 0x28, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x41, 0x4e, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x11, 0x12, 0x2a, 0x0a, 0x26, + 0x49, 0x44, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x14, 0x12, 0x30, 0x0a, 0x2c, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, + 0x5f, 0x53, 0x50, 0x41, 0x43, 0x45, 0x4c, 0x49, 0x46, 0x54, 0x10, 0x15, 0x12, 0x31, 0x0a, 0x2d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x10, 0x12, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, - 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, - 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, - 0x43, 0x50, 0x10, 0x13, 0x12, 0x2c, 0x0a, 0x28, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, - 0x10, 0x14, 0x12, 0x30, 0x0a, 0x2c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, - 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x50, 0x41, 0x43, 0x45, 0x4c, 0x49, - 0x46, 0x54, 0x10, 0x15, 0x12, 0x31, 0x0a, 0x2d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, - 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x16, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, - 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x5f, 0x49, 0x44, 0x10, 0x17, 0x12, 0x37, 0x0a, - 0x33, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, - 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x44, 0x4f, 0x47, - 0x5f, 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, - 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, + 0x49, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x16, 0x12, + 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, + 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, + 0x5f, 0x49, 0x44, 0x10, 0x17, 0x12, 0x37, 0x0a, 0x33, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x44, 0x4f, 0x47, 0x5f, 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, + 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x18, 0x12, 0x26, + 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, + 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, + 0x45, 0x4e, 0x4f, 0x57, 0x10, 0x19, 0x12, 0x2f, 0x0a, 0x2b, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x4e, 0x4f, 0x57, 0x10, 0x19, 0x12, 0x2f, - 0x0a, 0x2b, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, - 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x49, 0x44, - 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x1a, 0x2a, - 0xa7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x53, 0x54, 0x45, 0x50, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, - 0x53, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x49, 0x44, 0x43, - 0x10, 0x01, 0x12, 0x3e, 0x0a, 0x3a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, - 0x53, 0x49, 0x43, 0x5f, 0x53, 0x45, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x4c, 0x49, - 0x53, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, - 0x10, 0x02, 0x12, 0x3d, 0x0a, 0x39, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, - 0x53, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x53, - 0x41, 0x4d, 0x4c, 0x5f, 0x53, 0x50, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x10, - 0x03, 0x12, 0x36, 0x0a, 0x32, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, - 0x49, 0x43, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x43, 0x49, 0x4d, 0x5f, 0x43, 0x4f, 0x4e, - 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x2a, 0xfb, 0x01, 0x0a, 0x1b, 0x49, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, + 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x43, + 0x45, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x1a, 0x2a, 0xa7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, + 0x70, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x01, 0x12, 0x3e, 0x0a, 0x3a, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x53, 0x45, 0x54, 0x5f, + 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, + 0x4c, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x02, 0x12, 0x3d, 0x0a, 0x39, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x4c, 0x4f, + 0x41, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x53, 0x41, 0x4d, 0x4c, 0x5f, 0x53, 0x50, 0x5f, 0x4d, + 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x10, 0x03, 0x12, 0x36, 0x0a, 0x32, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, - 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, - 0x02, 0x12, 0x28, 0x0a, 0x24, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, + 0x53, 0x43, 0x49, 0x4d, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x04, 0x2a, 0xfb, 0x01, 0x0a, 0x1b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, - 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x2a, 0x0a, 0x26, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x42, - 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, 0x88, 0x01, 0x0a, 0x12, 0x45, 0x64, 0x69, 0x74, - 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, - 0x0a, 0x20, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, - 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, - 0x45, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x45, - 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, - 0x10, 0x02, 0x2a, 0x3f, 0x0a, 0x07, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, - 0x13, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, - 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, - 0x53, 0x10, 0x01, 0x2a, 0xa0, 0x01, 0x0a, 0x1b, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, - 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x29, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, - 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, - 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x26, - 0x0a, 0x22, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, - 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x44, 0x4f, 0x4e, 0x45, 0x10, 0x02, 0x2a, 0x82, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x63, 0x65, 0x6e, - 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x19, 0x4c, 0x49, 0x43, 0x45, 0x4e, - 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x28, 0x0a, 0x24, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, - 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, - 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x5f, 0x4a, 0x41, 0x4d, 0x46, 0x10, 0x01, - 0x12, 0x29, 0x0a, 0x25, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, - 0x54, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, - 0x45, 0x41, 0x4d, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x32, 0xb4, 0x02, 0x0a, 0x18, - 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, - 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x5b, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0d, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, - 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0xc9, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 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, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, - 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xca, 0x02, - 0x0e, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xe2, - 0x02, 0x1a, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, + 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x2a, 0x0a, + 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, + 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, + 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x12, 0x28, 0x0a, 0x24, 0x49, 0x4e, 0x54, + 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x03, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, + 0x88, 0x01, 0x0a, 0x12, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, + 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, + 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, + 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x3f, 0x0a, 0x07, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, + 0x0a, 0x17, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, + 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x10, 0x01, 0x2a, 0xa0, 0x01, 0x0a, 0x1b, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x29, 0x46, + 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x46, 0x45, + 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, + 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x4e, 0x45, 0x10, 0x02, 0x2a, 0x82, + 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, + 0x1d, 0x0a, 0x19, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x28, + 0x0a, 0x24, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, + 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, 0x45, 0x41, + 0x4d, 0x5f, 0x4a, 0x41, 0x4d, 0x46, 0x10, 0x01, 0x12, 0x29, 0x0a, 0x25, 0x4c, 0x49, 0x43, 0x45, + 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, + 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x5f, 0x55, 0x53, 0x41, 0x47, + 0x45, 0x10, 0x02, 0x32, 0xb4, 0x02, 0x0a, 0x18, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x5b, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x5b, 0x0a, + 0x0c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0d, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, + 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xc9, 0x01, 0x0a, 0x12, 0x63, + 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x4b, 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, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x3b, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xa2, + 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xca, 0x02, 0x0e, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xe2, 0x02, 0x1a, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/gen/proto/ts/prehog/v1/teleport_pb.ts b/gen/proto/ts/prehog/v1/teleport_pb.ts index 79f489dabd77c..aa3d941baaad4 100644 --- a/gen/proto/ts/prehog/v1/teleport_pb.ts +++ b/gen/proto/ts/prehog/v1/teleport_pb.ts @@ -253,6 +253,98 @@ export interface ResourceKindPresenceReport { */ resourceIds: bigint[]; } +/** + * counters for bot instance activity coming from a specific auth server from a + * specific cluster. + * + * PostHog event: tp.bot_instance.activity + * + * @generated from protobuf message prehog.v1.BotInstanceActivityReport + */ +export interface BotInstanceActivityReport { + /** + * randomly generated UUID for this specific report, 16 bytes (in string order) + * + * PostHog property: tp.report_uuid (in 8-4-4-4-12 string form) + * + * @generated from protobuf field: bytes report_uuid = 1; + */ + reportUuid: Uint8Array; + /** + * cluster name, anonymized, 32 bytes (HMAC-SHA-256) + * + * PostHog property: tp.cluster_name (in base64) + * + * @generated from protobuf field: bytes cluster_name = 2; + */ + clusterName: Uint8Array; + /** + * hostid of the auth that collected this report, anonymized, 32 bytes (HMAC-SHA-256) + * + * PostHog property: tp.reporter_hostid (in base64) + * + * @generated from protobuf field: bytes reporter_hostid = 3; + */ + reporterHostid: Uint8Array; + /** + * beginning of the time window for this data; ending is not specified but is + * intended to be at most 15 minutes + * + * PostHog timestamp (not a property, the ingest time is tp.report_time instead) + * + * @generated from protobuf field: google.protobuf.Timestamp start_time = 4; + */ + startTime?: Timestamp; + /** + * one set of counters for each bot instance + * + * PostHog property: tp.records (encoded as a map keyed by anonymized bot + * instance id, not as a list) + * + * @generated from protobuf field: repeated prehog.v1.BotInstanceActivityRecord records = 5; + */ + records: BotInstanceActivityRecord[]; +} +/** + * Records the activity for a single bot instance against a specific auth server + * from a specific cluster. + * + * @generated from protobuf message prehog.v1.BotInstanceActivityRecord + */ +export interface BotInstanceActivityRecord { + /** + * The UUID of the BotInstance, anonymized using HMAC-SHA-256. + * + * @generated from protobuf field: bytes bot_instance_id = 1; + */ + botInstanceId: Uint8Array; + /** + * The name of the user associated with the BotInstance, + * anonymized using HMAC-SHA-256. + * Enables correlation with the UserActivityRecord for the Bot. + * + * @generated from protobuf field: bytes bot_user_name = 2; + */ + botUserName: Uint8Array; + /** + * counter of bot joins + * + * @generated from protobuf field: uint64 bot_joins = 3; + */ + botJoins: bigint; + /** + * counter of SPIFFE SVIDs issued + * + * @generated from protobuf field: uint64 spiffe_svids_issued = 4; + */ + spiffeSvidsIssued: bigint; + /** + * counter of certificates issued for this user + * + * @generated from protobuf field: uint64 certificates_issued = 5; + */ + certificatesIssued: bigint; +} /** * @generated from protobuf message prehog.v1.SubmitUsageReportsRequest */ @@ -271,6 +363,12 @@ export interface SubmitUsageReportsRequest { * @generated from protobuf field: repeated prehog.v1.ResourcePresenceReport resource_presence = 2; */ resourcePresence: ResourcePresenceReport[]; + /** + * encoded as a seperate tp.bot_instance.activity PostHog event + * + * @generated from protobuf field: repeated prehog.v1.BotInstanceActivityReport bot_instance_activity = 3; + */ + botInstanceActivity: BotInstanceActivityReport[]; } /** * @generated from protobuf message prehog.v1.SubmitUsageReportsResponse @@ -778,17 +876,176 @@ class ResourceKindPresenceReport$Type extends MessageType { + constructor() { + super("prehog.v1.BotInstanceActivityReport", [ + { no: 1, name: "report_uuid", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 2, name: "cluster_name", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 3, name: "reporter_hostid", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 4, name: "start_time", kind: "message", T: () => Timestamp }, + { no: 5, name: "records", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => BotInstanceActivityRecord } + ]); + } + create(value?: PartialMessage): BotInstanceActivityReport { + const message = globalThis.Object.create((this.messagePrototype!)); + message.reportUuid = new Uint8Array(0); + message.clusterName = new Uint8Array(0); + message.reporterHostid = new Uint8Array(0); + message.records = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BotInstanceActivityReport): BotInstanceActivityReport { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes report_uuid */ 1: + message.reportUuid = reader.bytes(); + break; + case /* bytes cluster_name */ 2: + message.clusterName = reader.bytes(); + break; + case /* bytes reporter_hostid */ 3: + message.reporterHostid = reader.bytes(); + break; + case /* google.protobuf.Timestamp start_time */ 4: + message.startTime = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.startTime); + break; + case /* repeated prehog.v1.BotInstanceActivityRecord records */ 5: + message.records.push(BotInstanceActivityRecord.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BotInstanceActivityReport, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes report_uuid = 1; */ + if (message.reportUuid.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.reportUuid); + /* bytes cluster_name = 2; */ + if (message.clusterName.length) + writer.tag(2, WireType.LengthDelimited).bytes(message.clusterName); + /* bytes reporter_hostid = 3; */ + if (message.reporterHostid.length) + writer.tag(3, WireType.LengthDelimited).bytes(message.reporterHostid); + /* google.protobuf.Timestamp start_time = 4; */ + if (message.startTime) + Timestamp.internalBinaryWrite(message.startTime, writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + /* repeated prehog.v1.BotInstanceActivityRecord records = 5; */ + for (let i = 0; i < message.records.length; i++) + BotInstanceActivityRecord.internalBinaryWrite(message.records[i], writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message prehog.v1.BotInstanceActivityReport + */ +export const BotInstanceActivityReport = new BotInstanceActivityReport$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BotInstanceActivityRecord$Type extends MessageType { + constructor() { + super("prehog.v1.BotInstanceActivityRecord", [ + { no: 1, name: "bot_instance_id", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 2, name: "bot_user_name", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 3, name: "bot_joins", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 4, name: "spiffe_svids_issued", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 5, name: "certificates_issued", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ } + ]); + } + create(value?: PartialMessage): BotInstanceActivityRecord { + const message = globalThis.Object.create((this.messagePrototype!)); + message.botInstanceId = new Uint8Array(0); + message.botUserName = new Uint8Array(0); + message.botJoins = 0n; + message.spiffeSvidsIssued = 0n; + message.certificatesIssued = 0n; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BotInstanceActivityRecord): BotInstanceActivityRecord { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes bot_instance_id */ 1: + message.botInstanceId = reader.bytes(); + break; + case /* bytes bot_user_name */ 2: + message.botUserName = reader.bytes(); + break; + case /* uint64 bot_joins */ 3: + message.botJoins = reader.uint64().toBigInt(); + break; + case /* uint64 spiffe_svids_issued */ 4: + message.spiffeSvidsIssued = reader.uint64().toBigInt(); + break; + case /* uint64 certificates_issued */ 5: + message.certificatesIssued = reader.uint64().toBigInt(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BotInstanceActivityRecord, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes bot_instance_id = 1; */ + if (message.botInstanceId.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.botInstanceId); + /* bytes bot_user_name = 2; */ + if (message.botUserName.length) + writer.tag(2, WireType.LengthDelimited).bytes(message.botUserName); + /* uint64 bot_joins = 3; */ + if (message.botJoins !== 0n) + writer.tag(3, WireType.Varint).uint64(message.botJoins); + /* uint64 spiffe_svids_issued = 4; */ + if (message.spiffeSvidsIssued !== 0n) + writer.tag(4, WireType.Varint).uint64(message.spiffeSvidsIssued); + /* uint64 certificates_issued = 5; */ + if (message.certificatesIssued !== 0n) + writer.tag(5, WireType.Varint).uint64(message.certificatesIssued); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message prehog.v1.BotInstanceActivityRecord + */ +export const BotInstanceActivityRecord = new BotInstanceActivityRecord$Type(); +// @generated message type with reflection information, may provide speed optimized methods class SubmitUsageReportsRequest$Type extends MessageType { constructor() { super("prehog.v1.SubmitUsageReportsRequest", [ { no: 1, name: "user_activity", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => UserActivityReport }, - { no: 2, name: "resource_presence", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ResourcePresenceReport } + { no: 2, name: "resource_presence", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ResourcePresenceReport }, + { no: 3, name: "bot_instance_activity", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => BotInstanceActivityReport } ]); } create(value?: PartialMessage): SubmitUsageReportsRequest { const message = globalThis.Object.create((this.messagePrototype!)); message.userActivity = []; message.resourcePresence = []; + message.botInstanceActivity = []; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -804,6 +1061,9 @@ class SubmitUsageReportsRequest$Type extends MessageType): UserCertificateIssuedEvent { @@ -4664,6 +4685,7 @@ class UserCertificateIssuedEvent$Type extends MessageType(this, message, value); return message; @@ -4697,6 +4719,9 @@ class UserCertificateIssuedEvent$Type extends MessageType { { no: 3, name: "spiffe_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 4, name: "ip_sans_count", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, { no: 5, name: "dns_sans_count", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, - { no: 6, name: "svid_type", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 6, name: "svid_type", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "bot_instance_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): SPIFFESVIDIssuedEvent { @@ -4763,6 +4792,7 @@ class SPIFFESVIDIssuedEvent$Type extends MessageType { message.ipSansCount = 0; message.dnsSansCount = 0; message.svidType = ""; + message.botInstanceId = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -4790,6 +4820,9 @@ class SPIFFESVIDIssuedEvent$Type extends MessageType { case /* string svid_type */ 6: message.svidType = reader.string(); break; + case /* string bot_instance_id */ 7: + message.botInstanceId = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -4820,6 +4853,9 @@ class SPIFFESVIDIssuedEvent$Type extends MessageType { /* string svid_type = 6; */ if (message.svidType !== "") writer.tag(6, WireType.LengthDelimited).string(message.svidType); + /* string bot_instance_id = 7; */ + if (message.botInstanceId !== "") + writer.tag(7, WireType.LengthDelimited).string(message.botInstanceId); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -6871,7 +6907,8 @@ class BotJoinEvent$Type extends MessageType { { no: 1, name: "bot_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 2, name: "join_method", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 3, name: "join_token_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 4, name: "user_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 4, name: "user_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "bot_instance_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): BotJoinEvent { @@ -6880,6 +6917,7 @@ class BotJoinEvent$Type extends MessageType { message.joinMethod = ""; message.joinTokenName = ""; message.userName = ""; + message.botInstanceId = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -6901,6 +6939,9 @@ class BotJoinEvent$Type extends MessageType { case /* string user_name */ 4: message.userName = reader.string(); break; + case /* string bot_instance_id */ 5: + message.botInstanceId = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -6925,6 +6966,9 @@ class BotJoinEvent$Type extends MessageType { /* string user_name = 4; */ if (message.userName !== "") writer.tag(4, WireType.LengthDelimited).string(message.userName); + /* string bot_instance_id = 5; */ + if (message.botInstanceId !== "") + writer.tag(5, WireType.LengthDelimited).string(message.botInstanceId); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 1ccf48467ea57..2c727237da972 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -3038,6 +3038,7 @@ func (a *Server) submitCertificateIssuedEvent(req *certRequest, attestedKeyPolic UsageKubernetes: kubernetes, UsageDesktop: desktop, PrivateKeyPolicy: string(attestedKeyPolicy), + BotInstanceId: req.botInstanceID, }) } diff --git a/lib/usagereporter/teleport/aggregating/reporter.go b/lib/usagereporter/teleport/aggregating/reporter.go index 7dc288411b92a..dad1471158bf7 100644 --- a/lib/usagereporter/teleport/aggregating/reporter.go +++ b/lib/usagereporter/teleport/aggregating/reporter.go @@ -39,10 +39,11 @@ import ( ) const ( - userActivityReportGranularity = 15 * time.Minute - resourceReportGranularity = time.Hour - rollbackGrace = time.Minute - reportTTL = 60 * 24 * time.Hour + userActivityReportGranularity = 15 * time.Minute + resourceReportGranularity = time.Hour + botInstanceActivityReportGranularity = 15 * time.Minute + rollbackGrace = time.Minute + reportTTL = 60 * 24 * time.Hour checkInterval = time.Minute ) @@ -272,6 +273,23 @@ func (r *Reporter) run(ctx context.Context) { return record } + botInstanceActivityStartTime := r.clock.Now().UTC().Truncate(botInstanceActivityReportGranularity) + botInstanceActivityWindowStart := botInstanceActivityStartTime.Add(-rollbackGrace) + botInstanceActivityWindowEnd := botInstanceActivityStartTime.Add(botInstanceActivityReportGranularity) + botInstanceActivity := make(map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord) + botInstanceRecord := func(botUserName string, botInstanceID string) *prehogv1.BotInstanceActivityRecord { + key := botInstanceActivityKey{ + botUserName: botUserName, + botInstanceID: botInstanceID, + } + record := botInstanceActivity[key] + if record == nil { + record = &prehogv1.BotInstanceActivityRecord{} + botInstanceActivity[key] = record + } + return record + } + resourceUsageStartTime := r.clock.Now().UTC().Truncate(resourceReportGranularity) resourceUsageWindowStart := resourceUsageStartTime.Add(-rollbackGrace) resourceUsageWindowEnd := resourceUsageStartTime.Add(resourceReportGranularity) @@ -317,6 +335,25 @@ Ingest: userActivity = make(map[string]*prehogv1.UserActivityRecord, len(userActivity)) } + if now := r.clock.Now().UTC(); now.Before(botInstanceActivityWindowStart) || !now.Before(botInstanceActivityWindowEnd) { + if len(botInstanceActivity) > 0 { + wg.Add(1) + go func( + ctx context.Context, + startTime time.Time, + botInstanceActivity map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord, + ) { + defer wg.Done() + r.persistBotInstanceActivity(ctx, startTime, botInstanceActivity) + }(ctx, botInstanceActivityStartTime, botInstanceActivity) + } + + botInstanceActivityStartTime = now.Truncate(botInstanceActivityReportGranularity) + botInstanceActivityWindowStart = botInstanceActivityStartTime.Add(-rollbackGrace) + botInstanceActivityWindowEnd = botInstanceActivityStartTime.Add(botInstanceActivityReportGranularity) + botInstanceActivity = make(map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord, len(botInstanceActivity)) + } + if now := r.clock.Now().UTC(); now.Before(resourceUsageWindowStart) || !now.Before(resourceUsageWindowEnd) { if len(resourcePresences) > 0 { wg.Add(1) @@ -364,9 +401,15 @@ Ingest: resourcePresence(prehogv1.ResourceKind(te.Kind))[te.Name] = struct{}{} case *usagereporter.SPIFFESVIDIssuedEvent: userRecord(te.UserName, te.UserKind).SpiffeSvidsIssued++ + if te.BotInstanceId != "" { + botInstanceRecord(te.UserName, te.BotInstanceId).SpiffeSvidsIssued++ + } case *usagereporter.BotJoinEvent: botUserName := machineidv1.BotResourceName(te.BotName) userRecord(botUserName, prehogv1alpha.UserKind_USER_KIND_BOT).BotJoins++ + if te.BotInstanceId != "" { + botInstanceRecord(botUserName, te.BotInstanceId).BotJoins++ + } case *usagereporter.UserCertificateIssuedEvent: // Note: kind is poorly defined for this event type, so we'll assume // unspecified even though non-bot users are almost certainly human. @@ -376,6 +419,9 @@ Ingest: } userRecord(te.UserName, kind).CertificatesIssued++ + if te.BotInstanceId != "" { + botInstanceRecord(te.UserName, te.BotInstanceId).CertificatesIssued++ + } } if ae != nil && r.ingested != nil { @@ -387,6 +433,10 @@ Ingest: r.persistUserActivity(ctx, userActivityStartTime, userActivity) } + if len(botInstanceActivity) > 0 { + r.persistBotInstanceActivity(ctx, botInstanceActivityStartTime, botInstanceActivity) + } + if len(resourcePresences) > 0 { r.persistResourcePresence(ctx, resourceUsageStartTime, resourcePresences) } @@ -394,6 +444,57 @@ Ingest: wg.Wait() } +type botInstanceActivityKey struct { + botUserName string + botInstanceID string +} + +func (r *Reporter) persistBotInstanceActivity( + ctx context.Context, + startTime time.Time, + botInstanceActivity map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord, +) { + records := make([]*prehogv1.BotInstanceActivityRecord, 0, len(botInstanceActivity)) + for key, record := range botInstanceActivity { + record.BotUserName = r.anonymizer.AnonymizeNonEmpty(key.botUserName) + record.BotInstanceId = r.anonymizer.AnonymizeNonEmpty(key.botInstanceID) + records = append(records, record) + } + + anonymizedClusterName := r.anonymizer.AnonymizeNonEmpty(r.clusterName) + anonymizedHostID := r.anonymizer.AnonymizeNonEmpty(r.hostID) + + reports, err := prepareBotInstanceActivityReports( + anonymizedClusterName, anonymizedHostID, startTime, records, + ) + if err != nil { + r.logger.ErrorContext(ctx, "Failed to prepare bot instance activity report, dropping data.", + "start_time", startTime, + "lost_records", len(records), + "error", err, + ) + return + } + + for _, report := range reports { + if err := r.svc.upsertBotInstanceActivityReport(ctx, report, reportTTL); err != nil { + r.logger.ErrorContext(ctx, "Failed to persist bot instance activity report, dropping data.", + "start_time", startTime, + "lost_records", len(report.Records), + "error", err, + ) + continue + } + + reportUUID, _ := uuid.FromBytes(report.ReportUuid) + r.logger.DebugContext(ctx, "Persisted bot instance activity report.", + "report_uuid", reportUUID, + "start_time", startTime, + "records", len(report.Records), + ) + } +} + func (r *Reporter) persistUserActivity(ctx context.Context, startTime time.Time, userActivity map[string]*prehogv1.UserActivityRecord) { records := make([]*prehogv1.UserActivityRecord, 0, len(userActivity)) for userName, record := range userActivity { diff --git a/lib/usagereporter/teleport/aggregating/reporter_test.go b/lib/usagereporter/teleport/aggregating/reporter_test.go index 0c82a51fbd938..d860d04c24180 100644 --- a/lib/usagereporter/teleport/aggregating/reporter_test.go +++ b/lib/usagereporter/teleport/aggregating/reporter_test.go @@ -21,6 +21,7 @@ package aggregating import ( "bytes" "context" + "slices" "testing" "time" @@ -181,3 +182,113 @@ func TestReporter(t *testing.T) { require.Equal(t, uint64(0), rec1.KubeSessions) require.Equal(t, uint64(1), rec2.KubeSessions) } + +func TestReporterBotInstanceActivity(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + clk := clockwork.NewFakeClock() + bk, err := memory.New(memory.Config{ + Clock: clk, + }) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, bk.Close()) }) + // we set up a watcher to not have to poll the backend for newly added items + // we expect + w, err := bk.NewWatcher(ctx, backend.Watch{}) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, w.Close()) }) + recvBackendEvent := func() backend.Event { + select { + case e := <-w.Events(): + return e + case <-time.After(time.Second): + t.Fatal("failed to get backend event") + return backend.Event{} + } + } + require.Equal(t, types.OpInit, recvBackendEvent().Type) + + clusterName, err := services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ + ClusterName: "clustername", + }) + require.NoError(t, err) + + anonymizer, err := utils.NewHMACAnonymizer("0123456789abcdef") + require.NoError(t, err) + + r, err := NewReporter(ctx, ReporterConfig{ + Backend: bk, + Clock: clk, + ClusterName: clusterName, + HostID: uuid.NewString(), + Anonymizer: anonymizer, + }) + require.NoError(t, err) + + svc := reportService{bk} + + r.ingested = make(chan usagereporter.Anonymizable, 4) + recvIngested := func() { + select { + case <-r.ingested: + case <-time.After(time.Second): + t.Fatal("failed to receive ingested event") + } + } + + r.AnonymizeAndSubmit(&usagereporter.UserCertificateIssuedEvent{ + UserName: "bot-bob", + BotInstanceId: "0000-01", + IsBot: true, + }) + r.AnonymizeAndSubmit(&usagereporter.BotJoinEvent{ + BotName: "bob", + BotInstanceId: "0000-01", + }) + // Submit for two different bot instances, we expect a useractivity record + // with a value of two, and two bot instance activity records with a single + // value of 1. + r.AnonymizeAndSubmit(&usagereporter.SPIFFESVIDIssuedEvent{ + UserName: "bot-bob", + BotInstanceId: "0000-01", + UserKind: prehogv1a.UserKind_USER_KIND_BOT, + }) + r.AnonymizeAndSubmit(&usagereporter.SPIFFESVIDIssuedEvent{ + UserName: "bot-bob", + BotInstanceId: "0000-02", + UserKind: prehogv1a.UserKind_USER_KIND_BOT, + }) + recvIngested() + recvIngested() + recvIngested() + recvIngested() + + clk.BlockUntil(1) + clk.Advance(botInstanceActivityReportGranularity) + + require.Equal(t, types.OpPut, recvBackendEvent().Type) + require.Equal(t, types.OpPut, recvBackendEvent().Type) + + userActivityReports, err := svc.listUserActivityReports(ctx, 10) + require.NoError(t, err) + require.Len(t, userActivityReports, 1) + require.Len(t, userActivityReports[0].Records, 1) + userActivityRecord := userActivityReports[0].Records[0] + require.Equal(t, uint64(1), userActivityRecord.BotJoins) + require.Equal(t, uint64(2), userActivityRecord.SpiffeSvidsIssued) + require.Equal(t, uint64(1), userActivityRecord.CertificatesIssued) + + botInstanceActivityReports, err := svc.listBotInstanceActivityReports(ctx, 10) + require.NoError(t, err) + require.Len(t, botInstanceActivityReports, 1) + require.Len(t, botInstanceActivityReports[0].Records, 2) + for _, record := range botInstanceActivityReports[0].Records { + require.Equal(t, userActivityRecord.UserName, record.BotUserName) + } + require.True(t, slices.ContainsFunc(botInstanceActivityReports[0].Records, func(record *prehogv1.BotInstanceActivityRecord) bool { + return record.BotJoins == 1 && record.CertificatesIssued == 1 && record.SpiffeSvidsIssued == 1 + })) + require.True(t, slices.ContainsFunc(botInstanceActivityReports[0].Records, func(record *prehogv1.BotInstanceActivityRecord) bool { + return record.BotJoins == 0 && record.CertificatesIssued == 0 && record.SpiffeSvidsIssued == 1 + })) +} diff --git a/lib/usagereporter/teleport/aggregating/service.go b/lib/usagereporter/teleport/aggregating/service.go index 586688826cc12..c215b2fa9b976 100644 --- a/lib/usagereporter/teleport/aggregating/service.go +++ b/lib/usagereporter/teleport/aggregating/service.go @@ -39,8 +39,12 @@ const ( ) const ( - userActivityReportsPrefix = "userActivityReports" - userActivityReportsLock = "userActivityReportsLock" + botInstanceActivityReportsPrefix = "botInstanceActivityReports" + userActivityReportsPrefix = "userActivityReports" + // usageReportingLock is a lock that should be held when submitting usage + // reports to the upstream service. Whilst the underlying key refers + // specifically to "userActivityReports", this is inaccurate. + usageReportingLock = "userActivityReportsLock" ResourcePresenceReportsPrefix = "resourcePresenceReports" ) @@ -164,6 +168,42 @@ func prepareResourcePresenceReports( return reports, nil } +// botInstanceActivityReportKey returns the backend key for a bot instance +// activity report with a given UUID and start time, such that reports with +// an earlier start time will appear earlier in lexicographic ordering. +func botInstanceActivityReportKey(reportUUID uuid.UUID, startTime time.Time) backend.Key { + return backend.NewKey(botInstanceActivityReportsPrefix, startTime.Format(time.RFC3339), reportUUID.String()) +} + +func prepareBotInstanceActivityReports( + clusterName, reporterHostID []byte, + startTime time.Time, records []*prehogv1.BotInstanceActivityRecord, +) (reports []*prehogv1.BotInstanceActivityReport, err error) { + for len(records) > 0 { + reportUUID := uuid.New() + report := &prehogv1.BotInstanceActivityReport{ + ReportUuid: reportUUID[:], + ClusterName: clusterName, + ReporterHostid: reporterHostID, + StartTime: timestamppb.New(startTime), + Records: records, + } + + for proto.Size(report) > maxItemSize { + if len(report.Records) <= 1 { + return nil, trace.LimitExceeded("failed to marshal bot instance activity report within size limit (this is a bug)") + } + + report.Records = report.Records[:len(report.Records)/2] + } + + records = records[len(report.Records):] + reports = append(reports, report) + } + + return reports, nil +} + // reportService is a [backend.Backend] wrapper that handles usage reports. type reportService struct { b backend.Backend @@ -236,16 +276,18 @@ func (r reportService) listUserActivityReports(ctx context.Context, count int) ( return reports, nil } -func (r reportService) createUserActivityReportsLock(ctx context.Context, ttl time.Duration, payload []byte) error { +// createUsageReportingLock creates a lock that should be held when reading +// reports and submitting them to the upstream service. +func (r reportService) createUsageReportingLock(ctx context.Context, ttl time.Duration, payload []byte) error { if len(payload) == 0 { payload = []byte("null") } - lockKey := backend.NewKey(userActivityReportsLock) + lockKey := backend.NewKey(usageReportingLock) // HACK(espadolini): dynamodbbk doesn't let you Create over an expired item // but it will explicitly delete expired items on a Get; in addition, reads // are cheaper than writes in most backends, so we do a Get here first if _, err := r.b.Get(ctx, lockKey); err == nil { - return trace.AlreadyExists(userActivityReportsLock + " already exists") + return trace.AlreadyExists(usageReportingLock + " already exists") } else if !trace.IsNotFound(err) { return trace.Wrap(err) } @@ -326,3 +368,76 @@ func (r reportService) listResourcePresenceReports(ctx context.Context, count in return reports, nil } + +func (r reportService) upsertBotInstanceActivityReport( + ctx context.Context, report *prehogv1.BotInstanceActivityReport, ttl time.Duration, +) error { + wire, err := proto.Marshal(report) + if err != nil { + return trace.Wrap(err) + } + + reportUUID, err := uuid.FromBytes(report.GetReportUuid()) + if err != nil { + return trace.Wrap(err) + } + + startTime := report.GetStartTime().AsTime() + if startTime.IsZero() { + return trace.BadParameter("missing start_time") + } + + if _, err := r.b.Put(ctx, backend.Item{ + Key: botInstanceActivityReportKey(reportUUID, startTime), + Value: wire, + Expires: startTime.Add(ttl), + }); err != nil { + return trace.Wrap(err) + } + + return nil +} + +func (r reportService) deleteBotInstanceActivityReport( + ctx context.Context, report *prehogv1.BotInstanceActivityReport, +) error { + reportUUID, err := uuid.FromBytes(report.GetReportUuid()) + if err != nil { + return trace.Wrap(err) + } + + startTime := report.GetStartTime().AsTime() + if startTime.IsZero() { + return trace.BadParameter("missing start_time") + } + + if err := r.b.Delete(ctx, botInstanceActivityReportKey(reportUUID, startTime)); err != nil { + return trace.Wrap(err) + } + + return nil +} + +// listBotInstanceActivityReports returns the first `count` user activity reports +// according to the key order; as we store them with time and uuid in the key, +// this results in returning earlier reports first. +func (r reportService) listBotInstanceActivityReports( + ctx context.Context, count int, +) ([]*prehogv1.BotInstanceActivityReport, error) { + rangeStart := backend.ExactKey(botInstanceActivityReportsPrefix) + result, err := r.b.GetRange(ctx, rangeStart, backend.RangeEnd(rangeStart), count) + if err != nil { + return nil, trace.Wrap(err) + } + + reports := make([]*prehogv1.BotInstanceActivityReport, 0, len(result.Items)) + for _, item := range result.Items { + report := &prehogv1.BotInstanceActivityReport{} + if err := proto.Unmarshal(item.Value, report); err != nil { + return nil, trace.Wrap(err) + } + reports = append(reports, report) + } + + return reports, nil +} diff --git a/lib/usagereporter/teleport/aggregating/service_test.go b/lib/usagereporter/teleport/aggregating/service_test.go index 9d075743b0779..6bccb56432b17 100644 --- a/lib/usagereporter/teleport/aggregating/service_test.go +++ b/lib/usagereporter/teleport/aggregating/service_test.go @@ -125,13 +125,13 @@ func TestLock(t *testing.T) { svc := reportService{bk} - require.NoError(t, svc.createUserActivityReportsLock(ctx, 2*time.Minute, nil)) + require.NoError(t, svc.createUsageReportingLock(ctx, 2*time.Minute, nil)) clk.Advance(time.Minute) - err = svc.createUserActivityReportsLock(ctx, 2*time.Minute, nil) + err = svc.createUsageReportingLock(ctx, 2*time.Minute, nil) require.Error(t, err) require.True(t, trace.IsAlreadyExists(err)) clk.Advance(time.Minute) - require.NoError(t, svc.createUserActivityReportsLock(ctx, 2*time.Minute, nil)) + require.NoError(t, svc.createUsageReportingLock(ctx, 2*time.Minute, nil)) } func newResourcePresenceReport(startTime time.Time) *prehogv1.ResourcePresenceReport { @@ -210,3 +210,28 @@ func TestResourcePresenceReportSplitting(t *testing.T) { "resource ids for resource kind %v do not match", resKindReport.ResourceKind) } } + +func TestBotInstanceActivityReportSplitting(t *testing.T) { + recordCount := 10000 + records := make([]*prehogv1.BotInstanceActivityRecord, 0, recordCount) + for i := 0; i < recordCount; i++ { + records = append(records, &prehogv1.BotInstanceActivityRecord{ + BotUserName: []byte("user"), + BotInstanceId: []byte("foo"), + BotJoins: 1000, + }) + } + reports, err := prepareBotInstanceActivityReports( + []byte("clusterName"), []byte("reporterHostID"), time.Now(), records, + ) + require.NoError(t, err) + require.GreaterOrEqual(t, len(reports), 2) // some reports were split into two + require.GreaterOrEqual(t, len(reports[0].Records), 2) // first report was able to contain a few user activity records + + // reassemble records and ensure that nothing was lost + recordsCopy := make([]*prehogv1.BotInstanceActivityRecord, 0, recordCount) + for _, report := range reports { + recordsCopy = append(recordsCopy, report.Records...) + } + require.Equal(t, records, recordsCopy, "some bot instance activity records have been lost during splitting") +} diff --git a/lib/usagereporter/teleport/aggregating/submitter.go b/lib/usagereporter/teleport/aggregating/submitter.go index ebb43942da2f4..4d4e9dae1b118 100644 --- a/lib/usagereporter/teleport/aggregating/submitter.go +++ b/lib/usagereporter/teleport/aggregating/submitter.go @@ -140,7 +140,17 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { } } - totalReportCount := len(userActivityReports) + len(resourcePresenceReports) + freeBatchSize = submitBatchSize - len(userActivityReports) - len(resourcePresenceReports) + var botInstanceActivityReports []*prehogv1.BotInstanceActivityReport + if freeBatchSize > 0 { + botInstanceActivityReports, err = svc.listBotInstanceActivityReports(ctx, freeBatchSize) + if err != nil { + c.Logger.ErrorContext(ctx, "Failed to load bot instance activity reports for submission.", "error", err) + return + } + } + + totalReportCount := len(userActivityReports) + len(resourcePresenceReports) + len(botInstanceActivityReports) if totalReportCount < 1 { err := ClearAlert(ctx, c.Status) @@ -170,13 +180,21 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { newest = t } } + if len(botInstanceActivityReports) > 0 { + if t := botInstanceActivityReports[0].GetStartTime().AsTime(); t.Before(oldest) { + oldest = t + } + if t := botInstanceActivityReports[len(botInstanceActivityReports)-1].GetStartTime().AsTime(); t.After(newest) { + newest = t + } + } debugPayload := fmt.Sprintf("%v %q", time.Now().Round(0), c.HostID) - if err := svc.createUserActivityReportsLock(ctx, submitLockDuration, []byte(debugPayload)); err != nil { + if err := svc.createUsageReportingLock(ctx, submitLockDuration, []byte(debugPayload)); err != nil { if trace.IsAlreadyExists(err) { - c.Logger.DebugContext(ctx, "Failed to acquire lock, already held.", "lock", userActivityReportsLock) + c.Logger.DebugContext(ctx, "Failed to acquire lock, already held.", "lock", usageReportingLock) } else { - c.Logger.ErrorContext(ctx, "Failed to acquire lock.", "lock", userActivityReportsLock, "error", err) + c.Logger.ErrorContext(ctx, "Failed to acquire lock.", "lock", usageReportingLock, "error", err) } return } @@ -185,8 +203,9 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { defer cancel() batchUUID, err := c.Submitter(lockCtx, &prehogv1.SubmitUsageReportsRequest{ - UserActivity: userActivityReports, - ResourcePresence: resourcePresenceReports, + UserActivity: userActivityReports, + ResourcePresence: resourcePresenceReports, + BotInstanceActivity: botInstanceActivityReports, }) if err != nil { c.Logger.ErrorContext(ctx, "Failed to send usage reports.", @@ -236,6 +255,11 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { lastErr = err } } + for _, report := range botInstanceActivityReports { + if err := svc.deleteBotInstanceActivityReport(ctx, report); err != nil { + lastErr = err + } + } if lastErr != nil { c.Logger.WarnContext(ctx, "Failed to delete some usage reports after successful send.", "last_error", lastErr) } diff --git a/lib/usagereporter/teleport/audit.go b/lib/usagereporter/teleport/audit.go index e093fe887ec54..8d3dc3b1a6cc0 100644 --- a/lib/usagereporter/teleport/audit.go +++ b/lib/usagereporter/teleport/audit.go @@ -194,6 +194,7 @@ func ConvertAuditEvent(event apievents.AuditEvent) Anonymizable { JoinMethod: e.Method, JoinTokenName: e.TokenName, UserName: e.UserName, + BotInstanceId: e.BotInstanceID, } case *apievents.DeviceEvent2: @@ -269,12 +270,13 @@ func ConvertAuditEvent(event apievents.AuditEvent) Anonymizable { } case *apievents.SPIFFESVIDIssued: return &SPIFFESVIDIssuedEvent{ - UserName: e.User, - UserKind: prehogUserKindFromEventKind(e.UserKind), - SpiffeId: e.SPIFFEID, - IpSansCount: int32(len(e.IPSANs)), - DnsSansCount: int32(len(e.DNSSANs)), - SvidType: e.SVIDType, + UserName: e.User, + UserKind: prehogUserKindFromEventKind(e.UserKind), + SpiffeId: e.SPIFFEID, + IpSansCount: int32(len(e.IPSANs)), + DnsSansCount: int32(len(e.DNSSANs)), + SvidType: e.SVIDType, + BotInstanceId: e.BotInstanceID, } case *apievents.DatabaseUserCreate: return &DatabaseUserCreatedEvent{ diff --git a/lib/usagereporter/teleport/types.go b/lib/usagereporter/teleport/types.go index 43729db3baed4..3b783f73b55e1 100644 --- a/lib/usagereporter/teleport/types.go +++ b/lib/usagereporter/teleport/types.go @@ -71,6 +71,7 @@ func (u *BotJoinEvent) Anonymize(a utils.Anonymizer) prehogv1a.SubmitEventReques JoinTokenName: a.AnonymizeString(u.JoinTokenName), JoinMethod: u.JoinMethod, UserName: a.AnonymizeString(u.UserName), + BotInstanceId: a.AnonymizeString(u.BotInstanceId), }, }, } @@ -516,18 +517,22 @@ func (u *UICallToActionClickEvent) Anonymize(a utils.Anonymizer) prehogv1a.Submi type UserCertificateIssuedEvent prehogv1a.UserCertificateIssuedEvent func (u *UserCertificateIssuedEvent) Anonymize(a utils.Anonymizer) prehogv1a.SubmitEventRequest { + e := &prehogv1a.UserCertificateIssuedEvent{ + UserName: a.AnonymizeString(u.UserName), + Ttl: u.Ttl, + IsBot: u.IsBot, + UsageDatabase: u.UsageDatabase, + UsageApp: u.UsageApp, + UsageKubernetes: u.UsageKubernetes, + UsageDesktop: u.UsageDesktop, + PrivateKeyPolicy: u.PrivateKeyPolicy, + } + if u.BotInstanceId != "" { + e.BotInstanceId = a.AnonymizeString(u.BotInstanceId) + } return prehogv1a.SubmitEventRequest{ Event: &prehogv1a.SubmitEventRequest_UserCertificateIssuedEvent{ - UserCertificateIssuedEvent: &prehogv1a.UserCertificateIssuedEvent{ - UserName: a.AnonymizeString(u.UserName), - Ttl: u.Ttl, - IsBot: u.IsBot, - UsageDatabase: u.UsageDatabase, - UsageApp: u.UsageApp, - UsageKubernetes: u.UsageKubernetes, - UsageDesktop: u.UsageDesktop, - PrivateKeyPolicy: u.PrivateKeyPolicy, - }, + UserCertificateIssuedEvent: e, }, } } @@ -1274,16 +1279,20 @@ func (u *DatabaseUserPermissionsUpdateEvent) Anonymize(a utils.Anonymizer) preho type SPIFFESVIDIssuedEvent prehogv1a.SPIFFESVIDIssuedEvent func (u *SPIFFESVIDIssuedEvent) Anonymize(a utils.Anonymizer) prehogv1a.SubmitEventRequest { + e := &prehogv1a.SPIFFESVIDIssuedEvent{ + UserName: a.AnonymizeString(u.UserName), + UserKind: u.UserKind, + SpiffeId: a.AnonymizeString(u.SpiffeId), + IpSansCount: u.IpSansCount, + DnsSansCount: u.DnsSansCount, + SvidType: u.SvidType, + } + if u.BotInstanceId != "" { + e.BotInstanceId = a.AnonymizeString(u.BotInstanceId) + } return prehogv1a.SubmitEventRequest{ Event: &prehogv1a.SubmitEventRequest_SpiffeSvidIssued{ - SpiffeSvidIssued: &prehogv1a.SPIFFESVIDIssuedEvent{ - UserName: a.AnonymizeString(u.UserName), - UserKind: u.UserKind, - SpiffeId: a.AnonymizeString(u.SpiffeId), - IpSansCount: u.IpSansCount, - DnsSansCount: u.DnsSansCount, - SvidType: u.SvidType, - }, + SpiffeSvidIssued: e, }, } } diff --git a/proto/prehog/v1/teleport.proto b/proto/prehog/v1/teleport.proto index 2afb47fb95f72..821e8f1c1e8ad 100644 --- a/proto/prehog/v1/teleport.proto +++ b/proto/prehog/v1/teleport.proto @@ -182,6 +182,57 @@ message ResourceKindPresenceReport { repeated fixed64 resource_ids = 2; } +// counters for bot instance activity coming from a specific auth server from a +// specific cluster. +// +// PostHog event: tp.bot_instance.activity +message BotInstanceActivityReport { + // randomly generated UUID for this specific report, 16 bytes (in string order) + // + // PostHog property: tp.report_uuid (in 8-4-4-4-12 string form) + bytes report_uuid = 1; + + // cluster name, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.cluster_name (in base64) + bytes cluster_name = 2; + + // hostid of the auth that collected this report, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.reporter_hostid (in base64) + bytes reporter_hostid = 3; + + // beginning of the time window for this data; ending is not specified but is + // intended to be at most 15 minutes + // + // PostHog timestamp (not a property, the ingest time is tp.report_time instead) + google.protobuf.Timestamp start_time = 4; + + // one set of counters for each bot instance + // + // PostHog property: tp.records (encoded as a map keyed by anonymized bot + // instance id, not as a list) + repeated BotInstanceActivityRecord records = 5; +} + +// Records the activity for a single bot instance against a specific auth server +// from a specific cluster. +message BotInstanceActivityRecord { + // The UUID of the BotInstance, anonymized using HMAC-SHA-256. + bytes bot_instance_id = 1; + // The name of the user associated with the BotInstance, + // anonymized using HMAC-SHA-256. + // Enables correlation with the UserActivityRecord for the Bot. + bytes bot_user_name = 2; + + // counter of bot joins + uint64 bot_joins = 3; + // counter of SPIFFE SVIDs issued + uint64 spiffe_svids_issued = 4; + // counter of certificates issued for this user + uint64 certificates_issued = 5; +} + message SubmitUsageReportsRequest { // at most 10 reports of all kinds in a single RPC, each shouldn't exceed 128KiB or so // @@ -189,6 +240,8 @@ message SubmitUsageReportsRequest { repeated UserActivityReport user_activity = 1; // encoded as a separate tp.resource.counts PostHog event repeated ResourcePresenceReport resource_presence = 2; + // encoded as a seperate tp.bot_instance.activity PostHog event + repeated BotInstanceActivityReport bot_instance_activity = 3; } message SubmitUsageReportsResponse { // randomly generated UUID for this specific batch, 16 bytes (in string order) diff --git a/proto/prehog/v1alpha/teleport.proto b/proto/prehog/v1alpha/teleport.proto index 1b979b3789d70..01b0f63b65598 100644 --- a/proto/prehog/v1alpha/teleport.proto +++ b/proto/prehog/v1alpha/teleport.proto @@ -298,6 +298,10 @@ message UserCertificateIssuedEvent { // the private key policy associated with these user certificates. string private_key_policy = 8; + + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + string bot_instance_id = 9; } // the issuance of a SPIFFE SVID @@ -330,6 +334,10 @@ message SPIFFESVIDIssuedEvent { // Type of SVID issued. `x509` or `jwt` // PostHog property: tp.spiffe.svid_type string svid_type = 6; + + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + string bot_instance_id = 7; } // UIBannerClickEvent is a usage event sent by the UI when the upgrade @@ -741,6 +749,8 @@ message BotJoinEvent { string join_token_name = 3; // user_name is the anonymised name of the Bot user. string user_name = 4; + // bot_instance_id is the anonymized instance id of the bot. + string bot_instance_id = 5; } // UICreateNewRoleClickEvent is an event that can be triggered during custom role creation From 479830987545ea6308560775b22af0eb68c9db2b Mon Sep 17 00:00:00 2001 From: Forrest <30576607+fspmarshall@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:01:58 -0800 Subject: [PATCH 19/27] Add host fields and protos for ssh identities (#51024) (#51665) * add host fields to sshca.Identity * add ssh identity proto --- .../decision/v1alpha1/ssh_identity.pb.go | 670 +++++++++++++++++- .../decision/v1alpha1/ssh_identity.proto | 167 ++++- integration/helpers/instance.go | 9 +- lib/auth/auth.go | 45 +- lib/auth/auth_test.go | 2 +- lib/auth/auth_with_roles.go | 8 +- lib/auth/init_test.go | 41 +- lib/auth/keygen/keygen.go | 69 +- lib/auth/keygen/keygen_test.go | 28 +- lib/auth/sessions.go | 4 +- lib/auth/test/suite.go | 37 +- lib/auth/testauthority/testauthority.go | 5 +- lib/client/client_store_test.go | 11 +- lib/client/identityfile/identity_test.go | 4 +- lib/client/keyagent_test.go | 33 +- lib/client/known_hosts_migrate_test.go | 8 +- lib/decision/ssh_identity.go | 143 ++++ lib/decision/ssh_identity_test.go | 101 +++ lib/reversetunnel/srv_test.go | 11 +- lib/services/authority.go | 42 -- lib/srv/authhandlers_test.go | 8 +- lib/srv/git/forward_test.go | 10 +- lib/sshca/identity.go | 117 ++- lib/sshca/identity_test.go | 49 +- lib/sshca/sshca.go | 54 +- 25 files changed, 1401 insertions(+), 275 deletions(-) create mode 100644 lib/decision/ssh_identity.go create mode 100644 lib/decision/ssh_identity_test.go diff --git a/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go b/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go index cefff7cdc1ffc..b603dc75473c5 100644 --- a/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go +++ b/api/gen/proto/go/teleport/decision/v1alpha1/ssh_identity.pb.go @@ -21,8 +21,10 @@ package decisionpb import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/trait/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -34,11 +36,200 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// CertExtensionMode specifies the type of extension to use in the cert. This type +// must be kept up to date with types.CertExtensionMode. +type CertExtensionMode int32 + +const ( + // CERT_EXTENSION_MODE_UNSPECIFIED is the default value and should not be used. + CertExtensionMode_CERT_EXTENSION_MODE_UNSPECIFIED CertExtensionMode = 0 + // EXTENSION represents a cert extension that may or may not be + // honored by the server. + CertExtensionMode_CERT_EXTENSION_MODE_EXTENSION CertExtensionMode = 1 +) + +// Enum value maps for CertExtensionMode. +var ( + CertExtensionMode_name = map[int32]string{ + 0: "CERT_EXTENSION_MODE_UNSPECIFIED", + 1: "CERT_EXTENSION_MODE_EXTENSION", + } + CertExtensionMode_value = map[string]int32{ + "CERT_EXTENSION_MODE_UNSPECIFIED": 0, + "CERT_EXTENSION_MODE_EXTENSION": 1, + } +) + +func (x CertExtensionMode) Enum() *CertExtensionMode { + p := new(CertExtensionMode) + *p = x + return p +} + +func (x CertExtensionMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CertExtensionMode) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_decision_v1alpha1_ssh_identity_proto_enumTypes[0].Descriptor() +} + +func (CertExtensionMode) Type() protoreflect.EnumType { + return &file_teleport_decision_v1alpha1_ssh_identity_proto_enumTypes[0] +} + +func (x CertExtensionMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CertExtensionMode.Descriptor instead. +func (CertExtensionMode) EnumDescriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP(), []int{0} +} + +// CertExtensionType represents the certificate type the extension is for. +// Currently only ssh is supported. This type must be kept up to date with +// types.CertExtensionType. +type CertExtensionType int32 + +const ( + // CERT_EXTENSION_TYPE_UNSPECIFIED is the default value and should not be used. + CertExtensionType_CERT_EXTENSION_TYPE_UNSPECIFIED CertExtensionType = 0 + // SSH is used when extending an ssh certificate + CertExtensionType_CERT_EXTENSION_TYPE_SSH CertExtensionType = 1 +) + +// Enum value maps for CertExtensionType. +var ( + CertExtensionType_name = map[int32]string{ + 0: "CERT_EXTENSION_TYPE_UNSPECIFIED", + 1: "CERT_EXTENSION_TYPE_SSH", + } + CertExtensionType_value = map[string]int32{ + "CERT_EXTENSION_TYPE_UNSPECIFIED": 0, + "CERT_EXTENSION_TYPE_SSH": 1, + } +) + +func (x CertExtensionType) Enum() *CertExtensionType { + p := new(CertExtensionType) + *p = x + return p +} + +func (x CertExtensionType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CertExtensionType) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_decision_v1alpha1_ssh_identity_proto_enumTypes[1].Descriptor() +} + +func (CertExtensionType) Type() protoreflect.EnumType { + return &file_teleport_decision_v1alpha1_ssh_identity_proto_enumTypes[1] +} + +func (x CertExtensionType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CertExtensionType.Descriptor instead. +func (CertExtensionType) EnumDescriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP(), []int{1} +} + // SSHIdentity is the identity used for SSH connections. type SSHIdentity struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // ValidAfter is the unix timestamp that marks the start time for when the certificate should + // be considered valid. + ValidAfter uint64 `protobuf:"varint,1,opt,name=valid_after,json=validAfter,proto3" json:"valid_after,omitempty"` + // ValidBefore is the unix timestamp that marks the end time for when the certificate should + // be considered valid. + ValidBefore uint64 `protobuf:"varint,2,opt,name=valid_before,json=validBefore,proto3" json:"valid_before,omitempty"` + // CertType indicates what type of cert this is (user or host). + CertType uint32 `protobuf:"varint,3,opt,name=cert_type,json=certType,proto3" json:"cert_type,omitempty"` + // Principals is the list of SSH principals associated with the certificate (this means the + // list of allowed unix logins in the case of user certs). + Principals []string `protobuf:"bytes,4,rep,name=principals,proto3" json:"principals,omitempty"` + // ClusterName is the name of the cluster within which a node lives + ClusterName string `protobuf:"bytes,5,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` + // SystemRole identifies the system role of a Teleport instance + SystemRole string `protobuf:"bytes,6,opt,name=system_role,json=systemRole,proto3" json:"system_role,omitempty"` + // Username is teleport username + Username string `protobuf:"bytes,7,opt,name=username,proto3" json:"username,omitempty"` + // Impersonator is set when a user requests certificate for another user + Impersonator string `protobuf:"bytes,8,opt,name=impersonator,proto3" json:"impersonator,omitempty"` + // PermitX11Forwarding permits X11 forwarding for this cert + PermitX11Forwarding bool `protobuf:"varint,9,opt,name=permit_x11_forwarding,json=permitX11Forwarding,proto3" json:"permit_x11_forwarding,omitempty"` + // PermitAgentForwarding permits agent forwarding for this cert + PermitAgentForwarding bool `protobuf:"varint,10,opt,name=permit_agent_forwarding,json=permitAgentForwarding,proto3" json:"permit_agent_forwarding,omitempty"` + // PermitPortForwarding permits port forwarding. + PermitPortForwarding bool `protobuf:"varint,11,opt,name=permit_port_forwarding,json=permitPortForwarding,proto3" json:"permit_port_forwarding,omitempty"` + // Roles is a list of roles assigned to this user + Roles []string `protobuf:"bytes,12,rep,name=roles,proto3" json:"roles,omitempty"` + // RouteToCluster specifies the target cluster + // if present in the certificate, will be used + // to route the requests to + RouteToCluster string `protobuf:"bytes,13,opt,name=route_to_cluster,json=routeToCluster,proto3" json:"route_to_cluster,omitempty"` + // Traits hold claim data used to populate a role at runtime. + Traits []*v1.Trait `protobuf:"bytes,14,rep,name=traits,proto3" json:"traits,omitempty"` + // ActiveRequests tracks privilege escalation requests applied during + // certificate construction. + ActiveRequests []string `protobuf:"bytes,15,rep,name=active_requests,json=activeRequests,proto3" json:"active_requests,omitempty"` + // MFAVerified is the UUID of an MFA device when this Identity was + // confirmed immediately after an MFA check. + MfaVerified string `protobuf:"bytes,16,opt,name=mfa_verified,json=mfaVerified,proto3" json:"mfa_verified,omitempty"` + // PreviousIdentityExpires is the expiry time of the identity/cert that this + // identity/cert was derived from. It is used to determine a session's hard + // deadline in cases where both require_session_mfa and disconnect_expired_cert + // are enabled. See https://github.com/gravitational/teleport/issues/18544. + PreviousIdentityExpires *timestamppb.Timestamp `protobuf:"bytes,17,opt,name=previous_identity_expires,json=previousIdentityExpires,proto3" json:"previous_identity_expires,omitempty"` + // LoginIP is an observed IP of the client on the moment of certificate creation. + LoginIp string `protobuf:"bytes,18,opt,name=login_ip,json=loginIp,proto3" json:"login_ip,omitempty"` + // PinnedIP is an IP from which client must communicate with Teleport. + PinnedIp string `protobuf:"bytes,19,opt,name=pinned_ip,json=pinnedIp,proto3" json:"pinned_ip,omitempty"` + // DisallowReissue flags that any attempt to request new certificates while + // authenticated with this cert should be denied. + DisallowReissue bool `protobuf:"varint,20,opt,name=disallow_reissue,json=disallowReissue,proto3" json:"disallow_reissue,omitempty"` + // CertificateExtensions are user configured ssh key extensions (note: this field also + // ends up aggregating all *unknown* extensions during cert parsing, meaning that this + // can sometimes contain fields that were inserted by a newer version of teleport). + CertificateExtensions []*CertExtension `protobuf:"bytes,21,rep,name=certificate_extensions,json=certificateExtensions,proto3" json:"certificate_extensions,omitempty"` + // Renewable indicates this certificate is renewable. + Renewable bool `protobuf:"varint,22,opt,name=renewable,proto3" json:"renewable,omitempty"` + // Generation counts the number of times a certificate has been renewed, with a generation of 1 + // meaning the cert has never been renewed. A generation of zero means the cert's generation is + // not being tracked. + Generation uint64 `protobuf:"varint,23,opt,name=generation,proto3" json:"generation,omitempty"` + // BotName is set to the name of the bot, if the user is a Machine ID bot user. + // Empty for human users. + BotName string `protobuf:"bytes,24,opt,name=bot_name,json=botName,proto3" json:"bot_name,omitempty"` + // BotInstanceID is the unique identifier for the bot instance, if this is a + // Machine ID bot. It is empty for human users. + BotInstanceId string `protobuf:"bytes,25,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` + // AllowedResourceIDs lists the resources the user should be able to access. + AllowedResourceIds []*ResourceId `protobuf:"bytes,26,rep,name=allowed_resource_ids,json=allowedResourceIds,proto3" json:"allowed_resource_ids,omitempty"` + // ConnectionDiagnosticID references the ConnectionDiagnostic that we should use to append traces when testing a Connection. + ConnectionDiagnosticId string `protobuf:"bytes,27,opt,name=connection_diagnostic_id,json=connectionDiagnosticId,proto3" json:"connection_diagnostic_id,omitempty"` + // PrivateKeyPolicy is the private key policy supported by this certificate. + PrivateKeyPolicy string `protobuf:"bytes,28,opt,name=private_key_policy,json=privateKeyPolicy,proto3" json:"private_key_policy,omitempty"` + // DeviceID is the trusted device identifier. + DeviceId string `protobuf:"bytes,29,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"` + // DeviceAssetTag is the device inventory identifier. + DeviceAssetTag string `protobuf:"bytes,30,opt,name=device_asset_tag,json=deviceAssetTag,proto3" json:"device_asset_tag,omitempty"` + // DeviceCredentialID is the identifier for the credential used by the device + // to authenticate itself. + DeviceCredentialId string `protobuf:"bytes,31,opt,name=device_credential_id,json=deviceCredentialId,proto3" json:"device_credential_id,omitempty"` + // GitHubUserID indicates the GitHub user ID identified by the GitHub + // connector. + GithubUserId string `protobuf:"bytes,32,opt,name=github_user_id,json=githubUserId,proto3" json:"github_user_id,omitempty"` + // GitHubUsername indicates the GitHub username identified by the GitHub + // connector. + GithubUsername string `protobuf:"bytes,33,opt,name=github_username,json=githubUsername,proto3" json:"github_username,omitempty"` } func (x *SSHIdentity) Reset() { @@ -71,6 +262,316 @@ func (*SSHIdentity) Descriptor() ([]byte, []int) { return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP(), []int{0} } +func (x *SSHIdentity) GetValidAfter() uint64 { + if x != nil { + return x.ValidAfter + } + return 0 +} + +func (x *SSHIdentity) GetValidBefore() uint64 { + if x != nil { + return x.ValidBefore + } + return 0 +} + +func (x *SSHIdentity) GetCertType() uint32 { + if x != nil { + return x.CertType + } + return 0 +} + +func (x *SSHIdentity) GetPrincipals() []string { + if x != nil { + return x.Principals + } + return nil +} + +func (x *SSHIdentity) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *SSHIdentity) GetSystemRole() string { + if x != nil { + return x.SystemRole + } + return "" +} + +func (x *SSHIdentity) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *SSHIdentity) GetImpersonator() string { + if x != nil { + return x.Impersonator + } + return "" +} + +func (x *SSHIdentity) GetPermitX11Forwarding() bool { + if x != nil { + return x.PermitX11Forwarding + } + return false +} + +func (x *SSHIdentity) GetPermitAgentForwarding() bool { + if x != nil { + return x.PermitAgentForwarding + } + return false +} + +func (x *SSHIdentity) GetPermitPortForwarding() bool { + if x != nil { + return x.PermitPortForwarding + } + return false +} + +func (x *SSHIdentity) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *SSHIdentity) GetRouteToCluster() string { + if x != nil { + return x.RouteToCluster + } + return "" +} + +func (x *SSHIdentity) GetTraits() []*v1.Trait { + if x != nil { + return x.Traits + } + return nil +} + +func (x *SSHIdentity) GetActiveRequests() []string { + if x != nil { + return x.ActiveRequests + } + return nil +} + +func (x *SSHIdentity) GetMfaVerified() string { + if x != nil { + return x.MfaVerified + } + return "" +} + +func (x *SSHIdentity) GetPreviousIdentityExpires() *timestamppb.Timestamp { + if x != nil { + return x.PreviousIdentityExpires + } + return nil +} + +func (x *SSHIdentity) GetLoginIp() string { + if x != nil { + return x.LoginIp + } + return "" +} + +func (x *SSHIdentity) GetPinnedIp() string { + if x != nil { + return x.PinnedIp + } + return "" +} + +func (x *SSHIdentity) GetDisallowReissue() bool { + if x != nil { + return x.DisallowReissue + } + return false +} + +func (x *SSHIdentity) GetCertificateExtensions() []*CertExtension { + if x != nil { + return x.CertificateExtensions + } + return nil +} + +func (x *SSHIdentity) GetRenewable() bool { + if x != nil { + return x.Renewable + } + return false +} + +func (x *SSHIdentity) GetGeneration() uint64 { + if x != nil { + return x.Generation + } + return 0 +} + +func (x *SSHIdentity) GetBotName() string { + if x != nil { + return x.BotName + } + return "" +} + +func (x *SSHIdentity) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + +func (x *SSHIdentity) GetAllowedResourceIds() []*ResourceId { + if x != nil { + return x.AllowedResourceIds + } + return nil +} + +func (x *SSHIdentity) GetConnectionDiagnosticId() string { + if x != nil { + return x.ConnectionDiagnosticId + } + return "" +} + +func (x *SSHIdentity) GetPrivateKeyPolicy() string { + if x != nil { + return x.PrivateKeyPolicy + } + return "" +} + +func (x *SSHIdentity) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *SSHIdentity) GetDeviceAssetTag() string { + if x != nil { + return x.DeviceAssetTag + } + return "" +} + +func (x *SSHIdentity) GetDeviceCredentialId() string { + if x != nil { + return x.DeviceCredentialId + } + return "" +} + +func (x *SSHIdentity) GetGithubUserId() string { + if x != nil { + return x.GithubUserId + } + return "" +} + +func (x *SSHIdentity) GetGithubUsername() string { + if x != nil { + return x.GithubUsername + } + return "" +} + +// CertExtension represents a key/value for a certificate extension. This type must +// be kept up to date with types.CertExtension. +type CertExtension struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Type represents the certificate type being extended, only ssh + // is supported at this time. + // 0 is "ssh". + Type CertExtensionType `protobuf:"varint,1,opt,name=type,proto3,enum=teleport.decision.v1alpha1.CertExtensionType" json:"type,omitempty"` + // Mode is the type of extension to be used -- currently + // critical-option is not supported. + // 0 is "extension". + Mode CertExtensionMode `protobuf:"varint,2,opt,name=mode,proto3,enum=teleport.decision.v1alpha1.CertExtensionMode" json:"mode,omitempty"` + // Name specifies the key to be used in the cert extension. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + // Value specifies the value to be used in the cert extension. + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *CertExtension) Reset() { + *x = CertExtension{} + mi := &file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CertExtension) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CertExtension) ProtoMessage() {} + +func (x *CertExtension) ProtoReflect() protoreflect.Message { + mi := &file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CertExtension.ProtoReflect.Descriptor instead. +func (*CertExtension) Descriptor() ([]byte, []int) { + return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP(), []int{1} +} + +func (x *CertExtension) GetType() CertExtensionType { + if x != nil { + return x.Type + } + return CertExtensionType_CERT_EXTENSION_TYPE_UNSPECIFIED +} + +func (x *CertExtension) GetMode() CertExtensionMode { + if x != nil { + return x.Mode + } + return CertExtensionMode_CERT_EXTENSION_MODE_UNSPECIFIED +} + +func (x *CertExtension) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CertExtension) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + var File_teleport_decision_v1alpha1_ssh_identity_proto protoreflect.FileDescriptor var file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc = []byte{ @@ -78,14 +579,134 @@ var file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x0d, 0x0a, 0x0b, 0x53, - 0x53, 0x48, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x5a, 0x5a, 0x58, 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, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x65, 0x63, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x74, 0x6c, 0x73, 0x5f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x72, 0x61, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x0b, 0x0a, 0x0b, 0x53, + 0x53, 0x48, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x08, 0x63, 0x65, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, + 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x69, + 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x12, + 0x32, 0x0a, 0x15, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x5f, 0x78, 0x31, 0x31, 0x5f, 0x66, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x58, 0x31, 0x31, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x5f, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x0e, 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, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, + 0x6d, 0x66, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x66, 0x61, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, + 0x56, 0x0a, 0x19, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x11, 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, 0x17, + 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x69, 0x6e, + 0x5f, 0x69, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x6e, + 0x49, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x49, 0x70, 0x12, + 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x69, 0x73, + 0x73, 0x75, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x69, 0x73, 0x73, 0x75, 0x65, 0x12, 0x60, 0x0a, 0x16, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x15, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, + 0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6f, + 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x6f, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x58, 0x0a, + 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x64, 0x52, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x5f, 0x69, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x49, + 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, + 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x1d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, + 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x54, 0x61, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x1f, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x27, + 0x0a, 0x0f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xbf, 0x01, 0x0a, 0x0d, 0x43, 0x65, 0x72, 0x74, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x5b, 0x0a, 0x11, 0x43, 0x65, 0x72, + 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x23, + 0x0a, 0x1f, 0x43, 0x45, 0x52, 0x54, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, + 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x45, 0x52, 0x54, 0x5f, 0x45, 0x58, 0x54, 0x45, + 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, + 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x2a, 0x55, 0x0a, 0x11, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x43, + 0x45, 0x52, 0x54, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x45, 0x52, 0x54, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, + 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x53, 0x48, 0x10, 0x01, 0x42, 0x5a, 0x5a, + 0x58, 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, 0x64, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -100,16 +721,29 @@ func file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescGZIP() []byte { return file_teleport_decision_v1alpha1_ssh_identity_proto_rawDescData } -var file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_decision_v1alpha1_ssh_identity_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_teleport_decision_v1alpha1_ssh_identity_proto_goTypes = []any{ - (*SSHIdentity)(nil), // 0: teleport.decision.v1alpha1.SSHIdentity + (CertExtensionMode)(0), // 0: teleport.decision.v1alpha1.CertExtensionMode + (CertExtensionType)(0), // 1: teleport.decision.v1alpha1.CertExtensionType + (*SSHIdentity)(nil), // 2: teleport.decision.v1alpha1.SSHIdentity + (*CertExtension)(nil), // 3: teleport.decision.v1alpha1.CertExtension + (*v1.Trait)(nil), // 4: teleport.trait.v1.Trait + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + (*ResourceId)(nil), // 6: teleport.decision.v1alpha1.ResourceId } var file_teleport_decision_v1alpha1_ssh_identity_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 4, // 0: teleport.decision.v1alpha1.SSHIdentity.traits:type_name -> teleport.trait.v1.Trait + 5, // 1: teleport.decision.v1alpha1.SSHIdentity.previous_identity_expires:type_name -> google.protobuf.Timestamp + 3, // 2: teleport.decision.v1alpha1.SSHIdentity.certificate_extensions:type_name -> teleport.decision.v1alpha1.CertExtension + 6, // 3: teleport.decision.v1alpha1.SSHIdentity.allowed_resource_ids:type_name -> teleport.decision.v1alpha1.ResourceId + 1, // 4: teleport.decision.v1alpha1.CertExtension.type:type_name -> teleport.decision.v1alpha1.CertExtensionType + 0, // 5: teleport.decision.v1alpha1.CertExtension.mode:type_name -> teleport.decision.v1alpha1.CertExtensionMode + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_teleport_decision_v1alpha1_ssh_identity_proto_init() } @@ -117,18 +751,20 @@ func file_teleport_decision_v1alpha1_ssh_identity_proto_init() { if File_teleport_decision_v1alpha1_ssh_identity_proto != nil { return } + file_teleport_decision_v1alpha1_tls_identity_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_decision_v1alpha1_ssh_identity_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, + NumEnums: 2, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, GoTypes: file_teleport_decision_v1alpha1_ssh_identity_proto_goTypes, DependencyIndexes: file_teleport_decision_v1alpha1_ssh_identity_proto_depIdxs, + EnumInfos: file_teleport_decision_v1alpha1_ssh_identity_proto_enumTypes, MessageInfos: file_teleport_decision_v1alpha1_ssh_identity_proto_msgTypes, }.Build() File_teleport_decision_v1alpha1_ssh_identity_proto = out.File diff --git a/api/proto/teleport/decision/v1alpha1/ssh_identity.proto b/api/proto/teleport/decision/v1alpha1/ssh_identity.proto index 01f4ea2af2d58..c63fa2f73850c 100644 --- a/api/proto/teleport/decision/v1alpha1/ssh_identity.proto +++ b/api/proto/teleport/decision/v1alpha1/ssh_identity.proto @@ -16,9 +16,174 @@ syntax = "proto3"; package teleport.decision.v1alpha1; +import "google/protobuf/timestamp.proto"; +import "teleport/decision/v1alpha1/tls_identity.proto"; +import "teleport/trait/v1/trait.proto"; + option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1;decisionpb"; // SSHIdentity is the identity used for SSH connections. message SSHIdentity { - // TBD + // --- common identity fields --- + + // ValidAfter is the unix timestamp that marks the start time for when the certificate should + // be considered valid. + uint64 valid_after = 1; + + // ValidBefore is the unix timestamp that marks the end time for when the certificate should + // be considered valid. + uint64 valid_before = 2; + + // CertType indicates what type of cert this is (user or host). + uint32 cert_type = 3; + + // Principals is the list of SSH principals associated with the certificate (this means the + // list of allowed unix logins in the case of user certs). + repeated string principals = 4; + + // --- host identity fields --- + + // ClusterName is the name of the cluster within which a node lives + string cluster_name = 5; + // SystemRole identifies the system role of a Teleport instance + string system_role = 6; + + // -- user identity fields --- + + // Username is teleport username + string username = 7; + + // Impersonator is set when a user requests certificate for another user + string impersonator = 8; + + // PermitX11Forwarding permits X11 forwarding for this cert + bool permit_x11_forwarding = 9; + + // PermitAgentForwarding permits agent forwarding for this cert + bool permit_agent_forwarding = 10; + + // PermitPortForwarding permits port forwarding. + bool permit_port_forwarding = 11; + + // Roles is a list of roles assigned to this user + repeated string roles = 12; + + // RouteToCluster specifies the target cluster + // if present in the certificate, will be used + // to route the requests to + string route_to_cluster = 13; + + // Traits hold claim data used to populate a role at runtime. + repeated teleport.trait.v1.Trait traits = 14; + + // ActiveRequests tracks privilege escalation requests applied during + // certificate construction. + repeated string active_requests = 15; + + // MFAVerified is the UUID of an MFA device when this Identity was + // confirmed immediately after an MFA check. + string mfa_verified = 16; + + // PreviousIdentityExpires is the expiry time of the identity/cert that this + // identity/cert was derived from. It is used to determine a session's hard + // deadline in cases where both require_session_mfa and disconnect_expired_cert + // are enabled. See https://github.com/gravitational/teleport/issues/18544. + google.protobuf.Timestamp previous_identity_expires = 17; + + // LoginIP is an observed IP of the client on the moment of certificate creation. + string login_ip = 18; + + // PinnedIP is an IP from which client must communicate with Teleport. + string pinned_ip = 19; + + // DisallowReissue flags that any attempt to request new certificates while + // authenticated with this cert should be denied. + bool disallow_reissue = 20; + + // CertificateExtensions are user configured ssh key extensions (note: this field also + // ends up aggregating all *unknown* extensions during cert parsing, meaning that this + // can sometimes contain fields that were inserted by a newer version of teleport). + repeated CertExtension certificate_extensions = 21; + + // Renewable indicates this certificate is renewable. + bool renewable = 22; + + // Generation counts the number of times a certificate has been renewed, with a generation of 1 + // meaning the cert has never been renewed. A generation of zero means the cert's generation is + // not being tracked. + uint64 generation = 23; + + // BotName is set to the name of the bot, if the user is a Machine ID bot user. + // Empty for human users. + string bot_name = 24; + + // BotInstanceID is the unique identifier for the bot instance, if this is a + // Machine ID bot. It is empty for human users. + string bot_instance_id = 25; + + // AllowedResourceIDs lists the resources the user should be able to access. + repeated ResourceId allowed_resource_ids = 26; + + // ConnectionDiagnosticID references the ConnectionDiagnostic that we should use to append traces when testing a Connection. + string connection_diagnostic_id = 27; + + // PrivateKeyPolicy is the private key policy supported by this certificate. + string private_key_policy = 28; + + // DeviceID is the trusted device identifier. + string device_id = 29; + + // DeviceAssetTag is the device inventory identifier. + string device_asset_tag = 30; + + // DeviceCredentialID is the identifier for the credential used by the device + // to authenticate itself. + string device_credential_id = 31; + + // GitHubUserID indicates the GitHub user ID identified by the GitHub + // connector. + string github_user_id = 32; + + // GitHubUsername indicates the GitHub username identified by the GitHub + // connector. + string github_username = 33; +} + +// CertExtensionMode specifies the type of extension to use in the cert. This type +// must be kept up to date with types.CertExtensionMode. +enum CertExtensionMode { + // CERT_EXTENSION_MODE_UNSPECIFIED is the default value and should not be used. + CERT_EXTENSION_MODE_UNSPECIFIED = 0; + + // EXTENSION represents a cert extension that may or may not be + // honored by the server. + CERT_EXTENSION_MODE_EXTENSION = 1; +} + +// CertExtensionType represents the certificate type the extension is for. +// Currently only ssh is supported. This type must be kept up to date with +// types.CertExtensionType. +enum CertExtensionType { + // CERT_EXTENSION_TYPE_UNSPECIFIED is the default value and should not be used. + CERT_EXTENSION_TYPE_UNSPECIFIED = 0; + + // SSH is used when extending an ssh certificate + CERT_EXTENSION_TYPE_SSH = 1; +} + +// CertExtension represents a key/value for a certificate extension. This type must +// be kept up to date with types.CertExtension. +message CertExtension { + // Type represents the certificate type being extended, only ssh + // is supported at this time. + // 0 is "ssh". + CertExtensionType type = 1; + // Mode is the type of extension to be used -- currently + // critical-option is not supported. + // 0 is "extension". + CertExtensionMode mode = 2; + // Name specifies the key to be used in the cert extension. + string name = 3; + // Value specifies the value to be used in the cert extension. + string value = 4; } diff --git a/integration/helpers/instance.go b/integration/helpers/instance.go index b132b027b3bef..60354d01c9ef6 100644 --- a/integration/helpers/instance.go +++ b/integration/helpers/instance.go @@ -67,6 +67,7 @@ import ( "github.com/gravitational/teleport/lib/service" "github.com/gravitational/teleport/lib/service/servicecfg" "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/sshca" "github.com/gravitational/teleport/lib/sshutils" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" @@ -365,14 +366,16 @@ func NewInstance(t *testing.T, cfg InstanceConfig) *TeleInstance { fatalIf(err) keygen := keygen.New(context.TODO()) - cert, err := keygen.GenerateHostCert(services.HostCertParams{ + cert, err := keygen.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: sshSigner, PublicHostKey: cfg.Pub, HostID: cfg.HostID, NodeName: cfg.NodeName, - ClusterName: cfg.ClusterName, - Role: types.RoleAdmin, TTL: 24 * time.Hour, + Identity: sshca.Identity{ + ClusterName: cfg.ClusterName, + SystemRole: types.RoleAdmin, + }, }) fatalIf(err) tlsCA, err := tlsca.FromKeys(tlsCACert, cfg.Priv) diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 2c727237da972..3a124a9fd6412 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -2120,20 +2120,22 @@ func (a *Server) GenerateHostCert(ctx context.Context, hostPublicKey []byte, hos } // create and sign! - return a.generateHostCert(ctx, services.HostCertParams{ + return a.generateHostCert(ctx, sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: hostPublicKey, HostID: hostID, NodeName: nodeName, - Principals: principals, - ClusterName: clusterName, - Role: role, TTL: ttl, + Identity: sshca.Identity{ + Principals: principals, + ClusterName: clusterName, + SystemRole: role, + }, }) } func (a *Server) generateHostCert( - ctx context.Context, p services.HostCertParams, + ctx context.Context, req sshca.HostCertificateRequest, ) ([]byte, error) { readOnlyAuthPref, err := a.GetReadOnlyAuthPreference(ctx) if err != nil { @@ -2141,7 +2143,7 @@ func (a *Server) generateHostCert( } var locks []types.LockTarget - switch p.Role { + switch req.Identity.SystemRole { case types.RoleNode: // Node role is a special case because it was previously suported as a // lock target that only locked the `ssh_service`. If the same Teleport server @@ -2154,9 +2156,9 @@ func (a *Server) generateHostCert( // and `Node` fields if the role is `Node` so that the previous behavior // is preserved. // This is a legacy behavior that we need to support for backwards compatibility. - locks = []types.LockTarget{{ServerID: p.HostID, Node: p.HostID}, {ServerID: HostFQDN(p.HostID, p.ClusterName), Node: HostFQDN(p.HostID, p.ClusterName)}} + locks = []types.LockTarget{{ServerID: req.HostID, Node: req.HostID}, {ServerID: HostFQDN(req.HostID, req.Identity.ClusterName), Node: HostFQDN(req.HostID, req.Identity.ClusterName)}} default: - locks = []types.LockTarget{{ServerID: p.HostID}, {ServerID: HostFQDN(p.HostID, p.ClusterName)}} + locks = []types.LockTarget{{ServerID: req.HostID}, {ServerID: HostFQDN(req.HostID, req.Identity.ClusterName)}} } if lockErr := a.checkLockInForce(readOnlyAuthPref.GetLockingMode(), locks, @@ -2164,7 +2166,7 @@ func (a *Server) generateHostCert( return nil, trace.Wrap(lockErr) } - return a.Authority.GenerateHostCert(p) + return a.Authority.GenerateHostCert(req) } // GetKeyStore returns the KeyStore used by the auth server @@ -2216,7 +2218,7 @@ type certRequest struct { traits wrappers.Traits // activeRequests tracks privilege escalation requests applied // during the construction of the certificate. - activeRequests services.RequestIDs + activeRequests []string // appSessionID is the session ID of the application session. appSessionID string // appPublicAddr is the public address of the application. @@ -3072,7 +3074,7 @@ func generateCert(ctx context.Context, a *Server, req certRequest, caType types. defaultMode: readOnlyAuthPref.GetLockingMode(), username: req.user.GetName(), mfaVerified: req.mfaVerified, - activeAccessRequests: req.activeRequests.AccessRequests, + activeAccessRequests: req.activeRequests, deviceID: req.deviceExtensions.DeviceID, }); err != nil { return nil, trace.Wrap(err) @@ -3201,11 +3203,6 @@ func generateCert(ctx context.Context, a *Server, req certRequest, caType types. // All users have access to this and join RBAC rules are checked after the connection is established. allowedLogins = append(allowedLogins, teleport.SSHSessionJoinPrincipal) - requestedResourcesStr, err := types.ResourceIDsToString(req.checker.GetAllowedResourceIDs()) - if err != nil { - return nil, trace.Wrap(err) - } - pinnedIP := "" if caType == types.UserCA && (req.checker.PinSourceIP() || req.pinIP) { if req.loginIP == "" { @@ -3245,7 +3242,7 @@ func generateCert(ctx context.Context, a *Server, req certRequest, caType types. Identity: sshca.Identity{ Username: req.user.GetName(), Impersonator: req.impersonator, - AllowedLogins: allowedLogins, + Principals: allowedLogins, Roles: req.checker.RoleNames(), PermitPortForwarding: req.checker.CanPortForward(), PermitAgentForwarding: req.checker.CanForwardAgents(), @@ -3263,7 +3260,7 @@ func generateCert(ctx context.Context, a *Server, req certRequest, caType types. BotName: req.botName, BotInstanceID: req.botInstanceID, CertificateExtensions: req.checker.CertificateExtensions(), - AllowedResourceIDs: requestedResourcesStr, + AllowedResourceIDs: req.checker.GetAllowedResourceIDs(), ConnectionDiagnosticID: req.connectionDiagnosticID, PrivateKeyPolicy: attestedKeyPolicy, DeviceID: req.deviceExtensions.DeviceID, @@ -3358,7 +3355,7 @@ func generateCert(ctx context.Context, a *Server, req certRequest, caType types. AWSRoleARNs: roleARNs, AzureIdentities: azureIdentities, GCPServiceAccounts: gcpAccounts, - ActiveRequests: req.activeRequests.AccessRequests, + ActiveRequests: req.activeRequests, DisallowReissue: req.disallowReissue, Renewable: req.renewable, Generation: req.generation, @@ -4703,14 +4700,16 @@ func (a *Server) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequ return nil, trace.Wrap(err) } // generate host SSH certificate - hostSSHCert, err := a.generateHostCert(ctx, services.HostCertParams{ + hostSSHCert, err := a.generateHostCert(ctx, sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: req.PublicSSHKey, HostID: req.HostID, NodeName: req.NodeName, - ClusterName: clusterName.GetClusterName(), - Role: req.Role, - Principals: req.AdditionalPrincipals, + Identity: sshca.Identity{ + ClusterName: clusterName.GetClusterName(), + SystemRole: req.Role, + Principals: req.AdditionalPrincipals, + }, }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index b9e9eb0a5aa8b..485490b7be37f 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -2646,7 +2646,7 @@ func TestGenerateUserCertWithLocks(t *testing.T) { mfaVerified: mfaID, sshPublicKey: sshPubKey, tlsPublicKey: tlsPubKey, - activeRequests: services.RequestIDs{AccessRequests: []string{requestID}}, + activeRequests: []string{requestID}, deviceExtensions: DeviceExtensions{ DeviceID: deviceID, AssetTag: "assettag1", diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index 50880b2e93d94..e365758f709a9 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -3413,11 +3413,9 @@ func (a *ServerWithRoles) generateUserCerts(ctx context.Context, req proto.UserC checker: checker, // Copy IP from current identity to the generated certificate, if present, // to avoid generateUserCerts() being used to drop IP pinning in the new certificates. - loginIP: a.context.Identity.GetIdentity().LoginIP, - traits: accessInfo.Traits, - activeRequests: services.RequestIDs{ - AccessRequests: req.AccessRequests, - }, + loginIP: a.context.Identity.GetIdentity().LoginIP, + traits: accessInfo.Traits, + activeRequests: req.AccessRequests, connectionDiagnosticID: req.ConnectionDiagnosticID, botName: getBotName(user), diff --git a/lib/auth/init_test.go b/lib/auth/init_test.go index 291458bd196e8..f4218479f302b 100644 --- a/lib/auth/init_test.go +++ b/lib/auth/init_test.go @@ -62,6 +62,7 @@ import ( "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/suite" "github.com/gravitational/teleport/lib/srv/db/common/databaseobjectimportrule" + "github.com/gravitational/teleport/lib/sshca" "github.com/gravitational/teleport/lib/sshutils" "github.com/gravitational/teleport/lib/utils" "github.com/gravitational/teleport/lib/utils/proxy" @@ -77,14 +78,16 @@ func TestReadIdentity(t *testing.T) { caSigner, err := ssh.ParsePrivateKey(priv) require.NoError(t, err) - cert, err := a.GenerateHostCert(services.HostCertParams{ + cert, err := a.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: pub, HostID: "id1", NodeName: "node-name", - ClusterName: "example.com", - Role: types.RoleNode, TTL: 0, + Identity: sshca.Identity{ + ClusterName: "example.com", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) @@ -98,14 +101,16 @@ func TestReadIdentity(t *testing.T) { // test TTL by converting the generated cert to text -> back and making sure ExpireAfter is valid ttl := 10 * time.Second expiryDate := clock.Now().Add(ttl) - bytes, err := a.GenerateHostCert(services.HostCertParams{ + bytes, err := a.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: pub, HostID: "id1", NodeName: "node-name", - ClusterName: "example.com", - Role: types.RoleNode, TTL: ttl, + Identity: sshca.Identity{ + ClusterName: "example.com", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) copy, err := apisshutils.ParseCertificate(bytes) @@ -125,14 +130,16 @@ func TestBadIdentity(t *testing.T) { require.IsType(t, trace.BadParameter(""), err) // missing authority domain - cert, err := a.GenerateHostCert(services.HostCertParams{ + cert, err := a.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: pub, HostID: "id2", NodeName: "", - ClusterName: "", - Role: types.RoleNode, TTL: 0, + Identity: sshca.Identity{ + ClusterName: "", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) @@ -140,14 +147,16 @@ func TestBadIdentity(t *testing.T) { require.IsType(t, trace.BadParameter(""), err) // missing host uuid - cert, err = a.GenerateHostCert(services.HostCertParams{ + cert, err = a.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: pub, HostID: "example.com", NodeName: "", - ClusterName: "", - Role: types.RoleNode, TTL: 0, + Identity: sshca.Identity{ + ClusterName: "", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) @@ -155,14 +164,16 @@ func TestBadIdentity(t *testing.T) { require.IsType(t, trace.BadParameter(""), err) // unrecognized role - cert, err = a.GenerateHostCert(services.HostCertParams{ + cert, err = a.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: pub, HostID: "example.com", NodeName: "", - ClusterName: "id1", - Role: "bad role", TTL: 0, + Identity: sshca.Identity{ + ClusterName: "id1", + SystemRole: "bad role", + }, }) require.NoError(t, err) diff --git a/lib/auth/keygen/keygen.go b/lib/auth/keygen/keygen.go index 5f47b3a90ac16..6133a90c907c7 100644 --- a/lib/auth/keygen/keygen.go +++ b/lib/auth/keygen/keygen.go @@ -33,9 +33,7 @@ import ( "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/lib/modules" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/sshca" - "github.com/gravitational/teleport/lib/utils" ) // Keygen is a key generator that precomputes keys to provide quick access to @@ -69,58 +67,64 @@ func New(_ context.Context, opts ...Option) *Keygen { // GenerateHostCert generates a host certificate with the passed in parameters. // The private key of the CA to sign the certificate must be provided. -func (k *Keygen) GenerateHostCert(c services.HostCertParams) ([]byte, error) { - if err := c.Check(); err != nil { +func (k *Keygen) GenerateHostCert(req sshca.HostCertificateRequest) ([]byte, error) { + if err := req.Check(); err != nil { return nil, trace.Wrap(err) } - return k.GenerateHostCertWithoutValidation(c) + return k.GenerateHostCertWithoutValidation(req) } // GenerateHostCertWithoutValidation generates a host certificate with the // passed in parameters without validating them. For use in tests only. -func (k *Keygen) GenerateHostCertWithoutValidation(c services.HostCertParams) ([]byte, error) { - pubKey, _, _, _, err := ssh.ParseAuthorizedKey(c.PublicHostKey) +func (k *Keygen) GenerateHostCertWithoutValidation(req sshca.HostCertificateRequest) ([]byte, error) { + pubKey, _, _, _, err := ssh.ParseAuthorizedKey(req.PublicHostKey) if err != nil { return nil, trace.Wrap(err) } + // create shallow copy of identity since we want to make some local changes + ident := req.Identity + + ident.CertType = ssh.HostCert + // Build a valid list of principals from the HostID and NodeName and then // add in any additional principals passed in. - principals := BuildPrincipals(c.HostID, c.NodeName, c.ClusterName, types.SystemRoles{c.Role}) - principals = append(principals, c.Principals...) + principals := BuildPrincipals(req.HostID, req.NodeName, ident.ClusterName, types.SystemRoles{ident.SystemRole}) + principals = append(principals, ident.Principals...) if len(principals) == 0 { - return nil, trace.BadParameter("no principals provided: %v, %v, %v", - c.HostID, c.NodeName, c.Principals) + return nil, trace.BadParameter("cannot generate host certificate without principals") } principals = apiutils.Deduplicate(principals) + ident.Principals = principals - // create certificate - validBefore := uint64(ssh.CertTimeInfinity) - if c.TTL != 0 { - b := k.clock.Now().UTC().Add(c.TTL) - validBefore = uint64(b.Unix()) + // calculate ValidBefore based on the outer request TTL + ident.ValidBefore = uint64(ssh.CertTimeInfinity) + if req.TTL != 0 { + b := k.clock.Now().UTC().Add(req.TTL) + ident.ValidBefore = uint64(b.Unix()) } - cert := &ssh.Certificate{ - ValidPrincipals: principals, - Key: pubKey, - ValidAfter: uint64(k.clock.Now().UTC().Add(-1 * time.Minute).Unix()), - ValidBefore: validBefore, - CertType: ssh.HostCert, + + ident.ValidAfter = uint64(k.clock.Now().UTC().Add(-1 * time.Minute).Unix()) + + // encode the identity into a certificate + cert, err := ident.Encode("") + if err != nil { + return nil, trace.Wrap(err) } - cert.Permissions.Extensions = make(map[string]string) - cert.Permissions.Extensions[utils.CertExtensionRole] = c.Role.String() - cert.Permissions.Extensions[utils.CertExtensionAuthority] = c.ClusterName + + // set the public key of the certificate + cert.Key = pubKey // sign host certificate with private signing key of certificate authority - if err := cert.SignCert(rand.Reader, c.CASigner); err != nil { + if err := cert.SignCert(rand.Reader, req.CASigner); err != nil { return nil, trace.Wrap(err) } slog.DebugContext( context.TODO(), "Generated SSH host certificate.", - "role", c.Role, "principals", principals, + "role", ident.SystemRole, "principals", ident.Principals, ) return ssh.MarshalAuthorizedKey(cert), nil } @@ -145,14 +149,7 @@ func (k *Keygen) GenerateUserCertWithoutValidation(req sshca.UserCertificateRequ // create shallow copy of identity since we want to make some local changes ident := req.Identity - // since this method ignores the supplied values for ValidBefore/ValidAfter, avoid confusing by - // rejecting identities where they are set. - if ident.ValidBefore != 0 { - return nil, trace.BadParameter("ValidBefore should not be set in calls to GenerateUserCert") - } - if ident.ValidAfter != 0 { - return nil, trace.BadParameter("ValidAfter should not be set in calls to GenerateUserCert") - } + ident.CertType = ssh.UserCert // calculate ValidBefore based on the outer request TTL ident.ValidBefore = uint64(ssh.CertTimeInfinity) @@ -162,7 +159,7 @@ func (k *Keygen) GenerateUserCertWithoutValidation(req sshca.UserCertificateRequ slog.DebugContext( context.TODO(), "Generated user key with expiry.", - "allowed_logins", ident.AllowedLogins, + "allowed_logins", ident.Principals, "valid_before_unix_ts", ident.ValidBefore, "valid_before", b, ) diff --git a/lib/auth/keygen/keygen_test.go b/lib/auth/keygen/keygen_test.go index d6c243b3ee986..e82933b944885 100644 --- a/lib/auth/keygen/keygen_test.go +++ b/lib/auth/keygen/keygen_test.go @@ -37,7 +37,6 @@ import ( "github.com/gravitational/teleport/api/utils/sshutils" "github.com/gravitational/teleport/lib/auth/test" "github.com/gravitational/teleport/lib/cryptosuites" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/sshca" ) @@ -176,16 +175,17 @@ func TestBuildPrincipals(t *testing.T) { // run tests for _, tc := range tests { t.Logf("Running test case: %q", tc.desc) - hostCertificateBytes, err := tt.suite.A.GenerateHostCert( - services.HostCertParams{ - CASigner: caSigner, - PublicHostKey: hostPublicKey, - HostID: tc.inHostID, - NodeName: tc.inNodeName, - ClusterName: tc.inClusterName, - Role: tc.inRole, - TTL: time.Hour, - }) + hostCertificateBytes, err := tt.suite.A.GenerateHostCert(sshca.HostCertificateRequest{ + CASigner: caSigner, + PublicHostKey: hostPublicKey, + HostID: tc.inHostID, + NodeName: tc.inNodeName, + TTL: time.Hour, + Identity: sshca.Identity{ + ClusterName: tc.inClusterName, + SystemRole: tc.inRole, + }, + }) require.NoError(t, err) hostCertificate, err := sshutils.ParseCertificate(hostCertificateBytes) @@ -233,9 +233,9 @@ func TestUserCertCompatibility(t *testing.T) { TTL: time.Hour, CertificateFormat: tc.inCompatibility, Identity: sshca.Identity{ - Username: "user", - AllowedLogins: []string{"centos", "root"}, - Roles: []string{"foo"}, + Username: "user", + Principals: []string{"centos", "root"}, + Roles: []string{"foo"}, CertificateExtensions: []*types.CertExtension{{ Type: types.CertExtensionType_SSH, Mode: types.CertExtensionMode_EXTENSION, diff --git a/lib/auth/sessions.go b/lib/auth/sessions.go index 5dac230331e20..7a20ec5653b53 100644 --- a/lib/auth/sessions.go +++ b/lib/auth/sessions.go @@ -291,7 +291,7 @@ func (a *Server) newWebSession( tlsPublicKey: tlsPublicKeyPEM, checker: checker, traits: req.Traits, - activeRequests: services.RequestIDs{AccessRequests: req.AccessRequests}, + activeRequests: req.AccessRequests, } var hasDeviceExtensions bool if opts != nil && opts.deviceExtensions != nil { @@ -560,7 +560,7 @@ func (a *Server) CreateAppSessionFromReq(ctx context.Context, req NewAppSessionR checker: checker, ttl: req.SessionTTL, traits: req.Traits, - activeRequests: services.RequestIDs{AccessRequests: req.AccessRequests}, + activeRequests: req.AccessRequests, // Set the app session ID in the certificate - used in auditing from the App Service. appSessionID: sessionID, // Only allow this certificate to be used for applications. diff --git a/lib/auth/test/suite.go b/lib/auth/test/suite.go index 14d22f8265647..ac1a9ee4cd2d1 100644 --- a/lib/auth/test/suite.go +++ b/lib/auth/test/suite.go @@ -64,16 +64,17 @@ func (s *AuthSuite) GenerateHostCert(t *testing.T) { caSigner, err := ssh.ParsePrivateKey(priv) require.NoError(t, err) - cert, err := s.A.GenerateHostCert( - services.HostCertParams{ - CASigner: caSigner, - PublicHostKey: pub, - HostID: "00000000-0000-0000-0000-000000000000", - NodeName: "auth.example.com", - ClusterName: "example.com", - Role: types.RoleAdmin, - TTL: time.Hour, - }) + cert, err := s.A.GenerateHostCert(sshca.HostCertificateRequest{ + CASigner: caSigner, + PublicHostKey: pub, + HostID: "00000000-0000-0000-0000-000000000000", + NodeName: "auth.example.com", + TTL: time.Hour, + Identity: sshca.Identity{ + ClusterName: "example.com", + SystemRole: types.RoleAdmin, + }, + }) require.NoError(t, err) certificate, err := sshutils.ParseCertificate(cert) @@ -102,7 +103,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ Username: "user", - AllowedLogins: []string{"centos", "root"}, + Principals: []string{"centos", "root"}, PermitAgentForwarding: true, PermitPortForwarding: true, }, @@ -121,7 +122,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ Username: "user", - AllowedLogins: []string{"root"}, + Principals: []string{"root"}, PermitAgentForwarding: true, PermitPortForwarding: true, }, @@ -137,7 +138,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ Username: "user", - AllowedLogins: []string{"root"}, + Principals: []string{"root"}, PermitAgentForwarding: true, PermitPortForwarding: true, }, @@ -153,7 +154,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ Username: "user", - AllowedLogins: []string{"root"}, + Principals: []string{"root"}, PermitAgentForwarding: true, PermitPortForwarding: true, }, @@ -170,7 +171,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { Identity: sshca.Identity{ Username: "user", Impersonator: impersonator, - AllowedLogins: []string{"root"}, + Principals: []string{"root"}, PermitAgentForwarding: true, PermitPortForwarding: true, Roles: inRoles, @@ -195,7 +196,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ Username: "user", - AllowedLogins: []string{"root"}, + Principals: []string{"root"}, MFAVerified: "mfa-device-id", PreviousIdentityExpires: clock.Now().Add(time.Hour), }, @@ -219,7 +220,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { PublicUserKey: pub, // Required. Identity: sshca.Identity{ Username: "llama", // Required. - AllowedLogins: []string{"llama"}, // Required. + Principals: []string{"llama"}, // Required. DeviceID: devID, DeviceAssetTag: devTag, DeviceCredentialID: devCred, @@ -242,7 +243,7 @@ func (s *AuthSuite) GenerateUserCert(t *testing.T) { PublicUserKey: pub, // Required. Identity: sshca.Identity{ Username: "llama", // Required. - AllowedLogins: []string{"llama"}, // Required. + Principals: []string{"llama"}, // Required. GitHubUserID: githubUserID, GitHubUsername: githubUsername, }, diff --git a/lib/auth/testauthority/testauthority.go b/lib/auth/testauthority/testauthority.go index b58f9ac27493d..dbb14c56c20cb 100644 --- a/lib/auth/testauthority/testauthority.go +++ b/lib/auth/testauthority/testauthority.go @@ -28,7 +28,6 @@ import ( "github.com/gravitational/teleport/lib/auth/keygen" "github.com/gravitational/teleport/lib/cryptosuites" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/sshca" ) @@ -57,8 +56,8 @@ func (n *Keygen) GenerateKeyPair() (priv []byte, pub []byte, err error) { return privateKey.PrivateKeyPEM(), privateKey.MarshalSSHPublicKey(), nil } -func (n *Keygen) GenerateHostCert(c services.HostCertParams) ([]byte, error) { - return n.GenerateHostCertWithoutValidation(c) +func (n *Keygen) GenerateHostCert(req sshca.HostCertificateRequest) ([]byte, error) { + return n.GenerateHostCertWithoutValidation(req) } func (n *Keygen) GenerateUserCert(c sshca.UserCertificateRequest) ([]byte, error) { diff --git a/lib/client/client_store_test.go b/lib/client/client_store_test.go index 71239884aaaba..f62aaefeacf00 100644 --- a/lib/client/client_store_test.go +++ b/lib/client/client_store_test.go @@ -44,7 +44,6 @@ import ( "github.com/gravitational/teleport/lib/auth/testauthority" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/defaults" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/sshca" "github.com/gravitational/teleport/lib/sshutils" "github.com/gravitational/teleport/lib/tlsca" @@ -111,7 +110,7 @@ func (s *testAuthority) makeSignedKeyRing(t *testing.T, idx KeyRingIndex, makeEx TTL: ttl, Identity: sshca.Identity{ Username: idx.Username, - AllowedLogins: allowedLogins, + Principals: allowedLogins, PermitAgentForwarding: false, PermitPortForwarding: true, GitHubUserID: "1234567", @@ -311,13 +310,15 @@ func TestProxySSHConfig(t *testing.T) { caSigner, err := ssh.ParsePrivateKey(CAPriv) require.NoError(t, err) - hostCert, err := auth.keygen.GenerateHostCert(services.HostCertParams{ + hostCert, err := auth.keygen.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: hostPub, HostID: "127.0.0.1", NodeName: "127.0.0.1", - ClusterName: "host-cluster-name", - Role: types.RoleNode, + Identity: sshca.Identity{ + ClusterName: "host-cluster-name", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) diff --git a/lib/client/identityfile/identity_test.go b/lib/client/identityfile/identity_test.go index 9d8eeb62a894d..fe1d9df9a9857 100644 --- a/lib/client/identityfile/identity_test.go +++ b/lib/client/identityfile/identity_test.go @@ -112,8 +112,8 @@ func newClientKeyRing(t *testing.T, modifiers ...func(*tlsca.Identity)) *client. CASigner: caSigner, PublicUserKey: ssh.MarshalAuthorizedKey(privateKey.SSHPublicKey()), Identity: sshca.Identity{ - Username: "testuser", - AllowedLogins: []string{"testuser"}, + Username: "testuser", + Principals: []string{"testuser"}, }, }) require.NoError(t, err) diff --git a/lib/client/keyagent_test.go b/lib/client/keyagent_test.go index cbf313591e4d9..20f95bb7e9c6f 100644 --- a/lib/client/keyagent_test.go +++ b/lib/client/keyagent_test.go @@ -49,7 +49,6 @@ import ( "github.com/gravitational/teleport/lib/auth/testauthority" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/fixtures" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/sshca" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" @@ -366,17 +365,19 @@ func TestHostCertVerification(t *testing.T) { // Generate a host certificate for node with role "node". _, rootHostPub, err := keygen.GenerateKeyPair() require.NoError(t, err) - rootHostCertBytes, err := keygen.GenerateHostCert(services.HostCertParams{ + rootHostCertBytes, err := keygen.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: root.signer, PublicHostKey: rootHostPub, HostID: "5ff40d80-9007-4f28-8f49-7d4fda2f574d", NodeName: "server01", - Principals: []string{ - "127.0.0.1", + TTL: 1 * time.Hour, + Identity: sshca.Identity{ + Principals: []string{ + "127.0.0.1", + }, + ClusterName: "example.com", + SystemRole: types.RoleNode, }, - ClusterName: "example.com", - Role: types.RoleNode, - TTL: 1 * time.Hour, }) require.NoError(t, err) rootHostPublicKey, _, _, _, err := ssh.ParseAuthorizedKey(rootHostCertBytes) @@ -384,14 +385,16 @@ func TestHostCertVerification(t *testing.T) { _, leafHostPub, err := keygen.GenerateKeyPair() require.NoError(t, err) - leafHostCertBytes, err := keygen.GenerateHostCert(services.HostCertParams{ + leafHostCertBytes, err := keygen.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: leaf.signer, PublicHostKey: leafHostPub, HostID: "620bb71c-c9eb-4f6d-9823-f7d9125ebb1d", NodeName: "server02", - ClusterName: "leaf.example.com", - Role: types.RoleNode, TTL: 1 * time.Hour, + Identity: sshca.Identity{ + ClusterName: "leaf.example.com", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) leafHostPublicKey, _, _, _, err := ssh.ParseAuthorizedKey(leafHostCertBytes) @@ -620,14 +623,16 @@ func TestHostCertVerificationLoadAllCasProxyAddrEqClusterName(t *testing.T) { func mustGenerateHostPublicCert(t *testing.T, keygen *testauthority.Keygen, signer ssh.Signer, nodeName, clusterName string) ssh.PublicKey { _, leafHostPub, err := keygen.GenerateKeyPair() require.NoError(t, err) - leafHostCertBytes, err := keygen.GenerateHostCert(services.HostCertParams{ + leafHostCertBytes, err := keygen.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: signer, PublicHostKey: leafHostPub, HostID: uuid.NewString(), NodeName: nodeName, - ClusterName: clusterName, - Role: types.RoleNode, TTL: 1 * time.Hour, + Identity: sshca.Identity{ + ClusterName: clusterName, + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) leafCerts, err := sshutils.ParseAuthorizedKeys([][]byte{leafHostCertBytes}) @@ -759,7 +764,7 @@ func (s *KeyAgentTestSuite) makeKeyRing(t *testing.T, username, proxyHost string TTL: ttl, Identity: sshca.Identity{ Username: username, - AllowedLogins: []string{username}, + Principals: []string{username}, PermitAgentForwarding: true, PermitPortForwarding: true, RouteToCluster: s.clusterName, diff --git a/lib/client/known_hosts_migrate_test.go b/lib/client/known_hosts_migrate_test.go index 612e7d3082f06..cba71bda212d6 100644 --- a/lib/client/known_hosts_migrate_test.go +++ b/lib/client/known_hosts_migrate_test.go @@ -28,7 +28,7 @@ import ( "golang.org/x/crypto/ssh" "github.com/gravitational/teleport/lib/auth/testauthority" - "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/sshca" ) type knownHostsMigrateTest struct { @@ -48,12 +48,14 @@ func generateHostCert(t *testing.T, s *knownHostsMigrateTest, clusterName string caSigner, err := ssh.ParsePrivateKey(CAPriv) require.NoError(t, err) - cert, err := s.keygen.GenerateHostCert(services.HostCertParams{ + cert, err := s.keygen.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, HostID: "127.0.0.1", NodeName: "127.0.0.1", - ClusterName: clusterName, PublicHostKey: hostPub, + Identity: sshca.Identity{ + ClusterName: clusterName, + }, }) require.NoError(t, err) diff --git a/lib/decision/ssh_identity.go b/lib/decision/ssh_identity.go new file mode 100644 index 0000000000000..0bf120d5307a2 --- /dev/null +++ b/lib/decision/ssh_identity.go @@ -0,0 +1,143 @@ +// Teleport +// Copyright (C) 2025 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 decision + +import ( + decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/keys" + "github.com/gravitational/teleport/lib/sshca" +) + +// SSHIdentityToSSHCA transforms a [decisionpb.SSHIdentity] into its +// equivalent [sshca.Identity]. +// Note that certain types, like slices, are not deep-copied. +func SSHIdentityToSSHCA(id *decisionpb.SSHIdentity) *sshca.Identity { + if id == nil { + return nil + } + + return &sshca.Identity{ + ValidAfter: id.ValidAfter, + ValidBefore: id.ValidBefore, + CertType: id.CertType, + ClusterName: id.ClusterName, + SystemRole: types.SystemRole(id.SystemRole), + Username: id.Username, + Impersonator: id.Impersonator, + Principals: id.Principals, + PermitX11Forwarding: id.PermitX11Forwarding, + PermitAgentForwarding: id.PermitAgentForwarding, + PermitPortForwarding: id.PermitPortForwarding, + Roles: id.Roles, + RouteToCluster: id.RouteToCluster, + Traits: traitToWrappers(id.Traits), + ActiveRequests: id.ActiveRequests, + MFAVerified: id.MfaVerified, + PreviousIdentityExpires: timestampToGoTime(id.PreviousIdentityExpires), + LoginIP: id.LoginIp, + PinnedIP: id.PinnedIp, + DisallowReissue: id.DisallowReissue, + CertificateExtensions: certExtensionsFromProto(id.CertificateExtensions), + Renewable: id.Renewable, + Generation: id.Generation, + BotName: id.BotName, + BotInstanceID: id.BotInstanceId, + AllowedResourceIDs: resourceIDsToTypes(id.AllowedResourceIds), + ConnectionDiagnosticID: id.ConnectionDiagnosticId, + PrivateKeyPolicy: keys.PrivateKeyPolicy(id.PrivateKeyPolicy), + DeviceID: id.DeviceId, + DeviceAssetTag: id.DeviceAssetTag, + DeviceCredentialID: id.DeviceCredentialId, + GitHubUserID: id.GithubUserId, + GitHubUsername: id.GithubUsername, + } +} + +func SSHIdentityFromSSHCA(id *sshca.Identity) *decisionpb.SSHIdentity { + if id == nil { + return nil + } + + return &decisionpb.SSHIdentity{ + ValidAfter: id.ValidAfter, + ValidBefore: id.ValidBefore, + CertType: id.CertType, + ClusterName: id.ClusterName, + SystemRole: string(id.SystemRole), + Username: id.Username, + Impersonator: id.Impersonator, + Principals: id.Principals, + PermitX11Forwarding: id.PermitX11Forwarding, + PermitAgentForwarding: id.PermitAgentForwarding, + PermitPortForwarding: id.PermitPortForwarding, + Roles: id.Roles, + RouteToCluster: id.RouteToCluster, + Traits: traitFromWrappers(id.Traits), + ActiveRequests: id.ActiveRequests, + MfaVerified: id.MFAVerified, + PreviousIdentityExpires: timestampFromGoTime(id.PreviousIdentityExpires), + LoginIp: id.LoginIP, + PinnedIp: id.PinnedIP, + DisallowReissue: id.DisallowReissue, + CertificateExtensions: certExtensionsToProto(id.CertificateExtensions), + Renewable: id.Renewable, + Generation: id.Generation, + BotName: id.BotName, + BotInstanceId: id.BotInstanceID, + AllowedResourceIds: resourceIDsFromTypes(id.AllowedResourceIDs), + ConnectionDiagnosticId: id.ConnectionDiagnosticID, + PrivateKeyPolicy: string(id.PrivateKeyPolicy), + DeviceId: id.DeviceID, + DeviceAssetTag: id.DeviceAssetTag, + DeviceCredentialId: id.DeviceCredentialID, + GithubUserId: id.GitHubUserID, + GithubUsername: id.GitHubUsername, + } +} + +func certExtensionsFromProto(extensions []*decisionpb.CertExtension) []*types.CertExtension { + if len(extensions) == 0 { + return nil + } + out := make([]*types.CertExtension, 0, len(extensions)) + for _, extension := range extensions { + out = append(out, &types.CertExtension{ + Mode: types.CertExtensionMode(int32(extension.Mode) - 1), // enum is equivalent but off by 1 + Type: types.CertExtensionType(int32(extension.Type) - 1), // enum is equivalent but off by 1 + Name: extension.Name, + Value: extension.Value, + }) + } + return out +} + +func certExtensionsToProto(extensions []*types.CertExtension) []*decisionpb.CertExtension { + if len(extensions) == 0 { + return nil + } + out := make([]*decisionpb.CertExtension, 0, len(extensions)) + for _, extension := range extensions { + out = append(out, &decisionpb.CertExtension{ + Mode: decisionpb.CertExtensionMode(int32(extension.Mode) + 1), // enum is equivalent but off by 1 + Type: decisionpb.CertExtensionType(int32(extension.Type) + 1), // enum is equivalent but off by 1 + Name: extension.Name, + Value: extension.Value, + }) + } + return out +} diff --git a/lib/decision/ssh_identity_test.go b/lib/decision/ssh_identity_test.go new file mode 100644 index 0000000000000..9bd1412143010 --- /dev/null +++ b/lib/decision/ssh_identity_test.go @@ -0,0 +1,101 @@ +// Teleport +// Copyright (C) 2025 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 decision + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/wrappers" + "github.com/gravitational/teleport/api/utils/keys" + "github.com/gravitational/teleport/lib/sshca" + "github.com/gravitational/teleport/lib/utils/testutils" +) + +func TestSSHIdentityConversion(t *testing.T) { + ident := &sshca.Identity{ + ValidAfter: 1, + ValidBefore: 2, + CertType: ssh.UserCert, + ClusterName: "some-cluster", + SystemRole: types.RoleNode, + Username: "user", + Impersonator: "impersonator", + Principals: []string{"login1", "login2"}, + PermitX11Forwarding: true, + PermitAgentForwarding: true, + PermitPortForwarding: true, + Roles: []string{"role1", "role2"}, + RouteToCluster: "cluster", + Traits: wrappers.Traits{"trait1": []string{"value1"}, "trait2": []string{"value2"}}, + ActiveRequests: []string{uuid.NewString()}, + MFAVerified: "mfa", + PreviousIdentityExpires: time.Unix(12345, 0), + LoginIP: "127.0.0.1", + PinnedIP: "127.0.0.1", + DisallowReissue: true, + CertificateExtensions: []*types.CertExtension{&types.CertExtension{ + Name: "extname", + Value: "extvalue", + Type: types.CertExtensionType_SSH, + Mode: types.CertExtensionMode_EXTENSION, + }}, + Renewable: true, + Generation: 3, + BotName: "bot", + BotInstanceID: "instance", + AllowedResourceIDs: []types.ResourceID{{ + ClusterName: "cluster", + Kind: types.KindKubePod, // must use a kube resource kind for parsing of sub-resource to work correctly + Name: "name", + SubResourceName: "sub/sub", + }}, + ConnectionDiagnosticID: "diag", + PrivateKeyPolicy: keys.PrivateKeyPolicy("policy"), + DeviceID: "device", + DeviceAssetTag: "asset", + DeviceCredentialID: "cred", + GitHubUserID: "github", + GitHubUsername: "ghuser", + } + + ignores := []string{ + "CertExtension.Type", // only currently defined enum variant is a zero value + "CertExtension.Mode", // only currently defined enum variant is a zero value + // TODO(fspmarshall): figure out a mechanism for making ignore of grpc fields more convenient + "CertExtension.XXX_NoUnkeyedLiteral", + "CertExtension.XXX_unrecognized", + "CertExtension.XXX_sizecache", + "ResourceID.XXX_NoUnkeyedLiteral", + "ResourceID.XXX_unrecognized", + "ResourceID.XXX_sizecache", + } + + require.True(t, testutils.ExhaustiveNonEmpty(ident, ignores...), "empty=%+v", testutils.FindAllEmpty(ident, ignores...)) + + proto := SSHIdentityFromSSHCA(ident) + + ident2 := SSHIdentityToSSHCA(proto) + + require.Empty(t, cmp.Diff(ident, ident2)) +} diff --git a/lib/reversetunnel/srv_test.go b/lib/reversetunnel/srv_test.go index 5d4a62e485eab..c21f9fa25247f 100644 --- a/lib/reversetunnel/srv_test.go +++ b/lib/reversetunnel/srv_test.go @@ -39,7 +39,6 @@ import ( "github.com/gravitational/teleport/api/utils/sshutils" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/testauthority" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/sshca" "github.com/gravitational/teleport/lib/utils" ) @@ -81,13 +80,15 @@ func TestServerKeyAuth(t *testing.T) { { desc: "host cert", key: func() ssh.PublicKey { - rawCert, err := ta.GenerateHostCert(services.HostCertParams{ + rawCert, err := ta.GenerateHostCert(sshca.HostCertificateRequest{ CASigner: caSigner, PublicHostKey: pub, HostID: "host-id", NodeName: con.User(), - ClusterName: "host-cluster-name", - Role: types.RoleNode, + Identity: sshca.Identity{ + ClusterName: "host-cluster-name", + SystemRole: types.RoleNode, + }, }) require.NoError(t, err) key, _, _, _, err := ssh.ParseAuthorizedKey(rawCert) @@ -112,7 +113,7 @@ func TestServerKeyAuth(t *testing.T) { TTL: time.Minute, Identity: sshca.Identity{ Username: con.User(), - AllowedLogins: []string{con.User()}, + Principals: []string{con.User()}, Roles: []string{"dev", "admin"}, RouteToCluster: "user-cluster-name", }, diff --git a/lib/services/authority.go b/lib/services/authority.go index 2345342b1195b..bd04c8c7c284a 100644 --- a/lib/services/authority.go +++ b/lib/services/authority.go @@ -23,14 +23,12 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" - "time" "github.com/gogo/protobuf/proto" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "golang.org/x/crypto/ssh" "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" @@ -279,46 +277,6 @@ func GetSSHCheckingKeys(ca types.CertAuthority) [][]byte { return out } -// HostCertParams defines all parameters needed to generate a host certificate -type HostCertParams struct { - // CASigner is the signer that will sign the public key of the host with the CA private key. - CASigner ssh.Signer - // PublicHostKey is the public key of the host - PublicHostKey []byte - // HostID is used by Teleport to uniquely identify a node within a cluster - HostID string - // Principals is a list of additional principals to add to the certificate. - Principals []string - // NodeName is the DNS name of the node - NodeName string - // ClusterName is the name of the cluster within which a node lives - ClusterName string - // Role identifies the role of a Teleport instance - Role types.SystemRole - // TTL defines how long a certificate is valid for - TTL time.Duration -} - -// Check checks parameters for errors -func (c HostCertParams) Check() error { - if c.CASigner == nil { - return trace.BadParameter("CASigner is required") - } - if c.HostID == "" && len(c.Principals) == 0 { - return trace.BadParameter("HostID [%q] or Principals [%q] are required", - c.HostID, c.Principals) - } - if c.ClusterName == "" { - return trace.BadParameter("ClusterName [%q] is required", c.ClusterName) - } - - if err := c.Role.Check(); err != nil { - return trace.Wrap(err) - } - - return nil -} - // CertPoolFromCertAuthorities returns a certificate pool from the TLS certificates // set up in the certificate authorities list, as well as the number of certificates // that were added to the pool. diff --git a/lib/srv/authhandlers_test.go b/lib/srv/authhandlers_test.go index 8e009819e2108..9c5ce5b43b1d7 100644 --- a/lib/srv/authhandlers_test.go +++ b/lib/srv/authhandlers_test.go @@ -220,8 +220,8 @@ func TestRBAC(t *testing.T) { CASigner: caSigner, PublicUserKey: ssh.MarshalAuthorizedKey(privateKey.SSHPublicKey()), Identity: sshca.Identity{ - Username: "testuser", - AllowedLogins: []string{"testuser"}, + Username: "testuser", + Principals: []string{"testuser"}, }, }) require.NoError(t, err) @@ -395,8 +395,8 @@ func TestRBACJoinMFA(t *testing.T) { PublicUserKey: privateKey.MarshalSSHPublicKey(), CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ - Username: username, - AllowedLogins: []string{username}, + Username: username, + Principals: []string{username}, Traits: wrappers.Traits{ teleport.TraitInternalPrefix: []string{""}, }, diff --git a/lib/srv/git/forward_test.go b/lib/srv/git/forward_test.go index 3b4438cfa3a99..4ea3566bd9744 100644 --- a/lib/srv/git/forward_test.go +++ b/lib/srv/git/forward_test.go @@ -282,11 +282,11 @@ func makeUserCert(t *testing.T, caSigner ssh.Signer) ssh.Signer { PublicUserKey: clientPrivateKey.MarshalSSHPublicKey(), CertificateFormat: constants.CertificateFormatStandard, Identity: sshca.Identity{ - Username: "alice", - AllowedLogins: []string{"does-not-matter"}, - GitHubUserID: "1234567", - Traits: wrappers.Traits{}, - Roles: []string{"editor"}, + Username: "alice", + Principals: []string{"does-not-matter"}, + GitHubUserID: "1234567", + Traits: wrappers.Traits{}, + Roles: []string{"editor"}, }, }) require.NoError(t, err) diff --git a/lib/sshca/identity.go b/lib/sshca/identity.go index 762aa701c206c..f927b1354544f 100644 --- a/lib/sshca/identity.go +++ b/lib/sshca/identity.go @@ -35,22 +35,39 @@ import ( "github.com/gravitational/teleport/api/types/wrappers" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/utils" ) // Identity is a user identity. All identity fields map directly to an ssh certificate field. type Identity struct { + + // --- common identity fields --- + // ValidAfter is the unix timestamp that marks the start time for when the certificate should // be considered valid. ValidAfter uint64 // ValidBefore is the unix timestamp that marks the end time for when the certificate should // be considered valid. ValidBefore uint64 + // CertType indicates what type of cert this is (user or host). + CertType uint32 + // Principals is the list of SSH principals associated with the certificate (this means the + // list of allowed unix logins in the case of user certs). + Principals []string + + // --- host identity fields --- + + // ClusterName is the name of the cluster within which a node lives + ClusterName string + // SystemRole identifies the system role of a Teleport instance + SystemRole types.SystemRole + + // -- user identity fields --- + // Username is teleport username Username string // Impersonator is set when a user requests certificate for another user Impersonator string - // AllowedLogins is a list of SSH principals - AllowedLogins []string // PermitX11Forwarding permits X11 forwarding for this cert PermitX11Forwarding bool // PermitAgentForwarding permits agent forwarding for this cert @@ -67,7 +84,7 @@ type Identity struct { Traits wrappers.Traits // ActiveRequests tracks privilege escalation requests applied during // certificate construction. - ActiveRequests services.RequestIDs + ActiveRequests []string // MFAVerified is the UUID of an MFA device when this Identity was // confirmed immediately after an MFA check. MFAVerified string @@ -100,7 +117,7 @@ type Identity struct { // Machine ID bot. It is empty for human users. BotInstanceID string // AllowedResourceIDs lists the resources the user should be able to access. - AllowedResourceIDs string + AllowedResourceIDs []types.ResourceID // ConnectionDiagnosticID references the ConnectionDiagnostic that we should use to append traces when testing a Connection. ConnectionDiagnosticID string // PrivateKeyPolicy is the private key policy supported by this certificate. @@ -120,15 +137,6 @@ type Identity struct { GitHubUsername string } -// Check performs validation of certain fields in the identity. -func (i *Identity) Check() error { - if len(i.AllowedLogins) == 0 { - return trace.BadParameter("ssh user identity missing allowed logins") - } - - return nil -} - // Encode encodes the identity into an ssh certificate. Note that the returned certificate is incomplete // and must be have its public key set before signing. func (i *Identity) Encode(certFormat string) (*ssh.Certificate, error) { @@ -140,18 +148,38 @@ func (i *Identity) Encode(certFormat string) (*ssh.Certificate, error) { if validAfter == 0 { validAfter = uint64(time.Now().UTC().Add(-1 * time.Minute).Unix()) } + + if i.CertType == 0 { + return nil, trace.BadParameter("cannot encode ssh identity missing required field CertType") + } + cert := &ssh.Certificate{ // we have to use key id to identify teleport user KeyId: i.Username, - ValidPrincipals: i.AllowedLogins, + ValidPrincipals: i.Principals, ValidAfter: validAfter, ValidBefore: validBefore, - CertType: ssh.UserCert, + CertType: i.CertType, + } + + cert.Permissions.Extensions = make(map[string]string) + + if i.CertType == ssh.UserCert { + cert.Permissions.Extensions[teleport.CertExtensionPermitPTY] = "" + } + + // --- host extensions --- + + if sr := i.SystemRole.String(); sr != "" { + cert.Permissions.Extensions[utils.CertExtensionRole] = sr } - cert.Permissions.Extensions = map[string]string{ - teleport.CertExtensionPermitPTY: "", + + if i.ClusterName != "" { + cert.Permissions.Extensions[utils.CertExtensionAuthority] = i.ClusterName } + // --- user extensions --- + if i.PermitX11Forwarding { cert.Permissions.Extensions[teleport.CertExtensionPermitX11Forwarding] = "" } @@ -188,8 +216,12 @@ func (i *Identity) Encode(certFormat string) (*ssh.Certificate, error) { if i.BotInstanceID != "" { cert.Permissions.Extensions[teleport.CertExtensionBotInstanceID] = i.BotInstanceID } - if i.AllowedResourceIDs != "" { - cert.Permissions.Extensions[teleport.CertExtensionAllowedResources] = i.AllowedResourceIDs + if len(i.AllowedResourceIDs) != 0 { + requestedResourcesStr, err := types.ResourceIDsToString(i.AllowedResourceIDs) + if err != nil { + return nil, trace.Wrap(err) + } + cert.Permissions.Extensions[teleport.CertExtensionAllowedResources] = requestedResourcesStr } if i.ConnectionDiagnosticID != "" { cert.Permissions.Extensions[teleport.CertExtensionConnectionDiagnosticID] = i.ConnectionDiagnosticID @@ -257,8 +289,11 @@ func (i *Identity) Encode(certFormat string) (*ssh.Certificate, error) { if i.RouteToCluster != "" { cert.Permissions.Extensions[teleport.CertExtensionTeleportRouteToCluster] = i.RouteToCluster } - if !i.ActiveRequests.IsEmpty() { - requests, err := i.ActiveRequests.Marshal() + if len(i.ActiveRequests) != 0 { + reqs := services.RequestIDs{ + AccessRequests: i.ActiveRequests, + } + requests, err := reqs.Marshal() if err != nil { return nil, trace.Wrap(err) } @@ -271,14 +306,12 @@ func (i *Identity) Encode(certFormat string) (*ssh.Certificate, error) { // DecodeIdentity decodes an ssh certificate into an identity. func DecodeIdentity(cert *ssh.Certificate) (*Identity, error) { - if cert.CertType != ssh.UserCert { - return nil, trace.BadParameter("DecodeIdentity intended for use with user certs, got %v", cert.CertType) - } ident := &Identity{ - Username: cert.KeyId, - AllowedLogins: cert.ValidPrincipals, - ValidAfter: cert.ValidAfter, - ValidBefore: cert.ValidBefore, + Username: cert.KeyId, + Principals: cert.ValidPrincipals, + ValidAfter: cert.ValidAfter, + ValidBefore: cert.ValidBefore, + CertType: cert.CertType, } // clone the extension map and remove entries from the clone as they are processed so @@ -304,9 +337,19 @@ func DecodeIdentity(cert *ssh.Certificate) (*Identity, error) { return ok } - // ignore the permit pty extension, it's always set + // ignore the permit pty extension, teleport considers this permission implied for all users _, _ = takeExtension(teleport.CertExtensionPermitPTY) + // --- host extensions --- + + if v, ok := takeExtension(utils.CertExtensionRole); ok { + ident.SystemRole = types.SystemRole(v) + } + + ident.ClusterName = takeValue(utils.CertExtensionAuthority) + + // --- user extensions --- + ident.PermitX11Forwarding = takeBool(teleport.CertExtensionPermitX11Forwarding) ident.PermitAgentForwarding = takeBool(teleport.CertExtensionPermitAgentForwarding) ident.PermitPortForwarding = takeBool(teleport.CertExtensionPermitPortForwarding) @@ -335,7 +378,15 @@ func DecodeIdentity(cert *ssh.Certificate) (*Identity, error) { ident.BotName = takeValue(teleport.CertExtensionBotName) ident.BotInstanceID = takeValue(teleport.CertExtensionBotInstanceID) - ident.AllowedResourceIDs = takeValue(teleport.CertExtensionAllowedResources) + + if v, ok := takeExtension(teleport.CertExtensionAllowedResources); ok { + resourceIDs, err := types.ResourceIDsFromString(v) + if err != nil { + return nil, trace.BadParameter("failed to parse value %q for extension %q as resource IDs: %v", v, teleport.CertExtensionAllowedResources, err) + } + ident.AllowedResourceIDs = resourceIDs + } + ident.ConnectionDiagnosticID = takeValue(teleport.CertExtensionConnectionDiagnosticID) ident.PrivateKeyPolicy = keys.PrivateKeyPolicy(takeValue(teleport.CertExtensionPrivateKeyPolicy)) ident.DeviceID = takeValue(teleport.CertExtensionDeviceID) @@ -371,11 +422,11 @@ func DecodeIdentity(cert *ssh.Certificate) (*Identity, error) { ident.RouteToCluster = takeValue(teleport.CertExtensionTeleportRouteToCluster) if v, ok := takeExtension(teleport.CertExtensionTeleportActiveRequests); ok { - var requests services.RequestIDs - if err := requests.Unmarshal([]byte(v)); err != nil { + var reqs services.RequestIDs + if err := reqs.Unmarshal([]byte(v)); err != nil { return nil, trace.BadParameter("failed to unmarshal value %q for extension %q as active requests: %v", v, teleport.CertExtensionTeleportActiveRequests, err) } - ident.ActiveRequests = requests + ident.ActiveRequests = reqs.AccessRequests } // aggregate all remaining extensions into the CertificateExtensions field diff --git a/lib/sshca/identity_test.go b/lib/sshca/identity_test.go index 5c7c6db75b3e8..ef5b721f993a4 100644 --- a/lib/sshca/identity_test.go +++ b/lib/sshca/identity_test.go @@ -26,31 +26,32 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/wrappers" "github.com/gravitational/teleport/api/utils/keys" - "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/utils/testutils" ) func TestIdentityConversion(t *testing.T) { ident := &Identity{ - ValidAfter: 1, - ValidBefore: 2, - Username: "user", - Impersonator: "impersonator", - AllowedLogins: []string{"login1", "login2"}, - PermitX11Forwarding: true, - PermitAgentForwarding: true, - PermitPortForwarding: true, - Roles: []string{"role1", "role2"}, - RouteToCluster: "cluster", - Traits: wrappers.Traits{"trait1": []string{"value1"}, "trait2": []string{"value2"}}, - ActiveRequests: services.RequestIDs{ - AccessRequests: []string{uuid.NewString()}, - }, + ValidAfter: 1, + ValidBefore: 2, + CertType: ssh.UserCert, + ClusterName: "some-cluster", + SystemRole: types.RoleNode, + Username: "user", + Impersonator: "impersonator", + Principals: []string{"login1", "login2"}, + PermitX11Forwarding: true, + PermitAgentForwarding: true, + PermitPortForwarding: true, + Roles: []string{"role1", "role2"}, + RouteToCluster: "cluster", + Traits: wrappers.Traits{"trait1": []string{"value1"}, "trait2": []string{"value2"}}, + ActiveRequests: []string{uuid.NewString()}, MFAVerified: "mfa", PreviousIdentityExpires: time.Unix(12345, 0), LoginIP: "127.0.0.1", @@ -62,11 +63,16 @@ func TestIdentityConversion(t *testing.T) { Type: types.CertExtensionType_SSH, Mode: types.CertExtensionMode_EXTENSION, }}, - Renewable: true, - Generation: 3, - BotName: "bot", - BotInstanceID: "instance", - AllowedResourceIDs: "resource", + Renewable: true, + Generation: 3, + BotName: "bot", + BotInstanceID: "instance", + AllowedResourceIDs: []types.ResourceID{{ + ClusterName: "cluster", + Kind: types.KindKubePod, // must use a kube resource kind for parsing of sub-resource to work correctly + Name: "name", + SubResourceName: "sub/sub", + }}, ConnectionDiagnosticID: "diag", PrivateKeyPolicy: keys.PrivateKeyPolicy("policy"), DeviceID: "device", @@ -83,6 +89,9 @@ func TestIdentityConversion(t *testing.T) { "CertExtension.XXX_NoUnkeyedLiteral", "CertExtension.XXX_unrecognized", "CertExtension.XXX_sizecache", + "ResourceID.XXX_NoUnkeyedLiteral", + "ResourceID.XXX_unrecognized", + "ResourceID.XXX_sizecache", } require.True(t, testutils.ExhaustiveNonEmpty(ident, ignores...), "empty=%+v", testutils.FindAllEmpty(ident, ignores...)) diff --git a/lib/sshca/sshca.go b/lib/sshca/sshca.go index 15f5dcf6c1aeb..95f3c1fb7a17e 100644 --- a/lib/sshca/sshca.go +++ b/lib/sshca/sshca.go @@ -26,7 +26,6 @@ import ( "golang.org/x/crypto/ssh" apidefaults "github.com/gravitational/teleport/api/defaults" - "github.com/gravitational/teleport/lib/services" ) // Authority implements minimal key-management facility for generating OpenSSH @@ -35,13 +34,54 @@ type Authority interface { // GenerateHostCert takes the private key of the CA, public key of the new host, // along with metadata (host ID, node name, cluster name, roles, and ttl) and generates // a host certificate. - GenerateHostCert(certParams services.HostCertParams) ([]byte, error) + GenerateHostCert(HostCertificateRequest) ([]byte, error) // GenerateUserCert generates user ssh certificate, it takes pkey as a signing // private key (user certificate authority) GenerateUserCert(UserCertificateRequest) ([]byte, error) } +// HostCertificateRequest is a request to generate a new ssh host certificate. +type HostCertificateRequest struct { + // CASigner is the signer that will sign the public key of the host with the CA private key + CASigner ssh.Signer + // PublicHostKey is the public key of the host + PublicHostKey []byte + // HostID is used by Teleport to uniquely identify a node within a cluster (this is used to help infill + // Identity.Princiapals and is not a standalone cert field). + HostID string + // NodeName is the DNS name of the node (this is used to help infill Identity.Princiapals and is not a + // standalone cert field). + NodeName string + // TTL defines how long a certificate is valid for + TTL time.Duration + // Identity is the host identity to be encoded in the certificate. + Identity Identity +} + +func (r *HostCertificateRequest) Check() error { + if r.CASigner == nil { + return trace.BadParameter("ssh host certificate request missing ca signer") + } + if r.HostID == "" && len(r.Identity.Principals) == 0 { + return trace.BadParameter("ssh host certificate request missing host ID and principals") + } + if r.Identity.ClusterName == "" { + return trace.BadParameter("ssh host certificate request missing cluster name") + } + if r.Identity.ValidBefore != 0 { + return trace.BadParameter("ValidBefore should not be set in host cert requests (derived from TTL)") + } + if r.Identity.ValidAfter != 0 { + return trace.BadParameter("ValidAfter should not be set in host cert requests (derived from TTL)") + } + if err := r.Identity.SystemRole.Check(); err != nil { + return trace.Wrap(err) + } + + return nil +} + // UserCertificateRequest is a request to generate a new ssh user certificate. type UserCertificateRequest struct { // CASigner is the signer that will sign the public key of the user with the CA private key @@ -64,8 +104,14 @@ func (r *UserCertificateRequest) CheckAndSetDefaults() error { if r.TTL < apidefaults.MinCertDuration { r.TTL = apidefaults.MinCertDuration } - if err := r.Identity.Check(); err != nil { - return trace.Wrap(err) + if len(r.Identity.Principals) == 0 { + return trace.BadParameter("ssh user identity missing allowed logins") + } + if r.Identity.ValidBefore != 0 { + return trace.BadParameter("ValidBefore should not be set in user cert requests (derived from TTL)") + } + if r.Identity.ValidAfter != 0 { + return trace.BadParameter("ValidAfter should not be set in user cert requests (derived from TTL)") } return nil From f740f8694220320157ae5e03c9ecf442a7f2d711 Mon Sep 17 00:00:00 2001 From: Grzegorz Zdunek Date: Thu, 30 Jan 2025 19:17:51 +0100 Subject: [PATCH 20/27] [v17] Redesign profile switcher (#51654) * Store profile color in workspace (#51417) * Adjust workspace tests to accept persisted workspace type * Store profile color in workspace * Replace manual workspace creation in stories/tests with `addRootClusterWithDoc` * Fix checking if all colors are taken * Add DELETE IN comment * `ProfileColor` -> `WorkspaceColor` * Lint * Prettier * Add TODO about creating workspaces in `setActiveWorkspace` (cherry picked from commit 3b1c68947da83f8128e11a14f34e6a5c46f12c41) * Redesign profile switcher (#51419) * Add mapping of profile color to theme color * Prepare UserIcon to display colors, make it slightly larger * Rewrite single identity item to show icon and user/cluster in separate lines * Render single cluster items in a list * Add color picker * Render active cluster separately, above inactive clusters * Put the new identity components together * Refactor `Identity` story, render the container component instead of "presentational" one * Refresh startup page * Minor style fixes * Add comment about `dataVisualisationColors` * Bring back the original styling of `StaticListItem` * Make the pencil icon hoverable and clickable * Increase min-width from 200 px to 300 px, simplify active cluster layout * Show logout button when any part of `ListItem` is hovered * Remove text from logout button, improve titles * Pass correct index number to `AddClusterItem` * Update comment for `focusGrabber` * Use `useStoreSelector` correctly * Improve accessibility of color picker * Replace Pam icon with plus symbol * Remove unnecessary optional chaining * Align profile status error with user icon * Add story for cluster connect panel * Make user icon letter follow active theme This was suggested by Kenny, and I think it looks good. * Change gap from 11 px to 10 px * Rename profile color -> workspace color (cherry picked from commit 937e4a9ac9f85b2c3501168fd509693fea2e218e) --- .../jest/jest-environment-patched-jsdom.js | 14 + .../design/src/theme/themes/darkTheme.ts | 6 +- .../useAssumedRolesBar.test.tsx | 10 +- .../ClusterConnect/ClusterAdd/ClusterAdd.tsx | 3 +- .../DocumentConnectMyComputer/Setup.story.tsx | 14 +- .../DocumentConnectMyComputer/Setup.test.tsx | 11 +- .../Status.story.tsx | 16 +- .../NavigationMenu.story.tsx | 13 +- .../connectMyComputerContext.test.tsx | 14 +- .../DocumentAccessRequests.story.tsx | 72 +-- .../DocumentAuthorizeWebSession.test.tsx | 12 +- .../DocumentCluster/DocumentCluster.story.tsx | 124 ++--- .../DocumentCluster/DocumentCluster.test.tsx | 105 ++--- .../DocumentCluster/UnifiedResources.test.tsx | 68 +-- .../ui/DocumentGateway/useGateway.test.tsx | 13 +- .../DocumentGatewayApp.story.tsx | 18 +- .../DocumentGatewayKube.story.tsx | 21 +- .../teleterm/src/ui/Search/SearchBar.test.tsx | 19 +- .../src/ui/Search/SearchContext.test.tsx | 20 +- .../Search/pickers/useDisplayResults.test.tsx | 43 +- .../ClusterConnectPanel.story.tsx | 83 ++++ .../ClusterConnectPanel.tsx | 90 +++- .../ClusterConnectPanel/RecentClusters.tsx | 94 ---- .../teleterm/src/ui/TabHost/TabHost.test.tsx | 22 +- .../src/ui/TabHost/useTabShortcuts.test.tsx | 11 +- .../EmptyIdentityList/EmptyIdentityList.tsx | 43 -- .../src/ui/TopBar/Identity/Identity.story.tsx | 429 +++++------------- .../src/ui/TopBar/Identity/Identity.test.tsx | 28 +- .../src/ui/TopBar/Identity/Identity.tsx | 205 ++++----- .../IdentityList/AddNewClusterItem.tsx | 51 --- .../Identity/IdentityList/ColorPicker.tsx | 130 ++++++ .../Identity/IdentityList/IdentityList.tsx | 168 ++++--- .../IdentityList/IdentityListItem.tsx | 178 +++++--- .../IdentitySelector/IdentitySelector.tsx | 41 +- .../Identity/IdentitySelector/PamIcon.tsx | 41 -- .../Identity/IdentitySelector/UserIcon.tsx | 66 ++- .../TopBar/Identity/IdentitySelector/pam.svg | 65 --- .../src/ui/TopBar/Identity/useIdentity.ts | 53 +-- .../KeyboardArrowsNavigation.tsx | 18 + .../teleterm/src/ui/components/ListItem.tsx | 23 +- .../src/ui/components/ProfileStatusError.tsx | 16 +- .../teleterm/src/ui/fixtures/mocks.ts | 12 +- .../connectionTrackerService.legacy.test.ts | 1 + .../statePersistenceService.ts | 19 +- .../ui/services/workspacesService/color.ts | 87 ++++ .../ui/services/workspacesService/index.ts | 1 + .../workspacesService.test.ts | 125 ++++- .../workspacesService/workspacesService.ts | 42 +- 48 files changed, 1300 insertions(+), 1458 deletions(-) create mode 100644 web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx delete mode 100644 web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx create mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg create mode 100644 web/packages/teleterm/src/ui/services/workspacesService/color.ts diff --git a/web/packages/build/jest/jest-environment-patched-jsdom.js b/web/packages/build/jest/jest-environment-patched-jsdom.js index d80f8460502dd..6da25be856fe0 100644 --- a/web/packages/build/jest/jest-environment-patched-jsdom.js +++ b/web/packages/build/jest/jest-environment-patched-jsdom.js @@ -56,6 +56,20 @@ export default class PatchedJSDOMEnvironment extends JSDOMEnvironment { global.AbortSignal = AbortSignal; global.AbortController = AbortController; } + // TODO(gzdunek): Remove when JSDOM supports Set.prototype.difference. + // After the update to Node.js 22, we can replace the implementation with + // global.Set.prototype.difference = Set.prototype.difference. + if (!global.Set.difference) { + global.Set.prototype.difference = function (otherSet) { + const result = new Set(); + for (const value of this) { + if (!otherSet.has(value)) { + result.add(value); + } + } + return result; + }; + } } } export const TestEnvironment = PatchedJSDOMEnvironment; diff --git a/web/packages/design/src/theme/themes/darkTheme.ts b/web/packages/design/src/theme/themes/darkTheme.ts index eb0f044ee51c2..d4158282b3d5f 100644 --- a/web/packages/design/src/theme/themes/darkTheme.ts +++ b/web/packages/design/src/theme/themes/darkTheme.ts @@ -32,7 +32,11 @@ import { lighten } from '../utils/colorManipulator'; import { sharedColors, sharedStyles } from './sharedStyles'; import { DataVisualisationColors, Theme, ThemeColors } from './types'; -const dataVisualisationColors: DataVisualisationColors = { +/** + * Used for the user icon in Connect (the top-right one). + * In both the light and dark mode, the dark version of dataVisualisationColors is used. + */ +export const dataVisualisationColors: DataVisualisationColors = { primary: { purple: '#9F85FF', wednesdays: '#F74DFF', diff --git a/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx b/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx index d0bcc2dcba6f0..0cf1cd9cfd0dc 100644 --- a/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx +++ b/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx @@ -33,15 +33,7 @@ import { useAssumedRolesBar } from './useAssumedRolesBar'; test('dropping a request refreshes resources', async () => { const appContext = new MockAppContext(); const cluster = makeRootCluster(); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); jest.spyOn(appContext.clustersService, 'dropRoles'); const refreshListener = jest.fn(); diff --git a/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx b/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx index 68d96c1c0bb95..e2d6303bb7313 100644 --- a/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx +++ b/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx @@ -35,11 +35,12 @@ export function ClusterAdd(props: { onSuccess(clusterUri: string): void; prefill: { clusterAddress: string }; }) { - const { clustersService } = useAppContext(); + const { clustersService, workspacesService } = useAppContext(); const [{ status, statusText }, addCluster] = useAsync( async (addr: string) => { const proxyAddr = parseClusterProxyWebAddr(addr); const cluster = await clustersService.addRootCluster(proxyAddr); + workspacesService.addWorkspace(cluster.uri); return props.onSuccess(cluster.uri); } ); diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx index 4d1ab55176e3a..d41968fef69ec 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx @@ -27,7 +27,6 @@ import { ResourcesContextProvider } from 'teleterm/ui/DocumentCluster/resourcesC import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { IAppContext } from 'teleterm/ui/types'; import { ConnectMyComputerContextProvider } from '../connectMyComputerContext'; import { Setup } from './Setup'; @@ -153,20 +152,11 @@ function ShowState({ clickStartSetup = true, }: { cluster: Cluster; - appContext: IAppContext; + appContext: MockAppContext; clickStartSetup?: boolean; }) { if (!appContext.clustersService.state.clusters.get(cluster.uri)) { - appContext.clustersService.state.clusters.set(cluster.uri, cluster); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); } useLayoutEffect(() => { diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx index 41912c9b4adc6..e8e96e1e49c6b 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx @@ -131,16 +131,7 @@ function setupAppContext(): { const appContext = new MockAppContext({ appVersion: cluster.proxyVersion, }); - appContext.clustersService.state.clusters.set(cluster.uri, cluster); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); jest .spyOn(appContext.mainProcessClient, 'isAgentConfigFileCreated') diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx index fe659cd9ee305..84aa769bd2a80 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx @@ -25,7 +25,6 @@ import { makeRootCluster, makeServer, } from 'teleterm/services/tshd/testHelpers'; -import AppContext from 'teleterm/ui/appContext'; import { ResourcesContextProvider } from 'teleterm/ui/DocumentCluster/resourcesContext'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; @@ -236,7 +235,7 @@ export function UpgradeAgentSuggestion() { function ShowState(props: { agentProcessState: AgentProcessState; - appContext?: AppContext; + appContext?: MockAppContext; proxyVersion?: string; autoStart?: boolean; }) { @@ -248,18 +247,7 @@ function ShowState(props: { new MockAppContext({ appVersion: cluster.proxyVersion }); appContext.mainProcessClient.getAgentState = () => props.agentProcessState; - appContext.clustersService.state.clusters.set(cluster.uri, cluster); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces = { - [cluster.uri]: { - localClusterUri: cluster.uri, - documents: [], - location: '/docs/1234', - accessRequests: undefined, - }, - }; - }); + appContext.addRootCluster(cluster); if (props.autoStart) { appContext.workspacesService.setConnectMyComputerAutoStart( diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx index c3f037e9151f4..b0d85e60b53b0 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx @@ -32,7 +32,7 @@ export default { title: 'Teleterm/ConnectMyComputer/NavigationMenu', }; -export function AgenNotConfigured() { +export function AgentNotConfigured() { return ( { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); appContext.mainProcessClient.getAgentState = () => agentProcessState; appContext.connectMyComputerService.isAgentConfigFileCreated = diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx index ee0a84a9272c2..86674bb9d8a49 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx @@ -65,19 +65,7 @@ function getMocks() { const appContext = new MockAppContext({ appVersion: rootCluster.proxyVersion, }); - - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, rootCluster); - }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - documents: [], - location: undefined, - localClusterUri: rootCluster.uri, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(rootCluster); return { appContext, rootCluster }; } diff --git a/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx b/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx index fc0c623198ae0..c9325fb5ce68e 100644 --- a/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx @@ -27,7 +27,6 @@ import { ResourcesContextProvider } from 'teleterm/ui/DocumentCluster/resourcesC import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; import * as types from 'teleterm/ui/services/workspacesService'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; const rootCluster = makeRootCluster(); @@ -89,18 +88,7 @@ export function Browsing() { startKey: '', requests: [mockedAccessRequest], }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, [doc]); return ( @@ -117,21 +105,7 @@ export function BrowsingError() { const appContext = new MockAppContext(); appContext.tshd.getAccessRequests = () => new MockedUnaryCall(null, new Error('network error')); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, rootCluster); - }); + appContext.addRootClusterWithDoc(rootCluster, [doc]); return ( @@ -156,24 +130,13 @@ export function CreatingWhenUnifiedResourcesShowOnlyAccessibleResources() { startKey: '', requests: [mockedAccessRequest], }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: docCreating.clusterUri, - documents: [docCreating], - location: docCreating.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, { + appContext.addRootClusterWithDoc( + { ...rootCluster, showResources: ShowResources.ACCESSIBLE_ONLY, - }); - }); + }, + [doc] + ); return ( @@ -198,24 +161,13 @@ export function CreatingWhenUnifiedResourcesShowRequestableAndAccessibleResource startKey: '', requests: [mockedAccessRequest], }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: docCreating.clusterUri, - documents: [docCreating], - location: docCreating.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, { + appContext.addRootClusterWithDoc( + { ...rootCluster, showResources: ShowResources.REQUESTABLE, - }); - }); + }, + [doc] + ); return ( diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx index 59246adf0cf32..df3af448a8d04 100644 --- a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx @@ -95,17 +95,7 @@ test('authorizing a session opens its URL and closes document', async () => { loggedInUser: makeLoggedInUser({ isDeviceTrusted: true }), }); const appContext = new MockAppContext(); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, rootCluster); - }); - appContext.workspacesService.setState(draftState => { - draftState.workspaces[rootCluster.uri] = { - localClusterUri: rootCluster.uri, - documents: [doc], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, doc); render( diff --git a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx index b1043c9600789..2ad72ab0e928d 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx @@ -35,16 +35,10 @@ import AppContextProvider from 'teleterm/ui/appContextProvider'; import { ConnectMyComputerContextProvider } from 'teleterm/ui/ConnectMyComputer'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { - ClustersServiceState, - createClusterServiceState, -} from 'teleterm/ui/services/clusters'; import { ResourcesService } from 'teleterm/ui/services/resources'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; import * as docTypes from 'teleterm/ui/services/workspacesService/documentsService/types'; import { ConnectionsContextProvider } from 'teleterm/ui/TopBar/Connections/connectionsContext'; -import { routing } from 'teleterm/ui/uri'; import { VnetContextProvider } from 'teleterm/ui/Vnet'; import DocumentCluster from './DocumentCluster'; @@ -65,16 +59,10 @@ const leafClusterDoc = makeDocumentCluster({ }); export const OnlineLoadedResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ - uri: rootClusterDoc.clusterUri, - }) - ); - return renderState({ - state, + cluster: makeRootCluster({ + uri: rootClusterDoc.clusterUri, + }), doc: rootClusterDoc, listUnifiedResources: () => Promise.resolve({ @@ -161,10 +149,8 @@ export const OnlineLoadedResources = () => { }; export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.LOCAL, @@ -179,11 +165,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { }, }), }), - }) - ); - - return renderState({ - state, + }), doc: rootClusterDoc, platform: 'darwin', listUnifiedResources: () => @@ -197,10 +179,8 @@ export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.SSO, @@ -215,11 +195,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = }, }), }), - }) - ); - - return renderState({ - state, + }), doc: rootClusterDoc, platform: 'win32', listUnifiedResources: () => @@ -232,10 +208,8 @@ export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = }; export const OnlineEmptyResourcesAndCannotAddResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ acl: makeAcl({ @@ -249,11 +223,7 @@ export const OnlineEmptyResourcesAndCannotAddResources = () => { }, }), }), - }) - ); - - return renderState({ - state, + }), doc: rootClusterDoc, listUnifiedResources: () => Promise.resolve({ @@ -265,14 +235,6 @@ export const OnlineEmptyResourcesAndCannotAddResources = () => { }; export const OnlineLoadingResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ - uri: rootClusterDoc.clusterUri, - }) - ); - let rejectPromise: (error: Error) => void; const promiseRejectedOnUnmount = new Promise((resolve, reject) => { rejectPromise = reject; @@ -285,23 +247,19 @@ export const OnlineLoadingResources = () => { }, [rejectPromise]); return renderState({ - state, + cluster: makeRootCluster({ + uri: rootClusterDoc.clusterUri, + }), doc: rootClusterDoc, listUnifiedResources: () => promiseRejectedOnUnmount, }); }; export const OnlineErrorLoadingResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ - uri: rootClusterDoc.clusterUri, - }) - ); - return renderState({ - state, + cluster: makeRootCluster({ + uri: rootClusterDoc.clusterUri, + }), doc: rootClusterDoc, listUnifiedResources: () => Promise.reject(new Error('Whoops, something went wrong, sorry!')), @@ -309,58 +267,38 @@ export const OnlineErrorLoadingResources = () => { }; export const Offline = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ connected: false, uri: rootClusterDoc.clusterUri, - }) - ); - - return renderState({ state, doc: rootClusterDoc }); + }), + doc: rootClusterDoc, + }); }; export const Notfound = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, - }) - ); - return renderState({ state, doc: leafClusterDoc }); + }), + doc: leafClusterDoc, + }); }; function renderState({ - state, + cluster, doc, listUnifiedResources, platform = 'darwin', }: { - state: ClustersServiceState; + cluster: tsh.Cluster; doc: docTypes.DocumentCluster; listUnifiedResources?: ResourcesService['listUnifiedResources']; platform?: NodeJS.Platform; userType?: tsh.LoggedInUser_UserType; }) { const appContext = new MockAppContext({ platform }); - appContext.clustersService.state = state; - - const rootClusterUri = routing.ensureRootClusterUri(doc.clusterUri); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - + appContext.addRootClusterWithDoc(cluster, doc); appContext.resourcesService.listUnifiedResources = (params, abortSignal) => listUnifiedResources ? listUnifiedResources(params, abortSignal) diff --git a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx index 02d89810e9b47..0c3ac10a61fbe 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx @@ -31,7 +31,6 @@ import { ConnectMyComputerContextProvider } from 'teleterm/ui/ConnectMyComputer' import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; import DocumentCluster from './DocumentCluster'; @@ -43,41 +42,25 @@ it('displays a button for Connect My Computer in the empty state if the user can const doc = makeDocumentCluster(); const appContext = new MockAppContext({ platform: 'darwin' }); - appContext.clustersService.setState(draft => { - draft.clusters.set( - doc.clusterUri, - makeRootCluster({ - uri: doc.clusterUri, - loggedInUser: makeLoggedInUser({ - userType: tsh.LoggedInUser_UserType.LOCAL, - acl: makeAcl({ - tokens: { - create: true, - list: true, - edit: true, - delete: true, - read: true, - use: true, - }, - }), + appContext.addRootClusterWithDoc( + makeRootCluster({ + uri: doc.clusterUri, + loggedInUser: makeLoggedInUser({ + userType: tsh.LoggedInUser_UserType.LOCAL, + acl: makeAcl({ + tokens: { + create: true, + list: true, + edit: true, + delete: true, + read: true, + use: true, + }, }), - }) - ); - }); - - appContext.workspacesService.setState(draftState => { - const rootClusterUri = doc.clusterUri; - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + }), + }), + doc + ); const emptyResponse = { resources: [], @@ -116,41 +99,25 @@ it('does not display a button for Connect My Computer in the empty state if the }); const appContext = new MockAppContext({ platform: 'linux' }); - appContext.clustersService.setState(draft => { - draft.clusters.set( - doc.clusterUri, - makeRootCluster({ - uri: doc.clusterUri, - loggedInUser: makeLoggedInUser({ - userType: tsh.LoggedInUser_UserType.LOCAL, - acl: makeAcl({ - tokens: { - create: false, - list: true, - edit: true, - delete: true, - read: true, - use: true, - }, - }), + appContext.addRootClusterWithDoc( + makeRootCluster({ + uri: doc.clusterUri, + loggedInUser: makeLoggedInUser({ + userType: tsh.LoggedInUser_UserType.LOCAL, + acl: makeAcl({ + tokens: { + create: false, + list: true, + edit: true, + delete: true, + read: true, + use: true, + }, }), - }) - ); - }); - - appContext.workspacesService.setState(draftState => { - const rootClusterUri = doc.clusterUri; - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + }), + }), + doc + ); const emptyResponse = { resources: [], diff --git a/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx b/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx index c6d81570b11c2..d2d9dab4483dd 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx @@ -44,7 +44,6 @@ import { UnifiedResources } from 'teleterm/ui/DocumentCluster/UnifiedResources'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; import * as uri from 'teleterm/ui/uri'; @@ -175,39 +174,25 @@ test.each([ const doc = makeDocumentCluster(); const appContext = new MockAppContext({ platform: 'darwin' }); - appContext.clustersService.setState(draft => { - draft.clusters.set( - doc.clusterUri, - makeRootCluster({ - uri: doc.clusterUri, - features: { - advancedAccessWorkflows: - testCase.conditions.isClusterSupportingAccessRequests, - isUsageBasedBilling: false, - }, - showResources: testCase.conditions.showResources, - }) - ); - }); - - appContext.workspacesService.setState(draftState => { - const rootClusterUri = doc.clusterUri; - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - unifiedResourcePreferences: { - defaultTab: DefaultTab.ALL, - viewMode: ViewMode.CARD, - labelsViewMode: LabelsViewMode.COLLAPSED, - availableResourceMode: - testCase.conditions.availableResourceModePreference, - }, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, + appContext.addRootClusterWithDoc( + makeRootCluster({ + uri: doc.clusterUri, + features: { + advancedAccessWorkflows: + testCase.conditions.isClusterSupportingAccessRequests, + isUsageBasedBilling: false, }, + showResources: testCase.conditions.showResources, + }), + doc + ); + appContext.workspacesService.setState(draftState => { + draftState.workspaces[doc.clusterUri].unifiedResourcePreferences = { + defaultTab: DefaultTab.ALL, + viewMode: ViewMode.CARD, + labelsViewMode: LabelsViewMode.COLLAPSED, + availableResourceMode: + testCase.conditions.availableResourceModePreference, }; }); @@ -302,22 +287,7 @@ test.each([ }); const serverResource = makeServer(); const appContext = new MockAppContext(); - appContext.clustersService.setState(draft => { - draft.clusters.set(rootCluster.uri, rootCluster); - }); - - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: rootCluster.uri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, doc); jest .spyOn(appContext.resourcesService, 'listUnifiedResources') diff --git a/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx b/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx index 5f7cef9704cfd..503171d4735a6 100644 --- a/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx @@ -126,18 +126,7 @@ const testSetup = () => { title: '', status: '', }; - appContext.clustersService.setState(draftState => { - draftState.clusters.set(cluster.uri, cluster); - }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - documents: [doc], - location: doc.uri, - localClusterUri: cluster.uri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(cluster, doc); const workspaceContext = { rootClusterUri: cluster.uri, localClusterUri: cluster.uri, diff --git a/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx b/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx index b140fe1aac5c8..47144e12f1011 100644 --- a/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx @@ -22,7 +22,11 @@ import { Flex } from 'design'; import { usePromiseRejectedOnUnmount, wait } from 'shared/utils/wait'; import { MockedUnaryCall } from 'teleterm/services/tshd/cloneableClient'; -import { makeApp, makeAppGateway } from 'teleterm/services/tshd/testHelpers'; +import { + makeApp, + makeAppGateway, + makeRootCluster, +} from 'teleterm/services/tshd/testHelpers'; import { DocumentGatewayApp } from 'teleterm/ui/DocumentGatewayApp/DocumentGatewayApp'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; @@ -80,7 +84,7 @@ const meta: Meta = { export default meta; export function Story(props: StoryProps) { - const rootClusterUri = '/clusters/bar'; + const rootCluster = makeRootCluster({ uri: '/clusters/bar' }); const gateway = makeAppGateway(); if (props.appType === 'tcp') { gateway.protocol = 'TCP'; @@ -111,15 +115,7 @@ export function Story(props: StoryProps) { const infinitePromise = usePromiseRejectedOnUnmount(); const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [documentGateway], - location: documentGateway.uri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, documentGateway); if (props.online) { appContext.clustersService.createGateway = () => Promise.resolve(gateway); appContext.clustersService.setState(draftState => { diff --git a/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx b/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx index 15a68c41e2c9c..c6ef7ec2bc5cf 100644 --- a/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; @@ -27,38 +28,28 @@ export default { title: 'Teleterm/DocumentGatewayKube', }; -const offlineDocumentGatewayProps: types.DocumentGatewayKube = { +const rootCluster = makeRootCluster(); +const offlineDocumentGateway: types.DocumentGatewayKube = { kind: 'doc.gateway_kube', rootClusterId: '', leafClusterId: '', - targetUri: '/clusters/bar/kubes/quux', + targetUri: `${rootCluster.uri}/kubes/quux`, origin: 'resource_table', status: '', uri: '/docs/123', title: 'quux', }; -const rootClusterUri = '/clusters/bar'; - export function Offline() { const appContext = new MockAppContext(); appContext.clustersService.createGateway = () => Promise.reject(new Error('failed to create gateway')); - - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [offlineDocumentGatewayProps], - location: offlineDocumentGatewayProps.uri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, offlineDocumentGateway); return ( - + ); diff --git a/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx b/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx index 412d39a8be931..8d063772cddf8 100644 --- a/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx +++ b/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx @@ -31,7 +31,7 @@ import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import ModalsHost from 'teleterm/ui/ModalsHost'; import { ResourceSearchError } from 'teleterm/ui/services/resources'; import { ConnectionsContextProvider } from 'teleterm/ui/TopBar/Connections/connectionsContext'; -import { ClusterUri } from 'teleterm/ui/uri'; +import { ClusterUri, routing } from 'teleterm/ui/uri'; import { VnetContextProvider } from 'teleterm/ui/Vnet'; import { SearchAction } from './actions'; @@ -411,16 +411,11 @@ const getMockedSearchContext = (): SearchContext.SearchContext => ({ const setUpContext = (clusterUri: ClusterUri) => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = clusterUri; - draft.workspaces = { - [clusterUri]: { - documents: [], - location: undefined, - localClusterUri: clusterUri, - accessRequests: undefined, - }, - }; - }); + appContext.addRootCluster( + makeRootCluster({ + uri: clusterUri, + name: routing.parseClusterUri(clusterUri).params.rootClusterId, + }) + ); return appContext; }; diff --git a/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx b/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx index 841eafe91fadb..ef30cd17b26c7 100644 --- a/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx +++ b/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx @@ -29,6 +29,7 @@ import { screen, } from '@testing-library/react'; +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { IAppContext } from 'teleterm/ui/types'; @@ -233,17 +234,10 @@ describe('closeWithoutRestoringFocus', () => { }); test('search bar state is adjusted to the active document', () => { - const rootClusterUri = '/clusters/localhost'; + const rootCluster = makeRootCluster({ uri: '/clusters/localhost' }); const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(rootCluster); + const docService = appContext.workspacesService.getActiveWorkspaceDocumentService(); const { result } = renderHook(() => useSearchContext(), { @@ -260,7 +254,7 @@ test('search bar state is adjusted to the active document', () => { // document changes to the cluster document act(() => { const clusterDoc = docService.createClusterDocument({ - clusterUri: rootClusterUri, + clusterUri: rootCluster.uri, queryParams: { search: 'foo', resourceKinds: ['db'], @@ -281,7 +275,7 @@ test('search bar state is adjusted to the active document', () => { // document changes to another cluster document act(() => { const clusterDoc = docService.createClusterDocument({ - clusterUri: rootClusterUri, + clusterUri: rootCluster.uri, queryParams: { search: 'bar', resourceKinds: ['kube_cluster'], @@ -316,7 +310,7 @@ test('search bar state is adjusted to the active document', () => { // document changes to a cluster document act(() => { const clusterDoc = docService.createClusterDocument({ - clusterUri: rootClusterUri, + clusterUri: rootCluster.uri, queryParams: { search: 'bar', resourceKinds: ['kube_cluster'], diff --git a/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx b/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx index 0d60c80125215..30a2fb11c2ffd 100644 --- a/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx +++ b/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx @@ -18,6 +18,7 @@ import { renderHook } from '@testing-library/react'; +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; @@ -30,17 +31,10 @@ const documentCluster = makeDocumentCluster({ test('if the cluster document is active, the search results should be shown in it', () => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.workspaces = { - '/clusters/teleport-a': { - localClusterUri: '/clusters/teleport-a', - location: documentCluster.uri, - accessRequests: undefined, - documents: [documentCluster], - }, - }; - draftState.rootClusterUri = '/clusters/teleport-a'; - }); + appContext.addRootClusterWithDoc( + makeRootCluster({ uri: '/clusters/teleport-a' }), + documentCluster + ); const { result } = renderHook( () => @@ -65,17 +59,10 @@ test('if the cluster document is active, the search results should be shown in i test('if the cluster filter does not match the document cluster, the results should be opened in a new document', () => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.workspaces = { - '/clusters/teleport-a': { - localClusterUri: '/clusters/teleport-a', - location: '/docs/abc', - accessRequests: undefined, - documents: [documentCluster], - }, - }; - draftState.rootClusterUri = '/clusters/teleport-a'; - }); + appContext.addRootClusterWithDoc( + makeRootCluster({ uri: '/clusters/teleport-a' }), + documentCluster + ); const { result } = renderHook( () => @@ -101,17 +88,7 @@ test('if the cluster filter does not match the document cluster, the results sho test('if the cluster document is not active, the results should be opened in a new document', () => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.workspaces = { - '/clusters/teleport-a': { - localClusterUri: '/clusters/teleport-a', - location: '/docs/abc', - accessRequests: undefined, - documents: [], - }, - }; - draftState.rootClusterUri = '/clusters/teleport-a'; - }); + appContext.addRootCluster(makeRootCluster({ uri: '/clusters/teleport-a' })); const { result } = renderHook( () => diff --git a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx new file mode 100644 index 0000000000000..8a4d827e6e4b0 --- /dev/null +++ b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx @@ -0,0 +1,83 @@ +/** + * Teleport + * Copyright (C) 2025 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 { + makeLoggedInUser, + makeRootCluster, +} from 'teleterm/services/tshd/testHelpers'; +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; + +import { ClusterConnectPanel } from './ClusterConnectPanel'; + +export default { + title: 'Teleterm/ClusterConnectPanel', +}; + +const profileStatusError = + 'No YubiKey device connected with serial number 14358031. Connect the device and try again.'; +const clusterOrange = makeRootCluster({ + name: 'orange', + loggedInUser: makeLoggedInUser({ + name: 'bob', + roles: ['access', 'editor'], + sshLogins: ['root'], + }), + uri: '/clusters/orange', +}); +const clusterViolet = makeRootCluster({ + name: 'violet', + loggedInUser: makeLoggedInUser({ name: 'sammy' }), + uri: '/clusters/violet', +}); + +export const Empty = () => { + return ( + + + + ); +}; + +export const WithClusters = () => { + const ctx = new MockAppContext(); + ctx.addRootCluster(clusterOrange); + ctx.addRootCluster(clusterViolet); + + return ( + + ; + + ); +}; + +export const WithErrors = () => { + const ctx = new MockAppContext(); + ctx.addRootCluster( + makeRootCluster({ + ...clusterOrange, + profileStatusError, + }) + ); + ctx.addRootCluster(clusterViolet); + return ( + + ; + + ); +}; diff --git a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx index 773f5808cc6e6..b8eda061b186f 100644 --- a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx +++ b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx @@ -16,21 +16,51 @@ * along with this program. If not, see . */ +import { useCallback, useEffect, useRef } from 'react'; import styled from 'styled-components'; -import { Box, ButtonPrimary, Flex, H1, ResourceIcon, Text } from 'design'; +import { + Box, + ButtonPrimary, + Flex, + H1, + H2, + P2, + ResourceIcon, + Text, +} from 'design'; import { useAppContext } from 'teleterm/ui/appContextProvider'; - -import { RecentClusters } from './RecentClusters'; +import { NullKeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation'; +import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; +import { ClusterList } from 'teleterm/ui/TopBar/Identity/IdentityList/IdentityList'; +import { RootClusterUri } from 'teleterm/ui/uri'; export function ClusterConnectPanel() { const ctx = useAppContext(); - - function handleConnect() { + const clusters = useStoreSelector( + 'clustersService', + useCallback(state => state.clusters, []) + ); + const rootClusters = [...clusters.values()].filter(c => !c.leaf); + function add(): void { ctx.commandLauncher.executeCommand('cluster-connect', {}); } + function connect(clusterUri: RootClusterUri): void { + ctx.workspacesService.setActiveWorkspace(clusterUri); + } + + const containerRef = useRef(); + + // Focus the first item. + const hasCluster = !!rootClusters.length; + useEffect(() => { + if (hasCluster) { + containerRef.current.querySelector('li').focus(); + } + }, [hasCluster]); + return ( @@ -41,16 +71,48 @@ export function ClusterConnectPanel() { alignItems="center" > -

Connect a Cluster

- - Connect an existing Teleport cluster
to start using Teleport - Connect. -
- - Connect - + {hasCluster ? ( + +

Clusters

+ + Log in to a cluster to use Teleport Connect. + + {/*Disable arrows navigation, it doesn't work well here,*/} + {/*since it requires the container to be focused.*/} + {/*The user can navigate with Tab.*/} + + p.theme.radii[2]}px; + padding: ${p => p.theme.space[2]}px; + } + `} + > + + + +
+ ) : ( + <> +

Connect a Cluster

+ + Connect an existing Teleport cluster
to start using + Teleport Connect. +
+ + Connect + + + )} -
); diff --git a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx deleted file mode 100644 index c1b7264633c6d..0000000000000 --- a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 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 { Box, ButtonBorder, Card, Flex, Text } from 'design'; - -import { useAppContext } from 'teleterm/ui/appContextProvider'; -import { ProfileStatusError } from 'teleterm/ui/components/ProfileStatusError'; -import { RootClusterUri } from 'teleterm/ui/uri'; -import { getUserWithClusterName } from 'teleterm/ui/utils'; - -export function RecentClusters() { - const ctx = useAppContext(); - - ctx.clustersService.useState(); - - const rootClusters = ctx.clustersService - .getClusters() - .filter(c => !c.leaf) - .map(cluster => ({ - userWithClusterName: getUserWithClusterName({ - userName: cluster.loggedInUser?.name, - clusterName: cluster.name, - }), - connectionProblemError: cluster.profileStatusError, - uri: cluster.uri, - })); - - function connect(clusterUri: RootClusterUri): void { - ctx.workspacesService.setActiveWorkspace(clusterUri); - } - - if (!rootClusters.length) { - return null; - } - - return ( - - - Recent clusters - - - {rootClusters.map((cluster, index) => ( - - - - {cluster.userWithClusterName} - - {cluster.connectionProblemError && ( - - )} - - connect(cluster.uri)} - title={`Connect to ${cluster.userWithClusterName}`} - > - Connect - - - ))} - - - ); -} diff --git a/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx b/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx index a224cfb3221cc..5a8db6c1cd294 100644 --- a/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx +++ b/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx @@ -54,27 +54,7 @@ async function getTestSetup({ documents }: { documents: Document[] }) { const appContext = new MockAppContext(); jest.spyOn(appContext.mainProcessClient, 'openTabContextMenu'); - appContext.clustersService.setState(draft => { - draft.clusters.set( - rootClusterUri, - makeRootCluster({ - uri: rootClusterUri, - }) - ); - }); - - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = rootClusterUri; - draft.workspaces[rootClusterUri] = { - documents, - location: documents[0]?.uri, - localClusterUri: rootClusterUri, - accessRequests: { - isBarCollapsed: true, - pending: { kind: 'resource', resources: new Map() }, - }, - }; - }); + appContext.addRootClusterWithDoc(makeRootCluster(), documents); const docsService = appContext.workspacesService.getActiveWorkspaceDocumentService(); diff --git a/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx b/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx index b8fe467178b54..e459582fd54ae 100644 --- a/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx +++ b/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx @@ -20,6 +20,7 @@ import { PropsWithChildren } from 'react'; import renderHook from 'design/utils/renderHook'; +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import AppContextProvider from 'teleterm/ui/appContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { @@ -107,15 +108,7 @@ function getTestSetup({ documents }: { documents: Document[] }) { eventEmitter = null; }); - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = rootClusterUri; - draft.workspaces[rootClusterUri] = { - documents, - location: documents[0]?.uri, - localClusterUri: rootClusterUri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(makeRootCluster(), documents); const docsService = appContext.workspacesService.getActiveWorkspaceDocumentService(); diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx deleted file mode 100644 index 1824054ebdfce..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 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 { ButtonPrimary, Flex, ResourceIcon, Text } from 'design'; - -interface EmptyIdentityListProps { - onConnect(): void; -} - -export function EmptyIdentityList(props: EmptyIdentityListProps) { - return ( - - - - No cluster connected - - - Connect - - - ); -} diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx index 9abacf8a59480..43eb4967ef282 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx @@ -16,91 +16,104 @@ * along with this program. If not, see . */ -import { useEffect, useRef } from 'react'; +import { useLayoutEffect } from 'react'; import Flex from 'design/Flex'; import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/trusted_device_requirement_pb'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; import { makeLoggedInUser, makeRootCluster, } from 'teleterm/services/tshd/testHelpers'; +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; +import { RootClusterUri } from 'teleterm/ui/uri'; -import { Identity, IdentityHandler, IdentityProps } from './Identity'; -import { IdentityRootCluster } from './useIdentity'; +import { IdentityContainer } from './Identity'; export default { title: 'Teleterm/Identity', }; -const makeTitle = (userWithClusterName: string) => userWithClusterName; +const clusterOrange = makeRootCluster({ + name: 'orange', + loggedInUser: makeLoggedInUser({ + name: 'bob', + roles: ['access', 'editor'], + sshLogins: ['root'], + }), + uri: '/clusters/orange', +}); +const clusterViolet = makeRootCluster({ + name: 'violet', + loggedInUser: makeLoggedInUser({ name: 'sammy' }), + uri: '/clusters/violet', +}); +const clusterGreen = makeRootCluster({ + name: 'green', + loggedInUser: undefined, + uri: '/clusters/green', +}); + const profileStatusError = 'No YubiKey device connected with serial number 14358031. Connect the device and try again.'; -const OpenedIdentity = (props: IdentityProps) => { - const ref = useRef(); - useEffect(() => { - if (ref.current) { - ref.current.togglePopover(); - } - }, [ref.current]); +const OpenIdentityPopover = (props: { + clusters: Cluster[]; + activeClusterUri: RootClusterUri | undefined; +}) => { + const ctx = new MockAppContext(); + props.clusters.forEach(c => { + ctx.addRootCluster(c); + }); + ctx.workspacesService.setState(draftState => { + draftState.rootClusterUri = props.activeClusterUri; + }); + useOpenPopover(); return ( - + + + ); }; +const useOpenPopover = () => { + useLayoutEffect(() => { + const isProfileSelectorOpen = !!document.querySelector( + 'button[title~="logout"i]' + ); + + if (isProfileSelectorOpen) { + return; + } + + const button = document.querySelector( + 'button[title~="profiles"i]' + ) as HTMLButtonElement; + + button?.click(); + }, []); +}; + export function NoRootClusters() { - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} - /> - ); + return ; } export function OneClusterWithNoActiveCluster() { - const identityRootCluster: IdentityRootCluster = { - active: false, - clusterName: 'teleport-localhost', - userName: '', - uri: '/clusters/localhost', - connected: false, - profileStatusError: '', - }; - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function OneClusterWithActiveCluster() { - const identityRootCluster: IdentityRootCluster = { - active: true, - clusterName: 'Teleport-Localhost', - userName: 'alice', - uri: '/clusters/localhost', - connected: true, - profileStatusError: '', - }; - const cluster = makeRootCluster({ - uri: '/clusters/localhost', - name: 'teleport-localhost', - proxyHost: 'localhost:3080', loggedInUser: makeLoggedInUser({ name: 'alice', roles: ['access', 'editor'], @@ -109,297 +122,105 @@ export function OneClusterWithActiveCluster() { }); return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} - /> + ); } export function ManyClustersWithNoActiveCluster() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - const identityRootCluster2: IdentityRootCluster = { - active: false, - clusterName: 'violet', - userName: 'sammy', - uri: '/clusters/violet', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: true, - profileStatusError: '', - }; - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function ManyClustersWithActiveCluster() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - const identityRootCluster2: IdentityRootCluster = { - active: true, - clusterName: 'violet', - userName: 'sammy', - uri: '/clusters/violet', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster2; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - name: activeIdentityRootCluster.userName, - roles: ['access', 'editor'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function ManyClustersWithProfileErrorsAndActiveCluster() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: false, - profileStatusError: profileStatusError, - }; - const identityRootCluster2: IdentityRootCluster = { - active: true, - clusterName: 'violet', - userName: 'sammy', - uri: '/clusters/violet', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: false, - profileStatusError: profileStatusError, - }; - - const activeIdentityRootCluster = identityRootCluster2; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - name: activeIdentityRootCluster.userName, - roles: ['access', 'editor'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + activeClusterUri={clusterOrange.uri} /> ); } export function LongNamesWithManyRoles() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - const identityRootCluster2: IdentityRootCluster = { - active: true, - clusterName: 'psv-eindhoven-eredivisie-production-lorem-ipsum', - userName: 'ruud-van-nistelrooy-van-der-sar', - uri: '/clusters/psv', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster2; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - name: activeIdentityRootCluster.userName, - roles: [ - 'circle-mark-app-access', - 'grafana-lite-app-access', - 'grafana-gold-app-access', - 'release-lion-app-access', - 'release-fox-app-access', - 'sales-center-lorem-app-access', - 'sales-center-ipsum-db-access', - 'sales-center-shop-app-access', - 'sales-center-floor-db-access', - ], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + activeClusterUri={clusterViolet.uri} /> ); } export function TrustedDeviceEnrolled() { - const identityRootCluster: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - isDeviceTrusted: true, - name: activeIdentityRootCluster.userName, - roles: ['circle-mark-app-access', 'grafana-lite-app-access'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function TrustedDeviceRequiredButNotEnrolled() { - const identityRootCluster: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - trustedDeviceRequirement: TrustedDeviceRequirement.REQUIRED, - name: activeIdentityRootCluster.userName, - roles: ['circle-mark-app-access'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx index ba52b2a9a872c..d9ae5e88962b9 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx @@ -25,7 +25,6 @@ import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/tru import { makeLoggedInUser, makeRootCluster, - rootClusterUri, } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; @@ -73,28 +72,11 @@ test.each([ }, ])('$name', async testCase => { const appContext = new MockAppContext(); - appContext.clustersService.setState(draft => { - draft.clusters.set( - rootClusterUri, - makeRootCluster({ - uri: rootClusterUri, - loggedInUser: testCase.user, - }) - ); - }); - - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = rootClusterUri; - draft.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [], - location: undefined, - accessRequests: { - isBarCollapsed: true, - pending: { kind: 'resource', resources: new Map() }, - }, - }; - }); + appContext.addRootCluster( + makeRootCluster({ + loggedInUser: testCase.user, + }) + ); render( diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx index f5c7cd25cbc1f..e15db0888d35d 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx @@ -16,14 +16,7 @@ * along with this program. If not, see . */ -import { - forwardRef, - useCallback, - useImperativeHandle, - useMemo, - useRef, - useState, -} from 'react'; +import { useCallback, useMemo, useRef, useState } from 'react'; import styled from 'styled-components'; import { Box } from 'design'; @@ -31,15 +24,16 @@ import Popover from 'design/Popover'; import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/trusted_device_requirement_pb'; import * as tshd from 'teleterm/services/tshd/types'; +import { KeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; +import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; import { useKeyboardShortcutFormatters, useKeyboardShortcuts, } from 'teleterm/ui/services/keyboardShortcuts'; -import { EmptyIdentityList } from './EmptyIdentityList/EmptyIdentityList'; -import { IdentityList } from './IdentityList/IdentityList'; +import { ActiveCluster, ClusterList } from './IdentityList/IdentityList'; import { IdentitySelector } from './IdentitySelector/IdentitySelector'; -import { IdentityRootCluster, useIdentity } from './useIdentity'; +import { useIdentity } from './useIdentity'; export function IdentityContainer() { const { @@ -48,17 +42,27 @@ export function IdentityContainer() { changeRootCluster, logout, addCluster, + refreshCluster, + changeColor, } = useIdentity(); + const selectorRef = useRef(); + const [open, setOpen] = useState(false); const { getLabelWithAccelerator } = useKeyboardShortcutFormatters(); - - const presenterRef = useRef(); + const hasClusters = activeRootCluster || rootClusters.length; + const togglePopoverOrAddCluster = useCallback(() => { + if (hasClusters) { + setOpen(o => !o); + } else { + addCluster(); + } + }, [addCluster, hasClusters]); useKeyboardShortcuts( useMemo( () => ({ - openProfiles: presenterRef.current?.togglePopover, + openProfiles: togglePopoverOrAddCluster, }), - [presenterRef.current?.togglePopover] + [togglePopoverOrAddCluster] ) ); @@ -68,109 +72,71 @@ export function IdentityContainer() { 'openProfiles' ); + function withClose any>( + fn: T + ): (...args: Parameters) => ReturnType { + return (...args) => { + setOpen(false); + return fn(...args); + }; + } + + const deviceTrustStatus = calculateDeviceTrustStatus( + activeRootCluster?.loggedInUser + ); + const activeColor = useStoreSelector( + 'workspacesService', + useCallback(state => state.workspaces[state.rootClusterUri]?.color, []) + ); + return ( - + <> + + setOpen(false)} + popoverCss={() => `max-width: min(450px, 90%)`} + > + + {activeRootCluster && ( + logout(activeRootCluster.uri))} + onRefresh={withClose(() => refreshCluster(activeRootCluster.uri))} + deviceTrustStatus={deviceTrustStatus} + /> + )} + + {focusGrabber} + + + + + ); } -export type IdentityHandler = { togglePopover: () => void }; - -export type IdentityProps = { - activeRootCluster: tshd.Cluster | undefined; - rootClusters: IdentityRootCluster[]; - changeRootCluster: (clusterUri: string) => Promise; - logout: (clusterUri: string) => void; - addCluster: () => void; - makeTitle: (userWithClusterName: string | undefined) => string; -}; - -export const Identity = forwardRef( - ( - { - activeRootCluster, - rootClusters, - changeRootCluster, - logout, - addCluster, - makeTitle, - }, - ref - ) => { - const selectorRef = useRef(); - const [isPopoverOpened, setIsPopoverOpened] = useState(false); - - const togglePopover = useCallback(() => { - setIsPopoverOpened(wasOpened => !wasOpened); - }, [setIsPopoverOpened]); - - function withClose any>( - fn: T - ): (...args: Parameters) => ReturnType { - return (...args) => { - setIsPopoverOpened(false); - return fn(...args); - }; - } - - useImperativeHandle(ref, () => ({ - togglePopover: () => { - togglePopover(); - }, - })); - - const loggedInUser = activeRootCluster?.loggedInUser; - - const deviceTrustStatus = calculateDeviceTrustStatus(loggedInUser); - - return ( - <> - - setIsPopoverOpened(false)} - popoverCss={() => `max-width: min(560px, 90%)`} - > - - {rootClusters.length ? ( - - ) : ( - - )} - - - - ); - } -); - const Container = styled(Box)` background: ${props => props.theme.colors.levels.elevated}; + min-width: 300px; width: 100%; `; @@ -192,3 +158,18 @@ function calculateDeviceTrustStatus( } return 'none'; } + +// Hack - for some reason xterm.js doesn't allow moving focus to the Identity popover +// when it is focused using element.focus(). +// It used to restore focus after the popover was closed, but this no longer seems to work. +const focusGrabber = ( + +); diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx deleted file mode 100644 index 71755da3d4a21..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 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 styled from 'styled-components'; - -import { Add } from 'design/Icon'; - -import { useKeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; -import { ListItem } from 'teleterm/ui/components/ListItem'; - -interface AddNewClusterItemProps { - index: number; - - onClick(): void; -} - -export function AddNewClusterItem(props: AddNewClusterItemProps) { - const { isActive } = useKeyboardArrowsNavigation({ - index: props.index, - onRun: props.onClick, - }); - - return ( - - - Add another cluster - - ); -} - -const StyledListItem = styled(ListItem)` - border-radius: 0; - height: 38px; - justify-content: center; - color: ${props => props.theme.colors.text.slightlyMuted}; -`; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx new file mode 100644 index 0000000000000..479b852d6b60f --- /dev/null +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx @@ -0,0 +1,130 @@ +/** + * Teleport + * Copyright (C) 2025 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 { useState } from 'react'; +import styled from 'styled-components'; + +import { Box, Flex } from 'design'; +import { Pencil } from 'design/Icon'; +import { useRefClickOutside } from 'shared/hooks/useRefClickOutside'; + +import { + WorkspaceColor, + workspaceColorMapping, + workspaceColors, +} from 'teleterm/ui/services/workspacesService'; + +import { UserIcon } from '../IdentitySelector/UserIcon'; + +export function ColorPicker(props: { + letter: string; + color: WorkspaceColor; + setColor(color: WorkspaceColor): void; +}) { + const [open, setOpen] = useState(false); + const [hoveredColor, setHoveredColor] = useState< + WorkspaceColor | undefined + >(); + const ref = useRefClickOutside({ open, setOpen }); + + const userIconProps = { + size: 'big' as const, + onClick: () => setOpen(o => !o), + letter: props.letter, + }; + + return ( + + + + + {open && ( + + + + {workspaceColors.options.map(color => ( + setHoveredColor(color)} + onMouseLeave={() => setHoveredColor(undefined)} + onClick={() => { + props.setColor(color); + setOpen(false); + }} + /> + ))} + + + )} + + ); +} + +const Circle = styled.button<{ color?: string }>` + border-radius: 50%; + background: ${props => props.color}; + height: 16px; + width: 16px; + border: none; + cursor: pointer; + box-shadow: rgba(0, 0, 0, 0.15) 0 1px 3px; + + &:focus-visible { + outline: 1px solid ${props => props.theme.colors.text.muted}; + } + + &:hover { + opacity: 0.9; + } +`; + +const AbsolutePencilIcon = styled(Pencil).attrs({ size: 11 })` + position: absolute; + bottom: -1px; + left: 21px; + border-radius: 50%; + color: black; + background: rgb(240, 240, 240); + box-shadow: rgba(0, 0, 0, 0.15) 0 1px 3px; + height: 16px; + width: 16px; +`; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx index 9f2d023272023..86158707c1200 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx @@ -19,68 +19,117 @@ import { JSX } from 'react'; import styled from 'styled-components'; -import { Box, Flex, Label, P3, Text } from 'design'; -import { ShieldCheck, ShieldWarning } from 'design/Icon'; +import { ButtonText, Flex, Label, P3 } from 'design'; +import { Logout, Refresh, ShieldCheck, ShieldWarning } from 'design/Icon'; import Link from 'design/Link'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; -import { LoggedInUser } from 'teleterm/services/tshd/types'; -import { KeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; +import { ProfileStatusError } from 'teleterm/ui/components/ProfileStatusError'; +import { WorkspaceColor } from 'teleterm/ui/services/workspacesService'; import { DeviceTrustStatus } from 'teleterm/ui/TopBar/Identity/Identity'; +import { RootClusterUri } from 'teleterm/ui/uri'; -import { IdentityRootCluster } from '../useIdentity'; -import { AddNewClusterItem } from './AddNewClusterItem'; -import { IdentityListItem } from './IdentityListItem'; +import { ColorPicker } from './ColorPicker'; +import { + AddClusterItem, + getClusterLetter, + IdentityListItem, + TitleAndSubtitle, +} from './IdentityListItem'; -export function IdentityList(props: { - loggedInUser: LoggedInUser; - clusters: IdentityRootCluster[]; - onSelectCluster(clusterUri: string): void; - onAddCluster(): void; - onLogout(clusterUri: string): void; +export function ActiveCluster(props: { + activeCluster: Cluster | undefined; + activeColor: WorkspaceColor; deviceTrustStatus: DeviceTrustStatus; + onChangeColor(color: WorkspaceColor): void; + onRefresh(): void; + onLogout(): void; }) { return ( - - {props.loggedInUser && ( - <> - - - {props.loggedInUser.name} - - {props.loggedInUser.roles.map(role => ( - - ))} - - - - - - - )} - - {focusGrabber} - - {props.clusters.map((cluster, index) => ( - props.onSelectCluster(cluster.uri)} - onLogout={() => props.onLogout(cluster.uri)} + <> + + + + - ))} - - - - + + + + props.onRefresh()} + > + + + props.onLogout()} + intent="danger" + size="small" + > + + + + + {props.activeCluster.profileStatusError && ( + props.theme.space[2]}px; + gap: 14px; + `} /> - - - + )} + + {props.activeCluster.loggedInUser?.roles.map(role => ( + + ))} + + + + + + ); +} + +export function ClusterList(props: { + clusters: Cluster[]; + onSelect(clusterUri: RootClusterUri): void; + onLogout?(clusterUri: RootClusterUri): void; + onAdd(): void; +}) { + return ( + <> + {props.clusters.map((cluster, index) => ( + props.onSelect(cluster.uri)} + onLogout={ + props.onLogout ? () => props.onLogout(cluster.uri) : undefined + } + /> + ))} + + ); } @@ -126,21 +175,6 @@ function DeviceTrustMessage(props: { status: DeviceTrustStatus }) { } } -// Hack - for some reason xterm.js doesn't allow moving a focus to the Identity popover -// when it is focused using element.focus(). Moreover, it looks like this solution has a benefit -// of returning the focus to the previously focused element when popover is closed. -const focusGrabber = ( - -); - const Separator = styled.div` background: ${props => props.theme.colors.spotBackground[1]}; height: 1px; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx index d1d053612d1dd..bc3a8b2f6248a 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx @@ -15,85 +15,157 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +import { useCallback } from 'react'; +import styled from 'styled-components'; -import { useState } from 'react'; - -import { ButtonIcon, Flex, Label, Text } from 'design'; +import { ButtonText, Flex, P3, Text } from 'design'; import { Logout } from 'design/Icon'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; import { useKeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; import { ListItem } from 'teleterm/ui/components/ListItem'; import { ProfileStatusError } from 'teleterm/ui/components/ProfileStatusError'; -import { getUserWithClusterName } from 'teleterm/ui/utils'; +import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; +import { WorkspaceColor } from 'teleterm/ui/services/workspacesService'; -import { IdentityRootCluster } from '../useIdentity'; +import { UserIcon } from '../IdentitySelector/UserIcon'; export function IdentityListItem(props: { index: number; - cluster: IdentityRootCluster; + cluster: Cluster; onSelect(): void; - onLogout(): void; + /** If defined, the logout button is rendered. */ + onLogout?(): void; }) { - const [isHovered, setIsHovered] = useState(false); const { isActive } = useKeyboardArrowsNavigation({ index: props.index, onRun: props.onSelect, }); - - const userWithClusterName = getUserWithClusterName(props.cluster); + const workspaceColor = useStoreSelector( + 'workspacesService', + useCallback( + state => state.workspaces[props.cluster.uri]?.color, + [props.cluster.uri] + ) + ); return ( - + (e.key === 'Enter' || e.key === 'Space') && props.onSelect() + } isActive={isActive} - onMouseEnter={() => { - setIsHovered(true); - }} - onMouseLeave={() => { - setIsHovered(false); - }} + title={`Switch to ${props.cluster.name}`} > - - - - {userWithClusterName} - - {props.cluster.profileStatusError && ( - - )} - - - {props.cluster.active ? ( - - ) : null} - + + {props.onLogout && ( + { e.stopPropagation(); props.onLogout(); }} > - {/* Due to the icon shape it appears to be not centered, so a small margin is added */} - - - + + + )} - + {props.cluster.profileStatusError && ( + props.theme.space[2]}px; + gap: 10px; + `} + /> + )} + ); } + +export function AddClusterItem(props: { index: number; onClick(): void }) { + const { isActive } = useKeyboardArrowsNavigation({ + index: props.index, + onRun: props.onClick, + }); + + return ( + + + + ); +} + +const StyledListItem = styled(ListItem)` + padding: ${props => props.theme.space[2]}px ${props => props.theme.space[3]}px; + flex-direction: column; + align-items: start; + gap: ${props => props.theme.space[1]}px; + border-radius: 0; + height: 100%; + &:hover .logout { + visibility: visible; + } +`; + +function WithIconItem(props: { + letter: string; + title: string; + subtitle?: string; + color?: WorkspaceColor; +}) { + return ( + + + + + ); +} + +export function TitleAndSubtitle(props: { title: string; subtitle?: string }) { + return ( + + + {props.title} + + + {props.subtitle && ( + + {props.subtitle} + + )} + + ); +} + +export function getClusterLetter(cluster: Cluster): string { + return cluster.name.at(0); +} diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx index c99d3f20ff729..df1d83ac0d7ee 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx @@ -19,35 +19,39 @@ import { forwardRef } from 'react'; import { Box } from 'design'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; +import { WorkspaceColor } from 'teleterm/ui/services/workspacesService'; import { ConnectionStatusIndicator } from 'teleterm/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator'; import { DeviceTrustStatus } from 'teleterm/ui/TopBar/Identity/Identity'; import { TopBarButton } from 'teleterm/ui/TopBar/TopBarButton'; import { getUserWithClusterName } from 'teleterm/ui/utils'; -import { PamIcon } from './PamIcon'; +import { getClusterLetter } from '../IdentityList/IdentityListItem'; import { UserIcon } from './UserIcon'; -interface IdentitySelectorProps { - isOpened: boolean; - userName: string; - clusterName: string; - onClick(): void; - makeTitle: (userWithClusterName: string | undefined) => string; - deviceTrustStatus: DeviceTrustStatus; -} - export const IdentitySelector = forwardRef< HTMLButtonElement, - IdentitySelectorProps + { + open: boolean; + activeCluster: Cluster | undefined; + onClick(): void; + makeTitle(userWithClusterName: string | undefined): string; + deviceTrustStatus: DeviceTrustStatus; + activeColor: WorkspaceColor; + } >((props, ref) => { - const isSelected = props.userName && props.clusterName; - const selectorText = isSelected && getUserWithClusterName(props); + const selectorText = + props.activeCluster && + getUserWithClusterName({ + clusterName: props.activeCluster.name, + userName: props.activeCluster.loggedInUser?.name, + }); const title = props.makeTitle(selectorText); return ( - {isSelected ? ( + {props.activeCluster ? ( - + {props.deviceTrustStatus === 'requires-enrollment' && ( ) : ( - + )} ); diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx deleted file mode 100644 index a7a4c9d4dc282..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 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 styled from 'styled-components'; - -import { Image } from 'design'; - -import pam from './pam.svg'; - -export function PamIcon() { - return ( - - - - ); -} - -const PamCircle = styled.div` - height: 24px; - width: 24px; - display: flex; - align-content: center; - justify-content: center; - border-radius: 50%; - background: ${props => props.theme.colors.spotBackground[0]}; -`; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx index 4807171195940..a71c1b3f571cf 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx @@ -16,25 +16,67 @@ * along with this program. If not, see . */ +import { MouseEvent, ReactNode } from 'react'; import styled from 'styled-components'; -interface UserIconProps { - letter: string; -} +import { + WorkspaceColor, + workspaceColorMapping, +} from 'teleterm/ui/services/workspacesService'; -export function UserIcon(props: UserIconProps) { - return {props.letter.toLocaleUpperCase()}; +export function UserIcon(props: { + letter: string; + /** If not provided, a default neutral color is rendered. */ + color?: WorkspaceColor; + onClick?(e: MouseEvent): void; + children?: ReactNode; + interactive?: boolean; + size?: 'regular' | 'big'; +}) { + return ( + + {props.letter?.toLocaleUpperCase()} + {props.children} + + ); } -const Circle = styled.span` +const Circle = styled.span<{ + color?: string; + interactive?: boolean; + size: string; +}>` + position: relative; border-radius: 50%; - color: ${props => props.theme.colors.buttons.primary.text}; - background: ${props => props.theme.colors.buttons.primary.default}; - height: 24px; - width: 24px; + color: ${props => + props.color + ? props.theme.colors.text.primaryInverse + : props.theme.colors.text.main}; + background: ${props => + props.color || props.theme.colors.interactive.tonal.neutral[1]}; + height: ${props => props.size}; + width: ${props => props.size}; display: flex; - flex-shrink: 0; + font-weight: 500; justify-content: center; align-items: center; - overflow: hidden; + box-shadow: rgba(0, 0, 0, 0.15) 0 1px 3px; + border: none; + &:focus-visible { + outline: 2px solid ${props => props.theme.colors.text.muted}; + } + ${props => + props.interactive && + ` + &:hover { + opacity: 0.9; + } + cursor: pointer; + `} `; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg deleted file mode 100644 index 8ae4aed3b0686..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts b/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts index a19e5201b3322..95e111e175594 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts +++ b/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts @@ -16,9 +16,14 @@ * along with this program. If not, see . */ -import { Cluster, LoggedInUser } from 'teleterm/services/tshd/types'; +import { useCallback } from 'react'; + +import { Cluster } from 'teleterm/services/tshd/types'; import { useAppContext } from 'teleterm/ui/appContextProvider'; -import { useWorkspaceServiceState } from 'teleterm/ui/services/workspacesService'; +import { + useWorkspaceServiceState, + WorkspaceColor, +} from 'teleterm/ui/services/workspacesService'; import { RootClusterUri } from 'teleterm/ui/uri'; export function useIdentity() { @@ -31,61 +36,43 @@ export function useIdentity() { await ctx.workspacesService.setActiveWorkspace(clusterUri); } - function addCluster(): void { + const addCluster = useCallback(() => { ctx.commandLauncher.executeCommand('cluster-connect', {}); + }, [ctx.commandLauncher]); + + function refreshCluster(clusterUri: RootClusterUri): void { + ctx.commandLauncher.executeCommand('cluster-connect', { clusterUri }); } function logout(clusterUri: RootClusterUri): void { ctx.commandLauncher.executeCommand('cluster-logout', { clusterUri }); } + const activeClusterUri = ctx.workspacesService.getRootClusterUri(); function getActiveRootCluster(): Cluster | undefined { - const clusterUri = ctx.workspacesService.getRootClusterUri(); - if (!clusterUri) { - return; - } - return ctx.clustersService.findCluster(clusterUri); + return ctx.clustersService.findCluster(activeClusterUri); } - function getLoggedInUser(): LoggedInUser | undefined { + function changeColor(color: WorkspaceColor): undefined { const clusterUri = ctx.workspacesService.getRootClusterUri(); if (!clusterUri) { return; } - const cluster = ctx.clustersService.findCluster(clusterUri); - if (!cluster) { - return; - } - return cluster.loggedInUser; + ctx.workspacesService.changeWorkspaceColor(clusterUri, color); } - const rootClusters: IdentityRootCluster[] = ctx.clustersService + const rootClusters = ctx.clustersService .getClusters() .filter(c => !c.leaf) - .map(cluster => ({ - active: cluster.uri === ctx.workspacesService.getRootClusterUri(), - clusterName: cluster.name, - userName: cluster.loggedInUser?.name, - uri: cluster.uri, - connected: cluster.connected, - profileStatusError: cluster.profileStatusError, - })); + .filter(c => c.uri !== activeClusterUri); return { changeRootCluster, addCluster, + refreshCluster, logout, - loggedInUser: getLoggedInUser(), + changeColor, activeRootCluster: getActiveRootCluster(), rootClusters, }; } - -export interface IdentityRootCluster { - active: boolean; - clusterName: string; - userName: string; - uri: RootClusterUri; - connected: boolean; - profileStatusError: string; -} diff --git a/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx b/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx index 7ea02bdc193bf..1ee0d43115751 100644 --- a/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx +++ b/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx @@ -106,6 +106,24 @@ export const KeyboardArrowsNavigation: FC = props => { ); }; +export const NullKeyboardArrowsNavigation: FC = props => { + const value = useMemo( + () => ({ + addItem: () => {}, + removeItem: () => {}, + activeIndex: -1, + setActiveIndex: () => {}, + }), + [] + ); + + return ( + +
{props.children}
+
+ ); +}; + function getNextIndex( items: RunActiveItemHandler[], currentIndex: number diff --git a/web/packages/teleterm/src/ui/components/ListItem.tsx b/web/packages/teleterm/src/ui/components/ListItem.tsx index 59b9ce56f70bc..44c2326f5bdc2 100644 --- a/web/packages/teleterm/src/ui/components/ListItem.tsx +++ b/web/packages/teleterm/src/ui/components/ListItem.tsx @@ -24,26 +24,33 @@ export const StaticListItem = styled.li` display: flex; align-items: center; justify-content: flex-start; - width: 100%; - position: relative; - font-size: 14px; - padding: 0 16px; + outline: none; font-weight: ${props => props.theme.regular}; font-family: ${props => props.theme.font}; color: ${props => props.theme.colors.text.main}; + position: relative; + font-size: 14px; + padding: 0 16px; height: 34px; background: inherit; border: none; border-radius: 4px; `; -export const ListItem = styled(StaticListItem)<{ isActive?: boolean }>` +export const ListItem = styled(StaticListItem).attrs({ tabIndex: 0 })<{ + isActive?: boolean; +}>` cursor: pointer; background: ${props => - props.isActive ? props.theme.colors.spotBackground[0] : null}; + props.isActive ? props.theme.colors.interactive.tonal.neutral[0] : null}; - &:focus, + &:focus-visible { + outline: 1px solid ${props => props.theme.colors.text.muted}; + background: ${props => props.theme.colors.interactive.tonal.neutral[0]}; + } &:hover { - background: ${props => props.theme.colors.spotBackground[0]}; + outline: 1px solid + ${props => props.theme.colors.interactive.tonal.neutral[0]}; + background: ${props => props.theme.colors.interactive.tonal.neutral[0]}; } `; diff --git a/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx b/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx index dfc6be8684823..de97f6432e863 100644 --- a/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx +++ b/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx @@ -21,12 +21,20 @@ import { Warning } from 'design/Icon'; export function ProfileStatusError(props: { error: string; - mb?: number | string; -}) { + className?: string; +}): JSX.Element { return ( - + - {toWellFormattedConnectionError(props.error)} + + {toWellFormattedConnectionError(props.error)} + ); } diff --git a/web/packages/teleterm/src/ui/fixtures/mocks.ts b/web/packages/teleterm/src/ui/fixtures/mocks.ts index f746eead52eb5..2c2d0a7b5d980 100644 --- a/web/packages/teleterm/src/ui/fixtures/mocks.ts +++ b/web/packages/teleterm/src/ui/fixtures/mocks.ts @@ -53,17 +53,11 @@ export class MockAppContext extends AppContext { draftState.clusters.set(cluster.uri, cluster); }); const docs = Array.isArray(doc) ? doc : [doc]; + this.workspacesService.addWorkspace(cluster.uri); this.workspacesService.setState(draftState => { draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - documents: docs.filter(Boolean), - location: docs[0]?.uri, - localClusterUri: cluster.uri, - accessRequests: { - isBarCollapsed: true, - pending: { kind: 'role', roles: new Set() }, - }, - }; + draftState.workspaces[cluster.uri].documents = docs.filter(Boolean); + draftState.workspaces[cluster.uri].location = docs[0]?.uri; }); } diff --git a/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts b/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts index c7a4c9c0795e4..16c29c9251631 100644 --- a/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts +++ b/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts @@ -272,6 +272,7 @@ function getTestSetupWithMockedDocuments(documents: Document[]) { // Insert the documents. workspacesService.setState(draftState => { draftState.workspaces['/clusters/localhost'] = { + color: 'purple', accessRequests: { pending: getEmptyPendingAccessRequest(), isBarCollapsed: false, diff --git a/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts b/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts index 75caa7cbc5cf5..074255002bd52 100644 --- a/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts +++ b/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts @@ -20,6 +20,7 @@ import { FileStorage } from 'teleterm/types'; import { ConnectionTrackerState } from 'teleterm/ui/services/connectionTracker'; import { Workspace, + WorkspaceColor, WorkspacesState, } from 'teleterm/ui/services/workspacesService'; @@ -31,14 +32,24 @@ interface UsageReportingState { askedForUserJobRole: boolean; } +/** + * Expected shape of the persisted workspaces. + * In the future, it should come from zod. + */ +export type PersistedWorkspace = Omit< + Workspace, + 'accessRequests' | 'documentsRestoredOrDiscarded' | 'color' +> & { + // TODO(gzdunek) DELETE IN v19.0.0: Make the field required by removing the 'color' type below and the omitted 'color' above. + // This only expresses that existing persisted state from older versions might not have color defined. + color?: WorkspaceColor; +}; + export type WorkspacesPersistedState = Omit< WorkspacesState, 'workspaces' | 'isInitialized' > & { - workspaces: Record< - string, - Omit - >; + workspaces: Record; }; export interface StatePersistenceState { diff --git a/web/packages/teleterm/src/ui/services/workspacesService/color.ts b/web/packages/teleterm/src/ui/services/workspacesService/color.ts new file mode 100644 index 0000000000000..8c1333aa68ab6 --- /dev/null +++ b/web/packages/teleterm/src/ui/services/workspacesService/color.ts @@ -0,0 +1,87 @@ +/** + * Teleport + * Copyright (C) 2025 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 { z } from 'zod'; + +import { dataVisualisationColors } from 'design/theme/themes/darkTheme'; + +import Logger from 'teleterm/logger'; + +export type WorkspaceColor = z.infer; + +export const workspaceColors = z.enum([ + 'purple', + 'green', + 'yellow', + 'red', + 'cyan', + 'pink', + 'blue', +]); + +// TODO(gzdunek): Parse the entire workspace state read from disk like below. +export function parseWorkspaceColor( + color: unknown, + workspaces: Record< + string, + { + color: WorkspaceColor; + } + > +): WorkspaceColor { + const getDefault = () => getNextWorkspaceColor(workspaces); + return workspaceColors + .default(getDefault) + .catch(ctx => { + new Logger('WorkspacesService').error( + 'Failed to read workspace color preference', + ctx.error + ); + return getDefault(); + }) + .parse(color); +} + +/** + * Determines the next available unused color across all workspaces. + * If all colors are already in use, it returns purple. + */ +function getNextWorkspaceColor( + workspaces: Record +): WorkspaceColor { + const takenColors = new Set(Object.values(workspaces).map(w => w.color)); + const allColors = new Set(workspaceColors.options); + const unusedColors = allColors.difference(takenColors); + return unusedColors.size > 0 ? [...unusedColors][0] : 'purple'; +} + +/** + * Maps workspace colors to the theme colors. + * We always use dark theme colors. + * They look good in both light and dark modes, + * and we avoid confusing users with different shades of the same color. + */ +export const workspaceColorMapping: Record = { + purple: dataVisualisationColors.primary.purple, + red: dataVisualisationColors.primary.abbey, + green: dataVisualisationColors.primary.caribbean, + yellow: dataVisualisationColors.primary.sunflower, + blue: dataVisualisationColors.primary.picton, + cyan: dataVisualisationColors.primary.cyan, + pink: dataVisualisationColors.primary.wednesdays, +}; diff --git a/web/packages/teleterm/src/ui/services/workspacesService/index.ts b/web/packages/teleterm/src/ui/services/workspacesService/index.ts index 23a5a63930c83..abf5d27d23ddb 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/index.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/index.ts @@ -18,3 +18,4 @@ export * from './workspacesService'; export * from './documentsService'; +export * from './color'; diff --git a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts index 8fd108779e9c7..48a18aff66d29 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts @@ -31,14 +31,14 @@ import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/docu import { ClustersService } from '../clusters'; import { ModalsService } from '../modals'; import { NotificationsService } from '../notifications'; -import { StatePersistenceService } from '../statePersistence'; +import { + PersistedWorkspace, + StatePersistenceService, + WorkspacesPersistedState, +} from '../statePersistence'; import { getEmptyPendingAccessRequest } from './accessRequestsService'; import { DocumentCluster, DocumentsService } from './documentsService'; -import { - Workspace, - WorkspacesService, - WorkspacesState, -} from './workspacesService'; +import { WorkspacesService, WorkspacesState } from './workspacesService'; beforeAll(() => { Logger.init(new NullService()); @@ -51,11 +51,7 @@ beforeEach(() => { describe('restoring workspace', () => { it('restores the workspace if there is a persisted state for given clusterUri', () => { const cluster = makeRootCluster(); - const testWorkspace: Workspace = { - accessRequests: { - isBarCollapsed: true, - pending: getEmptyPendingAccessRequest(), - }, + const testWorkspace: PersistedWorkspace = { localClusterUri: cluster.uri, documents: [ { @@ -85,6 +81,7 @@ describe('restoring workspace', () => { }, isBarCollapsed: false, }, + color: 'purple', localClusterUri: testWorkspace.localClusterUri, documents: [expect.objectContaining({ kind: 'doc.cluster' })], location: expect.any(String), @@ -121,6 +118,7 @@ describe('restoring workspace', () => { resources: new Map(), }, }, + color: 'purple', localClusterUri: cluster.uri, documents: [expect.objectContaining({ kind: 'doc.cluster' })], location: expect.any(String), @@ -136,6 +134,96 @@ describe('restoring workspace', () => { }); expect(workspacesService.getRestoredState().workspaces).toStrictEqual({}); }); + + it('restores workspace color from state or assigns if empty', async () => { + const clusterFoo = makeRootCluster({ uri: '/clusters/foo' }); + const workspaceFoo: PersistedWorkspace = { + color: 'blue', + localClusterUri: clusterFoo.uri, + documents: [], + location: undefined, + }; + const clusterBar = makeRootCluster({ uri: '/clusters/bar' }); + const workspaceBar: PersistedWorkspace = { + localClusterUri: clusterBar.uri, + documents: [], + location: undefined, + }; + const clusterBaz = makeRootCluster({ uri: '/clusters/baz' }); + const workspaceBaz: PersistedWorkspace = { + localClusterUri: clusterBaz.uri, + documents: [], + location: undefined, + }; + const clusterQux = makeRootCluster({ uri: '/clusters/qux' }); + const workspaceQux: PersistedWorkspace = { + localClusterUri: clusterQux.uri, + documents: [], + location: undefined, + }; + const clusterWaldo = makeRootCluster({ uri: '/clusters/waldo' }); + const workspaceWaldo: PersistedWorkspace = { + localClusterUri: clusterWaldo.uri, + documents: [], + location: undefined, + }; + const clusterFred = makeRootCluster({ uri: '/clusters/fred' }); + const workspaceFred: PersistedWorkspace = { + localClusterUri: clusterFred.uri, + documents: [], + location: undefined, + }; + const clusterGrault = makeRootCluster({ uri: '/clusters/grault' }); + const workspaceGrault: PersistedWorkspace = { + localClusterUri: clusterGrault.uri, + documents: [], + location: undefined, + }; + const clusterPlugh = makeRootCluster({ uri: '/clusters/plugh' }); + const workspacePlugh: PersistedWorkspace = { + localClusterUri: clusterPlugh.uri, + documents: [], + location: undefined, + }; + + const { workspacesService } = getTestSetup({ + cluster: [ + clusterFoo, + clusterBar, + clusterBaz, + clusterQux, + clusterWaldo, + clusterFred, + clusterGrault, + clusterPlugh, + ], + persistedWorkspaces: { + [clusterFoo.uri]: workspaceFoo, + [clusterBar.uri]: workspaceBar, + [clusterBaz.uri]: workspaceBaz, + [clusterQux.uri]: workspaceQux, + [clusterWaldo.uri]: workspaceWaldo, + [clusterFred.uri]: workspaceFred, + [clusterGrault.uri]: workspaceGrault, + [clusterPlugh.uri]: workspacePlugh, + }, + }); + + workspacesService.restorePersistedState(); + + expect(workspacesService.getWorkspace(clusterFoo.uri).color).toBe('blue'); // read from disk + expect(workspacesService.getWorkspace(clusterBar.uri).color).toBe('purple'); // the first unused color + expect(workspacesService.getWorkspace(clusterBaz.uri).color).toBe('green'); + expect(workspacesService.getWorkspace(clusterQux.uri).color).toBe('yellow'); + expect(workspacesService.getWorkspace(clusterWaldo.uri).color).toBe('red'); + expect(workspacesService.getWorkspace(clusterFred.uri).color).toBe('cyan'); + expect(workspacesService.getWorkspace(clusterGrault.uri).color).toBe( + 'pink' + ); + expect(workspacesService.getWorkspace(clusterPlugh.uri).color).toBe( + 'purple' + ); // we have run out of colors, assign the default purple color + }); }); describe('state persistence', () => { @@ -150,6 +238,7 @@ describe('state persistence', () => { isBarCollapsed: true, pending: getEmptyPendingAccessRequest(), }, + color: 'purple', localClusterUri: cluster.uri, documents: [ { @@ -309,11 +398,7 @@ describe('setActiveWorkspace', () => { it('sets location to first document if location points to non-existing document when reopening documents', async () => { const cluster = makeRootCluster(); - const testWorkspace: Workspace = { - accessRequests: { - isBarCollapsed: true, - pending: getEmptyPendingAccessRequest(), - }, + const testWorkspace: PersistedWorkspace = { localClusterUri: cluster.uri, documents: [ { @@ -374,11 +459,7 @@ describe('setActiveWorkspace', () => { it('ongoing setActive call is canceled when the method is called again', async () => { const clusterFoo = makeRootCluster({ uri: '/clusters/foo' }); const clusterBar = makeRootCluster({ uri: '/clusters/bar' }); - const workspace1: Workspace = { - accessRequests: { - isBarCollapsed: true, - pending: getEmptyPendingAccessRequest(), - }, + const workspace1: PersistedWorkspace = { localClusterUri: clusterFoo.uri, documents: [ { @@ -410,7 +491,7 @@ describe('setActiveWorkspace', () => { function getTestSetup(options: { cluster: tshd.Cluster | tshd.Cluster[] | undefined; - persistedWorkspaces: Record; + persistedWorkspaces: WorkspacesPersistedState['workspaces']; }) { const { cluster } = options; diff --git a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts index 6173dcb02881b..d7a1f6d55afe2 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts @@ -38,6 +38,7 @@ import { ImmutableStore } from 'teleterm/ui/services/immutableStore'; import { ModalsService } from 'teleterm/ui/services/modals'; import { NotificationsService } from 'teleterm/ui/services/notifications'; import { + PersistedWorkspace, StatePersistenceService, WorkspacesPersistedState, } from 'teleterm/ui/services/statePersistence'; @@ -54,6 +55,7 @@ import { getEmptyPendingAccessRequest, PendingAccessRequest, } from './accessRequestsService'; +import { parseWorkspaceColor, WorkspaceColor } from './color'; import { createClusterDocument, Document, @@ -82,6 +84,7 @@ export interface WorkspacesState { export interface Workspace { localClusterUri: ClusterUri; + color: WorkspaceColor; documents: Document[]; location: DocumentUri | undefined; accessRequests: { @@ -176,6 +179,15 @@ export class WorkspacesService extends ImmutableStore { }); } + changeWorkspaceColor( + rootClusterUri: RootClusterUri, + color: WorkspaceColor + ): void { + this.setState(draftState => { + draftState.workspaces[rootClusterUri].color = color; + }); + } + getWorkspaceDocumentService( clusterUri: RootClusterUri ): DocumentsService | undefined { @@ -373,10 +385,14 @@ export class WorkspacesService extends ImmutableStore { } } // If we don't have a workspace for this cluster, add it. + // TODO(gzdunek): Creating a workspace here might not be necessary + // after we started calling workspacesService.addWorkspace in ClusterAdd. this.setState(draftState => { if (!draftState.workspaces[clusterUri]) { - draftState.workspaces[clusterUri] = - getWorkspaceDefaultState(clusterUri); + draftState.workspaces[clusterUri] = getWorkspaceDefaultState( + clusterUri, + draftState.workspaces + ); } draftState.rootClusterUri = clusterUri; }); @@ -421,6 +437,18 @@ export class WorkspacesService extends ImmutableStore { return { isAtDesiredWorkspace: true }; } + addWorkspace(clusterUri: RootClusterUri): void { + if (this.state.workspaces[clusterUri]) { + return; + } + this.setState(draftState => { + draftState.workspaces[clusterUri] = getWorkspaceDefaultState( + clusterUri, + draftState.workspaces + ); + }); + } + removeWorkspace(clusterUri: RootClusterUri): void { this.setState(draftState => { delete draftState.workspaces[clusterUri]; @@ -459,6 +487,7 @@ export class WorkspacesService extends ImmutableStore { const restoredWorkspace = this.restoredState.workspaces[cluster.uri]; workspaces[cluster.uri] = getWorkspaceDefaultState( cluster.uri, + workspaces, restoredWorkspace ); return workspaces; @@ -558,6 +587,7 @@ export class WorkspacesService extends ImmutableStore { stateToSave.workspaces[w] = { localClusterUri: workspace.localClusterUri, location: workspace.location, + color: workspace.color, documents: documentsToPersist, connectMyComputer: workspace.connectMyComputer, unifiedResourcePreferences: workspace.unifiedResourcePreferences, @@ -633,7 +663,8 @@ function getLocationToRestore( function getWorkspaceDefaultState( rootClusterUri: RootClusterUri, - restoredWorkspace?: Immutable> + workspaces: Record, + restoredWorkspace?: Immutable ): Workspace { const defaultDocument = createClusterDocument({ clusterUri: rootClusterUri }); const defaultWorkspace: Workspace = { @@ -647,6 +678,7 @@ function getWorkspaceDefaultState( hasDocumentsToReopen: false, localClusterUri: rootClusterUri, unifiedResourcePreferences: parseUnifiedResourcePreferences(undefined), + color: parseWorkspaceColor(undefined, workspaces), }; if (!restoredWorkspace) { return defaultWorkspace; @@ -656,6 +688,10 @@ function getWorkspaceDefaultState( defaultWorkspace.unifiedResourcePreferences = parseUnifiedResourcePreferences( restoredWorkspace.unifiedResourcePreferences ); + defaultWorkspace.color = parseWorkspaceColor( + restoredWorkspace.color, + workspaces + ); defaultWorkspace.connectMyComputer = restoredWorkspace.connectMyComputer; defaultWorkspace.hasDocumentsToReopen = hasDocumentsToReopen({ previousDocuments: restoredWorkspace.documents, From b63b38e78c5d271e882c641580ecff574dbdccf7 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 30 Jan 2025 13:26:01 -0500 Subject: [PATCH 21/27] Add Audit Log tab to tctl top (#51655) The new tab consumes `audit_failed_emit_events`, `teleport_audit_stored_trimmed_events`, and `teleport_audit_emitted_event_sizes` to help troubleshoot issues related to audit log backends. The metrics are displayed in graphs which illustrate the change in metrics over the sampling period. --- tool/tctl/common/top/model.go | 59 ++++++++++++++++- tool/tctl/common/top/report.go | 118 ++++++++++++++++++++++++++++++++- tool/tsh/common/latency.go | 1 + 3 files changed, 176 insertions(+), 2 deletions(-) diff --git a/tool/tctl/common/top/model.go b/tool/tctl/common/top/model.go index be7debcd6105e..dd4668a197d64 100644 --- a/tool/tctl/common/top/model.go +++ b/tool/tctl/common/top/model.go @@ -103,6 +103,8 @@ func (m *topModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.selected = 2 case "4": m.selected = 3 + case "5": + m.selected = 4 case "right": m.selected = min(m.selected+1, len(tabs)-1) case "left": @@ -218,6 +220,8 @@ func (m *topModel) contentView() string { return renderCache(m.report, m.height, m.width) case 3: return renderWatcher(m.report, m.height, m.width) + case 4: + return renderAudit(m.report, m.height, m.width) default: return "" } @@ -412,6 +416,7 @@ func renderWatcher(report *Report, height, width int) string { eventData, asciigraph.Height(graphHeight), asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), ) eventCountContent := boxedView("Events/Sec", countPlot, graphWidth) @@ -423,6 +428,7 @@ func renderWatcher(report *Report, height, width int) string { sizeData, asciigraph.Height(graphHeight), asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), ) eventSizeContent := boxedView("Bytes/Sec", sizePlot, graphWidth) @@ -449,6 +455,54 @@ func renderWatcher(report *Report, height, width int) string { ) } +// renderAudit generates the view for the audit stats tab. +func renderAudit(report *Report, height, width int) string { + graphHeight := height / 3 + graphWidth := width + + eventsLegend := lipgloss.JoinHorizontal( + lipgloss.Left, + "- Emitted", + failedEventStyle.Render(" - Failed"), + trimmedEventStyle.Render(" - Trimmed"), + ) + + eventsPlot := asciigraph.PlotMany( + [][]float64{ + report.Audit.EmittedEventsBuffer.Data(graphWidth - 15), + report.Audit.FailedEventsBuffer.Data(graphWidth - 15), + report.Audit.TrimmedEventsBuffer.Data(graphWidth - 15), + }, + asciigraph.Height(graphHeight), + asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), + asciigraph.SeriesColors(asciigraph.Default, asciigraph.Red, asciigraph.Goldenrod), + asciigraph.Caption(eventsLegend), + ) + eventGraph := boxedView("Events Emitted", eventsPlot, graphWidth) + + eventSizePlot := asciigraph.Plot( + report.Audit.EventSizeBuffer.Data(graphWidth-15), + asciigraph.Height(graphHeight), + asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), + ) + sizeGraph := boxedView("Event Sizes", eventSizePlot, graphWidth) + + graphStyle := lipgloss.NewStyle(). + Width(graphWidth). + Padding(0). + Margin(0). + Align(lipgloss.Left) + + return lipgloss.JoinVertical(lipgloss.Left, + graphStyle.Render( + eventGraph, + sizeGraph, + ), + ) +} + // tabView renders the tabbed content in the header. func tabView(selectedTab int) string { output := lipgloss.NewStyle(). @@ -520,5 +574,8 @@ var ( selectedColor = lipgloss.Color("4") - tabs = []string{"Common", "Backend", "Cache", "Watcher"} + failedEventStyle = lipgloss.NewStyle().Foreground(lipgloss.Color(fmt.Sprintf("%d", asciigraph.Red))) + trimmedEventStyle = lipgloss.NewStyle().Foreground(lipgloss.Color(fmt.Sprintf("%d", asciigraph.Goldenrod))) + + tabs = []string{"Common", "Backend", "Cache", "Watcher", "Audit"} ) diff --git a/tool/tctl/common/top/report.go b/tool/tctl/common/top/report.go index 95ff68382804f..b185daf9958e9 100644 --- a/tool/tctl/common/top/report.go +++ b/tool/tctl/common/top/report.go @@ -59,6 +59,32 @@ type Report struct { Cluster ClusterStats // Watcher is watcher stats Watcher *WatcherStats + // Audit contains stats for audit event backends. + Audit *AuditStats +} + +// AuditStats contains metrics related to the audit log. +type AuditStats struct { + // FailedEventsCounter tallies the frequency of failed events. + FailedEventsCounter *Counter + // FailedEventsBuffer contains the historical frequencies of + // the FailedEventsCounter. + FailedEventsBuffer *utils.CircularBuffer + // EmittedEventsCounter tallies the frequency of all emitted events. + EmittedEventsCounter *Counter + // EmittedEventsBuffer contains the historical frequencies of + // the EmittedEventsCounter. + EmittedEventsBuffer *utils.CircularBuffer + // EventSizeCounter tallies the frequency of all events. + EventSizeCounter *Counter + // EventSizeBuffer contains the historical sizes of + // the EventSizeCounter. + EventSizeBuffer *utils.CircularBuffer + // EventsCounter tallies the frequency of trimmed events. + TrimmedEventsCounter *Counter + // TrimmedEventsBuffer contains the historical sizes of + // the TrimmedEventsCounter. + TrimmedEventsBuffer *utils.CircularBuffer } // WatcherStats contains watcher stats @@ -256,7 +282,8 @@ type Counter struct { } // SetFreq sets counter frequency based on the previous value -// and the time period +// and the time period. SetFreq should be preffered over UpdateFreq +// when initializing a Counter from previous statistics. func (c *Counter) SetFreq(prevCount Counter, period time.Duration) { if period == 0 { return @@ -265,6 +292,25 @@ func (c *Counter) SetFreq(prevCount Counter, period time.Duration) { c.Freq = &freq } +// UpdateFreq sets counter frequency based on the previous value +// and the time period. UpdateFreq should be preferred over SetFreq +// if the Counter is reused. +func (c *Counter) UpdateFreq(currentCount int64, period time.Duration) { + if period == 0 { + return + } + + // Do not calculate the frequency until there are two data points. + if c.Count == 0 && c.Freq == nil { + c.Count = currentCount + return + } + + freq := float64(currentCount-c.Count) / float64(period/time.Second) + c.Freq = &freq + c.Count = currentCount +} + // GetFreq returns frequency of the request func (c Counter) GetFreq() float64 { if c.Freq == nil { @@ -424,6 +470,13 @@ func generateReport(metrics map[string]*dto.MetricFamily, prev *Report, period t Roles: getGaugeValue(metrics[prometheus.BuildFQName(teleport.MetricNamespace, "", "roles_total")]), } + var auditStats *AuditStats + if prev != nil { + auditStats = prev.Audit + } + + re.Audit = getAuditStats(metrics, auditStats, period) + if prev != nil { re.Cluster.GenerateRequestsCount.SetFreq(prev.Cluster.GenerateRequestsCount, period) re.Cluster.GenerateRequestsThrottledCount.SetFreq(prev.Cluster.GenerateRequestsThrottledCount, period) @@ -548,6 +601,69 @@ func getWatcherStats(metrics map[string]*dto.MetricFamily, prev *WatcherStats, p return stats } +func getAuditStats(metrics map[string]*dto.MetricFamily, prev *AuditStats, period time.Duration) *AuditStats { + if prev == nil { + failed, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + events, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + trimmed, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + sizes, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + prev = &AuditStats{ + FailedEventsBuffer: failed, + FailedEventsCounter: &Counter{}, + EmittedEventsBuffer: events, + EmittedEventsCounter: &Counter{}, + TrimmedEventsBuffer: trimmed, + TrimmedEventsCounter: &Counter{}, + EventSizeBuffer: sizes, + EventSizeCounter: &Counter{}, + } + } + + updateCounter := func(metrics map[string]*dto.MetricFamily, metric string, counter *Counter, buf *utils.CircularBuffer) { + current := getCounterValue(metrics[metric]) + counter.UpdateFreq(current, period) + buf.Add(counter.GetFreq()) + } + + updateCounter(metrics, prometheus.BuildFQName("", "audit", "failed_emit_events"), prev.FailedEventsCounter, prev.FailedEventsBuffer) + updateCounter(metrics, prometheus.BuildFQName(teleport.MetricNamespace, "audit", "stored_trimmed_events"), prev.TrimmedEventsCounter, prev.TrimmedEventsBuffer) + + histogram := getHistogram(metrics[prometheus.BuildFQName(teleport.MetricNamespace, "", "audit_emitted_event_sizes")], atIndex(0)) + + prev.EmittedEventsCounter.UpdateFreq(histogram.Count, period) + prev.EmittedEventsBuffer.Add(prev.EmittedEventsCounter.GetFreq()) + + prev.EventSizeCounter.UpdateFreq(int64(histogram.Sum), period) + prev.EventSizeBuffer.Add(prev.EventSizeCounter.GetFreq()) + + return &AuditStats{ + FailedEventsBuffer: prev.FailedEventsBuffer, + FailedEventsCounter: prev.FailedEventsCounter, + EmittedEventsBuffer: prev.EmittedEventsBuffer, + EmittedEventsCounter: prev.EmittedEventsCounter, + TrimmedEventsBuffer: prev.TrimmedEventsBuffer, + TrimmedEventsCounter: prev.TrimmedEventsCounter, + EventSizeBuffer: prev.EventSizeBuffer, + EventSizeCounter: prev.EventSizeCounter, + } +} + func getRemoteClusters(metric *dto.MetricFamily) []RemoteCluster { if metric == nil || metric.GetType() != dto.MetricType_GAUGE || len(metric.Metric) == 0 { return nil diff --git a/tool/tsh/common/latency.go b/tool/tsh/common/latency.go index 6089f58c7bd44..6c73bd73d623b 100644 --- a/tool/tsh/common/latency.go +++ b/tool/tsh/common/latency.go @@ -151,6 +151,7 @@ func (m *latencyModel) View() string { [][]float64{clientData, serverData}, asciigraph.Height(m.h-4), asciigraph.Width(m.w), + asciigraph.UpperBound(1), asciigraph.SeriesColors(clientColor, serverColor), asciigraph.Caption(legend), ) From 040ccf3f7fd2595f152d02b2372c913532013ec3 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Thu, 30 Jan 2025 13:36:50 -0700 Subject: [PATCH 22/27] Don't emit SSO failures to audit log for illegitimate requests (#51668) SSO flows are initiated via unauthenticated APIs, so it's not uncommon to see spam from security tools or malicious bots probing. If we can tell that these are not legitimate SSO attempts then we avoid emitting falures that clutter the audit log. --- lib/auth/auth_with_roles.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index e365758f709a9..2b0a02a313533 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -4148,7 +4148,14 @@ func (a *ServerWithRoles) CreateGithubAuthRequest(ctx context.Context, req types githubReq, err := a.authServer.CreateGithubAuthRequest(ctx, req) if err != nil { - emitSSOLoginFailureEvent(a.authServer.closeCtx, a.authServer.emitter, events.LoginMethodGithub, err, req.SSOTestFlow) + if trace.IsNotFound(err) { + // This flow is triggered via an unauthenticated endpoint, so it's not unusual to see + // attempts to hit this API with an invalid connector ID. These are not legitimate SSO + // attempts, so avoid cluttering the audit log with them. + a.authServer.logger.InfoContext(ctx, "rejecting invalid GitHub auth request", "connector", req.ConnectorID) + } else { + emitSSOLoginFailureEvent(a.authServer.closeCtx, a.authServer.emitter, events.LoginMethodGithub, err, req.SSOTestFlow) + } return nil, trace.Wrap(err) } From a8f2ae4eb5acc605669d9892a908c64799560515 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Thu, 30 Jan 2025 13:48:33 -0700 Subject: [PATCH 23/27] docs: add a dedicated section to desktop LDAP discovery (#51622) Closes #51485 --- .../desktop-access/active-directory.mdx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/pages/enroll-resources/desktop-access/active-directory.mdx b/docs/pages/enroll-resources/desktop-access/active-directory.mdx index 6615ecc4b5ce8..26e11fd4291e3 100644 --- a/docs/pages/enroll-resources/desktop-access/active-directory.mdx +++ b/docs/pages/enroll-resources/desktop-access/active-directory.mdx @@ -689,6 +689,61 @@ To connect to a Windows desktop: To view the recording, select **Management** in the Teleport Web UI, then click **Session Recordings** in the Activity section. +## LDAP Discovery + +In Active Directory environments, Teleport can be configured to discover hosts +via LDAP. LDAP discovery is enabled by setting the `discovery.base_dn` field in +the Teleport Windows Desktop Service configuration. You can set `base_dn` to a +wildcard `'*` to search from the root of the domain, or you can specify an alternate +base distinguished name to search from. + +```yaml +windows_desktop_service: + enabled: yes + discovery: + base_dn: '*' +``` + +### Filters + +Teleport optionally accepts a set of filters that can be used to narrow the +search results for discovery. The filters are specified with [LDAP +Filter](https://ldap.com/ldap-filters/) syntax. Teleport will automatically +compute a logical AND of all filters specified. + +```yaml +windows_desktop_service: + enabled: yes + discovery: + base_dn: '*' + filters: + - '(location=Oakland)' + - '(!(primaryGroupID=516))' +``` + +### Labeling + +It is often necessary to apply labels to discovered hosts to control access. You +can configure Teleport to convert LDAP attributes to Teleport labels by setting +the `discovery.label_attributes` field in the Teleport Windows Desktop Service +configuration. + +```yaml +windows_desktop_service: + enabled: yes + discovery: + base_dn: '*' + label_attributes: + - 'location' + - 'department' +``` + +Each of the specified attributes will be placed in a Teleport label prefixed with `ldap/`. + +For example, if an AD computer object had a location attribute with a value of Oakland, +and a department attribute with a value of Engineering, the Teleport resource for this +host would have both `ldap/location=Oakland` and `ldap/department=Engineering` labels. + ## Security hardening By default, the Default Domain Policy grants the **Add workstations to domain From 2bf229b4599f338f3ee1b780d0045fb9246e4c98 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Thu, 30 Jan 2025 15:11:24 -0700 Subject: [PATCH 24/27] docs: update CA import instructions for HSMs (#51623) Now that #51301 is merged, we have the ability to get all of the active user CA certificates. --- .../desktop-access/active-directory.mdx | 16 ++++++++++++++-- .../desktop-access/getting-started.mdx | 10 +++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/pages/enroll-resources/desktop-access/active-directory.mdx b/docs/pages/enroll-resources/desktop-access/active-directory.mdx index 26e11fd4291e3..73c9d00c285f3 100644 --- a/docs/pages/enroll-resources/desktop-access/active-directory.mdx +++ b/docs/pages/enroll-resources/desktop-access/active-directory.mdx @@ -237,7 +237,7 @@ You must repeat these steps if you rotate the Teleport user certificate authorit To export the Teleport user CA certificate: -1. Log on to a Windows domain controller where you can access **Group Policy Management**. +1. Log on to a Windows host where you can access **Group Policy Management**. 1. Open PowerShell and download the Teleport user certificate authority by running the following command and replacing `teleport.example.com` with the address of your Teleport cluster: @@ -246,7 +246,11 @@ To export the Teleport user CA certificate: $ curl.exe -fo user-ca.cer https:///webapi/auth/export?type=windows ``` -1. Take note of the path to the `user-ca.cer` file for use in a later step. + If you are using Teleport's support for HSM-backed keys, then your Teleport + cluster has multiple user CAs (one for each Auth Service instance). You can + download a bundle containing all CAs by appending `&format=zip` to the URL. + +1. Take note of the path to file you just downloaded for use in a later step. #### Create the GPO for the Teleport certificate @@ -289,6 +293,8 @@ To configure the group policy object: ![Import Teleport CA](../../../img/desktop-access/ca.png) + If you are using HSM-backed keys, you should repeat this step for each CA certificate. + 1. To ensure your GPO update takes effect immediately on this host, open PowerShell and run the following command (optional): @@ -314,6 +320,9 @@ To publish the Teleport certificate in the Active Directory domain: This command enables the domain controllers to trust the Teleport CA so that certificate-based smart card authentication through Teleport can succeed. + If you are using HSM-backed keys, you should repeat this step for each CA certificate + in the zip file you exported earlier in this guide. + #### Publish the Teleport CA to the NTAuth Store For authentication with Teleport-issued certificates to succeed, the @@ -322,6 +331,9 @@ Teleport periodically publishes its CA after it is able to authenticate, but this step must be performed manually the first time for Teleport to have LDAP access. +If you are using HSM-backed keys, you should repeat these steps for each CA certificate +in the bundle. + To publish the Teleport CA to LDAP: 1. Open PowerShell and run the following command using the path to the `user-ca.cer` diff --git a/docs/pages/enroll-resources/desktop-access/getting-started.mdx b/docs/pages/enroll-resources/desktop-access/getting-started.mdx index 520df5a97f79c..3170e6c05eaf4 100644 --- a/docs/pages/enroll-resources/desktop-access/getting-started.mdx +++ b/docs/pages/enroll-resources/desktop-access/getting-started.mdx @@ -48,6 +48,10 @@ To prepare a Windows computer: $ curl.exe -fo teleport.cer https:///webapi/auth/export?type=windows ``` + If you are using Teleport's support for HSM-backed keys, then your Teleport cluster + has multiple user CAs (one for each Auth Service instance). You can download a bundle + containing all CAs by appending `&format=zip` to the URL. + 3. Download the Teleport Windows Auth setup program: ```code @@ -55,7 +59,11 @@ $ curl.exe -fo teleport-windows-auth-setup-v(=teleport.version=)-amd64.exe https ``` 4. Double-click the executable you downloaded to run the Teleport Windows Auth Setup program -interactively and select the Teleport certificate that you exported when prompted. + interactively and select the Teleport certificate that you exported when prompted. + + If you are using Teleport's support for HSM-backed keys and you downloaded a zip file in step 2, + then you should extract the zip file and repeat the process below for each CA certificate. + You can defer the reboot until you have installed all of the certificates. The setup program: From 3e88b7134444e2aa8ea442edc57c5b185b355a6b Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Thu, 30 Jan 2025 14:16:59 -0800 Subject: [PATCH 25/27] Added 01/29 Upcoming Releases Update (#51621) * Added 01/29 Upcoming Releases Update * Zac update * Update upcoming-releases.mdx --------- Co-authored-by: Zac Bergquist Co-authored-by: Roman Tkachenko --- docs/pages/upcoming-releases.mdx | 52 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/docs/pages/upcoming-releases.mdx b/docs/pages/upcoming-releases.mdx index 8133354391611..193cb931198d4 100644 --- a/docs/pages/upcoming-releases.mdx +++ b/docs/pages/upcoming-releases.mdx @@ -9,39 +9,47 @@ The Teleport team delivers a new major release roughly every 4 months. | Version | Date | |---------|-----------------------------| -| 17.2.0 | Week of January 20th, 2025 | +| 17.3.0 | Week of February 24th, 2025 | +| 18.0.0 | Week of April 28th, 2025 | -### 17.2.0 +### 17.3.0 -#### Per-session MFA via IdP +#### Delegated joining for Oracle Cloud Infrastructure -Teleport users will be able to satisfy per-session MFA checks by authenticating -with an external identity provider as an alternative to using second factors -registered with Teleport. +Teleport agents running on Oracle Cloud Infrastructure (OCI) will be able to +join the Teleport cluster without a static join token. -*Delayed from Teleport 17.1.0.* +#### Stable UIDs for host-user creation -#### GitHub access +Teleport will provide the ability to create host users with stable UIDs across +the entire Teleport cluster. -Teleport will natively support GitHub access allowing users to transparently -interact with Github with RBAC and audit logging support. +#### VNet for Windows -*Delayed from Teleport 17.1.0.* +Teleport's VNet feature will be available for Windows, allowing users to access +TCP applications protected by Teleport as if they were on the same network. -#### Oracle Toad client support +### 18.0.0 -Oracle Database Access users will be able to use Toad GUI client. +#### Encrypted session recordings -#### Trusted clusters support for Kubernetes operator +Teleport will provide the ability to integrate with Hardware Security Modules +(HSMs) in order to encrypt session recordings prior to uploading them to storage. -Kubernetes operator users will be able to create trusted clusters using -Kubernetes custom resources. +#### Desktop Access in Teleport Connect + +Teleport Connect will allow users to connect to Windows desktops directly from +the Teleport Connect application without needing to use a browser. + +#### Azure Console via SAML IdP + +Teleport SAML IdP will support Azure web console as a service provider. ## Teleport Policy -| Version | Date | -|---------|---------------| -| 1.27.0 | January 2025 | +| Version | Date | +|---------|----------------| +| 1.27.0 | February 2025 | ### 1.27.0 @@ -61,10 +69,8 @@ The key deliverables for Teleport Cloud in the next quarter: | Week of | Description | |-----------------------|----------------------------------------------------------------| -| January 13th, 2025 | Teleport 17.1 will begin rollout on Cloud. | -| January 13th, 2025 | Teleport 17.1 agents will begin rollout to eligible tenants. | -| January 27th, 2025 | Teleport 17.2 will begin rollout on Cloud. | -| January 27th, 2025 | Teleport 17.2 agents will begin rollout to eligible tenants. | +| March 3rd, 2025 | Teleport 17.3 will begin rollout on Cloud. | +| March 3rd, 2025 | Teleport 17.3 agents will begin rollout to eligible tenants. | ## Production readiness From 757a57131b3f1df137fd965bbda1c7cedb091081 Mon Sep 17 00:00:00 2001 From: Brian Joerger Date: Thu, 30 Jan 2025 15:24:13 -0800 Subject: [PATCH 26/27] Fix WebUI Admin Action infinite retry with no MFA devices (#51134) (#51513) * Fix admin action retry method resulting in an infinite loop. * Return an empty challenge and challenge response instead of undefined. * Add api.getAdminActionMfaResponse and add new custom error message. * Resolve comments. * Don't swallow non-admin-action-required errors. * Remove unnecessary awaits. * Fix try/catch. --- .../ChangePasswordWizard.tsx | 2 +- web/packages/teleport/src/lib/term/tty.ts | 6 +- .../teleport/src/services/api/api.test.ts | 26 +++-- web/packages/teleport/src/services/api/api.ts | 109 +++++++++--------- .../teleport/src/services/auth/auth.ts | 17 +-- 5 files changed, 83 insertions(+), 77 deletions(-) diff --git a/web/packages/teleport/src/Account/ChangePasswordWizard/ChangePasswordWizard.tsx b/web/packages/teleport/src/Account/ChangePasswordWizard/ChangePasswordWizard.tsx index 738b88890b2dd..ce1bfdfb4b5f9 100644 --- a/web/packages/teleport/src/Account/ChangePasswordWizard/ChangePasswordWizard.tsx +++ b/web/packages/teleport/src/Account/ChangePasswordWizard/ChangePasswordWizard.tsx @@ -64,7 +64,7 @@ export function ChangePasswordWizard({ const reauthState = useReAuthenticate({ challengeScope: MfaChallengeScope.CHANGE_PASSWORD, onMfaResponse: async mfaResponse => - setWebauthnResponse(mfaResponse?.webauthn_response), + setWebauthnResponse(mfaResponse.webauthn_response), }); const [reauthMethod, setReauthMethod] = useState(); diff --git a/web/packages/teleport/src/lib/term/tty.ts b/web/packages/teleport/src/lib/term/tty.ts index de5f79a4da624..55aa52823411e 100644 --- a/web/packages/teleport/src/lib/term/tty.ts +++ b/web/packages/teleport/src/lib/term/tty.ts @@ -80,7 +80,7 @@ class Tty extends EventEmitterMfaSender { this.socket.send(bytearray.buffer); } - sendChallengeResponse(resp: MfaChallengeResponse) { + sendChallengeResponse(data: MfaChallengeResponse) { // we want to have the backend listen on a single message type // for any responses. so our data will look like data.webauthn, data.sso, etc // but to be backward compatible, we need to still spread the existing webauthn only fields @@ -88,8 +88,8 @@ class Tty extends EventEmitterMfaSender { // in 19, we can just pass "data" without this extra step // TODO (avatus): DELETE IN 19.0.0 const backwardCompatibleData = { - ...resp?.webauthn_response, - ...resp, + ...data.webauthn_response, + ...data, }; const encoded = this._proto.encodeChallengeResponse( JSON.stringify(backwardCompatibleData) diff --git a/web/packages/teleport/src/services/api/api.test.ts b/web/packages/teleport/src/services/api/api.test.ts index 7bc6005cdd056..5d2e470ddbf3d 100644 --- a/web/packages/teleport/src/services/api/api.test.ts +++ b/web/packages/teleport/src/services/api/api.test.ts @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { MfaChallengeResponse } from '../mfa'; import api, { defaultRequestOptions, getAuthHeaders, @@ -24,9 +25,18 @@ import api, { } from './api'; describe('api.fetch', () => { - const mockedFetch = jest.spyOn(global, 'fetch').mockResolvedValue({} as any); // we don't care about response + let mockedFetch: jest.SpiedFunction; + beforeEach(() => { + mockedFetch = jest + .spyOn(global, 'fetch') + .mockResolvedValue({ json: async () => ({}), ok: true } as Response); // we don't care about response + }); + + afterEach(() => { + jest.resetAllMocks(); + }); - const mfaResp = { + const mfaResp: MfaChallengeResponse = { webauthn_response: { id: 'some-id', type: 'some-type', @@ -43,7 +53,7 @@ describe('api.fetch', () => { }, }; - const customOpts = { + const customOpts: RequestInit = { method: 'POST', // Override the default header from `defaultRequestOptions`. headers: { @@ -51,10 +61,6 @@ describe('api.fetch', () => { }, }; - afterEach(() => { - jest.resetAllMocks(); - }); - test('default (no optional params provided)', async () => { await api.fetch('/something'); expect(mockedFetch).toHaveBeenCalledTimes(1); @@ -156,7 +162,7 @@ describe('api.fetch', () => { }); }); -// The code below should guard us from changes to api.fetchJson which would cause it to lose type +// The code below should guard us from changes to api.fetchJsonWithMfaAuthnRetry which would cause it to lose type // information, for example by returning `any`. const fooService = { @@ -171,13 +177,13 @@ const makeFoo = (): { foo: string } => { // This is a bogus test to satisfy Jest. We don't even need to execute the code that's in the async // function, we're interested only in the type system checking the code. -test('fetchJson does not return any', () => { +test('fetchJsonWithMfaAuthnRetry does not return any', () => { async () => { const result = await fooService.doSomething(); // Reading foo is correct. We add a bogus expect to satisfy Jest. result.foo; - // @ts-expect-error If there's no error here, it means that api.fetchJson returns any, which it + // @ts-expect-error If there's no error here, it means that api.fetchJsonWithMfaAuthnRetry returns any, which it // shouldn't. result.bar; }; diff --git a/web/packages/teleport/src/services/api/api.ts b/web/packages/teleport/src/services/api/api.ts index f253c43635186..ac386c641f6a4 100644 --- a/web/packages/teleport/src/services/api/api.ts +++ b/web/packages/teleport/src/services/api/api.ts @@ -150,66 +150,31 @@ const api = { customOptions: RequestInit, mfaResponse?: MfaChallengeResponse ): Promise { - const response = await api.fetch(url, customOptions, mfaResponse); - - let json; try { - json = await response.json(); + return await api.fetch(url, customOptions, mfaResponse); } catch (err) { - // error reading JSON - const message = response.ok - ? err.message - : `${response.status} - ${response.url}`; - throw new ApiError({ message, response, opts: { cause: err } }); - } - - if (response.ok) { - return json; - } - - /** This error can occur in the edge case where a role in the user's certificate was deleted during their session. */ - const isRoleNotFoundErr = isRoleNotFoundError(parseError(json)); - if (isRoleNotFoundErr) { - websession.logoutWithoutSlo({ - /* Don't remember location after login, since they may no longer have access to the page they were on. */ - rememberLocation: false, - /* Show "access changed" notice on login page. */ - withAccessChangedMessage: true, - }); - return; + // Retry with MFA if we get an admin action MFA error. + if (!mfaResponse && isAdminActionRequiresMfaError(err)) { + mfaResponse = await api.getAdminActionMfaResponse(); + return api.fetch(url, customOptions, mfaResponse); + } else { + throw err; + } } + }, - // Retry with MFA if we get an admin action missing MFA error. - const isAdminActionMfaError = isAdminActionRequiresMfaError( - parseError(json) - ); - const shouldRetry = isAdminActionMfaError && !mfaResponse; - if (!shouldRetry) { - throw new ApiError({ - message: parseError(json), - response, - proxyVersion: parseProxyVersion(json), - messages: json.messages, - }); - } + async getAdminActionMfaResponse() { + const challenge = await auth.getMfaChallenge({ + scope: MfaChallengeScope.ADMIN_ACTION, + }); - let mfaResponseForRetry; - try { - const challenge = await auth.getMfaChallenge({ - scope: MfaChallengeScope.ADMIN_ACTION, - }); - mfaResponseForRetry = await auth.getMfaChallengeResponse(challenge); - } catch { + if (!challenge) { throw new Error( - 'Failed to fetch MFA challenge. Please connect a registered hardware key and try again. If you do not have a hardware key registered, you can add one from your account settings page.' + 'This is an admin-level API request and requires MFA verification. Please try again with a registered MFA device. If you do not have an MFA device registered, you can add one in the account settings page.' ); } - return api.fetchJsonWithMfaAuthnRetry( - url, - customOptions, - mfaResponseForRetry - ); + return auth.getMfaChallengeResponse(challenge); }, /** @@ -254,7 +219,7 @@ const api = { * @param mfaResponse if defined (eg: `fetchJsonWithMfaAuthnRetry`) * will add a custom MFA header field that will hold the mfaResponse. */ - fetch( + async fetch( url: string, customOptions: RequestInit = {}, mfaResponse?: MfaChallengeResponse @@ -280,7 +245,41 @@ const api = { } // native call - return fetch(url, options); + const response = await fetch(url, options); + + let json; + try { + json = await response.json(); + } catch (err) { + // error reading JSON + const message = response.ok + ? err.message + : `${response.status} - ${response.url}`; + throw new ApiError({ message, response, opts: { cause: err } }); + } + + if (response.ok) { + return json; + } + + /** This error can occur in the edge case where a role in the user's certificate was deleted during their session. */ + const isRoleNotFoundErr = isRoleNotFoundError(parseError(json)); + if (isRoleNotFoundErr) { + websession.logoutWithoutSlo({ + /* Don't remember location after login, since they may no longer have access to the page they were on. */ + rememberLocation: false, + /* Show "access changed" notice on login page. */ + withAccessChangedMessage: true, + }); + return; + } + + throw new ApiError({ + message: parseError(json), + response, + proxyVersion: parseProxyVersion(json), + messages: json.messages, + }); }, }; @@ -326,8 +325,8 @@ export function getHostName() { return location.hostname + (location.port ? ':' + location.port : ''); } -function isAdminActionRequiresMfaError(errMessage) { - return errMessage.includes( +function isAdminActionRequiresMfaError(err: Error) { + return err.message.includes( 'admin-level API request requires MFA verification' ); } diff --git a/web/packages/teleport/src/services/auth/auth.ts b/web/packages/teleport/src/services/auth/auth.ts index 100259d6dfc20..3e58e9f5f5f4b 100644 --- a/web/packages/teleport/src/services/auth/auth.ts +++ b/web/packages/teleport/src/services/auth/auth.ts @@ -238,7 +238,7 @@ const auth = { .then(res => { const request = { action: 'accept', - webauthnAssertionResponse: res?.webauthn_response, + webauthnAssertionResponse: res.webauthn_response, }; return api.put(cfg.getHeadlessSsoPath(transactionId), request); @@ -254,11 +254,11 @@ const auth = { }, // getChallenge gets an MFA challenge for the provided parameters. If is_mfa_required_req - // is provided and it is found that MFA is not required, returns null instead. + // is provided and it is found that MFA is not required, returns undefined instead. async getMfaChallenge( req: CreateAuthenticateChallengeRequest, abortSignal?: AbortSignal - ) { + ): Promise { return api .post( cfg.api.mfaAuthnChallengePath, @@ -274,13 +274,14 @@ const auth = { }, // getChallengeResponse gets an MFA challenge response for the provided parameters. - // If is_mfa_required_req is provided and it is found that MFA is not required, returns null instead. + // If challenge is undefined or has no viable challenge options, returns empty response. async getMfaChallengeResponse( challenge: MfaAuthenticateChallenge, mfaType?: DeviceType, totpCode?: string - ): Promise { - if (!challenge) return; + ): Promise { + // No challenge, return empty response. + if (!challenge) return {}; // TODO(Joerger): If mfaType is not provided by a parent component, use some global context // to display a component, similar to the one used in useMfa. For now we just default to @@ -310,7 +311,7 @@ const auth = { } // No viable challenge, return empty response. - return; + return {}; }, async getWebAuthnChallengeResponse( @@ -439,7 +440,7 @@ const auth = { return auth .getMfaChallenge({ scope, allowReuse, isMfaRequiredRequest }, abortSignal) .then(challenge => auth.getMfaChallengeResponse(challenge, 'webauthn')) - .then(res => res?.webauthn_response); + .then(res => res.webauthn_response); }, getMfaChallengeResponseForAdminAction(allowReuse?: boolean) { From e9c7898ac4cf9165e32c51b8169fad37f1bce911 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:28:36 -0500 Subject: [PATCH 27/27] Tweaks to various sloglint overrides (#51522) (#51545) This aims to either alter logs to avoid the linter override, or at minimum prevent formatting of messages if the log level is not enabled. --- lib/auth/join/join.go | 12 ++--- .../awsoidc/eks_enroll_clusters.go | 7 ++- lib/service/pyroscope.go | 12 +++++ lib/service/service.go | 4 ++ tool/tbot/spiffe.go | 48 +++++++++++++++++-- 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/lib/auth/join/join.go b/lib/auth/join/join.go index 15deb2bb5da7b..01b5982414db0 100644 --- a/lib/auth/join/join.go +++ b/lib/auth/join/join.go @@ -495,12 +495,12 @@ func getHostAddresses(params RegisterParams) []string { // CA on disk. If no CA is found on disk, Teleport will not verify the Auth // Server it is connecting to. func insecureRegisterClient(ctx context.Context, params RegisterParams) (*authclient.Client, error) { - //nolint:sloglint // Conjoined string literals trip up the linter. - slog.WarnContext(ctx, "Joining cluster without validating the identity of the Auth "+ - "Server. This may open you up to a Man-In-The-Middle (MITM) attack if an "+ - "attacker can gain privileged network access. To remedy this, use the CA pin "+ - "value provided when join token was generated to validate the identity of "+ - "the Auth Server or point to a valid Certificate via the CA Path option.") + const msg = "Joining cluster without validating the identity of the Auth " + + "Server. This may open you up to a Man-In-The-Middle (MITM) attack if an " + + "attacker can gain privileged network access. To remedy this, use the CA pin " + + "value provided when join token was generated to validate the identity of " + + "the Auth Server or point to a valid Certificate via the CA Path option." + slog.WarnContext(ctx, msg) tlsConfig := utils.TLSConfig(params.CipherSuites) tlsConfig.Time = params.Clock.Now diff --git a/lib/integrations/awsoidc/eks_enroll_clusters.go b/lib/integrations/awsoidc/eks_enroll_clusters.go index dbeb6f2385484..14f3c848b975b 100644 --- a/lib/integrations/awsoidc/eks_enroll_clusters.go +++ b/lib/integrations/awsoidc/eks_enroll_clusters.go @@ -590,8 +590,11 @@ func getHelmActionConfig(ctx context.Context, clientGetter genericclioptions.RES // > func(format string, v ...interface{}) // slog.Log does not support it, so it must be added debugLogWithFormat := func(format string, v ...interface{}) { - formatString := fmt.Sprintf(format, v...) - log.DebugContext(ctx, formatString) //nolint:sloglint // message should be a constant but in this case we are creating it at runtime. + if !log.Handler().Enabled(ctx, slog.LevelDebug) { + return + } + //nolint:sloglint // message should be a constant but in this case we are creating it at runtime. + log.DebugContext(ctx, fmt.Sprintf(format, v...)) } if err := actionConfig.Init(clientGetter, agentNamespace, "secret", debugLogWithFormat); err != nil { return nil, trace.Wrap(err) diff --git a/lib/service/pyroscope.go b/lib/service/pyroscope.go index 34b289004a081..e911c6d722011 100644 --- a/lib/service/pyroscope.go +++ b/lib/service/pyroscope.go @@ -17,6 +17,7 @@ package service import ( + "context" "fmt" "log/slog" "os" @@ -33,16 +34,27 @@ type pyroscopeLogger struct { } func (l pyroscopeLogger) Infof(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelInfo) { + return + } //nolint:sloglint // msg cannot be constant l.l.Info(fmt.Sprintf(format, args...)) } func (l pyroscopeLogger) Debugf(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelDebug) { + return + } + //nolint:sloglint // msg cannot be constant l.l.Debug(fmt.Sprintf(format, args...)) } func (l pyroscopeLogger) Errorf(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelError) { + return + } + //nolint:sloglint // msg cannot be constant l.l.Error(fmt.Sprintf(format, args...)) } diff --git a/lib/service/service.go b/lib/service/service.go index bc174046d7891..526611db130c7 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -3430,6 +3430,10 @@ type promHTTPLogAdapter struct { // Println implements the promhttp.Logger interface. func (l promHTTPLogAdapter) Println(v ...interface{}) { + if !l.Handler().Enabled(l.ctx, slog.LevelError) { + return + } + //nolint:sloglint // msg cannot be constant l.ErrorContext(l.ctx, fmt.Sprint(v...)) } diff --git a/tool/tbot/spiffe.go b/tool/tbot/spiffe.go index f319505de8caa..1bfe3bfa43d6b 100644 --- a/tool/tbot/spiffe.go +++ b/tool/tbot/spiffe.go @@ -21,22 +21,64 @@ package main import ( "context" "fmt" + "log/slog" "time" "github.com/gravitational/trace" "github.com/spiffe/go-spiffe/v2/svid/jwtsvid" "github.com/spiffe/go-spiffe/v2/workloadapi" - - "github.com/gravitational/teleport/lib/utils" ) +// TODO(tross/noah): Remove once go-spiff has a slog<->workloadapi.Logger adapter. +// https://github.com/spiffe/go-spiffe/issues/281 +type logger struct { + l *slog.Logger +} + +func (l logger) Debugf(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelDebug) { + return + } + + //nolint:sloglint // msg cannot be constant + l.l.DebugContext(context.Background(), fmt.Sprintf(format, args...)) +} + +func (l logger) Infof(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelInfo) { + return + } + + //nolint:sloglint // msg cannot be constant + l.l.InfoContext(context.Background(), fmt.Sprintf(format, args...)) +} + +func (l logger) Warnf(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelWarn) { + return + } + + //nolint:sloglint // msg cannot be constant + l.l.WarnContext(context.Background(), fmt.Sprintf(format, args...)) +} + +func (l logger) Errorf(format string, args ...interface{}) { + if !l.l.Handler().Enabled(context.Background(), slog.LevelError) { + return + } + + //nolint:sloglint // msg cannot be constant + l.l.ErrorContext(context.Background(), fmt.Sprintf(format, args...)) +} + func onSPIFFEInspect(ctx context.Context, path string) error { log.InfoContext(ctx, "Inspecting SPIFFE Workload API Endpoint", "path", path) source, err := workloadapi.New( ctx, // TODO(noah): Upstream PR to add slog<->workloadapi.Logger adapter. - workloadapi.WithLogger(utils.NewLogger()), + // https://github.com/spiffe/go-spiffe/issues/281 + workloadapi.WithLogger(logger{l: slog.Default()}), workloadapi.WithAddr(path), ) if err != nil {