diff --git a/pkg/kubelet/BUILD b/pkg/kubelet/BUILD index f942cf4c2aa0b..b156983f15f21 100644 --- a/pkg/kubelet/BUILD +++ b/pkg/kubelet/BUILD @@ -22,6 +22,8 @@ go_library( "kubelet_node_status_windows.go", "kubelet_pods.go", "kubelet_resources.go", + "kubelet_usernamespace_linux.go", + "kubelet_usernamespace_others.go", "kubelet_volumes.go", "pod_container_deletor.go", "pod_workers.go", diff --git a/pkg/kubelet/container/runtime.go b/pkg/kubelet/container/runtime.go index 71f6dc20f7ef6..af9da624d8f57 100644 --- a/pkg/kubelet/container/runtime.go +++ b/pkg/kubelet/container/runtime.go @@ -115,6 +115,12 @@ type Runtime interface { // This method just proxies a new runtimeConfig with the updated // CIDR value down to the runtime shim. UpdatePodCIDR(podCIDR string) error + // GetRuntimeConfigInfo returns runtime's configuration details, eg: if user-namespaces are enabled or not + GetRuntimeConfigInfo() (*RuntimeConfigInfo, error) + // GetHostUID returns the uid from the host usernamespace that is mapped to the container usernamespace uid, containerUID + GetHostUID(containerUID int) (int, error) + // GetHostGID returns the gid from the host usernamespace that is mapped to the container usernamespace gid, containerGID + GetHostGID(containerGID int) (int, error) } // StreamingRuntime is the interface implemented by runtimes that handle the serving of the @@ -465,6 +471,62 @@ type RuntimeStatus struct { Conditions []RuntimeCondition } +// RuntimeConfigInfo contains runtime's configuration details, eg: user-namespaces mapping between host and container +type RuntimeConfigInfo struct { + UserNamespaceConfig UserNamespaceConfigInfo +} + +// UserNamespaceConfigInfo contains runtime's user-namespace configuration +type UserNamespaceConfigInfo struct { + UidMappings []*UserNSMapping + GidMappings []*UserNSMapping +} + +// UserNSMaping represents mapping of user-namespaces between host and container +type UserNSMapping struct { + ContainerID uint32 + HostID uint32 + Size uint32 +} + +// IsUserNamespaceEnabled returns true if user-namespace feature is enabled at runtime +func (c *RuntimeConfigInfo) IsUserNamespaceEnabled() bool { + if len(c.UserNamespaceConfig.UidMappings) == 1 && + c.UserNamespaceConfig.UidMappings[0].HostID == uint32(0) && c.UserNamespaceConfig.UidMappings[0].Size == uint32(4294967295) { + return false + } + return true +} + +// IsUserNamespaceSupported returns true if user-namespace feature is supported at runtime +func (c *RuntimeConfigInfo) IsUserNamespaceSupported() bool { + if len(c.UserNamespaceConfig.UidMappings) == 1 && + c.UserNamespaceConfig.UidMappings[0].HostID == uint32(0) && c.UserNamespaceConfig.UidMappings[0].Size == uint32(0) { + return false + } + return true +} + +// GetHostUIDFor returns uid on host usernamespace that is mapped to the given uid in container usernamespace +func (c *RuntimeConfigInfo) GetHostUIDFor(containerUID uint32) (int, error) { + for _, mapping := range c.UserNamespaceConfig.UidMappings { + if containerUID >= mapping.ContainerID && containerUID < mapping.ContainerID+mapping.Size { + return int(mapping.HostID + (containerUID - mapping.ContainerID)), nil + } + } + return -1, fmt.Errorf("IdMapping not found for container usernamespace UID %v", containerUID) +} + +// GetHostGIDFor returns gid on host usernamespace that is mapped to the given gid in container usernamespace +func (c *RuntimeConfigInfo) GetHostGIDFor(containerGID uint32) (int, error) { + for _, mapping := range c.UserNamespaceConfig.GidMappings { + if containerGID >= mapping.ContainerID && containerGID < mapping.ContainerID+mapping.Size { + return int(mapping.HostID + (containerGID - mapping.ContainerID)), nil + } + } + return -1, fmt.Errorf("IdMapping not found for container usernamespace GID %v", containerGID) +} + // GetRuntimeCondition gets a specified runtime condition from the runtime status. func (r *RuntimeStatus) GetRuntimeCondition(t RuntimeConditionType) *RuntimeCondition { for i := range r.Conditions { diff --git a/pkg/kubelet/container/testing/fake_runtime.go b/pkg/kubelet/container/testing/fake_runtime.go index 1824b8b84b785..fc0f2cb8263f5 100644 --- a/pkg/kubelet/container/testing/fake_runtime.go +++ b/pkg/kubelet/container/testing/fake_runtime.go @@ -41,23 +41,27 @@ type FakePod struct { // FakeRuntime is a fake container runtime for testing. type FakeRuntime struct { sync.Mutex - CalledFunctions []string - PodList []*FakePod - AllPodList []*FakePod - ImageList []kubecontainer.Image - APIPodStatus v1.PodStatus - PodStatus kubecontainer.PodStatus - StartedPods []string - KilledPods []string - StartedContainers []string - KilledContainers []string - RuntimeStatus *kubecontainer.RuntimeStatus - VersionInfo string - APIVersionInfo string - RuntimeType string - Err error - InspectErr error - StatusErr error + CalledFunctions []string + PodList []*FakePod + AllPodList []*FakePod + ImageList []kubecontainer.Image + APIPodStatus v1.PodStatus + PodStatus kubecontainer.PodStatus + StartedPods []string + KilledPods []string + StartedContainers []string + KilledContainers []string + RuntimeStatus *kubecontainer.RuntimeStatus + RuntimeConfigInfo *RuntimeConfigInfo + RuntimeConfigInfoErr error + VersionInfo string + APIVersionInfo string + RuntimeType string + Err error + InspectErr error + StatusErr error + RemappedUID int + RemappedGID int } const FakeHost = "localhost:12345" @@ -123,6 +127,8 @@ func (f *FakeRuntime) ClearCalls() { f.StartedContainers = []string{} f.KilledContainers = []string{} f.RuntimeStatus = nil + f.RuntimeConfigInfo = nil + f.RuntimeConfigInfoErr = nil f.VersionInfo = "" f.RuntimeType = "" f.Err = nil @@ -205,6 +211,22 @@ func (f *FakeRuntime) Status() (*kubecontainer.RuntimeStatus, error) { return f.RuntimeStatus, f.StatusErr } +func (f *FakeRuntime) GetRuntimeConfigInfo() (*RuntimeConfigInfo, error) { + f.Lock() + defer f.Unlock() + + f.CalledFunctions = append(f.CalledFunctions, "GetRuntimeConfigInfo") + return f.RuntimeConfigInfo, f.RuntimeConfigInfoErr +} + +func (f *FakeRuntime) GetRemappedIds() (int, int) { + f.Lock() + defer f.Unlock() + + f.CalledFunctions = append(f.CalledFunctions, "GetRemappedIds") + return f.RemappedUID, f.RemappedGID +} + func (f *FakeRuntime) GetPods(all bool) ([]*kubecontainer.Pod, error) { f.Lock() defer f.Unlock() diff --git a/pkg/kubelet/container/testing/runtime_mock.go b/pkg/kubelet/container/testing/runtime_mock.go index aa363649e30a0..af7f0d24cb89b 100644 --- a/pkg/kubelet/container/testing/runtime_mock.go +++ b/pkg/kubelet/container/testing/runtime_mock.go @@ -67,6 +67,21 @@ func (r *Mock) Status() (*kubecontainer.RuntimeStatus, error) { return args.Get(0).(*kubecontainer.RuntimeStatus), args.Error(0) } +func (r *Mock) GetRuntimeConfigInfo() (*RuntimeConfigInfo, error) { + args := r.Called() + return args.Get(0).(*RuntimeConfigInfo), args.Error(1) +} + +func (r *Mock) GetHostUID(containerUID int) (int, error) { + args := r.Called(containerUID) + return args.Get(0).(int), args.Error(1) +} + +func (r *Mock) GetHostGID(containerGID int) (int, error) { + args := r.Called(containerGID) + return args.Get(0).(int), args.Error(1) +} + func (r *Mock) GetPods(all bool) ([]*kubecontainer.Pod, error) { args := r.Called(all) return args.Get(0).([]*kubecontainer.Pod), args.Error(1) diff --git a/pkg/kubelet/dockershim/docker_sandbox.go b/pkg/kubelet/dockershim/docker_sandbox.go index 1824cdbadbf48..4af02c4cd9245 100644 --- a/pkg/kubelet/dockershim/docker_sandbox.go +++ b/pkg/kubelet/dockershim/docker_sandbox.go @@ -464,6 +464,7 @@ func (ds *dockerService) PodSandboxStatus(ctx context.Context, req *runtimeapi.P Network: networkNamespaceMode(r), Pid: pidNamespaceMode(r), Ipc: ipcNamespaceMode(r), + User: userNamespaceMode(r), }, }, }, @@ -690,6 +691,17 @@ func ipcNamespaceMode(container *dockertypes.ContainerJSON) runtimeapi.Namespace return runtimeapi.NamespaceMode_POD } +// userNamespaceMode returns the user runtimeapi.NamespaceMode for this container. +// Supports: POD, NODE +func userNamespaceMode(container *dockertypes.ContainerJSON) runtimeapi.NamespaceMode { + if container != nil && container.HostConfig != nil { + if string(container.HostConfig.UsernsMode) == namespaceModeHost { + return runtimeapi.NamespaceMode_NODE + } + } + return runtimeapi.NamespaceMode_POD +} + func constructPodSandboxCheckpoint(config *runtimeapi.PodSandboxConfig) checkpointmanager.Checkpoint { data := CheckpointData{} for _, pm := range config.GetPortMappings() { diff --git a/pkg/kubelet/dockershim/docker_service.go b/pkg/kubelet/dockershim/docker_service.go index 0f07a4ca23601..85544baa0b878 100644 --- a/pkg/kubelet/dockershim/docker_service.go +++ b/pkg/kubelet/dockershim/docker_service.go @@ -19,9 +19,13 @@ package dockershim import ( "context" "fmt" + "io/ioutil" "net/http" "path" "path/filepath" + "regexp" + "strconv" + "strings" "sync" "time" @@ -81,6 +85,10 @@ const ( // to kubelet behavior and system settings in addition to any API flags that may be introduced. ) +var ( + linuxIDMappingRegexp = regexp.MustCompile("([aA-zZ]+):([0-9]+):([0-9]+)") +) + // CRIService includes all methods necessary for a CRI server. type CRIService interface { runtimeapi.RuntimeServiceServer @@ -319,6 +327,106 @@ type dockerService struct { // TODO: handle context. +// GetRuntimeConfigInfo returns the runtime config. +func (ds *dockerService) GetRuntimeConfigInfo(_ context.Context, r *runtimeapi.GetRuntimeConfigInfoRequest) (*runtimeapi.GetRuntimeConfigInfoResponse, error) { + dockerInfo, err := ds.client.Info() + if err != nil { + return nil, fmt.Errorf("failed to execute Info() call to the Docker client: %v", err) + } + uidMapping := &runtimeapi.LinuxIDMapping{ContainerId: uint32(0)} + gidMapping := &runtimeapi.LinuxIDMapping{ContainerId: uint32(0)} + + if isUserNsEnabled(dockerInfo) { + remappedNonRootHostID, err := getRemappedNonRootHostID(dockerInfo) + if err != nil { + return nil, fmt.Errorf("failed to get remappedNonRootHostID: %v", err) + } + uidMappingSize, gidMappingSize, err := getUserNsMappingSizes(remappedNonRootHostID) + if err != nil { + return nil, fmt.Errorf("failed to get user-namespace mapping sizes: %v", err) + } + + uidMapping.HostId = remappedNonRootHostID + gidMapping.HostId = remappedNonRootHostID + uidMapping.Size_ = uidMappingSize + gidMapping.Size_ = gidMappingSize + } else { + uidMapping.Size_ = uint32(4294967295) + gidMapping.Size_ = uint32(4294967295) + } + + linuxConfig := &runtimeapi.LinuxUserNamespaceConfig{ + UidMappings: []*runtimeapi.LinuxIDMapping{uidMapping}, + GidMappings: []*runtimeapi.LinuxIDMapping{gidMapping}, + } + activeRuntimeConfig := &runtimeapi.ActiveRuntimeConfig{UserNamespaceConfig: linuxConfig} + return &runtimeapi.GetRuntimeConfigInfoResponse{RuntimeConfig: activeRuntimeConfig}, nil +} + +// isUserNsEnabled parses docker info. Returns true if user-namespace feature is found to enabled, otherwise false +func isUserNsEnabled(dockerInfo *dockertypes.Info) bool { + for _, secOpt := range dockerInfo.SecurityOptions { + if strings.Contains(secOpt, "userns") { + return true + } + } + return false +} + +// getRemappedNonRootHostID parses docker info to determine ID on the host usernamespace which is mapped to {U/G}ID 0 in the container user-namespace +func getRemappedNonRootHostID(dockerInfo *dockertypes.Info) (uint32, error) { + if strings.HasPrefix(dockerInfo.DockerRootDir, "/var/lib/docker/") { + remappedNonRootHostID64, err := strconv.ParseUint(strings.Split(strings.TrimPrefix(dockerInfo.DockerRootDir, "/var/lib/docker/"), ".")[0], 10, 0) + if err != nil { + return uint32(0), fmt.Errorf("failed to parse DockerRootDir, %v: %v", dockerInfo.DockerRootDir, err) + } + return uint32(remappedNonRootHostID64), nil + } else { + return uint32(0), fmt.Errorf("unexpected DockerRootDir, %v. Expected prefixed with '/var/lib/docker' ", dockerInfo.DockerRootDir) + } +} + +// getUserNsMappingSizes return uid and gid mapping sizes +func getUserNsMappingSizes(remappedNonRootHostID uint32) (uint32, uint32, error) { + mappings, err := ioutil.ReadFile("/etc/subuid") + if err != nil { + return 0, 0, fmt.Errorf("failed to read /etc/subuid: %v", err) + } + uidMappingSize, err := getIDMappingSize(mappings, remappedNonRootHostID) + if err != nil { + return 0, 0, fmt.Errorf("failed to get uid mapping size: %v", err) + } + + mappings, err = ioutil.ReadFile("/etc/subgid") + if err != nil { + return 0, 0, fmt.Errorf("failed to read /etc/subgid: %v", err) + } + gidMappingSize, err := getIDMappingSize(mappings, remappedNonRootHostID) + if err != nil { + return 0, 0, fmt.Errorf("failed to get gid mapping size: %v", err) + } + return uidMappingSize, gidMappingSize, nil +} + +// getIDMappingSize parses input byte array and returns mapping size +func getIDMappingSize(mappings []byte, hostID uint32) (uint32, error) { + matches := linuxIDMappingRegexp.FindAllSubmatch(mappings, -1) + for _, match := range matches { + uid, err := strconv.ParseUint(string(match[2]), 10, 32) + if err != nil { + return 0, fmt.Errorf("error in parsing linux user-namespace mapping entry: %s", match) + } + if uint32(uid) == hostID { + size, err := strconv.ParseUint(string(match[3]), 10, 32) + if err != nil { + return 0, fmt.Errorf("error in parsing linux user-namespace mapping entry: %s", match) + } + return uint32(size), nil + } + } + return 0, fmt.Errorf("could not find user-namespace mapping entry for ID %v", hostID) +} + // Version returns the runtime name, runtime version and runtime API version func (ds *dockerService) Version(_ context.Context, r *runtimeapi.VersionRequest) (*runtimeapi.VersionResponse, error) { v, err := ds.getDockerVersion() diff --git a/pkg/kubelet/dockershim/security_context.go b/pkg/kubelet/dockershim/security_context.go index d1ffbf78ea852..372dab2254cb0 100644 --- a/pkg/kubelet/dockershim/security_context.go +++ b/pkg/kubelet/dockershim/security_context.go @@ -170,6 +170,9 @@ func modifyCommonNamespaceOptions(nsOpts *runtimeapi.NamespaceOption, hostConfig // modifyHostOptionsForSandbox applies NetworkMode/UTSMode to sandbox's dockercontainer.HostConfig. func modifyHostOptionsForSandbox(nsOpts *runtimeapi.NamespaceOption, network *knetwork.PluginManager, hc *dockercontainer.HostConfig) { + if nsOpts.GetUser() == runtimeapi.NamespaceMode_NODE { + hc.UsernsMode = namespaceModeHost + } if nsOpts.GetIpc() == runtimeapi.NamespaceMode_NODE { hc.IpcMode = namespaceModeHost } @@ -199,6 +202,9 @@ func modifyHostOptionsForContainer(nsOpts *runtimeapi.NamespaceOption, podSandbo hc.NetworkMode = dockercontainer.NetworkMode(sandboxNSMode) hc.IpcMode = dockercontainer.IpcMode(sandboxNSMode) hc.UTSMode = "" + if nsOpts.GetUser() == runtimeapi.NamespaceMode_NODE { + hc.UsernsMode = namespaceModeHost + } if nsOpts.GetNetwork() == runtimeapi.NamespaceMode_NODE { hc.UTSMode = namespaceModeHost diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 307df7e97760c..353d240518689 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -26,6 +26,7 @@ import ( "net/url" "os" "path" + "path/filepath" "sort" "strings" "sync" @@ -492,57 +493,56 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, } klet := &Kubelet{ - hostname: hostname, - hostnameOverridden: len(hostnameOverride) > 0, - nodeName: nodeName, - kubeClient: kubeDeps.KubeClient, - heartbeatClient: kubeDeps.HeartbeatClient, - onRepeatedHeartbeatFailure: kubeDeps.OnHeartbeatFailure, - rootDirectory: rootDirectory, - resyncInterval: kubeCfg.SyncFrequency.Duration, - sourcesReady: config.NewSourcesReady(kubeDeps.PodConfig.SeenAllSources), - registerNode: registerNode, - registerWithTaints: registerWithTaints, - registerSchedulable: registerSchedulable, - dnsConfigurer: dns.NewConfigurer(kubeDeps.Recorder, nodeRef, parsedNodeIP, clusterDNS, kubeCfg.ClusterDomain, kubeCfg.ResolverConfig), - serviceLister: serviceLister, - nodeLister: nodeLister, - masterServiceNamespace: masterServiceNamespace, - streamingConnectionIdleTimeout: kubeCfg.StreamingConnectionIdleTimeout.Duration, - recorder: kubeDeps.Recorder, - cadvisor: kubeDeps.CAdvisorInterface, - cloud: kubeDeps.Cloud, - externalCloudProvider: cloudprovider.IsExternal(cloudProvider), - providerID: providerID, - nodeRef: nodeRef, - nodeLabels: nodeLabels, - nodeStatusUpdateFrequency: kubeCfg.NodeStatusUpdateFrequency.Duration, - nodeStatusReportFrequency: kubeCfg.NodeStatusReportFrequency.Duration, - os: kubeDeps.OSInterface, - oomWatcher: oomWatcher, - cgroupsPerQOS: kubeCfg.CgroupsPerQOS, - cgroupRoot: kubeCfg.CgroupRoot, - mounter: kubeDeps.Mounter, - hostutil: kubeDeps.HostUtil, - subpather: kubeDeps.Subpather, - maxPods: int(kubeCfg.MaxPods), - podsPerCore: int(kubeCfg.PodsPerCore), - syncLoopMonitor: atomic.Value{}, - daemonEndpoints: daemonEndpoints, - containerManager: kubeDeps.ContainerManager, - containerRuntimeName: containerRuntime, - redirectContainerStreaming: crOptions.RedirectContainerStreaming, - nodeIP: parsedNodeIP, - nodeIPValidator: validateNodeIP, - clock: clock.RealClock{}, - enableControllerAttachDetach: kubeCfg.EnableControllerAttachDetach, - iptClient: utilipt.New(utilexec.New(), protocol), - makeIPTablesUtilChains: kubeCfg.MakeIPTablesUtilChains, - iptablesMasqueradeBit: int(kubeCfg.IPTablesMasqueradeBit), - iptablesDropBit: int(kubeCfg.IPTablesDropBit), - experimentalHostUserNamespaceDefaulting: utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalHostUserNamespaceDefaultingGate), - keepTerminatedPodVolumes: keepTerminatedPodVolumes, - nodeStatusMaxImages: nodeStatusMaxImages, + hostname: hostname, + hostnameOverridden: len(hostnameOverride) > 0, + nodeName: nodeName, + kubeClient: kubeDeps.KubeClient, + heartbeatClient: kubeDeps.HeartbeatClient, + onRepeatedHeartbeatFailure: kubeDeps.OnHeartbeatFailure, + rootDirectory: rootDirectory, + resyncInterval: kubeCfg.SyncFrequency.Duration, + sourcesReady: config.NewSourcesReady(kubeDeps.PodConfig.SeenAllSources), + registerNode: registerNode, + registerWithTaints: registerWithTaints, + registerSchedulable: registerSchedulable, + dnsConfigurer: dns.NewConfigurer(kubeDeps.Recorder, nodeRef, parsedNodeIP, clusterDNS, kubeCfg.ClusterDomain, kubeCfg.ResolverConfig), + serviceLister: serviceLister, + nodeLister: nodeLister, + masterServiceNamespace: masterServiceNamespace, + streamingConnectionIdleTimeout: kubeCfg.StreamingConnectionIdleTimeout.Duration, + recorder: kubeDeps.Recorder, + cadvisor: kubeDeps.CAdvisorInterface, + cloud: kubeDeps.Cloud, + externalCloudProvider: cloudprovider.IsExternal(cloudProvider), + providerID: providerID, + nodeRef: nodeRef, + nodeLabels: nodeLabels, + nodeStatusUpdateFrequency: kubeCfg.NodeStatusUpdateFrequency.Duration, + nodeStatusReportFrequency: kubeCfg.NodeStatusReportFrequency.Duration, + os: kubeDeps.OSInterface, + oomWatcher: oomWatcher, + cgroupsPerQOS: kubeCfg.CgroupsPerQOS, + cgroupRoot: kubeCfg.CgroupRoot, + mounter: kubeDeps.Mounter, + hostutil: kubeDeps.HostUtil, + subpather: kubeDeps.Subpather, + maxPods: int(kubeCfg.MaxPods), + podsPerCore: int(kubeCfg.PodsPerCore), + syncLoopMonitor: atomic.Value{}, + daemonEndpoints: daemonEndpoints, + containerManager: kubeDeps.ContainerManager, + containerRuntimeName: containerRuntime, + redirectContainerStreaming: crOptions.RedirectContainerStreaming, + nodeIP: parsedNodeIP, + nodeIPValidator: validateNodeIP, + clock: clock.RealClock{}, + enableControllerAttachDetach: kubeCfg.EnableControllerAttachDetach, + iptClient: utilipt.New(utilexec.New(), protocol), + makeIPTablesUtilChains: kubeCfg.MakeIPTablesUtilChains, + iptablesMasqueradeBit: int(kubeCfg.IPTablesMasqueradeBit), + iptablesDropBit: int(kubeCfg.IPTablesDropBit), + keepTerminatedPodVolumes: keepTerminatedPodVolumes, + nodeStatusMaxImages: nodeStatusMaxImages, } if klet.cloud != nil { @@ -570,10 +570,6 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, klet.secretManager = secretManager klet.configMapManager = configMapManager - if klet.experimentalHostUserNamespaceDefaulting { - klog.Infof("Experimental host user namespace defaulting is enabled.") - } - machineInfo, err := klet.cadvisor.MachineInfo() if err != nil { return nil, err @@ -1197,13 +1193,6 @@ type Kubelet struct { // The handler serving CRI streaming calls (exec/attach/port-forward). criHandler http.Handler - // experimentalHostUserNamespaceDefaulting sets userns=true when users request host namespaces (pid, ipc, net), - // are using non-namespaced capabilities (mknod, sys_time, sys_module), the pod contains a privileged container, - // or using host path volumes. - // This should only be enabled when the container runtime is performing user remapping AND if the - // experimental behavior is desired. - experimentalHostUserNamespaceDefaulting bool - // dockerLegacyService contains some legacy methods for backward compatibility. // It should be set only when docker is using non json-file logging driver. dockerLegacyService dockershim.DockerLegacyService @@ -1226,6 +1215,17 @@ type Kubelet struct { runtimeClassManager *runtimeclass.Manager } +// isUserNamespaceRemappingEnabledAtRuntime return true if usernamespace remapping is enabled in configurations +func (kl *Kubelet) isUserNamespaceRemappingEnabledAtRuntime() (bool, error) { + ci, err := kl.containerRuntime.GetRuntimeConfigInfo() + if err != nil { + return false, fmt.Errorf("failed to get container runtime info: %v", err) + } + klog.V(4).Infof("Container runtime config info: %v", ci) + + return ci.IsUserNamespaceSupported() && ci.IsUserNamespaceEnabled(), nil +} + // setupDataDirs creates: // 1. the root directory // 2. the pods directory @@ -1266,6 +1266,67 @@ func (kl *Kubelet) setupDataDirs() error { return nil } +// chownDirForRemappedIDs change dir and path ownerships if UserNamespace is enabled at container runtime +// noop if UserNamespace is disabled +func (kl *Kubelet) chownDirForRemappedIDs(path string) error { + isUseNamespaceSupportedAndEnabled, err := kl.isUserNamespaceRemappingEnabledAtRuntime() + if err != nil { + klog.Warningf("error while determining usernamespace configuration at runtime: %v", err) + return nil + } + if !isUseNamespaceSupportedAndEnabled { + // No-Op if UserNamespace remapping is not enabled at runtime + return nil + } + if path == "" { + return fmt.Errorf("path to be setup is empty") + } + if err := kl.chownAllFilesAt(path); err != nil { + return fmt.Errorf("error setting ownership to remapped IDs on %s: %v", path, err) + } + return nil +} + +// chownAllFilesAt traverses the directory tree at the give path and chowns the paths to adjust for the remapped usernamespaces +func (kl *Kubelet) chownAllFilesAt(dir string) error { + var files []string + + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + files = append(files, path) + return nil + }) + if err != nil { + return err + } + klog.V(5).Infof("Chowned paths %v", files) + for _, file := range files { + _, fileGID, err := kl.getOwnerIDsFor(file) + if err != nil { + return fmt.Errorf("error in getting volume path owner UID/GID: %v", err) + } + if fileGID != 0 { + klog.V(5).Infof("GID, %v, for path %v is not equal to 0. Skipping chowing assuming it to be FsGroup GID ", fileGID, file) + continue + } + containerUID := 0 + containerGID := 0 + uid, err := kl.getHostUID(containerUID) + if err != nil { + return fmt.Errorf("Failed to get remapped host UID corresponding to UID 0 in container namespace: %v", err) + } + gid, err := kl.getHostGID(containerGID) + if err != nil { + return fmt.Errorf("Failed to get remapped host GID corresponding to GID 0 in container namespace: %v", err) + } + klog.V(5).Infof("Remapped default uid %d, default gid %d path %s", uid, gid, file) + err = os.Chown(file, uid, gid) + if err != nil { + return err + } + } + return nil +} + // StartGarbageCollection starts garbage collection threads. func (kl *Kubelet) StartGarbageCollection() { loggedContainerGCFailure := false @@ -1359,6 +1420,10 @@ func (kl *Kubelet) initializeModules() error { // initializeRuntimeDependentModules will initialize internal modules that require the container runtime to be up. func (kl *Kubelet) initializeRuntimeDependentModules() { + if err := kl.chownDirForRemappedIDs(kl.getPodsDir()); err != nil { + klog.Fatalf("Kubelet failed to change kubelet pod dir ownership to remapped user: %v", err) + } + if err := kl.cadvisor.Start(); err != nil { // Fail kubelet and rely on the babysitter to retry starting kubelet. // TODO(random-liu): Add backoff logic in the babysitter @@ -1687,6 +1752,17 @@ func (kl *Kubelet) syncPod(o syncPodOptions) error { // Call the container runtime's SyncPod callback result := kl.containerRuntime.SyncPod(pod, podStatus, pullSecrets, kl.backOff) + + // TODO(Alban): use helper function and constants + userns, _ := pod.Annotations["alpha.kinvolk.io/userns"] + klog.V(4).Infof("pod userns setting: %v", userns) + if userns == "enabled" { + if err := kl.chownDirForRemappedIDs(kl.getPodVolumesDir(pod.UID)); err != nil { + kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedMountVolume, "Unable to set ownership on mount volumes for pod %q: %v", format.Pod(pod), err) + klog.Errorf("Unable to chown volumes for pod %q: %v; skipping pod", format.Pod(pod), err) + return err + } + } kl.reasonCache.Update(pod.UID, result) if err := result.Error(); err != nil { // Do not return error if the only failures were pods in backoff diff --git a/pkg/kubelet/kubelet_getters.go b/pkg/kubelet/kubelet_getters.go index 3dfed31904d4c..09ab22b5a24c3 100644 --- a/pkg/kubelet/kubelet_getters.go +++ b/pkg/kubelet/kubelet_getters.go @@ -227,6 +227,16 @@ func (kl *Kubelet) getRuntime() kubecontainer.Runtime { return kl.containerRuntime } +// getHostUID returns the uid from the host usernamespace that is mapped to given UID on container user-namespace +func (kl *Kubelet) getHostUID(containerUID int) (int, error) { + return kl.containerRuntime.GetHostUID(containerUID) +} + +// getHostGID returns the gid from the host usernamespace that is mapped to given GID on container user-namespace +func (kl *Kubelet) getHostGID(containerGID int) (int, error) { + return kl.containerRuntime.GetHostGID(containerGID) +} + // GetNode returns the node info for the configured node name of this Kubelet. func (kl *Kubelet) GetNode() (*v1.Node, error) { if kl.kubeClient == nil { diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index bb109753e167d..71231bfb2dc9c 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -492,10 +492,8 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai } } - // only do this check if the experimental behavior is enabled, otherwise allow it to default to false - if kl.experimentalHostUserNamespaceDefaulting { - opts.EnableHostUserNamespace = kl.enableHostUserNamespace(pod) - } + opts.EnableHostUserNamespace = kl.enableHostUserNamespace(pod) + klog.V(5).Infof("opts.EnableHostUserNamespace %v for pod %s", opts.EnableHostUserNamespace, pod.Name) return opts, cleanupAction, nil } @@ -1767,12 +1765,11 @@ func hasHostVolume(pod *v1.Pod) bool { return false } -// hasHostNamespace returns true if hostIPC, hostNetwork, or hostPID are set to true. +// hasHostNamespace returns true if hostIPC, hostNetwork, or hostPID are set to true or userNamespaceRemapping is set to false. func hasHostNamespace(pod *v1.Pod) bool { - if pod.Spec.SecurityContext == nil { - return false - } - return pod.Spec.HostIPC || pod.Spec.HostNetwork || pod.Spec.HostPID + // TODO(Alban): use helper function and constants + userns, _ := pod.Annotations["alpha.kinvolk.io/userns"] + return pod.Spec.HostIPC || pod.Spec.HostNetwork || pod.Spec.HostPID || userns != "enabled" } // hasHostMountPVC returns true if a PVC is referencing a HostPath volume. diff --git a/pkg/kubelet/kubelet_pods_linux_test.go b/pkg/kubelet/kubelet_pods_linux_test.go index d60d95a49fc44..712a07772a592 100644 --- a/pkg/kubelet/kubelet_pods_linux_test.go +++ b/pkg/kubelet/kubelet_pods_linux_test.go @@ -270,7 +270,7 @@ func TestMakeMounts(t *testing.T) { } func TestMakeBlockVolumes(t *testing.T) { - testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */) + testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */, false) defer testKubelet.Cleanup() kubelet := testKubelet.kubelet testCases := map[string]struct { diff --git a/pkg/kubelet/kubelet_usernamespace_linux.go b/pkg/kubelet/kubelet_usernamespace_linux.go new file mode 100644 index 0000000000000..00a13fd5252c7 --- /dev/null +++ b/pkg/kubelet/kubelet_usernamespace_linux.go @@ -0,0 +1,40 @@ +// +build linux + +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubelet + +import ( + "fmt" + "os" + "syscall" +) + +// getOwnerIDsFor returns UID and GID of the path +func (kl *Kubelet) getOwnerIDsFor(path string) (int, int, error) { + fi, err := os.Lstat(path) + if err != nil { + return -1, -1, err + } + + s, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return -1, -1, fmt.Errorf("could not get IDs for path %s. Error in converting stat value to syscall.Stat_t", path) + } + + return int(s.Uid), int(s.Gid), nil +} diff --git a/pkg/kubelet/kubelet_usernamespace_others.go b/pkg/kubelet/kubelet_usernamespace_others.go new file mode 100644 index 0000000000000..3d7317fd06c0a --- /dev/null +++ b/pkg/kubelet/kubelet_usernamespace_others.go @@ -0,0 +1,24 @@ +// +build !linux + +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubelet + +// Do nothing. +func (kl *Kubelet) getOwnerIDsFor(path string) (int, int, error) { + return -1, -1, nil +} diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go index 2d970333b3bd2..153006c001c67 100644 --- a/pkg/kubelet/kuberuntime/helpers.go +++ b/pkg/kubelet/kuberuntime/helpers.go @@ -202,6 +202,51 @@ func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus) *kubecontainer.Runtim return &kubecontainer.RuntimeStatus{Conditions: conditions} } +// getRootIDMapping returns {U/G}ID mapping corresponding to ID '0' in container usernamespace +func getRootIDMapping(idMappings []*runtimeapi.LinuxIDMapping) *runtimeapi.LinuxIDMapping { + for _, mapping := range idMappings { + if mapping.ContainerId == uint32(0) { + return mapping + } + } + return nil +} + +// toKubeRuntimeConfig converts the runtimeapi.ActiveRuntimeConfig to kubecontainer.RuntimeConfigInfo +func toKubeRuntimeConfig(config *runtimeapi.ActiveRuntimeConfig) *kubecontainer.RuntimeConfigInfo { + usernsConfig := config.GetUserNamespaceConfig() + if usernsConfig == nil { + return &kubecontainer.RuntimeConfigInfo{} + } + uidMappingsRuntime := usernsConfig.GetUidMappings() + if uidMappingsRuntime == nil || len(uidMappingsRuntime) == 0 { + return &kubecontainer.RuntimeConfigInfo{} + } + gidMappingsRuntime := usernsConfig.GetGidMappings() + if gidMappingsRuntime == nil || len(gidMappingsRuntime) == 0 { + return &kubecontainer.RuntimeConfigInfo{} + } + var uidMappings []*kubecontainer.UserNSMapping + var gidMappings []*kubecontainer.UserNSMapping + for _, runtimeMapping := range uidMappingsRuntime { + uidMappings = append(uidMappings, &kubecontainer.UserNSMapping{ + ContainerID: runtimeMapping.ContainerId, + HostID: runtimeMapping.HostId, + Size: runtimeMapping.Size_}) + } + for _, runtimeMapping := range gidMappingsRuntime { + gidMappings = append(gidMappings, &kubecontainer.UserNSMapping{ + ContainerID: runtimeMapping.ContainerId, + HostID: runtimeMapping.HostId, + Size: runtimeMapping.Size_}) + } + userNSConfig := kubecontainer.UserNamespaceConfigInfo{ + UidMappings: uidMappings, + GidMappings: gidMappings, + } + return &kubecontainer.RuntimeConfigInfo{UserNamespaceConfig: userNSConfig} +} + // getSeccompProfileFromAnnotations gets seccomp profile from annotations. // It gets pod's profile if containerName is empty. func (m *kubeGenericRuntimeManager) getSeccompProfileFromAnnotations(annotations map[string]string, containerName string) string { @@ -256,6 +301,32 @@ func pidNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { return runtimeapi.NamespaceMode_CONTAINER } +func userNamespaceDefinedForPod(pod *v1.Pod) bool { + if pod == nil { + return false + } + userns, ok := pod.Annotations["alpha.kinvolk.io/userns"] + if !ok { + return false + } + if userns == "enabled" || userns == "disabled" { + return true + } + return false +} + +func userNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { + if !userNamespaceDefinedForPod(pod) { + return runtimeapi.NamespaceMode_NODE + } + userns, _ := pod.Annotations["alpha.kinvolk.io/userns"] + if userns == "enabled" { + return runtimeapi.NamespaceMode_POD + } else { + return runtimeapi.NamespaceMode_NODE + } +} + // namespacesForPod returns the runtimeapi.NamespaceOption for a given pod. // An empty or nil pod can be used to get the namespace defaults for v1.Pod. func namespacesForPod(pod *v1.Pod) *runtimeapi.NamespaceOption { @@ -263,5 +334,6 @@ func namespacesForPod(pod *v1.Pod) *runtimeapi.NamespaceOption { Ipc: ipcNamespaceForPod(pod), Network: networkNamespaceForPod(pod), Pid: pidNamespaceForPod(pod), + User: userNamespaceForPod(pod), } } diff --git a/pkg/kubelet/kuberuntime/instrumented_services.go b/pkg/kubelet/kuberuntime/instrumented_services.go index 48088346dcd3e..a4ea11d1466e9 100644 --- a/pkg/kubelet/kuberuntime/instrumented_services.go +++ b/pkg/kubelet/kuberuntime/instrumented_services.go @@ -265,6 +265,15 @@ func (in instrumentedRuntimeService) UpdateRuntimeConfig(runtimeConfig *runtimea return err } +func (in instrumentedRuntimeService) GetRuntimeConfigInfo() (*runtimeapi.ActiveRuntimeConfig, error) { + const operation = "get_runtime_config" + defer recordOperation(operation, time.Now()) + + out, err := in.service.GetRuntimeConfigInfo() + recordError(operation, err) + return out, err +} + func (in instrumentedImageManagerService) ListImages(filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error) { const operation = "list_images" defer recordOperation(operation, time.Now()) diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 524767934f1fe..49cf4cc890d30 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -238,6 +238,9 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Contai StdinOnce: container.StdinOnce, Tty: container.TTY, } + if opts.EnableHostUserNamespace { + //TODO(Alban): should we add the annotation here? + } // set platform specific configurations. if err := m.applyPlatformSpecificContainerConfig(config, container, pod, uid, username); err != nil { diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index a6b301c769f6a..ce561e8b6e377 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -137,6 +137,9 @@ type kubeGenericRuntimeManager struct { // Cache last per-container error message to reduce log spam logReduction *logreduction.LogReduction + + // cache of runtime configuration eg, user-namespace configuration + runtimeConfig *kubecontainer.RuntimeConfigInfo } // KubeGenericRuntime is a interface contains interfaces for container runtime and command. @@ -312,6 +315,32 @@ func (m *kubeGenericRuntimeManager) Status() (*kubecontainer.RuntimeStatus, erro return toKubeRuntimeStatus(status), nil } +// GetRuntimeConfigInfo returns runtime configuration details cached at runtime manager +func (m *kubeGenericRuntimeManager) GetRuntimeConfigInfo() (*kubecontainer.RuntimeConfigInfo, error) { + if m.runtimeConfig != nil { + return m.runtimeConfig, nil + } + runtimeConfig, err := m.runtimeService.GetRuntimeConfigInfo() + if err != nil { + return nil, fmt.Errorf("container runtime info get failed: %v", err) + } + ci := toKubeRuntimeConfig(runtimeConfig) + klog.V(4).Infof("Container runtime config info: %v", ci) + m.runtimeConfig = ci + + return ci, nil +} + +// GetHostUID returns UID on host namespace which is mapped to given UID on container namespace +func (m *kubeGenericRuntimeManager) GetHostUID(containerUID int) (int, error) { + return m.runtimeConfig.GetHostUIDFor(uint32(containerUID)) +} + +// GetHostGID returns GID on host namespace which is mapped to given GID on container namespace +func (m *kubeGenericRuntimeManager) GetHostGID(containerGID int) (int, error) { + return m.runtimeConfig.GetHostGIDFor(uint32(containerGID)) +} + // GetPods returns a list of containers grouped by pods. The boolean parameter // specifies whether the runtime returns all containers including those already // exited and dead containers (used for garbage collection). diff --git a/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go b/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go index 07824b3fbfd80..82143b25ad404 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go @@ -169,6 +169,15 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxLinuxConfig(pod *v1.Pod) ( } lc.SecurityContext.NamespaceOptions = namespacesForPod(pod) + if m.runtimeConfig != nil && m.runtimeConfig.IsUserNamespaceSupported() && !userNamespaceDefinedForPod(pod) { + // if HostUserNamespace is not specified explicitly in pod, behavior is runtime defined + if m.runtimeConfig.IsUserNamespaceEnabled() { + lc.SecurityContext.NamespaceOptions.User = runtimeapi.NamespaceMode_POD + } else { + lc.SecurityContext.NamespaceOptions.User = runtimeapi.NamespaceMode_NODE + } + } + if sc.FSGroup != nil { lc.SecurityContext.SupplementalGroups = append(lc.SecurityContext.SupplementalGroups, int64(*sc.FSGroup)) } diff --git a/pkg/kubelet/kuberuntime/security_context.go b/pkg/kubelet/kuberuntime/security_context.go index 47d524256da78..18cc2d1ad596f 100644 --- a/pkg/kubelet/kuberuntime/security_context.go +++ b/pkg/kubelet/kuberuntime/security_context.go @@ -52,6 +52,15 @@ func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Po // set namespace options and supplemental groups. synthesized.NamespaceOptions = namespacesForPod(pod) + if m.runtimeConfig != nil && m.runtimeConfig.IsUserNamespaceSupported() && !userNamespaceDefinedForPod(pod) { + // if HostUserNamespace is not specified explicitly in pod, behavior is runtime defined + if m.runtimeConfig.IsUserNamespaceEnabled() { + synthesized.NamespaceOptions.User = runtimeapi.NamespaceMode_POD + } else { + synthesized.NamespaceOptions.User = runtimeapi.NamespaceMode_NODE + } + } + podSc := pod.Spec.SecurityContext if podSc != nil { if podSc.FSGroup != nil { diff --git a/pkg/kubelet/remote/remote_runtime.go b/pkg/kubelet/remote/remote_runtime.go index cf09dad4c1210..e4a927a450f04 100644 --- a/pkg/kubelet/remote/remote_runtime.go +++ b/pkg/kubelet/remote/remote_runtime.go @@ -443,6 +443,20 @@ func (r *RemoteRuntimeService) UpdateRuntimeConfig(runtimeConfig *runtimeapi.Run return nil } +// GetRuntimeConfigInfo returns the configuration information from the runtime +func (r *RemoteRuntimeService) GetRuntimeConfigInfo() (*runtimeapi.ActiveRuntimeConfig, error) { + ctx, cancel := getContextWithTimeout(r.timeout) + defer cancel() + + resp, err := r.runtimeClient.GetRuntimeConfigInfo(ctx, &runtimeapi.GetRuntimeConfigInfoRequest{}) + if err != nil { + klog.Errorf("GetRuntimeConfigInfo failed: %s", err) + return nil, err + } + + return resp.RuntimeConfig, nil +} + // Status returns the status of the runtime. func (r *RemoteRuntimeService) Status() (*runtimeapi.RuntimeStatus, error) { ctx, cancel := getContextWithTimeout(r.timeout) diff --git a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.pb.go b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.pb.go index 2d3e1f7b046c4..69598a6315b7c 100644 --- a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.pb.go +++ b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.pb.go @@ -124,18 +124,28 @@ const ( // For example, a container with a PID namespace of NODE expects to view // all of the processes on the host running the kubelet. NamespaceMode_NODE NamespaceMode = 2 + // A NODE_WIDE_REMAPPED namespace applies to all pods on a given kubernetes node. + // The uid/gids of the pods/containers on a given node are mapped to a range of uids/gids + // from that Node's namespace. For e.g. starting with 200000 id on the nodes namespace, + // 10000 ids are allocated for a pod. This means uid/gid 0 inside the pod would map to 200000 id on the nodes namespace. + // For example, starting from uid/gid 0, 10000 uids/gids in this namespace are mapped to + // 10000 ids on node namespace,starting with id 200000. i.e uid/gid 0 in this namespace is + // mapped to uid/gid 200000 on node namespace. + NamespaceMode_NODE_WIDE_REMAPPED NamespaceMode = 3 ) var NamespaceMode_name = map[int32]string{ 0: "POD", 1: "CONTAINER", 2: "NODE", + 3: "NODE_WIDE_REMAPPED", } var NamespaceMode_value = map[string]int32{ - "POD": 0, - "CONTAINER": 1, - "NODE": 2, + "POD": 0, + "CONTAINER": 1, + "NODE": 2, + "NODE_WIDE_REMAPPED": 3, } func (x NamespaceMode) String() string { @@ -562,7 +572,13 @@ type NamespaceOption struct { // IPC namespace for this container/sandbox. // Note: There is currently no way to set CONTAINER scoped IPC in the Kubernetes API. // Namespaces currently set by the kubelet: POD, NODE - Ipc NamespaceMode `protobuf:"varint,3,opt,name=ipc,proto3,enum=runtime.v1alpha2.NamespaceMode" json:"ipc,omitempty"` + Ipc NamespaceMode `protobuf:"varint,3,opt,name=ipc,proto3,enum=runtime.v1alpha2.NamespaceMode" json:"ipc,omitempty"` + // User namespace for this container/sandbox. + // Note: There is currently no way to set CONTAINER scoped user namespace in the Kubernetes API. + // The container runtime should ignore this if user namespace is NOT enabled. + // NODE is the default value. Kubelet will set it to NODE_WIDE_REMAPPED if pod spec indicates to use user-namespace remapping + // Namespaces currently set by the kubelet: NODE, NODE_WIDE_REMAPPED + User NamespaceMode `protobuf:"varint,4,opt,name=user,proto3,enum=runtime.v1alpha2.NamespaceMode" json:"user,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_sizecache int32 `json:"-"` } @@ -620,6 +636,13 @@ func (m *NamespaceOption) GetIpc() NamespaceMode { return NamespaceMode_POD } +func (m *NamespaceOption) GetUser() NamespaceMode { + if m != nil { + return m.User + } + return NamespaceMode_POD +} + // Int64Value is the wrapper of int64. type Int64Value struct { // The value. @@ -5854,6 +5877,259 @@ func (m *StatusResponse) GetInfo() map[string]string { return nil } +// LinuxIDMapping represents a single user namespace mapping in Linux. +type LinuxIDMapping struct { + // container_id is the starting id for the mapping inside the container. + ContainerId uint32 `protobuf:"varint,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + // host_id is the starting id for the mapping on the host. + HostId uint32 `protobuf:"varint,2,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty"` + // size is the length of the mapping. + Size_ uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LinuxIDMapping) Reset() { *m = LinuxIDMapping{} } +func (*LinuxIDMapping) ProtoMessage() {} +func (*LinuxIDMapping) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{87} +} +func (m *LinuxIDMapping) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LinuxIDMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LinuxIDMapping.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 *LinuxIDMapping) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxIDMapping.Merge(m, src) +} +func (m *LinuxIDMapping) XXX_Size() int { + return m.Size() +} +func (m *LinuxIDMapping) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxIDMapping.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxIDMapping proto.InternalMessageInfo + +func (m *LinuxIDMapping) GetContainerId() uint32 { + if m != nil { + return m.ContainerId + } + return 0 +} + +func (m *LinuxIDMapping) GetHostId() uint32 { + if m != nil { + return m.HostId + } + return 0 +} + +func (m *LinuxIDMapping) GetSize_() uint32 { + if m != nil { + return m.Size_ + } + return 0 +} + +// LinuxUserNamespaceConfig represents runtime's user-namespace configuration on a linux host. +type LinuxUserNamespaceConfig struct { + // uid_mappings is an array of user id mappings. + UidMappings []*LinuxIDMapping `protobuf:"bytes,1,rep,name=uid_mappings,json=uidMappings,proto3" json:"uid_mappings,omitempty"` + // gid_mappings is an array of group id mappings. + GidMappings []*LinuxIDMapping `protobuf:"bytes,2,rep,name=gid_mappings,json=gidMappings,proto3" json:"gid_mappings,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LinuxUserNamespaceConfig) Reset() { *m = LinuxUserNamespaceConfig{} } +func (*LinuxUserNamespaceConfig) ProtoMessage() {} +func (*LinuxUserNamespaceConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{88} +} +func (m *LinuxUserNamespaceConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LinuxUserNamespaceConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LinuxUserNamespaceConfig.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 *LinuxUserNamespaceConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxUserNamespaceConfig.Merge(m, src) +} +func (m *LinuxUserNamespaceConfig) XXX_Size() int { + return m.Size() +} +func (m *LinuxUserNamespaceConfig) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxUserNamespaceConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxUserNamespaceConfig proto.InternalMessageInfo + +func (m *LinuxUserNamespaceConfig) GetUidMappings() []*LinuxIDMapping { + if m != nil { + return m.UidMappings + } + return nil +} + +func (m *LinuxUserNamespaceConfig) GetGidMappings() []*LinuxIDMapping { + if m != nil { + return m.GidMappings + } + return nil +} + +// ActiveRuntimeConfig contains the configuration details from the runtime. +type ActiveRuntimeConfig struct { + // LinuxUserNamespaceConfig represents runtime's user-namespace configuration on a linux host. + UserNamespaceConfig *LinuxUserNamespaceConfig `protobuf:"bytes,1,opt,name=user_namespace_config,json=userNamespaceConfig,proto3" json:"user_namespace_config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ActiveRuntimeConfig) Reset() { *m = ActiveRuntimeConfig{} } +func (*ActiveRuntimeConfig) ProtoMessage() {} +func (*ActiveRuntimeConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{89} +} +func (m *ActiveRuntimeConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ActiveRuntimeConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ActiveRuntimeConfig.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 *ActiveRuntimeConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_ActiveRuntimeConfig.Merge(m, src) +} +func (m *ActiveRuntimeConfig) XXX_Size() int { + return m.Size() +} +func (m *ActiveRuntimeConfig) XXX_DiscardUnknown() { + xxx_messageInfo_ActiveRuntimeConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_ActiveRuntimeConfig proto.InternalMessageInfo + +func (m *ActiveRuntimeConfig) GetUserNamespaceConfig() *LinuxUserNamespaceConfig { + if m != nil { + return m.UserNamespaceConfig + } + return nil +} + +// GetRuntimeConfigInfoRequest is the message sent for requesting runtime configuration details. +type GetRuntimeConfigInfoRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetRuntimeConfigInfoRequest) Reset() { *m = GetRuntimeConfigInfoRequest{} } +func (*GetRuntimeConfigInfoRequest) ProtoMessage() {} +func (*GetRuntimeConfigInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{90} +} +func (m *GetRuntimeConfigInfoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetRuntimeConfigInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetRuntimeConfigInfoRequest.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 *GetRuntimeConfigInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetRuntimeConfigInfoRequest.Merge(m, src) +} +func (m *GetRuntimeConfigInfoRequest) XXX_Size() int { + return m.Size() +} +func (m *GetRuntimeConfigInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetRuntimeConfigInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetRuntimeConfigInfoRequest proto.InternalMessageInfo + +// GetRuntimeConfigInfoResponse is the response message from runtime that includes configuration details +type GetRuntimeConfigInfoResponse struct { + // GetRuntimeConfig are the configuration details from the runtime. + RuntimeConfig *ActiveRuntimeConfig `protobuf:"bytes,1,opt,name=runtime_config,json=runtimeConfig,proto3" json:"runtime_config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetRuntimeConfigInfoResponse) Reset() { *m = GetRuntimeConfigInfoResponse{} } +func (*GetRuntimeConfigInfoResponse) ProtoMessage() {} +func (*GetRuntimeConfigInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{91} +} +func (m *GetRuntimeConfigInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetRuntimeConfigInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetRuntimeConfigInfoResponse.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 *GetRuntimeConfigInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetRuntimeConfigInfoResponse.Merge(m, src) +} +func (m *GetRuntimeConfigInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *GetRuntimeConfigInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetRuntimeConfigInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetRuntimeConfigInfoResponse proto.InternalMessageInfo + +func (m *GetRuntimeConfigInfoResponse) GetRuntimeConfig() *ActiveRuntimeConfig { + if m != nil { + return m.RuntimeConfig + } + return nil +} + type ImageFsInfoRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_sizecache int32 `json:"-"` @@ -5862,7 +6138,7 @@ type ImageFsInfoRequest struct { func (m *ImageFsInfoRequest) Reset() { *m = ImageFsInfoRequest{} } func (*ImageFsInfoRequest) ProtoMessage() {} func (*ImageFsInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{87} + return fileDescriptor_00212fb1f9d3bf1c, []int{92} } func (m *ImageFsInfoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5902,7 +6178,7 @@ type UInt64Value struct { func (m *UInt64Value) Reset() { *m = UInt64Value{} } func (*UInt64Value) ProtoMessage() {} func (*UInt64Value) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{88} + return fileDescriptor_00212fb1f9d3bf1c, []int{93} } func (m *UInt64Value) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5949,7 +6225,7 @@ type FilesystemIdentifier struct { func (m *FilesystemIdentifier) Reset() { *m = FilesystemIdentifier{} } func (*FilesystemIdentifier) ProtoMessage() {} func (*FilesystemIdentifier) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{89} + return fileDescriptor_00212fb1f9d3bf1c, []int{94} } func (m *FilesystemIdentifier) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6006,7 +6282,7 @@ type FilesystemUsage struct { func (m *FilesystemUsage) Reset() { *m = FilesystemUsage{} } func (*FilesystemUsage) ProtoMessage() {} func (*FilesystemUsage) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{90} + return fileDescriptor_00212fb1f9d3bf1c, []int{95} } func (m *FilesystemUsage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6073,7 +6349,7 @@ type ImageFsInfoResponse struct { func (m *ImageFsInfoResponse) Reset() { *m = ImageFsInfoResponse{} } func (*ImageFsInfoResponse) ProtoMessage() {} func (*ImageFsInfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{91} + return fileDescriptor_00212fb1f9d3bf1c, []int{96} } func (m *ImageFsInfoResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6119,7 +6395,7 @@ type ContainerStatsRequest struct { func (m *ContainerStatsRequest) Reset() { *m = ContainerStatsRequest{} } func (*ContainerStatsRequest) ProtoMessage() {} func (*ContainerStatsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{92} + return fileDescriptor_00212fb1f9d3bf1c, []int{97} } func (m *ContainerStatsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6165,7 +6441,7 @@ type ContainerStatsResponse struct { func (m *ContainerStatsResponse) Reset() { *m = ContainerStatsResponse{} } func (*ContainerStatsResponse) ProtoMessage() {} func (*ContainerStatsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{93} + return fileDescriptor_00212fb1f9d3bf1c, []int{98} } func (m *ContainerStatsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6211,7 +6487,7 @@ type ListContainerStatsRequest struct { func (m *ListContainerStatsRequest) Reset() { *m = ListContainerStatsRequest{} } func (*ListContainerStatsRequest) ProtoMessage() {} func (*ListContainerStatsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{94} + return fileDescriptor_00212fb1f9d3bf1c, []int{99} } func (m *ListContainerStatsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6265,7 +6541,7 @@ type ContainerStatsFilter struct { func (m *ContainerStatsFilter) Reset() { *m = ContainerStatsFilter{} } func (*ContainerStatsFilter) ProtoMessage() {} func (*ContainerStatsFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{95} + return fileDescriptor_00212fb1f9d3bf1c, []int{100} } func (m *ContainerStatsFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6325,7 +6601,7 @@ type ListContainerStatsResponse struct { func (m *ListContainerStatsResponse) Reset() { *m = ListContainerStatsResponse{} } func (*ListContainerStatsResponse) ProtoMessage() {} func (*ListContainerStatsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{96} + return fileDescriptor_00212fb1f9d3bf1c, []int{101} } func (m *ListContainerStatsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6381,7 +6657,7 @@ type ContainerAttributes struct { func (m *ContainerAttributes) Reset() { *m = ContainerAttributes{} } func (*ContainerAttributes) ProtoMessage() {} func (*ContainerAttributes) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{97} + return fileDescriptor_00212fb1f9d3bf1c, []int{102} } func (m *ContainerAttributes) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6455,7 +6731,7 @@ type ContainerStats struct { func (m *ContainerStats) Reset() { *m = ContainerStats{} } func (*ContainerStats) ProtoMessage() {} func (*ContainerStats) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{98} + return fileDescriptor_00212fb1f9d3bf1c, []int{103} } func (m *ContainerStats) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6525,7 +6801,7 @@ type CpuUsage struct { func (m *CpuUsage) Reset() { *m = CpuUsage{} } func (*CpuUsage) ProtoMessage() {} func (*CpuUsage) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{99} + return fileDescriptor_00212fb1f9d3bf1c, []int{104} } func (m *CpuUsage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6581,7 +6857,7 @@ type MemoryUsage struct { func (m *MemoryUsage) Reset() { *m = MemoryUsage{} } func (*MemoryUsage) ProtoMessage() {} func (*MemoryUsage) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{100} + return fileDescriptor_00212fb1f9d3bf1c, []int{105} } func (m *MemoryUsage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6634,7 +6910,7 @@ type ReopenContainerLogRequest struct { func (m *ReopenContainerLogRequest) Reset() { *m = ReopenContainerLogRequest{} } func (*ReopenContainerLogRequest) ProtoMessage() {} func (*ReopenContainerLogRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{101} + return fileDescriptor_00212fb1f9d3bf1c, []int{106} } func (m *ReopenContainerLogRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6678,7 +6954,7 @@ type ReopenContainerLogResponse struct { func (m *ReopenContainerLogResponse) Reset() { *m = ReopenContainerLogResponse{} } func (*ReopenContainerLogResponse) ProtoMessage() {} func (*ReopenContainerLogResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{102} + return fileDescriptor_00212fb1f9d3bf1c, []int{107} } func (m *ReopenContainerLogResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6819,6 +7095,11 @@ func init() { proto.RegisterType((*StatusRequest)(nil), "runtime.v1alpha2.StatusRequest") proto.RegisterType((*StatusResponse)(nil), "runtime.v1alpha2.StatusResponse") proto.RegisterMapType((map[string]string)(nil), "runtime.v1alpha2.StatusResponse.InfoEntry") + proto.RegisterType((*LinuxIDMapping)(nil), "runtime.v1alpha2.LinuxIDMapping") + proto.RegisterType((*LinuxUserNamespaceConfig)(nil), "runtime.v1alpha2.LinuxUserNamespaceConfig") + proto.RegisterType((*ActiveRuntimeConfig)(nil), "runtime.v1alpha2.ActiveRuntimeConfig") + proto.RegisterType((*GetRuntimeConfigInfoRequest)(nil), "runtime.v1alpha2.GetRuntimeConfigInfoRequest") + proto.RegisterType((*GetRuntimeConfigInfoResponse)(nil), "runtime.v1alpha2.GetRuntimeConfigInfoResponse") proto.RegisterType((*ImageFsInfoRequest)(nil), "runtime.v1alpha2.ImageFsInfoRequest") proto.RegisterType((*UInt64Value)(nil), "runtime.v1alpha2.UInt64Value") proto.RegisterType((*FilesystemIdentifier)(nil), "runtime.v1alpha2.FilesystemIdentifier") @@ -6843,306 +7124,318 @@ func init() { func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 4770 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5c, 0xcd, 0x6f, 0x1b, 0x49, - 0x76, 0x57, 0x93, 0xa2, 0x44, 0x3e, 0x8a, 0x14, 0x55, 0x96, 0x2d, 0x9a, 0x1e, 0x6b, 0xac, 0x9e, - 0xf1, 0xe7, 0xcc, 0xc8, 0x63, 0xcd, 0xac, 0x27, 0xb6, 0x67, 0x6d, 0xd3, 0x92, 0x6c, 0x33, 0x6b, - 0x53, 0x4c, 0x53, 0x9a, 0x8f, 0x9d, 0x01, 0x7a, 0x5b, 0xec, 0x12, 0xd5, 0x6b, 0xb2, 0xbb, 0xa7, - 0xbb, 0x69, 0x5b, 0x09, 0x10, 0x2c, 0xb0, 0xc8, 0x1e, 0x02, 0x04, 0xc8, 0x39, 0xc7, 0xcd, 0x21, - 0x87, 0xdc, 0x02, 0x04, 0x39, 0xe4, 0xb4, 0x41, 0x0e, 0x7b, 0x09, 0x90, 0xd3, 0x22, 0x41, 0x2e, - 0x99, 0x49, 0x72, 0x09, 0x90, 0x20, 0x7f, 0x40, 0x0e, 0x41, 0x7d, 0xf5, 0x77, 0xf3, 0xc3, 0xe3, - 0xdd, 0xd9, 0x9c, 0xd4, 0xf5, 0xfa, 0xbd, 0x57, 0xaf, 0x5f, 0xbd, 0x7a, 0xf5, 0xea, 0x57, 0x45, - 0x41, 0x49, 0xb3, 0x8d, 0x4d, 0xdb, 0xb1, 0x3c, 0x0b, 0xd5, 0x9c, 0x91, 0xe9, 0x19, 0x43, 0xbc, - 0xf9, 0xfc, 0x86, 0x36, 0xb0, 0x8f, 0xb5, 0xad, 0xc6, 0x7b, 0x7d, 0xc3, 0x3b, 0x1e, 0x1d, 0x6e, - 0xf6, 0xac, 0xe1, 0xf5, 0xbe, 0xd5, 0xb7, 0xae, 0x53, 0xc6, 0xc3, 0xd1, 0x11, 0x6d, 0xd1, 0x06, - 0x7d, 0x62, 0x0a, 0xe4, 0x6b, 0x50, 0xfd, 0x04, 0x3b, 0xae, 0x61, 0x99, 0x0a, 0xfe, 0x6a, 0x84, - 0x5d, 0x0f, 0xd5, 0x61, 0xf1, 0x39, 0xa3, 0xd4, 0xa5, 0x0b, 0xd2, 0x95, 0x92, 0x22, 0x9a, 0xf2, - 0x5f, 0x48, 0xb0, 0xec, 0x33, 0xbb, 0xb6, 0x65, 0xba, 0x38, 0x9b, 0x1b, 0x6d, 0xc0, 0x12, 0x37, - 0x4e, 0x35, 0xb5, 0x21, 0xae, 0xe7, 0xe8, 0xeb, 0x32, 0xa7, 0xb5, 0xb5, 0x21, 0x46, 0x97, 0x61, - 0x59, 0xb0, 0x08, 0x25, 0x79, 0xca, 0x55, 0xe5, 0x64, 0xde, 0x1b, 0xda, 0x84, 0x53, 0x82, 0x51, - 0xb3, 0x0d, 0x9f, 0x79, 0x9e, 0x32, 0xaf, 0xf0, 0x57, 0x4d, 0xdb, 0xe0, 0xfc, 0xf2, 0x17, 0x50, - 0xda, 0x69, 0x77, 0xb7, 0x2d, 0xf3, 0xc8, 0xe8, 0x13, 0x13, 0x5d, 0xec, 0x10, 0x99, 0xba, 0x74, - 0x21, 0x4f, 0x4c, 0xe4, 0x4d, 0xd4, 0x80, 0xa2, 0x8b, 0x35, 0xa7, 0x77, 0x8c, 0xdd, 0x7a, 0x8e, - 0xbe, 0xf2, 0xdb, 0x44, 0xca, 0xb2, 0x3d, 0xc3, 0x32, 0xdd, 0x7a, 0x9e, 0x49, 0xf1, 0xa6, 0xfc, - 0x73, 0x09, 0xca, 0x1d, 0xcb, 0xf1, 0x9e, 0x6a, 0xb6, 0x6d, 0x98, 0x7d, 0x74, 0x13, 0x8a, 0xd4, - 0x97, 0x3d, 0x6b, 0x40, 0x7d, 0x50, 0xdd, 0x6a, 0x6c, 0xc6, 0x87, 0x65, 0xb3, 0xc3, 0x39, 0x14, - 0x9f, 0x17, 0x5d, 0x84, 0x6a, 0xcf, 0x32, 0x3d, 0xcd, 0x30, 0xb1, 0xa3, 0xda, 0x96, 0xe3, 0x51, - 0x17, 0x15, 0x94, 0x8a, 0x4f, 0x25, 0xbd, 0xa0, 0x73, 0x50, 0x3a, 0xb6, 0x5c, 0x8f, 0x71, 0xe4, - 0x29, 0x47, 0x91, 0x10, 0xe8, 0xcb, 0x35, 0x58, 0xa4, 0x2f, 0x0d, 0x9b, 0x3b, 0x63, 0x81, 0x34, - 0x5b, 0xb6, 0xfc, 0x2b, 0x09, 0x0a, 0x4f, 0xad, 0x91, 0xe9, 0xc5, 0xba, 0xd1, 0xbc, 0x63, 0x3e, - 0x50, 0xa1, 0x6e, 0x34, 0xef, 0x38, 0xe8, 0x86, 0x70, 0xb0, 0xb1, 0x62, 0xdd, 0x90, 0x97, 0x0d, - 0x28, 0x3a, 0x58, 0xd3, 0x2d, 0x73, 0x70, 0x42, 0x4d, 0x28, 0x2a, 0x7e, 0x9b, 0x0c, 0xa2, 0x8b, - 0x07, 0x86, 0x39, 0x7a, 0xa9, 0x3a, 0x78, 0xa0, 0x1d, 0xe2, 0x01, 0x35, 0xa5, 0xa8, 0x54, 0x39, - 0x59, 0x61, 0x54, 0xb4, 0x03, 0x65, 0xdb, 0xb1, 0x6c, 0xad, 0xaf, 0x11, 0x3f, 0xd6, 0x0b, 0xd4, - 0x55, 0x72, 0xd2, 0x55, 0xd4, 0xec, 0x4e, 0xc0, 0xa9, 0x84, 0xc5, 0xe4, 0xbf, 0x92, 0x60, 0x99, - 0x04, 0x8f, 0x6b, 0x6b, 0x3d, 0xbc, 0x47, 0x87, 0x04, 0xdd, 0x82, 0x45, 0x13, 0x7b, 0x2f, 0x2c, - 0xe7, 0x19, 0x1f, 0x80, 0x37, 0x93, 0x5a, 0x7d, 0x99, 0xa7, 0x96, 0x8e, 0x15, 0xc1, 0x8f, 0x6e, - 0x40, 0xde, 0x36, 0x74, 0xfa, 0xc1, 0x53, 0x88, 0x11, 0x5e, 0x22, 0x62, 0xd8, 0x3d, 0xea, 0x87, - 0x69, 0x44, 0x0c, 0xbb, 0x27, 0xcb, 0x00, 0x2d, 0xd3, 0xbb, 0xf9, 0xe1, 0x27, 0xda, 0x60, 0x84, - 0xd1, 0x2a, 0x14, 0x9e, 0x93, 0x07, 0x6a, 0x6c, 0x5e, 0x61, 0x0d, 0xf9, 0xeb, 0x3c, 0x9c, 0x7b, - 0x42, 0xfc, 0xd5, 0xd5, 0x4c, 0xfd, 0xd0, 0x7a, 0xd9, 0xc5, 0xbd, 0x91, 0x63, 0x78, 0x27, 0xdb, - 0x96, 0xe9, 0xe1, 0x97, 0x1e, 0x6a, 0xc3, 0x8a, 0x29, 0x34, 0xab, 0x22, 0x34, 0x89, 0x86, 0xf2, - 0xd6, 0xc6, 0x18, 0x23, 0x98, 0x8b, 0x94, 0x9a, 0x19, 0x25, 0xb8, 0xe8, 0x71, 0x30, 0x6e, 0x42, - 0x5b, 0x8e, 0x6a, 0x4b, 0xf9, 0xa4, 0xee, 0x2e, 0xb5, 0x8c, 0xeb, 0x12, 0x03, 0x2b, 0x34, 0x7d, - 0x0c, 0x64, 0x56, 0xab, 0x9a, 0xab, 0x8e, 0x5c, 0xec, 0x50, 0xc7, 0x94, 0xb7, 0xde, 0x48, 0x6a, - 0x09, 0x5c, 0xa0, 0x94, 0x9c, 0x91, 0xd9, 0x74, 0x0f, 0x5c, 0xec, 0xa0, 0xbb, 0x34, 0x4f, 0x10, - 0xe9, 0xbe, 0x63, 0x8d, 0xec, 0x7a, 0x71, 0x0a, 0x71, 0xa0, 0xe2, 0x8f, 0x08, 0x3f, 0x4d, 0x22, - 0x3c, 0x16, 0x55, 0xc7, 0xb2, 0xbc, 0x23, 0x57, 0xc4, 0x9f, 0x20, 0x2b, 0x94, 0x8a, 0xae, 0xc3, - 0x29, 0x77, 0x64, 0xdb, 0x03, 0x3c, 0xc4, 0xa6, 0xa7, 0x0d, 0x58, 0x77, 0x6e, 0xbd, 0x70, 0x21, - 0x7f, 0x25, 0xaf, 0xa0, 0xf0, 0x2b, 0xaa, 0xd8, 0x45, 0xeb, 0x00, 0xb6, 0x63, 0x3c, 0x37, 0x06, - 0xb8, 0x8f, 0xf5, 0xfa, 0x02, 0x55, 0x1a, 0xa2, 0xa0, 0xf7, 0x61, 0xd5, 0xc5, 0xbd, 0x9e, 0x35, - 0xb4, 0x55, 0xdb, 0xb1, 0x8e, 0x8c, 0x01, 0x66, 0xb3, 0x67, 0x91, 0xce, 0x1e, 0xc4, 0xdf, 0x75, - 0xd8, 0x2b, 0x32, 0x8f, 0xe4, 0x9f, 0xe7, 0xe0, 0x34, 0xf5, 0x64, 0xc7, 0xd2, 0xf9, 0x30, 0xf3, - 0x24, 0xf5, 0x16, 0x54, 0x7a, 0xd4, 0x20, 0xd5, 0xd6, 0x1c, 0x6c, 0x7a, 0x7c, 0x92, 0x2e, 0x31, - 0x62, 0x87, 0xd2, 0xd0, 0x67, 0x50, 0x73, 0x79, 0x54, 0xa8, 0x3d, 0x16, 0x16, 0x7c, 0xcc, 0xde, - 0x4b, 0xba, 0x6b, 0x4c, 0x2c, 0x29, 0xcb, 0x6e, 0x22, 0xb8, 0x16, 0xdd, 0x13, 0xb7, 0xe7, 0x0d, - 0x58, 0xb6, 0x2b, 0x6f, 0x7d, 0x98, 0xa1, 0x30, 0x6e, 0xf8, 0x66, 0x97, 0x89, 0xed, 0x9a, 0x9e, - 0x73, 0xa2, 0x08, 0x25, 0x8d, 0xdb, 0xb0, 0x14, 0x7e, 0x81, 0x6a, 0x90, 0x7f, 0x86, 0x4f, 0xf8, - 0x47, 0x91, 0xc7, 0x60, 0x12, 0xb0, 0x5c, 0xc3, 0x1a, 0xb7, 0x73, 0xbf, 0x23, 0xc9, 0x0e, 0xa0, - 0xa0, 0x97, 0xa7, 0xd8, 0xd3, 0x74, 0xcd, 0xd3, 0x10, 0x82, 0x79, 0xba, 0x8c, 0x30, 0x15, 0xf4, - 0x99, 0x68, 0x1d, 0xf1, 0xc9, 0x5b, 0x52, 0xc8, 0x23, 0x7a, 0x03, 0x4a, 0x7e, 0xa0, 0xf3, 0xb5, - 0x24, 0x20, 0x90, 0x9c, 0xae, 0x79, 0x1e, 0x1e, 0xda, 0x1e, 0x0d, 0x91, 0x8a, 0x22, 0x9a, 0xf2, - 0x7f, 0xcf, 0x43, 0x2d, 0x31, 0x26, 0xf7, 0xa1, 0x38, 0xe4, 0xdd, 0xf3, 0x89, 0xf6, 0x76, 0x4a, - 0x62, 0x4f, 0x98, 0xaa, 0xf8, 0x52, 0x24, 0x6f, 0x92, 0x1c, 0x1a, 0x5a, 0xff, 0xfc, 0x36, 0x19, - 0xf1, 0x81, 0xd5, 0x57, 0x75, 0xc3, 0xc1, 0x3d, 0xcf, 0x72, 0x4e, 0xb8, 0xb9, 0x4b, 0x03, 0xab, - 0xbf, 0x23, 0x68, 0xe8, 0x36, 0x80, 0x6e, 0xba, 0x64, 0xb0, 0x8f, 0x8c, 0x3e, 0x35, 0xba, 0xbc, - 0x75, 0x2e, 0x69, 0x84, 0xbf, 0xd8, 0x29, 0x25, 0xdd, 0x74, 0xb9, 0xf9, 0x0f, 0xa0, 0x42, 0xd6, - 0x0c, 0x75, 0xc8, 0xd6, 0x29, 0x16, 0xe9, 0xe5, 0xad, 0xf3, 0x69, 0xdf, 0xe0, 0xaf, 0x66, 0xca, - 0x92, 0x1d, 0x34, 0x5c, 0xf4, 0x10, 0x16, 0x68, 0xf2, 0x76, 0xeb, 0x0b, 0x54, 0x78, 0x73, 0x9c, - 0x03, 0x78, 0x44, 0x3c, 0xa1, 0x02, 0x2c, 0x20, 0xb8, 0x34, 0x3a, 0x80, 0xb2, 0x66, 0x9a, 0x96, - 0xa7, 0xb1, 0x44, 0xb3, 0x48, 0x95, 0x7d, 0x30, 0x85, 0xb2, 0x66, 0x20, 0xc5, 0x34, 0x86, 0xf5, - 0xa0, 0xef, 0x43, 0x81, 0x66, 0x22, 0x9e, 0x34, 0x2e, 0x4f, 0x19, 0xb4, 0x0a, 0x93, 0x6a, 0xdc, - 0x82, 0x72, 0xc8, 0xd8, 0x59, 0x82, 0xb4, 0x71, 0x17, 0x6a, 0x71, 0xd3, 0x66, 0x0a, 0xf2, 0x3f, - 0x80, 0x55, 0x65, 0x64, 0x06, 0x86, 0x89, 0xea, 0xeb, 0x36, 0x2c, 0xf0, 0xc1, 0x66, 0x11, 0x27, - 0x4f, 0xf6, 0x91, 0xc2, 0x25, 0xc2, 0xe5, 0xd4, 0xb1, 0x66, 0xea, 0x03, 0xec, 0xf0, 0x7e, 0x45, - 0x39, 0xf5, 0x98, 0x51, 0xe5, 0xef, 0xc3, 0xe9, 0x58, 0xe7, 0xbc, 0x9a, 0x7b, 0x1b, 0xaa, 0xb6, - 0xa5, 0xab, 0x2e, 0x23, 0xab, 0x86, 0x2e, 0xd2, 0x90, 0xed, 0xf3, 0xb6, 0x74, 0x22, 0xde, 0xf5, - 0x2c, 0x3b, 0x69, 0xfc, 0x74, 0xe2, 0x75, 0x38, 0x13, 0x17, 0x67, 0xdd, 0xcb, 0xf7, 0x60, 0x4d, - 0xc1, 0x43, 0xeb, 0x39, 0x7e, 0x55, 0xd5, 0x0d, 0xa8, 0x27, 0x15, 0x70, 0xe5, 0x9f, 0xc3, 0x5a, - 0x40, 0xed, 0x7a, 0x9a, 0x37, 0x72, 0x67, 0x52, 0xce, 0x4b, 0xdd, 0x43, 0xcb, 0x65, 0xc3, 0x59, - 0x54, 0x44, 0x53, 0x5e, 0x83, 0x42, 0xc7, 0xd2, 0x5b, 0x1d, 0x54, 0x85, 0x9c, 0x61, 0x73, 0xe1, - 0x9c, 0x61, 0xcb, 0x46, 0xb8, 0xcf, 0x36, 0x2b, 0x39, 0x58, 0xd7, 0x71, 0x56, 0x74, 0x17, 0xaa, - 0x9a, 0xae, 0x1b, 0x24, 0x9c, 0xb4, 0x81, 0x6a, 0xd8, 0xac, 0x22, 0x2d, 0x6f, 0xad, 0xa5, 0x06, - 0x40, 0xab, 0xa3, 0x54, 0x02, 0xf6, 0x96, 0xed, 0xca, 0x8f, 0xa1, 0xe4, 0xaf, 0xf9, 0xe8, 0x4e, - 0x50, 0xbc, 0xe6, 0xa6, 0xad, 0x10, 0xfc, 0xfa, 0x76, 0x3f, 0xb1, 0x46, 0x71, 0x93, 0xef, 0x00, - 0xf8, 0xb9, 0x54, 0x94, 0x1e, 0xe7, 0xc6, 0x28, 0x56, 0x42, 0xec, 0xf2, 0x4f, 0x0b, 0xe1, 0x0c, - 0x1b, 0x72, 0x82, 0xee, 0x3b, 0x41, 0x8f, 0x64, 0xdc, 0xdc, 0x2b, 0x65, 0xdc, 0x8f, 0xa0, 0xe0, - 0x7a, 0x9a, 0x87, 0x79, 0x79, 0xb6, 0x31, 0x4e, 0x9c, 0x18, 0x81, 0x15, 0xc6, 0x8f, 0xce, 0x03, - 0xf4, 0x1c, 0xac, 0x79, 0x58, 0x57, 0x35, 0xb6, 0x3c, 0xe4, 0x95, 0x12, 0xa7, 0x34, 0x3d, 0xb4, - 0x1d, 0x94, 0x98, 0x05, 0x6a, 0xd8, 0xd5, 0x71, 0x9a, 0x23, 0x43, 0x1d, 0x14, 0x9b, 0x7e, 0xba, - 0x5a, 0x98, 0x32, 0x5d, 0x71, 0x05, 0x4c, 0x2a, 0x94, 0x8c, 0x17, 0x27, 0x27, 0x63, 0x26, 0x3a, - 0x4d, 0x32, 0x2e, 0x4e, 0x4e, 0xc6, 0x5c, 0xd9, 0xf8, 0x64, 0x9c, 0x92, 0x7e, 0x4a, 0x69, 0xe9, - 0xe7, 0xbb, 0x4c, 0xbb, 0xff, 0x2c, 0x41, 0x3d, 0x99, 0x05, 0x78, 0xf6, 0xbb, 0x0d, 0x0b, 0x2e, - 0xa5, 0x4c, 0x93, 0x7b, 0xb9, 0x2c, 0x97, 0x40, 0x8f, 0x61, 0xde, 0x30, 0x8f, 0x2c, 0x3e, 0x69, - 0x3f, 0x9c, 0x42, 0x92, 0xf7, 0xba, 0xd9, 0x32, 0x8f, 0x2c, 0xe6, 0x4d, 0xaa, 0xa1, 0xf1, 0x11, - 0x94, 0x7c, 0xd2, 0x4c, 0xdf, 0xb6, 0x07, 0xab, 0xb1, 0xd8, 0x66, 0xdb, 0x0d, 0x7f, 0x4a, 0x48, - 0xb3, 0x4d, 0x09, 0xf9, 0x27, 0xb9, 0xf0, 0x94, 0x7d, 0x68, 0x0c, 0x3c, 0xec, 0x24, 0xa6, 0xec, - 0xc7, 0x42, 0x3b, 0x9b, 0xaf, 0x97, 0x26, 0x6a, 0x67, 0x15, 0x3c, 0x9f, 0x75, 0x5f, 0x42, 0x95, - 0x06, 0xa5, 0xea, 0xe2, 0x01, 0x2d, 0x79, 0x78, 0xf9, 0xf9, 0xbd, 0x71, 0x6a, 0x98, 0x25, 0x2c, - 0xb4, 0xbb, 0x5c, 0x8e, 0x79, 0xb0, 0x32, 0x08, 0xd3, 0x1a, 0xf7, 0x01, 0x25, 0x99, 0x66, 0xf2, - 0x69, 0x97, 0xe4, 0x42, 0xb2, 0xd7, 0x4e, 0x59, 0xa7, 0x8f, 0xa8, 0x19, 0xd3, 0xc4, 0x0a, 0x33, - 0x58, 0xe1, 0x12, 0xf2, 0x7f, 0xe5, 0x01, 0x82, 0x97, 0xff, 0x8f, 0x92, 0xe0, 0x7d, 0x3f, 0x01, - 0xb1, 0x52, 0xf2, 0xca, 0x38, 0xc5, 0xa9, 0xa9, 0x67, 0x2f, 0x9a, 0x7a, 0x58, 0x51, 0xf9, 0xde, - 0x58, 0x35, 0x33, 0x27, 0x9d, 0xc5, 0xdf, 0xb6, 0xa4, 0xf3, 0x04, 0xce, 0xc4, 0x83, 0x88, 0x67, - 0x9c, 0x2d, 0x28, 0x18, 0x1e, 0x1e, 0x32, 0x60, 0x2a, 0x75, 0xd3, 0x1b, 0x12, 0x62, 0xac, 0xf2, - 0x06, 0x94, 0x5a, 0x43, 0xad, 0x8f, 0xbb, 0x36, 0xee, 0x91, 0x4e, 0x0d, 0xd2, 0xe0, 0x86, 0xb0, - 0x86, 0xbc, 0x05, 0xc5, 0x1f, 0xe0, 0x13, 0x36, 0xfb, 0xa7, 0x34, 0x54, 0xfe, 0x93, 0x1c, 0xac, - 0xd1, 0xd5, 0x67, 0x5b, 0xc0, 0x42, 0x0a, 0x76, 0xad, 0x91, 0xd3, 0xc3, 0x2e, 0x0d, 0x0b, 0x7b, - 0xa4, 0xda, 0xd8, 0x31, 0x2c, 0x9d, 0xa3, 0x16, 0xa5, 0x9e, 0x3d, 0xea, 0x50, 0x02, 0x3a, 0x07, - 0xa4, 0xa1, 0x7e, 0x35, 0xb2, 0x78, 0xc4, 0xe6, 0x95, 0x62, 0xcf, 0x1e, 0xfd, 0x1e, 0x69, 0x0b, - 0x59, 0xf7, 0x58, 0x73, 0xb0, 0x4b, 0x03, 0x92, 0xc9, 0x76, 0x29, 0x01, 0xdd, 0x80, 0xd3, 0x43, - 0x3c, 0xb4, 0x9c, 0x13, 0x75, 0x60, 0x0c, 0x0d, 0x4f, 0x35, 0x4c, 0xf5, 0xf0, 0xc4, 0xc3, 0x2e, - 0x0f, 0x3e, 0xc4, 0x5e, 0x3e, 0x21, 0xef, 0x5a, 0xe6, 0x03, 0xf2, 0x06, 0xc9, 0x50, 0xb1, 0xac, - 0xa1, 0xea, 0xf6, 0x2c, 0x07, 0xab, 0x9a, 0xfe, 0x63, 0xba, 0x20, 0xe7, 0x95, 0xb2, 0x65, 0x0d, - 0xbb, 0x84, 0xd6, 0xd4, 0x7f, 0x8c, 0xde, 0x84, 0x72, 0xcf, 0x1e, 0xb9, 0xd8, 0x53, 0xc9, 0x1f, - 0xba, 0xde, 0x96, 0x14, 0x60, 0xa4, 0x6d, 0x7b, 0xe4, 0x86, 0x18, 0x86, 0xc4, 0xff, 0x8b, 0x61, - 0x86, 0xa7, 0xc4, 0xcd, 0x1a, 0x54, 0x22, 0xa8, 0x07, 0xd9, 0x80, 0x52, 0x78, 0x83, 0x6f, 0x40, - 0xc9, 0x33, 0xa1, 0x39, 0xd6, 0x40, 0x78, 0x92, 0x3e, 0x13, 0x9a, 0x77, 0x62, 0x8b, 0xdd, 0x27, - 0x7d, 0x26, 0x2e, 0x1f, 0xe0, 0xe7, 0x1c, 0x19, 0x2b, 0x29, 0xac, 0x21, 0xeb, 0x00, 0xdb, 0x9a, - 0xad, 0x1d, 0x1a, 0x03, 0xc3, 0x3b, 0x41, 0x57, 0xa1, 0xa6, 0xe9, 0xba, 0xda, 0x13, 0x14, 0x03, - 0x0b, 0xbc, 0x72, 0x59, 0xd3, 0xf5, 0xed, 0x10, 0x19, 0xbd, 0x03, 0x2b, 0xba, 0x63, 0xd9, 0x51, - 0x5e, 0x06, 0x60, 0xd6, 0xc8, 0x8b, 0x30, 0xb3, 0xfc, 0xef, 0x05, 0x38, 0x1f, 0x1d, 0xd8, 0x38, - 0xb2, 0x74, 0x1f, 0x96, 0x62, 0xbd, 0x66, 0x20, 0x30, 0x81, 0xb5, 0x4a, 0x44, 0x22, 0x86, 0x94, - 0xe4, 0x12, 0x48, 0x49, 0x2a, 0x76, 0x95, 0x7f, 0xad, 0xd8, 0xd5, 0xfc, 0x6b, 0xc1, 0xae, 0x0a, - 0xdf, 0x0e, 0xbb, 0x5a, 0x9a, 0x11, 0xbb, 0xba, 0x44, 0xb3, 0x97, 0xe8, 0x9d, 0xc2, 0x04, 0x2c, - 0x54, 0x2b, 0x7e, 0x1f, 0xa6, 0x00, 0xca, 0x63, 0x18, 0xd7, 0xe2, 0x2c, 0x18, 0x57, 0x31, 0x13, - 0xe3, 0x22, 0x51, 0x67, 0xdb, 0x9a, 0x33, 0xb4, 0x1c, 0x01, 0x62, 0xf1, 0xaa, 0x6d, 0x59, 0xd0, - 0x39, 0x80, 0x95, 0x09, 0x77, 0x41, 0x16, 0xdc, 0x85, 0x2e, 0xc0, 0x92, 0x69, 0xa9, 0x26, 0x7e, - 0xa1, 0x92, 0x58, 0x70, 0xeb, 0x65, 0x16, 0x18, 0xa6, 0xd5, 0xc6, 0x2f, 0x3a, 0x84, 0x82, 0x36, - 0x60, 0x69, 0xa8, 0xb9, 0xcf, 0xb0, 0x4e, 0x55, 0xb9, 0xf5, 0x0a, 0x0d, 0xe2, 0x32, 0xa3, 0x11, - 0x1d, 0x2e, 0xba, 0x08, 0xfe, 0x47, 0x72, 0xa6, 0x2a, 0x65, 0xaa, 0x08, 0x2a, 0x65, 0x93, 0xff, - 0x56, 0x82, 0xd5, 0x68, 0x98, 0x73, 0x18, 0xe4, 0x11, 0x94, 0x1c, 0x91, 0xc9, 0x78, 0x68, 0x5f, - 0xcd, 0x28, 0xbc, 0x93, 0xa9, 0x4f, 0x09, 0x64, 0xd1, 0x0f, 0x33, 0xd1, 0xb7, 0xeb, 0x93, 0xf4, - 0x4d, 0xc2, 0xdf, 0x64, 0x07, 0xde, 0xfc, 0xd4, 0x30, 0x75, 0xeb, 0x85, 0x9b, 0x39, 0x4b, 0x53, - 0x62, 0x45, 0xca, 0x88, 0x95, 0x9e, 0x83, 0x75, 0x6c, 0x7a, 0x86, 0x36, 0x50, 0x5d, 0x1b, 0xf7, - 0x04, 0x0a, 0x10, 0x90, 0xc9, 0xda, 0x21, 0xff, 0x42, 0x82, 0x33, 0xf1, 0x4e, 0xb9, 0xcf, 0x5a, - 0x49, 0x9f, 0xbd, 0x93, 0xfc, 0xc6, 0xb8, 0x70, 0xaa, 0xd7, 0xbe, 0xcc, 0xf4, 0xda, 0x8d, 0xc9, - 0x1a, 0x27, 0xfa, 0xed, 0x2f, 0x25, 0x38, 0x9b, 0x69, 0x46, 0x6c, 0xed, 0x91, 0xe2, 0x6b, 0x0f, - 0x5f, 0xb7, 0x7a, 0xd6, 0xc8, 0xf4, 0x42, 0xeb, 0xd6, 0x36, 0x3d, 0x36, 0x61, 0x0b, 0x84, 0x3a, - 0xd4, 0x5e, 0x1a, 0xc3, 0xd1, 0x90, 0x2f, 0x5c, 0x44, 0xdd, 0x53, 0x46, 0x79, 0x85, 0x95, 0x4b, - 0x6e, 0xc2, 0x8a, 0x6f, 0xe5, 0x58, 0x60, 0x33, 0x04, 0x54, 0xe6, 0xa2, 0x40, 0xa5, 0x09, 0x0b, - 0x3b, 0xf8, 0xb9, 0xd1, 0xc3, 0xaf, 0xe5, 0x5c, 0xe7, 0x02, 0x94, 0x6d, 0xec, 0x0c, 0x0d, 0xd7, - 0xf5, 0x33, 0x72, 0x49, 0x09, 0x93, 0xe4, 0xff, 0x58, 0x80, 0xe5, 0x78, 0x74, 0xdc, 0x4b, 0xe0, - 0xa2, 0x6f, 0xa5, 0xac, 0x15, 0xf1, 0x0f, 0x0d, 0xd5, 0xa7, 0x37, 0x44, 0xd5, 0x92, 0xcb, 0xc2, - 0x10, 0xfc, 0x0a, 0x87, 0x97, 0x34, 0xc4, 0x23, 0x3d, 0x6b, 0x38, 0xd4, 0x4c, 0x5d, 0x1c, 0xc7, - 0xf1, 0x26, 0xf1, 0x9f, 0xe6, 0xf4, 0x89, 0xdb, 0x09, 0x99, 0x3e, 0x93, 0xc1, 0x23, 0x1b, 0x6e, - 0xc3, 0xa4, 0xf8, 0x2a, 0xcd, 0xea, 0x25, 0x05, 0x38, 0x69, 0xc7, 0x70, 0xd0, 0x26, 0xcc, 0x63, - 0xf3, 0xb9, 0x28, 0x40, 0x53, 0xce, 0xeb, 0x44, 0xfd, 0xa4, 0x50, 0x3e, 0x74, 0x1d, 0x16, 0x86, - 0x24, 0x2c, 0xc4, 0xd6, 0x7b, 0x2d, 0xe3, 0xd8, 0x4a, 0xe1, 0x6c, 0x68, 0x0b, 0x16, 0x75, 0x3a, - 0x4e, 0x62, 0x7f, 0x5d, 0x4f, 0x41, 0x6d, 0x29, 0x83, 0x22, 0x18, 0xd1, 0xae, 0x5f, 0x5e, 0x97, - 0xb2, 0xea, 0xe2, 0xd8, 0x50, 0xa4, 0xd6, 0xd8, 0xfb, 0xd1, 0x1a, 0x1b, 0xa8, 0xae, 0xad, 0xc9, - 0xba, 0xc6, 0x17, 0xda, 0x67, 0xa1, 0x38, 0xb0, 0xfa, 0x2c, 0x8c, 0xca, 0xec, 0xa4, 0x77, 0x60, - 0xf5, 0x69, 0x14, 0xad, 0x92, 0xed, 0x86, 0x6e, 0x98, 0x74, 0xf9, 0x2b, 0x2a, 0xac, 0x41, 0x26, - 0x1f, 0x7d, 0x50, 0x2d, 0xb3, 0x87, 0xeb, 0x15, 0xfa, 0xaa, 0x44, 0x29, 0x7b, 0x66, 0x8f, 0xd6, - 0xa5, 0x9e, 0x77, 0x52, 0xaf, 0x52, 0x3a, 0x79, 0x24, 0x3b, 0x49, 0x86, 0x8e, 0x2c, 0x67, 0xed, - 0x24, 0xd3, 0xf2, 0xbb, 0x00, 0x47, 0x1e, 0xc0, 0xe2, 0x0b, 0x96, 0x08, 0xea, 0x35, 0x2a, 0x7f, - 0x65, 0x72, 0x7a, 0xe1, 0x1a, 0x84, 0xe0, 0x77, 0xb9, 0x47, 0xf8, 0x7b, 0x09, 0xce, 0x6c, 0xd3, - 0x8d, 0x56, 0x28, 0x8f, 0xcd, 0x82, 0x4e, 0xde, 0xf2, 0x81, 0xe3, 0x4c, 0xc4, 0x2f, 0xfe, 0xdd, - 0x02, 0x37, 0x6e, 0x41, 0x55, 0x28, 0xe7, 0x2a, 0xf2, 0x53, 0x63, 0xcf, 0x15, 0x37, 0xdc, 0x94, - 0x3f, 0x86, 0xb5, 0xc4, 0x57, 0xf0, 0xbd, 0xce, 0x06, 0x2c, 0x05, 0xf9, 0xca, 0xff, 0x88, 0xb2, - 0x4f, 0x6b, 0xe9, 0xf2, 0x6d, 0x38, 0xdd, 0xf5, 0x34, 0xc7, 0x4b, 0xb8, 0x60, 0x0a, 0x59, 0x8a, - 0x2a, 0x47, 0x65, 0x39, 0xf0, 0xdb, 0x85, 0xd5, 0xae, 0x67, 0xd9, 0xaf, 0xa0, 0x94, 0x64, 0x1d, - 0xf2, 0xfd, 0xd6, 0x48, 0xac, 0x0f, 0xa2, 0x29, 0xaf, 0x31, 0x0c, 0x3c, 0xd9, 0xdb, 0x1d, 0x38, - 0xc3, 0x20, 0xe8, 0x57, 0xf9, 0x88, 0xb3, 0x02, 0x00, 0x4f, 0xea, 0x7d, 0x0a, 0xa7, 0x82, 0x65, - 0x31, 0x00, 0x77, 0x6e, 0x46, 0xc1, 0x9d, 0x0b, 0x63, 0x46, 0x3d, 0x82, 0xed, 0xfc, 0x79, 0x2e, - 0x94, 0xd7, 0x33, 0xa0, 0x9d, 0x3b, 0x51, 0x68, 0xe7, 0xe2, 0x24, 0xdd, 0x11, 0x64, 0x27, 0x19, - 0xb5, 0xf9, 0x94, 0xa8, 0xfd, 0x22, 0x81, 0xff, 0xcc, 0x67, 0x01, 0x68, 0x31, 0x6b, 0x7f, 0x23, - 0xf0, 0x8f, 0xc2, 0xe0, 0x1f, 0xbf, 0x6b, 0xff, 0xc4, 0xe0, 0x56, 0x0c, 0xfe, 0xd9, 0x98, 0x68, - 0xaf, 0x8f, 0xfe, 0xfc, 0xf5, 0x3c, 0x94, 0xfc, 0x77, 0x09, 0x9f, 0x27, 0xdd, 0x96, 0x4b, 0x71, - 0x5b, 0x78, 0x05, 0xce, 0x7f, 0xab, 0x15, 0x78, 0x7e, 0xea, 0x15, 0xf8, 0x1c, 0x94, 0xe8, 0x83, - 0xea, 0xe0, 0x23, 0xbe, 0xa2, 0x16, 0x29, 0x41, 0xc1, 0x47, 0x41, 0x18, 0x2e, 0xcc, 0x14, 0x86, - 0x31, 0xc0, 0x69, 0x31, 0x0e, 0x38, 0xdd, 0xf3, 0x57, 0x44, 0xb6, 0x88, 0x5e, 0x1e, 0xa3, 0x37, - 0x75, 0x2d, 0x6c, 0x47, 0xd7, 0x42, 0xb6, 0xae, 0xbe, 0x3b, 0x4e, 0xcb, 0xd8, 0x55, 0xf0, 0xbb, - 0x5c, 0x21, 0x0e, 0x18, 0x8a, 0x14, 0x8e, 0x45, 0x9e, 0x59, 0xef, 0x00, 0xf8, 0x49, 0x44, 0x40, - 0x49, 0xe7, 0xc6, 0x7c, 0xa3, 0x12, 0x62, 0x27, 0x6a, 0x23, 0x43, 0x13, 0x9c, 0x8a, 0x4d, 0x97, - 0x1f, 0x33, 0x8e, 0xc4, 0xfe, 0xb7, 0x10, 0xca, 0x2f, 0x19, 0xa7, 0x3d, 0xf7, 0x12, 0x40, 0xe7, - 0x8c, 0x51, 0x7c, 0x33, 0x8a, 0x73, 0xbe, 0x62, 0xd4, 0x25, 0x60, 0x4e, 0x5a, 0xb9, 0x68, 0x0e, - 0x7f, 0xcd, 0xd0, 0xa5, 0x12, 0xa7, 0x34, 0xe9, 0xce, 0xe0, 0xc8, 0x30, 0x0d, 0xf7, 0x98, 0xbd, - 0x5f, 0x60, 0x3b, 0x03, 0x41, 0x6a, 0xd2, 0x1b, 0x5b, 0xf8, 0xa5, 0xe1, 0xa9, 0x3d, 0x4b, 0xc7, - 0x34, 0xa6, 0x0b, 0x4a, 0x91, 0x10, 0xb6, 0x2d, 0x1d, 0x07, 0x33, 0xaf, 0xf8, 0x6a, 0x33, 0xaf, - 0x14, 0x9b, 0x79, 0x67, 0x60, 0xc1, 0xc1, 0x9a, 0x6b, 0x99, 0x7c, 0x1f, 0xce, 0x5b, 0x64, 0x68, - 0x86, 0xd8, 0x75, 0x49, 0x4f, 0xbc, 0x5c, 0xe3, 0xcd, 0x50, 0x99, 0xb9, 0x34, 0xb1, 0xcc, 0x1c, - 0x73, 0x8a, 0x14, 0x2b, 0x33, 0x2b, 0x13, 0xcb, 0xcc, 0xa9, 0x0e, 0x91, 0x82, 0x42, 0xbb, 0x3a, - 0x5d, 0xa1, 0x1d, 0xae, 0x4b, 0x97, 0x23, 0x75, 0xe9, 0x77, 0x39, 0x59, 0x7f, 0x25, 0xc1, 0x5a, - 0x62, 0x5a, 0xf1, 0xe9, 0x7a, 0x2b, 0x76, 0xcc, 0xb4, 0x31, 0xd1, 0x67, 0xfe, 0x29, 0xd3, 0xa3, - 0xc8, 0x29, 0xd3, 0x07, 0x93, 0x05, 0x5f, 0xfb, 0x21, 0xd3, 0x1f, 0x49, 0xf0, 0xe6, 0x81, 0xad, - 0xc7, 0x2a, 0x3c, 0xbe, 0xed, 0x9f, 0x3e, 0x71, 0xdc, 0x13, 0xb5, 0x7e, 0x6e, 0x56, 0x40, 0x86, - 0xc9, 0xc9, 0x32, 0x5c, 0xc8, 0x36, 0x83, 0x97, 0x4c, 0x3f, 0x82, 0xe5, 0xdd, 0x97, 0xb8, 0xd7, - 0x3d, 0x31, 0x7b, 0x33, 0x98, 0x56, 0x83, 0x7c, 0x6f, 0xa8, 0x73, 0x38, 0x95, 0x3c, 0x86, 0xab, - 0xc0, 0x7c, 0xb4, 0x0a, 0x54, 0xa1, 0x16, 0xf4, 0xc0, 0x87, 0xf7, 0x0c, 0x19, 0x5e, 0x9d, 0x30, - 0x13, 0xe5, 0x4b, 0x0a, 0x6f, 0x71, 0x3a, 0x76, 0xd8, 0xa5, 0x0c, 0x46, 0xc7, 0x8e, 0x13, 0xcd, - 0x16, 0xf9, 0x68, 0xb6, 0x90, 0xff, 0x4c, 0x82, 0x32, 0xe9, 0xe1, 0x5b, 0xd9, 0xcf, 0xb7, 0x5a, - 0xf9, 0x60, 0xab, 0xe5, 0xef, 0xd8, 0xe6, 0xc3, 0x3b, 0xb6, 0xc0, 0xf2, 0x02, 0x25, 0x27, 0x2d, - 0x5f, 0xf0, 0xe9, 0xd8, 0x71, 0xe4, 0x0b, 0xb0, 0xc4, 0x6c, 0xe3, 0x5f, 0x5e, 0x83, 0xfc, 0xc8, - 0x19, 0x88, 0x38, 0x1a, 0x39, 0x03, 0xf9, 0x8f, 0x25, 0xa8, 0x34, 0x3d, 0x4f, 0xeb, 0x1d, 0xcf, - 0xf0, 0x01, 0xbe, 0x71, 0xb9, 0xb0, 0x71, 0xc9, 0x8f, 0x08, 0xcc, 0x9d, 0xcf, 0x30, 0xb7, 0x10, - 0x31, 0x57, 0x86, 0xaa, 0xb0, 0x25, 0xd3, 0xe0, 0x36, 0xa0, 0x8e, 0xe5, 0x78, 0x0f, 0x2d, 0xe7, - 0x85, 0xe6, 0xe8, 0xb3, 0xed, 0xc0, 0x10, 0xcc, 0xf3, 0x5b, 0xbc, 0xf9, 0x2b, 0x05, 0x85, 0x3e, - 0xcb, 0x97, 0xe1, 0x54, 0x44, 0x5f, 0x66, 0xc7, 0xf7, 0xa1, 0x4c, 0xf3, 0x3e, 0x2f, 0xc5, 0x6f, - 0x84, 0xcf, 0x75, 0xa6, 0x5a, 0x25, 0xe4, 0xdf, 0x85, 0x15, 0x52, 0x1f, 0x50, 0xba, 0x3f, 0x15, - 0xbf, 0x17, 0xab, 0x53, 0xcf, 0x67, 0x28, 0x8a, 0xd5, 0xa8, 0x7f, 0x23, 0x41, 0x81, 0xd2, 0x13, - 0x6b, 0xf6, 0x39, 0x28, 0x39, 0xd8, 0xb6, 0x54, 0x4f, 0xeb, 0xfb, 0x77, 0xa6, 0x09, 0x61, 0x5f, - 0xeb, 0x53, 0x34, 0x97, 0xbe, 0xd4, 0x8d, 0x3e, 0x76, 0x3d, 0x71, 0x71, 0xba, 0x4c, 0x68, 0x3b, - 0x8c, 0x44, 0x9c, 0xe4, 0x1a, 0xbf, 0xcf, 0xea, 0xce, 0x79, 0x85, 0x3e, 0xa3, 0x4d, 0x76, 0x8d, - 0x6f, 0x1a, 0xec, 0x9d, 0x5e, 0xf2, 0x6b, 0x40, 0x31, 0x06, 0x97, 0xfb, 0x6d, 0x79, 0x17, 0x50, - 0xd8, 0x0b, 0xdc, 0xdf, 0xd7, 0x61, 0x81, 0x3a, 0x49, 0x54, 0x47, 0x6b, 0x19, 0x6e, 0x50, 0x38, - 0x9b, 0xac, 0x01, 0x62, 0x0e, 0x8e, 0x54, 0x44, 0xb3, 0x8f, 0xca, 0x98, 0x0a, 0xe9, 0xef, 0x24, - 0x38, 0x15, 0xe9, 0x83, 0xdb, 0xfa, 0x5e, 0xb4, 0x93, 0x4c, 0x53, 0x79, 0x07, 0xdb, 0x91, 0x25, - 0xe1, 0x7a, 0x96, 0x49, 0xbf, 0xa6, 0xe5, 0xe0, 0x1f, 0x24, 0x80, 0xe6, 0xc8, 0x3b, 0xe6, 0xc8, - 0x60, 0x78, 0x64, 0xa4, 0xe8, 0xc8, 0x90, 0x77, 0xb6, 0xe6, 0xba, 0x2f, 0x2c, 0x47, 0xec, 0x69, - 0xfc, 0x36, 0xc5, 0xf0, 0x46, 0xde, 0xb1, 0x38, 0x33, 0x23, 0xcf, 0xe8, 0x22, 0x54, 0xd9, 0x3d, - 0x7d, 0x55, 0xd3, 0x75, 0x07, 0xbb, 0x2e, 0x3f, 0x3c, 0xab, 0x30, 0x6a, 0x93, 0x11, 0x09, 0x9b, - 0x41, 0x51, 0x6d, 0xef, 0x44, 0xf5, 0xac, 0x67, 0xd8, 0xe4, 0x7b, 0x93, 0x8a, 0xa0, 0xee, 0x13, - 0x22, 0x3b, 0x45, 0xe8, 0x1b, 0xae, 0xe7, 0x08, 0x36, 0x71, 0xd0, 0xc2, 0xa9, 0x94, 0x8d, 0x0c, - 0x4a, 0xad, 0x33, 0x1a, 0x0c, 0x98, 0x8b, 0x5f, 0x7d, 0xd8, 0xdf, 0xe7, 0x1f, 0x94, 0xcb, 0x8a, - 0xe9, 0xc0, 0x69, 0xfc, 0x73, 0x5f, 0x23, 0x08, 0xf3, 0x3e, 0xac, 0x84, 0xbe, 0x81, 0x87, 0x55, - 0xa4, 0x88, 0x94, 0xa2, 0x45, 0xa4, 0xfc, 0x08, 0x10, 0xc3, 0x1d, 0xbe, 0xe5, 0x77, 0xcb, 0xa7, - 0xe1, 0x54, 0x44, 0x11, 0x5f, 0x89, 0xaf, 0x41, 0x85, 0x5f, 0x89, 0xe2, 0x81, 0x72, 0x16, 0x8a, - 0x24, 0xa3, 0xf6, 0x0c, 0x5d, 0x1c, 0xa8, 0x2e, 0xda, 0x96, 0xbe, 0x6d, 0xe8, 0x8e, 0xfc, 0x29, - 0x54, 0x14, 0xd6, 0x0f, 0xe7, 0x7d, 0x08, 0x55, 0x7e, 0x81, 0x4a, 0x8d, 0x5c, 0x8d, 0x4c, 0xbb, - 0x7a, 0x1f, 0xee, 0x44, 0xa9, 0x98, 0xe1, 0xa6, 0xac, 0x43, 0x83, 0x95, 0x0c, 0x11, 0xf5, 0xe2, - 0x63, 0x1f, 0x82, 0xb8, 0x31, 0x30, 0xb1, 0x97, 0xa8, 0x7c, 0xc5, 0x09, 0x37, 0xe5, 0xf3, 0x70, - 0x2e, 0xb5, 0x17, 0xee, 0x09, 0x1b, 0x6a, 0xc1, 0x0b, 0x76, 0x7f, 0xcf, 0x3f, 0x31, 0x96, 0x42, - 0x27, 0xc6, 0x67, 0xfc, 0x22, 0x31, 0x27, 0x16, 0x31, 0x5a, 0x01, 0x06, 0xe5, 0x7e, 0x3e, 0xab, - 0xdc, 0x9f, 0x8f, 0x94, 0xfb, 0x72, 0xd7, 0xf7, 0x27, 0xdf, 0x86, 0x3d, 0xa0, 0xdb, 0x45, 0xd6, - 0xb7, 0x48, 0x88, 0xf2, 0xb8, 0xaf, 0x64, 0xac, 0x4a, 0x48, 0x4a, 0xbe, 0x0a, 0x95, 0x68, 0x6a, - 0x0c, 0xe5, 0x39, 0x29, 0x91, 0xe7, 0xaa, 0xb1, 0x14, 0xf7, 0x51, 0xac, 0x02, 0xce, 0xf6, 0x71, - 0xac, 0xfe, 0xbd, 0x1b, 0x49, 0x76, 0xd7, 0x52, 0x0e, 0x7b, 0x7f, 0x4d, 0x79, 0x6e, 0x95, 0xaf, - 0x07, 0x0f, 0x5d, 0x22, 0xcf, 0x3f, 0x5a, 0x7e, 0x0b, 0xca, 0x07, 0x59, 0xbf, 0xeb, 0x98, 0x17, - 0x17, 0x2b, 0x6e, 0xc2, 0xea, 0x43, 0x63, 0x80, 0xdd, 0x13, 0xd7, 0xc3, 0xc3, 0x16, 0x4d, 0x4a, - 0x47, 0x06, 0x76, 0xd0, 0x3a, 0x00, 0xdd, 0xc2, 0xd8, 0x96, 0xe1, 0x5f, 0xf7, 0x0f, 0x51, 0xe4, - 0xff, 0x94, 0x60, 0x39, 0x10, 0x3c, 0xa0, 0x5b, 0xb7, 0x37, 0xa0, 0x44, 0xbe, 0xd7, 0xf5, 0xb4, - 0xa1, 0x2d, 0xce, 0xb3, 0x7c, 0x02, 0xba, 0x03, 0x85, 0x23, 0x57, 0x40, 0x46, 0xa9, 0x00, 0x7a, - 0x9a, 0x21, 0xca, 0xfc, 0x91, 0xdb, 0xd2, 0xd1, 0xc7, 0x00, 0x23, 0x17, 0xeb, 0xfc, 0x0c, 0x2b, - 0x9f, 0x55, 0x2d, 0x1c, 0x84, 0x0f, 0xc2, 0x89, 0x00, 0xbb, 0x93, 0x71, 0x17, 0xca, 0x86, 0x69, - 0xe9, 0x98, 0x1e, 0x4e, 0xea, 0x1c, 0x55, 0x9a, 0x20, 0x0e, 0x4c, 0xe2, 0xc0, 0xc5, 0xba, 0x8c, - 0xf9, 0x5a, 0x28, 0xfc, 0xcb, 0x03, 0xa5, 0x0d, 0x2b, 0x2c, 0x69, 0x1d, 0xf9, 0x86, 0x8b, 0x88, - 0xdd, 0x18, 0xf7, 0x75, 0xd4, 0x5b, 0x4a, 0xcd, 0xe0, 0xa5, 0x8d, 0x10, 0x95, 0x6f, 0xc3, 0xe9, - 0xc8, 0x0e, 0x69, 0x86, 0x2d, 0x8b, 0xdc, 0x89, 0x01, 0x25, 0x41, 0x38, 0x73, 0x18, 0x42, 0x44, - 0xf3, 0x24, 0x18, 0xc2, 0x65, 0x30, 0x84, 0x2b, 0x7f, 0x01, 0x67, 0x23, 0x88, 0x4e, 0xc4, 0xa2, - 0xbb, 0xb1, 0xca, 0xed, 0xd2, 0x24, 0xad, 0xb1, 0x12, 0xee, 0x7f, 0x24, 0x58, 0x4d, 0x63, 0x78, - 0x45, 0xc4, 0xf1, 0x47, 0x19, 0x17, 0xf5, 0x6e, 0x4d, 0x67, 0xd6, 0x6f, 0x04, 0xad, 0xdd, 0x87, - 0x46, 0x9a, 0x3f, 0x93, 0xa3, 0x94, 0x9f, 0x65, 0x94, 0x7e, 0x96, 0x0f, 0x21, 0xef, 0x4d, 0xcf, - 0x73, 0x8c, 0xc3, 0x11, 0x09, 0xf9, 0xd7, 0x8e, 0x66, 0xb5, 0x7c, 0x5c, 0x86, 0xb9, 0xf6, 0xc6, - 0x18, 0xf1, 0xc0, 0x8e, 0x54, 0x6c, 0xe6, 0xb3, 0x28, 0x36, 0xc3, 0x30, 0xf5, 0x9b, 0xd3, 0xe9, - 0xfb, 0xad, 0x05, 0x40, 0x7f, 0x96, 0x83, 0x6a, 0x74, 0x88, 0xd0, 0x2e, 0x80, 0xe6, 0x5b, 0xce, - 0x27, 0xca, 0xc5, 0xa9, 0x3e, 0x53, 0x09, 0x09, 0xa2, 0x77, 0x21, 0xdf, 0xb3, 0x47, 0x7c, 0xd4, - 0x52, 0x0e, 0x83, 0xb7, 0xed, 0x11, 0xcb, 0x28, 0x84, 0x8d, 0xec, 0xa9, 0xd8, 0xd9, 0x7e, 0x76, - 0x96, 0x7c, 0x4a, 0xdf, 0x33, 0x19, 0xce, 0x8c, 0x1e, 0x43, 0xf5, 0x85, 0x63, 0x78, 0xda, 0xe1, - 0x00, 0xab, 0x03, 0xed, 0x04, 0x3b, 0x3c, 0x4b, 0x4e, 0x91, 0xc8, 0x2a, 0x42, 0xf0, 0x09, 0x91, - 0x93, 0xff, 0x10, 0x8a, 0xc2, 0xa2, 0x09, 0x2b, 0xc2, 0x3e, 0xac, 0x8d, 0x08, 0x9b, 0x4a, 0xef, - 0xca, 0x99, 0x9a, 0x69, 0xa9, 0x2e, 0x26, 0xcb, 0xb8, 0xf8, 0x5d, 0xc0, 0x84, 0x14, 0xbd, 0x4a, - 0xa5, 0xb7, 0x2d, 0x07, 0xb7, 0x35, 0xd3, 0xea, 0x32, 0x51, 0xf9, 0x39, 0x94, 0x43, 0x1f, 0x38, - 0xc1, 0x84, 0x16, 0xac, 0x88, 0xa3, 0x78, 0x17, 0x7b, 0x7c, 0x79, 0x99, 0xaa, 0xf3, 0x65, 0x2e, - 0xd7, 0xc5, 0x1e, 0xbb, 0x3e, 0x71, 0x17, 0xce, 0x2a, 0xd8, 0xb2, 0xb1, 0xe9, 0x8f, 0xe7, 0x13, - 0xab, 0x3f, 0x43, 0x06, 0x7f, 0x03, 0x1a, 0x69, 0xf2, 0x2c, 0x3f, 0x5c, 0xbb, 0x04, 0x45, 0xf1, - 0x23, 0x5d, 0xb4, 0x08, 0xf9, 0xfd, 0xed, 0x4e, 0x6d, 0x8e, 0x3c, 0x1c, 0xec, 0x74, 0x6a, 0x12, - 0x2a, 0xc2, 0x7c, 0x77, 0x7b, 0xbf, 0x53, 0xcb, 0x5d, 0x1b, 0x42, 0x2d, 0xfe, 0x0b, 0x55, 0xb4, - 0x06, 0xa7, 0x3a, 0xca, 0x5e, 0xa7, 0xf9, 0xa8, 0xb9, 0xdf, 0xda, 0x6b, 0xab, 0x1d, 0xa5, 0xf5, - 0x49, 0x73, 0x7f, 0xb7, 0x36, 0x87, 0x36, 0xe0, 0x7c, 0xf8, 0xc5, 0xe3, 0xbd, 0xee, 0xbe, 0xba, - 0xbf, 0xa7, 0x6e, 0xef, 0xb5, 0xf7, 0x9b, 0xad, 0xf6, 0xae, 0x52, 0x93, 0xd0, 0x79, 0x38, 0x1b, - 0x66, 0x79, 0xd0, 0xda, 0x69, 0x29, 0xbb, 0xdb, 0xe4, 0xb9, 0xf9, 0xa4, 0x96, 0xbb, 0x76, 0x03, - 0x2a, 0x91, 0x1f, 0x94, 0x12, 0x93, 0x3a, 0x7b, 0x3b, 0xb5, 0x39, 0x54, 0x81, 0x52, 0x58, 0x4f, - 0x11, 0xe6, 0xdb, 0x7b, 0x3b, 0xbb, 0xb5, 0xdc, 0xb5, 0xdb, 0xb0, 0x1c, 0xbb, 0xdf, 0x8b, 0x56, - 0xa0, 0xd2, 0x6d, 0xb6, 0x77, 0x1e, 0xec, 0x7d, 0xa6, 0x2a, 0xbb, 0xcd, 0x9d, 0xcf, 0x6b, 0x73, - 0x68, 0x15, 0x6a, 0x82, 0xd4, 0xde, 0xdb, 0x67, 0x54, 0xe9, 0xda, 0xb3, 0xd8, 0x1c, 0xc3, 0xe8, - 0x34, 0xac, 0xf8, 0xdd, 0xa8, 0xdb, 0xca, 0x6e, 0x73, 0x7f, 0x97, 0xf4, 0x1e, 0x21, 0x2b, 0x07, - 0xed, 0x76, 0xab, 0xfd, 0xa8, 0x26, 0x11, 0xad, 0x01, 0x79, 0xf7, 0xb3, 0x16, 0x61, 0xce, 0x45, - 0x99, 0x0f, 0xda, 0x3f, 0x68, 0xef, 0x7d, 0xda, 0xae, 0xe5, 0xb7, 0x7e, 0xb1, 0x02, 0x55, 0x51, - 0xe8, 0x61, 0x87, 0xde, 0x6a, 0xe9, 0xc0, 0xa2, 0xf8, 0xd1, 0x77, 0x4a, 0x86, 0x8e, 0xfe, 0x54, - 0xbd, 0xb1, 0x31, 0x86, 0x83, 0xd7, 0xdb, 0x73, 0xe8, 0x90, 0xd6, 0xbf, 0xa1, 0xfb, 0xd6, 0x97, - 0x52, 0xab, 0xcd, 0xc4, 0x15, 0xef, 0xc6, 0xe5, 0x89, 0x7c, 0x7e, 0x1f, 0x98, 0x94, 0xb8, 0xe1, - 0x9f, 0x34, 0xa1, 0xcb, 0x69, 0xb5, 0x69, 0xca, 0x6f, 0xa6, 0x1a, 0x57, 0x26, 0x33, 0xfa, 0xdd, - 0x3c, 0x83, 0x5a, 0xfc, 0xe7, 0x4d, 0x28, 0x05, 0x3a, 0xcd, 0xf8, 0x0d, 0x55, 0xe3, 0xda, 0x34, - 0xac, 0xe1, 0xce, 0x12, 0xbf, 0xd7, 0xb9, 0x3a, 0xcd, 0xef, 0x1a, 0x32, 0x3b, 0xcb, 0xfa, 0x09, - 0x04, 0x73, 0x60, 0xf4, 0x8a, 0x34, 0x4a, 0xfd, 0x71, 0x4c, 0xca, 0x4d, 0xfc, 0x34, 0x07, 0xa6, - 0xdf, 0xb6, 0x96, 0xe7, 0xd0, 0x31, 0x2c, 0xc7, 0xae, 0x27, 0xa0, 0x14, 0xf1, 0xf4, 0x7b, 0x18, - 0x8d, 0xab, 0x53, 0x70, 0x46, 0x23, 0x22, 0x7c, 0x1d, 0x21, 0x3d, 0x22, 0x52, 0x2e, 0x3b, 0xa4, - 0x47, 0x44, 0xea, 0xcd, 0x06, 0x1a, 0xdc, 0x91, 0x6b, 0x08, 0x69, 0xc1, 0x9d, 0x76, 0xf9, 0xa1, - 0x71, 0x79, 0x22, 0x5f, 0xd8, 0x69, 0xb1, 0x4b, 0x09, 0x69, 0x4e, 0x4b, 0xbf, 0xf4, 0xd0, 0xb8, - 0x3a, 0x05, 0x67, 0x3c, 0x0a, 0x82, 0x23, 0xce, 0xac, 0x28, 0x48, 0x1c, 0xc8, 0x67, 0x45, 0x41, - 0xf2, 0xb4, 0x94, 0x47, 0x41, 0xec, 0x68, 0xf2, 0xca, 0x14, 0x47, 0x29, 0xd9, 0x51, 0x90, 0x7e, - 0xe8, 0x22, 0xcf, 0xa1, 0x9f, 0x4a, 0x50, 0xcf, 0x3a, 0xa6, 0x40, 0x29, 0xf5, 0xdd, 0x84, 0x93, - 0x95, 0xc6, 0xd6, 0x2c, 0x22, 0xbe, 0x15, 0x5f, 0x01, 0x4a, 0xae, 0x7b, 0xe8, 0x9d, 0xb4, 0x91, - 0xc9, 0x58, 0x5d, 0x1b, 0xef, 0x4e, 0xc7, 0xec, 0x77, 0xd9, 0x85, 0xa2, 0x38, 0x18, 0x41, 0x29, - 0x59, 0x3a, 0x76, 0x2c, 0xd3, 0x90, 0xc7, 0xb1, 0xf8, 0x4a, 0x1f, 0xc1, 0x3c, 0xa1, 0xa2, 0xf3, - 0xe9, 0xdc, 0x42, 0xd9, 0x7a, 0xd6, 0x6b, 0x5f, 0xd1, 0x53, 0x58, 0x60, 0x27, 0x01, 0x28, 0x05, - 0x79, 0x88, 0x9c, 0x57, 0x34, 0x2e, 0x64, 0x33, 0xf8, 0xea, 0xbe, 0x64, 0xff, 0x0f, 0x84, 0x83, - 0xfc, 0xe8, 0xed, 0xf4, 0x1f, 0x58, 0x47, 0xcf, 0x14, 0x1a, 0x17, 0x27, 0x70, 0x85, 0x27, 0x45, - 0xac, 0xea, 0xbd, 0x3c, 0x71, 0xeb, 0x92, 0x3d, 0x29, 0xd2, 0x37, 0x47, 0x2c, 0x48, 0x92, 0x9b, - 0xa7, 0xb4, 0x20, 0xc9, 0xdc, 0xb2, 0xa6, 0x05, 0x49, 0xf6, 0x7e, 0x4c, 0x9e, 0x43, 0x1e, 0x9c, - 0x4a, 0x81, 0xca, 0xd0, 0xbb, 0x59, 0x41, 0x9e, 0x86, 0xdb, 0x35, 0xde, 0x9b, 0x92, 0x3b, 0x3c, - 0xf8, 0x7c, 0xd2, 0xbf, 0x99, 0x8d, 0x1f, 0x65, 0x0e, 0x7e, 0x7c, 0x8a, 0x6f, 0xfd, 0x4b, 0x1e, - 0x96, 0x18, 0x0c, 0xca, 0x2b, 0x98, 0xcf, 0x01, 0x82, 0x13, 0x08, 0xf4, 0x56, 0xba, 0x4f, 0x22, - 0xa7, 0x34, 0x8d, 0xb7, 0xc7, 0x33, 0x85, 0x03, 0x2d, 0x84, 0xe6, 0xa7, 0x05, 0x5a, 0xf2, 0xd0, - 0x22, 0x2d, 0xd0, 0x52, 0x8e, 0x04, 0xe4, 0x39, 0xf4, 0x09, 0x94, 0x7c, 0xd8, 0x18, 0xa5, 0xc1, - 0xce, 0x31, 0x5c, 0xbc, 0xf1, 0xd6, 0x58, 0x9e, 0xb0, 0xd5, 0x21, 0x4c, 0x38, 0xcd, 0xea, 0x24, - 0xf6, 0x9c, 0x66, 0x75, 0x1a, 0xb0, 0x1c, 0xf8, 0x84, 0x21, 0x47, 0x99, 0x3e, 0x89, 0x00, 0x77, - 0x99, 0x3e, 0x89, 0xc2, 0x4f, 0xf2, 0xdc, 0x83, 0x4b, 0xbf, 0xfc, 0x7a, 0x5d, 0xfa, 0xa7, 0xaf, - 0xd7, 0xe7, 0x7e, 0xf2, 0xcd, 0xba, 0xf4, 0xcb, 0x6f, 0xd6, 0xa5, 0x7f, 0xfc, 0x66, 0x5d, 0xfa, - 0xd7, 0x6f, 0xd6, 0xa5, 0x3f, 0xfd, 0xb7, 0xf5, 0xb9, 0x1f, 0x16, 0x85, 0xf4, 0xe1, 0x02, 0xfd, - 0xaf, 0x3e, 0x1f, 0xfc, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xde, 0xe7, 0x02, 0x9b, 0x49, - 0x00, 0x00, + // 4961 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3c, 0x4d, 0x8f, 0x1b, 0x47, + 0x76, 0xd3, 0xe4, 0x70, 0x86, 0x7c, 0x1c, 0x72, 0xa8, 0xd2, 0x48, 0x43, 0x51, 0x96, 0xac, 0x69, + 0xdb, 0xfa, 0xb2, 0x3d, 0xb2, 0xc6, 0x5e, 0x39, 0x92, 0xbc, 0xb2, 0x29, 0xce, 0x48, 0x62, 0x56, + 0xe2, 0x30, 0xcd, 0x19, 0x7f, 0xac, 0x8d, 0xb4, 0x7b, 0xd8, 0x35, 0x9c, 0x5e, 0x91, 0xdd, 0xed, + 0xee, 0xe6, 0x48, 0x93, 0x00, 0xc1, 0x02, 0x8b, 0xec, 0x21, 0x40, 0x80, 0x9c, 0x73, 0xdc, 0x04, + 0xc8, 0x21, 0xe7, 0x20, 0x40, 0x72, 0x4a, 0x90, 0xc3, 0x5e, 0x02, 0xe4, 0xb4, 0x48, 0x90, 0x4b, + 0xec, 0x24, 0x08, 0x10, 0x20, 0x41, 0x7e, 0x40, 0x0e, 0x41, 0x7d, 0xf5, 0x77, 0xf3, 0x43, 0xd6, + 0xae, 0x37, 0xa7, 0x61, 0xbd, 0x7a, 0xef, 0xd5, 0xab, 0x57, 0xaf, 0x5e, 0xbd, 0x7a, 0xaf, 0x7a, + 0xa0, 0xa4, 0xd9, 0xc6, 0xa6, 0xed, 0x58, 0x9e, 0x85, 0x6a, 0xce, 0xd8, 0xf4, 0x8c, 0x11, 0xde, + 0x3c, 0xbe, 0xa9, 0x0d, 0xed, 0x23, 0x6d, 0xab, 0xf1, 0xf6, 0xc0, 0xf0, 0x8e, 0xc6, 0x07, 0x9b, + 0x7d, 0x6b, 0x74, 0x63, 0x60, 0x0d, 0xac, 0x1b, 0x14, 0xf1, 0x60, 0x7c, 0x48, 0x5b, 0xb4, 0x41, + 0x7f, 0x31, 0x06, 0xf2, 0x75, 0xa8, 0x7e, 0x8c, 0x1d, 0xd7, 0xb0, 0x4c, 0x05, 0x7f, 0x35, 0xc6, + 0xae, 0x87, 0xea, 0xb0, 0x7c, 0xcc, 0x20, 0x75, 0xe9, 0x92, 0x74, 0xb5, 0xa4, 0x88, 0xa6, 0xfc, + 0x67, 0x12, 0xac, 0xfa, 0xc8, 0xae, 0x6d, 0x99, 0x2e, 0xce, 0xc6, 0x46, 0x1b, 0xb0, 0xc2, 0x85, + 0x53, 0x4d, 0x6d, 0x84, 0xeb, 0x39, 0xda, 0x5d, 0xe6, 0xb0, 0x8e, 0x36, 0xc2, 0xe8, 0x0a, 0xac, + 0x0a, 0x14, 0xc1, 0x24, 0x4f, 0xb1, 0xaa, 0x1c, 0xcc, 0x47, 0x43, 0x9b, 0x70, 0x5a, 0x20, 0x6a, + 0xb6, 0xe1, 0x23, 0x2f, 0x52, 0xe4, 0x53, 0xbc, 0xab, 0x69, 0x1b, 0x1c, 0x5f, 0xfe, 0x1c, 0x4a, + 0xdb, 0x9d, 0x5e, 0xcb, 0x32, 0x0f, 0x8d, 0x01, 0x11, 0xd1, 0xc5, 0x0e, 0xa1, 0xa9, 0x4b, 0x97, + 0xf2, 0x44, 0x44, 0xde, 0x44, 0x0d, 0x28, 0xba, 0x58, 0x73, 0xfa, 0x47, 0xd8, 0xad, 0xe7, 0x68, + 0x97, 0xdf, 0x26, 0x54, 0x96, 0xed, 0x19, 0x96, 0xe9, 0xd6, 0xf3, 0x8c, 0x8a, 0x37, 0xe5, 0x9f, + 0x49, 0x50, 0xee, 0x5a, 0x8e, 0xf7, 0x44, 0xb3, 0x6d, 0xc3, 0x1c, 0xa0, 0x5b, 0x50, 0xa4, 0xba, + 0xec, 0x5b, 0x43, 0xaa, 0x83, 0xea, 0x56, 0x63, 0x33, 0xbe, 0x2c, 0x9b, 0x5d, 0x8e, 0xa1, 0xf8, + 0xb8, 0xe8, 0x0d, 0xa8, 0xf6, 0x2d, 0xd3, 0xd3, 0x0c, 0x13, 0x3b, 0xaa, 0x6d, 0x39, 0x1e, 0x55, + 0x51, 0x41, 0xa9, 0xf8, 0x50, 0x32, 0x0a, 0x3a, 0x0f, 0xa5, 0x23, 0xcb, 0xf5, 0x18, 0x46, 0x9e, + 0x62, 0x14, 0x09, 0x80, 0x76, 0xae, 0xc3, 0x32, 0xed, 0x34, 0x6c, 0xae, 0x8c, 0x25, 0xd2, 0x6c, + 0xdb, 0xf2, 0x2f, 0x24, 0x28, 0x3c, 0xb1, 0xc6, 0xa6, 0x17, 0x1b, 0x46, 0xf3, 0x8e, 0xf8, 0x42, + 0x85, 0x86, 0xd1, 0xbc, 0xa3, 0x60, 0x18, 0x82, 0xc1, 0xd6, 0x8a, 0x0d, 0x43, 0x3a, 0x1b, 0x50, + 0x74, 0xb0, 0xa6, 0x5b, 0xe6, 0xf0, 0x84, 0x8a, 0x50, 0x54, 0xfc, 0x36, 0x59, 0x44, 0x17, 0x0f, + 0x0d, 0x73, 0xfc, 0x5c, 0x75, 0xf0, 0x50, 0x3b, 0xc0, 0x43, 0x2a, 0x4a, 0x51, 0xa9, 0x72, 0xb0, + 0xc2, 0xa0, 0x68, 0x1b, 0xca, 0xb6, 0x63, 0xd9, 0xda, 0x40, 0x23, 0x7a, 0xac, 0x17, 0xa8, 0xaa, + 0xe4, 0xa4, 0xaa, 0xa8, 0xd8, 0xdd, 0x00, 0x53, 0x09, 0x93, 0xc9, 0xff, 0x21, 0xc1, 0x2a, 0x31, + 0x1e, 0xd7, 0xd6, 0xfa, 0x78, 0x97, 0x2e, 0x09, 0xba, 0x0d, 0xcb, 0x26, 0xf6, 0x9e, 0x59, 0xce, + 0x53, 0xbe, 0x00, 0xaf, 0x26, 0xb9, 0xfa, 0x34, 0x4f, 0x2c, 0x1d, 0x2b, 0x02, 0x1f, 0xdd, 0x84, + 0xbc, 0x6d, 0xe8, 0x74, 0xc2, 0x33, 0x90, 0x11, 0x5c, 0x42, 0x62, 0xd8, 0x7d, 0xaa, 0x87, 0x59, + 0x48, 0x0c, 0xbb, 0x8f, 0xde, 0x85, 0xc5, 0xb1, 0x8b, 0x1d, 0xaa, 0x98, 0x19, 0x68, 0x28, 0xb2, + 0x2c, 0x03, 0xb4, 0x4d, 0xef, 0xd6, 0x7b, 0x1f, 0x6b, 0xc3, 0x31, 0x46, 0x6b, 0x50, 0x38, 0x26, + 0x3f, 0xe8, 0x0c, 0xf3, 0x0a, 0x6b, 0xc8, 0x5f, 0xe7, 0xe1, 0xfc, 0x63, 0xa2, 0xe4, 0x9e, 0x66, + 0xea, 0x07, 0xd6, 0xf3, 0x1e, 0xee, 0x8f, 0x1d, 0xc3, 0x3b, 0x69, 0x59, 0xa6, 0x87, 0x9f, 0x7b, + 0xa8, 0x03, 0xa7, 0x4c, 0xc1, 0x5a, 0x15, 0xf6, 0x4c, 0x38, 0x94, 0xb7, 0x36, 0x26, 0x48, 0xc1, + 0xf4, 0xaa, 0xd4, 0xcc, 0x28, 0xc0, 0x45, 0x8f, 0x82, 0xc5, 0x16, 0xdc, 0x72, 0x94, 0x5b, 0xca, + 0x9c, 0x7a, 0x3b, 0x54, 0x32, 0xce, 0x4b, 0x58, 0x83, 0xe0, 0xf4, 0x01, 0x10, 0x57, 0xa0, 0x6a, + 0xae, 0x4a, 0x35, 0x93, 0xa7, 0x5c, 0x5e, 0x49, 0x72, 0x09, 0x54, 0xa0, 0x94, 0x9c, 0xb1, 0xd9, + 0x74, 0xf7, 0x5d, 0xec, 0xa0, 0x7b, 0xd4, 0xb9, 0x10, 0xea, 0x81, 0x63, 0x8d, 0xed, 0x7a, 0x71, + 0x06, 0x72, 0xa0, 0xe4, 0x0f, 0x09, 0x3e, 0xf5, 0x3c, 0xdc, 0x80, 0x55, 0xc7, 0xb2, 0xbc, 0x43, + 0x57, 0x18, 0xad, 0x00, 0x2b, 0x14, 0x8a, 0x6e, 0xc0, 0x69, 0x77, 0x6c, 0xdb, 0x43, 0x3c, 0xc2, + 0xa6, 0xa7, 0x0d, 0xd9, 0x70, 0x6e, 0xbd, 0x70, 0x29, 0x7f, 0x35, 0xaf, 0xa0, 0x70, 0x17, 0x65, + 0xec, 0xa2, 0x8b, 0x00, 0xb6, 0x63, 0x1c, 0x1b, 0x43, 0x3c, 0xc0, 0x7a, 0x7d, 0x89, 0x32, 0x0d, + 0x41, 0xd0, 0x3b, 0xb0, 0xe6, 0xe2, 0x7e, 0xdf, 0x1a, 0xd9, 0xaa, 0xed, 0x58, 0x87, 0xc6, 0x10, + 0xb3, 0x2d, 0xb7, 0x4c, 0xb7, 0x1c, 0xe2, 0x7d, 0x5d, 0xd6, 0x45, 0x36, 0x9f, 0xfc, 0xb3, 0x1c, + 0x9c, 0xa1, 0x9a, 0xec, 0x5a, 0x3a, 0x5f, 0x66, 0xee, 0xd9, 0x5e, 0x83, 0x4a, 0x9f, 0x0a, 0xa4, + 0xda, 0x9a, 0x83, 0x4d, 0x8f, 0xef, 0xec, 0x15, 0x06, 0xec, 0x52, 0x18, 0xfa, 0x14, 0x6a, 0x2e, + 0xb7, 0x0a, 0xb5, 0xcf, 0xcc, 0x82, 0xaf, 0xd9, 0xdb, 0x49, 0x75, 0x4d, 0xb0, 0x25, 0x65, 0xd5, + 0x4d, 0x18, 0xd7, 0xb2, 0x7b, 0xe2, 0xf6, 0xbd, 0x21, 0x73, 0x91, 0xe5, 0xad, 0xf7, 0x32, 0x18, + 0xc6, 0x05, 0xdf, 0xec, 0x31, 0xb2, 0x1d, 0xd3, 0x73, 0x4e, 0x14, 0xc1, 0xa4, 0x71, 0x07, 0x56, + 0xc2, 0x1d, 0xa8, 0x06, 0xf9, 0xa7, 0xf8, 0x84, 0x4f, 0x8a, 0xfc, 0x0c, 0x36, 0x01, 0x73, 0x50, + 0xac, 0x71, 0x27, 0xf7, 0x1b, 0x92, 0xec, 0x00, 0x0a, 0x46, 0x79, 0x82, 0x3d, 0x4d, 0xd7, 0x3c, + 0x0d, 0x21, 0x58, 0xa4, 0x67, 0x0f, 0x63, 0x41, 0x7f, 0x13, 0xae, 0x63, 0xbe, 0xe3, 0x4b, 0x0a, + 0xf9, 0x89, 0x5e, 0x81, 0x92, 0x6f, 0xe8, 0xfc, 0x00, 0x0a, 0x00, 0xe4, 0x20, 0xd0, 0x3c, 0x0f, + 0x8f, 0x6c, 0x8f, 0x9a, 0x48, 0x45, 0x11, 0x4d, 0xf9, 0xbf, 0x17, 0xa1, 0x96, 0x58, 0x93, 0x8f, + 0xa0, 0x38, 0xe2, 0xc3, 0xf3, 0x8d, 0xf6, 0x7a, 0xca, 0x69, 0x90, 0x10, 0x55, 0xf1, 0xa9, 0x88, + 0xb3, 0x25, 0x8e, 0x37, 0x74, 0x68, 0xfa, 0x6d, 0xb2, 0xe2, 0x43, 0x6b, 0xa0, 0xea, 0x86, 0x83, + 0xfb, 0x9e, 0xe5, 0x9c, 0x70, 0x71, 0x57, 0x86, 0xd6, 0x60, 0x5b, 0xc0, 0xd0, 0x1d, 0x00, 0xdd, + 0x74, 0xc9, 0x62, 0x1f, 0x1a, 0x03, 0x2a, 0x74, 0x79, 0xeb, 0x7c, 0x52, 0x08, 0xff, 0x84, 0x54, + 0x4a, 0xba, 0xe9, 0x72, 0xf1, 0xef, 0x43, 0x85, 0x1c, 0x34, 0xea, 0x88, 0x1d, 0x6e, 0xcc, 0xd2, + 0xcb, 0x5b, 0x17, 0xd2, 0xe6, 0xe0, 0x1f, 0x81, 0xca, 0x8a, 0x1d, 0x34, 0x5c, 0xf4, 0x00, 0x96, + 0xa8, 0xc7, 0x77, 0xeb, 0x4b, 0x94, 0x78, 0x73, 0x92, 0x02, 0xb8, 0x45, 0x3c, 0xa6, 0x04, 0xcc, + 0x20, 0x38, 0x35, 0xda, 0x87, 0xb2, 0x66, 0x9a, 0x96, 0xa7, 0x31, 0x47, 0xb3, 0x4c, 0x99, 0xbd, + 0x3b, 0x03, 0xb3, 0x66, 0x40, 0xc5, 0x38, 0x86, 0xf9, 0xa0, 0xef, 0x43, 0x81, 0x7a, 0x22, 0xee, + 0x34, 0xae, 0xcc, 0x68, 0xb4, 0x0a, 0xa3, 0x6a, 0xdc, 0x86, 0x72, 0x48, 0xd8, 0x79, 0x8c, 0xb4, + 0x71, 0x0f, 0x6a, 0x71, 0xd1, 0xe6, 0x32, 0xf2, 0xdf, 0x85, 0x35, 0x65, 0x6c, 0x06, 0x82, 0x89, + 0x90, 0xed, 0x0e, 0x2c, 0xf1, 0xc5, 0x66, 0x16, 0x27, 0x4f, 0xd7, 0x91, 0xc2, 0x29, 0xc2, 0x31, + 0xd8, 0x91, 0x66, 0xea, 0x43, 0xec, 0xf0, 0x71, 0x45, 0x0c, 0xf6, 0x88, 0x41, 0xe5, 0xef, 0xc3, + 0x99, 0xd8, 0xe0, 0x3c, 0x04, 0x7c, 0x1d, 0xaa, 0xb6, 0xa5, 0xab, 0x2e, 0x03, 0xab, 0x86, 0x2e, + 0xdc, 0x90, 0xed, 0xe3, 0xb6, 0x75, 0x42, 0xde, 0xf3, 0x2c, 0x3b, 0x29, 0xfc, 0x6c, 0xe4, 0x75, + 0x38, 0x1b, 0x27, 0x67, 0xc3, 0xcb, 0x1f, 0xc2, 0xba, 0x82, 0x47, 0xd6, 0x31, 0x7e, 0x51, 0xd6, + 0x0d, 0xa8, 0x27, 0x19, 0x70, 0xe6, 0x9f, 0xc1, 0x7a, 0x00, 0xed, 0x79, 0x9a, 0x37, 0x76, 0xe7, + 0x62, 0xce, 0xe3, 0xe3, 0x03, 0xcb, 0x65, 0xcb, 0x59, 0x54, 0x44, 0x53, 0x5e, 0x87, 0x42, 0xd7, + 0xd2, 0xdb, 0x5d, 0x54, 0x85, 0x9c, 0x61, 0x73, 0xe2, 0x9c, 0x61, 0xcb, 0x46, 0x78, 0xcc, 0x0e, + 0x8b, 0x53, 0xd8, 0xd0, 0x71, 0x54, 0x74, 0x0f, 0xaa, 0x9a, 0xae, 0x1b, 0xc4, 0x9c, 0xb4, 0xa1, + 0x6a, 0xd8, 0x2c, 0x8c, 0x2d, 0x6f, 0xad, 0xa7, 0x1a, 0x40, 0xbb, 0xab, 0x54, 0x02, 0xf4, 0xb6, + 0xed, 0xca, 0x8f, 0xa0, 0xe4, 0x9f, 0xf9, 0xe8, 0x6e, 0x10, 0xf1, 0xe6, 0x66, 0x8d, 0x10, 0xfc, + 0xa0, 0x78, 0x2f, 0x71, 0x46, 0x71, 0x91, 0xef, 0x02, 0xf8, 0xbe, 0x54, 0x84, 0x1e, 0xe7, 0x27, + 0x30, 0x56, 0x42, 0xe8, 0xf2, 0x4f, 0x0a, 0x61, 0x0f, 0x1b, 0x52, 0x82, 0xee, 0x2b, 0x41, 0x8f, + 0x78, 0xdc, 0xdc, 0x0b, 0x79, 0xdc, 0xf7, 0xa1, 0xe0, 0x7a, 0x9a, 0x87, 0x79, 0x4c, 0xb7, 0x31, + 0x89, 0x9c, 0x08, 0x81, 0x15, 0x86, 0x8f, 0x2e, 0x00, 0xf4, 0x1d, 0xac, 0x79, 0x58, 0x57, 0x35, + 0x76, 0x3c, 0xe4, 0x95, 0x12, 0x87, 0x34, 0x3d, 0xd4, 0x0a, 0xe2, 0xd2, 0x02, 0x15, 0xec, 0xda, + 0x24, 0xce, 0x91, 0xa5, 0x0e, 0x22, 0x54, 0xdf, 0x5d, 0x2d, 0xcd, 0xe8, 0xae, 0x38, 0x03, 0x46, + 0x15, 0x72, 0xc6, 0xcb, 0xd3, 0x9d, 0x31, 0x23, 0x9d, 0xc5, 0x19, 0x17, 0xa7, 0x3b, 0x63, 0xce, + 0x6c, 0xb2, 0x33, 0x4e, 0x71, 0x3f, 0xa5, 0x34, 0xf7, 0xf3, 0x5d, 0xba, 0xdd, 0x7f, 0x92, 0xa0, + 0x9e, 0xf4, 0x02, 0xdc, 0xfb, 0xdd, 0x81, 0x25, 0x97, 0x42, 0x66, 0xf1, 0xbd, 0x9c, 0x96, 0x53, + 0xa0, 0x47, 0xb0, 0x68, 0x98, 0x87, 0x16, 0xdf, 0xb4, 0xef, 0xcd, 0x40, 0xc9, 0x47, 0xdd, 0x6c, + 0x9b, 0x87, 0x16, 0xd3, 0x26, 0xe5, 0xd0, 0x78, 0x1f, 0x4a, 0x3e, 0x68, 0xae, 0xb9, 0xed, 0xc2, + 0x5a, 0xcc, 0xb6, 0xd9, 0x75, 0xc3, 0xdf, 0x12, 0xd2, 0x7c, 0x5b, 0x42, 0xfe, 0x71, 0x2e, 0xbc, + 0x65, 0x1f, 0x18, 0x43, 0x0f, 0x3b, 0x89, 0x2d, 0xfb, 0x81, 0xe0, 0xce, 0xf6, 0xeb, 0xe5, 0xa9, + 0xdc, 0x59, 0x04, 0xcf, 0x77, 0xdd, 0x17, 0x50, 0xa5, 0x46, 0xa9, 0xba, 0x78, 0x48, 0x43, 0x1e, + 0x1e, 0x7e, 0x7e, 0x6f, 0x12, 0x1b, 0x26, 0x09, 0x33, 0xed, 0x1e, 0xa7, 0x63, 0x1a, 0xac, 0x0c, + 0xc3, 0xb0, 0xc6, 0x47, 0x80, 0x92, 0x48, 0x73, 0xe9, 0xb4, 0x47, 0x7c, 0x21, 0xb9, 0xa0, 0xa7, + 0x9c, 0xd3, 0x87, 0x54, 0x8c, 0x59, 0x6c, 0x85, 0x09, 0xac, 0x70, 0x0a, 0xf9, 0xbf, 0xf2, 0x00, + 0x41, 0xe7, 0xff, 0x23, 0x27, 0xf8, 0x91, 0xef, 0x80, 0x58, 0x28, 0x79, 0x75, 0x12, 0xe3, 0x54, + 0xd7, 0xb3, 0x1b, 0x75, 0x3d, 0x2c, 0xa8, 0x7c, 0x7b, 0x22, 0x9b, 0xb9, 0x9d, 0xce, 0xf2, 0xaf, + 0x9b, 0xd3, 0x79, 0x0c, 0x67, 0xe3, 0x46, 0xc4, 0x3d, 0xce, 0x16, 0x14, 0x0c, 0x0f, 0x8f, 0x58, + 0x36, 0x2b, 0xf5, 0xd2, 0x1b, 0x22, 0x62, 0xa8, 0xf2, 0x06, 0x94, 0xda, 0x23, 0x6d, 0x80, 0x7b, + 0x36, 0xee, 0x93, 0x41, 0x0d, 0xd2, 0xe0, 0x82, 0xb0, 0x86, 0xbc, 0x05, 0xc5, 0x1f, 0xe0, 0x13, + 0xb6, 0xfb, 0x67, 0x14, 0x54, 0xfe, 0xc3, 0x1c, 0xac, 0xd3, 0xd3, 0xa7, 0x25, 0x72, 0x49, 0x0a, + 0x76, 0xad, 0xb1, 0xd3, 0xc7, 0x2e, 0x35, 0x0b, 0x7b, 0xac, 0xda, 0xd8, 0x31, 0x2c, 0x9d, 0x67, + 0x2d, 0x4a, 0x7d, 0x7b, 0xdc, 0xa5, 0x00, 0x74, 0x1e, 0x48, 0x43, 0xfd, 0x6a, 0x6c, 0x71, 0x8b, + 0xcd, 0x2b, 0xc5, 0xbe, 0x3d, 0xfe, 0x2d, 0xd2, 0x16, 0xb4, 0xee, 0x91, 0xe6, 0x60, 0x97, 0x1a, + 0x24, 0xa3, 0xed, 0x51, 0x00, 0xba, 0x09, 0x67, 0x46, 0x78, 0x64, 0x39, 0x27, 0xea, 0xd0, 0x18, + 0x19, 0x9e, 0x6a, 0x98, 0xea, 0xc1, 0x89, 0x87, 0x5d, 0x6e, 0x7c, 0x88, 0x75, 0x3e, 0x26, 0x7d, + 0x6d, 0xf3, 0x3e, 0xe9, 0x41, 0x32, 0x54, 0x2c, 0x6b, 0xa4, 0xba, 0x7d, 0xcb, 0xc1, 0xaa, 0xa6, + 0xff, 0x88, 0x1e, 0xc8, 0x79, 0xa5, 0x6c, 0x59, 0xa3, 0x1e, 0x81, 0x35, 0xf5, 0x1f, 0xa1, 0x57, + 0xa1, 0xdc, 0xb7, 0xc7, 0x2e, 0xf6, 0x54, 0xf2, 0x87, 0x9e, 0xb7, 0x25, 0x05, 0x18, 0xa8, 0x65, + 0x8f, 0xdd, 0x10, 0xc2, 0x88, 0xe8, 0x7f, 0x39, 0x8c, 0xf0, 0x84, 0xa8, 0x59, 0x83, 0x4a, 0x24, + 0xeb, 0x41, 0x2e, 0xa0, 0x34, 0xbd, 0xc1, 0x2f, 0xa0, 0xe4, 0x37, 0x81, 0x39, 0xd6, 0x50, 0x68, + 0x92, 0xfe, 0x26, 0x30, 0xef, 0xc4, 0x16, 0xb7, 0x4f, 0xfa, 0x9b, 0xa8, 0x7c, 0x88, 0x8f, 0x79, + 0x3a, 0xad, 0xa4, 0xb0, 0x86, 0xac, 0x03, 0xb4, 0x34, 0x5b, 0x3b, 0x30, 0x86, 0x86, 0x77, 0x82, + 0xae, 0x41, 0x4d, 0xd3, 0x75, 0xb5, 0x2f, 0x20, 0x06, 0x16, 0x49, 0xce, 0x55, 0x4d, 0xd7, 0x5b, + 0x21, 0x30, 0x7a, 0x13, 0x4e, 0xe9, 0x8e, 0x65, 0x47, 0x71, 0x59, 0xd6, 0xb3, 0x46, 0x3a, 0xc2, + 0xc8, 0xf2, 0xbf, 0x15, 0xe0, 0x42, 0x74, 0x61, 0xe3, 0x99, 0xa5, 0x8f, 0x60, 0x25, 0x36, 0x6a, + 0x46, 0x06, 0x26, 0x90, 0x56, 0x89, 0x50, 0xc4, 0x32, 0x25, 0xb9, 0x44, 0xa6, 0x24, 0x35, 0x77, + 0x95, 0x7f, 0xa9, 0xb9, 0xab, 0xc5, 0x97, 0x92, 0xbb, 0x2a, 0x7c, 0xbb, 0xdc, 0xd5, 0xca, 0x9c, + 0xb9, 0xab, 0xcb, 0xd4, 0x7b, 0x89, 0xd1, 0x69, 0x9a, 0x80, 0x99, 0x6a, 0xc5, 0x1f, 0xc3, 0x14, + 0xd9, 0xf5, 0x58, 0x8e, 0x6b, 0x79, 0x9e, 0x1c, 0x57, 0x31, 0x33, 0xc7, 0x45, 0xac, 0xce, 0xb6, + 0x35, 0x67, 0x64, 0x39, 0x22, 0x89, 0xc5, 0xa3, 0xb6, 0x55, 0x01, 0xe7, 0x09, 0xac, 0xcc, 0x74, + 0x17, 0x64, 0xa5, 0xbb, 0xd0, 0x25, 0x58, 0x31, 0x2d, 0xd5, 0xc4, 0xcf, 0x54, 0x62, 0x0b, 0x6e, + 0xbd, 0xcc, 0x0c, 0xc3, 0xb4, 0x3a, 0xf8, 0x59, 0x97, 0x40, 0xd0, 0x06, 0xac, 0x8c, 0x34, 0xf7, + 0x29, 0xd6, 0x29, 0x2b, 0xb7, 0x5e, 0xa1, 0x46, 0x5c, 0x66, 0x30, 0xc2, 0xc3, 0x45, 0x6f, 0x80, + 0x3f, 0x49, 0x8e, 0x54, 0xa5, 0x48, 0x15, 0x01, 0xa5, 0x68, 0xf2, 0x5f, 0x4b, 0xb0, 0x16, 0x35, + 0x73, 0x9e, 0x06, 0x79, 0x08, 0x25, 0x47, 0x78, 0x32, 0x6e, 0xda, 0xd7, 0x32, 0x02, 0xef, 0xa4, + 0xeb, 0x53, 0x02, 0x5a, 0xf4, 0xc3, 0xcc, 0xec, 0xdb, 0x8d, 0x69, 0xfc, 0xa6, 0xe5, 0xdf, 0x64, + 0x07, 0x5e, 0xfd, 0xc4, 0x30, 0x75, 0xeb, 0x99, 0x9b, 0xb9, 0x4b, 0x53, 0x6c, 0x45, 0xca, 0xb0, + 0x95, 0xbe, 0x83, 0x75, 0x6c, 0x7a, 0x86, 0x36, 0x54, 0x5d, 0x1b, 0xf7, 0x45, 0x16, 0x20, 0x00, + 0x93, 0xb3, 0x43, 0xfe, 0x1b, 0x09, 0xce, 0xc6, 0x07, 0xe5, 0x3a, 0x6b, 0x27, 0x75, 0xf6, 0x66, + 0x72, 0x8e, 0x71, 0xe2, 0x54, 0xad, 0x7d, 0x91, 0xa9, 0xb5, 0x9b, 0xd3, 0x39, 0x4e, 0xd5, 0xdb, + 0x9f, 0x4b, 0x70, 0x2e, 0x53, 0x8c, 0xd8, 0xd9, 0x23, 0xc5, 0xcf, 0x1e, 0x7e, 0x6e, 0xf5, 0xad, + 0xb1, 0xe9, 0x85, 0xce, 0xad, 0x16, 0xad, 0xb5, 0xb0, 0x03, 0x42, 0x1d, 0x69, 0xcf, 0x8d, 0xd1, + 0x78, 0xc4, 0x0f, 0x2e, 0xc2, 0xee, 0x09, 0x83, 0xbc, 0xc0, 0xc9, 0x25, 0x37, 0xe1, 0x94, 0x2f, + 0xe5, 0xc4, 0xc4, 0x66, 0x28, 0x51, 0x99, 0x8b, 0x26, 0x2a, 0x4d, 0x58, 0xda, 0xc6, 0xc7, 0x46, + 0x1f, 0xbf, 0x94, 0x62, 0xd0, 0x25, 0x28, 0xdb, 0xd8, 0x19, 0x19, 0xae, 0xeb, 0x7b, 0xe4, 0x92, + 0x12, 0x06, 0xc9, 0xff, 0xbe, 0x04, 0xab, 0x71, 0xeb, 0xf8, 0x30, 0x91, 0x17, 0x7d, 0x2d, 0xe5, + 0xac, 0x88, 0x4f, 0x34, 0x14, 0x9f, 0xde, 0x14, 0x51, 0x4b, 0x2e, 0x2b, 0x87, 0xe0, 0x47, 0x38, + 0x3c, 0xa4, 0x21, 0x1a, 0xe9, 0x5b, 0xa3, 0x91, 0x66, 0xea, 0xa2, 0x86, 0xc7, 0x9b, 0x44, 0x7f, + 0x9a, 0x33, 0x20, 0x6a, 0x27, 0x60, 0xfa, 0x9b, 0x2c, 0x1e, 0xb9, 0x70, 0x1b, 0x26, 0xcd, 0xaf, + 0x52, 0xaf, 0x5e, 0x52, 0x80, 0x83, 0xb6, 0x0d, 0x07, 0x6d, 0xc2, 0x22, 0x36, 0x8f, 0x45, 0x00, + 0x9a, 0x52, 0xe4, 0x13, 0xf1, 0x93, 0x42, 0xf1, 0xd0, 0x0d, 0x58, 0x1a, 0x11, 0xb3, 0x10, 0x57, + 0xef, 0xf5, 0x8c, 0x5a, 0x97, 0xc2, 0xd1, 0xd0, 0x16, 0x2c, 0xeb, 0x74, 0x9d, 0xc4, 0xfd, 0xba, + 0x9e, 0x92, 0xb5, 0xa5, 0x08, 0x8a, 0x40, 0x44, 0x3b, 0x7e, 0x78, 0x5d, 0xca, 0x8a, 0x8b, 0x63, + 0x4b, 0x91, 0x1a, 0x63, 0xef, 0x45, 0x63, 0x6c, 0xa0, 0xbc, 0xb6, 0xa6, 0xf3, 0x9a, 0x1c, 0x68, + 0x9f, 0x83, 0xe2, 0xd0, 0x1a, 0x30, 0x33, 0x2a, 0xb3, 0xf2, 0xf0, 0xd0, 0x1a, 0x50, 0x2b, 0x5a, + 0x23, 0xd7, 0x0d, 0xdd, 0x30, 0xe9, 0xf1, 0x57, 0x54, 0x58, 0x83, 0x6c, 0x3e, 0xfa, 0x43, 0xb5, + 0xcc, 0x3e, 0xae, 0x57, 0x68, 0x57, 0x89, 0x42, 0x76, 0xcd, 0x3e, 0x8d, 0x4b, 0x3d, 0xef, 0xa4, + 0x5e, 0xa5, 0x70, 0xf2, 0x93, 0xdc, 0x24, 0x59, 0x76, 0x64, 0x35, 0xeb, 0x26, 0x99, 0xe6, 0xdf, + 0x45, 0x72, 0xe4, 0x3e, 0x2c, 0x3f, 0x63, 0x8e, 0xa0, 0x5e, 0xa3, 0xf4, 0x57, 0xa7, 0xbb, 0x17, + 0xce, 0x41, 0x10, 0x7e, 0x97, 0x77, 0x84, 0xbf, 0x93, 0xe0, 0x6c, 0x8b, 0x5e, 0xb4, 0x42, 0x7e, + 0x6c, 0x9e, 0xec, 0xe4, 0x6d, 0x3f, 0x71, 0x9c, 0x99, 0xf1, 0x8b, 0xcf, 0x5b, 0xe4, 0x8d, 0xdb, + 0x50, 0x15, 0xcc, 0x39, 0x8b, 0xfc, 0xcc, 0xb9, 0xe7, 0x8a, 0x1b, 0x6e, 0xca, 0x1f, 0xc0, 0x7a, + 0x62, 0x16, 0xfc, 0xae, 0xb3, 0x01, 0x2b, 0x81, 0xbf, 0xf2, 0x27, 0x51, 0xf6, 0x61, 0x6d, 0x5d, + 0xbe, 0x03, 0x67, 0x7a, 0x9e, 0xe6, 0x78, 0x09, 0x15, 0xcc, 0x40, 0x4b, 0xb3, 0xca, 0x51, 0x5a, + 0x9e, 0xf8, 0xed, 0xc1, 0x5a, 0xcf, 0xb3, 0xec, 0x17, 0x60, 0x4a, 0xbc, 0x0e, 0x99, 0xbf, 0x35, + 0x16, 0xe7, 0x83, 0x68, 0xca, 0xeb, 0x2c, 0x07, 0x9e, 0x1c, 0xed, 0x2e, 0x9c, 0x65, 0x29, 0xe8, + 0x17, 0x99, 0xc4, 0x39, 0x91, 0x00, 0x4f, 0xf2, 0x7d, 0x02, 0xa7, 0x83, 0x63, 0x31, 0x48, 0xee, + 0xdc, 0x8a, 0x26, 0x77, 0x2e, 0x4d, 0x58, 0xf5, 0x48, 0x6e, 0xe7, 0x4f, 0x72, 0x21, 0xbf, 0x9e, + 0x91, 0xda, 0xb9, 0x1b, 0x4d, 0xed, 0xbc, 0x31, 0x8d, 0x77, 0x24, 0xb3, 0x93, 0xb4, 0xda, 0x7c, + 0x8a, 0xd5, 0x7e, 0x9e, 0xc8, 0xff, 0x2c, 0x66, 0x25, 0xd0, 0x62, 0xd2, 0xfe, 0x4a, 0xd2, 0x3f, + 0x0a, 0x4b, 0xff, 0xf8, 0x43, 0xfb, 0x15, 0x83, 0xdb, 0xb1, 0xf4, 0xcf, 0xc6, 0x54, 0x79, 0xfd, + 0xec, 0xcf, 0x5f, 0x2c, 0x42, 0xc9, 0xef, 0x4b, 0xe8, 0x3c, 0xa9, 0xb6, 0x5c, 0x8a, 0xda, 0xc2, + 0x27, 0x70, 0xfe, 0x5b, 0x9d, 0xc0, 0x8b, 0x33, 0x9f, 0xc0, 0xe7, 0xa1, 0x44, 0x7f, 0xa8, 0x0e, + 0x3e, 0xe4, 0x27, 0x6a, 0x91, 0x02, 0x14, 0x7c, 0x18, 0x98, 0xe1, 0xd2, 0x5c, 0x66, 0x18, 0x4b, + 0x38, 0x2d, 0xc7, 0x13, 0x4e, 0x1f, 0xfa, 0x27, 0x22, 0x3b, 0x44, 0xaf, 0x4c, 0xe0, 0x9b, 0x7a, + 0x16, 0x76, 0xa2, 0x67, 0x21, 0x3b, 0x57, 0xdf, 0x9a, 0xc4, 0x65, 0xe2, 0x29, 0xf8, 0x5d, 0x9e, + 0x10, 0xfb, 0x2c, 0x8b, 0x14, 0xb6, 0x45, 0xee, 0x59, 0xef, 0x02, 0xf8, 0x4e, 0x44, 0xa4, 0x92, + 0xce, 0x4f, 0x98, 0xa3, 0x12, 0x42, 0x27, 0x6c, 0x23, 0x4b, 0x13, 0x54, 0xc5, 0x66, 0xf3, 0x8f, + 0x19, 0x25, 0xb1, 0xff, 0x2d, 0x84, 0xfc, 0x4b, 0x46, 0xb5, 0xe7, 0xc3, 0x44, 0xa2, 0x73, 0x4e, + 0x2b, 0xbe, 0x15, 0xcd, 0x73, 0xbe, 0xa0, 0xd5, 0x25, 0xd2, 0x9c, 0x34, 0x72, 0xd1, 0x1c, 0xde, + 0xcd, 0xb2, 0x4b, 0x25, 0x0e, 0x69, 0xd2, 0x9b, 0xc1, 0xa1, 0x61, 0x1a, 0xee, 0x11, 0xeb, 0x5f, + 0x62, 0x37, 0x03, 0x01, 0x6a, 0xd2, 0x67, 0x5e, 0xf8, 0xb9, 0xe1, 0xa9, 0x7d, 0x4b, 0xc7, 0xd4, + 0xa6, 0x0b, 0x4a, 0x91, 0x00, 0x5a, 0x96, 0x8e, 0x83, 0x9d, 0x57, 0x7c, 0xb1, 0x9d, 0x57, 0x8a, + 0xed, 0xbc, 0xb3, 0xb0, 0xe4, 0x60, 0xcd, 0xb5, 0x4c, 0x7e, 0x0f, 0xe7, 0x2d, 0xb2, 0x34, 0x23, + 0xec, 0xba, 0x64, 0x24, 0x1e, 0xae, 0xf1, 0x66, 0x28, 0xcc, 0x5c, 0x99, 0x1a, 0x66, 0x4e, 0xa8, + 0x22, 0xc5, 0xc2, 0xcc, 0xca, 0xd4, 0x30, 0x73, 0xa6, 0x22, 0x52, 0x10, 0x68, 0x57, 0x67, 0x0b, + 0xb4, 0xc3, 0x71, 0xe9, 0x6a, 0x24, 0x2e, 0xfd, 0x2e, 0x37, 0xeb, 0x2f, 0x24, 0x58, 0x4f, 0x6c, + 0x2b, 0xbe, 0x5d, 0x6f, 0xc7, 0xca, 0x4c, 0x1b, 0x53, 0x75, 0xe6, 0x57, 0x99, 0x1e, 0x46, 0xaa, + 0x4c, 0xef, 0x4e, 0x27, 0x7c, 0xe9, 0x45, 0xa6, 0xdf, 0x97, 0xe0, 0xd5, 0x7d, 0x5b, 0x8f, 0x45, + 0x78, 0xfc, 0xda, 0x3f, 0xbb, 0xe3, 0xf8, 0x50, 0xc4, 0xfa, 0xb9, 0x79, 0x13, 0x32, 0x8c, 0x4e, + 0x96, 0xe1, 0x52, 0xb6, 0x18, 0x3c, 0x64, 0xfa, 0x12, 0x56, 0x77, 0x9e, 0xe3, 0x7e, 0xef, 0xc4, + 0xec, 0xcf, 0x21, 0x5a, 0x0d, 0xf2, 0xfd, 0x91, 0xce, 0xd3, 0xa9, 0xe4, 0x67, 0x38, 0x0a, 0xcc, + 0x47, 0xa3, 0x40, 0x15, 0x6a, 0xc1, 0x08, 0x7c, 0x79, 0xcf, 0x92, 0xe5, 0xd5, 0x09, 0x32, 0x61, + 0xbe, 0xa2, 0xf0, 0x16, 0x87, 0x63, 0x87, 0x3d, 0xca, 0x60, 0x70, 0xec, 0x38, 0x51, 0x6f, 0x91, + 0x8f, 0x7a, 0x0b, 0xf9, 0x8f, 0x25, 0x28, 0x93, 0x11, 0xbe, 0x95, 0xfc, 0xfc, 0xaa, 0x95, 0x0f, + 0xae, 0x5a, 0xfe, 0x8d, 0x6d, 0x31, 0x7c, 0x63, 0x0b, 0x24, 0x2f, 0x50, 0x70, 0x52, 0xf2, 0x25, + 0x1f, 0x8e, 0x1d, 0x47, 0xbe, 0x04, 0x2b, 0x4c, 0x36, 0x3e, 0xf3, 0x1a, 0xe4, 0xc7, 0xce, 0x50, + 0xd8, 0xd1, 0xd8, 0x19, 0xca, 0x7f, 0x20, 0x41, 0xa5, 0xe9, 0x79, 0x5a, 0xff, 0x68, 0x8e, 0x09, + 0xf8, 0xc2, 0xe5, 0xc2, 0xc2, 0x25, 0x27, 0x11, 0x88, 0xbb, 0x98, 0x21, 0x6e, 0x21, 0x22, 0xae, + 0x0c, 0x55, 0x21, 0x4b, 0xa6, 0xc0, 0x1d, 0x40, 0x5d, 0xcb, 0xf1, 0x1e, 0x58, 0xce, 0x33, 0xcd, + 0xd1, 0xe7, 0xbb, 0x81, 0x21, 0x58, 0xe4, 0x4f, 0x7f, 0xf3, 0x57, 0x0b, 0x0a, 0xfd, 0x2d, 0x5f, + 0x81, 0xd3, 0x11, 0x7e, 0x99, 0x03, 0x7f, 0x04, 0x65, 0xea, 0xf7, 0x79, 0x28, 0x7e, 0x33, 0x5c, + 0xd7, 0x99, 0xe9, 0x94, 0x90, 0x7f, 0x13, 0x4e, 0x91, 0xf8, 0x80, 0xc2, 0xfd, 0xad, 0xf8, 0xbd, + 0x58, 0x9c, 0x7a, 0x21, 0x83, 0x51, 0x2c, 0x46, 0xfd, 0x4b, 0x09, 0x0a, 0x14, 0x9e, 0x38, 0xb3, + 0xcf, 0x43, 0xc9, 0xc1, 0xb6, 0xa5, 0x7a, 0xda, 0xc0, 0x7f, 0x68, 0x4d, 0x00, 0x7b, 0xda, 0x80, + 0x66, 0x73, 0x69, 0xa7, 0x6e, 0x0c, 0xb0, 0xeb, 0x89, 0xd7, 0xd6, 0x65, 0x02, 0xdb, 0x66, 0x20, + 0xa2, 0x24, 0xd7, 0xf8, 0x1d, 0x16, 0x77, 0x2e, 0x2a, 0xf4, 0x37, 0xda, 0x64, 0xcf, 0xf8, 0x66, + 0xc9, 0xbd, 0xd3, 0x47, 0x7e, 0x0d, 0x28, 0xc6, 0xd2, 0xe5, 0x7e, 0x5b, 0xde, 0x01, 0x14, 0xd6, + 0x02, 0xd7, 0xf7, 0x0d, 0x58, 0xa2, 0x4a, 0x12, 0xd1, 0xd1, 0x7a, 0x86, 0x1a, 0x14, 0x8e, 0x26, + 0x6b, 0x80, 0x98, 0x82, 0x23, 0x11, 0xd1, 0xfc, 0xab, 0x32, 0x21, 0x42, 0xfa, 0x5b, 0x09, 0x4e, + 0x47, 0xc6, 0xe0, 0xb2, 0xbe, 0x1d, 0x1d, 0x24, 0x53, 0x54, 0x3e, 0x40, 0x2b, 0x72, 0x24, 0xdc, + 0xc8, 0x12, 0xe9, 0x97, 0x74, 0x1c, 0xfc, 0xbd, 0x04, 0xd0, 0x1c, 0x7b, 0x47, 0x3c, 0x33, 0x18, + 0x5e, 0x19, 0x29, 0xba, 0x32, 0xa4, 0xcf, 0xd6, 0x5c, 0xf7, 0x99, 0xe5, 0x88, 0x3b, 0x8d, 0xdf, + 0xa6, 0x39, 0xbc, 0xb1, 0x77, 0x24, 0x6a, 0x66, 0xe4, 0x37, 0x7a, 0x03, 0xaa, 0xec, 0x71, 0xbf, + 0xaa, 0xe9, 0xba, 0x83, 0x5d, 0x97, 0x17, 0xcf, 0x2a, 0x0c, 0xda, 0x64, 0x40, 0x82, 0x66, 0xd0, + 0xac, 0xb6, 0x77, 0xa2, 0x7a, 0xd6, 0x53, 0x6c, 0xf2, 0xbb, 0x49, 0x45, 0x40, 0xf7, 0x08, 0x90, + 0x55, 0x11, 0x06, 0x86, 0xeb, 0x39, 0x02, 0x4d, 0x14, 0x5a, 0x38, 0x94, 0xa2, 0x91, 0x45, 0xa9, + 0x75, 0xc7, 0xc3, 0x21, 0x53, 0xf1, 0x8b, 0x2f, 0xfb, 0x3b, 0x7c, 0x42, 0xb9, 0x2c, 0x9b, 0x0e, + 0x94, 0xc6, 0xa7, 0xfb, 0x12, 0x93, 0x30, 0xef, 0xc0, 0xa9, 0xd0, 0x1c, 0xb8, 0x59, 0x45, 0x82, + 0x48, 0x29, 0x1a, 0x44, 0xca, 0x0f, 0x01, 0xb1, 0xbc, 0xc3, 0xb7, 0x9c, 0xb7, 0x7c, 0x06, 0x4e, + 0x47, 0x18, 0xf1, 0x93, 0xf8, 0x3a, 0x54, 0xf8, 0x93, 0x28, 0x6e, 0x28, 0xe7, 0xa0, 0x48, 0x3c, + 0x6a, 0xdf, 0xd0, 0x45, 0x41, 0x75, 0xd9, 0xb6, 0xf4, 0x96, 0xa1, 0x3b, 0xf2, 0x27, 0x50, 0x51, + 0xd8, 0x38, 0x1c, 0xf7, 0x01, 0x54, 0xf9, 0x03, 0x2a, 0x35, 0xf2, 0x34, 0x32, 0xed, 0xed, 0x7d, + 0x78, 0x10, 0xa5, 0x62, 0x86, 0x9b, 0xb2, 0x0e, 0x0d, 0x16, 0x32, 0x44, 0xd8, 0x8b, 0xc9, 0x3e, + 0x00, 0xf1, 0x62, 0x60, 0xea, 0x28, 0x51, 0xfa, 0x8a, 0x13, 0x6e, 0xca, 0x17, 0xe0, 0x7c, 0xea, + 0x28, 0x5c, 0x13, 0x36, 0xd4, 0x82, 0x0e, 0xf6, 0x7e, 0xcf, 0xaf, 0x18, 0x4b, 0xa1, 0x8a, 0xf1, + 0x59, 0x3f, 0x48, 0xcc, 0x89, 0x43, 0x8c, 0x46, 0x80, 0x41, 0xb8, 0x9f, 0xcf, 0x0a, 0xf7, 0x17, + 0x23, 0xe1, 0xbe, 0xdc, 0xf3, 0xf5, 0xc9, 0xaf, 0x61, 0xf7, 0xe9, 0x75, 0x91, 0x8d, 0x2d, 0x1c, + 0xa2, 0x3c, 0x69, 0x96, 0x0c, 0x55, 0x09, 0x51, 0xc9, 0xd7, 0xa0, 0x12, 0x75, 0x8d, 0x21, 0x3f, + 0x27, 0x25, 0xfc, 0x5c, 0x35, 0xe6, 0xe2, 0xde, 0x8f, 0x45, 0xc0, 0xd9, 0x3a, 0x8e, 0xc5, 0xbf, + 0xf7, 0x22, 0xce, 0xee, 0x7a, 0x4a, 0xb1, 0xf7, 0x97, 0xe4, 0xe7, 0xbe, 0x84, 0x2a, 0x0d, 0x48, + 0xdb, 0xdb, 0xe2, 0x53, 0xa1, 0xb4, 0x40, 0xa6, 0x12, 0x0d, 0x64, 0xfc, 0x2f, 0x7a, 0x74, 0x5e, + 0xc5, 0x61, 0x5f, 0xf4, 0xe8, 0xfe, 0x21, 0x98, 0xa7, 0x50, 0xfa, 0x5b, 0xfe, 0x53, 0x09, 0xea, + 0x74, 0x88, 0x7d, 0x17, 0x3b, 0x7e, 0x05, 0x9c, 0x6f, 0x81, 0x16, 0xac, 0x8c, 0x0d, 0x3d, 0x78, + 0xc9, 0xcd, 0x16, 0xed, 0x52, 0x46, 0xd4, 0xec, 0x0b, 0xa9, 0x94, 0xc7, 0x86, 0xee, 0xbf, 0xe5, + 0x6e, 0xc1, 0xca, 0x20, 0xcc, 0x24, 0x37, 0x2b, 0x93, 0x41, 0xc0, 0x44, 0x1e, 0xc3, 0xe9, 0x66, + 0xdf, 0x33, 0x8e, 0xa3, 0xe6, 0x8d, 0x7e, 0x1b, 0xce, 0x10, 0x47, 0xaf, 0x06, 0x55, 0xfe, 0xc8, + 0x26, 0xba, 0x9e, 0x31, 0x48, 0xca, 0x5c, 0x95, 0xd3, 0xe3, 0x24, 0x90, 0xec, 0xaa, 0x87, 0xd8, + 0x8b, 0x8c, 0x49, 0x16, 0x92, 0x5b, 0x9f, 0x3c, 0x84, 0x57, 0xd2, 0xbb, 0xb9, 0xc1, 0x3d, 0xce, + 0xd8, 0xdc, 0x29, 0x29, 0xcd, 0x94, 0xd9, 0xc5, 0xb7, 0xf8, 0x1a, 0x0f, 0x0e, 0x1e, 0xb8, 0x61, + 0x19, 0x5e, 0x83, 0xf2, 0x7e, 0xd6, 0x47, 0x3e, 0x8b, 0xe2, 0x95, 0xcd, 0x2d, 0x58, 0x7b, 0x60, + 0x0c, 0xb1, 0x7b, 0xe2, 0x7a, 0x78, 0xd4, 0xa6, 0x27, 0xd4, 0xa1, 0x81, 0x1d, 0x74, 0x11, 0x80, + 0xde, 0x67, 0x6d, 0xcb, 0xf0, 0xbf, 0xfd, 0x08, 0x41, 0xe4, 0xff, 0x94, 0x60, 0x35, 0x20, 0xdc, + 0xa7, 0xf7, 0xf8, 0x57, 0xa0, 0x44, 0x84, 0x72, 0x3d, 0x6d, 0x64, 0x8b, 0xe2, 0xa6, 0x0f, 0x40, + 0x77, 0xa1, 0x70, 0xe8, 0x0a, 0xd3, 0x4b, 0xad, 0xa6, 0xa4, 0x09, 0xa2, 0x2c, 0x1e, 0xba, 0x6d, + 0x1d, 0x7d, 0x00, 0x30, 0x76, 0xb1, 0xce, 0x0b, 0x9a, 0xf9, 0xac, 0xd0, 0x71, 0x3f, 0xfc, 0x2a, + 0x82, 0x10, 0xb0, 0x07, 0x3a, 0xf7, 0xa0, 0x6c, 0x98, 0x96, 0x8e, 0x69, 0xa5, 0x5a, 0xe7, 0x29, + 0xc6, 0x29, 0xe4, 0xc0, 0x28, 0xf6, 0x5d, 0xac, 0xcb, 0x98, 0x07, 0x46, 0x42, 0xbf, 0x7c, 0x11, + 0x3b, 0x70, 0x8a, 0x9d, 0x60, 0x87, 0xbe, 0xe0, 0x62, 0x27, 0x6c, 0x4c, 0x9a, 0x1d, 0xd5, 0x96, + 0x52, 0x33, 0x78, 0x9c, 0x2b, 0x48, 0xe5, 0x3b, 0x70, 0x26, 0x72, 0x5d, 0x9e, 0xe3, 0xfe, 0x2a, + 0x77, 0x63, 0x59, 0xb3, 0xc0, 0xb7, 0xf1, 0x9c, 0x94, 0x70, 0x6d, 0xd3, 0x72, 0x52, 0x2e, 0xcb, + 0x49, 0xb9, 0xf2, 0xe7, 0x70, 0x2e, 0x92, 0xde, 0x8b, 0x48, 0x74, 0x2f, 0x16, 0xc6, 0x5f, 0x9e, + 0xc6, 0x35, 0x16, 0xcf, 0xff, 0x8f, 0x04, 0x6b, 0x69, 0x08, 0x2f, 0x98, 0x7e, 0xfe, 0x32, 0xe3, + 0xd5, 0xe6, 0xed, 0xd9, 0xc4, 0xfa, 0x95, 0xa4, 0xee, 0xf7, 0xa0, 0x91, 0xa6, 0xcf, 0xe4, 0x2a, + 0xe5, 0xe7, 0x59, 0xa5, 0x9f, 0xe6, 0x43, 0x65, 0x98, 0xa6, 0xe7, 0x39, 0xc6, 0xc1, 0x98, 0x98, + 0xfc, 0x4b, 0x4f, 0x6d, 0xb6, 0xfd, 0x24, 0x1d, 0x53, 0xed, 0xcd, 0x09, 0xe4, 0x81, 0x1c, 0xa9, + 0x89, 0xba, 0x4f, 0xa3, 0x89, 0x3a, 0x56, 0x60, 0xb9, 0x35, 0x1b, 0xbf, 0x5f, 0xdb, 0x6c, 0xf8, + 0x4f, 0x73, 0x50, 0x8d, 0x2e, 0x11, 0xda, 0x01, 0xd0, 0x7c, 0xc9, 0xb3, 0x1d, 0x7c, 0xca, 0x34, + 0x95, 0x10, 0x21, 0x7a, 0x0b, 0xf2, 0x7d, 0x7b, 0xcc, 0x57, 0x2d, 0xe5, 0x65, 0x40, 0xcb, 0x1e, + 0x33, 0x8f, 0x42, 0xd0, 0xc8, 0x05, 0x9b, 0x3d, 0xf4, 0xc8, 0xf6, 0x92, 0x4f, 0x68, 0x3f, 0xa3, + 0xe1, 0xc8, 0xe8, 0x11, 0x54, 0x9f, 0x39, 0x86, 0xa7, 0x1d, 0x0c, 0xb1, 0x3a, 0xd4, 0x4e, 0xf8, + 0xf7, 0xa4, 0x33, 0x39, 0xb2, 0x8a, 0x20, 0x7c, 0x4c, 0xe8, 0xe4, 0xdf, 0x83, 0xa2, 0x90, 0x68, + 0xca, 0x89, 0xb0, 0x07, 0xeb, 0x63, 0x82, 0xa6, 0xd2, 0x87, 0x93, 0xa6, 0x66, 0x5a, 0xaa, 0x8b, + 0x49, 0x4c, 0x27, 0x3e, 0x12, 0x99, 0xe2, 0xa2, 0xd7, 0x28, 0x75, 0xcb, 0x72, 0x70, 0x47, 0x33, + 0xad, 0x1e, 0x23, 0x95, 0x8f, 0xa1, 0x1c, 0x9a, 0xe0, 0x14, 0x11, 0xda, 0x70, 0x4a, 0xbc, 0xcb, + 0x70, 0xb1, 0xc7, 0x8f, 0x97, 0x99, 0x06, 0x5f, 0xe5, 0x74, 0x3d, 0xec, 0xb1, 0xb7, 0x34, 0xf7, + 0xe0, 0x9c, 0x82, 0x2d, 0x1b, 0x9b, 0xfe, 0x7a, 0x3e, 0xb6, 0x06, 0x73, 0x78, 0xf0, 0x57, 0xa0, + 0x91, 0x46, 0xcf, 0xfc, 0xc3, 0xf5, 0xcb, 0x50, 0x14, 0x9f, 0x79, 0xa3, 0x65, 0xc8, 0xef, 0xb5, + 0xba, 0xb5, 0x05, 0xf2, 0x63, 0x7f, 0xbb, 0x5b, 0x93, 0x50, 0x11, 0x16, 0x7b, 0xad, 0xbd, 0x6e, + 0x2d, 0x77, 0x7d, 0x04, 0xb5, 0xf8, 0x37, 0xce, 0x68, 0x1d, 0x4e, 0x77, 0x95, 0xdd, 0x6e, 0xf3, + 0x61, 0x73, 0xaf, 0xbd, 0xdb, 0x51, 0xbb, 0x4a, 0xfb, 0xe3, 0xe6, 0xde, 0x4e, 0x6d, 0x01, 0x6d, + 0xc0, 0x85, 0x70, 0xc7, 0xa3, 0xdd, 0xde, 0x9e, 0xba, 0xb7, 0xab, 0xb6, 0x76, 0x3b, 0x7b, 0xcd, + 0x76, 0x67, 0x47, 0xa9, 0x49, 0xe8, 0x02, 0x9c, 0x0b, 0xa3, 0xdc, 0x6f, 0x6f, 0xb7, 0x95, 0x9d, + 0x16, 0xf9, 0xdd, 0x7c, 0x5c, 0xcb, 0x5d, 0x6f, 0x43, 0x25, 0xf2, 0x79, 0x31, 0x11, 0xa9, 0xbb, + 0xbb, 0x5d, 0x5b, 0x40, 0x15, 0x28, 0x85, 0xf9, 0x14, 0x61, 0xb1, 0xb3, 0xbb, 0xbd, 0x53, 0xcb, + 0xa1, 0xb3, 0x80, 0xc8, 0x2f, 0xf5, 0x93, 0xf6, 0xf6, 0x8e, 0xaa, 0xec, 0x3c, 0x69, 0x76, 0xbb, + 0x3b, 0xdb, 0xb5, 0xfc, 0xf5, 0x3b, 0xb0, 0x1a, 0x7b, 0x04, 0x8e, 0x4e, 0x41, 0xa5, 0xd7, 0xec, + 0x6c, 0xdf, 0xdf, 0xfd, 0x54, 0x55, 0x76, 0x9a, 0xdb, 0x9f, 0xd5, 0x16, 0xd0, 0x1a, 0xd4, 0x04, + 0xa8, 0xb3, 0xbb, 0xc7, 0xa0, 0xd2, 0xf5, 0xa7, 0xb1, 0xbd, 0x87, 0xd1, 0x19, 0x38, 0xe5, 0x0f, + 0xaf, 0xb6, 0x94, 0x9d, 0xe6, 0xde, 0x0e, 0x91, 0x2a, 0x02, 0x56, 0xf6, 0x3b, 0x9d, 0x76, 0xe7, + 0x61, 0x4d, 0x22, 0x5c, 0x03, 0xf0, 0xce, 0xa7, 0x6d, 0x82, 0x9c, 0x8b, 0x22, 0xef, 0x77, 0x7e, + 0xd0, 0xd9, 0xfd, 0xa4, 0x53, 0xcb, 0x6f, 0xfd, 0x15, 0x82, 0xaa, 0xb8, 0x0d, 0x60, 0x87, 0x3e, + 0x7d, 0xea, 0xc2, 0xb2, 0xf8, 0x77, 0x02, 0x29, 0x9e, 0x3b, 0xfa, 0x4f, 0x10, 0x1a, 0x1b, 0x13, + 0x30, 0xf8, 0xa5, 0x6c, 0x01, 0x1d, 0xd0, 0x4b, 0x52, 0xe8, 0x51, 0xfe, 0xe5, 0xd4, 0x2b, 0x49, + 0xe2, 0x3b, 0x80, 0xc6, 0x95, 0xa9, 0x78, 0xfe, 0x18, 0x98, 0xdc, 0x83, 0xc2, 0xdf, 0xbd, 0xa1, + 0x2b, 0x69, 0x17, 0x98, 0x94, 0x0f, 0xeb, 0x1a, 0x57, 0xa7, 0x23, 0xfa, 0xc3, 0x3c, 0x85, 0x5a, + 0xfc, 0x1b, 0x38, 0x94, 0x92, 0x5f, 0xcf, 0xf8, 0xd0, 0xae, 0x71, 0x7d, 0x16, 0xd4, 0xf0, 0x60, + 0x89, 0x8f, 0xba, 0xae, 0xcd, 0xf2, 0xf1, 0x4b, 0xe6, 0x60, 0x59, 0xdf, 0xc9, 0x30, 0x05, 0x46, + 0xdf, 0xd1, 0xa3, 0xd4, 0x2f, 0xa8, 0x52, 0x3e, 0xd7, 0x48, 0x53, 0x60, 0xfa, 0x93, 0x7c, 0x79, + 0x01, 0x1d, 0xc1, 0x6a, 0xec, 0x0d, 0x0b, 0x4a, 0x21, 0x4f, 0x7f, 0xac, 0xd3, 0xb8, 0x36, 0x03, + 0x66, 0xd4, 0x22, 0xc2, 0x6f, 0x56, 0xd2, 0x2d, 0x22, 0xe5, 0x45, 0x4c, 0xba, 0x45, 0xa4, 0x3e, + 0x7f, 0xa1, 0xc6, 0x1d, 0x79, 0xab, 0x92, 0x66, 0xdc, 0x69, 0x2f, 0x64, 0x1a, 0x57, 0xa6, 0xe2, + 0x85, 0x95, 0x16, 0x7b, 0xb9, 0x92, 0xa6, 0xb4, 0xf4, 0x97, 0x31, 0x8d, 0x6b, 0x33, 0x60, 0xc6, + 0xad, 0x20, 0xa8, 0x83, 0x67, 0x59, 0x41, 0xe2, 0xd5, 0x46, 0x96, 0x15, 0x24, 0x4b, 0xea, 0xdc, + 0x0a, 0x62, 0xf5, 0xeb, 0xab, 0x33, 0xd4, 0xdb, 0xb2, 0xad, 0x20, 0xbd, 0x32, 0x27, 0x2f, 0xa0, + 0x9f, 0x48, 0x50, 0xcf, 0xaa, 0x65, 0xa1, 0x94, 0xb8, 0x6f, 0x4a, 0xf9, 0xad, 0xb1, 0x35, 0x0f, + 0x89, 0x2f, 0xc5, 0x57, 0x80, 0x92, 0xe7, 0x21, 0x7a, 0x33, 0x6d, 0x65, 0x32, 0x4e, 0xdd, 0xc6, + 0x5b, 0xb3, 0x21, 0xfb, 0x43, 0xf6, 0xa0, 0x28, 0xaa, 0x67, 0x28, 0xc5, 0x4b, 0xc7, 0x6a, 0x77, + 0x0d, 0x79, 0x12, 0x8a, 0xcf, 0xf4, 0x21, 0x2c, 0x12, 0x28, 0xba, 0x90, 0x8e, 0x2d, 0x98, 0x5d, + 0xcc, 0xea, 0xf6, 0x19, 0x3d, 0x81, 0x25, 0x56, 0x2e, 0x42, 0x29, 0xe9, 0xa9, 0x48, 0x51, 0xab, + 0x71, 0x29, 0x1b, 0xc1, 0x67, 0xf7, 0x05, 0xfb, 0x4f, 0x33, 0xbc, 0x12, 0x84, 0x5e, 0x4f, 0xff, + 0x0a, 0x3f, 0x5a, 0x78, 0x6a, 0xbc, 0x31, 0x05, 0x2b, 0xbc, 0x29, 0x62, 0xd1, 0xf0, 0x95, 0xa9, + 0x57, 0x9a, 0xec, 0x4d, 0x91, 0x7e, 0x69, 0x62, 0x46, 0x92, 0xbc, 0x54, 0xa5, 0x19, 0x49, 0xe6, + 0x55, 0x36, 0xcd, 0x48, 0xb2, 0xef, 0x69, 0xf2, 0x02, 0xf2, 0xe0, 0x74, 0x4a, 0x3e, 0x15, 0xbd, + 0x95, 0x65, 0xe4, 0x69, 0xc9, 0xdd, 0xc6, 0xdb, 0x33, 0x62, 0x87, 0x17, 0x9f, 0x6f, 0xfa, 0x57, + 0xb3, 0x93, 0x8c, 0x99, 0x8b, 0x9f, 0xd8, 0xe2, 0xcf, 0x60, 0x2d, 0x2d, 0x3f, 0x85, 0x52, 0xe4, + 0x9a, 0x90, 0xe6, 0x6a, 0x6c, 0xce, 0x8a, 0x2e, 0x06, 0xde, 0xfa, 0xe7, 0x3c, 0xac, 0xb0, 0x24, + 0x3d, 0x0f, 0x9d, 0x3e, 0x03, 0x08, 0xea, 0x63, 0xe8, 0xb5, 0xf4, 0xc5, 0x88, 0xd4, 0x10, 0x1b, + 0xaf, 0x4f, 0x46, 0x0a, 0x5b, 0x78, 0xa8, 0xd6, 0x94, 0x66, 0xe1, 0xc9, 0x92, 0x5a, 0x9a, 0x85, + 0xa7, 0x14, 0xac, 0xe4, 0x05, 0xf4, 0x31, 0x94, 0xfc, 0xa2, 0x06, 0x4a, 0x2b, 0x8a, 0xc4, 0xaa, + 0x36, 0x8d, 0xd7, 0x26, 0xe2, 0x84, 0xa5, 0x0e, 0x55, 0x2c, 0xd2, 0xa4, 0x4e, 0x56, 0x46, 0xd2, + 0xa4, 0x4e, 0x2b, 0x7b, 0x04, 0x3a, 0x61, 0xa9, 0xac, 0x4c, 0x9d, 0x44, 0x32, 0x89, 0x99, 0x3a, + 0x89, 0xe6, 0xc3, 0xe4, 0x85, 0xfb, 0x97, 0x7f, 0xfe, 0xf5, 0x45, 0xe9, 0x1f, 0xbf, 0xbe, 0xb8, + 0xf0, 0xe3, 0x6f, 0x2e, 0x4a, 0x3f, 0xff, 0xe6, 0xa2, 0xf4, 0x0f, 0xdf, 0x5c, 0x94, 0xfe, 0xe5, + 0x9b, 0x8b, 0xd2, 0x1f, 0xfd, 0xeb, 0xc5, 0x85, 0x1f, 0x16, 0x05, 0xf5, 0xc1, 0x12, 0xfd, 0x47, + 0x55, 0xef, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3a, 0xef, 0x21, 0x95, 0x6e, 0x4c, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -7226,6 +7519,8 @@ type RuntimeServiceClient interface { UpdateRuntimeConfig(ctx context.Context, in *UpdateRuntimeConfigRequest, opts ...grpc.CallOption) (*UpdateRuntimeConfigResponse, error) // Status returns the status of the runtime. Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) + // GetRuntimeConfigInfo returns the configuration details of the runtime. + GetRuntimeConfigInfo(ctx context.Context, in *GetRuntimeConfigInfoRequest, opts ...grpc.CallOption) (*GetRuntimeConfigInfoResponse, error) } type runtimeServiceClient struct { @@ -7434,6 +7729,15 @@ func (c *runtimeServiceClient) Status(ctx context.Context, in *StatusRequest, op return out, nil } +func (c *runtimeServiceClient) GetRuntimeConfigInfo(ctx context.Context, in *GetRuntimeConfigInfoRequest, opts ...grpc.CallOption) (*GetRuntimeConfigInfoResponse, error) { + out := new(GetRuntimeConfigInfoResponse) + err := c.cc.Invoke(ctx, "/runtime.v1alpha2.RuntimeService/GetRuntimeConfigInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RuntimeServiceServer is the server API for RuntimeService service. type RuntimeServiceServer interface { // Version returns the runtime name, runtime version, and runtime API version. @@ -7505,6 +7809,8 @@ type RuntimeServiceServer interface { UpdateRuntimeConfig(context.Context, *UpdateRuntimeConfigRequest) (*UpdateRuntimeConfigResponse, error) // Status returns the status of the runtime. Status(context.Context, *StatusRequest) (*StatusResponse, error) + // GetRuntimeConfigInfo returns the configuration details of the runtime. + GetRuntimeConfigInfo(context.Context, *GetRuntimeConfigInfoRequest) (*GetRuntimeConfigInfoResponse, error) } // UnimplementedRuntimeServiceServer can be embedded to have forward compatible implementations. @@ -7577,6 +7883,9 @@ func (*UnimplementedRuntimeServiceServer) UpdateRuntimeConfig(ctx context.Contex func (*UnimplementedRuntimeServiceServer) Status(ctx context.Context, req *StatusRequest) (*StatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") } +func (*UnimplementedRuntimeServiceServer) GetRuntimeConfigInfo(ctx context.Context, req *GetRuntimeConfigInfoRequest) (*GetRuntimeConfigInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRuntimeConfigInfo not implemented") +} func RegisterRuntimeServiceServer(s *grpc.Server, srv RuntimeServiceServer) { s.RegisterService(&_RuntimeService_serviceDesc, srv) @@ -7978,6 +8287,24 @@ func _RuntimeService_Status_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _RuntimeService_GetRuntimeConfigInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRuntimeConfigInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RuntimeServiceServer).GetRuntimeConfigInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/runtime.v1alpha2.RuntimeService/GetRuntimeConfigInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RuntimeServiceServer).GetRuntimeConfigInfo(ctx, req.(*GetRuntimeConfigInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _RuntimeService_serviceDesc = grpc.ServiceDesc{ ServiceName: "runtime.v1alpha2.RuntimeService", HandlerType: (*RuntimeServiceServer)(nil), @@ -8070,6 +8397,10 @@ var _RuntimeService_serviceDesc = grpc.ServiceDesc{ MethodName: "Status", Handler: _RuntimeService_Status_Handler, }, + { + MethodName: "GetRuntimeConfigInfo", + Handler: _RuntimeService_GetRuntimeConfigInfo_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api.proto", @@ -8567,6 +8898,11 @@ func (m *NamespaceOption) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.User != 0 { + i = encodeVarintApi(dAtA, i, uint64(m.User)) + i-- + dAtA[i] = 0x20 + } if m.Ipc != 0 { i = encodeVarintApi(dAtA, i, uint64(m.Ipc)) i-- @@ -12635,7 +12971,7 @@ func (m *StatusResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ImageFsInfoRequest) Marshal() (dAtA []byte, err error) { +func (m *LinuxIDMapping) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -12645,20 +12981,35 @@ func (m *ImageFsInfoRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ImageFsInfoRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *LinuxIDMapping) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ImageFsInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *LinuxIDMapping) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l + if m.Size_ != 0 { + i = encodeVarintApi(dAtA, i, uint64(m.Size_)) + i-- + dAtA[i] = 0x18 + } + if m.HostId != 0 { + i = encodeVarintApi(dAtA, i, uint64(m.HostId)) + i-- + dAtA[i] = 0x10 + } + if m.ContainerId != 0 { + i = encodeVarintApi(dAtA, i, uint64(m.ContainerId)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } -func (m *UInt64Value) Marshal() (dAtA []byte, err error) { +func (m *LinuxUserNamespaceConfig) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -12668,25 +13019,48 @@ func (m *UInt64Value) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *UInt64Value) MarshalTo(dAtA []byte) (int, error) { +func (m *LinuxUserNamespaceConfig) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *UInt64Value) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *LinuxUserNamespaceConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Value != 0 { - i = encodeVarintApi(dAtA, i, uint64(m.Value)) - i-- - dAtA[i] = 0x8 + if len(m.GidMappings) > 0 { + for iNdEx := len(m.GidMappings) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.GidMappings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.UidMappings) > 0 { + for iNdEx := len(m.UidMappings) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.UidMappings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } } return len(dAtA) - i, nil } -func (m *FilesystemIdentifier) Marshal() (dAtA []byte, err error) { +func (m *ActiveRuntimeConfig) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -12696,7 +13070,151 @@ func (m *FilesystemIdentifier) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *FilesystemIdentifier) MarshalTo(dAtA []byte) (int, error) { +func (m *ActiveRuntimeConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ActiveRuntimeConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UserNamespaceConfig != nil { + { + size, err := m.UserNamespaceConfig.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetRuntimeConfigInfoRequest) 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 *GetRuntimeConfigInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetRuntimeConfigInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *GetRuntimeConfigInfoResponse) 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 *GetRuntimeConfigInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetRuntimeConfigInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RuntimeConfig != nil { + { + size, err := m.RuntimeConfig.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ImageFsInfoRequest) 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 *ImageFsInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ImageFsInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *UInt64Value) 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 *UInt64Value) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UInt64Value) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Value != 0 { + i = encodeVarintApi(dAtA, i, uint64(m.Value)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *FilesystemIdentifier) 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 *FilesystemIdentifier) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } @@ -13433,6 +13951,9 @@ func (m *NamespaceOption) Size() (n int) { if m.Ipc != 0 { n += 1 + sovApi(uint64(m.Ipc)) } + if m.User != 0 { + n += 1 + sovApi(uint64(m.User)) + } return n } @@ -15132,6 +15653,80 @@ func (m *StatusResponse) Size() (n int) { return n } +func (m *LinuxIDMapping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ContainerId != 0 { + n += 1 + sovApi(uint64(m.ContainerId)) + } + if m.HostId != 0 { + n += 1 + sovApi(uint64(m.HostId)) + } + if m.Size_ != 0 { + n += 1 + sovApi(uint64(m.Size_)) + } + return n +} + +func (m *LinuxUserNamespaceConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.UidMappings) > 0 { + for _, e := range m.UidMappings { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } + if len(m.GidMappings) > 0 { + for _, e := range m.GidMappings { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } + return n +} + +func (m *ActiveRuntimeConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UserNamespaceConfig != nil { + l = m.UserNamespaceConfig.Size() + n += 1 + l + sovApi(uint64(l)) + } + return n +} + +func (m *GetRuntimeConfigInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *GetRuntimeConfigInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RuntimeConfig != nil { + l = m.RuntimeConfig.Size() + n += 1 + l + sovApi(uint64(l)) + } + return n +} + func (m *ImageFsInfoRequest) Size() (n int) { if m == nil { return 0 @@ -15472,6 +16067,7 @@ func (this *NamespaceOption) String() string { `Network:` + fmt.Sprintf("%v", this.Network) + `,`, `Pid:` + fmt.Sprintf("%v", this.Pid) + `,`, `Ipc:` + fmt.Sprintf("%v", this.Ipc) + `,`, + `User:` + fmt.Sprintf("%v", this.User) + `,`, `}`, }, "") return s @@ -16668,6 +17264,68 @@ func (this *StatusResponse) String() string { }, "") return s } +func (this *LinuxIDMapping) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LinuxIDMapping{`, + `ContainerId:` + fmt.Sprintf("%v", this.ContainerId) + `,`, + `HostId:` + fmt.Sprintf("%v", this.HostId) + `,`, + `Size_:` + fmt.Sprintf("%v", this.Size_) + `,`, + `}`, + }, "") + return s +} +func (this *LinuxUserNamespaceConfig) String() string { + if this == nil { + return "nil" + } + repeatedStringForUidMappings := "[]*LinuxIDMapping{" + for _, f := range this.UidMappings { + repeatedStringForUidMappings += strings.Replace(f.String(), "LinuxIDMapping", "LinuxIDMapping", 1) + "," + } + repeatedStringForUidMappings += "}" + repeatedStringForGidMappings := "[]*LinuxIDMapping{" + for _, f := range this.GidMappings { + repeatedStringForGidMappings += strings.Replace(f.String(), "LinuxIDMapping", "LinuxIDMapping", 1) + "," + } + repeatedStringForGidMappings += "}" + s := strings.Join([]string{`&LinuxUserNamespaceConfig{`, + `UidMappings:` + repeatedStringForUidMappings + `,`, + `GidMappings:` + repeatedStringForGidMappings + `,`, + `}`, + }, "") + return s +} +func (this *ActiveRuntimeConfig) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ActiveRuntimeConfig{`, + `UserNamespaceConfig:` + strings.Replace(this.UserNamespaceConfig.String(), "LinuxUserNamespaceConfig", "LinuxUserNamespaceConfig", 1) + `,`, + `}`, + }, "") + return s +} +func (this *GetRuntimeConfigInfoRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GetRuntimeConfigInfoRequest{`, + `}`, + }, "") + return s +} +func (this *GetRuntimeConfigInfoResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GetRuntimeConfigInfoResponse{`, + `RuntimeConfig:` + strings.Replace(this.RuntimeConfig.String(), "ActiveRuntimeConfig", "ActiveRuntimeConfig", 1) + `,`, + `}`, + }, "") + return s +} func (this *ImageFsInfoRequest) String() string { if this == nil { return "nil" @@ -17706,6 +18364,25 @@ func (m *NamespaceOption) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + m.User = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.User |= NamespaceMode(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -30703,6 +31380,468 @@ func (m *StatusResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *LinuxIDMapping) 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 ErrIntOverflowApi + } + 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: LinuxIDMapping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LinuxIDMapping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerId", wireType) + } + m.ContainerId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ContainerId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HostId", wireType) + } + m.HostId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HostId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType) + } + m.Size_ = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Size_ |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LinuxUserNamespaceConfig) 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 ErrIntOverflowApi + } + 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: LinuxUserNamespaceConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LinuxUserNamespaceConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UidMappings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UidMappings = append(m.UidMappings, &LinuxIDMapping{}) + if err := m.UidMappings[len(m.UidMappings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GidMappings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GidMappings = append(m.GidMappings, &LinuxIDMapping{}) + if err := m.GidMappings[len(m.GidMappings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ActiveRuntimeConfig) 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 ErrIntOverflowApi + } + 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: ActiveRuntimeConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ActiveRuntimeConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserNamespaceConfig", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UserNamespaceConfig == nil { + m.UserNamespaceConfig = &LinuxUserNamespaceConfig{} + } + if err := m.UserNamespaceConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetRuntimeConfigInfoRequest) 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 ErrIntOverflowApi + } + 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: GetRuntimeConfigInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetRuntimeConfigInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetRuntimeConfigInfoResponse) 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 ErrIntOverflowApi + } + 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: GetRuntimeConfigInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetRuntimeConfigInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RuntimeConfig", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RuntimeConfig == nil { + m.RuntimeConfig = &ActiveRuntimeConfig{} + } + if err := m.RuntimeConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ImageFsInfoRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto index 0290d0f240f98..70790f7d7c107 100644 --- a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto +++ b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto @@ -107,6 +107,9 @@ service RuntimeService { // Status returns the status of the runtime. rpc Status(StatusRequest) returns (StatusResponse) {} + + // GetRuntimeConfigInfo returns the configuration details of the runtime. + rpc GetRuntimeConfigInfo(GetRuntimeConfigInfoRequest) returns (GetRuntimeConfigInfoResponse) {} } // ImageService defines the public APIs for managing images. @@ -216,6 +219,14 @@ enum NamespaceMode { // For example, a container with a PID namespace of NODE expects to view // all of the processes on the host running the kubelet. NODE = 2; + // A NODE_WIDE_REMAPPED namespace applies to all pods on a given kubernetes node. + // The uid/gids of the pods/containers on a given node are mapped to a range of uids/gids + // from that Node's namespace. For e.g. starting with 200000 id on the nodes namespace, + // 10000 ids are allocated for a pod. This means uid/gid 0 inside the pod would map to 200000 id on the nodes namespace. + // For example, starting from uid/gid 0, 10000 uids/gids in this namespace are mapped to + // 10000 ids on node namespace,starting with id 200000. i.e uid/gid 0 in this namespace is + // mapped to uid/gid 200000 on node namespace. + NODE_WIDE_REMAPPED = 3; } // NamespaceOption provides options for Linux namespaces. @@ -233,6 +244,12 @@ message NamespaceOption { // Note: There is currently no way to set CONTAINER scoped IPC in the Kubernetes API. // Namespaces currently set by the kubelet: POD, NODE NamespaceMode ipc = 3; + // User namespace for this container/sandbox. + // Note: There is currently no way to set CONTAINER scoped user namespace in the Kubernetes API. + // The container runtime should ignore this if user namespace is NOT enabled. + // NODE is the default value. Kubelet will set it to NODE_WIDE_REMAPPED if pod spec indicates to use user-namespace remapping + // Namespaces currently set by the kubelet: NODE, NODE_WIDE_REMAPPED + NamespaceMode user = 4; } // Int64Value is the wrapper of int64. @@ -1161,6 +1178,39 @@ message StatusResponse { map info = 2; } +// LinuxIDMapping represents a single user namespace mapping in Linux. +message LinuxIDMapping { + // container_id is the starting id for the mapping inside the container. + uint32 container_id = 1; + // host_id is the starting id for the mapping on the host. + uint32 host_id = 2; + // size is the length of the mapping. + uint32 size = 3; +} + +// LinuxUserNamespaceConfig represents runtime's user-namespace configuration on a linux host. +message LinuxUserNamespaceConfig { + // uid_mappings is an array of user id mappings. + repeated LinuxIDMapping uid_mappings = 1; + // gid_mappings is an array of group id mappings. + repeated LinuxIDMapping gid_mappings = 2; +} + +// ActiveRuntimeConfig contains the configuration details from the runtime. +message ActiveRuntimeConfig { + // LinuxUserNamespaceConfig represents runtime's user-namespace configuration on a linux host. + LinuxUserNamespaceConfig user_namespace_config = 1; +} + +// GetRuntimeConfigInfoRequest is the message sent for requesting runtime configuration details. +message GetRuntimeConfigInfoRequest {} + +// GetRuntimeConfigInfoResponse is the response message from runtime that includes configuration details +message GetRuntimeConfigInfoResponse { + // GetRuntimeConfig are the configuration details from the runtime. + ActiveRuntimeConfig runtime_config = 1; +} + message ImageFsInfoRequest {} // UInt64Value is the wrapper of uint64. diff --git a/staging/src/k8s.io/cri-api/pkg/apis/services.go b/staging/src/k8s.io/cri-api/pkg/apis/services.go index 9a22ecbf031dd..1742738b4811d 100644 --- a/staging/src/k8s.io/cri-api/pkg/apis/services.go +++ b/staging/src/k8s.io/cri-api/pkg/apis/services.go @@ -100,6 +100,8 @@ type RuntimeService interface { UpdateRuntimeConfig(runtimeConfig *runtimeapi.RuntimeConfig) error // Status returns the status of the runtime. Status() (*runtimeapi.RuntimeStatus, error) + // GetRuntimeConfigInfo returns runtime's configuration details, eg: if user-namespaces are enabled or not + GetRuntimeConfigInfo() (*runtimeapi.ActiveRuntimeConfig, error) } // ImageManagerService interface should be implemented by a container image diff --git a/userns-tests/pod-simple.yaml b/userns-tests/pod-simple.yaml new file mode 100644 index 0000000000000..6e530e5d151f9 --- /dev/null +++ b/userns-tests/pod-simple.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-simple + namespace: default + annotations: + alpha.kinvolk.io/userns: "disabled" +spec: + restartPolicy: Never + containers: + - name: pod-simple + image: busybox + command: ["sh"] + args: ["-c", "sleep infinity"] + diff --git a/userns-tests/pod-userns.yaml b/userns-tests/pod-userns.yaml new file mode 100644 index 0000000000000..b64fb801b170b --- /dev/null +++ b/userns-tests/pod-userns.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-userns + namespace: default + annotations: + alpha.kinvolk.io/userns: "enabled" +spec: + restartPolicy: Never + containers: + - name: pod-userns + image: busybox + command: ["sh"] + args: ["-c", "sleep infinity"] +