From c73308e90ac1a1587a2b7c95c1a199515e65851d Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Thu, 3 Oct 2024 10:38:07 +0200 Subject: [PATCH 01/13] Introduce SELinuxChangePolicy Feature gate + the API --- pkg/apis/core/types.go | 42 +++++++++++++++++++ pkg/features/kube_features.go | 9 ++++ pkg/features/versioned_kube_features.go | 4 ++ staging/src/k8s.io/api/core/v1/types.go | 42 +++++++++++++++++++ .../test_data/versioned_feature_list.yaml | 6 +++ 5 files changed, 103 insertions(+) diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index cf3879fd78b..bfad02c78f8 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -3684,6 +3684,22 @@ const ( SupplementalGroupsPolicyStrict SupplementalGroupsPolicy = "Strict" ) +// PodSELinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. +type PodSELinuxChangePolicy string + +const ( + // Recursive relabeling of all Pod volumes by the container runtime. + // This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + SELinuxChangePolicyRecursive PodSELinuxChangePolicy = "Recursive" + // MountOption mounts all eligible Pod volumes with `-o context` mount option. + // This requires all Pods that share the same volume to use the same SELinux label. + // It is not possible to share the same volume among privileged and unprivileged Pods. + // Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + // whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + // CSIDriver instance. Other volumes are always re-labelled recursively. + SELinuxChangePolicyMountOption PodSELinuxChangePolicy = "MountOption" +) + // PodSecurityContext holds pod-level security attributes and common container settings. // Some fields are also present in container.securityContext. Field values of // container.securityContext take precedence over field values of PodSecurityContext. @@ -3820,6 +3836,32 @@ type PodSecurityContext struct { // Note that this field cannot be set when spec.os.name is windows. // +optional AppArmorProfile *AppArmorProfile + // seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + // It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + // Valid values are "MountOption" and "Recursive". + // + // "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + // This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + // + // "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + // This requires all Pods that share the same volume to use the same SELinux label. + // It is not possible to share the same volume among privileged and unprivileged Pods. + // Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + // whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + // CSIDriver instance. Other volumes are always re-labelled recursively. + // "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + // + // If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + // If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + // and "Recursive" for all other volumes. + // + // This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + // + // All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + // Note that this field cannot be set when spec.os.name is windows. + // +featureGate=SELinuxChangePolicy + // +optional + SELinuxChangePolicy *PodSELinuxChangePolicy } // SeccompProfile defines a pod/container's seccomp profile settings. diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 69258b83528..fbecc1c3d9c 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -788,6 +788,15 @@ const ( // unresponsive. The feature gate is enabled by default, but should only be used // if the system supports the systemd watchdog feature and has it configured properly. SystemdWatchdog = featuregate.Feature("SystemdWatchdog") + + // owner: @jsafrane + // kep: https://kep.k8s.io/1710 + // alpha: v1.32 + // + // Speed up container startup by mounting volumes with the correct SELinux label + // instead of changing each file on the volumes recursively. + // Enables the SELinuxChangePolicy field in PodSecurityContext before SELinuxMount featgure gate is enabled. + SELinuxChangePolicy featuregate.Feature = "SELinuxChangePolicy" ) func init() { diff --git a/pkg/features/versioned_kube_features.go b/pkg/features/versioned_kube_features.go index 0ed4bef24fc..7cd8227077e 100644 --- a/pkg/features/versioned_kube_features.go +++ b/pkg/features/versioned_kube_features.go @@ -634,6 +634,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Beta}, }, + SELinuxChangePolicy: { + {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + }, + SELinuxMount: { {Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha}, }, diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index 66df4250867..637182c64d9 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -4310,6 +4310,22 @@ const ( SupplementalGroupsPolicyStrict SupplementalGroupsPolicy = "Strict" ) +// PodSELinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. +type PodSELinuxChangePolicy string + +const ( + // Recursive relabeling of all Pod volumes by the container runtime. + // This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + SELinuxChangePolicyRecursive PodSELinuxChangePolicy = "Recursive" + // MountOption mounts all eligible Pod volumes with `-o context` mount option. + // This requires all Pods that share the same volume to use the same SELinux label. + // It is not possible to share the same volume among privileged and unprivileged Pods. + // Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + // whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + // CSIDriver instance. Other volumes are always re-labelled recursively. + SELinuxChangePolicyMountOption PodSELinuxChangePolicy = "MountOption" +) + // PodSecurityContext holds pod-level security attributes and common container settings. // Some fields are also present in container.securityContext. Field values of // container.securityContext take precedence over field values of PodSecurityContext. @@ -4408,6 +4424,32 @@ type PodSecurityContext struct { // Note that this field cannot be set when spec.os.name is windows. // +optional AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" protobuf:"bytes,11,opt,name=appArmorProfile"` + // seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + // It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + // Valid values are "MountOption" and "Recursive". + // + // "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + // This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + // + // "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + // This requires all Pods that share the same volume to use the same SELinux label. + // It is not possible to share the same volume among privileged and unprivileged Pods. + // Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + // whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + // CSIDriver instance. Other volumes are always re-labelled recursively. + // "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + // + // If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + // If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + // and "Recursive" for all other volumes. + // + // This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + // + // All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + // Note that this field cannot be set when spec.os.name is windows. + // +featureGate=SELinuxChangePolicy + // +optional + SELinuxChangePolicy *PodSELinuxChangePolicy `json:"seLinuxChangePolicy,omitempty" protobuf:"bytes,12,opt,name=seLinuxChangePolicy"` } // SeccompProfile defines a pod/container's seccomp profile settings. diff --git a/test/featuregates_linter/test_data/versioned_feature_list.yaml b/test/featuregates_linter/test_data/versioned_feature_list.yaml index ca7fdf1590c..0c73dbfebf1 100644 --- a/test/featuregates_linter/test_data/versioned_feature_list.yaml +++ b/test/featuregates_linter/test_data/versioned_feature_list.yaml @@ -1046,6 +1046,12 @@ lockToDefault: false preRelease: Beta version: "1.28" +- name: SELinuxChangePolicy + versionedSpecs: + - default: false + lockToDefault: false + preRelease: Alpha + version: "1.32" - name: SELinuxMount versionedSpecs: - default: false From 3867cb40add0cfc41157e9fd11f2377cda7d3770 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Thu, 3 Oct 2024 11:13:07 +0200 Subject: [PATCH 02/13] Regenerated API --- api/openapi-spec/swagger.json | 4 + api/openapi-spec/v3/api__v1_openapi.json | 4 + .../v3/apis__apps__v1_openapi.json | 4 + .../v3/apis__batch__v1_openapi.json | 4 + pkg/apis/core/v1/zz_generated.conversion.go | 2 + pkg/apis/core/zz_generated.deepcopy.go | 5 + pkg/generated/openapi/zz_generated.openapi.go | 7 + .../src/k8s.io/api/core/v1/generated.pb.go | 1334 +++++++++-------- .../src/k8s.io/api/core/v1/generated.proto | 27 + staging/src/k8s.io/api/core/v1/types.go | 2 +- .../core/v1/types_swagger_doc_generated.go | 1 + .../api/core/v1/zz_generated.deepcopy.go | 5 + .../api/testdata/HEAD/apps.v1.DaemonSet.json | 3 +- .../api/testdata/HEAD/apps.v1.DaemonSet.pb | Bin 10912 -> 10938 bytes .../api/testdata/HEAD/apps.v1.DaemonSet.yaml | 1 + .../api/testdata/HEAD/apps.v1.Deployment.json | 3 +- .../api/testdata/HEAD/apps.v1.Deployment.pb | Bin 10925 -> 10951 bytes .../api/testdata/HEAD/apps.v1.Deployment.yaml | 1 + .../api/testdata/HEAD/apps.v1.ReplicaSet.json | 3 +- .../api/testdata/HEAD/apps.v1.ReplicaSet.pb | Bin 10842 -> 10868 bytes .../api/testdata/HEAD/apps.v1.ReplicaSet.yaml | 1 + .../testdata/HEAD/apps.v1.StatefulSet.json | 3 +- .../api/testdata/HEAD/apps.v1.StatefulSet.pb | Bin 12013 -> 12039 bytes .../testdata/HEAD/apps.v1.StatefulSet.yaml | 1 + .../HEAD/apps.v1beta1.Deployment.json | 3 +- .../testdata/HEAD/apps.v1beta1.Deployment.pb | Bin 10934 -> 10960 bytes .../HEAD/apps.v1beta1.Deployment.yaml | 1 + .../HEAD/apps.v1beta1.StatefulSet.json | 3 +- .../testdata/HEAD/apps.v1beta1.StatefulSet.pb | Bin 12018 -> 12044 bytes .../HEAD/apps.v1beta1.StatefulSet.yaml | 1 + .../testdata/HEAD/apps.v1beta2.DaemonSet.json | 3 +- .../testdata/HEAD/apps.v1beta2.DaemonSet.pb | Bin 10917 -> 10943 bytes .../testdata/HEAD/apps.v1beta2.DaemonSet.yaml | 1 + .../HEAD/apps.v1beta2.Deployment.json | 3 +- .../testdata/HEAD/apps.v1beta2.Deployment.pb | Bin 10930 -> 10956 bytes .../HEAD/apps.v1beta2.Deployment.yaml | 1 + .../HEAD/apps.v1beta2.ReplicaSet.json | 3 +- .../testdata/HEAD/apps.v1beta2.ReplicaSet.pb | Bin 10847 -> 10873 bytes .../HEAD/apps.v1beta2.ReplicaSet.yaml | 1 + .../HEAD/apps.v1beta2.StatefulSet.json | 3 +- .../testdata/HEAD/apps.v1beta2.StatefulSet.pb | Bin 12018 -> 12044 bytes .../HEAD/apps.v1beta2.StatefulSet.yaml | 1 + .../api/testdata/HEAD/batch.v1.CronJob.json | 3 +- .../api/testdata/HEAD/batch.v1.CronJob.pb | Bin 11505 -> 11531 bytes .../api/testdata/HEAD/batch.v1.CronJob.yaml | 1 + .../api/testdata/HEAD/batch.v1.Job.json | 3 +- .../k8s.io/api/testdata/HEAD/batch.v1.Job.pb | Bin 11131 -> 11157 bytes .../api/testdata/HEAD/batch.v1.Job.yaml | 1 + .../testdata/HEAD/batch.v1beta1.CronJob.json | 3 +- .../testdata/HEAD/batch.v1beta1.CronJob.pb | Bin 11510 -> 11536 bytes .../testdata/HEAD/batch.v1beta1.CronJob.yaml | 1 + .../k8s.io/api/testdata/HEAD/core.v1.Pod.json | 3 +- .../k8s.io/api/testdata/HEAD/core.v1.Pod.pb | Bin 12071 -> 12097 bytes .../k8s.io/api/testdata/HEAD/core.v1.Pod.yaml | 1 + .../testdata/HEAD/core.v1.PodTemplate.json | 3 +- .../api/testdata/HEAD/core.v1.PodTemplate.pb | Bin 10678 -> 10704 bytes .../testdata/HEAD/core.v1.PodTemplate.yaml | 1 + .../HEAD/core.v1.ReplicationController.json | 3 +- .../HEAD/core.v1.ReplicationController.pb | Bin 10800 -> 10826 bytes .../HEAD/core.v1.ReplicationController.yaml | 1 + .../HEAD/extensions.v1beta1.DaemonSet.json | 3 +- .../HEAD/extensions.v1beta1.DaemonSet.pb | Bin 10925 -> 10951 bytes .../HEAD/extensions.v1beta1.DaemonSet.yaml | 1 + .../HEAD/extensions.v1beta1.Deployment.json | 3 +- .../HEAD/extensions.v1beta1.Deployment.pb | Bin 10940 -> 10966 bytes .../HEAD/extensions.v1beta1.Deployment.yaml | 1 + .../HEAD/extensions.v1beta1.ReplicaSet.json | 3 +- .../HEAD/extensions.v1beta1.ReplicaSet.pb | Bin 10853 -> 10879 bytes .../HEAD/extensions.v1beta1.ReplicaSet.yaml | 1 + .../core/v1/podsecuritycontext.go | 9 + .../applyconfigurations/internal/internal.go | 3 + 71 files changed, 823 insertions(+), 664 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 5f47fe88d65..823e0a31de6 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -9660,6 +9660,10 @@ "format": "int64", "type": "integer" }, + "seLinuxChangePolicy": { + "description": "seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. Valid values are \"MountOption\" and \"Recursive\".\n\n\"Recursive\" means relabeling of all files on all Pod volumes by the container runtime. This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n\"MountOption\" mounts all eligible Pod volumes with `-o context` mount option. This requires all Pods that share the same volume to use the same SELinux label. It is not possible to share the same volume among privileged and unprivileged Pods. Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their CSIDriver instance. Other volumes are always re-labelled recursively. \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\nIf not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used. If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes and \"Recursive\" for all other volumes.\n\nThis field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\nAll Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. Note that this field cannot be set when spec.os.name is windows.", + "type": "string" + }, "seLinuxOptions": { "$ref": "#/definitions/io.k8s.api.core.v1.SELinuxOptions", "description": "The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows." diff --git a/api/openapi-spec/v3/api__v1_openapi.json b/api/openapi-spec/v3/api__v1_openapi.json index e307edc8697..a2bbed968e0 100644 --- a/api/openapi-spec/v3/api__v1_openapi.json +++ b/api/openapi-spec/v3/api__v1_openapi.json @@ -5394,6 +5394,10 @@ "format": "int64", "type": "integer" }, + "seLinuxChangePolicy": { + "description": "seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. Valid values are \"MountOption\" and \"Recursive\".\n\n\"Recursive\" means relabeling of all files on all Pod volumes by the container runtime. This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n\"MountOption\" mounts all eligible Pod volumes with `-o context` mount option. This requires all Pods that share the same volume to use the same SELinux label. It is not possible to share the same volume among privileged and unprivileged Pods. Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their CSIDriver instance. Other volumes are always re-labelled recursively. \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\nIf not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used. If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes and \"Recursive\" for all other volumes.\n\nThis field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\nAll Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. Note that this field cannot be set when spec.os.name is windows.", + "type": "string" + }, "seLinuxOptions": { "allOf": [ { diff --git a/api/openapi-spec/v3/apis__apps__v1_openapi.json b/api/openapi-spec/v3/apis__apps__v1_openapi.json index 6bc3da14edb..34036de2ae3 100644 --- a/api/openapi-spec/v3/apis__apps__v1_openapi.json +++ b/api/openapi-spec/v3/apis__apps__v1_openapi.json @@ -3648,6 +3648,10 @@ "format": "int64", "type": "integer" }, + "seLinuxChangePolicy": { + "description": "seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. Valid values are \"MountOption\" and \"Recursive\".\n\n\"Recursive\" means relabeling of all files on all Pod volumes by the container runtime. This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n\"MountOption\" mounts all eligible Pod volumes with `-o context` mount option. This requires all Pods that share the same volume to use the same SELinux label. It is not possible to share the same volume among privileged and unprivileged Pods. Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their CSIDriver instance. Other volumes are always re-labelled recursively. \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\nIf not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used. If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes and \"Recursive\" for all other volumes.\n\nThis field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\nAll Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. Note that this field cannot be set when spec.os.name is windows.", + "type": "string" + }, "seLinuxOptions": { "allOf": [ { diff --git a/api/openapi-spec/v3/apis__batch__v1_openapi.json b/api/openapi-spec/v3/apis__batch__v1_openapi.json index a37d481afc7..533e95bf255 100644 --- a/api/openapi-spec/v3/apis__batch__v1_openapi.json +++ b/api/openapi-spec/v3/apis__batch__v1_openapi.json @@ -2852,6 +2852,10 @@ "format": "int64", "type": "integer" }, + "seLinuxChangePolicy": { + "description": "seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. Valid values are \"MountOption\" and \"Recursive\".\n\n\"Recursive\" means relabeling of all files on all Pod volumes by the container runtime. This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n\"MountOption\" mounts all eligible Pod volumes with `-o context` mount option. This requires all Pods that share the same volume to use the same SELinux label. It is not possible to share the same volume among privileged and unprivileged Pods. Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their CSIDriver instance. Other volumes are always re-labelled recursively. \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\nIf not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used. If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes and \"Recursive\" for all other volumes.\n\nThis field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\nAll Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. Note that this field cannot be set when spec.os.name is windows.", + "type": "string" + }, "seLinuxOptions": { "allOf": [ { diff --git a/pkg/apis/core/v1/zz_generated.conversion.go b/pkg/apis/core/v1/zz_generated.conversion.go index f97e6f33fae..ea0739d0986 100644 --- a/pkg/apis/core/v1/zz_generated.conversion.go +++ b/pkg/apis/core/v1/zz_generated.conversion.go @@ -6622,6 +6622,7 @@ func autoConvert_v1_PodSecurityContext_To_core_PodSecurityContext(in *corev1.Pod out.FSGroupChangePolicy = (*core.PodFSGroupChangePolicy)(unsafe.Pointer(in.FSGroupChangePolicy)) out.SeccompProfile = (*core.SeccompProfile)(unsafe.Pointer(in.SeccompProfile)) out.AppArmorProfile = (*core.AppArmorProfile)(unsafe.Pointer(in.AppArmorProfile)) + out.SELinuxChangePolicy = (*core.PodSELinuxChangePolicy)(unsafe.Pointer(in.SELinuxChangePolicy)) return nil } @@ -6648,6 +6649,7 @@ func autoConvert_core_PodSecurityContext_To_v1_PodSecurityContext(in *core.PodSe out.Sysctls = *(*[]corev1.Sysctl)(unsafe.Pointer(&in.Sysctls)) out.SeccompProfile = (*corev1.SeccompProfile)(unsafe.Pointer(in.SeccompProfile)) out.AppArmorProfile = (*corev1.AppArmorProfile)(unsafe.Pointer(in.AppArmorProfile)) + out.SELinuxChangePolicy = (*corev1.PodSELinuxChangePolicy)(unsafe.Pointer(in.SELinuxChangePolicy)) return nil } diff --git a/pkg/apis/core/zz_generated.deepcopy.go b/pkg/apis/core/zz_generated.deepcopy.go index f7ea2a6456a..a4771e469b2 100644 --- a/pkg/apis/core/zz_generated.deepcopy.go +++ b/pkg/apis/core/zz_generated.deepcopy.go @@ -4181,6 +4181,11 @@ func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) { *out = new(AppArmorProfile) (*in).DeepCopyInto(*out) } + if in.SELinuxChangePolicy != nil { + in, out := &in.SELinuxChangePolicy, &out.SELinuxChangePolicy + *out = new(PodSELinuxChangePolicy) + **out = **in + } return } diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 41e0b0fa592..590abdc1981 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -27618,6 +27618,13 @@ func schema_k8sio_api_core_v1_PodSecurityContext(ref common.ReferenceCallback) c Ref: ref("k8s.io/api/core/v1.AppArmorProfile"), }, }, + "seLinuxChangePolicy": { + SchemaProps: spec.SchemaProps{ + Description: "seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. Valid values are \"MountOption\" and \"Recursive\".\n\n\"Recursive\" means relabeling of all files on all Pod volumes by the container runtime. This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n\"MountOption\" mounts all eligible Pod volumes with `-o context` mount option. This requires all Pods that share the same volume to use the same SELinux label. It is not possible to share the same volume among privileged and unprivileged Pods. Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their CSIDriver instance. Other volumes are always re-labelled recursively. \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\nIf not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used. If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes and \"Recursive\" for all other volumes.\n\nThis field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\nAll Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. Note that this field cannot be set when spec.os.name is windows.", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/staging/src/k8s.io/api/core/v1/generated.pb.go b/staging/src/k8s.io/api/core/v1/generated.pb.go index 5654ee48291..b3164785410 100644 --- a/staging/src/k8s.io/api/core/v1/generated.pb.go +++ b/staging/src/k8s.io/api/core/v1/generated.pb.go @@ -6758,16 +6758,16 @@ func init() { } var fileDescriptor_6c07b07c062484ab = []byte{ - // 16056 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x79, 0x90, 0x1c, 0xd7, - 0x79, 0x18, 0xae, 0x9e, 0xd9, 0xf3, 0xdb, 0xfb, 0x2d, 0x8e, 0xc5, 0x12, 0xc0, 0x80, 0x4d, 0x12, - 0x04, 0xaf, 0x85, 0xc0, 0x43, 0x84, 0x48, 0x8a, 0xe6, 0x9e, 0xc0, 0x12, 0xd8, 0xc5, 0xf0, 0xcd, - 0x02, 0x90, 0x28, 0x4a, 0x56, 0x63, 0xe6, 0xed, 0x6e, 0x6b, 0x67, 0xba, 0x87, 0xdd, 0x3d, 0x0b, - 0x2c, 0x7e, 0x72, 0xd9, 0x96, 0x7f, 0x96, 0x2d, 0xd9, 0xa9, 0x52, 0xb9, 0x9c, 0x38, 0x25, 0xbb, - 0x5c, 0x29, 0xc7, 0xf1, 0x11, 0xc5, 0x4e, 0x14, 0x39, 0xb6, 0x63, 0xf9, 0xca, 0x55, 0x65, 0x27, - 0x29, 0xc7, 0x71, 0x55, 0x24, 0x57, 0x5c, 0x59, 0x47, 0xeb, 0x54, 0xb9, 0xfc, 0x47, 0x6c, 0x97, - 0x93, 0x3f, 0x92, 0x2d, 0x27, 0x4e, 0xbd, 0xb3, 0xdf, 0xeb, 0x63, 0x66, 0x16, 0x04, 0x56, 0x14, - 0x8b, 0xff, 0xcd, 0xbc, 0xef, 0x7b, 0xdf, 0x7b, 0xfd, 0xce, 0xef, 0x7d, 0x27, 0xd8, 0x5b, 0x17, + // 16080 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x79, 0x8c, 0x1c, 0xd9, + 0x79, 0x18, 0xae, 0xea, 0x9e, 0xf3, 0x9b, 0xfb, 0x0d, 0x8f, 0xe1, 0x2c, 0xc9, 0xe6, 0xd6, 0xee, + 0x72, 0xb9, 0xd7, 0x50, 0xdc, 0x43, 0x4b, 0xed, 0xae, 0xd6, 0x3b, 0x27, 0x39, 0x4b, 0xce, 0xb0, + 0xf7, 0xf5, 0x90, 0x94, 0x56, 0x2b, 0x59, 0xc5, 0xee, 0x37, 0x33, 0xa5, 0xe9, 0xae, 0xea, 0xad, + 0xaa, 0x1e, 0x72, 0xf8, 0x93, 0x61, 0x5b, 0xfe, 0x59, 0xb6, 0x64, 0x07, 0x10, 0x0c, 0x27, 0x0e, + 0x64, 0xc3, 0x08, 0x1c, 0xc7, 0x47, 0x14, 0x3b, 0x56, 0xe4, 0xd8, 0x8e, 0xe5, 0x2b, 0x17, 0x60, + 0x07, 0x81, 0xe3, 0x18, 0x88, 0x64, 0xc4, 0xc8, 0x38, 0x1a, 0x07, 0x30, 0xfc, 0x47, 0x6c, 0xc3, + 0xc9, 0x1f, 0xc9, 0xc0, 0x89, 0x83, 0x77, 0xd6, 0x7b, 0x75, 0x74, 0xf7, 0x70, 0xc9, 0xd1, 0x6a, + 0xb1, 0xff, 0x75, 0xbf, 0xef, 0x7b, 0xdf, 0x7b, 0xf5, 0xce, 0xef, 0x7d, 0x27, 0xd8, 0x5b, 0x17, 0xc3, 0x19, 0xd7, 0x3f, 0xef, 0x34, 0xdd, 0xf3, 0x55, 0x3f, 0x20, 0xe7, 0xb7, 0x2f, 0x9c, 0xdf, 0x20, 0x1e, 0x09, 0x9c, 0x88, 0xd4, 0x66, 0x9a, 0x81, 0x1f, 0xf9, 0x08, 0x71, 0x9c, 0x19, 0xa7, 0xe9, 0xce, 0x50, 0x9c, 0x99, 0xed, 0x0b, 0xd3, 0xcf, 0x6c, 0xb8, 0xd1, 0x66, 0xeb, 0xd6, 0x4c, @@ -6779,7 +6779,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x2b, 0x72, 0xeb, 0xe7, 0x5d, 0x2f, 0x0a, 0xa3, 0x20, 0x59, 0xc9, 0xfe, 0x86, 0x05, 0x67, 0x66, 0x6f, 0x56, 0x16, 0xeb, 0x4e, 0x18, 0xb9, 0xd5, 0xb9, 0xba, 0x5f, 0xdd, 0xaa, 0x44, 0x7e, 0x40, 0x6e, 0xf8, 0xf5, 0x56, 0x83, 0x54, 0xd8, 0x40, 0xa0, 0xa7, 0x61, 0x60, 0x9b, 0xfd, 0x5f, 0x5e, - 0x98, 0xb2, 0xce, 0x58, 0xe7, 0x06, 0xe7, 0xc6, 0x7f, 0x67, 0xb7, 0xf4, 0x81, 0xbd, 0xdd, 0xd2, + 0x98, 0xb2, 0xce, 0x58, 0xe7, 0x06, 0xe7, 0xc6, 0x7f, 0x77, 0xb7, 0xf4, 0x81, 0xbd, 0xdd, 0xd2, 0xc0, 0x0d, 0x51, 0x8e, 0x15, 0x06, 0x3a, 0x0b, 0x7d, 0xeb, 0xe1, 0xda, 0x4e, 0x93, 0x4c, 0x15, 0x18, 0xee, 0xa8, 0xc0, 0xed, 0x5b, 0xaa, 0xd0, 0x52, 0x2c, 0xa0, 0xe8, 0x3c, 0x0c, 0x36, 0x9d, 0x20, 0x72, 0x23, 0xd7, 0xf7, 0xa6, 0x8a, 0x67, 0xac, 0x73, 0xbd, 0x73, 0x13, 0x02, 0x75, 0xb0, @@ -6801,7 +6801,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x44, 0x5d, 0x58, 0x50, 0x10, 0xac, 0x61, 0xd9, 0x77, 0x60, 0x70, 0x76, 0xdb, 0x77, 0x6b, 0x65, 0xbf, 0x16, 0xa2, 0x2d, 0x18, 0x6b, 0x06, 0x64, 0x9d, 0x04, 0xaa, 0x68, 0xca, 0x3a, 0x53, 0x3c, 0x37, 0xf4, 0xec, 0xb9, 0xcc, 0xb1, 0x37, 0x51, 0x17, 0xbd, 0x28, 0xd8, 0x99, 0x3b, 0x2e, 0xda, - 0x1b, 0x4b, 0x40, 0x71, 0x92, 0xb2, 0xfd, 0xaf, 0x0b, 0x70, 0x74, 0xf6, 0x6e, 0x2b, 0x20, 0x0b, + 0x1b, 0x4b, 0x40, 0x71, 0x92, 0xb2, 0xfd, 0x6f, 0x0a, 0x70, 0x74, 0xf6, 0x6e, 0x2b, 0x20, 0x0b, 0x6e, 0xb8, 0x95, 0xdc, 0x70, 0x35, 0x37, 0xdc, 0x5a, 0x8d, 0x47, 0x40, 0xad, 0xf4, 0x05, 0x51, 0x8e, 0x15, 0x06, 0x7a, 0x06, 0xfa, 0xe9, 0xef, 0xeb, 0x78, 0x59, 0x7c, 0xf2, 0xa4, 0x40, 0x1e, 0x5a, 0x70, 0x22, 0x67, 0x81, 0x83, 0xb0, 0xc4, 0x41, 0x2b, 0x30, 0x54, 0x65, 0xe7, 0xc3, 0xc6, @@ -6814,8 +6814,8 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x44, 0xda, 0x90, 0xaa, 0x85, 0x51, 0x51, 0x10, 0xac, 0x61, 0xd1, 0xf3, 0x29, 0xdc, 0x74, 0x02, 0xb6, 0xbe, 0xc4, 0xc0, 0xaa, 0xf3, 0xa9, 0x22, 0x01, 0x38, 0xc6, 0x31, 0xce, 0xa7, 0x62, 0xa7, 0xf3, 0x09, 0x7d, 0x04, 0xc6, 0xe2, 0xc6, 0xc2, 0xa6, 0x53, 0x95, 0x03, 0xc8, 0x76, 0x70, 0xc5, - 0x04, 0xe1, 0x24, 0xae, 0xfd, 0x0f, 0x2d, 0xb1, 0x78, 0xe8, 0x57, 0xbf, 0xcb, 0xbf, 0xd5, 0xfe, - 0x55, 0x0b, 0xfa, 0xe7, 0x5c, 0xaf, 0xe6, 0x7a, 0x1b, 0xe8, 0x53, 0x30, 0x40, 0xaf, 0xca, 0x9a, + 0x04, 0xe1, 0x24, 0xae, 0xfd, 0x8f, 0x2d, 0xb1, 0x78, 0xe8, 0x57, 0xbf, 0xcb, 0xbf, 0xd5, 0xfe, + 0x35, 0x0b, 0xfa, 0xe7, 0x5c, 0xaf, 0xe6, 0x7a, 0x1b, 0xe8, 0x53, 0x30, 0x40, 0xaf, 0xca, 0x9a, 0x13, 0x39, 0xe2, 0x18, 0xfe, 0xa0, 0xb6, 0xb7, 0xd4, 0xcd, 0x35, 0xd3, 0xdc, 0xda, 0xa0, 0x05, 0xe1, 0x0c, 0xc5, 0xa6, 0xbb, 0xed, 0xda, 0xad, 0x4f, 0x93, 0x6a, 0xb4, 0x42, 0x22, 0x27, 0xfe, 0x9c, 0xb8, 0x0c, 0x2b, 0xaa, 0xe8, 0x0a, 0xf4, 0x45, 0x4e, 0xb0, 0x41, 0x22, 0x71, 0x1e, 0x67, @@ -6836,14 +6836,14 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x4a, 0x38, 0xbf, 0x11, 0xe4, 0xc1, 0x24, 0xed, 0x5a, 0xb2, 0x6d, 0xe8, 0xbe, 0xed, 0xe3, 0x7b, 0xbb, 0xa5, 0xc9, 0xd5, 0x34, 0x0d, 0x9c, 0x45, 0x78, 0x7a, 0x1e, 0x8e, 0x66, 0xae, 0x4e, 0x34, 0x0e, 0xc5, 0x2d, 0xc2, 0x99, 0xc0, 0x41, 0x4c, 0x7f, 0xa2, 0x23, 0xd0, 0xbb, 0xed, 0xd4, 0x5b, - 0x62, 0x63, 0x62, 0xfe, 0xe7, 0xa5, 0xc2, 0x45, 0xcb, 0xfe, 0x37, 0x45, 0x18, 0x9b, 0xaf, 0x2c, + 0x62, 0x63, 0x62, 0xfe, 0xe7, 0xa5, 0xc2, 0x45, 0xcb, 0xfe, 0xb7, 0x45, 0x18, 0x9b, 0xaf, 0x2c, 0xdf, 0xd3, 0xae, 0xd7, 0xaf, 0xbd, 0x42, 0xdb, 0x6b, 0x2f, 0xbe, 0x44, 0x8b, 0xb9, 0x97, 0xe8, 0x77, 0x67, 0x6c, 0xd9, 0x1e, 0xb6, 0x65, 0x3f, 0x9c, 0xb3, 0x65, 0xef, 0xf3, 0x46, 0xdd, 0xce, 0x59, 0xb5, 0xbd, 0x6c, 0x02, 0x33, 0x39, 0x24, 0xc6, 0xfb, 0x25, 0x8f, 0xda, 0x03, 0x2e, 0xdd, 0xfb, 0x33, 0x8f, 0x55, 0x18, 0x9e, 0x77, 0x9a, 0xce, 0x2d, 0xb7, 0xee, 0x46, 0x2e, 0x09, 0xd1, 0xe3, 0x50, 0x74, 0x6a, 0x35, 0xc6, 0xdd, 0x0d, 0xce, 0x1d, 0xdd, 0xdb, 0x2d, 0x15, 0x67, 0x6b, 0x94, 0xcd, 0x00, 0x85, 0xb5, 0x83, 0x29, 0x06, 0x7a, 0x12, 0x7a, 0x6a, 0x81, 0xdf, 0x9c, 0x2a, - 0x30, 0x4c, 0xba, 0xcb, 0x7b, 0x16, 0x02, 0xbf, 0x99, 0x40, 0x65, 0x38, 0xf6, 0x6f, 0x17, 0xe0, + 0x30, 0x4c, 0xba, 0xcb, 0x7b, 0x16, 0x02, 0xbf, 0x99, 0x40, 0x65, 0x38, 0xf6, 0xef, 0x14, 0xe0, 0xe4, 0x3c, 0x69, 0x6e, 0x2e, 0x55, 0x72, 0xee, 0x8b, 0x73, 0x30, 0xd0, 0xf0, 0x3d, 0x37, 0xf2, 0x83, 0x50, 0x34, 0xcd, 0x56, 0xc4, 0x8a, 0x28, 0xc3, 0x0a, 0x8a, 0xce, 0x40, 0x4f, 0x33, 0x66, 0x62, 0x87, 0x25, 0x03, 0xcc, 0xd8, 0x57, 0x06, 0xa1, 0x18, 0xad, 0x90, 0x04, 0x62, 0xc5, 0x28, @@ -6852,7 +6852,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x50, 0x33, 0x19, 0x13, 0x31, 0x6e, 0xb0, 0xbe, 0x8e, 0xac, 0xc2, 0xd7, 0x0a, 0x80, 0xf8, 0x10, 0x7e, 0x9b, 0x0d, 0xdc, 0xf5, 0xf4, 0xc0, 0x75, 0xbf, 0x25, 0xee, 0xd7, 0xe8, 0xfd, 0x4f, 0x0b, 0x4e, 0xce, 0xbb, 0x5e, 0x8d, 0x04, 0x39, 0x0b, 0xf0, 0xc1, 0x3c, 0xe5, 0x0f, 0xc6, 0xa4, 0x18, - 0x4b, 0xac, 0xe7, 0x3e, 0x2c, 0x31, 0xfb, 0x2f, 0x2c, 0x40, 0xfc, 0xb3, 0xdf, 0x75, 0x1f, 0x7b, + 0x4b, 0xac, 0xe7, 0x3e, 0x2c, 0x31, 0xfb, 0x2f, 0x2d, 0x40, 0xfc, 0xb3, 0xdf, 0x75, 0x1f, 0x7b, 0x3d, 0xfd, 0xb1, 0xf7, 0x61, 0x59, 0xd8, 0x57, 0x61, 0x74, 0xbe, 0xee, 0x12, 0x2f, 0x5a, 0x2e, 0xcf, 0xfb, 0xde, 0xba, 0xbb, 0x81, 0x5e, 0x82, 0xd1, 0xc8, 0x6d, 0x10, 0xbf, 0x15, 0x55, 0x48, 0xd5, 0xf7, 0xd8, 0xcb, 0xd5, 0x3a, 0xd7, 0x3b, 0x87, 0xf6, 0x76, 0x4b, 0xa3, 0x6b, 0x06, 0x04, @@ -6862,7 +6862,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xab, 0xa8, 0x52, 0xac, 0x61, 0xa0, 0x3a, 0x8c, 0xd4, 0x9d, 0x5b, 0xa4, 0x5e, 0x21, 0x75, 0x52, 0x8d, 0xfc, 0x40, 0xc8, 0x37, 0x9e, 0xeb, 0xee, 0x1d, 0x70, 0x55, 0xaf, 0x3a, 0x37, 0xb1, 0xb7, 0x5b, 0x1a, 0x31, 0x8a, 0xb0, 0x49, 0x9c, 0x1e, 0x1d, 0x7e, 0x93, 0x7e, 0x85, 0x53, 0xd7, 0x1f, - 0x9f, 0xd7, 0x44, 0x19, 0x56, 0x50, 0x75, 0x74, 0xf4, 0xe4, 0x1d, 0x1d, 0xf6, 0x1f, 0xd1, 0x85, + 0x9f, 0xd7, 0x44, 0x19, 0x56, 0x50, 0x75, 0x74, 0xf4, 0xe4, 0x1d, 0x1d, 0xf6, 0x1f, 0xd3, 0x85, 0xe6, 0x37, 0x9a, 0xbe, 0x47, 0xbc, 0x68, 0xde, 0xf7, 0x6a, 0x5c, 0x32, 0xf5, 0x92, 0x21, 0x3a, 0x39, 0x9b, 0x10, 0x9d, 0x1c, 0x4b, 0xd7, 0xd0, 0xa4, 0x27, 0x1f, 0x86, 0xbe, 0x30, 0x72, 0xa2, 0x56, 0x28, 0x06, 0xee, 0x61, 0xb9, 0xec, 0x2a, 0xac, 0x74, 0x7f, 0xb7, 0x34, 0xa6, 0xaa, 0xf1, @@ -6870,17 +6870,17 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xdb, 0xbf, 0xc2, 0x8b, 0xb1, 0x84, 0xa3, 0x47, 0xa0, 0x97, 0x04, 0x81, 0x1f, 0x88, 0x6f, 0x1b, 0x11, 0x88, 0xbd, 0x8b, 0xb4, 0x10, 0x73, 0x98, 0xfd, 0x1f, 0x2c, 0x18, 0x53, 0x7d, 0xe5, 0x6d, 0x1d, 0xc2, 0x73, 0xed, 0x4d, 0x80, 0xaa, 0xfc, 0xc0, 0x90, 0x5d, 0xb3, 0x43, 0xcf, 0x9e, 0xcd, - 0xe4, 0x68, 0x52, 0xc3, 0x18, 0x53, 0x56, 0x45, 0x21, 0xd6, 0xa8, 0xd9, 0xbf, 0x61, 0xc1, 0x64, + 0xe4, 0x68, 0x52, 0xc3, 0x18, 0x53, 0x56, 0x45, 0x21, 0xd6, 0xa8, 0xd9, 0xbf, 0x69, 0xc1, 0x64, 0xe2, 0x8b, 0xae, 0xba, 0x61, 0x84, 0xde, 0x4a, 0x7d, 0xd5, 0x4c, 0x97, 0x8b, 0xcf, 0x0d, 0xf9, 0x37, 0xa9, 0x3d, 0x2f, 0x4b, 0xb4, 0x2f, 0xba, 0x0c, 0xbd, 0x6e, 0x44, 0x1a, 0xf2, 0x63, 0x1e, - 0x69, 0xfb, 0x31, 0xbc, 0x57, 0xf1, 0x8c, 0x2c, 0xd3, 0x9a, 0x98, 0x13, 0xb0, 0x7f, 0xbb, 0x08, + 0x69, 0xfb, 0x31, 0xbc, 0x57, 0xf1, 0x8c, 0x2c, 0xd3, 0x9a, 0x98, 0x13, 0xb0, 0x7f, 0xa7, 0x08, 0x83, 0x7c, 0x7f, 0xaf, 0x38, 0xcd, 0x43, 0x98, 0x8b, 0xa7, 0x60, 0xd0, 0x6d, 0x34, 0x5a, 0x91, 0x73, 0x4b, 0xdc, 0x7b, 0x03, 0xfc, 0x0c, 0x5a, 0x96, 0x85, 0x38, 0x86, 0xa3, 0x65, 0xe8, 0x61, 0x5d, 0xe1, 0x5f, 0xf9, 0x78, 0xf6, 0x57, 0x8a, 0xbe, 0xcf, 0x2c, 0x38, 0x91, 0xc3, 0x59, 0x4e, 0xb5, 0xaf, 0x68, 0x11, 0x66, 0x24, 0x90, 0x03, 0x70, 0xcb, 0xf5, 0x9c, 0x60, 0x87, 0x96, 0x4d, 0x15, 0x19, 0xc1, 0x67, 0xda, 0x13, 0x9c, 0x53, 0xf8, 0x9c, 0xac, 0xfa, 0xb0, 0x18, 0x80, 0x35, 0xa2, 0xd3, 0x2f, 0xc2, 0xa0, 0x42, 0x3e, 0x08, 0xe7, 0x38, 0xfd, 0x11, 0x18, 0x4b, 0xb4, 0xd5, - 0xa9, 0xfa, 0xb0, 0xce, 0x78, 0xfe, 0x1a, 0x3b, 0x32, 0x44, 0xaf, 0x17, 0xbd, 0x6d, 0x71, 0x37, + 0xa9, 0xfa, 0xb0, 0xce, 0x78, 0xfe, 0x3a, 0x3b, 0x32, 0x44, 0xaf, 0x17, 0xbd, 0x6d, 0x71, 0x37, 0xdd, 0x85, 0x23, 0xf5, 0x8c, 0x23, 0x5f, 0xcc, 0x6b, 0xf7, 0x57, 0xc4, 0x49, 0xf1, 0xd9, 0x47, 0xb2, 0xa0, 0x38, 0xb3, 0x0d, 0xe3, 0x44, 0x2c, 0xb4, 0x3b, 0x11, 0xe9, 0x79, 0x77, 0x44, 0x75, 0xfe, 0x0a, 0xd9, 0x51, 0x87, 0xea, 0xb7, 0xb2, 0xfb, 0xa7, 0xf8, 0xe8, 0xf3, 0xe3, 0x72, 0x48, @@ -6893,9 +6893,9 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x5e, 0xc0, 0xb4, 0x32, 0x9a, 0x85, 0x31, 0xa9, 0x55, 0xbb, 0x41, 0xf9, 0x52, 0xdf, 0x13, 0xf7, 0x90, 0x12, 0x96, 0x63, 0x13, 0x8c, 0x93, 0xf8, 0x68, 0x01, 0xc6, 0xb7, 0x5a, 0xb7, 0x48, 0x9d, 0x44, 0xfc, 0x83, 0xaf, 0x10, 0x2e, 0x4a, 0x1e, 0x8c, 0x9f, 0xb0, 0x57, 0x12, 0x70, 0x9c, 0xaa, - 0x61, 0xff, 0x0d, 0xbb, 0x0f, 0xc4, 0xe8, 0x69, 0xfc, 0xcd, 0xb7, 0x72, 0x39, 0x77, 0xb3, 0x2a, + 0x61, 0xff, 0x2d, 0xbb, 0x0f, 0xc4, 0xe8, 0x69, 0xfc, 0xcd, 0xb7, 0x72, 0x39, 0x77, 0xb3, 0x2a, 0xae, 0x90, 0x9d, 0x35, 0x9f, 0xf2, 0x21, 0xd9, 0xab, 0xc2, 0x58, 0xf3, 0x3d, 0x6d, 0xd7, 0xfc, - 0x2f, 0x15, 0xe0, 0xa8, 0x1a, 0x01, 0x83, 0x5b, 0xfe, 0x76, 0x1f, 0x83, 0x0b, 0x30, 0x54, 0x23, + 0x2f, 0x17, 0xe0, 0xa8, 0x1a, 0x01, 0x83, 0x5b, 0xfe, 0x76, 0x1f, 0x83, 0x0b, 0x30, 0x54, 0x23, 0xeb, 0x4e, 0xab, 0x1e, 0x29, 0xbd, 0x46, 0x2f, 0x57, 0xb5, 0x2d, 0xc4, 0xc5, 0x58, 0xc7, 0x39, 0xc0, 0xb0, 0xfd, 0xc2, 0x08, 0xbb, 0x88, 0x23, 0x87, 0xae, 0x71, 0xb5, 0x6b, 0xac, 0xdc, 0x5d, 0xf3, 0x08, 0xf4, 0xba, 0x0d, 0xca, 0x98, 0x15, 0x4c, 0x7e, 0x6b, 0x99, 0x16, 0x62, 0x0e, 0x43, @@ -6939,7 +6939,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x85, 0x81, 0x5e, 0x86, 0x91, 0xaa, 0xde, 0x80, 0xb8, 0xd4, 0xd5, 0x31, 0x62, 0xb4, 0x8e, 0x4d, 0x5c, 0x74, 0x11, 0x06, 0x98, 0x8d, 0x53, 0xd5, 0xaf, 0x0b, 0x6e, 0x53, 0x72, 0x26, 0x03, 0x65, 0x51, 0xbe, 0xaf, 0xfd, 0xc6, 0x0a, 0x1b, 0x9d, 0x85, 0x3e, 0xda, 0x85, 0xe5, 0xb2, 0xb8, 0x4e, - 0x95, 0x24, 0xf0, 0x32, 0x2b, 0xc5, 0x02, 0x6a, 0xff, 0x86, 0xc5, 0x78, 0xa9, 0xf4, 0x99, 0x8f, + 0x95, 0x24, 0xf0, 0x32, 0x2b, 0xc5, 0x02, 0x6a, 0xff, 0xa6, 0xc5, 0x78, 0xa9, 0xf4, 0x99, 0x8f, 0x2e, 0xb3, 0x4b, 0x83, 0xdd, 0x20, 0x9a, 0x16, 0xfe, 0x51, 0xed, 0x26, 0x50, 0xb0, 0xfd, 0xc4, 0x7f, 0x6c, 0xd4, 0x44, 0x6f, 0x26, 0x6f, 0x06, 0xce, 0x50, 0x3c, 0x2f, 0x87, 0x20, 0x79, 0x3b, 0x3c, 0x14, 0x5f, 0x71, 0xb4, 0x3f, 0xed, 0xae, 0x08, 0xfb, 0x47, 0x0a, 0xda, 0x2a, 0xa9, 0x44, @@ -6949,7 +6949,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x90, 0x27, 0x04, 0xa9, 0x09, 0xd9, 0xe1, 0xd3, 0x9d, 0x89, 0xae, 0xa9, 0x3a, 0x5c, 0x38, 0x19, 0xff, 0xc7, 0x1a, 0x3d, 0x3b, 0xd2, 0xe6, 0x54, 0xef, 0x0c, 0xfa, 0x38, 0xdd, 0xa2, 0x4e, 0x10, 0x91, 0xda, 0x6c, 0x24, 0x06, 0xe7, 0xc9, 0xee, 0x1e, 0x87, 0x6b, 0x6e, 0x83, 0xe8, 0xdb, 0x59, - 0x10, 0xc1, 0x31, 0x3d, 0xfb, 0x57, 0x8a, 0x30, 0x95, 0xd7, 0x5d, 0xba, 0x69, 0xc8, 0x1d, 0x37, + 0x10, 0xc1, 0x31, 0x3d, 0xfb, 0x57, 0x8b, 0x30, 0x95, 0xd7, 0x5d, 0xba, 0x69, 0xc8, 0x1d, 0x37, 0x9a, 0xa7, 0x6c, 0xad, 0x65, 0x6e, 0x9a, 0x45, 0x51, 0x8e, 0x15, 0x06, 0x5d, 0xbd, 0xa1, 0xbb, 0x21, 0xdf, 0xf6, 0xbd, 0xf1, 0xea, 0xad, 0xb0, 0x52, 0x2c, 0xa0, 0x14, 0x2f, 0x20, 0x4e, 0x28, 0x8c, 0xef, 0xb4, 0x55, 0x8e, 0x59, 0x29, 0x16, 0x50, 0x5d, 0xca, 0xd8, 0xd3, 0x41, 0xca, 0x68, @@ -6967,7 +6967,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x43, 0x5f, 0x7d, 0x62, 0x51, 0x33, 0xb3, 0x8b, 0x01, 0x7e, 0xca, 0x89, 0x25, 0x8f, 0x25, 0x0c, 0xfd, 0xac, 0x05, 0xc8, 0xa9, 0xd3, 0xd7, 0x32, 0x2d, 0x56, 0x8f, 0x1b, 0x60, 0xac, 0xf6, 0xcb, 0x1d, 0x87, 0xbd, 0x15, 0xce, 0xcc, 0xa6, 0x6a, 0x73, 0x49, 0xe9, 0x4b, 0xa2, 0x8b, 0x28, 0x8d, - 0xa0, 0x5f, 0x46, 0x57, 0xdd, 0x30, 0xfa, 0xec, 0x1f, 0x27, 0x2e, 0xa7, 0x8c, 0x2e, 0xa1, 0xeb, + 0xa0, 0x5f, 0x46, 0x57, 0xdd, 0x30, 0xfa, 0xec, 0x9f, 0x24, 0x2e, 0xa7, 0x8c, 0x2e, 0xa1, 0xeb, 0xfa, 0xe3, 0x6b, 0xe8, 0x80, 0x8f, 0xaf, 0x91, 0xdc, 0x87, 0xd7, 0x77, 0x26, 0x1e, 0x30, 0xc3, 0xec, 0xcb, 0x1f, 0xeb, 0xf0, 0x80, 0x11, 0xe2, 0xf4, 0x6e, 0x9e, 0x31, 0x65, 0xa1, 0x07, 0x1e, 0x61, 0x5d, 0x6e, 0xff, 0x08, 0xbe, 0x1e, 0x92, 0x60, 0xee, 0x84, 0x54, 0x13, 0xef, 0xeb, 0xbc, @@ -6987,7 +6987,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x5b, 0x84, 0x26, 0x71, 0x66, 0xc2, 0x8d, 0x13, 0x64, 0x70, 0x8a, 0x30, 0x3a, 0x09, 0x3d, 0x0d, 0xca, 0x9f, 0xf4, 0xb0, 0xe1, 0x67, 0x42, 0x2a, 0x26, 0x6f, 0x63, 0xa5, 0xf6, 0x4f, 0x58, 0x70, 0x3c, 0x35, 0x32, 0x42, 0xee, 0x78, 0x9f, 0x67, 0x21, 0x29, 0x07, 0x2c, 0x74, 0x96, 0x03, 0xda, - 0xff, 0xc8, 0x82, 0x23, 0x8b, 0x8d, 0x66, 0xb4, 0xb3, 0xe0, 0x9a, 0x16, 0x04, 0x2f, 0x42, 0x5f, + 0xff, 0xc4, 0x82, 0x23, 0x8b, 0x8d, 0x66, 0xb4, 0xb3, 0xe0, 0x9a, 0x16, 0x04, 0x2f, 0x42, 0x5f, 0x83, 0xd4, 0xdc, 0x56, 0x43, 0xcc, 0x5c, 0x49, 0xde, 0xe1, 0x2b, 0xac, 0x94, 0x9e, 0x03, 0x95, 0xc8, 0x0f, 0x9c, 0x0d, 0xc2, 0x0b, 0xb0, 0x40, 0x67, 0x9c, 0x90, 0x7b, 0x97, 0x5c, 0x75, 0x1b, 0x6e, 0x74, 0x6f, 0xbb, 0x4b, 0x28, 0xff, 0x25, 0x11, 0x1c, 0xd3, 0xb3, 0xbf, 0x61, 0xc1, 0x98, @@ -6995,17 +6995,17 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x65, 0x61, 0xb9, 0x8c, 0x0b, 0x6e, 0x53, 0x3e, 0xba, 0x18, 0x9b, 0x50, 0x34, 0xed, 0x20, 0x2e, 0x8b, 0x72, 0xac, 0x30, 0xd0, 0x39, 0x18, 0xf0, 0xfc, 0x1a, 0x7f, 0xb7, 0x08, 0x4d, 0x38, 0xc5, 0x5c, 0x15, 0x65, 0x58, 0x41, 0x51, 0x19, 0x06, 0xb9, 0x95, 0x6c, 0xbc, 0x68, 0xbb, 0xb2, 0xb5, - 0x65, 0x5f, 0xb6, 0x26, 0x6b, 0xe2, 0x98, 0x88, 0xfd, 0x5b, 0x16, 0x0c, 0xcb, 0x2f, 0xeb, 0xf2, + 0x65, 0x5f, 0xb6, 0x26, 0x6b, 0xe2, 0x98, 0x88, 0xfd, 0xdb, 0x16, 0x0c, 0xcb, 0x2f, 0xeb, 0xf2, 0x45, 0x49, 0xb7, 0x56, 0xfc, 0x9a, 0x8c, 0xb7, 0x16, 0x7d, 0x11, 0x32, 0x88, 0xf1, 0x10, 0x2c, 0x1e, 0xe8, 0x21, 0x78, 0x01, 0x86, 0x9c, 0x66, 0xb3, 0x6c, 0xbe, 0x22, 0xd9, 0x52, 0x9a, 0x8d, 0x8b, 0xb1, 0x8e, 0x63, 0xff, 0x78, 0x01, 0x46, 0xe5, 0x17, 0x54, 0x5a, 0xb7, 0x42, 0x12, 0xa1, 0x35, 0x18, 0x74, 0xf8, 0x2c, 0x11, 0xb9, 0xc8, 0x1f, 0xc9, 0x96, 0x6e, 0x1a, 0x53, 0x1a, 0xb3, 0xc3, 0xb3, 0xb2, 0x36, 0x8e, 0x09, 0xa1, 0x3a, 0x4c, 0x78, 0x7e, 0xc4, 0x58, 0x23, 0x05, 0x6f, 0xa7, 0x70, 0x4e, 0x52, 0x3f, 0x21, 0xa8, 0x4f, 0xac, 0x26, 0xa9, 0xe0, 0x34, 0x61, 0xb4, 0x28, - 0x25, 0xc6, 0xc5, 0x7c, 0x51, 0x9f, 0x3e, 0x71, 0xd9, 0x02, 0x63, 0xfb, 0xd7, 0x2d, 0x18, 0x94, + 0x25, 0xc6, 0xc5, 0x7c, 0x51, 0x9f, 0x3e, 0x71, 0xd9, 0x02, 0x63, 0xfb, 0x37, 0x2c, 0x18, 0x94, 0x68, 0x87, 0x61, 0x5b, 0xb0, 0x02, 0xfd, 0x21, 0x9b, 0x04, 0x39, 0x34, 0x76, 0xbb, 0x8e, 0xf3, 0xf9, 0x8a, 0x39, 0x3e, 0xfe, 0x3f, 0xc4, 0x92, 0x06, 0x53, 0x18, 0xaa, 0xee, 0xbf, 0x4b, 0x14, - 0x86, 0xaa, 0x3f, 0x39, 0x97, 0xd2, 0x9f, 0xb2, 0x3e, 0x6b, 0x12, 0x78, 0xfa, 0x30, 0x69, 0x06, + 0x86, 0xaa, 0x3f, 0x39, 0x97, 0xd2, 0x9f, 0xb1, 0x3e, 0x6b, 0x12, 0x78, 0xfa, 0x30, 0x69, 0x06, 0x64, 0xdd, 0xbd, 0x93, 0x7c, 0x98, 0x94, 0x59, 0x29, 0x16, 0x50, 0xf4, 0x16, 0x0c, 0x57, 0xa5, 0xa6, 0x28, 0xde, 0xe1, 0x67, 0xdb, 0x6a, 0x2d, 0x95, 0x82, 0x9b, 0x4b, 0x3a, 0xe7, 0xb5, 0xfa, 0xd8, 0xa0, 0x66, 0x5a, 0x81, 0x15, 0x3b, 0x59, 0x81, 0xc5, 0x74, 0xf3, 0x6d, 0xa2, 0x7e, 0xd2, @@ -7015,15 +7015,15 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xeb, 0xc1, 0x5d, 0xfa, 0x85, 0x07, 0x75, 0xe9, 0x6f, 0xc0, 0x58, 0x55, 0xb3, 0x0e, 0x88, 0x67, 0xf2, 0x5c, 0xdb, 0x45, 0xa2, 0x19, 0x12, 0x70, 0x19, 0xea, 0xbc, 0x49, 0x04, 0x27, 0xa9, 0xa2, 0x8f, 0xc3, 0x30, 0x9f, 0x67, 0xd1, 0x0a, 0x37, 0xa4, 0x7b, 0x2c, 0x7f, 0xbd, 0xe8, 0x4d, 0x70, - 0x99, 0xbb, 0x56, 0x1d, 0x1b, 0xc4, 0xec, 0xbf, 0xb4, 0x00, 0x2d, 0x36, 0x37, 0x49, 0x83, 0x04, + 0x99, 0xbb, 0x56, 0x1d, 0x1b, 0xc4, 0xec, 0xbf, 0xb2, 0x00, 0x2d, 0x36, 0x37, 0x49, 0x83, 0x04, 0x4e, 0x3d, 0x56, 0xf2, 0x7d, 0xc1, 0x82, 0x29, 0x92, 0x2a, 0x9e, 0xf7, 0x1b, 0x0d, 0xf1, 0xa4, 0xcf, 0x91, 0x3a, 0x2d, 0xe6, 0xd4, 0x89, 0xd9, 0xfa, 0x3c, 0x0c, 0x9c, 0xdb, 0x1e, 0x5a, 0x81, 0x49, 0x7e, 0x4b, 0x2a, 0x80, 0x66, 0x6b, 0xf7, 0x90, 0x20, 0x3c, 0xb9, 0x96, 0x46, 0xc1, 0x59, - 0xf5, 0xec, 0x5f, 0x1f, 0x81, 0xdc, 0x5e, 0xbc, 0xaf, 0xdd, 0x7c, 0x5f, 0xbb, 0xf9, 0xbe, 0x76, - 0xf3, 0x7d, 0xed, 0xe6, 0xfb, 0xda, 0xcd, 0xf7, 0xb5, 0x9b, 0xef, 0x52, 0xed, 0xe6, 0xdf, 0xb6, + 0xf5, 0xec, 0xdf, 0x18, 0x81, 0xdc, 0x5e, 0xbc, 0xaf, 0xdd, 0x7c, 0x5f, 0xbb, 0xf9, 0xbe, 0x76, + 0xf3, 0x7d, 0xed, 0xe6, 0xfb, 0xda, 0xcd, 0xf7, 0xb5, 0x9b, 0xef, 0x52, 0xed, 0xe6, 0xdf, 0xb5, 0xe0, 0xa8, 0xba, 0xbe, 0x8c, 0x07, 0xfb, 0x67, 0x60, 0x92, 0x6f, 0xb7, 0xf9, 0xba, 0xe3, 0x36, 0xd6, 0x48, 0xa3, 0x59, 0x77, 0x22, 0x69, 0xc3, 0x74, 0x21, 0x73, 0xe5, 0x26, 0x1c, 0x25, 0x8c, - 0x8a, 0xdc, 0xe3, 0x2c, 0x03, 0x80, 0xb3, 0x9a, 0xb1, 0x7f, 0x65, 0x00, 0x7a, 0x17, 0xb7, 0x89, + 0x8a, 0xdc, 0xe3, 0x2c, 0x03, 0x80, 0xb3, 0x9a, 0xb1, 0x7f, 0x75, 0x00, 0x7a, 0x17, 0xb7, 0x89, 0x17, 0x1d, 0xc2, 0xd3, 0xa6, 0x0a, 0xa3, 0xae, 0xb7, 0xed, 0xd7, 0xb7, 0x49, 0x8d, 0xc3, 0x0f, 0xf2, 0x02, 0x3f, 0x26, 0x48, 0x8f, 0x2e, 0x1b, 0x24, 0x70, 0x82, 0xe4, 0x83, 0xd0, 0x11, 0x5d, 0x82, 0x3e, 0x7e, 0xf9, 0x08, 0x05, 0x51, 0xe6, 0x99, 0xcd, 0x06, 0x51, 0x5c, 0xa9, 0xb1, 0xfe, @@ -7046,7 +7046,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x09, 0xfb, 0x53, 0xb2, 0xab, 0xca, 0x3e, 0xba, 0xaa, 0xe6, 0x3c, 0x61, 0x1f, 0xad, 0x66, 0x15, 0xc7, 0x38, 0x74, 0xab, 0x6d, 0xfa, 0x61, 0x94, 0xb4, 0x8f, 0xbe, 0xec, 0x87, 0x11, 0x66, 0x10, 0xfb, 0x39, 0x80, 0xc5, 0x3b, 0xa4, 0xca, 0x57, 0xac, 0xfe, 0xe8, 0xb1, 0xf2, 0x1f, 0x3d, 0xf6, - 0x1f, 0x58, 0x30, 0xba, 0x34, 0x6f, 0xdc, 0x5c, 0x33, 0x00, 0xfc, 0xa5, 0x76, 0xf3, 0xe6, 0xaa, + 0x1f, 0x5a, 0x30, 0xba, 0x34, 0x6f, 0xdc, 0x5c, 0x33, 0x00, 0xfc, 0xa5, 0x76, 0xf3, 0xe6, 0xaa, 0x34, 0xd2, 0xe1, 0x76, 0x0a, 0xaa, 0x14, 0x6b, 0x18, 0xe8, 0x04, 0x14, 0xeb, 0x2d, 0x4f, 0x88, 0x3d, 0xfb, 0xe9, 0xf5, 0x78, 0xb5, 0xe5, 0x61, 0x5a, 0xa6, 0x79, 0xb2, 0x15, 0xbb, 0xf6, 0x64, 0xeb, 0x18, 0x50, 0x07, 0x95, 0xa0, 0xf7, 0xf6, 0x6d, 0xb7, 0xc6, 0xe3, 0x04, 0x08, 0x03, 0xa2, @@ -7058,15 +7058,15 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x7b, 0xbe, 0x76, 0x9e, 0x8d, 0xb7, 0x92, 0xb3, 0x71, 0x21, 0x6f, 0x36, 0x0e, 0x7b, 0x0e, 0xbe, 0xcf, 0x82, 0xc9, 0xa5, 0xba, 0x5f, 0xdd, 0x4a, 0x78, 0xa7, 0xbe, 0x00, 0x43, 0xf4, 0x38, 0x0e, 0x8d, 0x40, 0x2d, 0x46, 0xe8, 0x1e, 0x01, 0xc2, 0x3a, 0x9e, 0x56, 0xed, 0xfa, 0xf5, 0xe5, 0x85, - 0xac, 0x88, 0x3f, 0x02, 0x84, 0x75, 0x3c, 0xfb, 0xf7, 0x2c, 0x38, 0x75, 0x69, 0x7e, 0x31, 0x5e, + 0xac, 0x88, 0x3f, 0x02, 0x84, 0x75, 0x3c, 0xfb, 0xf7, 0x2d, 0x38, 0x75, 0x69, 0x7e, 0x31, 0x5e, 0x8a, 0xa9, 0xa0, 0x43, 0x67, 0xa1, 0xaf, 0x59, 0xd3, 0xba, 0x12, 0x8b, 0x85, 0x17, 0x58, 0x2f, 0x04, 0xf4, 0xdd, 0x12, 0xdf, 0xeb, 0x3a, 0xc0, 0x25, 0x5c, 0x9e, 0x17, 0xe7, 0xae, 0xd4, 0x02, 0x59, 0xb9, 0x5a, 0xa0, 0xc7, 0xa0, 0x9f, 0xde, 0x0b, 0x6e, 0x55, 0xf6, 0x9b, 0x9b, 0x5d, 0xf0, 0x22, 0x2c, 0x61, 0xf6, 0xcf, 0x59, 0x30, 0x79, 0xc9, 0x8d, 0xe8, 0xa5, 0x9d, 0x8c, 0xaa, 0x43, 0x6f, 0xed, 0xd0, 0x8d, 0xfc, 0x60, 0x27, 0x19, 0x55, 0x07, 0x2b, 0x08, 0xd6, 0xb0, 0xf8, 0x07, 0x6d, 0xbb, 0xcc, 0xdf, 0xa5, 0x60, 0xea, 0xdd, 0xb0, 0x28, 0xc7, 0x0a, 0x83, 0x8e, 0x57, 0xcd, - 0x0d, 0x98, 0xc8, 0x72, 0x47, 0x1c, 0xdc, 0x6a, 0xbc, 0x16, 0x24, 0x00, 0xc7, 0x38, 0xf6, 0x9f, - 0x5b, 0x50, 0xba, 0xc4, 0xbd, 0x76, 0xd7, 0xc3, 0x9c, 0x43, 0xf7, 0x39, 0x18, 0x24, 0x52, 0x41, + 0x0d, 0x98, 0xc8, 0x72, 0x47, 0x1c, 0xdc, 0x6a, 0xbc, 0x16, 0x24, 0x00, 0xc7, 0x38, 0xf6, 0x5f, + 0x58, 0x50, 0xba, 0xc4, 0xbd, 0x76, 0xd7, 0xc3, 0x9c, 0x43, 0xf7, 0x39, 0x18, 0x24, 0x52, 0x41, 0x20, 0x7a, 0xad, 0x18, 0x51, 0xa5, 0x39, 0xe0, 0xc1, 0x7d, 0x14, 0x5e, 0x17, 0x2e, 0xf4, 0x07, 0xf3, 0x81, 0x5e, 0x02, 0x44, 0xf4, 0xb6, 0xf4, 0x68, 0x47, 0x2c, 0x6c, 0xca, 0x62, 0x0a, 0x8a, 0x33, 0x6a, 0xd8, 0x3f, 0x61, 0xc1, 0x51, 0xf5, 0xc1, 0xef, 0xba, 0xcf, 0xb4, 0xbf, 0x5a, 0x80, @@ -7080,7 +7080,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xeb, 0xae, 0xd3, 0x5e, 0x35, 0xfe, 0x14, 0x0c, 0x4a, 0xc5, 0x77, 0x28, 0x42, 0x7c, 0xb0, 0x1b, 0x49, 0xea, 0xc5, 0x43, 0x1c, 0xc3, 0xed, 0x47, 0x41, 0x58, 0x00, 0xb7, 0x23, 0x69, 0xaf, 0xc3, 0x11, 0x66, 0xca, 0xec, 0x44, 0x9b, 0xc6, 0x1a, 0xed, 0xbc, 0x18, 0x9e, 0x16, 0xef, 0x3a, 0xfe, - 0x65, 0x53, 0x9a, 0x0b, 0xf9, 0xb0, 0xa4, 0x18, 0xbf, 0xf1, 0xec, 0x3f, 0xeb, 0x81, 0x87, 0x96, + 0x65, 0x53, 0x9a, 0x0b, 0xf9, 0xb0, 0xa4, 0x18, 0xbf, 0xf1, 0xec, 0x3f, 0xef, 0x81, 0x87, 0x96, 0x2b, 0xf9, 0xb1, 0xa9, 0x2e, 0xc2, 0x30, 0x67, 0x17, 0xe9, 0xd2, 0x70, 0xea, 0xa2, 0x5d, 0x25, 0x01, 0x5d, 0xd3, 0x60, 0xd8, 0xc0, 0x44, 0xa7, 0xa0, 0xe8, 0xbe, 0xed, 0x25, 0x1d, 0x2c, 0x97, 0xdf, 0x58, 0xc5, 0xb4, 0x9c, 0x82, 0x29, 0xe7, 0xc9, 0x8f, 0x74, 0x05, 0x56, 0xdc, 0xe7, 0xab, @@ -7106,7 +7106,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x4e, 0x14, 0x61, 0x59, 0x9d, 0x19, 0xa4, 0x55, 0x9b, 0x15, 0xfa, 0xd6, 0x8a, 0xda, 0x89, 0x04, 0xd6, 0xe6, 0xcb, 0x1c, 0x49, 0x50, 0xe3, 0x06, 0x69, 0xb2, 0x10, 0xc7, 0x44, 0xd0, 0x6b, 0xd0, 0x1b, 0xd6, 0x09, 0x69, 0x0a, 0x8b, 0x83, 0x4c, 0x29, 0x67, 0x85, 0x22, 0x08, 0x4a, 0x4c, 0x2a, - 0xc2, 0x0a, 0x30, 0xaf, 0x68, 0xff, 0x92, 0x05, 0xc0, 0x2d, 0xf8, 0x1c, 0x6f, 0x83, 0x1c, 0x82, + 0xc2, 0x0a, 0x30, 0xaf, 0x68, 0xff, 0xb2, 0x05, 0xc0, 0x2d, 0xf8, 0x1c, 0x6f, 0x83, 0x1c, 0x82, 0x62, 0x60, 0x01, 0x7a, 0xc2, 0x26, 0xa9, 0xb6, 0xb3, 0xf6, 0x8f, 0xfb, 0x53, 0x69, 0x92, 0x6a, 0xbc, 0x66, 0xe9, 0x3f, 0xcc, 0x6a, 0xdb, 0xdf, 0x0f, 0x30, 0x1a, 0xa3, 0x2d, 0x47, 0xa4, 0x81, 0x9e, 0x31, 0xa2, 0xdc, 0x9c, 0x48, 0x44, 0xb9, 0x19, 0x64, 0xd8, 0x9a, 0x0c, 0xfa, 0xd3, 0x50, @@ -7114,7 +7114,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0x1d, 0xfe, 0x94, 0xdc, 0x63, 0x2b, 0xce, 0x9d, 0x8e, 0x16, 0xe9, 0xb4, 0x11, 0xd6, 0x96, 0xeb, 0x09, 0xe3, 0xb4, 0xae, 0xda, 0x72, 0xbd, 0x64, 0x5b, 0xae, 0xd7, 0x45, 0x5b, 0xae, 0x87, 0xee, 0x42, 0xbf, 0xb0, 0x1d, 0x15, 0xe1, 0xf7, 0xce, 0x77, 0xd1, 0x9e, 0x30, 0x3d, 0xe5, 0x6d, 0x9e, - 0x97, 0x72, 0x06, 0x51, 0xda, 0xb1, 0x5d, 0xd9, 0x20, 0xfa, 0x3b, 0x16, 0x8c, 0x8a, 0xdf, 0x98, + 0x97, 0x72, 0x06, 0x51, 0xda, 0xb1, 0x5d, 0xd9, 0x20, 0xfa, 0x7b, 0x16, 0x8c, 0x8a, 0xdf, 0x98, 0xbc, 0xdd, 0x22, 0x61, 0x24, 0xf8, 0xf0, 0x0f, 0x75, 0xdf, 0x07, 0x51, 0x91, 0x77, 0xe5, 0x43, 0xf2, 0xca, 0x34, 0x81, 0x1d, 0x7b, 0x94, 0xe8, 0x05, 0xfa, 0x45, 0x0b, 0x8e, 0x34, 0x9c, 0x3b, 0xbc, 0x45, 0x5e, 0x86, 0x9d, 0xc8, 0xf5, 0x85, 0x0d, 0xc6, 0x2b, 0xdd, 0x4d, 0x7f, 0xaa, 0x3a, @@ -7128,7 +7128,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xe6, 0x93, 0x54, 0x10, 0x98, 0x53, 0x50, 0xdc, 0x70, 0x6b, 0xc2, 0xb3, 0x58, 0x81, 0x2f, 0x51, 0xf0, 0x86, 0x5b, 0x43, 0x4b, 0x80, 0xc2, 0x56, 0xb3, 0x59, 0x67, 0x66, 0x4b, 0x4e, 0xfd, 0x52, 0xe0, 0xb7, 0x9a, 0xdc, 0xdc, 0xb8, 0xc8, 0x85, 0x44, 0x95, 0x14, 0x14, 0x67, 0xd4, 0xb0, 0x7f, - 0xd5, 0x82, 0x9e, 0x43, 0x98, 0x26, 0x6c, 0x4e, 0xd3, 0x33, 0xb9, 0xa4, 0x45, 0xd6, 0x86, 0x19, + 0xcd, 0x82, 0x9e, 0x43, 0x98, 0x26, 0x6c, 0x4e, 0xd3, 0x33, 0xb9, 0xa4, 0x45, 0xd6, 0x86, 0x19, 0xec, 0xdc, 0x5e, 0xbc, 0x13, 0x11, 0x2f, 0x64, 0x0c, 0x47, 0xe6, 0xac, 0xed, 0x5a, 0x30, 0x79, 0xd5, 0x77, 0x6a, 0x73, 0x4e, 0xdd, 0xf1, 0xaa, 0x24, 0x58, 0xf6, 0x36, 0x0e, 0x64, 0xdb, 0x5f, 0xe8, 0x68, 0xdb, 0x7f, 0x11, 0xfa, 0xdc, 0xa6, 0x16, 0xf6, 0xfd, 0x0c, 0x9d, 0xdd, 0xe5, 0xb2, @@ -7141,7 +7141,7 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xca, 0xed, 0x7c, 0xdd, 0x09, 0x43, 0x4d, 0x22, 0xff, 0xb8, 0x68, 0xb7, 0xb4, 0xd6, 0x1e, 0x1d, 0x77, 0xa2, 0x87, 0xde, 0x48, 0x04, 0x1d, 0xfc, 0x70, 0x2a, 0xe8, 0xe0, 0xe3, 0x99, 0x76, 0x31, 0xe9, 0xde, 0xcb, 0x60, 0x84, 0xf6, 0xe7, 0x2d, 0x18, 0x5b, 0x4d, 0x44, 0x6d, 0x3d, 0xcb, 0x8c, - 0x04, 0x32, 0x34, 0x4d, 0x15, 0x56, 0x8a, 0x05, 0xf4, 0xbe, 0x4b, 0x62, 0xff, 0xc6, 0x82, 0x38, + 0x04, 0x32, 0x34, 0x4d, 0x15, 0x56, 0x8a, 0x05, 0xf4, 0xbe, 0x4b, 0x62, 0xff, 0xd6, 0x82, 0x38, 0xdc, 0xd5, 0x21, 0xb0, 0xdc, 0xf3, 0x06, 0xcb, 0x9d, 0xf9, 0x7c, 0x51, 0xdd, 0xc9, 0xe3, 0xb8, 0xd1, 0x15, 0x35, 0x27, 0x6d, 0x5e, 0x2e, 0x31, 0x19, 0xbe, 0xcf, 0x46, 0xcd, 0x89, 0x53, 0xb3, 0xf1, 0xf5, 0x02, 0x20, 0x85, 0xdb, 0x75, 0xa0, 0xca, 0x74, 0x8d, 0xfb, 0x13, 0xa8, 0x72, 0x1b, @@ -7152,617 +7152,618 @@ var fileDescriptor_6c07b07c062484ab = []byte{ 0xe2, 0x29, 0x97, 0x84, 0x6b, 0xbc, 0x28, 0xdd, 0xdf, 0x2d, 0x8d, 0xa8, 0x7f, 0x3c, 0x82, 0x6b, 0x5c, 0xc5, 0xfe, 0x69, 0xba, 0xd9, 0xcd, 0xa5, 0x88, 0x5e, 0x80, 0xde, 0xe6, 0xa6, 0x13, 0x92, 0x84, 0xab, 0x5c, 0x6f, 0x99, 0x16, 0xee, 0xef, 0x96, 0x46, 0x55, 0x05, 0x56, 0x82, 0x39, 0x76, - 0xf7, 0xe1, 0x3f, 0xd3, 0x8b, 0xb3, 0x63, 0xf8, 0xcf, 0xbf, 0xb4, 0xa0, 0x67, 0x95, 0xde, 0x5e, + 0xf7, 0xe1, 0x3f, 0xd3, 0x8b, 0xb3, 0x63, 0xf8, 0xcf, 0xbf, 0xb2, 0xa0, 0x67, 0x95, 0xde, 0x5e, 0x0f, 0xfe, 0x08, 0x78, 0xd5, 0x38, 0x02, 0x4e, 0xe6, 0x65, 0x16, 0xca, 0xdd, 0xfd, 0x4b, 0x89, 0xdd, 0x7f, 0x3a, 0x97, 0x42, 0xfb, 0x8d, 0xdf, 0x80, 0x21, 0x96, 0xaf, 0x48, 0xb8, 0x05, 0x3e, 0x67, 0x6c, 0xf8, 0x52, 0x62, 0xc3, 0x8f, 0x69, 0xa8, 0xda, 0x4e, 0x7f, 0x02, 0xfa, 0x85, 0x9f, - 0x59, 0x32, 0x22, 0x81, 0xc0, 0xc5, 0x12, 0x6e, 0xff, 0x64, 0x11, 0x8c, 0xfc, 0x48, 0xe8, 0xd7, - 0x2d, 0x98, 0x09, 0xb8, 0xfd, 0x79, 0x6d, 0xa1, 0x15, 0xb8, 0xde, 0x46, 0xa5, 0xba, 0x49, 0x6a, + 0x59, 0x32, 0x22, 0x81, 0xc0, 0xc5, 0x12, 0x6e, 0xff, 0x64, 0x11, 0x8c, 0xfc, 0x48, 0xe8, 0x37, + 0x2c, 0x98, 0x09, 0xb8, 0xfd, 0x79, 0x6d, 0xa1, 0x15, 0xb8, 0xde, 0x46, 0xa5, 0xba, 0x49, 0x6a, 0xad, 0xba, 0xeb, 0x6d, 0x2c, 0x6f, 0x78, 0xbe, 0x2a, 0x5e, 0xbc, 0x43, 0xaa, 0x2d, 0xa6, 0x1b, 0xee, 0x90, 0x8c, 0x49, 0xf9, 0x71, 0x3c, 0xbb, 0xb7, 0x5b, 0x9a, 0xc1, 0x07, 0xa2, 0x8d, 0x0f, - 0xd8, 0x17, 0xf4, 0x7b, 0x16, 0x9c, 0xe7, 0x79, 0x7a, 0xba, 0xef, 0x7f, 0x1b, 0x09, 0x47, 0x59, + 0xd8, 0x17, 0xf4, 0xfb, 0x16, 0x9c, 0xe7, 0x79, 0x7a, 0xba, 0xef, 0x7f, 0x1b, 0x09, 0x47, 0x59, 0x92, 0x8a, 0x89, 0xac, 0x91, 0xa0, 0x31, 0xf7, 0xa2, 0x18, 0xd0, 0xf3, 0xe5, 0x83, 0xb5, 0x85, - 0x0f, 0xda, 0x39, 0xfb, 0x5f, 0x14, 0x61, 0x44, 0x84, 0x89, 0x14, 0x77, 0xc0, 0x0b, 0xc6, 0x92, + 0x0f, 0xda, 0x39, 0xfb, 0x5f, 0x16, 0x61, 0x44, 0x84, 0x89, 0x14, 0x77, 0xc0, 0x0b, 0xc6, 0x92, 0x78, 0x38, 0xb1, 0x24, 0x26, 0x0c, 0xe4, 0xfb, 0x73, 0xfc, 0x87, 0x30, 0x41, 0x0f, 0xe7, 0xcb, 0xc4, 0x09, 0xa2, 0x5b, 0xc4, 0xe1, 0x56, 0x89, 0xc5, 0x03, 0x9f, 0xfe, 0x4a, 0x3c, 0x7e, 0x35, 0x49, 0x0c, 0xa7, 0xe9, 0xbf, 0x97, 0xee, 0x1c, 0x0f, 0xc6, 0x53, 0x91, 0x3e, 0xdf, 0x84, 0x41, 0xe5, 0x24, 0x25, 0x0e, 0x9d, 0xf6, 0x01, 0x73, 0x93, 0x14, 0xb8, 0xd0, 0x33, 0x76, 0xd0, 0x8b, - 0xc9, 0xd9, 0xff, 0xa4, 0x60, 0x34, 0xc8, 0x27, 0x71, 0x15, 0x06, 0x9c, 0x90, 0x05, 0xf1, 0xae, - 0xb5, 0x93, 0x4b, 0xa7, 0x9a, 0x61, 0x8e, 0x6a, 0xb3, 0xa2, 0x26, 0x56, 0x34, 0xd0, 0x65, 0x6e, - 0xfb, 0xb9, 0x4d, 0xda, 0x09, 0xa5, 0x53, 0xd4, 0x40, 0x5a, 0x87, 0x6e, 0x13, 0x2c, 0xea, 0xa3, - 0x4f, 0x70, 0xe3, 0xdc, 0x2b, 0x9e, 0x7f, 0xdb, 0xbb, 0xe4, 0xfb, 0x32, 0x24, 0x50, 0x77, 0x04, - 0x27, 0xa4, 0x49, 0xae, 0xaa, 0x8e, 0x4d, 0x6a, 0xdd, 0x85, 0xce, 0xfe, 0x0c, 0xb0, 0xbc, 0x24, - 0x66, 0x4c, 0x82, 0x10, 0x11, 0x18, 0x13, 0x31, 0x48, 0x65, 0x99, 0x18, 0xbb, 0xcc, 0xe7, 0xb7, - 0x59, 0x3b, 0xd6, 0xe3, 0x5c, 0x31, 0x49, 0xe0, 0x24, 0x4d, 0x7b, 0x93, 0x1f, 0xc2, 0x4b, 0xc4, - 0x89, 0x5a, 0x01, 0x09, 0xd1, 0x47, 0x61, 0x2a, 0xfd, 0x32, 0x16, 0xea, 0x10, 0x8b, 0x71, 0xcf, - 0x27, 0xf7, 0x76, 0x4b, 0x53, 0x95, 0x1c, 0x1c, 0x9c, 0x5b, 0xdb, 0xfe, 0x59, 0x0b, 0x98, 0x27, - 0xf8, 0x21, 0x70, 0x3e, 0x1f, 0x31, 0x39, 0x9f, 0xa9, 0xbc, 0xe9, 0xcc, 0x61, 0x7a, 0x9e, 0xe7, - 0x6b, 0xb8, 0x1c, 0xf8, 0x77, 0x76, 0x84, 0xed, 0x56, 0xe7, 0x67, 0x9c, 0xfd, 0x45, 0x0b, 0x58, - 0x12, 0x1f, 0xcc, 0x5f, 0xed, 0x52, 0xc1, 0xd1, 0xd9, 0x2c, 0xe1, 0xa3, 0x30, 0xb0, 0x2e, 0x86, - 0x3f, 0x43, 0xe8, 0x64, 0x74, 0xd8, 0xa4, 0x2d, 0x27, 0x4d, 0x78, 0x74, 0x8a, 0x7f, 0x58, 0x51, - 0xb3, 0xff, 0xb1, 0x05, 0xd3, 0xf9, 0xd5, 0xd0, 0x75, 0x38, 0x1e, 0x90, 0x6a, 0x2b, 0x08, 0xe9, - 0x96, 0x10, 0x0f, 0x20, 0xe1, 0x14, 0xc5, 0xa7, 0xfa, 0xa1, 0xbd, 0xdd, 0xd2, 0x71, 0x9c, 0x8d, - 0x82, 0xf3, 0xea, 0xa2, 0x97, 0x60, 0xb4, 0x15, 0x72, 0xce, 0x8f, 0x31, 0x5d, 0xa1, 0x88, 0x14, - 0xcd, 0xfc, 0x86, 0xae, 0x1b, 0x10, 0x9c, 0xc0, 0xb4, 0xbf, 0x8b, 0x2f, 0x47, 0x15, 0x2c, 0xba, - 0x01, 0x13, 0x9e, 0xf6, 0x9f, 0xde, 0x80, 0xf2, 0xa9, 0xff, 0x68, 0xa7, 0x5b, 0x9f, 0x5d, 0x97, - 0x9a, 0xaf, 0x7a, 0x82, 0x0c, 0x4e, 0x53, 0xb6, 0x7f, 0xca, 0x82, 0xe3, 0x3a, 0xa2, 0xe6, 0x0e, - 0xd7, 0x49, 0x97, 0xb7, 0x00, 0x03, 0x7e, 0x93, 0x04, 0x4e, 0xe4, 0x07, 0xe2, 0x9a, 0x3b, 0x27, - 0x57, 0xe8, 0x35, 0x51, 0xbe, 0x2f, 0x92, 0xd7, 0x48, 0xea, 0xb2, 0x1c, 0xab, 0x9a, 0xc8, 0x86, - 0x3e, 0x26, 0x40, 0x0c, 0x85, 0xe3, 0x23, 0x3b, 0xb4, 0x98, 0x7d, 0x4a, 0x88, 0x05, 0xc4, 0xfe, - 0x33, 0x8b, 0xaf, 0x4f, 0xbd, 0xeb, 0xe8, 0x6d, 0x18, 0x6f, 0x38, 0x51, 0x75, 0x73, 0xf1, 0x4e, - 0x33, 0xe0, 0x2a, 0x5a, 0x39, 0x4e, 0x4f, 0x75, 0x1a, 0x27, 0xed, 0x23, 0x63, 0x03, 0xe9, 0x95, - 0x04, 0x31, 0x9c, 0x22, 0x8f, 0x6e, 0xc1, 0x10, 0x2b, 0x63, 0x3e, 0xbd, 0x61, 0x3b, 0x5e, 0x26, - 0xaf, 0x35, 0x65, 0xe2, 0xb3, 0x12, 0xd3, 0xc1, 0x3a, 0x51, 0xfb, 0xcb, 0x45, 0x7e, 0x68, 0xb0, - 0xb7, 0xc7, 0x13, 0xd0, 0xdf, 0xf4, 0x6b, 0xf3, 0xcb, 0x0b, 0x58, 0xcc, 0x82, 0xba, 0xf7, 0xca, - 0xbc, 0x18, 0x4b, 0x38, 0x3a, 0x07, 0x03, 0xe2, 0xa7, 0x54, 0xa9, 0xb3, 0x3d, 0x22, 0xf0, 0x42, - 0xac, 0xa0, 0xe8, 0x59, 0x80, 0x66, 0xe0, 0x6f, 0xbb, 0x35, 0x16, 0x89, 0xa9, 0x68, 0x5a, 0xe7, - 0x95, 0x15, 0x04, 0x6b, 0x58, 0xe8, 0x65, 0x18, 0x69, 0x79, 0x21, 0xe7, 0x9f, 0xb4, 0x78, 0xf7, - 0xca, 0x6e, 0xec, 0xba, 0x0e, 0xc4, 0x26, 0x2e, 0x9a, 0x85, 0xbe, 0xc8, 0x61, 0xd6, 0x66, 0xbd, - 0xf9, 0x46, 0xf4, 0x6b, 0x14, 0x43, 0xcf, 0x2c, 0x47, 0x2b, 0x60, 0x51, 0x11, 0xbd, 0x29, 0xdd, - 0xeb, 0xf9, 0x4d, 0x24, 0xbc, 0x57, 0xba, 0xbb, 0xb5, 0x34, 0xe7, 0x7a, 0xe1, 0x15, 0x63, 0xd0, - 0x42, 0x2f, 0x01, 0x90, 0x3b, 0x11, 0x09, 0x3c, 0xa7, 0xae, 0x6c, 0x44, 0x15, 0x23, 0xb3, 0xe0, - 0xaf, 0xfa, 0xd1, 0xf5, 0x90, 0x2c, 0x2a, 0x0c, 0xac, 0x61, 0xdb, 0xdf, 0x3f, 0x04, 0x10, 0x3f, - 0x34, 0xd0, 0x5d, 0x18, 0xa8, 0x3a, 0x4d, 0xa7, 0xca, 0xd3, 0xa6, 0x16, 0xf3, 0xbc, 0x9e, 0xe3, - 0x1a, 0x33, 0xf3, 0x02, 0x9d, 0x2b, 0x6f, 0x64, 0xc8, 0xf0, 0x01, 0x59, 0xdc, 0x51, 0x61, 0xa3, - 0xda, 0x43, 0x9f, 0xb3, 0x60, 0x48, 0x44, 0x3a, 0x62, 0x33, 0x54, 0xc8, 0xd7, 0xb7, 0x69, 0xed, - 0xcf, 0xc6, 0x35, 0x78, 0x17, 0x9e, 0x93, 0x2b, 0x54, 0x83, 0x74, 0xec, 0x85, 0xde, 0x30, 0xfa, - 0xa0, 0x7c, 0xdb, 0x16, 0x8d, 0xa1, 0x54, 0x6f, 0xdb, 0x41, 0x76, 0xd5, 0xe8, 0xcf, 0xda, 0xeb, - 0xc6, 0xb3, 0xb6, 0x27, 0xdf, 0x7f, 0xd8, 0xe0, 0xb7, 0x3b, 0xbd, 0x68, 0x51, 0x59, 0x8f, 0x25, - 0xd2, 0x9b, 0xef, 0xf4, 0xaa, 0x3d, 0xec, 0x3a, 0xc4, 0x11, 0xf9, 0x34, 0x8c, 0xd5, 0x4c, 0xae, - 0x45, 0xac, 0xc4, 0xc7, 0xf3, 0xe8, 0x26, 0x98, 0x9c, 0x98, 0x4f, 0x49, 0x00, 0x70, 0x92, 0x30, - 0x2a, 0xf3, 0xd0, 0x32, 0xcb, 0xde, 0xba, 0x2f, 0x3c, 0xa8, 0xec, 0xdc, 0xb9, 0xdc, 0x09, 0x23, - 0xd2, 0xa0, 0x98, 0x31, 0x93, 0xb0, 0x2a, 0xea, 0x62, 0x45, 0x05, 0xbd, 0x0e, 0x7d, 0xcc, 0xeb, - 0x31, 0x9c, 0x1a, 0xc8, 0x57, 0x6b, 0x98, 0x91, 0x50, 0xe3, 0x0d, 0xc9, 0xfe, 0x86, 0x58, 0x50, - 0x40, 0x97, 0xa5, 0x4f, 0x71, 0xb8, 0xec, 0x5d, 0x0f, 0x09, 0xf3, 0x29, 0x1e, 0x9c, 0x7b, 0x34, - 0x76, 0x17, 0xe6, 0xe5, 0x99, 0xf9, 0x67, 0x8d, 0x9a, 0x94, 0xed, 0x13, 0xff, 0x65, 0x5a, 0x5b, - 0x11, 0xb7, 0x2d, 0xb3, 0x7b, 0x66, 0xea, 0xdb, 0x78, 0x38, 0x6f, 0x98, 0x24, 0x70, 0x92, 0x26, - 0x65, 0xa1, 0xf9, 0xae, 0x17, 0x3e, 0x58, 0x9d, 0xce, 0x0e, 0x2e, 0x39, 0x60, 0xb7, 0x11, 0x2f, - 0xc1, 0xa2, 0x3e, 0x72, 0x61, 0x2c, 0x30, 0xd8, 0x0b, 0x19, 0x6e, 0xed, 0x6c, 0x77, 0x4c, 0x8c, - 0x16, 0xc8, 0xdf, 0x24, 0x83, 0x93, 0x74, 0xd1, 0xeb, 0x1a, 0xa3, 0x34, 0xd2, 0xfe, 0xe5, 0xdf, - 0x89, 0x35, 0x9a, 0xde, 0x82, 0x11, 0xe3, 0xb0, 0x79, 0xa0, 0x2a, 0x48, 0x0f, 0xc6, 0x93, 0x27, - 0xcb, 0x03, 0xd5, 0x3c, 0xfe, 0x49, 0x0f, 0x8c, 0x9a, 0x3b, 0x01, 0x9d, 0x87, 0x41, 0x41, 0x44, - 0x65, 0xb4, 0x52, 0x9b, 0x7b, 0x45, 0x02, 0x70, 0x8c, 0xc3, 0x12, 0x99, 0xb1, 0xea, 0x9a, 0xaf, - 0x40, 0x9c, 0xc8, 0x4c, 0x41, 0xb0, 0x86, 0x45, 0x1f, 0xb0, 0xb7, 0x7c, 0x3f, 0x52, 0xf7, 0xa8, - 0xda, 0x2e, 0x73, 0xac, 0x14, 0x0b, 0x28, 0xbd, 0x3f, 0xb7, 0x48, 0xe0, 0x91, 0xba, 0x99, 0xd2, - 0x41, 0xdd, 0x9f, 0x57, 0x74, 0x20, 0x36, 0x71, 0x29, 0x17, 0xe0, 0x87, 0x6c, 0xff, 0x89, 0x67, - 0x72, 0xec, 0x7b, 0x51, 0xe1, 0x51, 0x24, 0x24, 0x1c, 0x7d, 0x0c, 0x8e, 0xab, 0xf0, 0x89, 0x62, - 0x75, 0xc9, 0x16, 0xfb, 0x0c, 0xa9, 0xd6, 0xf1, 0xf9, 0x6c, 0x34, 0x9c, 0x57, 0x1f, 0xbd, 0x0a, - 0xa3, 0xe2, 0x29, 0x25, 0x29, 0xf6, 0x9b, 0x86, 0x84, 0x57, 0x0c, 0x28, 0x4e, 0x60, 0xcb, 0xa4, - 0x14, 0xec, 0x8d, 0x21, 0x29, 0x0c, 0xa4, 0x93, 0x52, 0xe8, 0x70, 0x9c, 0xaa, 0x81, 0x66, 0x61, - 0x8c, 0xb3, 0x8e, 0xae, 0xb7, 0xc1, 0xe7, 0x44, 0x78, 0x76, 0xaa, 0x4d, 0x75, 0xcd, 0x04, 0xe3, - 0x24, 0x3e, 0xba, 0x08, 0xc3, 0x4e, 0x50, 0xdd, 0x74, 0x23, 0x52, 0xa5, 0x3b, 0x83, 0xd9, 0xf2, - 0x69, 0x96, 0x98, 0xb3, 0x1a, 0x0c, 0x1b, 0x98, 0xf6, 0x5d, 0x98, 0xcc, 0x08, 0x2f, 0x43, 0x17, - 0x8e, 0xd3, 0x74, 0xe5, 0x37, 0x25, 0xdc, 0x1d, 0x66, 0xcb, 0xcb, 0xf2, 0x6b, 0x34, 0x2c, 0xba, - 0x3a, 0x59, 0x18, 0x1a, 0x2d, 0xf9, 0xb6, 0x5a, 0x9d, 0x4b, 0x12, 0x80, 0x63, 0x1c, 0xfb, 0xaf, - 0x0a, 0x30, 0x96, 0xa1, 0xa0, 0x63, 0x09, 0xa0, 0x13, 0x2f, 0xad, 0x38, 0xdf, 0xb3, 0x99, 0xe3, - 0xa4, 0x70, 0x80, 0x1c, 0x27, 0xc5, 0x4e, 0x39, 0x4e, 0x7a, 0xde, 0x49, 0x8e, 0x13, 0x73, 0xc4, - 0x7a, 0xbb, 0x1a, 0xb1, 0x8c, 0xbc, 0x28, 0x7d, 0x07, 0xcc, 0x8b, 0x62, 0x0c, 0x7a, 0x7f, 0x17, - 0x83, 0xfe, 0xa3, 0x05, 0x18, 0x4f, 0xea, 0xf6, 0x0e, 0x41, 0x3e, 0xfe, 0xba, 0x21, 0x1f, 0x3f, - 0xd7, 0x8d, 0x27, 0x7e, 0xae, 0xac, 0x1c, 0x27, 0x64, 0xe5, 0x4f, 0x76, 0x45, 0xad, 0xbd, 0xdc, - 0xfc, 0xef, 0x17, 0xe0, 0x68, 0xa6, 0xca, 0xf3, 0x10, 0xc6, 0xe6, 0x9a, 0x31, 0x36, 0xcf, 0x74, - 0x1d, 0xa5, 0x20, 0x77, 0x80, 0x6e, 0x26, 0x06, 0xe8, 0x7c, 0xf7, 0x24, 0xdb, 0x8f, 0xd2, 0x37, - 0x8a, 0x70, 0x3a, 0xb3, 0x5e, 0x2c, 0x5e, 0x5e, 0x32, 0xc4, 0xcb, 0xcf, 0x26, 0xc4, 0xcb, 0x76, - 0xfb, 0xda, 0xf7, 0x47, 0xde, 0x2c, 0xbc, 0xf5, 0x59, 0xcc, 0x91, 0x7b, 0x94, 0x35, 0x1b, 0xde, - 0xfa, 0x8a, 0x10, 0x36, 0xe9, 0xbe, 0x97, 0x64, 0xcc, 0xbf, 0x6b, 0xc1, 0x89, 0xcc, 0xb9, 0x39, - 0x04, 0x49, 0xdf, 0xaa, 0x29, 0xe9, 0x7b, 0xa2, 0xeb, 0xd5, 0x9a, 0x23, 0xfa, 0xfb, 0x7c, 0x5f, - 0xce, 0xb7, 0x30, 0x01, 0xc4, 0x35, 0x18, 0x72, 0xaa, 0x55, 0x12, 0x86, 0x2b, 0x7e, 0x4d, 0xa5, - 0x43, 0x78, 0x86, 0x3d, 0x0f, 0xe3, 0xe2, 0xfd, 0xdd, 0xd2, 0x74, 0x92, 0x44, 0x0c, 0xc6, 0x3a, - 0x05, 0xf4, 0x09, 0x18, 0x08, 0x65, 0x26, 0xcb, 0x9e, 0x7b, 0xcf, 0x64, 0xc9, 0x98, 0x5c, 0x25, - 0x60, 0x51, 0x24, 0xd1, 0x77, 0xea, 0xd1, 0x9f, 0xda, 0x88, 0x16, 0x79, 0x27, 0xef, 0x21, 0x06, - 0xd4, 0xb3, 0x00, 0xdb, 0xea, 0x25, 0x93, 0x14, 0x9e, 0x68, 0x6f, 0x1c, 0x0d, 0x0b, 0xbd, 0x06, - 0xe3, 0x21, 0x0f, 0x7c, 0x1a, 0x1b, 0xa9, 0xf0, 0xb5, 0xc8, 0x62, 0xc7, 0x55, 0x12, 0x30, 0x9c, - 0xc2, 0x46, 0x4b, 0xb2, 0x55, 0x66, 0x8e, 0xc4, 0x97, 0xe7, 0xd9, 0xb8, 0x45, 0x61, 0x92, 0x74, - 0x24, 0x39, 0x09, 0x6c, 0xf8, 0xb5, 0x9a, 0xe8, 0x13, 0x00, 0x74, 0x11, 0x09, 0x21, 0x4a, 0x7f, - 0xfe, 0x11, 0x4a, 0xcf, 0x96, 0x5a, 0xa6, 0x27, 0x03, 0x73, 0xb3, 0x5f, 0x50, 0x44, 0xb0, 0x46, - 0x10, 0x39, 0x30, 0x12, 0xff, 0x8b, 0x73, 0xb4, 0x9f, 0xcb, 0x6d, 0x21, 0x49, 0x9c, 0x29, 0x18, - 0x16, 0x74, 0x12, 0xd8, 0xa4, 0x88, 0x3e, 0x0e, 0x27, 0xb6, 0x73, 0x2d, 0x7f, 0x38, 0x27, 0xc8, - 0x92, 0xae, 0xe7, 0xdb, 0xfb, 0xe4, 0xd7, 0xb7, 0xff, 0x2d, 0xc0, 0x43, 0x6d, 0x4e, 0x7a, 0x34, - 0x6b, 0x6a, 0xed, 0x9f, 0x4a, 0x4a, 0x36, 0xa6, 0x33, 0x2b, 0x1b, 0xa2, 0x8e, 0xc4, 0x86, 0x2a, - 0xbc, 0xe3, 0x0d, 0xf5, 0x43, 0x96, 0x26, 0x73, 0xe2, 0x36, 0xdd, 0x1f, 0x39, 0xe0, 0x0d, 0x76, - 0x1f, 0x85, 0x50, 0xeb, 0x19, 0x92, 0x9c, 0x67, 0xbb, 0xee, 0x4e, 0xf7, 0xa2, 0x9d, 0xaf, 0x66, - 0x07, 0x7c, 0xe7, 0x42, 0x9e, 0x4b, 0x07, 0xfd, 0xfe, 0xc3, 0x0a, 0xfe, 0xfe, 0x75, 0x0b, 0x4e, - 0xa4, 0x8a, 0x79, 0x1f, 0x48, 0x28, 0xa2, 0xdd, 0xad, 0xbe, 0xe3, 0xce, 0x4b, 0x82, 0xfc, 0x1b, - 0x2e, 0x8b, 0x6f, 0x38, 0x91, 0x8b, 0x97, 0xec, 0xfa, 0x17, 0xfe, 0xb8, 0x34, 0xc9, 0x1a, 0x30, - 0x11, 0x71, 0x7e, 0xd7, 0x51, 0x13, 0xce, 0x54, 0x5b, 0x41, 0x10, 0x2f, 0xd6, 0x8c, 0xcd, 0xc9, - 0xdf, 0x7a, 0x8f, 0xee, 0xed, 0x96, 0xce, 0xcc, 0x77, 0xc0, 0xc5, 0x1d, 0xa9, 0x21, 0x0f, 0x50, - 0x23, 0x65, 0x5f, 0xc7, 0x0e, 0x80, 0x1c, 0x39, 0x4c, 0xda, 0x1a, 0x8f, 0x5b, 0xca, 0x66, 0x58, - 0xe9, 0x65, 0x50, 0x3e, 0x5c, 0xe9, 0xc9, 0xb7, 0x26, 0x2e, 0xfd, 0xf4, 0x55, 0x38, 0xdd, 0x7e, - 0x31, 0x1d, 0x28, 0x94, 0xc3, 0x1f, 0x58, 0x70, 0xaa, 0x6d, 0xbc, 0xb0, 0x6f, 0xc3, 0xc7, 0x82, - 0xfd, 0x59, 0x0b, 0x1e, 0xce, 0xac, 0x91, 0x74, 0xc2, 0xab, 0xd2, 0x42, 0xcd, 0x1c, 0x35, 0x8e, - 0x9c, 0x23, 0x01, 0x38, 0xc6, 0x31, 0x2c, 0x36, 0x0b, 0x1d, 0x2d, 0x36, 0x7f, 0xcb, 0x82, 0xd4, - 0x55, 0x7f, 0x08, 0x9c, 0xe7, 0xb2, 0xc9, 0x79, 0x3e, 0xda, 0xcd, 0x68, 0xe6, 0x30, 0x9d, 0x7f, - 0x31, 0x06, 0xc7, 0x72, 0x3c, 0xb1, 0xb7, 0x61, 0x62, 0xa3, 0x4a, 0xcc, 0xd0, 0x1b, 0xed, 0x42, - 0xd2, 0xb5, 0x8d, 0xd3, 0x31, 0x77, 0x74, 0x6f, 0xb7, 0x34, 0x91, 0x42, 0xc1, 0xe9, 0x26, 0xd0, - 0x67, 0x2d, 0x38, 0xe2, 0xdc, 0x0e, 0x17, 0xe9, 0x0b, 0xc2, 0xad, 0xce, 0xd5, 0xfd, 0xea, 0x16, - 0x65, 0xcc, 0xe4, 0xb6, 0x7a, 0x3e, 0x53, 0x18, 0x7d, 0xb3, 0x92, 0xc2, 0x37, 0x9a, 0x9f, 0xda, - 0xdb, 0x2d, 0x1d, 0xc9, 0xc2, 0xc2, 0x99, 0x6d, 0x21, 0x2c, 0x32, 0x7e, 0x39, 0xd1, 0x66, 0xbb, - 0xe0, 0x30, 0x59, 0x2e, 0xf3, 0x9c, 0x25, 0x96, 0x10, 0xac, 0xe8, 0xa0, 0x4f, 0xc1, 0xe0, 0x86, - 0x8c, 0x03, 0x91, 0xc1, 0x72, 0xc7, 0x03, 0xd9, 0x3e, 0x3a, 0x06, 0x37, 0x81, 0x51, 0x48, 0x38, - 0x26, 0x8a, 0x5e, 0x85, 0xa2, 0xb7, 0x1e, 0x8a, 0x10, 0x75, 0xd9, 0x96, 0xb8, 0xa6, 0xad, 0x33, - 0x0f, 0xc1, 0xb4, 0xba, 0x54, 0xc1, 0xb4, 0x22, 0xba, 0x0c, 0xc5, 0xe0, 0x56, 0x4d, 0x68, 0x52, - 0x32, 0x37, 0x29, 0x9e, 0x5b, 0xc8, 0xe9, 0x15, 0xa3, 0x84, 0xe7, 0x16, 0x30, 0x25, 0x81, 0xca, - 0xd0, 0xcb, 0xdc, 0x97, 0x05, 0x6b, 0x9b, 0xf9, 0x94, 0x6f, 0x13, 0x06, 0x80, 0x7b, 0x24, 0x32, - 0x04, 0xcc, 0x09, 0xa1, 0x35, 0xe8, 0xab, 0xba, 0x5e, 0x8d, 0x04, 0x82, 0x97, 0xfd, 0x60, 0xa6, - 0xce, 0x84, 0x61, 0xe4, 0xd0, 0xe4, 0x2a, 0x04, 0x86, 0x81, 0x05, 0x2d, 0x46, 0x95, 0x34, 0x37, - 0xd7, 0xe5, 0x8d, 0x95, 0x4d, 0x95, 0x34, 0x37, 0x97, 0x2a, 0x6d, 0xa9, 0x32, 0x0c, 0x2c, 0x68, - 0xa1, 0x97, 0xa0, 0xb0, 0x5e, 0x15, 0xae, 0xc9, 0x99, 0xca, 0x13, 0x33, 0x8a, 0xd6, 0x5c, 0xdf, - 0xde, 0x6e, 0xa9, 0xb0, 0x34, 0x8f, 0x0b, 0xeb, 0x55, 0xb4, 0x0a, 0xfd, 0xeb, 0x3c, 0xee, 0x8e, - 0xd0, 0x8f, 0x3c, 0x9e, 0x1d, 0x12, 0x28, 0x15, 0x9a, 0x87, 0x7b, 0x97, 0x0a, 0x00, 0x96, 0x44, - 0x58, 0x02, 0x2a, 0x15, 0x3f, 0x48, 0x84, 0x2f, 0x9d, 0x39, 0x58, 0xcc, 0x27, 0xfe, 0xd4, 0x88, - 0xa3, 0x10, 0x61, 0x8d, 0x22, 0x5d, 0xd5, 0xce, 0xdd, 0x56, 0xc0, 0x72, 0x5b, 0x08, 0xd5, 0x48, - 0xe6, 0xaa, 0x9e, 0x95, 0x48, 0xed, 0x56, 0xb5, 0x42, 0xc2, 0x31, 0x51, 0xb4, 0x05, 0x23, 0xdb, - 0x61, 0x73, 0x93, 0xc8, 0x2d, 0xcd, 0xc2, 0xde, 0xe5, 0x70, 0xb3, 0x37, 0x04, 0xa2, 0x1b, 0x44, - 0x2d, 0xa7, 0x9e, 0x3a, 0x85, 0xd8, 0xb3, 0xe6, 0x86, 0x4e, 0x0c, 0x9b, 0xb4, 0xe9, 0xf0, 0xbf, - 0xdd, 0xf2, 0x6f, 0xed, 0x44, 0x44, 0x44, 0x1d, 0xcd, 0x1c, 0xfe, 0x37, 0x38, 0x4a, 0x7a, 0xf8, - 0x05, 0x00, 0x4b, 0x22, 0xe8, 0x86, 0x18, 0x1e, 0x76, 0x7a, 0x8e, 0xe7, 0x87, 0x34, 0x9f, 0x95, - 0x48, 0x39, 0x83, 0xc2, 0x4e, 0xcb, 0x98, 0x14, 0x3b, 0x25, 0x9b, 0x9b, 0x7e, 0xe4, 0x7b, 0x89, - 0x13, 0x7a, 0x22, 0xff, 0x94, 0x2c, 0x67, 0xe0, 0xa7, 0x4f, 0xc9, 0x2c, 0x2c, 0x9c, 0xd9, 0x16, - 0xaa, 0xc1, 0x68, 0xd3, 0x0f, 0xa2, 0xdb, 0x7e, 0x20, 0xd7, 0x17, 0x6a, 0x23, 0x28, 0x35, 0x30, - 0x45, 0x8b, 0xcc, 0x30, 0xc7, 0x84, 0xe0, 0x04, 0x4d, 0xf4, 0x51, 0xe8, 0x0f, 0xab, 0x4e, 0x9d, - 0x2c, 0x5f, 0x9b, 0x9a, 0xcc, 0xbf, 0x7e, 0x2a, 0x1c, 0x25, 0x67, 0x75, 0xf1, 0xb0, 0x49, 0x1c, - 0x05, 0x4b, 0x72, 0x68, 0x09, 0x7a, 0x59, 0x62, 0x67, 0x16, 0x22, 0x37, 0x27, 0x32, 0x7b, 0xca, - 0xad, 0x86, 0x9f, 0x4d, 0xac, 0x18, 0xf3, 0xea, 0x74, 0x0f, 0x08, 0x49, 0x81, 0x1f, 0x4e, 0x1d, - 0xcd, 0xdf, 0x03, 0x42, 0xc0, 0x70, 0xad, 0xd2, 0x6e, 0x0f, 0x28, 0x24, 0x1c, 0x13, 0xa5, 0x27, - 0x33, 0x3d, 0x4d, 0x8f, 0xb5, 0x31, 0x99, 0xcc, 0x3d, 0x4b, 0xd9, 0xc9, 0x4c, 0x4f, 0x52, 0x4a, - 0xc2, 0xfe, 0x8d, 0x81, 0x34, 0xcf, 0xc2, 0x24, 0x4c, 0xff, 0xbf, 0x95, 0xb2, 0x99, 0xf8, 0x50, - 0xb7, 0x02, 0xef, 0xfb, 0xf8, 0x70, 0xfd, 0xac, 0x05, 0xc7, 0x9a, 0x99, 0x1f, 0x22, 0x18, 0x80, - 0xee, 0xe4, 0xe6, 0xfc, 0xd3, 0x55, 0x38, 0xe5, 0x6c, 0x38, 0xce, 0x69, 0x29, 0x29, 0x1c, 0x28, - 0xbe, 0x63, 0xe1, 0xc0, 0x0a, 0x0c, 0x54, 0xf9, 0x4b, 0x4e, 0xa6, 0x01, 0xe8, 0x2a, 0x18, 0x28, - 0x63, 0x25, 0xc4, 0x13, 0x70, 0x1d, 0x2b, 0x12, 0xe8, 0x87, 0x2d, 0x38, 0x95, 0xec, 0x3a, 0x26, - 0x0c, 0x2c, 0x0c, 0x26, 0xb9, 0x58, 0x6b, 0x49, 0x7c, 0x7f, 0x8a, 0xff, 0x37, 0x90, 0xf7, 0x3b, - 0x21, 0xe0, 0xf6, 0x8d, 0xa1, 0x85, 0x0c, 0xb9, 0x5a, 0x9f, 0xa9, 0x51, 0xec, 0x42, 0xb6, 0xf6, - 0x3c, 0x0c, 0x37, 0xfc, 0x96, 0x17, 0x09, 0xbb, 0x47, 0x61, 0x3c, 0xc5, 0x8c, 0x86, 0x56, 0xb4, - 0x72, 0x6c, 0x60, 0x25, 0x24, 0x72, 0x03, 0xf7, 0x2c, 0x91, 0x7b, 0x0b, 0x86, 0x3d, 0xcd, 0x25, - 0xa0, 0xdd, 0x0b, 0x56, 0x48, 0x17, 0x35, 0x6c, 0xde, 0x4b, 0xbd, 0x04, 0x1b, 0xd4, 0xda, 0x4b, - 0xcb, 0xe0, 0x9d, 0x49, 0xcb, 0x0e, 0xf5, 0x49, 0x6c, 0xff, 0x42, 0x21, 0xe3, 0xc5, 0xc0, 0xa5, - 0x72, 0xaf, 0x98, 0x52, 0xb9, 0xb3, 0x49, 0xa9, 0x5c, 0x4a, 0x55, 0x65, 0x08, 0xe4, 0xba, 0xcf, - 0x28, 0xd9, 0x75, 0x80, 0xe7, 0xef, 0xb5, 0xe0, 0x38, 0xd3, 0x7d, 0xd0, 0x06, 0xde, 0xb1, 0xbe, - 0x83, 0x99, 0xa4, 0x5e, 0xcd, 0x26, 0x87, 0xf3, 0xda, 0xb1, 0xeb, 0x70, 0xa6, 0xd3, 0xbd, 0xcb, - 0x2c, 0x7c, 0x6b, 0xca, 0x38, 0x22, 0xb6, 0xf0, 0xad, 0x2d, 0x2f, 0x60, 0x06, 0xe9, 0x36, 0x7c, - 0xa1, 0xfd, 0xdf, 0x2d, 0x28, 0x96, 0xfd, 0xda, 0x21, 0xbc, 0xe8, 0x3f, 0x62, 0xbc, 0xe8, 0x1f, - 0xca, 0xbe, 0xf1, 0x6b, 0xb9, 0xca, 0xbe, 0xc5, 0x84, 0xb2, 0xef, 0x54, 0x1e, 0x81, 0xf6, 0xaa, - 0xbd, 0x9f, 0x2e, 0xc2, 0x50, 0xd9, 0xaf, 0xa9, 0x7d, 0xf6, 0xaf, 0xee, 0xc5, 0x91, 0x27, 0x37, - 0xfb, 0x94, 0x46, 0x99, 0x59, 0xf4, 0xca, 0xb8, 0x13, 0xdf, 0x66, 0xfe, 0x3c, 0x37, 0x89, 0xbb, - 0xb1, 0x19, 0x91, 0x5a, 0xf2, 0x73, 0x0e, 0xcf, 0x9f, 0xe7, 0x9b, 0x45, 0x18, 0x4b, 0xb4, 0x8e, - 0xea, 0x30, 0x52, 0xd7, 0x55, 0x49, 0x62, 0x9d, 0xde, 0x93, 0x16, 0x4a, 0xf8, 0x43, 0x68, 0x45, - 0xd8, 0x24, 0x8e, 0x66, 0x00, 0x3c, 0xdd, 0x2a, 0x5c, 0x05, 0x2a, 0xd6, 0x2c, 0xc2, 0x35, 0x0c, - 0xf4, 0x02, 0x0c, 0x45, 0x7e, 0xd3, 0xaf, 0xfb, 0x1b, 0x3b, 0x57, 0x88, 0x8c, 0x6c, 0xa9, 0x8c, - 0x86, 0xd7, 0x62, 0x10, 0xd6, 0xf1, 0xd0, 0x1d, 0x98, 0x50, 0x44, 0x2a, 0xf7, 0x41, 0xbd, 0xc6, - 0xc4, 0x26, 0xab, 0x49, 0x8a, 0x38, 0xdd, 0x08, 0x7a, 0x09, 0x46, 0x99, 0xf5, 0x32, 0xab, 0x7f, - 0x85, 0xec, 0xc8, 0x88, 0xc7, 0x8c, 0xc3, 0x5e, 0x31, 0x20, 0x38, 0x81, 0x89, 0xe6, 0x61, 0xa2, - 0xe1, 0x86, 0x89, 0xea, 0x7d, 0xac, 0x3a, 0xeb, 0xc0, 0x4a, 0x12, 0x88, 0xd3, 0xf8, 0xf6, 0xcf, - 0x89, 0x39, 0xf6, 0x22, 0xf7, 0xfd, 0xed, 0xf8, 0xee, 0xde, 0x8e, 0xdf, 0xb0, 0x60, 0x9c, 0xb6, - 0xce, 0x4c, 0x32, 0x25, 0x23, 0xa5, 0x72, 0x62, 0x58, 0x6d, 0x72, 0x62, 0x9c, 0xa5, 0xc7, 0x76, - 0xcd, 0x6f, 0x45, 0x42, 0x3a, 0xaa, 0x9d, 0xcb, 0xb4, 0x14, 0x0b, 0xa8, 0xc0, 0x23, 0x41, 0x20, - 0xfc, 0xde, 0x75, 0x3c, 0x12, 0x04, 0x58, 0x40, 0x65, 0xca, 0x8c, 0x9e, 0xec, 0x94, 0x19, 0x3c, - 0xf2, 0xb9, 0xb0, 0x82, 0x13, 0x2c, 0xad, 0x16, 0xf9, 0x5c, 0x9a, 0xc7, 0xc5, 0x38, 0xf6, 0x57, - 0x8b, 0x30, 0x5c, 0xf6, 0x6b, 0xb1, 0x61, 0xc7, 0xf3, 0x86, 0x61, 0xc7, 0x99, 0x84, 0x61, 0xc7, - 0xb8, 0x8e, 0xfb, 0xbe, 0x19, 0xc7, 0xb7, 0xca, 0x8c, 0xe3, 0x37, 0x2d, 0x36, 0x6b, 0x0b, 0xab, - 0x15, 0x6e, 0xe1, 0x8b, 0x2e, 0xc0, 0x10, 0x3b, 0xe1, 0x58, 0xa0, 0x05, 0x69, 0xed, 0xc0, 0x52, - 0x58, 0xae, 0xc6, 0xc5, 0x58, 0xc7, 0x41, 0xe7, 0x60, 0x20, 0x24, 0x4e, 0x50, 0xdd, 0x54, 0xc7, - 0xbb, 0x30, 0x4d, 0xe0, 0x65, 0x58, 0x41, 0xd1, 0x1b, 0x71, 0xd0, 0xed, 0x62, 0xbe, 0xb9, 0xb0, - 0xde, 0x1f, 0xbe, 0x45, 0xf2, 0x23, 0x6d, 0xdb, 0x37, 0x01, 0xa5, 0xf1, 0xbb, 0xf0, 0xbf, 0x2a, - 0x99, 0x61, 0x61, 0x07, 0x53, 0x21, 0x61, 0xff, 0xda, 0x82, 0xd1, 0xb2, 0x5f, 0xa3, 0x5b, 0xf7, - 0xbd, 0xb4, 0x4f, 0xf5, 0x8c, 0x03, 0x7d, 0x6d, 0x32, 0x0e, 0x3c, 0x02, 0xbd, 0x65, 0xbf, 0xd6, - 0x21, 0x74, 0xed, 0x3f, 0xb0, 0xa0, 0xbf, 0xec, 0xd7, 0x0e, 0x41, 0xf1, 0xf2, 0x8a, 0xa9, 0x78, - 0x39, 0x9e, 0xb3, 0x6e, 0x72, 0x74, 0x2d, 0x7f, 0xaf, 0x07, 0x46, 0x68, 0x3f, 0xfd, 0x0d, 0x39, - 0x95, 0xc6, 0xb0, 0x59, 0x5d, 0x0c, 0x1b, 0x7d, 0x06, 0xf8, 0xf5, 0xba, 0x7f, 0x3b, 0x39, 0xad, - 0x4b, 0xac, 0x14, 0x0b, 0x28, 0x7a, 0x1a, 0x06, 0x9a, 0x01, 0xd9, 0x76, 0x7d, 0xc1, 0x5f, 0x6b, - 0x6a, 0xac, 0xb2, 0x28, 0xc7, 0x0a, 0x83, 0x3e, 0xbc, 0x43, 0xd7, 0xa3, 0xbc, 0x44, 0xd5, 0xf7, - 0x6a, 0x5c, 0x37, 0x51, 0x14, 0x69, 0xb1, 0xb4, 0x72, 0x6c, 0x60, 0xa1, 0x9b, 0x30, 0xc8, 0xfe, - 0xb3, 0x63, 0xa7, 0xf7, 0xc0, 0xc7, 0x8e, 0x48, 0x14, 0x2c, 0x08, 0xe0, 0x98, 0x16, 0x7a, 0x16, - 0x20, 0x92, 0xa9, 0x65, 0x42, 0x11, 0xc2, 0x54, 0xbd, 0x45, 0x54, 0xd2, 0x99, 0x10, 0x6b, 0x58, - 0xe8, 0x29, 0x18, 0x8c, 0x1c, 0xb7, 0x7e, 0xd5, 0xf5, 0x98, 0xfe, 0x9e, 0xf6, 0x5f, 0xe4, 0xeb, - 0x15, 0x85, 0x38, 0x86, 0x53, 0x5e, 0x90, 0xc5, 0x84, 0x9a, 0xdb, 0x89, 0x44, 0x6a, 0xba, 0x22, - 0xe7, 0x05, 0xaf, 0xaa, 0x52, 0xac, 0x61, 0xa0, 0x4d, 0x38, 0xe9, 0x7a, 0x2c, 0x85, 0x14, 0xa9, - 0x6c, 0xb9, 0xcd, 0xb5, 0xab, 0x95, 0x1b, 0x24, 0x70, 0xd7, 0x77, 0xe6, 0x9c, 0xea, 0x16, 0xf1, - 0x64, 0x42, 0xfc, 0x47, 0x45, 0x17, 0x4f, 0x2e, 0xb7, 0xc1, 0xc5, 0x6d, 0x29, 0xd9, 0xcf, 0xb1, - 0xf5, 0x7e, 0xad, 0x82, 0x9e, 0x34, 0x8e, 0x8e, 0x63, 0xfa, 0xd1, 0xb1, 0xbf, 0x5b, 0xea, 0xbb, - 0x56, 0xd1, 0x62, 0xff, 0x5c, 0x84, 0xa3, 0x65, 0xbf, 0x56, 0xf6, 0x83, 0x68, 0xc9, 0x0f, 0x6e, - 0x3b, 0x41, 0x4d, 0x2e, 0xaf, 0x92, 0x8c, 0x7e, 0x44, 0xcf, 0xcf, 0x5e, 0x7e, 0xba, 0x18, 0x91, - 0x8d, 0x9e, 0x63, 0x1c, 0xdb, 0x01, 0x9d, 0x4d, 0xab, 0x8c, 0x77, 0x50, 0x49, 0xd8, 0x2e, 0x39, - 0x11, 0x41, 0xd7, 0x60, 0xa4, 0xaa, 0x5f, 0xa3, 0xa2, 0xfa, 0x13, 0xf2, 0x22, 0x33, 0xee, 0xd8, - 0xcc, 0x7b, 0xd7, 0xac, 0x6f, 0x7f, 0xdd, 0x12, 0xad, 0x70, 0x49, 0x04, 0xb7, 0x69, 0xed, 0x7c, - 0x9e, 0xce, 0xc3, 0x44, 0xa0, 0x57, 0xd1, 0x6c, 0xc3, 0x8e, 0xf2, 0xac, 0x36, 0x09, 0x20, 0x4e, - 0xe3, 0xa3, 0x8f, 0xc3, 0x09, 0xa3, 0x50, 0xaa, 0xc9, 0xb5, 0xdc, 0xd2, 0x4c, 0x56, 0x83, 0xf3, - 0x90, 0x70, 0x7e, 0x7d, 0xfb, 0xbb, 0xe1, 0x58, 0xf2, 0xbb, 0x84, 0xf4, 0xe4, 0x1e, 0xbf, 0xae, - 0x70, 0xb0, 0xaf, 0xb3, 0x5f, 0x80, 0x09, 0xfa, 0xac, 0x56, 0x2c, 0x22, 0x9b, 0xbf, 0xce, 0x01, - 0xa6, 0xfe, 0x5d, 0x3f, 0xbb, 0xe2, 0x12, 0x99, 0xd5, 0xd0, 0x27, 0x61, 0x34, 0x24, 0x2c, 0xaa, - 0x9a, 0x94, 0xda, 0xb5, 0xf1, 0x14, 0xaf, 0x2c, 0xea, 0x98, 0xfc, 0x65, 0x62, 0x96, 0xe1, 0x04, - 0x35, 0xd4, 0x80, 0xd1, 0xdb, 0xae, 0x57, 0xf3, 0x6f, 0x87, 0x92, 0xfe, 0x40, 0xbe, 0x0a, 0xe0, - 0x26, 0xc7, 0x4c, 0xf4, 0xd1, 0x68, 0xee, 0xa6, 0x41, 0x0c, 0x27, 0x88, 0xd3, 0x63, 0x24, 0x68, - 0x79, 0xb3, 0xe1, 0xf5, 0x90, 0x04, 0x22, 0xe6, 0x1b, 0x3b, 0x46, 0xb0, 0x2c, 0xc4, 0x31, 0x9c, - 0x1e, 0x23, 0xec, 0x0f, 0x73, 0x35, 0x67, 0xe7, 0x94, 0x38, 0x46, 0xb0, 0x2a, 0xc5, 0x1a, 0x06, - 0x3d, 0x66, 0xd9, 0xbf, 0x55, 0xdf, 0xc3, 0xbe, 0x1f, 0xc9, 0x83, 0x99, 0xa5, 0xa1, 0xd4, 0xca, - 0xb1, 0x81, 0x95, 0x13, 0x61, 0xae, 0xe7, 0xa0, 0x11, 0xe6, 0x50, 0xd4, 0xc6, 0xbb, 0x9e, 0x47, - 0x3a, 0xbe, 0xd8, 0xce, 0xbb, 0x7e, 0xff, 0x9e, 0x3c, 0xef, 0xe9, 0x3d, 0xbf, 0x2e, 0x06, 0xa8, - 0x97, 0x87, 0xd0, 0x63, 0x4a, 0xca, 0x0a, 0x1f, 0x1d, 0x09, 0x43, 0x8b, 0xd0, 0x1f, 0xee, 0x84, - 0xd5, 0xa8, 0x1e, 0xb6, 0x4b, 0x35, 0x5a, 0x61, 0x28, 0x5a, 0xa6, 0x6b, 0x5e, 0x05, 0xcb, 0xba, - 0xa8, 0x0a, 0x93, 0x82, 0xe2, 0xfc, 0xa6, 0xe3, 0xa9, 0x04, 0x88, 0xdc, 0x1a, 0xf1, 0xc2, 0xde, - 0x6e, 0x69, 0x52, 0xb4, 0xac, 0x83, 0xf7, 0x77, 0x4b, 0x74, 0x4b, 0x66, 0x40, 0x70, 0x16, 0x35, - 0xbe, 0xe4, 0xab, 0x55, 0xbf, 0xd1, 0x2c, 0x07, 0xfe, 0xba, 0x5b, 0x27, 0xed, 0x14, 0xbd, 0x15, - 0x03, 0x53, 0x2c, 0x79, 0xa3, 0x0c, 0x27, 0xa8, 0xa1, 0x5b, 0x30, 0xe6, 0x34, 0x9b, 0xb3, 0x41, - 0xc3, 0x0f, 0x64, 0x03, 0x43, 0xf9, 0x1a, 0x83, 0x59, 0x13, 0x95, 0xe7, 0x3f, 0x4c, 0x14, 0xe2, - 0x24, 0x41, 0xfb, 0xbb, 0x18, 0xbf, 0x5d, 0x71, 0x37, 0x3c, 0xe6, 0x93, 0x86, 0x1a, 0x30, 0xd2, - 0x64, 0x27, 0xb2, 0x48, 0x1b, 0x26, 0x76, 0xf1, 0xf3, 0x5d, 0xca, 0x0c, 0x6f, 0xb3, 0xc4, 0xa7, - 0x86, 0xed, 0x68, 0x59, 0x27, 0x87, 0x4d, 0xea, 0xf6, 0xbf, 0x3f, 0xc1, 0x38, 0xb6, 0x0a, 0x17, - 0x04, 0xf6, 0x0b, 0x0f, 0x41, 0xf1, 0xf4, 0x9f, 0xce, 0x17, 0xb9, 0xc7, 0x53, 0x2f, 0xbc, 0x0c, - 0xb1, 0xac, 0x8b, 0x3e, 0x01, 0xa3, 0xf4, 0x25, 0xad, 0xb8, 0xa6, 0x70, 0xea, 0x48, 0x7e, 0xe8, - 0x29, 0x85, 0xa5, 0xa7, 0x14, 0xd4, 0x2b, 0xe3, 0x04, 0x31, 0xf4, 0x06, 0x33, 0xa7, 0x94, 0xa4, - 0x0b, 0xdd, 0x90, 0xd6, 0x2d, 0x27, 0x25, 0x59, 0x8d, 0x08, 0x6a, 0xc1, 0x64, 0x3a, 0x71, 0x72, - 0x38, 0x65, 0xe7, 0x3f, 0x49, 0xd2, 0xb9, 0x8f, 0xe3, 0xdc, 0x6f, 0x69, 0x58, 0x88, 0xb3, 0xe8, - 0xa3, 0xab, 0xc9, 0xb4, 0xb6, 0x45, 0x43, 0x58, 0x9f, 0x4a, 0x6d, 0x3b, 0xd2, 0x36, 0xa3, 0xed, - 0x06, 0x9c, 0xd2, 0x32, 0x83, 0x5e, 0x0a, 0x1c, 0x66, 0xce, 0xe3, 0xb2, 0x8b, 0x42, 0xe3, 0x25, - 0x1f, 0xde, 0xdb, 0x2d, 0x9d, 0x5a, 0x6b, 0x87, 0x88, 0xdb, 0xd3, 0x41, 0xd7, 0xe0, 0x28, 0x0f, - 0x9c, 0xb2, 0x40, 0x9c, 0x5a, 0xdd, 0xf5, 0x14, 0xb3, 0xca, 0x8f, 0x95, 0x13, 0x7b, 0xbb, 0xa5, - 0xa3, 0xb3, 0x59, 0x08, 0x38, 0xbb, 0x1e, 0x7a, 0x05, 0x06, 0x6b, 0x9e, 0x3c, 0x00, 0xfb, 0x8c, - 0xe4, 0xab, 0x83, 0x0b, 0xab, 0x15, 0xf5, 0xfd, 0xf1, 0x1f, 0x1c, 0x57, 0x40, 0x1b, 0x5c, 0x5b, - 0xa4, 0x44, 0x7c, 0xfd, 0xa9, 0x78, 0x9a, 0x49, 0x29, 0xb8, 0x11, 0x89, 0x80, 0xab, 0x49, 0x95, - 0xa7, 0x9b, 0x11, 0xa4, 0xc0, 0x20, 0x8c, 0x5e, 0x07, 0x24, 0x92, 0xfc, 0xcc, 0x56, 0x59, 0x4e, - 0x3a, 0xcd, 0x84, 0x53, 0xbd, 0xdc, 0x2b, 0x29, 0x0c, 0x9c, 0x51, 0x0b, 0x5d, 0xa6, 0x27, 0x97, - 0x5e, 0x2a, 0x4e, 0x46, 0x95, 0xe2, 0x7b, 0x81, 0x34, 0x03, 0xc2, 0xac, 0x0e, 0x4d, 0x8a, 0x38, - 0x51, 0x0f, 0xd5, 0xe0, 0xa4, 0xd3, 0x8a, 0x7c, 0xa6, 0x88, 0x33, 0x51, 0xd7, 0xfc, 0x2d, 0xe2, - 0x31, 0x1d, 0xf8, 0x00, 0x8b, 0xd3, 0x79, 0x72, 0xb6, 0x0d, 0x1e, 0x6e, 0x4b, 0x85, 0xbe, 0x62, - 0xe8, 0x58, 0x68, 0x3a, 0x32, 0xc3, 0xa9, 0x9a, 0x2b, 0x8e, 0x25, 0x06, 0x7a, 0x01, 0x86, 0x36, - 0xfd, 0x30, 0x5a, 0x25, 0xd1, 0x6d, 0x3f, 0xd8, 0x12, 0x59, 0x05, 0xe2, 0x4c, 0x2e, 0x31, 0x08, - 0xeb, 0x78, 0xe8, 0x09, 0xe8, 0x67, 0x16, 0x5a, 0xcb, 0x0b, 0xec, 0x1a, 0x1c, 0x88, 0xcf, 0x98, - 0xcb, 0xbc, 0x18, 0x4b, 0xb8, 0x44, 0x5d, 0x2e, 0xcf, 0x33, 0x43, 0x97, 0x04, 0xea, 0x72, 0x79, - 0x1e, 0x4b, 0x38, 0x5d, 0xae, 0xe1, 0xa6, 0x13, 0x90, 0x72, 0xe0, 0x57, 0x49, 0xa8, 0xe5, 0x0f, - 0x7a, 0x88, 0xe7, 0x4c, 0xa0, 0xcb, 0xb5, 0x92, 0x85, 0x80, 0xb3, 0xeb, 0x21, 0x92, 0xce, 0x8a, - 0x3b, 0x9a, 0xaf, 0xa1, 0x4c, 0x73, 0x6a, 0x5d, 0x26, 0xc6, 0xf5, 0x60, 0x5c, 0xe5, 0xe3, 0xe5, - 0x59, 0x12, 0xc2, 0xa9, 0x31, 0xb6, 0xb6, 0xbb, 0x4f, 0xb1, 0xa0, 0x74, 0xbe, 0xcb, 0x09, 0x4a, - 0x38, 0x45, 0xdb, 0x08, 0x04, 0x3b, 0xde, 0x31, 0x10, 0xec, 0x79, 0x18, 0x0c, 0x5b, 0xb7, 0x6a, - 0x7e, 0xc3, 0x71, 0x3d, 0x66, 0xe8, 0xa2, 0xbd, 0x97, 0x2b, 0x12, 0x80, 0x63, 0x1c, 0xb4, 0x04, - 0x03, 0x8e, 0x54, 0xe8, 0xa2, 0xfc, 0x18, 0x77, 0x4a, 0x8d, 0xcb, 0xc3, 0x3e, 0x49, 0x15, 0xae, - 0xaa, 0x8b, 0x5e, 0x86, 0x11, 0x11, 0x47, 0x43, 0xa4, 0xb0, 0x9f, 0x34, 0xbd, 0x86, 0x2b, 0x3a, - 0x10, 0x9b, 0xb8, 0xe8, 0x3a, 0x0c, 0x45, 0x7e, 0x9d, 0xb9, 0xbe, 0x52, 0x06, 0xf6, 0x58, 0x7e, - 0x28, 0xda, 0x35, 0x85, 0xa6, 0xab, 0x1a, 0x54, 0x55, 0xac, 0xd3, 0x41, 0x6b, 0x7c, 0xbd, 0xb3, - 0x6c, 0x41, 0x24, 0x14, 0x39, 0xd0, 0x4f, 0xe5, 0x59, 0x29, 0x32, 0x34, 0x73, 0x3b, 0x88, 0x9a, - 0x58, 0x27, 0x83, 0x2e, 0xc1, 0x44, 0x33, 0x70, 0x7d, 0xb6, 0x26, 0x94, 0x82, 0x7a, 0xca, 0xcc, - 0x0d, 0x5a, 0x4e, 0x22, 0xe0, 0x74, 0x1d, 0x16, 0x06, 0x45, 0x14, 0x4e, 0x9d, 0xe0, 0xf9, 0xcd, - 0xb8, 0xf8, 0x81, 0x97, 0x61, 0x05, 0x45, 0x2b, 0xec, 0x24, 0xe6, 0x92, 0xb3, 0xa9, 0xe9, 0x7c, - 0xe7, 0x7a, 0x5d, 0xc2, 0xc6, 0xd9, 0x72, 0xf5, 0x17, 0xc7, 0x14, 0x50, 0x4d, 0x4b, 0x2b, 0x4e, - 0x1f, 0x37, 0xe1, 0xd4, 0xc9, 0x36, 0x66, 0xb2, 0x89, 0x97, 0x6c, 0xcc, 0x10, 0x18, 0xc5, 0x21, - 0x4e, 0xd0, 0x44, 0xaf, 0xc1, 0xb8, 0x88, 0x11, 0x10, 0x0f, 0xd3, 0xa9, 0xd8, 0x95, 0x08, 0x27, - 0x60, 0x38, 0x85, 0xcd, 0xf3, 0x8b, 0x39, 0xb7, 0xea, 0x44, 0x1c, 0x7d, 0x57, 0x5d, 0x6f, 0x2b, - 0x9c, 0x3a, 0xcd, 0xce, 0x07, 0x91, 0x5f, 0x2c, 0x09, 0xc5, 0x19, 0x35, 0xd0, 0x1a, 0x8c, 0x37, - 0x03, 0x42, 0x1a, 0xec, 0x09, 0x23, 0xee, 0xb3, 0x12, 0x8f, 0x02, 0x44, 0x7b, 0x52, 0x4e, 0xc0, - 0xf6, 0x33, 0xca, 0x70, 0x8a, 0x02, 0xba, 0x0d, 0x03, 0xfe, 0x36, 0x09, 0x36, 0x89, 0x53, 0x9b, - 0x3a, 0xd3, 0xc6, 0xc1, 0x4d, 0x5c, 0x6e, 0xd7, 0x04, 0x6e, 0xc2, 0xfe, 0x47, 0x16, 0x77, 0xb6, - 0xff, 0x91, 0x8d, 0xa1, 0xbf, 0x65, 0xc1, 0x09, 0xa9, 0x51, 0xab, 0x34, 0xe9, 0xa8, 0xcf, 0xfb, - 0x5e, 0x18, 0x05, 0x3c, 0x6e, 0xcd, 0xc3, 0xf9, 0xb1, 0x5c, 0xd6, 0x72, 0x2a, 0x29, 0xe1, 0xfd, - 0x89, 0x3c, 0x8c, 0x10, 0xe7, 0xb7, 0x48, 0x1f, 0xdd, 0x21, 0x89, 0xe4, 0x61, 0x34, 0x1b, 0x2e, - 0xbd, 0xb1, 0xb0, 0x3a, 0xf5, 0x08, 0x0f, 0xba, 0x43, 0x37, 0x43, 0x25, 0x09, 0xc4, 0x69, 0x7c, - 0x74, 0x01, 0x0a, 0x7e, 0x38, 0xf5, 0x68, 0x9b, 0x4c, 0xf4, 0x7e, 0xed, 0x5a, 0x85, 0xdb, 0x81, - 0x5e, 0xab, 0xe0, 0x82, 0x1f, 0xca, 0x1c, 0x5f, 0xf4, 0xa5, 0x19, 0x4e, 0x3d, 0xc6, 0x45, 0xbd, - 0x32, 0xc7, 0x17, 0x2b, 0xc4, 0x31, 0x1c, 0x6d, 0xc2, 0x58, 0x68, 0xbc, 0xe8, 0xc3, 0xa9, 0xb3, - 0x6c, 0xa4, 0x1e, 0xcb, 0x9b, 0x34, 0x03, 0x5b, 0x4b, 0xbe, 0x63, 0x52, 0xc1, 0x49, 0xb2, 0x7c, - 0x77, 0x69, 0x32, 0x85, 0x70, 0xea, 0xf1, 0x0e, 0xbb, 0x4b, 0x43, 0xd6, 0x77, 0x97, 0x4e, 0x03, - 0x27, 0x68, 0x4e, 0x7f, 0x07, 0x4c, 0xa4, 0xd8, 0xa5, 0x83, 0xf8, 0x3c, 0x4c, 0x6f, 0xc1, 0x88, - 0xb1, 0x24, 0x1f, 0xa8, 0x49, 0xcc, 0xef, 0x0e, 0xc2, 0xa0, 0x32, 0x55, 0x40, 0xe7, 0x4d, 0x2b, - 0x98, 0x13, 0x49, 0x2b, 0x98, 0x81, 0xb2, 0x5f, 0x33, 0x0c, 0x5f, 0xd6, 0x32, 0x62, 0xc9, 0xe6, - 0x1d, 0x80, 0xdd, 0x3b, 0x66, 0x69, 0xea, 0x97, 0x62, 0xd7, 0xe6, 0x34, 0x3d, 0x6d, 0x35, 0x3a, - 0x97, 0x60, 0xc2, 0xf3, 0x19, 0x8f, 0x4e, 0x6a, 0x92, 0x01, 0x63, 0x7c, 0xd6, 0xa0, 0x1e, 0xeb, - 0x2c, 0x81, 0x80, 0xd3, 0x75, 0x68, 0x83, 0x9c, 0x51, 0x4a, 0xaa, 0x90, 0x38, 0x1f, 0x85, 0x05, - 0x94, 0xbe, 0x0d, 0xf9, 0xaf, 0x70, 0x6a, 0x3c, 0xff, 0x6d, 0xc8, 0x2b, 0x25, 0x99, 0xb1, 0x50, - 0x32, 0x63, 0x4c, 0x63, 0xd2, 0xf4, 0x6b, 0xcb, 0x65, 0xc1, 0xe6, 0x6b, 0x51, 0xde, 0x6b, 0xcb, - 0x65, 0xcc, 0x61, 0x68, 0x16, 0xfa, 0xd8, 0x0f, 0x19, 0x43, 0x26, 0x6f, 0x9b, 0x2e, 0x97, 0xb5, - 0x1c, 0xa3, 0xac, 0x02, 0x16, 0x15, 0x99, 0x44, 0x9c, 0xbe, 0x8d, 0x98, 0x44, 0xbc, 0xff, 0x1e, - 0x25, 0xe2, 0x92, 0x00, 0x8e, 0x69, 0xa1, 0x3b, 0x70, 0xd4, 0x78, 0x8f, 0x2a, 0x4f, 0x35, 0xc8, - 0x57, 0x96, 0x27, 0x90, 0xe7, 0x4e, 0x89, 0x4e, 0x1f, 0x5d, 0xce, 0xa2, 0x84, 0xb3, 0x1b, 0x40, - 0x75, 0x98, 0xa8, 0xa6, 0x5a, 0x1d, 0xe8, 0xbe, 0x55, 0xb5, 0x2e, 0xd2, 0x2d, 0xa6, 0x09, 0xa3, - 0x97, 0x61, 0xe0, 0x6d, 0x9f, 0x1b, 0xb6, 0x89, 0xa7, 0x89, 0x8c, 0x92, 0x32, 0xf0, 0xc6, 0xb5, - 0x0a, 0x2b, 0xdf, 0xdf, 0x2d, 0x0d, 0x95, 0xfd, 0x9a, 0xfc, 0x8b, 0x55, 0x05, 0xf4, 0x03, 0x16, - 0x4c, 0xa7, 0x1f, 0xbc, 0xaa, 0xd3, 0x23, 0xdd, 0x77, 0xda, 0x16, 0x8d, 0x4e, 0x2f, 0xe6, 0x92, - 0xc3, 0x6d, 0x9a, 0x42, 0x1f, 0xa6, 0xfb, 0x29, 0x74, 0xef, 0x12, 0x91, 0xa0, 0xfd, 0xe1, 0x78, - 0x3f, 0xd1, 0xd2, 0xfd, 0xdd, 0xd2, 0x18, 0x3f, 0x19, 0xdd, 0xbb, 0x2a, 0x1e, 0x3d, 0xaf, 0x80, - 0xbe, 0x1b, 0x8e, 0x06, 0x69, 0xd9, 0x30, 0x91, 0x4c, 0xf8, 0x93, 0xdd, 0x9c, 0xb2, 0xc9, 0x09, - 0xc7, 0x59, 0x04, 0x71, 0x76, 0x3b, 0xf6, 0xaf, 0x59, 0x4c, 0x27, 0x20, 0xba, 0x45, 0xc2, 0x56, - 0x3d, 0x3a, 0x04, 0x63, 0xb2, 0x45, 0x43, 0xdf, 0x7e, 0xcf, 0xd6, 0x60, 0xff, 0xd2, 0x62, 0xd6, - 0x60, 0x87, 0xe8, 0xd7, 0xf6, 0x06, 0x0c, 0x44, 0xa2, 0x35, 0xd1, 0xf5, 0x3c, 0xcb, 0x15, 0xd9, - 0x29, 0x66, 0x11, 0xa7, 0x1e, 0x39, 0xb2, 0x14, 0x2b, 0x32, 0xf6, 0x3f, 0xe3, 0x33, 0x20, 0x21, - 0x87, 0xa0, 0xd6, 0x5c, 0x30, 0xd5, 0x9a, 0xa5, 0x0e, 0x5f, 0x90, 0xa3, 0xde, 0xfc, 0xa7, 0x66, - 0xbf, 0x99, 0x70, 0xef, 0xdd, 0x6e, 0x86, 0x68, 0x7f, 0xde, 0x02, 0x88, 0x13, 0x80, 0x74, 0x91, - 0x90, 0xf9, 0x22, 0x7d, 0xd6, 0xf8, 0x91, 0x5f, 0xf5, 0xeb, 0x42, 0xf5, 0x72, 0x32, 0xd6, 0xac, - 0xf2, 0xf2, 0x7d, 0xed, 0x37, 0x56, 0xd8, 0xa8, 0x24, 0x23, 0xf2, 0x16, 0x63, 0x5d, 0xbf, 0x11, - 0x8d, 0xf7, 0x4b, 0x16, 0x1c, 0xc9, 0x72, 0x92, 0xa0, 0x8f, 0x64, 0x2e, 0xe6, 0x54, 0x26, 0xa2, - 0x6a, 0x36, 0x6f, 0x88, 0x72, 0xac, 0x30, 0xba, 0xce, 0x74, 0x7d, 0xb0, 0xe4, 0x14, 0xd7, 0x60, - 0xa4, 0x1c, 0x10, 0x8d, 0xbf, 0x78, 0x35, 0xce, 0x9b, 0x33, 0x38, 0xf7, 0xf4, 0x81, 0x23, 0x0f, - 0xd9, 0x5f, 0x2e, 0xc0, 0x11, 0x6e, 0xe8, 0x34, 0xbb, 0xed, 0xbb, 0xb5, 0xb2, 0x5f, 0x13, 0xae, - 0xad, 0x6f, 0xc2, 0x70, 0x53, 0x93, 0x4d, 0xb7, 0x0b, 0xb4, 0xae, 0xcb, 0xb0, 0x63, 0x69, 0x9a, - 0x5e, 0x8a, 0x0d, 0x5a, 0xa8, 0x06, 0xc3, 0x64, 0xdb, 0xad, 0x2a, 0x6b, 0x99, 0xc2, 0x81, 0x2f, - 0x69, 0xd5, 0xca, 0xa2, 0x46, 0x07, 0x1b, 0x54, 0xbb, 0x36, 0x4f, 0xd6, 0x58, 0xb4, 0x9e, 0x0e, - 0x16, 0x32, 0x3f, 0x6e, 0xc1, 0xf1, 0x9c, 0xb0, 0xec, 0xb4, 0xb9, 0xdb, 0xcc, 0xa4, 0x4c, 0x2c, - 0x5b, 0xd5, 0x1c, 0x37, 0x34, 0xc3, 0x02, 0x8a, 0x3e, 0x0a, 0xd0, 0x8c, 0x53, 0x52, 0x76, 0x88, - 0x5f, 0x6d, 0x44, 0xb2, 0xd5, 0x82, 0x92, 0xaa, 0xcc, 0x95, 0x1a, 0x2d, 0xfb, 0x4b, 0x3d, 0xd0, - 0xcb, 0x0c, 0x93, 0x50, 0x19, 0xfa, 0x37, 0x79, 0xcc, 0xbc, 0xb6, 0xf3, 0x46, 0x71, 0x65, 0x10, - 0xbe, 0x78, 0xde, 0xb4, 0x52, 0x2c, 0xc9, 0xa0, 0x15, 0x98, 0xe4, 0xe9, 0x36, 0xeb, 0x0b, 0xa4, - 0xee, 0xec, 0x48, 0xb1, 0x6f, 0x81, 0x7d, 0xaa, 0x12, 0x7f, 0x2f, 0xa7, 0x51, 0x70, 0x56, 0x3d, - 0xf4, 0x2a, 0x8c, 0xd2, 0x67, 0xb8, 0xdf, 0x8a, 0x24, 0x25, 0x9e, 0xdf, 0x52, 0xbd, 0x4c, 0xd6, - 0x0c, 0x28, 0x4e, 0x60, 0xa3, 0x97, 0x61, 0xa4, 0x99, 0x12, 0x70, 0xf7, 0xc6, 0x92, 0x20, 0x53, - 0xa8, 0x6d, 0xe2, 0x32, 0x3f, 0x89, 0x16, 0xf3, 0x0a, 0x59, 0xdb, 0x0c, 0x48, 0xb8, 0xe9, 0xd7, - 0x6b, 0x8c, 0x03, 0xee, 0xd5, 0xfc, 0x24, 0x12, 0x70, 0x9c, 0xaa, 0x41, 0xa9, 0xac, 0x3b, 0x6e, - 0xbd, 0x15, 0x90, 0x98, 0x4a, 0x9f, 0x49, 0x65, 0x29, 0x01, 0xc7, 0xa9, 0x1a, 0x9d, 0x25, 0xf7, - 0xfd, 0xf7, 0x47, 0x72, 0x6f, 0xff, 0x4c, 0x01, 0x8c, 0xa9, 0x7d, 0x0f, 0xe7, 0xdd, 0x7c, 0x05, - 0x7a, 0x36, 0x82, 0x66, 0x55, 0x18, 0xe1, 0x65, 0x7e, 0x59, 0x9c, 0xfd, 0x9f, 0x7f, 0x19, 0xfd, - 0x8f, 0x59, 0x2d, 0xba, 0xc7, 0x8f, 0x96, 0x03, 0x9f, 0x5e, 0x72, 0x32, 0xac, 0xa6, 0x72, 0x47, - 0xea, 0x97, 0x81, 0x35, 0xda, 0x04, 0xa0, 0x16, 0x3e, 0x15, 0x9c, 0x82, 0x61, 0xaf, 0x56, 0x11, - 0xe1, 0x73, 0x24, 0x15, 0x74, 0x01, 0x86, 0x44, 0x2a, 0x44, 0xe6, 0x35, 0xc3, 0x37, 0x13, 0xb3, - 0xaf, 0x5b, 0x88, 0x8b, 0xb1, 0x8e, 0x63, 0xff, 0x60, 0x01, 0x26, 0x33, 0xdc, 0x1e, 0xf9, 0x35, - 0xb2, 0xe1, 0x86, 0x51, 0xb0, 0x93, 0xbc, 0x9c, 0xb0, 0x28, 0xc7, 0x0a, 0x83, 0x9e, 0x55, 0xfc, - 0xa2, 0x4a, 0x5e, 0x4e, 0xc2, 0xad, 0x48, 0x40, 0x0f, 0x98, 0xaa, 0xff, 0x0c, 0xf4, 0xb4, 0x42, - 0x22, 0x63, 0xdd, 0xab, 0x6b, 0x9b, 0x29, 0xec, 0x19, 0x84, 0x3e, 0x01, 0x37, 0x94, 0x16, 0x5a, - 0x7b, 0x02, 0x72, 0x3d, 0x34, 0x87, 0xd1, 0xce, 0x45, 0xc4, 0x73, 0xbc, 0x48, 0x3c, 0x14, 0xe3, - 0x18, 0xc8, 0xac, 0x14, 0x0b, 0xa8, 0xfd, 0xc5, 0x22, 0x9c, 0xc8, 0x75, 0x84, 0xa6, 0x5d, 0x6f, - 0xf8, 0x9e, 0x1b, 0xf9, 0xca, 0x70, 0x91, 0xc7, 0x3d, 0x26, 0xcd, 0xcd, 0x15, 0x51, 0x8e, 0x15, - 0x06, 0x3a, 0x0b, 0xbd, 0x4c, 0x28, 0x9e, 0x4c, 0x83, 0x86, 0xe7, 0x16, 0x78, 0x44, 0x49, 0x0e, - 0xd6, 0x6e, 0xf5, 0x62, 0xdb, 0x5b, 0xfd, 0x11, 0xca, 0xc1, 0xf8, 0xf5, 0xe4, 0x85, 0x42, 0xbb, - 0xeb, 0xfb, 0x75, 0xcc, 0x80, 0xe8, 0x31, 0x31, 0x5e, 0x09, 0x4b, 0x3d, 0xec, 0xd4, 0xfc, 0x50, - 0x1b, 0xb4, 0x27, 0xa0, 0x7f, 0x8b, 0xec, 0x04, 0xae, 0xb7, 0x91, 0xb4, 0xe0, 0xbc, 0xc2, 0x8b, - 0xb1, 0x84, 0x9b, 0x59, 0xbf, 0xfb, 0xef, 0x47, 0xd6, 0x6f, 0x7d, 0x05, 0x0c, 0x74, 0x64, 0x4f, - 0x7e, 0xa8, 0x08, 0x63, 0x78, 0x6e, 0xe1, 0xfd, 0x89, 0xb8, 0x9e, 0x9e, 0x88, 0xfb, 0x91, 0x1c, - 0xfb, 0x60, 0xb3, 0xf1, 0xcb, 0x16, 0x8c, 0xb1, 0x84, 0x8c, 0x22, 0x8a, 0x89, 0xeb, 0x7b, 0x87, - 0xf0, 0x14, 0x78, 0x04, 0x7a, 0x03, 0xda, 0xa8, 0x98, 0x41, 0xb5, 0xc7, 0x59, 0x4f, 0x30, 0x87, - 0xa1, 0x93, 0xd0, 0xc3, 0xba, 0x40, 0x27, 0x6f, 0x98, 0x1f, 0xc1, 0x0b, 0x4e, 0xe4, 0x60, 0x56, - 0xca, 0xe2, 0x29, 0x62, 0xd2, 0xac, 0xbb, 0xbc, 0xd3, 0xb1, 0xc9, 0xc2, 0xbb, 0x23, 0x44, 0x4a, - 0x66, 0xd7, 0xde, 0x59, 0x3c, 0xc5, 0x6c, 0x92, 0xed, 0x9f, 0xd9, 0x7f, 0x5e, 0x80, 0xd3, 0x99, - 0xf5, 0xba, 0x8e, 0xa7, 0xd8, 0xbe, 0xf6, 0x83, 0x4c, 0xdf, 0x56, 0x3c, 0x44, 0xfb, 0xf8, 0x9e, - 0x6e, 0xb9, 0xff, 0xde, 0x2e, 0xc2, 0x1c, 0x66, 0x0e, 0xd9, 0xbb, 0x24, 0xcc, 0x61, 0x66, 0xdf, - 0x72, 0xc4, 0x04, 0x7f, 0x53, 0xc8, 0xf9, 0x16, 0x26, 0x30, 0x38, 0x47, 0xcf, 0x19, 0x06, 0x0c, - 0xe5, 0x23, 0x9c, 0x9f, 0x31, 0xbc, 0x0c, 0x2b, 0x28, 0x9a, 0x85, 0xb1, 0x86, 0xeb, 0xd1, 0xc3, - 0x67, 0xc7, 0x64, 0xc5, 0x95, 0x2e, 0x63, 0xc5, 0x04, 0xe3, 0x24, 0x3e, 0x72, 0xb5, 0x10, 0x88, - 0xfc, 0xeb, 0x5e, 0x3e, 0xd0, 0xae, 0x9b, 0x31, 0xcd, 0x39, 0xd4, 0x28, 0x66, 0x84, 0x43, 0x5c, - 0xd1, 0xe4, 0x44, 0xc5, 0xee, 0xe5, 0x44, 0xc3, 0xd9, 0x32, 0xa2, 0xe9, 0x97, 0x61, 0xe4, 0x9e, - 0x75, 0x23, 0xf6, 0x37, 0x8a, 0xf0, 0x50, 0x9b, 0x6d, 0xcf, 0xcf, 0x7a, 0x63, 0x0e, 0xb4, 0xb3, - 0x3e, 0x35, 0x0f, 0x65, 0x38, 0xb2, 0xde, 0xaa, 0xd7, 0x77, 0x98, 0x23, 0x18, 0xa9, 0x49, 0x0c, - 0xc1, 0x53, 0x4a, 0xe1, 0xc8, 0x91, 0xa5, 0x0c, 0x1c, 0x9c, 0x59, 0x93, 0x3e, 0xb1, 0xe8, 0x4d, - 0xb2, 0xa3, 0x48, 0x25, 0x9e, 0x58, 0x58, 0x07, 0x62, 0x13, 0x17, 0x5d, 0x82, 0x09, 0x67, 0xdb, - 0x71, 0x79, 0xfa, 0x0b, 0x49, 0x80, 0xbf, 0xb1, 0x94, 0x2c, 0x7a, 0x36, 0x89, 0x80, 0xd3, 0x75, - 0xd0, 0xeb, 0x80, 0xfc, 0x5b, 0xcc, 0xb9, 0xa4, 0x76, 0x89, 0x78, 0x42, 0xeb, 0xce, 0xe6, 0xae, - 0x18, 0x1f, 0x09, 0xd7, 0x52, 0x18, 0x38, 0xa3, 0x56, 0x22, 0x18, 0x5f, 0x5f, 0x7e, 0x30, 0xbe, - 0xf6, 0xe7, 0x62, 0xc7, 0xcc, 0x81, 0x6f, 0xc1, 0xc8, 0x41, 0x2d, 0xa6, 0x9f, 0x80, 0xfe, 0x40, - 0xe4, 0x64, 0x4f, 0x78, 0x5d, 0xcb, 0x8c, 0xd5, 0x12, 0x6e, 0xff, 0x17, 0x0b, 0x94, 0x2c, 0xd9, - 0x8c, 0xbb, 0xfd, 0x32, 0x33, 0xff, 0xe6, 0x52, 0x70, 0x2d, 0xd4, 0xd6, 0x51, 0xcd, 0xfc, 0x3b, - 0x06, 0x62, 0x13, 0x97, 0x2f, 0xb7, 0x30, 0x8e, 0xf0, 0x60, 0x3c, 0x20, 0x44, 0x58, 0x50, 0x85, - 0x81, 0x3e, 0x06, 0xfd, 0x35, 0x77, 0xdb, 0x0d, 0x85, 0x1c, 0xed, 0xc0, 0x7a, 0xbb, 0xf8, 0xfb, - 0x16, 0x38, 0x19, 0x2c, 0xe9, 0xd9, 0x3f, 0x62, 0x81, 0xd2, 0x4b, 0x5e, 0x26, 0x4e, 0x3d, 0xda, - 0x44, 0xaf, 0x01, 0x48, 0x0a, 0x4a, 0xf6, 0x26, 0xad, 0xa5, 0x00, 0x2b, 0xc8, 0xbe, 0xf1, 0x0f, - 0x6b, 0x75, 0xd0, 0xab, 0xd0, 0xb7, 0xc9, 0x68, 0x89, 0x6f, 0x3b, 0xab, 0x54, 0x5d, 0xac, 0x74, - 0x7f, 0xb7, 0x74, 0xc4, 0x6c, 0x53, 0xde, 0x62, 0xbc, 0x96, 0xfd, 0x43, 0x85, 0x78, 0x4e, 0xdf, - 0x68, 0xf9, 0x91, 0x73, 0x08, 0x9c, 0xc8, 0x25, 0x83, 0x13, 0x79, 0x2c, 0x7b, 0xa1, 0x6a, 0x5d, - 0xca, 0xe5, 0x40, 0xae, 0x25, 0x38, 0x90, 0xc7, 0x3b, 0x93, 0x6a, 0xcf, 0x79, 0xfc, 0x73, 0x0b, - 0x26, 0x0c, 0xfc, 0x43, 0xb8, 0x00, 0x97, 0xcc, 0x0b, 0xf0, 0xe1, 0x8e, 0xdf, 0x90, 0x73, 0xf1, - 0x7d, 0x7f, 0x31, 0xd1, 0x77, 0x76, 0xe1, 0xbd, 0x0d, 0x3d, 0x9b, 0x4e, 0x50, 0x13, 0xef, 0xfa, - 0xf3, 0x5d, 0x8d, 0xf5, 0xcc, 0x65, 0x27, 0x10, 0x96, 0x16, 0x4f, 0xcb, 0x51, 0xa7, 0x45, 0x1d, - 0xad, 0x2c, 0x58, 0x53, 0xe8, 0x22, 0xf4, 0x85, 0x55, 0xbf, 0xa9, 0xfc, 0xe4, 0x58, 0x3a, 0xed, - 0x0a, 0x2b, 0xd9, 0xdf, 0x2d, 0x21, 0xb3, 0x39, 0x5a, 0x8c, 0x05, 0x3e, 0x7a, 0x13, 0x46, 0xd8, - 0x2f, 0x65, 0xf6, 0x58, 0xcc, 0x97, 0xc0, 0x54, 0x74, 0x44, 0x6e, 0x13, 0x6c, 0x14, 0x61, 0x93, - 0xd4, 0xf4, 0x06, 0x0c, 0xaa, 0xcf, 0x7a, 0xa0, 0xda, 0xfa, 0xff, 0x58, 0x84, 0xc9, 0x8c, 0x35, - 0x87, 0x42, 0x63, 0x26, 0x2e, 0x74, 0xb9, 0x54, 0xdf, 0xe1, 0x5c, 0x84, 0xec, 0x01, 0x58, 0x13, - 0x6b, 0xab, 0xeb, 0x46, 0xaf, 0x87, 0x24, 0xd9, 0x28, 0x2d, 0xea, 0xdc, 0x28, 0x6d, 0xec, 0xd0, - 0x86, 0x9a, 0x36, 0xa4, 0x7a, 0xfa, 0x40, 0xe7, 0xf4, 0x37, 0x7b, 0xe0, 0x48, 0x56, 0x0c, 0x69, - 0xf4, 0x19, 0x10, 0xe9, 0xff, 0xc5, 0xb4, 0x3e, 0xdf, 0x6e, 0x84, 0xf5, 0x9a, 0x33, 0xcc, 0x17, - 0x4c, 0x84, 0x6e, 0x9d, 0x91, 0xc7, 0x11, 0x2f, 0xec, 0x38, 0xcc, 0xa2, 0x4d, 0x16, 0x52, 0x49, - 0xdc, 0x9e, 0xf2, 0xf8, 0xf8, 0x50, 0xd7, 0x1d, 0x10, 0xf7, 0x6f, 0x98, 0x30, 0xa9, 0x92, 0xc5, - 0x9d, 0x4d, 0xaa, 0x64, 0xcb, 0x68, 0x19, 0xfa, 0xaa, 0xdc, 0x56, 0xa7, 0xd8, 0xf9, 0x08, 0xe3, - 0x86, 0x3a, 0xea, 0x00, 0x16, 0x06, 0x3a, 0x82, 0xc0, 0xb4, 0x0b, 0x43, 0xda, 0xc0, 0x3c, 0xd0, - 0xc5, 0xb3, 0x45, 0x2f, 0x3e, 0x6d, 0x08, 0x1e, 0xe8, 0x02, 0xfa, 0x31, 0xed, 0xee, 0x17, 0xe7, - 0xc1, 0x07, 0x0d, 0xde, 0xe9, 0x64, 0xc2, 0x05, 0x2f, 0xb1, 0xaf, 0x18, 0x2f, 0x55, 0x31, 0x63, - 0x9e, 0xe7, 0xa6, 0x4e, 0x32, 0x2f, 0xfc, 0xf6, 0x71, 0xce, 0xed, 0x1f, 0xb7, 0x20, 0xe1, 0x24, - 0xa5, 0xc4, 0x9d, 0x56, 0xae, 0xb8, 0xf3, 0x0c, 0xf4, 0x04, 0x7e, 0x9d, 0x24, 0x53, 0xd3, 0x63, - 0xbf, 0x4e, 0x30, 0x83, 0x50, 0x8c, 0x28, 0x16, 0x62, 0x0d, 0xeb, 0x0f, 0x74, 0xf1, 0xf4, 0x7e, - 0x04, 0x7a, 0xeb, 0x64, 0x9b, 0xd4, 0x93, 0x19, 0x44, 0xaf, 0xd2, 0x42, 0xcc, 0x61, 0xf6, 0x2f, - 0xf7, 0xc0, 0xa9, 0xb6, 0x91, 0xd7, 0x28, 0x83, 0xb9, 0xe1, 0x44, 0xe4, 0xb6, 0xb3, 0x93, 0xcc, - 0x9c, 0x77, 0x89, 0x17, 0x63, 0x09, 0x67, 0xce, 0xc8, 0x3c, 0x93, 0x4c, 0x42, 0x38, 0x2c, 0x12, - 0xc8, 0x08, 0xa8, 0x29, 0x6c, 0x2c, 0xde, 0x0f, 0x61, 0xe3, 0xb3, 0x00, 0x61, 0x58, 0xe7, 0x06, - 0x97, 0x35, 0xe1, 0xe5, 0x1c, 0x67, 0x1c, 0xaa, 0x5c, 0x15, 0x10, 0xac, 0x61, 0xa1, 0x05, 0x18, - 0x6f, 0x06, 0x7e, 0xc4, 0x65, 0xed, 0x0b, 0xdc, 0x26, 0xb9, 0xd7, 0x0c, 0x7a, 0x55, 0x4e, 0xc0, - 0x71, 0xaa, 0x06, 0x7a, 0x01, 0x86, 0x44, 0x20, 0xac, 0xb2, 0xef, 0xd7, 0x85, 0x78, 0x4f, 0x99, - 0xe9, 0x56, 0x62, 0x10, 0xd6, 0xf1, 0xb4, 0x6a, 0x4c, 0x80, 0xdf, 0x9f, 0x59, 0x8d, 0x0b, 0xf1, - 0x35, 0xbc, 0x44, 0xd0, 0xfc, 0x81, 0xae, 0x82, 0xe6, 0xc7, 0x02, 0xcf, 0xc1, 0xae, 0xf5, 0xc9, - 0xd0, 0x51, 0x44, 0xf8, 0x95, 0x1e, 0x98, 0x14, 0x0b, 0xe7, 0x41, 0x2f, 0x97, 0xeb, 0xe9, 0xe5, - 0x72, 0x3f, 0x44, 0xa2, 0xef, 0xaf, 0x99, 0xc3, 0x5e, 0x33, 0x3f, 0x6c, 0x81, 0xc9, 0x43, 0xa2, - 0xff, 0x2f, 0x37, 0xf5, 0xe8, 0x0b, 0xb9, 0x3c, 0x69, 0x1c, 0x51, 0xfb, 0x9d, 0x25, 0x21, 0xb5, - 0xff, 0x93, 0x05, 0x0f, 0x77, 0xa4, 0x88, 0x16, 0x61, 0x90, 0x31, 0xba, 0xda, 0xbb, 0xf8, 0x71, - 0xe5, 0xb3, 0x20, 0x01, 0x39, 0x7c, 0x77, 0x5c, 0x13, 0x2d, 0xa6, 0x72, 0xbc, 0x3e, 0x91, 0x91, - 0xe3, 0xf5, 0xa8, 0x31, 0x3c, 0xf7, 0x98, 0xe4, 0xf5, 0x0b, 0xf4, 0xc6, 0x31, 0x7d, 0x12, 0x3f, - 0x64, 0x88, 0x73, 0xed, 0x84, 0x38, 0x17, 0x99, 0xd8, 0xda, 0x1d, 0xf2, 0x1a, 0x8c, 0xb3, 0x08, - 0x99, 0xcc, 0x83, 0x46, 0x38, 0x33, 0x16, 0x62, 0x2b, 0xf9, 0xab, 0x09, 0x18, 0x4e, 0x61, 0xdb, - 0x7f, 0x5a, 0x84, 0x3e, 0xbe, 0xfd, 0x0e, 0xe1, 0xe1, 0xfb, 0x14, 0x0c, 0xba, 0x8d, 0x46, 0x8b, - 0xa7, 0xed, 0xec, 0x8d, 0x6d, 0xae, 0x97, 0x65, 0x21, 0x8e, 0xe1, 0x68, 0x49, 0x68, 0x12, 0xda, - 0x04, 0xe1, 0xe6, 0x1d, 0x9f, 0x59, 0x70, 0x22, 0x87, 0x73, 0x71, 0xea, 0x9e, 0x8d, 0x75, 0x0e, - 0xe8, 0x93, 0x00, 0x61, 0x14, 0xb8, 0xde, 0x06, 0x2d, 0x13, 0x99, 0x1a, 0x9e, 0x6c, 0x43, 0xad, - 0xa2, 0x90, 0x39, 0xcd, 0xf8, 0xcc, 0x51, 0x00, 0xac, 0x51, 0x44, 0x33, 0xc6, 0x4d, 0x3f, 0x9d, - 0x98, 0x3b, 0xe0, 0x54, 0xe3, 0x39, 0x9b, 0x7e, 0x11, 0x06, 0x15, 0xf1, 0x4e, 0x72, 0xc5, 0x61, - 0x9d, 0x61, 0xfb, 0x08, 0x8c, 0x25, 0xfa, 0x76, 0x20, 0xb1, 0xe4, 0xaf, 0x58, 0x30, 0xc6, 0x3b, - 0xb3, 0xe8, 0x6d, 0x8b, 0xdb, 0xe0, 0x2e, 0x1c, 0xa9, 0x67, 0x9c, 0xca, 0x62, 0xfa, 0xbb, 0x3f, - 0xc5, 0x95, 0x18, 0x32, 0x0b, 0x8a, 0x33, 0xdb, 0x40, 0xe7, 0xe8, 0x8e, 0xa3, 0xa7, 0xae, 0x53, - 0x17, 0xd1, 0x36, 0x86, 0xf9, 0x6e, 0xe3, 0x65, 0x58, 0x41, 0xed, 0x3f, 0xb4, 0x60, 0x82, 0xf7, - 0xfc, 0x0a, 0xd9, 0x51, 0x67, 0xd3, 0xb7, 0xb2, 0xef, 0x22, 0x61, 0x74, 0x21, 0x27, 0x61, 0xb4, - 0xfe, 0x69, 0xc5, 0xb6, 0x9f, 0xf6, 0x65, 0x0b, 0xc4, 0x0a, 0x39, 0x04, 0x49, 0xcb, 0x77, 0x98, - 0x92, 0x96, 0xe9, 0xfc, 0x4d, 0x90, 0x23, 0x62, 0xf9, 0x6b, 0x0b, 0xc6, 0x39, 0x42, 0x6c, 0x05, - 0xf1, 0x2d, 0x9d, 0x87, 0x39, 0xf3, 0x8b, 0x32, 0xcd, 0x5a, 0xaf, 0x90, 0x9d, 0x35, 0xbf, 0xec, - 0x44, 0x9b, 0xd9, 0x1f, 0x65, 0x4c, 0x56, 0x4f, 0xdb, 0xc9, 0xaa, 0xc9, 0x0d, 0x64, 0x24, 0x26, - 0xec, 0x20, 0x00, 0x3e, 0x68, 0x62, 0x42, 0xfb, 0xcf, 0x2c, 0x40, 0xbc, 0x19, 0x83, 0x71, 0xa3, - 0xec, 0x10, 0x2b, 0xd5, 0x2e, 0xba, 0xf8, 0x68, 0x52, 0x10, 0xac, 0x61, 0xdd, 0x97, 0xe1, 0x49, - 0x98, 0xb2, 0x14, 0x3b, 0x9b, 0xb2, 0x1c, 0x60, 0x44, 0xbf, 0xdc, 0x0f, 0x49, 0x9f, 0x49, 0x74, - 0x03, 0x86, 0xab, 0x4e, 0xd3, 0xb9, 0xe5, 0xd6, 0xdd, 0xc8, 0x25, 0x61, 0x3b, 0x3b, 0xb7, 0x79, - 0x0d, 0x4f, 0x18, 0x1f, 0x68, 0x25, 0xd8, 0xa0, 0x83, 0x66, 0x00, 0x9a, 0x81, 0xbb, 0xed, 0xd6, - 0xc9, 0x06, 0x13, 0x08, 0xb1, 0xf8, 0x3e, 0xdc, 0xe8, 0x4e, 0x96, 0x62, 0x0d, 0x23, 0x23, 0xf4, - 0x46, 0xf1, 0x01, 0x87, 0xde, 0x80, 0x43, 0x0b, 0xbd, 0xd1, 0x73, 0xa0, 0xd0, 0x1b, 0x03, 0x07, - 0x0e, 0xbd, 0xd1, 0xdb, 0x55, 0xe8, 0x0d, 0x0c, 0xc7, 0x24, 0xef, 0x49, 0xff, 0x2f, 0xb9, 0x75, - 0x22, 0x1e, 0x1c, 0x3c, 0x28, 0xd1, 0xf4, 0xde, 0x6e, 0xe9, 0x18, 0xce, 0xc4, 0xc0, 0x39, 0x35, - 0xd1, 0x47, 0x61, 0xca, 0xa9, 0xd7, 0xfd, 0xdb, 0x6a, 0x52, 0x17, 0xc3, 0xaa, 0x53, 0xe7, 0xca, - 0xa5, 0x7e, 0x46, 0xf5, 0xe4, 0xde, 0x6e, 0x69, 0x6a, 0x36, 0x07, 0x07, 0xe7, 0xd6, 0x46, 0xaf, - 0xc0, 0x60, 0x33, 0xf0, 0xab, 0x2b, 0x9a, 0x63, 0xf7, 0x69, 0x3a, 0x80, 0x65, 0x59, 0xb8, 0xbf, - 0x5b, 0x1a, 0x51, 0x7f, 0xd8, 0x85, 0x1f, 0x57, 0xc8, 0x88, 0x6a, 0x31, 0xf4, 0xa0, 0xa3, 0x5a, - 0x0c, 0xdf, 0xef, 0xa8, 0x16, 0x5b, 0x30, 0x59, 0x21, 0x81, 0xeb, 0xd4, 0xdd, 0xbb, 0x94, 0x27, - 0x97, 0x67, 0xe0, 0x1a, 0x0c, 0x06, 0x89, 0x53, 0xbf, 0xab, 0xe0, 0xdb, 0x9a, 0x5c, 0x46, 0x9e, - 0xf2, 0x31, 0x21, 0xfb, 0x7f, 0x5b, 0xd0, 0x2f, 0xfc, 0x30, 0x0f, 0x81, 0x33, 0x9d, 0x35, 0x54, - 0x32, 0xa5, 0xec, 0x49, 0x61, 0x9d, 0xc9, 0x55, 0xc6, 0x2c, 0x27, 0x94, 0x31, 0x0f, 0xb7, 0x23, - 0xd2, 0x5e, 0x0d, 0xf3, 0x77, 0x8b, 0xf4, 0x85, 0x60, 0x44, 0x04, 0x78, 0xf0, 0x43, 0xb0, 0x0a, - 0xfd, 0xa1, 0xf0, 0x48, 0x2f, 0xe4, 0xfb, 0xf2, 0x24, 0x27, 0x31, 0xb6, 0x81, 0x14, 0x3e, 0xe8, - 0x92, 0x48, 0xa6, 0xab, 0x7b, 0xf1, 0x01, 0xba, 0xba, 0x77, 0x8a, 0x99, 0xd0, 0x73, 0x3f, 0x62, - 0x26, 0xd8, 0x5f, 0x63, 0xb7, 0xb3, 0x5e, 0x7e, 0x08, 0x8c, 0xdb, 0x25, 0xf3, 0x1e, 0xb7, 0xdb, - 0xac, 0x2c, 0xd1, 0xa9, 0x1c, 0x06, 0xee, 0x97, 0x2c, 0x38, 0x95, 0xf1, 0x55, 0x1a, 0x37, 0xf7, - 0x34, 0x0c, 0x38, 0xad, 0x9a, 0xab, 0xf6, 0xb2, 0xa6, 0x2d, 0x9e, 0x15, 0xe5, 0x58, 0x61, 0xa0, - 0x79, 0x98, 0x20, 0x77, 0x9a, 0x2e, 0x57, 0xc3, 0xeb, 0xa6, 0xe3, 0x45, 0xee, 0xbc, 0xbb, 0x98, - 0x04, 0xe2, 0x34, 0xbe, 0x0a, 0x89, 0x56, 0xcc, 0x0d, 0x89, 0xf6, 0x0b, 0x16, 0x0c, 0x29, 0x9f, - 0xec, 0x07, 0x3e, 0xda, 0xaf, 0x99, 0xa3, 0xfd, 0x50, 0x9b, 0xd1, 0xce, 0x19, 0xe6, 0x3f, 0x28, - 0xa8, 0xfe, 0x96, 0xfd, 0x20, 0xea, 0x82, 0x4b, 0xbc, 0x77, 0xb7, 0x97, 0x0b, 0x30, 0xe4, 0x34, - 0x9b, 0x12, 0x20, 0xed, 0x17, 0x59, 0x2a, 0x85, 0xb8, 0x18, 0xeb, 0x38, 0xca, 0x0b, 0xa7, 0x98, - 0xeb, 0x85, 0x53, 0x03, 0x88, 0x9c, 0x60, 0x83, 0x44, 0xb4, 0x4c, 0x98, 0x5b, 0xe7, 0x9f, 0x37, - 0xad, 0xc8, 0xad, 0xcf, 0xb8, 0x5e, 0x14, 0x46, 0xc1, 0xcc, 0xb2, 0x17, 0x5d, 0x0b, 0xf8, 0x33, - 0x55, 0x0b, 0x2a, 0xa8, 0x68, 0x61, 0x8d, 0xae, 0x8c, 0x3f, 0xc2, 0xda, 0xe8, 0x35, 0x0d, 0x61, - 0x56, 0x45, 0x39, 0x56, 0x18, 0xf6, 0x8b, 0xec, 0xf6, 0x61, 0x63, 0x7a, 0xb0, 0x80, 0x7a, 0x7f, - 0x3e, 0xac, 0x66, 0x83, 0xa9, 0x84, 0x17, 0xf4, 0xb0, 0x7d, 0xed, 0x0f, 0x7b, 0xda, 0xb0, 0xee, - 0xcf, 0x1a, 0xc7, 0xf6, 0x43, 0x1f, 0x4f, 0x19, 0x37, 0x3d, 0xd3, 0xe1, 0xd6, 0x38, 0x80, 0x39, - 0x13, 0xcb, 0xab, 0xc6, 0xb2, 0x4e, 0x2d, 0x97, 0xc5, 0xbe, 0xd0, 0xf2, 0xaa, 0x09, 0x00, 0x8e, - 0x71, 0x28, 0xc3, 0xa6, 0xfe, 0x84, 0x53, 0x28, 0x0e, 0xbf, 0xad, 0xb0, 0x43, 0xac, 0x61, 0xa0, - 0xf3, 0x42, 0x68, 0xc1, 0x75, 0x0f, 0x0f, 0x25, 0x84, 0x16, 0x72, 0xb8, 0x34, 0x49, 0xd3, 0x05, - 0x18, 0x22, 0x77, 0x22, 0x12, 0x78, 0x4e, 0x9d, 0xb6, 0xd0, 0x1b, 0x47, 0x8c, 0x5d, 0x8c, 0x8b, - 0xb1, 0x8e, 0x83, 0xd6, 0x60, 0x2c, 0xe4, 0xb2, 0x3c, 0x95, 0xf4, 0x81, 0xcb, 0x44, 0x9f, 0x54, - 0xde, 0xf0, 0x26, 0x78, 0x9f, 0x15, 0xf1, 0xd3, 0x49, 0xc6, 0x08, 0x49, 0x92, 0x40, 0xaf, 0xc2, - 0x68, 0xdd, 0x77, 0x6a, 0x73, 0x4e, 0xdd, 0xf1, 0xaa, 0x6c, 0x7c, 0x06, 0xcc, 0xec, 0xfc, 0x57, - 0x0d, 0x28, 0x4e, 0x60, 0x53, 0x06, 0x51, 0x2f, 0x11, 0x89, 0x4a, 0x1c, 0x6f, 0x83, 0x84, 0x53, - 0x83, 0xec, 0xab, 0x18, 0x83, 0x78, 0x35, 0x07, 0x07, 0xe7, 0xd6, 0x46, 0x17, 0x61, 0x58, 0x7e, - 0xbe, 0x16, 0x52, 0x27, 0x76, 0x68, 0xd2, 0x60, 0xd8, 0xc0, 0x44, 0x21, 0x1c, 0x95, 0xff, 0xd7, - 0x02, 0x67, 0x7d, 0xdd, 0xad, 0x8a, 0x38, 0x13, 0xdc, 0xf9, 0xfb, 0x23, 0xd2, 0xd3, 0x74, 0x31, - 0x0b, 0x69, 0x7f, 0xb7, 0x74, 0x52, 0x8c, 0x5a, 0x26, 0x1c, 0x67, 0xd3, 0x46, 0x2b, 0x30, 0xc9, - 0x6d, 0x60, 0xe6, 0x37, 0x49, 0x75, 0x4b, 0x6e, 0x38, 0xc6, 0x35, 0x6a, 0x8e, 0x3f, 0x97, 0xd3, - 0x28, 0x38, 0xab, 0x1e, 0x7a, 0x0b, 0xa6, 0x9a, 0xad, 0x5b, 0x75, 0x37, 0xdc, 0x5c, 0xf5, 0x23, - 0x66, 0x42, 0x36, 0x5b, 0xab, 0x05, 0x24, 0xe4, 0xbe, 0xc1, 0xec, 0xea, 0x95, 0x61, 0x90, 0xca, - 0x39, 0x78, 0x38, 0x97, 0x02, 0xba, 0x0b, 0x47, 0x13, 0x0b, 0x41, 0xc4, 0x33, 0x19, 0xcd, 0x4f, - 0xf9, 0x54, 0xc9, 0xaa, 0x20, 0x42, 0x03, 0x65, 0x81, 0x70, 0x76, 0x13, 0xe8, 0x25, 0x00, 0xb7, - 0xb9, 0xe4, 0x34, 0xdc, 0x3a, 0x7d, 0x8e, 0x4e, 0xb2, 0x35, 0x42, 0x9f, 0x26, 0xb0, 0x5c, 0x96, - 0xa5, 0xf4, 0x6c, 0x16, 0xff, 0x76, 0xb0, 0x86, 0x8d, 0xae, 0xc2, 0xa8, 0xf8, 0xb7, 0x23, 0xa6, - 0x74, 0x42, 0x65, 0x07, 0x1d, 0x95, 0x35, 0xd4, 0x3c, 0x26, 0x4a, 0x70, 0xa2, 0x2e, 0xda, 0x80, - 0x53, 0x32, 0x35, 0xa9, 0xbe, 0x3e, 0xe5, 0x1c, 0x84, 0x2c, 0xcf, 0xd2, 0x00, 0xf7, 0x29, 0x9a, - 0x6d, 0x87, 0x88, 0xdb, 0xd3, 0xa1, 0xf7, 0xba, 0xbe, 0xcc, 0xb9, 0xc7, 0xf8, 0xd1, 0x38, 0x12, - 0xe6, 0xd5, 0x24, 0x10, 0xa7, 0xf1, 0x91, 0x0f, 0x47, 0x5d, 0x2f, 0x6b, 0x55, 0x1f, 0x63, 0x84, - 0x3e, 0xcc, 0x9d, 0xe5, 0xdb, 0xaf, 0xe8, 0x4c, 0x38, 0xce, 0xa6, 0x8b, 0x96, 0x61, 0x32, 0xe2, - 0x05, 0x0b, 0x6e, 0xc8, 0xd3, 0xb8, 0xd0, 0x67, 0xdf, 0x71, 0xd6, 0xdc, 0x71, 0xba, 0x9a, 0xd7, - 0xd2, 0x60, 0x9c, 0x55, 0xe7, 0x9d, 0x19, 0x80, 0x7e, 0xdd, 0xa2, 0xb5, 0x35, 0x46, 0x1f, 0x7d, - 0x0a, 0x86, 0xf5, 0xf1, 0x11, 0x4c, 0xcb, 0xd9, 0x6c, 0x3e, 0x58, 0x3b, 0x5e, 0xf8, 0x33, 0x41, - 0x1d, 0x21, 0x3a, 0x0c, 0x1b, 0x14, 0x51, 0x35, 0x23, 0xc8, 0xc5, 0xf9, 0xee, 0x98, 0xa2, 0xee, - 0xed, 0x1f, 0x09, 0x64, 0xef, 0x1c, 0x74, 0x15, 0x06, 0xaa, 0x75, 0x97, 0x78, 0xd1, 0x72, 0xb9, - 0x5d, 0x80, 0xd2, 0x79, 0x81, 0x23, 0xb6, 0xa2, 0xc8, 0xbe, 0xc4, 0xcb, 0xb0, 0xa2, 0x60, 0x5f, - 0x84, 0xa1, 0x4a, 0x9d, 0x90, 0x26, 0xf7, 0xe3, 0x42, 0x4f, 0xb0, 0x87, 0x09, 0x63, 0x2d, 0x2d, - 0xc6, 0x5a, 0xea, 0x6f, 0x0e, 0xc6, 0x54, 0x4a, 0xb8, 0xfd, 0xdb, 0x05, 0x28, 0x75, 0x48, 0x02, - 0x96, 0xd0, 0xb7, 0x59, 0x5d, 0xe9, 0xdb, 0x66, 0x61, 0x2c, 0xfe, 0xa7, 0x8b, 0xf2, 0x94, 0x31, - 0xf4, 0x0d, 0x13, 0x8c, 0x93, 0xf8, 0x5d, 0xfb, 0xb5, 0xe8, 0x2a, 0xbb, 0x9e, 0x8e, 0x9e, 0x59, - 0x86, 0xaa, 0xbe, 0xb7, 0xfb, 0xb7, 0x77, 0xae, 0xda, 0xd5, 0xfe, 0x5a, 0x01, 0x8e, 0xaa, 0x21, - 0x7c, 0xef, 0x0e, 0xdc, 0xf5, 0xf4, 0xc0, 0xdd, 0x07, 0xa5, 0xb5, 0x7d, 0x0d, 0xfa, 0x78, 0xd4, - 0xd4, 0x2e, 0x78, 0xfe, 0x47, 0xcc, 0xe0, 0xf4, 0x8a, 0xcd, 0x34, 0x02, 0xd4, 0xff, 0x80, 0x05, - 0x63, 0x09, 0x07, 0x49, 0x84, 0x35, 0x2f, 0xfa, 0x7b, 0xe1, 0xcb, 0xb3, 0x38, 0xfe, 0x33, 0xd0, - 0xb3, 0xe9, 0x2b, 0x23, 0x65, 0x85, 0x71, 0xd9, 0x0f, 0x23, 0xcc, 0x20, 0xf6, 0x1f, 0x59, 0xd0, - 0xbb, 0xe6, 0xb8, 0x5e, 0x24, 0xb5, 0x1f, 0x56, 0x8e, 0xf6, 0xa3, 0x9b, 0xef, 0x42, 0x2f, 0x40, - 0x1f, 0x59, 0x5f, 0x27, 0xd5, 0x48, 0xcc, 0xaa, 0x8c, 0xa6, 0xd1, 0xb7, 0xc8, 0x4a, 0x29, 0x13, - 0xca, 0x1a, 0xe3, 0x7f, 0xb1, 0x40, 0x46, 0x37, 0x61, 0x30, 0x72, 0x1b, 0x64, 0xb6, 0x56, 0x13, - 0x36, 0x01, 0xf7, 0x10, 0x02, 0x66, 0x4d, 0x12, 0xc0, 0x31, 0x2d, 0xfb, 0x8b, 0x05, 0x80, 0x38, - 0x14, 0x5c, 0xa7, 0x4f, 0x9c, 0x4b, 0x69, 0x8b, 0xcf, 0x66, 0x68, 0x8b, 0x51, 0x4c, 0x30, 0x43, - 0x55, 0xac, 0x86, 0xa9, 0xd8, 0xd5, 0x30, 0xf5, 0x1c, 0x64, 0x98, 0xe6, 0x61, 0x22, 0x0e, 0x65, - 0x67, 0x46, 0xf2, 0x64, 0xf7, 0xf7, 0x5a, 0x12, 0x88, 0xd3, 0xf8, 0x36, 0x81, 0x33, 0x2a, 0xa2, - 0x97, 0xb8, 0x0b, 0x99, 0x2b, 0x81, 0xae, 0x7d, 0xef, 0x30, 0x4e, 0xb1, 0x3a, 0xbc, 0x90, 0xab, - 0x0e, 0xff, 0x29, 0x0b, 0x8e, 0x24, 0xdb, 0x61, 0x7e, 0xf7, 0x9f, 0xb7, 0xe0, 0x68, 0x9c, 0x03, - 0x27, 0x6d, 0x82, 0xf0, 0x7c, 0xdb, 0x28, 0x65, 0x39, 0x3d, 0x8e, 0xc3, 0xb6, 0xac, 0x64, 0x91, - 0xc6, 0xd9, 0x2d, 0xda, 0xff, 0xab, 0x07, 0xa6, 0xf2, 0xc2, 0x9b, 0x31, 0x4f, 0x23, 0xe7, 0x4e, - 0x65, 0x8b, 0xdc, 0x16, 0xfe, 0x1c, 0xb1, 0xa7, 0x11, 0x2f, 0xc6, 0x12, 0x9e, 0x4c, 0x7b, 0x54, - 0xe8, 0x32, 0xed, 0xd1, 0x26, 0x4c, 0xdc, 0xde, 0x24, 0xde, 0x75, 0x2f, 0x74, 0x22, 0x37, 0x5c, - 0x77, 0x99, 0x02, 0x9d, 0xaf, 0x1b, 0x99, 0xba, 0x7f, 0xe2, 0x66, 0x12, 0x61, 0x7f, 0xb7, 0x74, - 0xca, 0x28, 0x88, 0xbb, 0xcc, 0x0f, 0x12, 0x9c, 0x26, 0x9a, 0xce, 0x1a, 0xd5, 0xf3, 0x80, 0xb3, - 0x46, 0x35, 0x5c, 0x61, 0x76, 0x23, 0xdd, 0x48, 0xd8, 0xb3, 0x75, 0x45, 0x95, 0x62, 0x0d, 0x03, - 0x7d, 0x02, 0x90, 0x9e, 0xf6, 0xcf, 0x88, 0x2e, 0xfb, 0xcc, 0xde, 0x6e, 0x09, 0xad, 0xa6, 0xa0, - 0xfb, 0xbb, 0xa5, 0x49, 0x5a, 0xba, 0xec, 0xd1, 0xe7, 0x6f, 0x1c, 0x92, 0x2f, 0x83, 0x10, 0xba, - 0x09, 0xe3, 0xb4, 0x94, 0xed, 0x28, 0x19, 0xba, 0x96, 0x3f, 0x59, 0x9f, 0xda, 0xdb, 0x2d, 0x8d, - 0xaf, 0x26, 0x60, 0x79, 0xa4, 0x53, 0x44, 0x32, 0x92, 0x47, 0x0d, 0x74, 0x9b, 0x3c, 0xca, 0xfe, - 0xbc, 0x05, 0x27, 0xe8, 0x05, 0x57, 0xbb, 0x9a, 0xa3, 0x45, 0x77, 0x9a, 0x2e, 0xd7, 0xd3, 0x88, - 0xab, 0x86, 0xc9, 0xea, 0xca, 0xcb, 0x5c, 0x4b, 0xa3, 0xa0, 0xf4, 0x84, 0xdf, 0x72, 0xbd, 0x5a, - 0xf2, 0x84, 0xbf, 0xe2, 0x7a, 0x35, 0xcc, 0x20, 0xea, 0xca, 0x2a, 0xe6, 0x46, 0xa9, 0xff, 0x0a, - 0xdd, 0xab, 0xb4, 0x2f, 0xdf, 0xd2, 0x6e, 0xa0, 0xa7, 0x74, 0x9d, 0xaa, 0x30, 0x9f, 0xcc, 0xd5, - 0xa7, 0x7e, 0xce, 0x02, 0xe1, 0xfd, 0xde, 0xc5, 0x9d, 0xfc, 0x26, 0x0c, 0x6f, 0xa7, 0x53, 0xa2, - 0x9e, 0xc9, 0x0f, 0x07, 0x20, 0x12, 0xa1, 0x2a, 0x16, 0xdd, 0x48, 0x7f, 0x6a, 0xd0, 0xb2, 0x6b, - 0x20, 0xa0, 0x0b, 0x84, 0x69, 0x35, 0x3a, 0xf7, 0xe6, 0x59, 0x80, 0x1a, 0xc3, 0x65, 0x79, 0xd2, - 0x0b, 0x26, 0xc7, 0xb5, 0xa0, 0x20, 0x58, 0xc3, 0xb2, 0x7f, 0xae, 0x08, 0x43, 0x32, 0x05, 0x67, - 0xcb, 0xeb, 0x46, 0xf6, 0x78, 0xa0, 0x9c, 0xfc, 0xe8, 0x2d, 0x98, 0x08, 0x48, 0xb5, 0x15, 0x84, - 0xee, 0x36, 0x91, 0x60, 0xb1, 0x49, 0x66, 0x78, 0x92, 0x84, 0x04, 0x70, 0x9f, 0x85, 0xc8, 0x4a, - 0x14, 0x32, 0xa5, 0x71, 0x9a, 0x10, 0x3a, 0x0f, 0x83, 0x4c, 0xf4, 0x5e, 0x8e, 0x05, 0xc2, 0x4a, - 0xf0, 0xb5, 0x22, 0x01, 0x38, 0xc6, 0x61, 0x8f, 0x83, 0xd6, 0x2d, 0x86, 0x9e, 0xf0, 0x04, 0xaf, - 0xf0, 0x62, 0x2c, 0xe1, 0xe8, 0xa3, 0x30, 0xce, 0xeb, 0x05, 0x7e, 0xd3, 0xd9, 0xe0, 0x2a, 0xc1, - 0x5e, 0x15, 0x5e, 0x67, 0x7c, 0x25, 0x01, 0xdb, 0xdf, 0x2d, 0x1d, 0x49, 0x96, 0xb1, 0x6e, 0xa7, - 0xa8, 0x30, 0xcb, 0x3f, 0xde, 0x08, 0xbd, 0x33, 0x52, 0x06, 0x83, 0x31, 0x08, 0xeb, 0x78, 0xf6, - 0x5f, 0x59, 0x30, 0xa1, 0x4d, 0x55, 0xd7, 0x79, 0x2a, 0x8c, 0x41, 0x2a, 0x74, 0x31, 0x48, 0x07, - 0x8b, 0xf6, 0x90, 0x39, 0xc3, 0x3d, 0xf7, 0x69, 0x86, 0xed, 0x4f, 0x01, 0x4a, 0xe7, 0x77, 0x45, - 0xaf, 0x73, 0x43, 0x7e, 0x37, 0x20, 0xb5, 0x76, 0x0a, 0x7f, 0x3d, 0x72, 0x8e, 0xf4, 0x5c, 0xe5, - 0xb5, 0xb0, 0xaa, 0x6f, 0xff, 0x60, 0x0f, 0x8c, 0x27, 0x63, 0x75, 0xa0, 0xcb, 0xd0, 0xc7, 0xb9, - 0x74, 0x41, 0xbe, 0x8d, 0x3d, 0x99, 0x16, 0xe1, 0x83, 0xf1, 0x2b, 0x82, 0xd1, 0x17, 0xf5, 0xd1, - 0x5b, 0x30, 0x54, 0xf3, 0x6f, 0x7b, 0xb7, 0x9d, 0xa0, 0x36, 0x5b, 0x5e, 0x16, 0x27, 0x44, 0xa6, - 0x00, 0x6a, 0x21, 0x46, 0xd3, 0xa3, 0x86, 0x30, 0xdb, 0x89, 0x18, 0x84, 0x75, 0x72, 0x68, 0x8d, - 0xa5, 0x2c, 0x5a, 0x77, 0x37, 0x56, 0x9c, 0x66, 0x3b, 0xaf, 0xae, 0x79, 0x89, 0xa4, 0x51, 0x1e, - 0x11, 0x79, 0x8d, 0x38, 0x00, 0xc7, 0x84, 0xd0, 0x67, 0x60, 0x32, 0xcc, 0x51, 0x89, 0xe5, 0xa5, - 0xfb, 0x6e, 0xa7, 0x25, 0xe2, 0xc2, 0x94, 0x2c, 0xe5, 0x59, 0x56, 0x33, 0xe8, 0x0e, 0x20, 0x21, - 0x7a, 0x5e, 0x0b, 0x5a, 0x61, 0x34, 0xd7, 0xf2, 0x6a, 0x75, 0x99, 0xd2, 0xe8, 0x83, 0xd9, 0x72, - 0x82, 0x24, 0xb6, 0xd6, 0x36, 0x8b, 0xdd, 0x9b, 0xc6, 0xc0, 0x19, 0x6d, 0xd8, 0x9f, 0xeb, 0x81, - 0x69, 0x99, 0x50, 0x39, 0xc3, 0x7b, 0xe5, 0xb3, 0x56, 0xc2, 0x7d, 0xe5, 0xa5, 0xfc, 0x83, 0xfe, - 0x81, 0x39, 0xb1, 0x7c, 0x21, 0xed, 0xc4, 0xf2, 0xca, 0x01, 0xbb, 0x71, 0xdf, 0x5c, 0x59, 0xde, - 0xb3, 0xfe, 0x27, 0x7b, 0x47, 0xc0, 0xb8, 0x9a, 0x11, 0xe6, 0x81, 0xd1, 0xcb, 0x52, 0x75, 0x94, - 0xf3, 0xfc, 0xbf, 0x2c, 0x70, 0x8c, 0xcb, 0x7e, 0x58, 0x86, 0x4f, 0x67, 0xe7, 0xac, 0xa2, 0x43, - 0x69, 0x92, 0x46, 0x33, 0xda, 0x59, 0x70, 0x03, 0xd1, 0xe3, 0x4c, 0x9a, 0x8b, 0x02, 0x27, 0x4d, - 0x53, 0x42, 0xb0, 0xa2, 0x83, 0xb6, 0x61, 0x62, 0x83, 0x45, 0x7c, 0xd2, 0x72, 0x1b, 0x8b, 0x73, - 0x21, 0x73, 0xdf, 0x5e, 0x9a, 0x5f, 0xcc, 0x4f, 0x84, 0xcc, 0x1f, 0x7f, 0x29, 0x14, 0x9c, 0x6e, - 0x82, 0x6e, 0x8d, 0x23, 0xce, 0xed, 0x70, 0xb1, 0xee, 0x84, 0x91, 0x5b, 0x9d, 0xab, 0xfb, 0xd5, - 0xad, 0x4a, 0xe4, 0x07, 0x32, 0x01, 0x62, 0xe6, 0xdb, 0x6b, 0xf6, 0x66, 0x25, 0x85, 0x6f, 0x34, - 0x3f, 0xb5, 0xb7, 0x5b, 0x3a, 0x92, 0x85, 0x85, 0x33, 0xdb, 0x42, 0xab, 0xd0, 0xbf, 0xe1, 0x46, - 0x98, 0x34, 0x7d, 0x71, 0x5a, 0x64, 0x1e, 0x85, 0x97, 0x38, 0x8a, 0xd1, 0x12, 0x8b, 0x48, 0x25, - 0x00, 0x58, 0x12, 0x41, 0xaf, 0xab, 0x4b, 0xa0, 0x2f, 0x5f, 0x00, 0x9b, 0xb6, 0xbd, 0xcb, 0xbc, - 0x06, 0x5e, 0x85, 0xa2, 0xb7, 0x1e, 0xb6, 0x8b, 0xc5, 0xb3, 0xba, 0x64, 0xc8, 0xcf, 0xe6, 0xfa, - 0xe9, 0xd3, 0x78, 0x75, 0xa9, 0x82, 0x69, 0x45, 0xe6, 0xf6, 0x1a, 0x56, 0x43, 0x57, 0x24, 0x5c, - 0xca, 0xf4, 0x02, 0x5e, 0xae, 0xcc, 0x57, 0x96, 0x0d, 0x1a, 0x2c, 0xaa, 0x21, 0x2b, 0xc6, 0xbc, - 0x3a, 0xba, 0x01, 0x83, 0x1b, 0xfc, 0xe0, 0x5b, 0x0f, 0x45, 0x52, 0xf5, 0xcc, 0xcb, 0xe8, 0x92, - 0x44, 0x32, 0xe8, 0xb1, 0x2b, 0x43, 0x81, 0x70, 0x4c, 0x0a, 0x7d, 0xce, 0x82, 0xa3, 0xc9, 0xac, - 0xf4, 0xcc, 0x59, 0x4d, 0x98, 0xa9, 0x65, 0x3a, 0x00, 0x94, 0xb3, 0x2a, 0x18, 0x0d, 0x32, 0xf5, - 0x4b, 0x26, 0x1a, 0xce, 0x6e, 0x8e, 0x0e, 0x74, 0x70, 0xab, 0xd6, 0x2e, 0x47, 0x4f, 0x22, 0x30, - 0x11, 0x1f, 0x68, 0x3c, 0xb7, 0x80, 0x69, 0x45, 0xb4, 0x06, 0xb0, 0x5e, 0x27, 0x22, 0xe2, 0xa3, - 0x30, 0x8a, 0xca, 0xbc, 0xfd, 0x97, 0x14, 0x96, 0xa0, 0xc3, 0x5e, 0xa2, 0x71, 0x29, 0xd6, 0xe8, - 0xd0, 0xa5, 0x54, 0x75, 0xbd, 0x1a, 0x09, 0x98, 0x72, 0x2b, 0x67, 0x29, 0xcd, 0x33, 0x8c, 0xf4, - 0x52, 0xe2, 0xe5, 0x58, 0x50, 0x60, 0xb4, 0x48, 0x73, 0x73, 0x3d, 0x6c, 0x97, 0x72, 0x62, 0x9e, - 0x34, 0x37, 0x13, 0x0b, 0x8a, 0xd3, 0x62, 0xe5, 0x58, 0x50, 0xa0, 0x5b, 0x66, 0x9d, 0x6e, 0x20, - 0x12, 0x4c, 0x8d, 0xe5, 0x6f, 0x99, 0x25, 0x8e, 0x92, 0xde, 0x32, 0x02, 0x80, 0x25, 0x11, 0xf4, - 0x49, 0x93, 0xdb, 0x19, 0x67, 0x34, 0x9f, 0xea, 0xc0, 0xed, 0x18, 0x74, 0xdb, 0xf3, 0x3b, 0x2f, - 0x41, 0x61, 0xbd, 0xca, 0x94, 0x62, 0x39, 0x3a, 0x83, 0xa5, 0x79, 0x83, 0x1a, 0x0b, 0xe1, 0xbe, - 0x34, 0x8f, 0x0b, 0xeb, 0x55, 0xba, 0xf4, 0x9d, 0xbb, 0xad, 0x80, 0x2c, 0xb9, 0x75, 0x22, 0xd2, - 0x4f, 0x64, 0x2e, 0xfd, 0x59, 0x89, 0x94, 0x5e, 0xfa, 0x0a, 0x84, 0x63, 0x52, 0x94, 0x6e, 0xcc, - 0x83, 0x4d, 0xe6, 0xd3, 0x55, 0xac, 0x56, 0x9a, 0x6e, 0x26, 0x17, 0xb6, 0x05, 0x23, 0xdb, 0x61, - 0x73, 0x93, 0xc8, 0x53, 0x91, 0xa9, 0xeb, 0x72, 0x22, 0x55, 0xdc, 0x10, 0x88, 0x6e, 0x10, 0xb5, - 0x9c, 0x7a, 0xea, 0x20, 0x67, 0xa2, 0x95, 0x1b, 0x3a, 0x31, 0x6c, 0xd2, 0xa6, 0x0b, 0xe1, 0x6d, - 0x1e, 0x4e, 0x8e, 0x29, 0xee, 0x72, 0x16, 0x42, 0x46, 0xc4, 0x39, 0xbe, 0x10, 0x04, 0x00, 0x4b, - 0x22, 0x6a, 0xb0, 0xd9, 0x05, 0x74, 0xac, 0xc3, 0x60, 0xa7, 0xfa, 0x1b, 0x0f, 0x36, 0xbb, 0x70, - 0x62, 0x52, 0xec, 0xa2, 0x69, 0x66, 0x24, 0xf0, 0x67, 0x6a, 0xbb, 0x9c, 0x8b, 0xa6, 0x53, 0xc2, - 0x7f, 0x7e, 0xd1, 0x64, 0x61, 0xe1, 0xcc, 0xb6, 0xe8, 0xc7, 0x35, 0x65, 0x64, 0x40, 0x91, 0x22, - 0xe3, 0x89, 0x9c, 0xc0, 0x9a, 0xe9, 0xf0, 0x81, 0xfc, 0xe3, 0x14, 0x08, 0xc7, 0xa4, 0x50, 0x0d, - 0x46, 0x9b, 0x46, 0xc4, 0x59, 0x96, 0xea, 0x23, 0x87, 0x2f, 0xc8, 0x8a, 0x4d, 0xcb, 0x25, 0x44, - 0x26, 0x04, 0x27, 0x68, 0x32, 0xcb, 0x3d, 0xee, 0xea, 0xc7, 0x32, 0x81, 0xe4, 0x4c, 0x75, 0x86, - 0x37, 0x20, 0x9f, 0x6a, 0x01, 0xc0, 0x92, 0x08, 0x1d, 0x0d, 0xe1, 0xa0, 0xe6, 0x87, 0x2c, 0xa1, - 0x4e, 0x9e, 0x82, 0x3d, 0x4b, 0x4d, 0x24, 0xc3, 0xac, 0x0b, 0x10, 0x8e, 0x49, 0xd1, 0x93, 0x9c, - 0x5e, 0x78, 0x27, 0xf3, 0x4f, 0xf2, 0xe4, 0x75, 0xc7, 0x4e, 0x72, 0x7a, 0xd9, 0x15, 0xc5, 0x55, - 0xa7, 0xa2, 0x82, 0xb3, 0x64, 0x20, 0x39, 0xfd, 0x52, 0x61, 0xc5, 0xd3, 0xfd, 0x52, 0x20, 0x1c, - 0x93, 0x62, 0x57, 0x31, 0x0b, 0x4d, 0x77, 0xba, 0xcd, 0x55, 0x4c, 0x11, 0x32, 0xae, 0x62, 0x2d, - 0x74, 0x9d, 0xfd, 0x83, 0x05, 0x38, 0xdd, 0x7e, 0xdf, 0xc6, 0x3a, 0xb4, 0x72, 0x6c, 0xb3, 0x94, - 0xd0, 0xa1, 0x71, 0x89, 0x4e, 0x8c, 0xd5, 0x75, 0xc0, 0xe1, 0x4b, 0x30, 0xa1, 0xdc, 0x11, 0xeb, - 0x6e, 0x75, 0x47, 0x4b, 0xce, 0xa9, 0x42, 0xf3, 0x54, 0x92, 0x08, 0x38, 0x5d, 0x07, 0xcd, 0xc2, - 0x98, 0x51, 0xb8, 0xbc, 0x20, 0x9e, 0xff, 0x71, 0x1a, 0x0b, 0x13, 0x8c, 0x93, 0xf8, 0xf6, 0xcf, - 0x5b, 0x70, 0x3c, 0x27, 0x0f, 0x7b, 0xd7, 0xf1, 0x74, 0xd7, 0x61, 0xac, 0x69, 0x56, 0xed, 0x10, - 0x02, 0xdc, 0xc8, 0xf6, 0xae, 0xfa, 0x9a, 0x00, 0xe0, 0x24, 0x51, 0xfb, 0x67, 0x0b, 0x70, 0xaa, - 0xad, 0x7d, 0x3d, 0xc2, 0x70, 0x6c, 0xa3, 0x11, 0x3a, 0xf3, 0x01, 0xa9, 0x11, 0x2f, 0x72, 0x9d, - 0x7a, 0xa5, 0x49, 0xaa, 0x9a, 0x16, 0x94, 0x19, 0xaa, 0x5f, 0x5a, 0xa9, 0xcc, 0xa6, 0x31, 0x70, - 0x4e, 0x4d, 0xb4, 0x04, 0x28, 0x0d, 0x11, 0x33, 0xcc, 0x9e, 0xb8, 0x69, 0x7a, 0x38, 0xa3, 0x06, - 0x7a, 0x11, 0x46, 0x94, 0xdd, 0xbe, 0x36, 0xe3, 0xec, 0x82, 0xc0, 0x3a, 0x00, 0x9b, 0x78, 0xe8, - 0x02, 0xcf, 0x6f, 0x24, 0x32, 0x61, 0x09, 0x95, 0xe9, 0x98, 0x4c, 0x5e, 0x24, 0x8a, 0xb1, 0x8e, - 0x33, 0x77, 0xf1, 0x77, 0xbe, 0x79, 0xfa, 0x03, 0xbf, 0xff, 0xcd, 0xd3, 0x1f, 0xf8, 0xc3, 0x6f, - 0x9e, 0xfe, 0xc0, 0xf7, 0xec, 0x9d, 0xb6, 0x7e, 0x67, 0xef, 0xb4, 0xf5, 0xfb, 0x7b, 0xa7, 0xad, - 0x3f, 0xdc, 0x3b, 0x6d, 0xfd, 0xd7, 0xbd, 0xd3, 0xd6, 0x17, 0xff, 0xe4, 0xf4, 0x07, 0xde, 0x44, - 0x71, 0x84, 0xea, 0xf3, 0x74, 0x76, 0xce, 0x6f, 0x5f, 0xf8, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x67, 0xd5, 0x38, 0x2d, 0xc3, 0x23, 0x01, 0x00, + 0xc9, 0xd9, 0xbf, 0x54, 0x30, 0x1a, 0xe4, 0x93, 0xb8, 0x0a, 0x03, 0x4e, 0xc8, 0x82, 0x78, 0xd7, + 0xda, 0xc9, 0xa5, 0x53, 0xcd, 0x30, 0x47, 0xb5, 0x59, 0x51, 0x13, 0x2b, 0x1a, 0xe8, 0x32, 0xb7, + 0xfd, 0xdc, 0x26, 0xed, 0x84, 0xd2, 0x29, 0x6a, 0x20, 0xad, 0x43, 0xb7, 0x09, 0x16, 0xf5, 0xd1, + 0x27, 0xb8, 0x71, 0xee, 0x15, 0xcf, 0xbf, 0xed, 0x5d, 0xf2, 0x7d, 0x19, 0x12, 0xa8, 0x3b, 0x82, + 0x13, 0xd2, 0x24, 0x57, 0x55, 0xc7, 0x26, 0xb5, 0xee, 0x42, 0x67, 0x7f, 0x06, 0x58, 0x5e, 0x12, + 0x33, 0x26, 0x41, 0x88, 0x08, 0x8c, 0x89, 0x18, 0xa4, 0xb2, 0x4c, 0x8c, 0x5d, 0xe6, 0xf3, 0xdb, + 0xac, 0x1d, 0xeb, 0x71, 0xae, 0x98, 0x24, 0x70, 0x92, 0xa6, 0xbd, 0xc9, 0x0f, 0xe1, 0x25, 0xe2, + 0x44, 0xad, 0x80, 0x84, 0xe8, 0xa3, 0x30, 0x95, 0x7e, 0x19, 0x0b, 0x75, 0x88, 0xc5, 0xb8, 0xe7, + 0x93, 0x7b, 0xbb, 0xa5, 0xa9, 0x4a, 0x0e, 0x0e, 0xce, 0xad, 0x6d, 0xff, 0xac, 0x05, 0xcc, 0x13, + 0xfc, 0x10, 0x38, 0x9f, 0x8f, 0x98, 0x9c, 0xcf, 0x54, 0xde, 0x74, 0xe6, 0x30, 0x3d, 0xcf, 0xf3, + 0x35, 0x5c, 0x0e, 0xfc, 0x3b, 0x3b, 0xc2, 0x76, 0xab, 0xf3, 0x33, 0xce, 0xfe, 0xa2, 0x05, 0x2c, + 0x89, 0x0f, 0xe6, 0xaf, 0x76, 0xa9, 0xe0, 0xe8, 0x6c, 0x96, 0xf0, 0x51, 0x18, 0x58, 0x17, 0xc3, + 0x9f, 0x21, 0x74, 0x32, 0x3a, 0x6c, 0xd2, 0x96, 0x93, 0x26, 0x3c, 0x3a, 0xc5, 0x3f, 0xac, 0xa8, + 0xd9, 0xff, 0xd4, 0x82, 0xe9, 0xfc, 0x6a, 0xe8, 0x3a, 0x1c, 0x0f, 0x48, 0xb5, 0x15, 0x84, 0x74, + 0x4b, 0x88, 0x07, 0x90, 0x70, 0x8a, 0xe2, 0x53, 0xfd, 0xd0, 0xde, 0x6e, 0xe9, 0x38, 0xce, 0x46, + 0xc1, 0x79, 0x75, 0xd1, 0x4b, 0x30, 0xda, 0x0a, 0x39, 0xe7, 0xc7, 0x98, 0xae, 0x50, 0x44, 0x8a, + 0x66, 0x7e, 0x43, 0xd7, 0x0d, 0x08, 0x4e, 0x60, 0xda, 0xdf, 0xc5, 0x97, 0xa3, 0x0a, 0x16, 0xdd, + 0x80, 0x09, 0x4f, 0xfb, 0x4f, 0x6f, 0x40, 0xf9, 0xd4, 0x7f, 0xb4, 0xd3, 0xad, 0xcf, 0xae, 0x4b, + 0xcd, 0x57, 0x3d, 0x41, 0x06, 0xa7, 0x29, 0xdb, 0x3f, 0x65, 0xc1, 0x71, 0x1d, 0x51, 0x73, 0x87, + 0xeb, 0xa4, 0xcb, 0x5b, 0x80, 0x01, 0xbf, 0x49, 0x02, 0x27, 0xf2, 0x03, 0x71, 0xcd, 0x9d, 0x93, + 0x2b, 0xf4, 0x9a, 0x28, 0xdf, 0x17, 0xc9, 0x6b, 0x24, 0x75, 0x59, 0x8e, 0x55, 0x4d, 0x64, 0x43, + 0x1f, 0x13, 0x20, 0x86, 0xc2, 0xf1, 0x91, 0x1d, 0x5a, 0xcc, 0x3e, 0x25, 0xc4, 0x02, 0x62, 0xff, + 0xb9, 0xc5, 0xd7, 0xa7, 0xde, 0x75, 0xf4, 0x36, 0x8c, 0x37, 0x9c, 0xa8, 0xba, 0xb9, 0x78, 0xa7, + 0x19, 0x70, 0x15, 0xad, 0x1c, 0xa7, 0xa7, 0x3a, 0x8d, 0x93, 0xf6, 0x91, 0xb1, 0x81, 0xf4, 0x4a, + 0x82, 0x18, 0x4e, 0x91, 0x47, 0xb7, 0x60, 0x88, 0x95, 0x31, 0x9f, 0xde, 0xb0, 0x1d, 0x2f, 0x93, + 0xd7, 0x9a, 0x32, 0xf1, 0x59, 0x89, 0xe9, 0x60, 0x9d, 0xa8, 0xfd, 0xe5, 0x22, 0x3f, 0x34, 0xd8, + 0xdb, 0xe3, 0x09, 0xe8, 0x6f, 0xfa, 0xb5, 0xf9, 0xe5, 0x05, 0x2c, 0x66, 0x41, 0xdd, 0x7b, 0x65, + 0x5e, 0x8c, 0x25, 0x1c, 0x9d, 0x83, 0x01, 0xf1, 0x53, 0xaa, 0xd4, 0xd9, 0x1e, 0x11, 0x78, 0x21, + 0x56, 0x50, 0xf4, 0x2c, 0x40, 0x33, 0xf0, 0xb7, 0xdd, 0x1a, 0x8b, 0xc4, 0x54, 0x34, 0xad, 0xf3, + 0xca, 0x0a, 0x82, 0x35, 0x2c, 0xf4, 0x32, 0x8c, 0xb4, 0xbc, 0x90, 0xf3, 0x4f, 0x5a, 0xbc, 0x7b, + 0x65, 0x37, 0x76, 0x5d, 0x07, 0x62, 0x13, 0x17, 0xcd, 0x42, 0x5f, 0xe4, 0x30, 0x6b, 0xb3, 0xde, + 0x7c, 0x23, 0xfa, 0x35, 0x8a, 0xa1, 0x67, 0x96, 0xa3, 0x15, 0xb0, 0xa8, 0x88, 0xde, 0x94, 0xee, + 0xf5, 0xfc, 0x26, 0x12, 0xde, 0x2b, 0xdd, 0xdd, 0x5a, 0x9a, 0x73, 0xbd, 0xf0, 0x8a, 0x31, 0x68, + 0xa1, 0x97, 0x00, 0xc8, 0x9d, 0x88, 0x04, 0x9e, 0x53, 0x57, 0x36, 0xa2, 0x8a, 0x91, 0x59, 0xf0, + 0x57, 0xfd, 0xe8, 0x7a, 0x48, 0x16, 0x15, 0x06, 0xd6, 0xb0, 0xed, 0xef, 0x1f, 0x02, 0x88, 0x1f, + 0x1a, 0xe8, 0x2e, 0x0c, 0x54, 0x9d, 0xa6, 0x53, 0xe5, 0x69, 0x53, 0x8b, 0x79, 0x5e, 0xcf, 0x71, + 0x8d, 0x99, 0x79, 0x81, 0xce, 0x95, 0x37, 0x32, 0x64, 0xf8, 0x80, 0x2c, 0xee, 0xa8, 0xb0, 0x51, + 0xed, 0xa1, 0xcf, 0x59, 0x30, 0x24, 0x22, 0x1d, 0xb1, 0x19, 0x2a, 0xe4, 0xeb, 0xdb, 0xb4, 0xf6, + 0x67, 0xe3, 0x1a, 0xbc, 0x0b, 0xcf, 0xc9, 0x15, 0xaa, 0x41, 0x3a, 0xf6, 0x42, 0x6f, 0x18, 0x7d, + 0x50, 0xbe, 0x6d, 0x8b, 0xc6, 0x50, 0xaa, 0xb7, 0xed, 0x20, 0xbb, 0x6a, 0xf4, 0x67, 0xed, 0x75, + 0xe3, 0x59, 0xdb, 0x93, 0xef, 0x3f, 0x6c, 0xf0, 0xdb, 0x9d, 0x5e, 0xb4, 0xa8, 0xac, 0xc7, 0x12, + 0xe9, 0xcd, 0x77, 0x7a, 0xd5, 0x1e, 0x76, 0x1d, 0xe2, 0x88, 0x7c, 0x1a, 0xc6, 0x6a, 0x26, 0xd7, + 0x22, 0x56, 0xe2, 0xe3, 0x79, 0x74, 0x13, 0x4c, 0x4e, 0xcc, 0xa7, 0x24, 0x00, 0x38, 0x49, 0x18, + 0x95, 0x79, 0x68, 0x99, 0x65, 0x6f, 0xdd, 0x17, 0x1e, 0x54, 0x76, 0xee, 0x5c, 0xee, 0x84, 0x11, + 0x69, 0x50, 0xcc, 0x98, 0x49, 0x58, 0x15, 0x75, 0xb1, 0xa2, 0x82, 0x5e, 0x87, 0x3e, 0xe6, 0xf5, + 0x18, 0x4e, 0x0d, 0xe4, 0xab, 0x35, 0xcc, 0x48, 0xa8, 0xf1, 0x86, 0x64, 0x7f, 0x43, 0x2c, 0x28, + 0xa0, 0xcb, 0xd2, 0xa7, 0x38, 0x5c, 0xf6, 0xae, 0x87, 0x84, 0xf9, 0x14, 0x0f, 0xce, 0x3d, 0x1a, + 0xbb, 0x0b, 0xf3, 0xf2, 0xcc, 0xfc, 0xb3, 0x46, 0x4d, 0xca, 0xf6, 0x89, 0xff, 0x32, 0xad, 0xad, + 0x88, 0xdb, 0x96, 0xd9, 0x3d, 0x33, 0xf5, 0x6d, 0x3c, 0x9c, 0x37, 0x4c, 0x12, 0x38, 0x49, 0x93, + 0xb2, 0xd0, 0x7c, 0xd7, 0x0b, 0x1f, 0xac, 0x4e, 0x67, 0x07, 0x97, 0x1c, 0xb0, 0xdb, 0x88, 0x97, + 0x60, 0x51, 0x1f, 0xb9, 0x30, 0x16, 0x18, 0xec, 0x85, 0x0c, 0xb7, 0x76, 0xb6, 0x3b, 0x26, 0x46, + 0x0b, 0xe4, 0x6f, 0x92, 0xc1, 0x49, 0xba, 0xe8, 0x75, 0x8d, 0x51, 0x1a, 0x69, 0xff, 0xf2, 0xef, + 0xc4, 0x1a, 0x4d, 0x6f, 0xc1, 0x88, 0x71, 0xd8, 0x3c, 0x50, 0x15, 0xa4, 0x07, 0xe3, 0xc9, 0x93, + 0xe5, 0x81, 0x6a, 0x1e, 0xff, 0xb4, 0x07, 0x46, 0xcd, 0x9d, 0x80, 0xce, 0xc3, 0xa0, 0x20, 0xa2, + 0x32, 0x5a, 0xa9, 0xcd, 0xbd, 0x22, 0x01, 0x38, 0xc6, 0x61, 0x89, 0xcc, 0x58, 0x75, 0xcd, 0x57, + 0x20, 0x4e, 0x64, 0xa6, 0x20, 0x58, 0xc3, 0xa2, 0x0f, 0xd8, 0x5b, 0xbe, 0x1f, 0xa9, 0x7b, 0x54, + 0x6d, 0x97, 0x39, 0x56, 0x8a, 0x05, 0x94, 0xde, 0x9f, 0x5b, 0x24, 0xf0, 0x48, 0xdd, 0x4c, 0xe9, + 0xa0, 0xee, 0xcf, 0x2b, 0x3a, 0x10, 0x9b, 0xb8, 0x94, 0x0b, 0xf0, 0x43, 0xb6, 0xff, 0xc4, 0x33, + 0x39, 0xf6, 0xbd, 0xa8, 0xf0, 0x28, 0x12, 0x12, 0x8e, 0x3e, 0x06, 0xc7, 0x55, 0xf8, 0x44, 0xb1, + 0xba, 0x64, 0x8b, 0x7d, 0x86, 0x54, 0xeb, 0xf8, 0x7c, 0x36, 0x1a, 0xce, 0xab, 0x8f, 0x5e, 0x85, + 0x51, 0xf1, 0x94, 0x92, 0x14, 0xfb, 0x4d, 0x43, 0xc2, 0x2b, 0x06, 0x14, 0x27, 0xb0, 0x65, 0x52, + 0x0a, 0xf6, 0xc6, 0x90, 0x14, 0x06, 0xd2, 0x49, 0x29, 0x74, 0x38, 0x4e, 0xd5, 0x40, 0xb3, 0x30, + 0xc6, 0x59, 0x47, 0xd7, 0xdb, 0xe0, 0x73, 0x22, 0x3c, 0x3b, 0xd5, 0xa6, 0xba, 0x66, 0x82, 0x71, + 0x12, 0x1f, 0x5d, 0x84, 0x61, 0x27, 0xa8, 0x6e, 0xba, 0x11, 0xa9, 0xd2, 0x9d, 0xc1, 0x6c, 0xf9, + 0x34, 0x4b, 0xcc, 0x59, 0x0d, 0x86, 0x0d, 0x4c, 0xfb, 0x2e, 0x4c, 0x66, 0x84, 0x97, 0xa1, 0x0b, + 0xc7, 0x69, 0xba, 0xf2, 0x9b, 0x12, 0xee, 0x0e, 0xb3, 0xe5, 0x65, 0xf9, 0x35, 0x1a, 0x16, 0x5d, + 0x9d, 0x2c, 0x0c, 0x8d, 0x96, 0x7c, 0x5b, 0xad, 0xce, 0x25, 0x09, 0xc0, 0x31, 0x8e, 0xfd, 0xd7, + 0x05, 0x18, 0xcb, 0x50, 0xd0, 0xb1, 0x04, 0xd0, 0x89, 0x97, 0x56, 0x9c, 0xef, 0xd9, 0xcc, 0x71, + 0x52, 0x38, 0x40, 0x8e, 0x93, 0x62, 0xa7, 0x1c, 0x27, 0x3d, 0xef, 0x24, 0xc7, 0x89, 0x39, 0x62, + 0xbd, 0x5d, 0x8d, 0x58, 0x46, 0x5e, 0x94, 0xbe, 0x03, 0xe6, 0x45, 0x31, 0x06, 0xbd, 0xbf, 0x8b, + 0x41, 0xff, 0xd1, 0x02, 0x8c, 0x27, 0x75, 0x7b, 0x87, 0x20, 0x1f, 0x7f, 0xdd, 0x90, 0x8f, 0x9f, + 0xeb, 0xc6, 0x13, 0x3f, 0x57, 0x56, 0x8e, 0x13, 0xb2, 0xf2, 0x27, 0xbb, 0xa2, 0xd6, 0x5e, 0x6e, + 0xfe, 0x0f, 0x0b, 0x70, 0x34, 0x53, 0xe5, 0x79, 0x08, 0x63, 0x73, 0xcd, 0x18, 0x9b, 0x67, 0xba, + 0x8e, 0x52, 0x90, 0x3b, 0x40, 0x37, 0x13, 0x03, 0x74, 0xbe, 0x7b, 0x92, 0xed, 0x47, 0xe9, 0x1b, + 0x45, 0x38, 0x9d, 0x59, 0x2f, 0x16, 0x2f, 0x2f, 0x19, 0xe2, 0xe5, 0x67, 0x13, 0xe2, 0x65, 0xbb, + 0x7d, 0xed, 0xfb, 0x23, 0x6f, 0x16, 0xde, 0xfa, 0x2c, 0xe6, 0xc8, 0x3d, 0xca, 0x9a, 0x0d, 0x6f, + 0x7d, 0x45, 0x08, 0x9b, 0x74, 0xdf, 0x4b, 0x32, 0xe6, 0xdf, 0xb3, 0xe0, 0x44, 0xe6, 0xdc, 0x1c, + 0x82, 0xa4, 0x6f, 0xd5, 0x94, 0xf4, 0x3d, 0xd1, 0xf5, 0x6a, 0xcd, 0x11, 0xfd, 0x7d, 0xbe, 0x2f, + 0xe7, 0x5b, 0x98, 0x00, 0xe2, 0x1a, 0x0c, 0x39, 0xd5, 0x2a, 0x09, 0xc3, 0x15, 0xbf, 0xa6, 0xd2, + 0x21, 0x3c, 0xc3, 0x9e, 0x87, 0x71, 0xf1, 0xfe, 0x6e, 0x69, 0x3a, 0x49, 0x22, 0x06, 0x63, 0x9d, + 0x02, 0xfa, 0x04, 0x0c, 0x84, 0x32, 0x93, 0x65, 0xcf, 0xbd, 0x67, 0xb2, 0x64, 0x4c, 0xae, 0x12, + 0xb0, 0x28, 0x92, 0xe8, 0x3b, 0xf5, 0xe8, 0x4f, 0x6d, 0x44, 0x8b, 0xbc, 0x93, 0xf7, 0x10, 0x03, + 0xea, 0x59, 0x80, 0x6d, 0xf5, 0x92, 0x49, 0x0a, 0x4f, 0xb4, 0x37, 0x8e, 0x86, 0x85, 0x5e, 0x83, + 0xf1, 0x90, 0x07, 0x3e, 0x8d, 0x8d, 0x54, 0xf8, 0x5a, 0x64, 0xb1, 0xe3, 0x2a, 0x09, 0x18, 0x4e, + 0x61, 0xa3, 0x25, 0xd9, 0x2a, 0x33, 0x47, 0xe2, 0xcb, 0xf3, 0x6c, 0xdc, 0xa2, 0x30, 0x49, 0x3a, + 0x92, 0x9c, 0x04, 0x36, 0xfc, 0x5a, 0x4d, 0xf4, 0x09, 0x00, 0xba, 0x88, 0x84, 0x10, 0xa5, 0x3f, + 0xff, 0x08, 0xa5, 0x67, 0x4b, 0x2d, 0xd3, 0x93, 0x81, 0xb9, 0xd9, 0x2f, 0x28, 0x22, 0x58, 0x23, + 0x88, 0x1c, 0x18, 0x89, 0xff, 0xc5, 0x39, 0xda, 0xcf, 0xe5, 0xb6, 0x90, 0x24, 0xce, 0x14, 0x0c, + 0x0b, 0x3a, 0x09, 0x6c, 0x52, 0x44, 0x1f, 0x87, 0x13, 0xdb, 0xb9, 0x96, 0x3f, 0x9c, 0x13, 0x64, + 0x49, 0xd7, 0xf3, 0xed, 0x7d, 0xf2, 0xeb, 0xdb, 0xff, 0x0e, 0xe0, 0xa1, 0x36, 0x27, 0x3d, 0x9a, + 0x35, 0xb5, 0xf6, 0x4f, 0x25, 0x25, 0x1b, 0xd3, 0x99, 0x95, 0x0d, 0x51, 0x47, 0x62, 0x43, 0x15, + 0xde, 0xf1, 0x86, 0xfa, 0x21, 0x4b, 0x93, 0x39, 0x71, 0x9b, 0xee, 0x8f, 0x1c, 0xf0, 0x06, 0xbb, + 0x8f, 0x42, 0xa8, 0xf5, 0x0c, 0x49, 0xce, 0xb3, 0x5d, 0x77, 0xa7, 0x7b, 0xd1, 0xce, 0x57, 0xb3, + 0x03, 0xbe, 0x73, 0x21, 0xcf, 0xa5, 0x83, 0x7e, 0xff, 0x61, 0x05, 0x7f, 0xff, 0xba, 0x05, 0x27, + 0x52, 0xc5, 0xbc, 0x0f, 0x24, 0x14, 0xd1, 0xee, 0x56, 0xdf, 0x71, 0xe7, 0x25, 0x41, 0xfe, 0x0d, + 0x97, 0xc5, 0x37, 0x9c, 0xc8, 0xc5, 0x4b, 0x76, 0xfd, 0x0b, 0x7f, 0x52, 0x9a, 0x64, 0x0d, 0x98, + 0x88, 0x38, 0xbf, 0xeb, 0xa8, 0x09, 0x67, 0xaa, 0xad, 0x20, 0x88, 0x17, 0x6b, 0xc6, 0xe6, 0xe4, + 0x6f, 0xbd, 0x47, 0xf7, 0x76, 0x4b, 0x67, 0xe6, 0x3b, 0xe0, 0xe2, 0x8e, 0xd4, 0x90, 0x07, 0xa8, + 0x91, 0xb2, 0xaf, 0x63, 0x07, 0x40, 0x8e, 0x1c, 0x26, 0x6d, 0x8d, 0xc7, 0x2d, 0x65, 0x33, 0xac, + 0xf4, 0x32, 0x28, 0x1f, 0xae, 0xf4, 0xe4, 0x5b, 0x13, 0x97, 0x7e, 0xfa, 0x2a, 0x9c, 0x6e, 0xbf, + 0x98, 0x0e, 0x14, 0xca, 0xe1, 0x0f, 0x2d, 0x38, 0xd5, 0x36, 0x5e, 0xd8, 0xb7, 0xe1, 0x63, 0xc1, + 0xfe, 0xac, 0x05, 0x0f, 0x67, 0xd6, 0x48, 0x3a, 0xe1, 0x55, 0x69, 0xa1, 0x66, 0x8e, 0x1a, 0x47, + 0xce, 0x91, 0x00, 0x1c, 0xe3, 0x18, 0x16, 0x9b, 0x85, 0x8e, 0x16, 0x9b, 0xbf, 0x6d, 0x41, 0xea, + 0xaa, 0x3f, 0x04, 0xce, 0x73, 0xd9, 0xe4, 0x3c, 0x1f, 0xed, 0x66, 0x34, 0x73, 0x98, 0xce, 0xbf, + 0x1c, 0x83, 0x63, 0x39, 0x9e, 0xd8, 0xdb, 0x30, 0xb1, 0x51, 0x25, 0x66, 0xe8, 0x8d, 0x76, 0x21, + 0xe9, 0xda, 0xc6, 0xe9, 0x98, 0x3b, 0xba, 0xb7, 0x5b, 0x9a, 0x48, 0xa1, 0xe0, 0x74, 0x13, 0xe8, + 0xb3, 0x16, 0x1c, 0x71, 0x6e, 0x87, 0x8b, 0xf4, 0x05, 0xe1, 0x56, 0xe7, 0xea, 0x7e, 0x75, 0x8b, + 0x32, 0x66, 0x72, 0x5b, 0x3d, 0x9f, 0x29, 0x8c, 0xbe, 0x59, 0x49, 0xe1, 0x1b, 0xcd, 0x4f, 0xed, + 0xed, 0x96, 0x8e, 0x64, 0x61, 0xe1, 0xcc, 0xb6, 0x10, 0x16, 0x19, 0xbf, 0x9c, 0x68, 0xb3, 0x5d, + 0x70, 0x98, 0x2c, 0x97, 0x79, 0xce, 0x12, 0x4b, 0x08, 0x56, 0x74, 0xd0, 0xa7, 0x60, 0x70, 0x43, + 0xc6, 0x81, 0xc8, 0x60, 0xb9, 0xe3, 0x81, 0x6c, 0x1f, 0x1d, 0x83, 0x9b, 0xc0, 0x28, 0x24, 0x1c, + 0x13, 0x45, 0xaf, 0x42, 0xd1, 0x5b, 0x0f, 0x45, 0x88, 0xba, 0x6c, 0x4b, 0x5c, 0xd3, 0xd6, 0x99, + 0x87, 0x60, 0x5a, 0x5d, 0xaa, 0x60, 0x5a, 0x11, 0x5d, 0x86, 0x62, 0x70, 0xab, 0x26, 0x34, 0x29, + 0x99, 0x9b, 0x14, 0xcf, 0x2d, 0xe4, 0xf4, 0x8a, 0x51, 0xc2, 0x73, 0x0b, 0x98, 0x92, 0x40, 0x65, + 0xe8, 0x65, 0xee, 0xcb, 0x82, 0xb5, 0xcd, 0x7c, 0xca, 0xb7, 0x09, 0x03, 0xc0, 0x3d, 0x12, 0x19, + 0x02, 0xe6, 0x84, 0xd0, 0x1a, 0xf4, 0x55, 0x5d, 0xaf, 0x46, 0x02, 0xc1, 0xcb, 0x7e, 0x30, 0x53, + 0x67, 0xc2, 0x30, 0x72, 0x68, 0x72, 0x15, 0x02, 0xc3, 0xc0, 0x82, 0x16, 0xa3, 0x4a, 0x9a, 0x9b, + 0xeb, 0xf2, 0xc6, 0xca, 0xa6, 0x4a, 0x9a, 0x9b, 0x4b, 0x95, 0xb6, 0x54, 0x19, 0x06, 0x16, 0xb4, + 0xd0, 0x4b, 0x50, 0x58, 0xaf, 0x0a, 0xd7, 0xe4, 0x4c, 0xe5, 0x89, 0x19, 0x45, 0x6b, 0xae, 0x6f, + 0x6f, 0xb7, 0x54, 0x58, 0x9a, 0xc7, 0x85, 0xf5, 0x2a, 0x5a, 0x85, 0xfe, 0x75, 0x1e, 0x77, 0x47, + 0xe8, 0x47, 0x1e, 0xcf, 0x0e, 0x09, 0x94, 0x0a, 0xcd, 0xc3, 0xbd, 0x4b, 0x05, 0x00, 0x4b, 0x22, + 0x2c, 0x01, 0x95, 0x8a, 0x1f, 0x24, 0xc2, 0x97, 0xce, 0x1c, 0x2c, 0xe6, 0x13, 0x7f, 0x6a, 0xc4, + 0x51, 0x88, 0xb0, 0x46, 0x91, 0xae, 0x6a, 0xe7, 0x6e, 0x2b, 0x60, 0xb9, 0x2d, 0x84, 0x6a, 0x24, + 0x73, 0x55, 0xcf, 0x4a, 0xa4, 0x76, 0xab, 0x5a, 0x21, 0xe1, 0x98, 0x28, 0xda, 0x82, 0x91, 0xed, + 0xb0, 0xb9, 0x49, 0xe4, 0x96, 0x66, 0x61, 0xef, 0x72, 0xb8, 0xd9, 0x1b, 0x02, 0xd1, 0x0d, 0xa2, + 0x96, 0x53, 0x4f, 0x9d, 0x42, 0xec, 0x59, 0x73, 0x43, 0x27, 0x86, 0x4d, 0xda, 0x74, 0xf8, 0xdf, + 0x6e, 0xf9, 0xb7, 0x76, 0x22, 0x22, 0xa2, 0x8e, 0x66, 0x0e, 0xff, 0x1b, 0x1c, 0x25, 0x3d, 0xfc, + 0x02, 0x80, 0x25, 0x11, 0x74, 0x43, 0x0c, 0x0f, 0x3b, 0x3d, 0xc7, 0xf3, 0x43, 0x9a, 0xcf, 0x4a, + 0xa4, 0x9c, 0x41, 0x61, 0xa7, 0x65, 0x4c, 0x8a, 0x9d, 0x92, 0xcd, 0x4d, 0x3f, 0xf2, 0xbd, 0xc4, + 0x09, 0x3d, 0x91, 0x7f, 0x4a, 0x96, 0x33, 0xf0, 0xd3, 0xa7, 0x64, 0x16, 0x16, 0xce, 0x6c, 0x0b, + 0xd5, 0x60, 0xb4, 0xe9, 0x07, 0xd1, 0x6d, 0x3f, 0x90, 0xeb, 0x0b, 0xb5, 0x11, 0x94, 0x1a, 0x98, + 0xa2, 0x45, 0x66, 0x98, 0x63, 0x42, 0x70, 0x82, 0x26, 0xfa, 0x28, 0xf4, 0x87, 0x55, 0xa7, 0x4e, + 0x96, 0xaf, 0x4d, 0x4d, 0xe6, 0x5f, 0x3f, 0x15, 0x8e, 0x92, 0xb3, 0xba, 0x78, 0xd8, 0x24, 0x8e, + 0x82, 0x25, 0x39, 0xb4, 0x04, 0xbd, 0x2c, 0xb1, 0x33, 0x0b, 0x91, 0x9b, 0x13, 0x99, 0x3d, 0xe5, + 0x56, 0xc3, 0xcf, 0x26, 0x56, 0x8c, 0x79, 0x75, 0xba, 0x07, 0x84, 0xa4, 0xc0, 0x0f, 0xa7, 0x8e, + 0xe6, 0xef, 0x01, 0x21, 0x60, 0xb8, 0x56, 0x69, 0xb7, 0x07, 0x14, 0x12, 0x8e, 0x89, 0xd2, 0x93, + 0x99, 0x9e, 0xa6, 0xc7, 0xda, 0x98, 0x4c, 0xe6, 0x9e, 0xa5, 0xec, 0x64, 0xa6, 0x27, 0x29, 0x25, + 0x61, 0xff, 0xe6, 0x40, 0x9a, 0x67, 0x61, 0x12, 0xa6, 0xff, 0xdf, 0x4a, 0xd9, 0x4c, 0x7c, 0xa8, + 0x5b, 0x81, 0xf7, 0x7d, 0x7c, 0xb8, 0x7e, 0xd6, 0x82, 0x63, 0xcd, 0xcc, 0x0f, 0x11, 0x0c, 0x40, + 0x77, 0x72, 0x73, 0xfe, 0xe9, 0x2a, 0x9c, 0x72, 0x36, 0x1c, 0xe7, 0xb4, 0x94, 0x14, 0x0e, 0x14, + 0xdf, 0xb1, 0x70, 0x60, 0x05, 0x06, 0xaa, 0xfc, 0x25, 0x27, 0xd3, 0x00, 0x74, 0x15, 0x0c, 0x94, + 0xb1, 0x12, 0xe2, 0x09, 0xb8, 0x8e, 0x15, 0x09, 0xf4, 0xc3, 0x16, 0x9c, 0x4a, 0x76, 0x1d, 0x13, + 0x06, 0x16, 0x06, 0x93, 0x5c, 0xac, 0xb5, 0x24, 0xbe, 0x3f, 0xc5, 0xff, 0x1b, 0xc8, 0xfb, 0x9d, + 0x10, 0x70, 0xfb, 0xc6, 0xd0, 0x42, 0x86, 0x5c, 0xad, 0xcf, 0xd4, 0x28, 0x76, 0x21, 0x5b, 0x7b, + 0x1e, 0x86, 0x1b, 0x7e, 0xcb, 0x8b, 0x84, 0xdd, 0xa3, 0x30, 0x9e, 0x62, 0x46, 0x43, 0x2b, 0x5a, + 0x39, 0x36, 0xb0, 0x12, 0x12, 0xb9, 0x81, 0x7b, 0x96, 0xc8, 0xbd, 0x05, 0xc3, 0x9e, 0xe6, 0x12, + 0xd0, 0xee, 0x05, 0x2b, 0xa4, 0x8b, 0x1a, 0x36, 0xef, 0xa5, 0x5e, 0x82, 0x0d, 0x6a, 0xed, 0xa5, + 0x65, 0xf0, 0xce, 0xa4, 0x65, 0x87, 0xfa, 0x24, 0xb6, 0x7f, 0xa1, 0x90, 0xf1, 0x62, 0xe0, 0x52, + 0xb9, 0x57, 0x4c, 0xa9, 0xdc, 0xd9, 0xa4, 0x54, 0x2e, 0xa5, 0xaa, 0x32, 0x04, 0x72, 0xdd, 0x67, + 0x94, 0xec, 0x3a, 0xc0, 0xf3, 0xf7, 0x5a, 0x70, 0x9c, 0xe9, 0x3e, 0x68, 0x03, 0xef, 0x58, 0xdf, + 0xc1, 0x4c, 0x52, 0xaf, 0x66, 0x93, 0xc3, 0x79, 0xed, 0xd8, 0x75, 0x38, 0xd3, 0xe9, 0xde, 0x65, + 0x16, 0xbe, 0x35, 0x65, 0x1c, 0x11, 0x5b, 0xf8, 0xd6, 0x96, 0x17, 0x30, 0x83, 0x74, 0x1b, 0xbe, + 0xd0, 0xfe, 0xef, 0x16, 0x14, 0xcb, 0x7e, 0xed, 0x10, 0x5e, 0xf4, 0x1f, 0x31, 0x5e, 0xf4, 0x0f, + 0x65, 0xdf, 0xf8, 0xb5, 0x5c, 0x65, 0xdf, 0x62, 0x42, 0xd9, 0x77, 0x2a, 0x8f, 0x40, 0x7b, 0xd5, + 0xde, 0x4f, 0x17, 0x61, 0xa8, 0xec, 0xd7, 0xd4, 0x3e, 0xfb, 0xd7, 0xf7, 0xe2, 0xc8, 0x93, 0x9b, + 0x7d, 0x4a, 0xa3, 0xcc, 0x2c, 0x7a, 0x65, 0xdc, 0x89, 0x6f, 0x33, 0x7f, 0x9e, 0x9b, 0xc4, 0xdd, + 0xd8, 0x8c, 0x48, 0x2d, 0xf9, 0x39, 0x87, 0xe7, 0xcf, 0xf3, 0xcd, 0x22, 0x8c, 0x25, 0x5a, 0x47, + 0x75, 0x18, 0xa9, 0xeb, 0xaa, 0x24, 0xb1, 0x4e, 0xef, 0x49, 0x0b, 0x25, 0xfc, 0x21, 0xb4, 0x22, + 0x6c, 0x12, 0x47, 0x33, 0x00, 0x9e, 0x6e, 0x15, 0xae, 0x02, 0x15, 0x6b, 0x16, 0xe1, 0x1a, 0x06, + 0x7a, 0x01, 0x86, 0x22, 0xbf, 0xe9, 0xd7, 0xfd, 0x8d, 0x9d, 0x2b, 0x44, 0x46, 0xb6, 0x54, 0x46, + 0xc3, 0x6b, 0x31, 0x08, 0xeb, 0x78, 0xe8, 0x0e, 0x4c, 0x28, 0x22, 0x95, 0xfb, 0xa0, 0x5e, 0x63, + 0x62, 0x93, 0xd5, 0x24, 0x45, 0x9c, 0x6e, 0x04, 0xbd, 0x04, 0xa3, 0xcc, 0x7a, 0x99, 0xd5, 0xbf, + 0x42, 0x76, 0x64, 0xc4, 0x63, 0xc6, 0x61, 0xaf, 0x18, 0x10, 0x9c, 0xc0, 0x44, 0xf3, 0x30, 0xd1, + 0x70, 0xc3, 0x44, 0xf5, 0x3e, 0x56, 0x9d, 0x75, 0x60, 0x25, 0x09, 0xc4, 0x69, 0x7c, 0xfb, 0xe7, + 0xc4, 0x1c, 0x7b, 0x91, 0xfb, 0xfe, 0x76, 0x7c, 0x77, 0x6f, 0xc7, 0x6f, 0x58, 0x30, 0x4e, 0x5b, + 0x67, 0x26, 0x99, 0x92, 0x91, 0x52, 0x39, 0x31, 0xac, 0x36, 0x39, 0x31, 0xce, 0xd2, 0x63, 0xbb, + 0xe6, 0xb7, 0x22, 0x21, 0x1d, 0xd5, 0xce, 0x65, 0x5a, 0x8a, 0x05, 0x54, 0xe0, 0x91, 0x20, 0x10, + 0x7e, 0xef, 0x3a, 0x1e, 0x09, 0x02, 0x2c, 0xa0, 0x32, 0x65, 0x46, 0x4f, 0x76, 0xca, 0x0c, 0x1e, + 0xf9, 0x5c, 0x58, 0xc1, 0x09, 0x96, 0x56, 0x8b, 0x7c, 0x2e, 0xcd, 0xe3, 0x62, 0x1c, 0xfb, 0xab, + 0x45, 0x18, 0x2e, 0xfb, 0xb5, 0xd8, 0xb0, 0xe3, 0x79, 0xc3, 0xb0, 0xe3, 0x4c, 0xc2, 0xb0, 0x63, + 0x5c, 0xc7, 0x7d, 0xdf, 0x8c, 0xe3, 0x5b, 0x65, 0xc6, 0xf1, 0x5b, 0x16, 0x9b, 0xb5, 0x85, 0xd5, + 0x0a, 0xb7, 0xf0, 0x45, 0x17, 0x60, 0x88, 0x9d, 0x70, 0x2c, 0xd0, 0x82, 0xb4, 0x76, 0x60, 0x29, + 0x2c, 0x57, 0xe3, 0x62, 0xac, 0xe3, 0xa0, 0x73, 0x30, 0x10, 0x12, 0x27, 0xa8, 0x6e, 0xaa, 0xe3, + 0x5d, 0x98, 0x26, 0xf0, 0x32, 0xac, 0xa0, 0xe8, 0x8d, 0x38, 0xe8, 0x76, 0x31, 0xdf, 0x5c, 0x58, + 0xef, 0x0f, 0xdf, 0x22, 0xf9, 0x91, 0xb6, 0xed, 0x9b, 0x80, 0xd2, 0xf8, 0x5d, 0xf8, 0x5f, 0x95, + 0xcc, 0xb0, 0xb0, 0x83, 0xa9, 0x90, 0xb0, 0x7f, 0x63, 0xc1, 0x68, 0xd9, 0xaf, 0xd1, 0xad, 0xfb, + 0x5e, 0xda, 0xa7, 0x7a, 0xc6, 0x81, 0xbe, 0x36, 0x19, 0x07, 0x1e, 0x81, 0xde, 0xb2, 0x5f, 0xeb, + 0x10, 0xba, 0xf6, 0x1f, 0x59, 0xd0, 0x5f, 0xf6, 0x6b, 0x87, 0xa0, 0x78, 0x79, 0xc5, 0x54, 0xbc, + 0x1c, 0xcf, 0x59, 0x37, 0x39, 0xba, 0x96, 0x7f, 0xd0, 0x03, 0x23, 0xb4, 0x9f, 0xfe, 0x86, 0x9c, + 0x4a, 0x63, 0xd8, 0xac, 0x2e, 0x86, 0x8d, 0x3e, 0x03, 0xfc, 0x7a, 0xdd, 0xbf, 0x9d, 0x9c, 0xd6, + 0x25, 0x56, 0x8a, 0x05, 0x14, 0x3d, 0x0d, 0x03, 0xcd, 0x80, 0x6c, 0xbb, 0xbe, 0xe0, 0xaf, 0x35, + 0x35, 0x56, 0x59, 0x94, 0x63, 0x85, 0x41, 0x1f, 0xde, 0xa1, 0xeb, 0x51, 0x5e, 0xa2, 0xea, 0x7b, + 0x35, 0xae, 0x9b, 0x28, 0x8a, 0xb4, 0x58, 0x5a, 0x39, 0x36, 0xb0, 0xd0, 0x4d, 0x18, 0x64, 0xff, + 0xd9, 0xb1, 0xd3, 0x7b, 0xe0, 0x63, 0x47, 0x24, 0x0a, 0x16, 0x04, 0x70, 0x4c, 0x0b, 0x3d, 0x0b, + 0x10, 0xc9, 0xd4, 0x32, 0xa1, 0x08, 0x61, 0xaa, 0xde, 0x22, 0x2a, 0xe9, 0x4c, 0x88, 0x35, 0x2c, + 0xf4, 0x14, 0x0c, 0x46, 0x8e, 0x5b, 0xbf, 0xea, 0x7a, 0x4c, 0x7f, 0x4f, 0xfb, 0x2f, 0xf2, 0xf5, + 0x8a, 0x42, 0x1c, 0xc3, 0x29, 0x2f, 0xc8, 0x62, 0x42, 0xcd, 0xed, 0x44, 0x22, 0x35, 0x5d, 0x91, + 0xf3, 0x82, 0x57, 0x55, 0x29, 0xd6, 0x30, 0xd0, 0x26, 0x9c, 0x74, 0x3d, 0x96, 0x42, 0x8a, 0x54, + 0xb6, 0xdc, 0xe6, 0xda, 0xd5, 0xca, 0x0d, 0x12, 0xb8, 0xeb, 0x3b, 0x73, 0x4e, 0x75, 0x8b, 0x78, + 0x32, 0x21, 0xfe, 0xa3, 0xa2, 0x8b, 0x27, 0x97, 0xdb, 0xe0, 0xe2, 0xb6, 0x94, 0xec, 0xe7, 0xd8, + 0x7a, 0xbf, 0x56, 0x41, 0x4f, 0x1a, 0x47, 0xc7, 0x31, 0xfd, 0xe8, 0xd8, 0xdf, 0x2d, 0xf5, 0x5d, + 0xab, 0x68, 0xb1, 0x7f, 0x2e, 0xc2, 0xd1, 0xb2, 0x5f, 0x2b, 0xfb, 0x41, 0xb4, 0xe4, 0x07, 0xb7, + 0x9d, 0xa0, 0x26, 0x97, 0x57, 0x49, 0x46, 0x3f, 0xa2, 0xe7, 0x67, 0x2f, 0x3f, 0x5d, 0x8c, 0xc8, + 0x46, 0xcf, 0x31, 0x8e, 0xed, 0x80, 0xce, 0xa6, 0x55, 0xc6, 0x3b, 0xa8, 0x24, 0x6c, 0x97, 0x9c, + 0x88, 0xa0, 0x6b, 0x30, 0x52, 0xd5, 0xaf, 0x51, 0x51, 0xfd, 0x09, 0x79, 0x91, 0x19, 0x77, 0x6c, + 0xe6, 0xbd, 0x6b, 0xd6, 0xb7, 0xbf, 0x6e, 0x89, 0x56, 0xb8, 0x24, 0x82, 0xdb, 0xb4, 0x76, 0x3e, + 0x4f, 0xe7, 0x61, 0x22, 0xd0, 0xab, 0x68, 0xb6, 0x61, 0x47, 0x79, 0x56, 0x9b, 0x04, 0x10, 0xa7, + 0xf1, 0xd1, 0xc7, 0xe1, 0x84, 0x51, 0x28, 0xd5, 0xe4, 0x5a, 0x6e, 0x69, 0x26, 0xab, 0xc1, 0x79, + 0x48, 0x38, 0xbf, 0xbe, 0xfd, 0xdd, 0x70, 0x2c, 0xf9, 0x5d, 0x42, 0x7a, 0x72, 0x8f, 0x5f, 0x57, + 0x38, 0xd8, 0xd7, 0xd9, 0x2f, 0xc0, 0x04, 0x7d, 0x56, 0x2b, 0x16, 0x91, 0xcd, 0x5f, 0xe7, 0x00, + 0x53, 0xbf, 0x34, 0xc0, 0xae, 0xb8, 0x44, 0x66, 0x35, 0xf4, 0x49, 0x18, 0x0d, 0x09, 0x8b, 0xaa, + 0x26, 0xa5, 0x76, 0x6d, 0x3c, 0xc5, 0x2b, 0x8b, 0x3a, 0x26, 0x7f, 0x99, 0x98, 0x65, 0x38, 0x41, + 0x0d, 0x35, 0x60, 0xf4, 0xb6, 0xeb, 0xd5, 0xfc, 0xdb, 0xa1, 0xa4, 0x3f, 0x90, 0xaf, 0x02, 0xb8, + 0xc9, 0x31, 0x13, 0x7d, 0x34, 0x9a, 0xbb, 0x69, 0x10, 0xc3, 0x09, 0xe2, 0xf4, 0x18, 0x09, 0x5a, + 0xde, 0x6c, 0x78, 0x3d, 0x24, 0x81, 0x88, 0xf9, 0xc6, 0x8e, 0x11, 0x2c, 0x0b, 0x71, 0x0c, 0xa7, + 0xc7, 0x08, 0xfb, 0xc3, 0x5c, 0xcd, 0xd9, 0x39, 0x25, 0x8e, 0x11, 0xac, 0x4a, 0xb1, 0x86, 0x41, + 0x8f, 0x59, 0xf6, 0x6f, 0xd5, 0xf7, 0xb0, 0xef, 0x47, 0xf2, 0x60, 0x66, 0x69, 0x28, 0xb5, 0x72, + 0x6c, 0x60, 0xe5, 0x44, 0x98, 0xeb, 0x39, 0x68, 0x84, 0x39, 0x14, 0xb5, 0xf1, 0xae, 0xe7, 0x91, + 0x8e, 0x2f, 0xb6, 0xf3, 0xae, 0xdf, 0xbf, 0x27, 0xcf, 0x7b, 0x7a, 0xcf, 0xaf, 0x8b, 0x01, 0xea, + 0xe5, 0x21, 0xf4, 0x98, 0x92, 0xb2, 0xc2, 0x47, 0x47, 0xc2, 0xd0, 0x22, 0xf4, 0x87, 0x3b, 0x61, + 0x35, 0xaa, 0x87, 0xed, 0x52, 0x8d, 0x56, 0x18, 0x8a, 0x96, 0xe9, 0x9a, 0x57, 0xc1, 0xb2, 0x2e, + 0xaa, 0xc2, 0xa4, 0xa0, 0x38, 0xbf, 0xe9, 0x78, 0x2a, 0x01, 0x22, 0xb7, 0x46, 0xbc, 0xb0, 0xb7, + 0x5b, 0x9a, 0x14, 0x2d, 0xeb, 0xe0, 0xfd, 0xdd, 0x12, 0xdd, 0x92, 0x19, 0x10, 0x9c, 0x45, 0x8d, + 0x2f, 0xf9, 0x6a, 0xd5, 0x6f, 0x34, 0xcb, 0x81, 0xbf, 0xee, 0xd6, 0x49, 0x3b, 0x45, 0x6f, 0xc5, + 0xc0, 0x14, 0x4b, 0xde, 0x28, 0xc3, 0x09, 0x6a, 0xe8, 0x16, 0x8c, 0x39, 0xcd, 0xe6, 0x6c, 0xd0, + 0xf0, 0x03, 0xd9, 0xc0, 0x50, 0xbe, 0xc6, 0x60, 0xd6, 0x44, 0xe5, 0xf9, 0x0f, 0x13, 0x85, 0x38, + 0x49, 0x90, 0x0e, 0x94, 0xd8, 0x68, 0xc6, 0x40, 0x8d, 0xc4, 0x03, 0x25, 0xf6, 0x65, 0xc6, 0x40, + 0x65, 0x40, 0x70, 0x16, 0x35, 0xfb, 0xbb, 0x18, 0x53, 0x5f, 0x71, 0x37, 0x3c, 0xe6, 0xf8, 0x86, + 0x1a, 0x30, 0xd2, 0x64, 0xc7, 0xbe, 0xc8, 0x4d, 0x26, 0x8e, 0x8a, 0xe7, 0xbb, 0x14, 0x4c, 0xde, + 0x66, 0xd9, 0x55, 0x0d, 0x03, 0xd5, 0xb2, 0x4e, 0x0e, 0x9b, 0xd4, 0xed, 0x7f, 0x7f, 0x82, 0xb1, + 0x85, 0x15, 0x2e, 0x6d, 0xec, 0x17, 0x6e, 0x88, 0x42, 0xbe, 0x30, 0x9d, 0x2f, 0xd7, 0x8f, 0xd7, + 0x97, 0x70, 0x65, 0xc4, 0xb2, 0x2e, 0xfa, 0x04, 0x8c, 0xd2, 0xe7, 0xba, 0x62, 0xcd, 0xc2, 0xa9, + 0x23, 0xf9, 0xf1, 0xad, 0x14, 0x96, 0x9e, 0xb7, 0x50, 0xaf, 0x8c, 0x13, 0xc4, 0xd0, 0x1b, 0xcc, + 0x66, 0x53, 0x92, 0x2e, 0x74, 0x43, 0x5a, 0x37, 0xcf, 0x94, 0x64, 0x35, 0x22, 0xa8, 0x05, 0x93, + 0xe9, 0xec, 0xcc, 0xe1, 0x94, 0x9d, 0xff, 0xee, 0x49, 0x27, 0x58, 0x8e, 0x13, 0xcc, 0xa5, 0x61, + 0x21, 0xce, 0xa2, 0x8f, 0xae, 0x26, 0x73, 0xe7, 0x16, 0x0d, 0x8d, 0x40, 0x2a, 0x7f, 0xee, 0x48, + 0xdb, 0xb4, 0xb9, 0x1b, 0x70, 0x4a, 0x4b, 0x3f, 0x7a, 0x29, 0x70, 0x98, 0xcd, 0x90, 0xcb, 0x6e, + 0x23, 0x8d, 0x61, 0x7d, 0x78, 0x6f, 0xb7, 0x74, 0x6a, 0xad, 0x1d, 0x22, 0x6e, 0x4f, 0x07, 0x5d, + 0x83, 0xa3, 0x3c, 0x3a, 0xcb, 0x02, 0x71, 0x6a, 0x75, 0xd7, 0x53, 0x1c, 0x31, 0x3f, 0xbb, 0x4e, + 0xec, 0xed, 0x96, 0x8e, 0xce, 0x66, 0x21, 0xe0, 0xec, 0x7a, 0xe8, 0x15, 0x18, 0xac, 0x79, 0xf2, + 0x94, 0xed, 0x33, 0x32, 0xbc, 0x0e, 0x2e, 0xac, 0x56, 0xd4, 0xf7, 0xc7, 0x7f, 0x70, 0x5c, 0x01, + 0x6d, 0x70, 0x95, 0x94, 0x92, 0x23, 0xf6, 0xa7, 0x82, 0x76, 0x26, 0x45, 0xed, 0x46, 0xb8, 0x03, + 0xae, 0x8b, 0x55, 0xee, 0x74, 0x46, 0x24, 0x04, 0x83, 0x30, 0x7a, 0x1d, 0x90, 0xc8, 0x24, 0x34, + 0x5b, 0x65, 0x89, 0xef, 0x34, 0x3b, 0x51, 0x25, 0x1e, 0xa8, 0xa4, 0x30, 0x70, 0x46, 0x2d, 0x74, + 0x99, 0x1e, 0x8f, 0x7a, 0xa9, 0x38, 0x7e, 0x55, 0x1e, 0xf1, 0x05, 0xd2, 0x0c, 0x08, 0x33, 0x6d, + 0x34, 0x29, 0xe2, 0x44, 0x3d, 0x54, 0x83, 0x93, 0x4e, 0x2b, 0xf2, 0x99, 0xb6, 0xcf, 0x44, 0x5d, + 0xf3, 0xb7, 0x88, 0xc7, 0x14, 0xed, 0x03, 0x2c, 0x18, 0xe8, 0xc9, 0xd9, 0x36, 0x78, 0xb8, 0x2d, + 0x15, 0xfa, 0x54, 0xa2, 0x63, 0xa1, 0x29, 0xe2, 0x0c, 0xcf, 0x6d, 0xae, 0x9d, 0x96, 0x18, 0xe8, + 0x05, 0x18, 0xda, 0xf4, 0xc3, 0x68, 0x95, 0x44, 0xb7, 0xfd, 0x60, 0x4b, 0xa4, 0x2e, 0x88, 0xd3, + 0xc5, 0xc4, 0x20, 0xac, 0xe3, 0xa1, 0x27, 0xa0, 0x9f, 0x99, 0x81, 0x2d, 0x2f, 0xb0, 0xbb, 0x76, + 0x20, 0x3e, 0x63, 0x2e, 0xf3, 0x62, 0x2c, 0xe1, 0x12, 0x75, 0xb9, 0x3c, 0xcf, 0x8e, 0xe3, 0x04, + 0xea, 0x72, 0x79, 0x1e, 0x4b, 0x38, 0x5d, 0xae, 0xe1, 0xa6, 0x13, 0x90, 0x72, 0xe0, 0x57, 0x49, + 0xa8, 0x25, 0x29, 0x7a, 0x88, 0x27, 0x66, 0xa0, 0xcb, 0xb5, 0x92, 0x85, 0x80, 0xb3, 0xeb, 0x21, + 0x92, 0x4e, 0xbd, 0x3b, 0x9a, 0xaf, 0x06, 0x4d, 0xb3, 0x83, 0x5d, 0x66, 0xdf, 0xf5, 0x60, 0x5c, + 0x25, 0xfd, 0xe5, 0xa9, 0x18, 0xc2, 0xa9, 0x31, 0xb6, 0xb6, 0xbb, 0xcf, 0xe3, 0xa0, 0x14, 0xcb, + 0xcb, 0x09, 0x4a, 0x38, 0x45, 0xdb, 0x88, 0x36, 0x3b, 0xde, 0x31, 0xda, 0xec, 0x79, 0x18, 0x0c, + 0x5b, 0xb7, 0x6a, 0x7e, 0xc3, 0x71, 0x3d, 0x66, 0x4d, 0xa3, 0x3d, 0xca, 0x2b, 0x12, 0x80, 0x63, + 0x1c, 0xb4, 0x04, 0x03, 0x8e, 0xd4, 0x1a, 0xa3, 0xfc, 0x40, 0x7a, 0x4a, 0x57, 0xcc, 0x63, 0x4b, + 0x49, 0x3d, 0xb1, 0xaa, 0x8b, 0x5e, 0x86, 0x11, 0x11, 0xac, 0x43, 0xe4, 0xc9, 0x9f, 0x34, 0x5d, + 0x93, 0x2b, 0x3a, 0x10, 0x9b, 0xb8, 0xe8, 0x3a, 0x0c, 0x45, 0x7e, 0x9d, 0xf9, 0xd7, 0x52, 0x2e, + 0xf9, 0x58, 0x7e, 0xbc, 0xdb, 0x35, 0x85, 0xa6, 0xeb, 0x33, 0x54, 0x55, 0xac, 0xd3, 0x41, 0x6b, + 0x7c, 0xbd, 0xb3, 0x94, 0x44, 0x24, 0x14, 0x89, 0xd6, 0x4f, 0xe5, 0x99, 0x42, 0x32, 0x34, 0x73, + 0x3b, 0x88, 0x9a, 0x58, 0x27, 0x83, 0x2e, 0xc1, 0x44, 0x33, 0x70, 0x7d, 0xb6, 0x26, 0x94, 0x16, + 0x7c, 0xca, 0x4c, 0x40, 0x5a, 0x4e, 0x22, 0xe0, 0x74, 0x1d, 0x16, 0x6b, 0x45, 0x14, 0x4e, 0x9d, + 0xe0, 0x49, 0xd4, 0xb8, 0x8c, 0x83, 0x97, 0x61, 0x05, 0x45, 0x2b, 0xec, 0x24, 0xe6, 0xe2, 0xb9, + 0xa9, 0xe9, 0x7c, 0x0f, 0x7e, 0x5d, 0x8c, 0xc7, 0x79, 0x7f, 0xf5, 0x17, 0xc7, 0x14, 0x50, 0x4d, + 0xcb, 0x5d, 0x4e, 0x5f, 0x50, 0xe1, 0xd4, 0xc9, 0x36, 0xb6, 0xb8, 0x89, 0xe7, 0x72, 0xcc, 0x10, + 0x18, 0xc5, 0x21, 0x4e, 0xd0, 0x44, 0xaf, 0xc1, 0xb8, 0x08, 0x44, 0x10, 0x0f, 0xd3, 0xa9, 0xd8, + 0x5f, 0x09, 0x27, 0x60, 0x38, 0x85, 0xcd, 0x93, 0x98, 0x39, 0xb7, 0xea, 0x44, 0x1c, 0x7d, 0x57, + 0x5d, 0x6f, 0x2b, 0x9c, 0x3a, 0xcd, 0xce, 0x07, 0x91, 0xc4, 0x2c, 0x09, 0xc5, 0x19, 0x35, 0xd0, + 0x1a, 0x8c, 0x37, 0x03, 0x42, 0x1a, 0xec, 0x9d, 0x24, 0xee, 0xb3, 0x12, 0x0f, 0x35, 0x44, 0x7b, + 0x52, 0x4e, 0xc0, 0xf6, 0x33, 0xca, 0x70, 0x8a, 0x02, 0xba, 0x0d, 0x03, 0xfe, 0x36, 0x09, 0x36, + 0x89, 0x53, 0x9b, 0x3a, 0xd3, 0xc6, 0x8b, 0x4e, 0x5c, 0x6e, 0xd7, 0x04, 0x6e, 0xc2, 0xc8, 0x48, + 0x16, 0x77, 0x36, 0x32, 0x92, 0x8d, 0xa1, 0xbf, 0x63, 0xc1, 0x09, 0xa9, 0xb6, 0xab, 0x34, 0xe9, + 0xa8, 0xcf, 0xfb, 0x5e, 0x18, 0x05, 0x3c, 0x38, 0xce, 0xc3, 0xf9, 0x01, 0x63, 0xd6, 0x72, 0x2a, + 0x29, 0x0d, 0xc1, 0x89, 0x3c, 0x8c, 0x10, 0xe7, 0xb7, 0x48, 0x5f, 0xf6, 0x21, 0x89, 0xe4, 0x61, + 0x34, 0x1b, 0x2e, 0xbd, 0xb1, 0xb0, 0x3a, 0xf5, 0x08, 0x8f, 0xec, 0x43, 0x37, 0x43, 0x25, 0x09, + 0xc4, 0x69, 0x7c, 0x74, 0x01, 0x0a, 0x7e, 0x38, 0xf5, 0x68, 0x9b, 0x74, 0xf7, 0x7e, 0xed, 0x5a, + 0x85, 0x1b, 0x9b, 0x5e, 0xab, 0xe0, 0x82, 0x1f, 0xca, 0x44, 0x62, 0xf4, 0x39, 0x1b, 0x4e, 0x3d, + 0xc6, 0xe5, 0xc9, 0x32, 0x91, 0x18, 0x2b, 0xc4, 0x31, 0x1c, 0x6d, 0xc2, 0x58, 0x68, 0x88, 0x0d, + 0xc2, 0xa9, 0xb3, 0x6c, 0xa4, 0x1e, 0xcb, 0x9b, 0x34, 0x03, 0x5b, 0xcb, 0xf0, 0x63, 0x52, 0xc1, + 0x49, 0xb2, 0x7c, 0x77, 0x69, 0x82, 0x8b, 0x70, 0xea, 0xf1, 0x0e, 0xbb, 0x4b, 0x43, 0xd6, 0x77, + 0x97, 0x4e, 0x03, 0x27, 0x68, 0x4e, 0x7f, 0x07, 0x4c, 0xa4, 0xd8, 0xa5, 0x83, 0x38, 0x56, 0x4c, + 0x6f, 0xc1, 0x88, 0xb1, 0x24, 0x1f, 0xa8, 0xdd, 0xcd, 0xef, 0x0d, 0xc2, 0xa0, 0xb2, 0x87, 0x40, + 0xe7, 0x4d, 0x53, 0x9b, 0x13, 0x49, 0x53, 0x9b, 0x81, 0xb2, 0x5f, 0x33, 0xac, 0x6b, 0xd6, 0x32, + 0x02, 0xd6, 0xe6, 0x1d, 0x80, 0xdd, 0x7b, 0x7f, 0x69, 0x3a, 0x9e, 0x62, 0xd7, 0x36, 0x3b, 0x3d, + 0x6d, 0xd5, 0x46, 0x97, 0x60, 0xc2, 0xf3, 0x19, 0x8f, 0x4e, 0x6a, 0x92, 0x01, 0x63, 0x7c, 0xd6, + 0xa0, 0x1e, 0x50, 0x2d, 0x81, 0x80, 0xd3, 0x75, 0x68, 0x83, 0x9c, 0x51, 0x4a, 0xea, 0xa9, 0x38, + 0x1f, 0x85, 0x05, 0x94, 0xbe, 0x0d, 0xf9, 0xaf, 0x70, 0x6a, 0x3c, 0xff, 0x6d, 0xc8, 0x2b, 0x25, + 0x99, 0xb1, 0x50, 0x32, 0x63, 0x4c, 0x2d, 0xd3, 0xf4, 0x6b, 0xcb, 0x65, 0xc1, 0xe6, 0x6b, 0xa1, + 0xe4, 0x6b, 0xcb, 0x65, 0xcc, 0x61, 0x68, 0x16, 0xfa, 0xd8, 0x0f, 0x19, 0xa8, 0x26, 0x6f, 0x9b, + 0x2e, 0x97, 0xb5, 0x44, 0xa6, 0xac, 0x02, 0x16, 0x15, 0x99, 0xd8, 0x9d, 0xbe, 0x8d, 0x98, 0xd8, + 0xbd, 0xff, 0x1e, 0xc5, 0xee, 0x92, 0x00, 0x8e, 0x69, 0xa1, 0x3b, 0x70, 0xd4, 0x78, 0x8f, 0x2a, + 0x77, 0x38, 0xc8, 0xd7, 0xc8, 0x27, 0x90, 0xe7, 0x4e, 0x89, 0x4e, 0x1f, 0x5d, 0xce, 0xa2, 0x84, + 0xb3, 0x1b, 0x40, 0x75, 0x98, 0xa8, 0xa6, 0x5a, 0x1d, 0xe8, 0xbe, 0x55, 0xb5, 0x2e, 0xd2, 0x2d, + 0xa6, 0x09, 0xa3, 0x97, 0x61, 0xe0, 0x6d, 0x9f, 0x5b, 0xcf, 0x89, 0xa7, 0x89, 0x0c, 0xc5, 0x32, + 0xf0, 0xc6, 0xb5, 0x0a, 0x2b, 0xdf, 0xdf, 0x2d, 0x0d, 0x95, 0xfd, 0x9a, 0xfc, 0x8b, 0x55, 0x05, + 0xf4, 0x03, 0x16, 0x4c, 0xa7, 0x1f, 0xbc, 0xaa, 0xd3, 0x23, 0xdd, 0x77, 0xda, 0x16, 0x8d, 0x4e, + 0x2f, 0xe6, 0x92, 0xc3, 0x6d, 0x9a, 0x42, 0x1f, 0xa6, 0xfb, 0x29, 0x74, 0xef, 0x12, 0x91, 0x05, + 0xfe, 0xe1, 0x78, 0x3f, 0xd1, 0xd2, 0xfd, 0xdd, 0xd2, 0x18, 0x3f, 0x19, 0xdd, 0xbb, 0x2a, 0xe8, + 0x3d, 0xaf, 0x80, 0xbe, 0x1b, 0x8e, 0x06, 0x69, 0x01, 0x34, 0x91, 0x4c, 0xf8, 0x93, 0xdd, 0x9c, + 0xb2, 0xc9, 0x09, 0xc7, 0x59, 0x04, 0x71, 0x76, 0x3b, 0xf6, 0xaf, 0x5b, 0x4c, 0xf1, 0x20, 0xba, + 0x45, 0xc2, 0x56, 0x3d, 0x3a, 0x04, 0x8b, 0xb5, 0x45, 0x43, 0xa9, 0x7f, 0xcf, 0x26, 0x67, 0xff, + 0xca, 0x62, 0x26, 0x67, 0x87, 0xe8, 0x3c, 0xf7, 0x06, 0x0c, 0x44, 0xa2, 0x35, 0xd1, 0xf5, 0x3c, + 0xf3, 0x18, 0xd9, 0x29, 0x66, 0x76, 0xa7, 0x1e, 0x39, 0xb2, 0x14, 0x2b, 0x32, 0xf6, 0x3f, 0xe7, + 0x33, 0x20, 0x21, 0x87, 0xa0, 0x3b, 0x5d, 0x30, 0x75, 0xa7, 0xa5, 0x0e, 0x5f, 0x90, 0xa3, 0x43, + 0xfd, 0x67, 0x66, 0xbf, 0x99, 0x70, 0xef, 0xdd, 0x6e, 0xeb, 0x68, 0x7f, 0xde, 0x02, 0x88, 0xb3, + 0x8c, 0x74, 0x91, 0xf5, 0xf9, 0x22, 0x7d, 0xd6, 0xf8, 0x91, 0x5f, 0xf5, 0xeb, 0x42, 0xbf, 0x73, + 0x32, 0x56, 0xdf, 0xf2, 0xf2, 0x7d, 0xed, 0x37, 0x56, 0xd8, 0xa8, 0x24, 0xc3, 0xfe, 0x16, 0x63, + 0x83, 0x02, 0x23, 0xe4, 0xef, 0x97, 0x2c, 0x38, 0x92, 0xe5, 0x89, 0x41, 0x1f, 0xc9, 0x5c, 0xcc, + 0xa9, 0xec, 0x50, 0xd5, 0x6c, 0xde, 0x10, 0xe5, 0x58, 0x61, 0x74, 0x9d, 0x4e, 0xfb, 0x60, 0x19, + 0x30, 0xae, 0xc1, 0x48, 0x39, 0x20, 0x1a, 0x7f, 0xf1, 0x6a, 0x9c, 0x9c, 0x67, 0x70, 0xee, 0xe9, + 0x03, 0x87, 0x37, 0xb2, 0xbf, 0x5c, 0x80, 0x23, 0xdc, 0x9a, 0x6a, 0x76, 0xdb, 0x77, 0x6b, 0x65, + 0xbf, 0x26, 0xfc, 0x67, 0xdf, 0x84, 0xe1, 0xa6, 0x26, 0x9b, 0x6e, 0x17, 0xcd, 0x5d, 0x97, 0x61, + 0xc7, 0xd2, 0x34, 0xbd, 0x14, 0x1b, 0xb4, 0x50, 0x0d, 0x86, 0xc9, 0xb6, 0x5b, 0x55, 0x26, 0x39, + 0x85, 0x03, 0x5f, 0xd2, 0xaa, 0x95, 0x45, 0x8d, 0x0e, 0x36, 0xa8, 0x76, 0x6d, 0x03, 0xad, 0xb1, + 0x68, 0x3d, 0x1d, 0xcc, 0x70, 0x7e, 0xdc, 0x82, 0xe3, 0x39, 0xb1, 0xdf, 0x69, 0x73, 0xb7, 0x99, + 0xdd, 0x9a, 0x58, 0xb6, 0xaa, 0x39, 0x6e, 0xcd, 0x86, 0x05, 0x14, 0x7d, 0x14, 0xa0, 0x19, 0xe7, + 0xbd, 0xec, 0x10, 0x24, 0xdb, 0x08, 0x97, 0xab, 0x45, 0x3e, 0x55, 0xe9, 0x31, 0x35, 0x5a, 0xf6, + 0x97, 0x7a, 0xa0, 0x97, 0x59, 0x3f, 0xa1, 0x32, 0xf4, 0x6f, 0xf2, 0xc0, 0x7c, 0x6d, 0xe7, 0x8d, + 0xe2, 0xca, 0x48, 0x7f, 0xf1, 0xbc, 0x69, 0xa5, 0x58, 0x92, 0x41, 0x2b, 0x30, 0xc9, 0x73, 0x7a, + 0xd6, 0x17, 0x48, 0xdd, 0xd9, 0x91, 0x62, 0xdf, 0x02, 0xfb, 0x54, 0x25, 0xfe, 0x5e, 0x4e, 0xa3, + 0xe0, 0xac, 0x7a, 0xe8, 0x55, 0x18, 0xa5, 0xcf, 0x70, 0xbf, 0x15, 0x49, 0x4a, 0x3c, 0x89, 0xa6, + 0x7a, 0x99, 0xac, 0x19, 0x50, 0x9c, 0xc0, 0x46, 0x2f, 0xc3, 0x48, 0x33, 0x25, 0xe0, 0xee, 0x8d, + 0x25, 0x41, 0xa6, 0x50, 0xdb, 0xc4, 0x65, 0xce, 0x18, 0x2d, 0xe6, 0x7a, 0xb2, 0xb6, 0x19, 0x90, + 0x70, 0xd3, 0xaf, 0xd7, 0x18, 0x07, 0xdc, 0xab, 0x39, 0x63, 0x24, 0xe0, 0x38, 0x55, 0x83, 0x52, + 0x59, 0x77, 0xdc, 0x7a, 0x2b, 0x20, 0x31, 0x95, 0x3e, 0x93, 0xca, 0x52, 0x02, 0x8e, 0x53, 0x35, + 0x3a, 0x4b, 0xee, 0xfb, 0xef, 0x8f, 0xe4, 0xde, 0xfe, 0x99, 0x02, 0x18, 0x53, 0xfb, 0x1e, 0x4e, + 0xee, 0xf9, 0x0a, 0xf4, 0x6c, 0x04, 0xcd, 0xaa, 0xb0, 0xf4, 0xcb, 0xfc, 0xb2, 0x4b, 0xb8, 0x3c, + 0xaf, 0x7f, 0x19, 0xfd, 0x8f, 0x59, 0x2d, 0xba, 0xc7, 0x8f, 0x96, 0x03, 0x9f, 0x5e, 0x72, 0x32, + 0x76, 0xa7, 0xf2, 0x79, 0xea, 0x97, 0xd1, 0x3b, 0xda, 0x44, 0xb9, 0x16, 0x8e, 0x1b, 0x9c, 0x82, + 0x61, 0x14, 0x57, 0x11, 0x31, 0x7a, 0x24, 0x15, 0x74, 0x01, 0x86, 0x44, 0xbe, 0x45, 0xe6, 0x9a, + 0xc3, 0x37, 0x13, 0x33, 0xe2, 0x5b, 0x88, 0x8b, 0xb1, 0x8e, 0x63, 0xff, 0x60, 0x01, 0x26, 0x33, + 0x7c, 0x2b, 0xf9, 0x35, 0xb2, 0xe1, 0x86, 0x51, 0xb0, 0x93, 0xbc, 0x9c, 0xb0, 0x28, 0xc7, 0x0a, + 0x83, 0x9e, 0x55, 0xfc, 0xa2, 0x4a, 0x5e, 0x4e, 0xc2, 0x77, 0x49, 0x40, 0x0f, 0x76, 0x39, 0xd1, + 0x6b, 0xbb, 0x15, 0x12, 0x19, 0x50, 0x5f, 0x5d, 0xdb, 0xcc, 0x2a, 0x80, 0x41, 0xe8, 0x13, 0x70, + 0x43, 0xa9, 0xba, 0xb5, 0x27, 0x20, 0x57, 0x76, 0x73, 0x18, 0xed, 0x5c, 0x44, 0x3c, 0xc7, 0x8b, + 0xc4, 0x43, 0x31, 0x0e, 0xb4, 0xcc, 0x4a, 0xb1, 0x80, 0xda, 0x5f, 0x2c, 0xc2, 0x89, 0x5c, 0x6f, + 0x6b, 0xda, 0xf5, 0x86, 0xef, 0xb9, 0x91, 0xaf, 0xac, 0x23, 0x79, 0x70, 0x65, 0xd2, 0xdc, 0x5c, + 0x11, 0xe5, 0x58, 0x61, 0xa0, 0xb3, 0xd0, 0xcb, 0x84, 0xe2, 0xc9, 0x5c, 0x6b, 0x78, 0x6e, 0x81, + 0x87, 0xad, 0xe4, 0x60, 0xed, 0x56, 0x2f, 0xb6, 0xbd, 0xd5, 0x1f, 0xa1, 0x1c, 0x8c, 0x5f, 0x4f, + 0x5e, 0x28, 0xb4, 0xbb, 0xbe, 0x5f, 0xc7, 0x0c, 0x88, 0x1e, 0x13, 0xe3, 0x95, 0x30, 0x07, 0xc4, + 0x4e, 0xcd, 0x0f, 0xb5, 0x41, 0x7b, 0x02, 0xfa, 0xb7, 0xc8, 0x4e, 0xe0, 0x7a, 0x1b, 0x49, 0x33, + 0xd1, 0x2b, 0xbc, 0x18, 0x4b, 0xb8, 0x99, 0x5a, 0xbc, 0xff, 0x7e, 0xa4, 0x16, 0xd7, 0x57, 0xc0, + 0x40, 0x47, 0xf6, 0xe4, 0x87, 0x8a, 0x30, 0x86, 0xe7, 0x16, 0xde, 0x9f, 0x88, 0xeb, 0xe9, 0x89, + 0xb8, 0x1f, 0x19, 0xb8, 0x0f, 0x36, 0x1b, 0xbf, 0x62, 0xc1, 0x18, 0xcb, 0xfa, 0x28, 0x42, 0xa5, + 0xb8, 0xbe, 0x77, 0x08, 0x4f, 0x81, 0x47, 0xa0, 0x37, 0xa0, 0x8d, 0x8a, 0x19, 0x54, 0x7b, 0x9c, + 0xf5, 0x04, 0x73, 0x18, 0x3a, 0x09, 0x3d, 0xac, 0x0b, 0x74, 0xf2, 0x86, 0xf9, 0x11, 0xbc, 0xe0, + 0x44, 0x0e, 0x66, 0xa5, 0x2c, 0x68, 0x23, 0x26, 0xcd, 0xba, 0xcb, 0x3b, 0x1d, 0x9b, 0x2c, 0xbc, + 0x3b, 0xe2, 0xb0, 0x64, 0x76, 0xed, 0x9d, 0x05, 0x6d, 0xcc, 0x26, 0xd9, 0xfe, 0x99, 0xfd, 0x17, + 0x05, 0x38, 0x9d, 0x59, 0xaf, 0xeb, 0xa0, 0x8d, 0xed, 0x6b, 0x3f, 0xc8, 0x1c, 0x71, 0xc5, 0x43, + 0x34, 0xc2, 0xef, 0xe9, 0x96, 0xfb, 0xef, 0xed, 0x22, 0x96, 0x62, 0xe6, 0x90, 0xbd, 0x4b, 0x62, + 0x29, 0x66, 0xf6, 0x2d, 0x47, 0x4c, 0xf0, 0xb7, 0x85, 0x9c, 0x6f, 0x61, 0x02, 0x83, 0x73, 0xf4, + 0x9c, 0x61, 0xc0, 0x50, 0x3e, 0xc2, 0xf9, 0x19, 0xc3, 0xcb, 0xb0, 0x82, 0xa2, 0x59, 0x18, 0x6b, + 0xb8, 0x1e, 0x3d, 0x7c, 0x76, 0x4c, 0x56, 0x5c, 0xe9, 0x32, 0x56, 0x4c, 0x30, 0x4e, 0xe2, 0x23, + 0x57, 0x8b, 0xb3, 0xc8, 0xbf, 0xee, 0xe5, 0x03, 0xed, 0xba, 0x19, 0xd3, 0x9c, 0x43, 0x8d, 0x62, + 0x46, 0xcc, 0xc5, 0x15, 0x4d, 0x4e, 0x54, 0xec, 0x5e, 0x4e, 0x34, 0x9c, 0x2d, 0x23, 0x9a, 0x7e, + 0x19, 0x46, 0xee, 0x59, 0x37, 0x62, 0x7f, 0xa3, 0x08, 0x0f, 0xb5, 0xd9, 0xf6, 0xfc, 0xac, 0x37, + 0xe6, 0x40, 0x3b, 0xeb, 0x53, 0xf3, 0x50, 0x86, 0x23, 0xeb, 0xad, 0x7a, 0x7d, 0x87, 0x79, 0x9b, + 0x91, 0x9a, 0xc4, 0x10, 0x3c, 0xa5, 0x14, 0x8e, 0x1c, 0x59, 0xca, 0xc0, 0xc1, 0x99, 0x35, 0xe9, + 0x13, 0x8b, 0xde, 0x24, 0x3b, 0x8a, 0x54, 0xe2, 0x89, 0x85, 0x75, 0x20, 0x36, 0x71, 0xd1, 0x25, + 0x98, 0x70, 0xb6, 0x1d, 0x97, 0xe7, 0xd8, 0x90, 0x04, 0xf8, 0x1b, 0x4b, 0xc9, 0xa2, 0x67, 0x93, + 0x08, 0x38, 0x5d, 0x07, 0xbd, 0x0e, 0xc8, 0xbf, 0xc5, 0x3c, 0x58, 0x6a, 0x97, 0x88, 0x27, 0xb4, + 0xee, 0x6c, 0xee, 0x8a, 0xf1, 0x91, 0x70, 0x2d, 0x85, 0x81, 0x33, 0x6a, 0x25, 0x22, 0xfe, 0xf5, + 0xe5, 0x47, 0xfc, 0x6b, 0x7f, 0x2e, 0x76, 0x4c, 0x4f, 0xf8, 0x16, 0x8c, 0x1c, 0xd4, 0x2c, 0xfb, + 0x09, 0xe8, 0x0f, 0x44, 0xe2, 0xf7, 0x84, 0x6b, 0xb7, 0x4c, 0x8b, 0x2d, 0xe1, 0xf6, 0x7f, 0xb1, + 0x40, 0xc9, 0x92, 0xcd, 0xe0, 0xde, 0x2f, 0x33, 0x1b, 0x73, 0x2e, 0x05, 0xd7, 0xe2, 0x79, 0x1d, + 0xd5, 0x6c, 0xcc, 0x63, 0x20, 0x36, 0x71, 0xf9, 0x72, 0x0b, 0xe3, 0x30, 0x12, 0xc6, 0x03, 0x42, + 0xc4, 0x1e, 0x55, 0x18, 0xe8, 0x63, 0xd0, 0x5f, 0x73, 0xb7, 0xdd, 0x50, 0xc8, 0xd1, 0x0e, 0xac, + 0xb7, 0x8b, 0xbf, 0x6f, 0x81, 0x93, 0xc1, 0x92, 0x9e, 0xfd, 0x23, 0x16, 0x28, 0xbd, 0xe4, 0x65, + 0xe2, 0xd4, 0xa3, 0x4d, 0xf4, 0x1a, 0x80, 0xa4, 0xa0, 0x64, 0x6f, 0xd2, 0x5a, 0x0a, 0xb0, 0x82, + 0xec, 0x1b, 0xff, 0xb0, 0x56, 0x07, 0xbd, 0x0a, 0x7d, 0x9b, 0x8c, 0x96, 0xf8, 0xb6, 0xb3, 0x4a, + 0xd5, 0xc5, 0x4a, 0xf7, 0x77, 0x4b, 0x47, 0xcc, 0x36, 0xe5, 0x2d, 0xc6, 0x6b, 0xd9, 0x3f, 0x54, + 0x88, 0xe7, 0xf4, 0x8d, 0x96, 0x1f, 0x39, 0x87, 0xc0, 0x89, 0x5c, 0x32, 0x38, 0x91, 0xc7, 0xb2, + 0x17, 0xaa, 0xd6, 0xa5, 0x5c, 0x0e, 0xe4, 0x5a, 0x82, 0x03, 0x79, 0xbc, 0x33, 0xa9, 0xf6, 0x9c, + 0xc7, 0xbf, 0xb0, 0x60, 0xc2, 0xc0, 0x3f, 0x84, 0x0b, 0x70, 0xc9, 0xbc, 0x00, 0x1f, 0xee, 0xf8, + 0x0d, 0x39, 0x17, 0xdf, 0xf7, 0x17, 0x13, 0x7d, 0x67, 0x17, 0xde, 0xdb, 0xd0, 0xb3, 0xe9, 0x04, + 0x35, 0xf1, 0xae, 0x3f, 0xdf, 0xd5, 0x58, 0xcf, 0x5c, 0x76, 0x02, 0x61, 0x69, 0xf1, 0xb4, 0x1c, + 0x75, 0x5a, 0xd4, 0xd1, 0xca, 0x82, 0x35, 0x85, 0x2e, 0x42, 0x5f, 0x58, 0xf5, 0x9b, 0xca, 0x19, + 0x8f, 0xe5, 0xec, 0xae, 0xb0, 0x92, 0xfd, 0xdd, 0x12, 0x32, 0x9b, 0xa3, 0xc5, 0x58, 0xe0, 0xa3, + 0x37, 0x61, 0x84, 0xfd, 0x52, 0x66, 0x8f, 0xc5, 0x7c, 0x09, 0x4c, 0x45, 0x47, 0xe4, 0x36, 0xc1, + 0x46, 0x11, 0x36, 0x49, 0x4d, 0x6f, 0xc0, 0xa0, 0xfa, 0xac, 0x07, 0xaa, 0xad, 0xff, 0x8f, 0x45, + 0x98, 0xcc, 0x58, 0x73, 0x28, 0x34, 0x66, 0xe2, 0x42, 0x97, 0x4b, 0xf5, 0x1d, 0xce, 0x45, 0xc8, + 0x1e, 0x80, 0x35, 0xb1, 0xb6, 0xba, 0x6e, 0xf4, 0x7a, 0x48, 0x92, 0x8d, 0xd2, 0xa2, 0xce, 0x8d, + 0xd2, 0xc6, 0x0e, 0x6d, 0xa8, 0x69, 0x43, 0xaa, 0xa7, 0x0f, 0x74, 0x4e, 0x7f, 0xab, 0x07, 0x8e, + 0x64, 0x05, 0xaa, 0x46, 0x9f, 0x81, 0x3e, 0xe6, 0x2d, 0x26, 0x05, 0x67, 0xcf, 0xb7, 0x1b, 0x61, + 0xbd, 0xe6, 0x0c, 0x73, 0x38, 0x13, 0xf1, 0x61, 0x67, 0xe4, 0x71, 0xc4, 0x0b, 0x3b, 0x0e, 0xb3, + 0x68, 0x93, 0xc5, 0x6d, 0x12, 0xb7, 0xa7, 0x3c, 0x3e, 0x3e, 0xd4, 0x75, 0x07, 0xc4, 0xfd, 0x1b, + 0x26, 0x4c, 0xaa, 0x64, 0x71, 0x67, 0x93, 0x2a, 0xd9, 0x32, 0x5a, 0x86, 0xbe, 0x2a, 0xb7, 0xd5, + 0x29, 0x76, 0x3e, 0xc2, 0xb8, 0xa1, 0x8e, 0x3a, 0x80, 0x85, 0x81, 0x8e, 0x20, 0x30, 0xed, 0xc2, + 0x90, 0x36, 0x30, 0x0f, 0x74, 0xf1, 0x6c, 0xd1, 0x8b, 0x4f, 0x1b, 0x82, 0x07, 0xba, 0x80, 0x7e, + 0x4c, 0xbb, 0xfb, 0xc5, 0x79, 0xf0, 0x41, 0x83, 0x77, 0x3a, 0x99, 0xf0, 0xf3, 0x4b, 0xec, 0x2b, + 0xc6, 0x4b, 0x55, 0xcc, 0xc0, 0xea, 0xb9, 0xf9, 0x99, 0xcc, 0x0b, 0xbf, 0x7d, 0x30, 0x75, 0xfb, + 0xc7, 0x2d, 0x48, 0x78, 0x62, 0x29, 0x71, 0xa7, 0x95, 0x2b, 0xee, 0x3c, 0x03, 0x3d, 0x81, 0x5f, + 0x27, 0xc9, 0xfc, 0xf7, 0xd8, 0xaf, 0x13, 0xcc, 0x20, 0x14, 0x23, 0x8a, 0x85, 0x58, 0xc3, 0xfa, + 0x03, 0x5d, 0x3c, 0xbd, 0x1f, 0x81, 0xde, 0x3a, 0xd9, 0x26, 0xf5, 0x64, 0x9a, 0xd2, 0xab, 0xb4, + 0x10, 0x73, 0x98, 0xfd, 0x2b, 0x3d, 0x70, 0xaa, 0x6d, 0x78, 0x37, 0xca, 0x60, 0x6e, 0x38, 0x11, + 0xb9, 0xed, 0xec, 0x24, 0xd3, 0xf3, 0x5d, 0xe2, 0xc5, 0x58, 0xc2, 0x99, 0xc7, 0x33, 0x4f, 0x57, + 0x93, 0x10, 0x0e, 0x8b, 0x2c, 0x35, 0x02, 0x6a, 0x0a, 0x1b, 0x8b, 0xf7, 0x43, 0xd8, 0xf8, 0x2c, + 0x40, 0x18, 0xd6, 0xb9, 0xc1, 0x65, 0x4d, 0xb8, 0x52, 0xc7, 0x69, 0x8d, 0x2a, 0x57, 0x05, 0x04, + 0x6b, 0x58, 0x68, 0x01, 0xc6, 0x9b, 0x81, 0x1f, 0x71, 0x59, 0xfb, 0x02, 0xb7, 0x49, 0xee, 0x35, + 0x23, 0x6b, 0x95, 0x13, 0x70, 0x9c, 0xaa, 0x81, 0x5e, 0x80, 0x21, 0x11, 0x6d, 0xab, 0xec, 0xfb, + 0x75, 0x21, 0xde, 0x53, 0x66, 0xba, 0x95, 0x18, 0x84, 0x75, 0x3c, 0xad, 0x1a, 0x13, 0xe0, 0xf7, + 0x67, 0x56, 0xe3, 0x42, 0x7c, 0x0d, 0x2f, 0x11, 0x99, 0x7f, 0xa0, 0xab, 0xc8, 0xfc, 0xb1, 0xc0, + 0x73, 0xb0, 0x6b, 0x7d, 0x32, 0x74, 0x14, 0x11, 0x7e, 0xa5, 0x07, 0x26, 0xc5, 0xc2, 0x79, 0xd0, + 0xcb, 0xe5, 0x7a, 0x7a, 0xb9, 0xdc, 0x0f, 0x91, 0xe8, 0xfb, 0x6b, 0xe6, 0xb0, 0xd7, 0xcc, 0x0f, + 0x5b, 0x60, 0xf2, 0x90, 0xe8, 0xff, 0xcb, 0xcd, 0x6f, 0xfa, 0x42, 0x2e, 0x4f, 0x1a, 0x87, 0xed, + 0x7e, 0x67, 0x99, 0x4e, 0xed, 0xff, 0x64, 0xc1, 0xc3, 0x1d, 0x29, 0xa2, 0x45, 0x18, 0x64, 0x8c, + 0xae, 0xf6, 0x2e, 0x7e, 0x5c, 0xf9, 0x2c, 0x48, 0x40, 0x0e, 0xdf, 0x1d, 0xd7, 0x44, 0x8b, 0xa9, + 0x44, 0xb2, 0x4f, 0x64, 0x24, 0x92, 0x3d, 0x6a, 0x0c, 0xcf, 0x3d, 0x66, 0x92, 0xfd, 0x02, 0xbd, + 0x71, 0x4c, 0xc7, 0xc7, 0x0f, 0x19, 0xe2, 0x5c, 0x3b, 0x21, 0xce, 0x45, 0x26, 0xb6, 0x76, 0x87, + 0xbc, 0x06, 0xe3, 0x2c, 0x0c, 0x27, 0xf3, 0xa0, 0x11, 0x1e, 0x93, 0x85, 0xd8, 0x4a, 0xfe, 0x6a, + 0x02, 0x86, 0x53, 0xd8, 0xf6, 0x9f, 0x15, 0xa1, 0x8f, 0x6f, 0xbf, 0x43, 0x78, 0xf8, 0x3e, 0x05, + 0x83, 0x6e, 0xa3, 0xd1, 0xe2, 0xb9, 0x41, 0x7b, 0x63, 0x9b, 0xeb, 0x65, 0x59, 0x88, 0x63, 0x38, + 0x5a, 0x12, 0x9a, 0x84, 0x36, 0x91, 0xbe, 0x79, 0xc7, 0x67, 0x16, 0x9c, 0xc8, 0xe1, 0x5c, 0x9c, + 0xba, 0x67, 0x63, 0x9d, 0x03, 0xfa, 0x24, 0x40, 0x18, 0x05, 0xae, 0xb7, 0x41, 0xcb, 0x44, 0x3a, + 0x88, 0x27, 0xdb, 0x50, 0xab, 0x28, 0x64, 0x4e, 0x33, 0x3e, 0x73, 0x14, 0x00, 0x6b, 0x14, 0xd1, + 0x8c, 0x71, 0xd3, 0x4f, 0x27, 0xe6, 0x0e, 0x38, 0xd5, 0x78, 0xce, 0xa6, 0x5f, 0x84, 0x41, 0x45, + 0xbc, 0x93, 0x5c, 0x71, 0x58, 0x67, 0xd8, 0x3e, 0x02, 0x63, 0x89, 0xbe, 0x1d, 0x48, 0x2c, 0xf9, + 0xab, 0x16, 0x8c, 0xf1, 0xce, 0x2c, 0x7a, 0xdb, 0xe2, 0x36, 0xb8, 0x0b, 0x47, 0xea, 0x19, 0xa7, + 0xb2, 0x98, 0xfe, 0xee, 0x4f, 0x71, 0x25, 0x86, 0xcc, 0x82, 0xe2, 0xcc, 0x36, 0xd0, 0x39, 0xba, + 0xe3, 0xe8, 0xa9, 0xeb, 0xd4, 0x45, 0x48, 0x8f, 0x61, 0xbe, 0xdb, 0x78, 0x19, 0x56, 0x50, 0xfb, + 0x8f, 0x2c, 0x98, 0xe0, 0x3d, 0xbf, 0x42, 0x76, 0xd4, 0xd9, 0xf4, 0xad, 0xec, 0xbb, 0xc8, 0x4a, + 0x5d, 0xc8, 0xc9, 0x4a, 0xad, 0x7f, 0x5a, 0xb1, 0xed, 0xa7, 0x7d, 0xd9, 0x02, 0xb1, 0x42, 0x0e, + 0x41, 0xd2, 0xf2, 0x1d, 0xa6, 0xa4, 0x65, 0x3a, 0x7f, 0x13, 0xe4, 0x88, 0x58, 0xfe, 0xc6, 0x82, + 0x71, 0x8e, 0x10, 0x5b, 0x41, 0x7c, 0x4b, 0xe7, 0x61, 0xce, 0xfc, 0xa2, 0x4c, 0xb3, 0xd6, 0x2b, + 0x64, 0x67, 0xcd, 0x2f, 0x3b, 0xd1, 0x66, 0xf6, 0x47, 0x19, 0x93, 0xd5, 0xd3, 0x76, 0xb2, 0x6a, + 0x72, 0x03, 0x19, 0xd9, 0x0f, 0x3b, 0x08, 0x80, 0x0f, 0x9a, 0xfd, 0xd0, 0xfe, 0x73, 0x0b, 0x10, + 0x6f, 0xc6, 0x60, 0xdc, 0x28, 0x3b, 0xc4, 0x4a, 0xb5, 0x8b, 0x2e, 0x3e, 0x9a, 0x14, 0x04, 0x6b, + 0x58, 0xf7, 0x65, 0x78, 0x12, 0xa6, 0x2c, 0xc5, 0xce, 0xa6, 0x2c, 0x07, 0x18, 0xd1, 0x2f, 0xf7, + 0x43, 0xd2, 0x67, 0x12, 0xdd, 0x80, 0xe1, 0xaa, 0xd3, 0x74, 0x6e, 0xb9, 0x75, 0x37, 0x72, 0x49, + 0xd8, 0xce, 0xce, 0x6d, 0x5e, 0xc3, 0x13, 0xc6, 0x07, 0x5a, 0x09, 0x36, 0xe8, 0xa0, 0x19, 0x80, + 0x66, 0xe0, 0x6e, 0xbb, 0x75, 0xb2, 0xc1, 0x04, 0x42, 0x2c, 0x88, 0x10, 0x37, 0xba, 0x93, 0xa5, + 0x58, 0xc3, 0xc8, 0x88, 0xef, 0x51, 0x7c, 0xc0, 0xf1, 0x3d, 0xe0, 0xd0, 0xe2, 0x7b, 0xf4, 0x1c, + 0x28, 0xbe, 0xc7, 0xc0, 0x81, 0xe3, 0x7b, 0xf4, 0x76, 0x15, 0xdf, 0x03, 0xc3, 0x31, 0xc9, 0x7b, + 0xd2, 0xff, 0x4b, 0x6e, 0x9d, 0x88, 0x07, 0x07, 0x8f, 0x7c, 0x34, 0xbd, 0xb7, 0x5b, 0x3a, 0x86, + 0x33, 0x31, 0x70, 0x4e, 0x4d, 0xf4, 0x51, 0x98, 0x72, 0xea, 0x75, 0xff, 0xb6, 0x9a, 0xd4, 0xc5, + 0xb0, 0xea, 0xd4, 0xb9, 0x72, 0xa9, 0x9f, 0x51, 0x3d, 0xb9, 0xb7, 0x5b, 0x9a, 0x9a, 0xcd, 0xc1, + 0xc1, 0xb9, 0xb5, 0xd1, 0x2b, 0x30, 0xd8, 0x0c, 0xfc, 0xea, 0x8a, 0xe6, 0xd8, 0x7d, 0x9a, 0x0e, + 0x60, 0x59, 0x16, 0xee, 0xef, 0x96, 0x46, 0xd4, 0x1f, 0x76, 0xe1, 0xc7, 0x15, 0x32, 0x42, 0x67, + 0x0c, 0x3d, 0xe8, 0xd0, 0x19, 0xc3, 0xf7, 0x39, 0x74, 0x86, 0xbd, 0x05, 0x93, 0x15, 0x12, 0xb8, + 0x4e, 0xdd, 0xbd, 0x4b, 0x79, 0x72, 0x79, 0x06, 0xae, 0xc1, 0x60, 0x90, 0x38, 0xf5, 0xbb, 0x8a, + 0xf0, 0xad, 0xc9, 0x65, 0xe4, 0x29, 0x1f, 0x13, 0xb2, 0xff, 0xb7, 0x05, 0xfd, 0xc2, 0x0f, 0xf3, + 0x10, 0x38, 0xd3, 0x59, 0x43, 0x25, 0x53, 0xca, 0x9e, 0x14, 0xd6, 0x99, 0x5c, 0x65, 0xcc, 0x72, + 0x42, 0x19, 0xf3, 0x70, 0x3b, 0x22, 0xed, 0xd5, 0x30, 0x7f, 0xbf, 0x48, 0x5f, 0x08, 0x46, 0x44, + 0x80, 0x07, 0x3f, 0x04, 0xab, 0xd0, 0x1f, 0x0a, 0x8f, 0xf4, 0x42, 0xbe, 0x2f, 0x4f, 0x72, 0x12, + 0x63, 0x1b, 0x48, 0xe1, 0x83, 0x2e, 0x89, 0x64, 0xba, 0xba, 0x17, 0x1f, 0xa0, 0xab, 0x7b, 0xa7, + 0x98, 0x09, 0x3d, 0xf7, 0x23, 0x66, 0x82, 0xfd, 0x35, 0x76, 0x3b, 0xeb, 0xe5, 0x87, 0xc0, 0xb8, + 0x5d, 0x32, 0xef, 0x71, 0xbb, 0xcd, 0xca, 0x12, 0x9d, 0xca, 0x61, 0xe0, 0x7e, 0xd9, 0x82, 0x53, + 0x19, 0x5f, 0xa5, 0x71, 0x73, 0x4f, 0xc3, 0x80, 0xd3, 0xaa, 0xb9, 0x6a, 0x2f, 0x6b, 0xda, 0xe2, + 0x59, 0x51, 0x8e, 0x15, 0x06, 0x9a, 0x87, 0x09, 0x72, 0xa7, 0xe9, 0x72, 0x35, 0xbc, 0x6e, 0x3a, + 0x5e, 0xe4, 0xce, 0xbb, 0x8b, 0x49, 0x20, 0x4e, 0xe3, 0xab, 0xb8, 0x6b, 0xc5, 0xdc, 0xb8, 0x6b, + 0xbf, 0x60, 0xc1, 0x90, 0xf2, 0xc9, 0x7e, 0xe0, 0xa3, 0xfd, 0x9a, 0x39, 0xda, 0x0f, 0xb5, 0x19, + 0xed, 0x9c, 0x61, 0xfe, 0xc3, 0x82, 0xea, 0x6f, 0xd9, 0x0f, 0xa2, 0x2e, 0xb8, 0xc4, 0x7b, 0x77, + 0x7b, 0xb9, 0x00, 0x43, 0x4e, 0xb3, 0x29, 0x01, 0xd2, 0x7e, 0x91, 0xe5, 0x6b, 0x88, 0x8b, 0xb1, + 0x8e, 0xa3, 0xbc, 0x70, 0x8a, 0xb9, 0x5e, 0x38, 0x35, 0x80, 0xc8, 0x09, 0x36, 0x48, 0x44, 0xcb, + 0x84, 0xb9, 0x75, 0xfe, 0x79, 0xd3, 0x8a, 0xdc, 0xfa, 0x8c, 0xeb, 0x45, 0x61, 0x14, 0xcc, 0x2c, + 0x7b, 0xd1, 0xb5, 0x80, 0x3f, 0x53, 0xb5, 0xc8, 0x85, 0x8a, 0x16, 0xd6, 0xe8, 0xca, 0xf8, 0x23, + 0xac, 0x8d, 0x5e, 0xd3, 0x10, 0x66, 0x55, 0x94, 0x63, 0x85, 0x61, 0xbf, 0xc8, 0x6e, 0x1f, 0x36, + 0xa6, 0x07, 0x8b, 0xda, 0xf7, 0x17, 0xc3, 0x6a, 0x36, 0x98, 0x4a, 0x78, 0x41, 0x8f, 0x0d, 0xd8, + 0xfe, 0xb0, 0xa7, 0x0d, 0xeb, 0xfe, 0xac, 0x71, 0x00, 0x41, 0xf4, 0xf1, 0x94, 0x71, 0xd3, 0x33, + 0x1d, 0x6e, 0x8d, 0x03, 0x98, 0x33, 0xb1, 0xe4, 0x6d, 0x2c, 0xb5, 0xd5, 0x72, 0x59, 0xec, 0x0b, + 0x2d, 0x79, 0x9b, 0x00, 0xe0, 0x18, 0x87, 0x32, 0x6c, 0xea, 0x4f, 0x38, 0x85, 0xe2, 0x18, 0xdf, + 0x0a, 0x3b, 0xc4, 0x1a, 0x06, 0x3a, 0x2f, 0x84, 0x16, 0x5c, 0xf7, 0xf0, 0x50, 0x42, 0x68, 0x21, + 0x87, 0x4b, 0x93, 0x34, 0x5d, 0x80, 0x21, 0x72, 0x27, 0x22, 0x81, 0xe7, 0xd4, 0x69, 0x0b, 0xbd, + 0x71, 0x58, 0xda, 0xc5, 0xb8, 0x18, 0xeb, 0x38, 0x68, 0x0d, 0xc6, 0x42, 0x2e, 0xcb, 0x53, 0x99, + 0x25, 0xb8, 0x4c, 0xf4, 0x49, 0xe5, 0x0d, 0x6f, 0x82, 0xf7, 0x59, 0x11, 0x3f, 0x9d, 0x64, 0x8c, + 0x90, 0x24, 0x09, 0xf4, 0x2a, 0x8c, 0xd6, 0x7d, 0xa7, 0x36, 0xe7, 0xd4, 0x1d, 0xaf, 0xca, 0xc6, + 0x67, 0xc0, 0x08, 0x14, 0x39, 0x7a, 0xd5, 0x80, 0xe2, 0x04, 0x36, 0x65, 0x10, 0xf5, 0x12, 0x91, + 0x0d, 0xc5, 0xf1, 0x36, 0x48, 0x38, 0x35, 0xc8, 0xbe, 0x8a, 0x31, 0x88, 0x57, 0x73, 0x70, 0x70, + 0x6e, 0x6d, 0x74, 0x11, 0x86, 0xe5, 0xe7, 0x6b, 0x21, 0x75, 0x62, 0x87, 0x26, 0x0d, 0x86, 0x0d, + 0x4c, 0x14, 0xc2, 0x51, 0xf9, 0x7f, 0x2d, 0x70, 0xd6, 0xd7, 0xdd, 0xaa, 0x88, 0x33, 0xc1, 0x9d, + 0xbf, 0x3f, 0x22, 0x3d, 0x4d, 0x17, 0xb3, 0x90, 0xf6, 0x77, 0x4b, 0x27, 0xc5, 0xa8, 0x65, 0xc2, + 0x71, 0x36, 0x6d, 0xb4, 0x02, 0x93, 0xdc, 0x06, 0x66, 0x7e, 0x93, 0x54, 0xb7, 0xe4, 0x86, 0x63, + 0x5c, 0xa3, 0xe6, 0xf8, 0x73, 0x39, 0x8d, 0x82, 0xb3, 0xea, 0xa1, 0xb7, 0x60, 0xaa, 0xd9, 0xba, + 0x55, 0x77, 0xc3, 0xcd, 0x55, 0x3f, 0x62, 0x26, 0x64, 0xb3, 0xb5, 0x5a, 0x40, 0x42, 0xee, 0x1b, + 0xcc, 0xae, 0x5e, 0x19, 0x06, 0xa9, 0x9c, 0x83, 0x87, 0x73, 0x29, 0xa0, 0xbb, 0x70, 0x34, 0xb1, + 0x10, 0x44, 0x3c, 0x93, 0xd1, 0xfc, 0xbc, 0x52, 0x95, 0xac, 0x0a, 0x22, 0x34, 0x50, 0x16, 0x08, + 0x67, 0x37, 0x81, 0x5e, 0x02, 0x70, 0x9b, 0x4b, 0x4e, 0xc3, 0xad, 0xd3, 0xe7, 0xe8, 0x24, 0x5b, + 0x23, 0xf4, 0x69, 0x02, 0xcb, 0x65, 0x59, 0x4a, 0xcf, 0x66, 0xf1, 0x6f, 0x07, 0x6b, 0xd8, 0xe8, + 0x2a, 0x8c, 0x8a, 0x7f, 0x3b, 0x62, 0x4a, 0x27, 0x54, 0x0a, 0xd2, 0x51, 0x59, 0x43, 0xcd, 0x63, + 0xa2, 0x04, 0x27, 0xea, 0xa2, 0x0d, 0x38, 0x25, 0xf3, 0x9f, 0xea, 0xeb, 0x53, 0xce, 0x41, 0xc8, + 0x92, 0x39, 0x0d, 0x70, 0x9f, 0xa2, 0xd9, 0x76, 0x88, 0xb8, 0x3d, 0x1d, 0x7a, 0xaf, 0xeb, 0xcb, + 0x9c, 0x7b, 0x8c, 0x1f, 0x8d, 0xc3, 0x6d, 0x5e, 0x4d, 0x02, 0x71, 0x1a, 0x1f, 0xf9, 0x70, 0xd4, + 0xf5, 0xb2, 0x56, 0xf5, 0x31, 0x46, 0xe8, 0xc3, 0xdc, 0x59, 0xbe, 0xfd, 0x8a, 0xce, 0x84, 0xe3, + 0x6c, 0xba, 0x68, 0x19, 0x26, 0x23, 0x5e, 0xb0, 0xe0, 0x86, 0x3c, 0x57, 0x0c, 0x7d, 0xf6, 0x1d, + 0x67, 0xcd, 0x1d, 0xa7, 0xab, 0x79, 0x2d, 0x0d, 0xc6, 0x59, 0x75, 0xde, 0x99, 0x01, 0xe8, 0xd7, + 0x2d, 0x5a, 0x5b, 0x63, 0xf4, 0xd1, 0xa7, 0x60, 0x58, 0x1f, 0x1f, 0xc1, 0xb4, 0x9c, 0xcd, 0xe6, + 0x83, 0xb5, 0xe3, 0x85, 0x3f, 0x13, 0xd4, 0x11, 0xa2, 0xc3, 0xb0, 0x41, 0x11, 0x55, 0x33, 0x82, + 0x5c, 0x9c, 0xef, 0x8e, 0x29, 0xea, 0xde, 0xfe, 0x91, 0x40, 0xf6, 0xce, 0x41, 0x57, 0x61, 0xa0, + 0x5a, 0x77, 0x89, 0x17, 0x2d, 0x97, 0xdb, 0x45, 0x41, 0x9d, 0x17, 0x38, 0x62, 0x2b, 0x8a, 0x14, + 0x4f, 0xbc, 0x0c, 0x2b, 0x0a, 0xf6, 0x45, 0x18, 0xaa, 0xd4, 0x09, 0x69, 0x72, 0x3f, 0x2e, 0xf4, + 0x04, 0x7b, 0x98, 0x30, 0xd6, 0xd2, 0x62, 0xac, 0xa5, 0xfe, 0xe6, 0x60, 0x4c, 0xa5, 0x84, 0xdb, + 0xbf, 0x53, 0x80, 0x52, 0x87, 0x4c, 0x63, 0x09, 0x7d, 0x9b, 0xd5, 0x95, 0xbe, 0x6d, 0x16, 0xc6, + 0xe2, 0x7f, 0xba, 0x28, 0x4f, 0x19, 0x43, 0xdf, 0x30, 0xc1, 0x38, 0x89, 0xdf, 0xb5, 0x5f, 0x8b, + 0xae, 0xb2, 0xeb, 0xe9, 0xe8, 0x99, 0x65, 0xa8, 0xea, 0x7b, 0xbb, 0x7f, 0x7b, 0xe7, 0xaa, 0x5d, + 0xed, 0xaf, 0x15, 0xe0, 0xa8, 0x1a, 0xc2, 0xf7, 0xee, 0xc0, 0x5d, 0x4f, 0x0f, 0xdc, 0x7d, 0x50, + 0x5a, 0xdb, 0xd7, 0xa0, 0x8f, 0x87, 0x66, 0xed, 0x82, 0xe7, 0x7f, 0xc4, 0x8c, 0x80, 0xaf, 0xd8, + 0x4c, 0x23, 0x0a, 0xfe, 0x0f, 0x58, 0x30, 0x96, 0x70, 0x90, 0x44, 0x58, 0xf3, 0xa2, 0xbf, 0x17, + 0xbe, 0x3c, 0x8b, 0xe3, 0x3f, 0x03, 0x3d, 0x9b, 0xbe, 0x32, 0x52, 0x56, 0x18, 0x97, 0xfd, 0x30, + 0xc2, 0x0c, 0x62, 0xff, 0xb1, 0x05, 0xbd, 0x6b, 0x8e, 0xeb, 0x45, 0x52, 0xfb, 0x61, 0xe5, 0x68, + 0x3f, 0xba, 0xf9, 0x2e, 0xf4, 0x02, 0xf4, 0x91, 0xf5, 0x75, 0x52, 0x8d, 0xc4, 0xac, 0xca, 0x68, + 0x1a, 0x7d, 0x8b, 0xac, 0x94, 0x32, 0xa1, 0xac, 0x31, 0xfe, 0x17, 0x0b, 0x64, 0x74, 0x13, 0x06, + 0x23, 0xb7, 0x41, 0x66, 0x6b, 0x35, 0x61, 0x13, 0x70, 0x0f, 0x21, 0x60, 0xd6, 0x24, 0x01, 0x1c, + 0xd3, 0xb2, 0xbf, 0x58, 0x00, 0x88, 0x43, 0xc1, 0x75, 0xfa, 0xc4, 0xb9, 0x94, 0xb6, 0xf8, 0x6c, + 0x86, 0xb6, 0x18, 0xc5, 0x04, 0x33, 0x54, 0xc5, 0x6a, 0x98, 0x8a, 0x5d, 0x0d, 0x53, 0xcf, 0x41, + 0x86, 0x69, 0x1e, 0x26, 0xe2, 0x50, 0x76, 0x66, 0x24, 0x4f, 0x76, 0x7f, 0xaf, 0x25, 0x81, 0x38, + 0x8d, 0x6f, 0x13, 0x38, 0xa3, 0x22, 0x7a, 0x89, 0xbb, 0x90, 0xb9, 0x12, 0xe8, 0xda, 0xf7, 0x0e, + 0xe3, 0x14, 0xab, 0xc3, 0x0b, 0xb9, 0xea, 0xf0, 0x9f, 0xb2, 0xe0, 0x48, 0xb2, 0x1d, 0xe6, 0x77, + 0xff, 0x79, 0x0b, 0x8e, 0xc6, 0x89, 0x76, 0xd2, 0x26, 0x08, 0xcf, 0xb7, 0x8d, 0x52, 0x96, 0xd3, + 0xe3, 0x38, 0x6c, 0xcb, 0x4a, 0x16, 0x69, 0x9c, 0xdd, 0xa2, 0xfd, 0xbf, 0x7a, 0x60, 0x2a, 0x2f, + 0xbc, 0x19, 0xf3, 0x34, 0x72, 0xee, 0x54, 0xb6, 0xc8, 0x6d, 0xe1, 0xcf, 0x11, 0x7b, 0x1a, 0xf1, + 0x62, 0x2c, 0xe1, 0xc9, 0xdc, 0x4a, 0x85, 0x2e, 0x73, 0x2b, 0x6d, 0xc2, 0xc4, 0xed, 0x4d, 0xe2, + 0x5d, 0xf7, 0x42, 0x27, 0x72, 0xc3, 0x75, 0x97, 0x29, 0xd0, 0xf9, 0xba, 0x79, 0x49, 0x7a, 0x5d, + 0xdc, 0x4c, 0x22, 0xec, 0xef, 0x96, 0x4e, 0x19, 0x05, 0x71, 0x97, 0xf9, 0x41, 0x82, 0xd3, 0x44, + 0xd3, 0xa9, 0xa9, 0x7a, 0x1e, 0x70, 0x6a, 0xaa, 0x86, 0x2b, 0xcc, 0x6e, 0xa4, 0x1b, 0x09, 0x7b, + 0xb6, 0xae, 0xa8, 0x52, 0xac, 0x61, 0xa0, 0x4f, 0x00, 0xd2, 0x73, 0x0b, 0x1a, 0xd1, 0x65, 0x9f, + 0xd9, 0xdb, 0x2d, 0xa1, 0xd5, 0x14, 0x74, 0x7f, 0xb7, 0x34, 0x49, 0x4b, 0x97, 0x3d, 0xfa, 0xfc, + 0x8d, 0x43, 0xf2, 0x65, 0x10, 0x42, 0x37, 0x61, 0x9c, 0x96, 0xb2, 0x1d, 0x25, 0x43, 0xd7, 0xf2, + 0x27, 0xeb, 0x53, 0x7b, 0xbb, 0xa5, 0xf1, 0xd5, 0x04, 0x2c, 0x8f, 0x74, 0x8a, 0x48, 0x46, 0x86, + 0xaa, 0x81, 0x6e, 0x33, 0x54, 0xd9, 0x9f, 0xb7, 0xe0, 0x04, 0xbd, 0xe0, 0x6a, 0x57, 0x73, 0xb4, + 0xe8, 0x4e, 0xd3, 0xe5, 0x7a, 0x1a, 0x71, 0xd5, 0x30, 0x59, 0x5d, 0x79, 0x99, 0x6b, 0x69, 0x14, + 0x94, 0x9e, 0xf0, 0x5b, 0xae, 0x57, 0x4b, 0x9e, 0xf0, 0x57, 0x5c, 0xaf, 0x86, 0x19, 0x44, 0x5d, + 0x59, 0xc5, 0xdc, 0x50, 0xf8, 0x5f, 0xa1, 0x7b, 0x95, 0xf6, 0xe5, 0x5b, 0xda, 0x0d, 0xf4, 0x94, + 0xae, 0x53, 0x15, 0xe6, 0x93, 0xb9, 0xfa, 0xd4, 0xcf, 0x59, 0x20, 0xbc, 0xdf, 0xbb, 0xb8, 0x93, + 0xdf, 0x84, 0xe1, 0xed, 0x74, 0xde, 0xd5, 0x33, 0xf9, 0xe1, 0x00, 0x44, 0xb6, 0x55, 0xc5, 0xa2, + 0x1b, 0x39, 0x56, 0x0d, 0x5a, 0x76, 0x0d, 0x04, 0x74, 0x81, 0x30, 0xad, 0x46, 0xe7, 0xde, 0x3c, + 0x0b, 0x50, 0x63, 0xb8, 0x2c, 0x19, 0x7b, 0xc1, 0xe4, 0xb8, 0x16, 0x14, 0x04, 0x6b, 0x58, 0xf6, + 0xcf, 0x15, 0x61, 0x48, 0xe6, 0xf9, 0x6c, 0x79, 0xdd, 0xc8, 0x1e, 0x0f, 0x94, 0xf8, 0x1f, 0xbd, + 0x05, 0x13, 0x01, 0xa9, 0xb6, 0x82, 0xd0, 0xdd, 0x26, 0x12, 0x2c, 0x36, 0xc9, 0x0c, 0xcf, 0xc4, + 0x90, 0x00, 0xee, 0xb3, 0x10, 0x59, 0x89, 0x42, 0xa6, 0x34, 0x4e, 0x13, 0x42, 0xe7, 0x61, 0x90, + 0x89, 0xde, 0xcb, 0xb1, 0x40, 0x58, 0x09, 0xbe, 0x56, 0x24, 0x00, 0xc7, 0x38, 0xec, 0x71, 0xd0, + 0xba, 0xc5, 0xd0, 0x13, 0x9e, 0xe0, 0x15, 0x5e, 0x8c, 0x25, 0x1c, 0x7d, 0x14, 0xc6, 0x79, 0xbd, + 0xc0, 0x6f, 0x3a, 0x1b, 0x5c, 0x25, 0xd8, 0xab, 0xc2, 0xeb, 0x8c, 0xaf, 0x24, 0x60, 0xfb, 0xbb, + 0xa5, 0x23, 0xc9, 0x32, 0xd6, 0xed, 0x14, 0x15, 0x66, 0xf9, 0xc7, 0x1b, 0xa1, 0x77, 0x46, 0xca, + 0x60, 0x30, 0x06, 0x61, 0x1d, 0xcf, 0xfe, 0x6b, 0x0b, 0x26, 0xb4, 0xa9, 0xea, 0x3a, 0x19, 0x86, + 0x31, 0x48, 0x85, 0x2e, 0x06, 0xe9, 0x60, 0xd1, 0x1e, 0x32, 0x67, 0xb8, 0xe7, 0x3e, 0xcd, 0xb0, + 0xfd, 0x29, 0x40, 0xe9, 0x24, 0xb2, 0xe8, 0x75, 0x6e, 0xc8, 0xef, 0x06, 0xa4, 0xd6, 0x4e, 0xe1, + 0xaf, 0x47, 0xce, 0x91, 0x9e, 0xab, 0xbc, 0x16, 0x56, 0xf5, 0xed, 0x1f, 0xec, 0x81, 0xf1, 0x64, + 0xac, 0x0e, 0x74, 0x19, 0xfa, 0x38, 0x97, 0x2e, 0xc8, 0xb7, 0xb1, 0x27, 0xd3, 0x22, 0x7c, 0x30, + 0x7e, 0x45, 0x30, 0xfa, 0xa2, 0x3e, 0x7a, 0x0b, 0x86, 0x6a, 0xfe, 0x6d, 0xef, 0xb6, 0x13, 0xd4, + 0x66, 0xcb, 0xcb, 0xe2, 0x84, 0xc8, 0x14, 0x40, 0x2d, 0xc4, 0x68, 0x7a, 0xd4, 0x10, 0x66, 0x3b, + 0x11, 0x83, 0xb0, 0x4e, 0x0e, 0xad, 0xb1, 0xbc, 0x48, 0xeb, 0xee, 0xc6, 0x8a, 0xd3, 0x6c, 0xe7, + 0xd5, 0x35, 0x2f, 0x91, 0x34, 0xca, 0x23, 0x22, 0x79, 0x12, 0x07, 0xe0, 0x98, 0x10, 0xfa, 0x0c, + 0x4c, 0x86, 0x39, 0x2a, 0xb1, 0xbc, 0x9c, 0xe2, 0xed, 0xb4, 0x44, 0x5c, 0x98, 0x92, 0xa5, 0x3c, + 0xcb, 0x6a, 0x06, 0xdd, 0x01, 0x24, 0x44, 0xcf, 0x6b, 0x41, 0x2b, 0x8c, 0xe6, 0x5a, 0x5e, 0xad, + 0x2e, 0xf3, 0x26, 0x7d, 0x30, 0x5b, 0x4e, 0x90, 0xc4, 0xd6, 0xda, 0x66, 0xb1, 0x7b, 0xd3, 0x18, + 0x38, 0xa3, 0x0d, 0xfb, 0x73, 0x3d, 0x30, 0x2d, 0xb3, 0x36, 0x67, 0x78, 0xaf, 0x7c, 0xd6, 0x4a, + 0xb8, 0xaf, 0xbc, 0x94, 0x7f, 0xd0, 0x3f, 0x30, 0x27, 0x96, 0x2f, 0xa4, 0x9d, 0x58, 0x5e, 0x39, + 0x60, 0x37, 0xee, 0x9b, 0x2b, 0xcb, 0x7b, 0xd6, 0xff, 0x64, 0xef, 0x08, 0x18, 0x57, 0x33, 0xc2, + 0x3c, 0x30, 0x7a, 0x59, 0xaa, 0x8e, 0x72, 0x9e, 0xff, 0x97, 0x05, 0x8e, 0x71, 0xd9, 0x0f, 0xcb, + 0xf0, 0xe9, 0xec, 0x9c, 0x55, 0x74, 0x28, 0x4d, 0xd2, 0x68, 0x46, 0x3b, 0x0b, 0x6e, 0x20, 0x7a, + 0x9c, 0x49, 0x73, 0x51, 0xe0, 0xa4, 0x69, 0x4a, 0x08, 0x56, 0x74, 0xd0, 0x36, 0x4c, 0x6c, 0xb0, + 0x88, 0x4f, 0x5a, 0x02, 0x65, 0x71, 0x2e, 0x64, 0xee, 0xdb, 0x4b, 0xf3, 0x8b, 0xf9, 0xd9, 0x96, + 0xf9, 0xe3, 0x2f, 0x85, 0x82, 0xd3, 0x4d, 0xd0, 0xad, 0x71, 0xc4, 0xb9, 0x1d, 0x2e, 0xd6, 0x9d, + 0x30, 0x72, 0xab, 0x73, 0x75, 0xbf, 0xba, 0x55, 0x89, 0xfc, 0x40, 0x66, 0x59, 0xcc, 0x7c, 0x7b, + 0xcd, 0xde, 0xac, 0xa4, 0xf0, 0x8d, 0xe6, 0xa7, 0xf6, 0x76, 0x4b, 0x47, 0xb2, 0xb0, 0x70, 0x66, + 0x5b, 0x68, 0x15, 0xfa, 0x37, 0xdc, 0x08, 0x93, 0xa6, 0x2f, 0x4e, 0x8b, 0xcc, 0xa3, 0xf0, 0x12, + 0x47, 0x31, 0x5a, 0x62, 0x11, 0xa9, 0x04, 0x00, 0x4b, 0x22, 0xe8, 0x75, 0x75, 0x09, 0xf4, 0xe5, + 0x0b, 0x60, 0xd3, 0xb6, 0x77, 0x99, 0xd7, 0xc0, 0xab, 0x50, 0xf4, 0xd6, 0xc3, 0x76, 0xb1, 0x78, + 0x56, 0x97, 0x0c, 0xf9, 0xd9, 0x5c, 0x3f, 0x7d, 0x1a, 0xaf, 0x2e, 0x55, 0x30, 0xad, 0xc8, 0xdc, + 0x5e, 0xc3, 0x6a, 0xe8, 0x8a, 0xac, 0x4e, 0x99, 0x5e, 0xc0, 0xcb, 0x95, 0xf9, 0xca, 0xb2, 0x41, + 0x83, 0x45, 0x35, 0x64, 0xc5, 0x98, 0x57, 0x47, 0x37, 0x60, 0x70, 0x83, 0x1f, 0x7c, 0xeb, 0xa1, + 0xc8, 0xdc, 0x9e, 0x79, 0x19, 0x5d, 0x92, 0x48, 0x06, 0x3d, 0x76, 0x65, 0x28, 0x10, 0x8e, 0x49, + 0xa1, 0xcf, 0x59, 0x70, 0x34, 0x99, 0xfa, 0x9e, 0x39, 0xab, 0x09, 0x33, 0xb5, 0x4c, 0x07, 0x80, + 0x72, 0x56, 0x05, 0xa3, 0x41, 0xa6, 0x7e, 0xc9, 0x44, 0xc3, 0xd9, 0xcd, 0xd1, 0x81, 0x0e, 0x6e, + 0xd5, 0xda, 0x25, 0x02, 0x4a, 0x04, 0x26, 0xe2, 0x03, 0x8d, 0xe7, 0x16, 0x30, 0xad, 0x88, 0xd6, + 0x00, 0xd6, 0xeb, 0x44, 0x44, 0x7c, 0x14, 0x46, 0x51, 0x99, 0xb7, 0xff, 0x92, 0xc2, 0x12, 0x74, + 0xd8, 0x4b, 0x34, 0x2e, 0xc5, 0x1a, 0x1d, 0xba, 0x94, 0xaa, 0xae, 0x57, 0x23, 0x01, 0x53, 0x6e, + 0xe5, 0x2c, 0xa5, 0x79, 0x86, 0x91, 0x5e, 0x4a, 0xbc, 0x1c, 0x0b, 0x0a, 0x8c, 0x16, 0x69, 0x6e, + 0xae, 0x87, 0xed, 0x52, 0x4e, 0xcc, 0x93, 0xe6, 0x66, 0x62, 0x41, 0x71, 0x5a, 0xac, 0x1c, 0x0b, + 0x0a, 0x74, 0xcb, 0xac, 0xd3, 0x0d, 0x44, 0x82, 0xa9, 0xb1, 0xfc, 0x2d, 0xb3, 0xc4, 0x51, 0xd2, + 0x5b, 0x46, 0x00, 0xb0, 0x24, 0x82, 0x3e, 0x69, 0x72, 0x3b, 0xe3, 0x8c, 0xe6, 0x53, 0x1d, 0xb8, + 0x1d, 0x83, 0x6e, 0x7b, 0x7e, 0xe7, 0x25, 0x28, 0xac, 0x57, 0x99, 0x52, 0x2c, 0x47, 0x67, 0xb0, + 0x34, 0x6f, 0x50, 0x63, 0x21, 0xdc, 0x97, 0xe6, 0x71, 0x61, 0xbd, 0x4a, 0x97, 0xbe, 0x73, 0xb7, + 0x15, 0x90, 0x25, 0xb7, 0x4e, 0x44, 0xfa, 0x89, 0xcc, 0xa5, 0x3f, 0x2b, 0x91, 0xd2, 0x4b, 0x5f, + 0x81, 0x70, 0x4c, 0x8a, 0xd2, 0x8d, 0x79, 0xb0, 0xc9, 0x7c, 0xba, 0x8a, 0xd5, 0x4a, 0xd3, 0xcd, + 0xe4, 0xc2, 0xb6, 0x60, 0x64, 0x3b, 0x6c, 0x6e, 0x12, 0x79, 0x2a, 0x32, 0x75, 0x5d, 0x4e, 0xa4, + 0x8a, 0x1b, 0x02, 0xd1, 0x0d, 0xa2, 0x96, 0x53, 0x4f, 0x1d, 0xe4, 0x4c, 0xb4, 0x72, 0x43, 0x27, + 0x86, 0x4d, 0xda, 0x74, 0x21, 0xbc, 0xcd, 0xc3, 0xc9, 0x31, 0xc5, 0x5d, 0xce, 0x42, 0xc8, 0x88, + 0x38, 0xc7, 0x17, 0x82, 0x00, 0x60, 0x49, 0x44, 0x0d, 0x36, 0xbb, 0x80, 0x8e, 0x75, 0x18, 0xec, + 0x54, 0x7f, 0xe3, 0xc1, 0x66, 0x17, 0x4e, 0x4c, 0x8a, 0x5d, 0x34, 0xcd, 0x4d, 0x3f, 0xf2, 0xbd, + 0xc4, 0x25, 0x77, 0x3c, 0xff, 0xa2, 0x29, 0x67, 0xe0, 0xa7, 0x2f, 0x9a, 0x2c, 0x2c, 0x9c, 0xd9, + 0x16, 0xfd, 0xb8, 0xa6, 0x8c, 0x0c, 0x28, 0x52, 0x64, 0x3c, 0x91, 0x13, 0x58, 0x33, 0x1d, 0x3e, + 0x90, 0x7f, 0x9c, 0x02, 0xe1, 0x98, 0x14, 0xaa, 0xc1, 0x68, 0xd3, 0x88, 0x38, 0xcb, 0x52, 0x7d, + 0xe4, 0xf0, 0x05, 0x59, 0xb1, 0x69, 0xb9, 0x84, 0xc8, 0x84, 0xe0, 0x04, 0x4d, 0x66, 0xb9, 0xc7, + 0x5d, 0xfd, 0x58, 0x26, 0x90, 0x9c, 0xa9, 0xce, 0xf0, 0x06, 0xe4, 0x53, 0x2d, 0x00, 0x58, 0x12, + 0xa1, 0xa3, 0x21, 0x1c, 0xd4, 0xfc, 0x90, 0x25, 0xd4, 0xc9, 0x53, 0xb0, 0x67, 0xa9, 0x89, 0x64, + 0x98, 0x75, 0x01, 0xc2, 0x31, 0x29, 0x7a, 0x92, 0xd3, 0x0b, 0xef, 0x64, 0xfe, 0x49, 0x9e, 0xbc, + 0xee, 0xd8, 0x49, 0x4e, 0x2f, 0xbb, 0xa2, 0xb8, 0xea, 0x54, 0x54, 0x70, 0x96, 0x0c, 0x24, 0xa7, + 0x5f, 0x2a, 0xac, 0x78, 0xba, 0x5f, 0x0a, 0x84, 0x63, 0x52, 0xec, 0x2a, 0x66, 0xa1, 0xe9, 0x4e, + 0xb7, 0xb9, 0x8a, 0x29, 0x42, 0xc6, 0x55, 0xac, 0x85, 0xae, 0xb3, 0x7f, 0xb0, 0x00, 0xa7, 0xdb, + 0xef, 0xdb, 0x58, 0x87, 0x56, 0x8e, 0x6d, 0x96, 0x12, 0x3a, 0x34, 0x2e, 0xd1, 0x89, 0xb1, 0xba, + 0x0e, 0x38, 0x7c, 0x09, 0x26, 0x94, 0x3b, 0x62, 0xdd, 0xad, 0xee, 0x68, 0x19, 0x40, 0x55, 0x68, + 0x9e, 0x4a, 0x12, 0x01, 0xa7, 0xeb, 0xa0, 0x59, 0x18, 0x33, 0x0a, 0x97, 0x17, 0xc4, 0xf3, 0x3f, + 0x4e, 0x63, 0x61, 0x82, 0x71, 0x12, 0xdf, 0xfe, 0x79, 0x0b, 0x8e, 0xe7, 0x24, 0x7b, 0xef, 0x3a, + 0x9e, 0xee, 0x3a, 0x8c, 0x35, 0xcd, 0xaa, 0x1d, 0x42, 0x80, 0x1b, 0x29, 0xe5, 0x55, 0x5f, 0x13, + 0x00, 0x9c, 0x24, 0x6a, 0xff, 0x6c, 0x01, 0x4e, 0xb5, 0xb5, 0xaf, 0x47, 0x18, 0x8e, 0x6d, 0x34, + 0x42, 0x67, 0x3e, 0x20, 0x35, 0xe2, 0x45, 0xae, 0x53, 0xaf, 0x34, 0x49, 0x55, 0xd3, 0x82, 0x32, + 0x43, 0xf5, 0x4b, 0x2b, 0x95, 0xd9, 0x34, 0x06, 0xce, 0xa9, 0x89, 0x96, 0x00, 0xa5, 0x21, 0x62, + 0x86, 0xd9, 0x13, 0x37, 0x4d, 0x0f, 0x67, 0xd4, 0x40, 0x2f, 0xc2, 0x88, 0xb2, 0xdb, 0xd7, 0x66, + 0x9c, 0x5d, 0x10, 0x58, 0x07, 0x60, 0x13, 0x0f, 0x5d, 0xe0, 0xf9, 0x8d, 0x44, 0x26, 0x2c, 0xa1, + 0x32, 0x1d, 0x93, 0xc9, 0x8b, 0x44, 0x31, 0xd6, 0x71, 0xe6, 0x2e, 0xfe, 0xee, 0x37, 0x4f, 0x7f, + 0xe0, 0x0f, 0xbe, 0x79, 0xfa, 0x03, 0x7f, 0xf4, 0xcd, 0xd3, 0x1f, 0xf8, 0x9e, 0xbd, 0xd3, 0xd6, + 0xef, 0xee, 0x9d, 0xb6, 0xfe, 0x60, 0xef, 0xb4, 0xf5, 0x47, 0x7b, 0xa7, 0xad, 0xff, 0xba, 0x77, + 0xda, 0xfa, 0xe2, 0x9f, 0x9e, 0xfe, 0xc0, 0x9b, 0x28, 0x8e, 0x50, 0x7d, 0x9e, 0xce, 0xce, 0xf9, + 0xed, 0x0b, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x96, 0xf6, 0xed, 0xcc, 0x28, 0x24, 0x01, 0x00, } func (m *AWSElasticBlockStoreVolumeSource) Marshal() (dAtA []byte, err error) { @@ -16322,6 +16323,13 @@ func (m *PodSecurityContext) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SELinuxChangePolicy != nil { + i -= len(*m.SELinuxChangePolicy) + copy(dAtA[i:], *m.SELinuxChangePolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SELinuxChangePolicy))) + i-- + dAtA[i] = 0x6a + } if m.SupplementalGroupsPolicy != nil { i -= len(*m.SupplementalGroupsPolicy) copy(dAtA[i:], *m.SupplementalGroupsPolicy) @@ -24885,6 +24893,10 @@ func (m *PodSecurityContext) Size() (n int) { l = len(*m.SupplementalGroupsPolicy) n += 1 + l + sovGenerated(uint64(l)) } + if m.SELinuxChangePolicy != nil { + l = len(*m.SELinuxChangePolicy) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -29187,6 +29199,7 @@ func (this *PodSecurityContext) String() string { `SeccompProfile:` + strings.Replace(this.SeccompProfile.String(), "SeccompProfile", "SeccompProfile", 1) + `,`, `AppArmorProfile:` + strings.Replace(this.AppArmorProfile.String(), "AppArmorProfile", "AppArmorProfile", 1) + `,`, `SupplementalGroupsPolicy:` + valueToStringGenerated(this.SupplementalGroupsPolicy) + `,`, + `SELinuxChangePolicy:` + valueToStringGenerated(this.SELinuxChangePolicy) + `,`, `}`, }, "") return s @@ -58122,6 +58135,39 @@ func (m *PodSecurityContext) Unmarshal(dAtA []byte) error { s := SupplementalGroupsPolicy(dAtA[iNdEx:postIndex]) m.SupplementalGroupsPolicy = &s iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SELinuxChangePolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := PodSELinuxChangePolicy(dAtA[iNdEx:postIndex]) + m.SELinuxChangePolicy = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/api/core/v1/generated.proto b/staging/src/k8s.io/api/core/v1/generated.proto index acd078320c6..268ac96f7d4 100644 --- a/staging/src/k8s.io/api/core/v1/generated.proto +++ b/staging/src/k8s.io/api/core/v1/generated.proto @@ -4038,6 +4038,33 @@ message PodSecurityContext { // Note that this field cannot be set when spec.os.name is windows. // +optional optional AppArmorProfile appArmorProfile = 11; + + // seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + // It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + // Valid values are "MountOption" and "Recursive". + // + // "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + // This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + // + // "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + // This requires all Pods that share the same volume to use the same SELinux label. + // It is not possible to share the same volume among privileged and unprivileged Pods. + // Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + // whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + // CSIDriver instance. Other volumes are always re-labelled recursively. + // "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + // + // If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + // If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + // and "Recursive" for all other volumes. + // + // This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + // + // All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + // Note that this field cannot be set when spec.os.name is windows. + // +featureGate=SELinuxChangePolicy + // +optional + optional string seLinuxChangePolicy = 13; } // Describes the class of pods that should avoid this node. diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index 637182c64d9..36bc2692614 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -4449,7 +4449,7 @@ type PodSecurityContext struct { // Note that this field cannot be set when spec.os.name is windows. // +featureGate=SELinuxChangePolicy // +optional - SELinuxChangePolicy *PodSELinuxChangePolicy `json:"seLinuxChangePolicy,omitempty" protobuf:"bytes,12,opt,name=seLinuxChangePolicy"` + SELinuxChangePolicy *PodSELinuxChangePolicy `json:"seLinuxChangePolicy,omitempty" protobuf:"bytes,13,opt,name=seLinuxChangePolicy"` } // SeccompProfile defines a pod/container's seccomp profile settings. diff --git a/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go index fa757adf181..6134e5dc7ee 100644 --- a/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -1772,6 +1772,7 @@ var map_PodSecurityContext = map[string]string{ "fsGroupChangePolicy": "fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used. Note that this field cannot be set when spec.os.name is windows.", "seccompProfile": "The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows.", "appArmorProfile": "appArmorProfile is the AppArmor options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows.", + "seLinuxChangePolicy": "seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. Valid values are \"MountOption\" and \"Recursive\".\n\n\"Recursive\" means relabeling of all files on all Pod volumes by the container runtime. This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n\"MountOption\" mounts all eligible Pod volumes with `-o context` mount option. This requires all Pods that share the same volume to use the same SELinux label. It is not possible to share the same volume among privileged and unprivileged Pods. Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their CSIDriver instance. Other volumes are always re-labelled recursively. \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\nIf not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used. If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes and \"Recursive\" for all other volumes.\n\nThis field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\nAll Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. Note that this field cannot be set when spec.os.name is windows.", } func (PodSecurityContext) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/core/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/core/v1/zz_generated.deepcopy.go index 3d23f7f620e..189aca8199d 100644 --- a/staging/src/k8s.io/api/core/v1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/core/v1/zz_generated.deepcopy.go @@ -4169,6 +4169,11 @@ func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) { *out = new(AppArmorProfile) (*in).DeepCopyInto(*out) } + if in.SELinuxChangePolicy != nil { + in, out := &in.SELinuxChangePolicy, &out.SELinuxChangePolicy + *out = new(PodSELinuxChangePolicy) + **out = **in + } return } diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.json index 9e6c849bc64..a6c89e2e507 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.json @@ -1437,7 +1437,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.pb index f5b24b295388d18c6bde9c7f4a3107dbd7a4c302..b75325807c5aa8e4a988d158ac8aed3c983c8088 100644 GIT binary patch delta 69 zcmZ1wx+`>oG}Fw`jj}0>%nt&&CNJRhWfnRU0OB(~+ib}kE6BW?iEHv{LA}YxMLzLo YNff90WagDtIA%*O(`CNJRhWfs~L0OB*A*=)%iE6BW%iEHv{LA}YxMLuo5 IEc#po00guXoB#j- diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.yaml index 8d775f771f8..b2fe097d004 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.yaml @@ -878,6 +878,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.json index 8b0df04cebc..f44ffb4bb93 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.json @@ -1438,7 +1438,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.pb index 408b95f7b1b3282604f404218cda2a4b3e660222..ddaa4b71e0835536d75e6c25f8b3ce1e0ad63ef1 100644 GIT binary patch delta 70 zcmV-M0J;CIRmWA3908@V9c2Lp=1~X%5|iy2O#>RtP_Z6l0RiT-JOf=31G@qWlg<$? clgbqG4{8{5WlU*qb$CN)VQyz-v#}NY6mP8=s{jB1 delta 54 zcmV-60LlNyRjpN!907~59c2Lp%uxsd5|beqO#>RTP_Z6l0RhajJOf=31EB&6lg<$? MlgbqGv(^>y6y%N)w*UYD diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.yaml index eb6bebd9187..ec8f334121b 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.yaml @@ -886,6 +886,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.json index e6a0f6f79fc..97d93e688b3 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.json @@ -1439,7 +1439,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.pb index 020723d6bab9c2fd5dba35d4945f52b402dcd9c2..957822aeb547b4c13d5fd37a849ea6e202a68f97 100644 GIT binary patch delta 70 zcmV-M0J;C#RPRtP_Z6l0RiT-JOf=31G@qWlg<$? clgbqG4{8{5WlU*qb$CN)VQyz-v#}Ma6oPjdm;e9( delta 54 zcmV-60LlOKRN7RK909no9c2LphfxRt5|beqO#>RTP_Z6l0RhajJOf=31EB&6lg<$? MlgbqGv(^=!6!TaTqyPW_ diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.yaml index a852a56d1a5..7db2694f606 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.yaml @@ -878,6 +878,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.json index 6608d495484..8130519907a 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.json @@ -1438,7 +1438,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.pb index 6d47234a484a57332c2384ab17fe8e383e2d7ffc..3137a439ffe60baafe488c4d4f381757ec618088 100644 GIT binary patch delta 70 zcmV-M0J;C|U58$f9RcLA9%TUqgjxsz5|h6xO#>RtP_Z9m0RiT-Jp)}41G@qWlg|+@ clgkwH4{8{5WlU*qb$CN)VQyz-v$7RC8EQHh(EtDd delta 54 zcmV-60LlM{UhQ3w9RbR*9%TUq>RAW@5|gnPO#>RTP_Z9m0RhajJp)}41EB&6lg|+@ MlgkwHv)2_c84KtW2LJ#7 diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.yaml index 0fa09f8eedf..7b747e00f90 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.yaml @@ -886,6 +886,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.json index 2737e8a9f80..9cedd55ad0a 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.json @@ -1438,7 +1438,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.pb index f21185b0b5890f2d9e1b0918fb55423271e8a61d..c8b30c7b194a8491c0f0f987a8db26714757afed 100644 GIT binary patch delta 66 zcmV-I0KNaVRnS$CAp)sYv)ln>0R`$&2mun4ff-E#8qBlX0c8OJ=CeTqT@eAhv!4_q Y0S{^zb7f3vZgqG=Xkl(=Wuvwg6(9K*TmS$7 delta 51 zcmV-30L=f;Rkl@-Ap(z8v)ln>0R_-e2mun4!4^#d8nUz70c8OJ%(FoQT@eAHv!4_q J0khi`^%UrZ5`h2! diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.yaml index 259b45ff4e0..2d2e5836dc8 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.yaml @@ -888,6 +888,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.json index 192270b2428..f382fc62f79 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.json @@ -1438,7 +1438,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.pb index b69ef85750d5294190aaff60bed06c31b53e1440..ca2576f57b25103da64197627b61d8094cdb68e8 100644 GIT binary patch delta 67 zcmV-J0KEV5U5s9kA_C-Hv)ut?0R@Cw2mun4{}@dI8qBlY0c8OJ=CeWrT@eAhv!E0r Z0S{^zb7f3vZgqG=Xkl(=WwW;xI~h*f7##or delta 51 zcmV-30L=f4Uh-X#A_B@?v)ut?0R`$=2mun4UJOkF8nUz80c8OJ%(FrRT@eAHv!E0r J0khl{Fd6JU5y$`l diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.yaml index 684f18bf47e..d85954d2f3d 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.yaml @@ -886,6 +886,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.json index 02a9ea37fea..bf085d4e203 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.json @@ -1437,7 +1437,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.pb index 6fbf0cad5917769eec7efc04d825678684c5796b..6a0fd96123f03c8d9736571afc19bf7f69c6fa11 100644 GIT binary patch delta 70 zcmV-M0J;CARlik`AOe|Hv)KV;0R!Ms3X|^{O#%|kv)BP;0RiT-J_B751G@qWlh6?^ clgt$I4{8{5WlU*qb$CN)VQyz-v$GZQ6tp%P^8f$< delta 52 zcmV-40L%ZsRi#ysAOinXv)KV;0RqNRld%_10kX5$0c8OJ%(FfNT@eGJ0t%DR5iXO= K6!Np!73UNyWfboK diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.yaml index 7113936cffc..fc59afcd925 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.yaml @@ -878,6 +878,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.json index a07a873505d..2081c9ac26d 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.json @@ -1438,7 +1438,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.pb index 602311a3526f6adfa3d445ba948ca55bfb5493a6..5a95130c796bfdf0c662ace90665fc7e29756cf8 100644 GIT binary patch delta 67 zcmV-J0KEUQRm@e8Ap)gUv)ln>0R`q!2mun4ff-E#8qBlX0c8OJ=CeTqT@eAhv!4_q Z0S{^zb7f3vZgqG=Xkl(=WwW*w{1i2}7*_xQ delta 51 zcmV-30L=f)RkBr(Ap(n4v)ln>0R_xa2mun4!4^#d8nUz70c8OJ%(FoQT@eAHv!4_q J0khi`@f78)5^Vqg diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.yaml index 8a8a41bdd91..947b24fb4d4 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.yaml @@ -886,6 +886,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.json index 884ec3f3459..677f0d6fd67 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.json @@ -1439,7 +1439,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.pb index f7251e4bf4c11ce6da6d61b138147b57d57e3da7..48cb5e6f60dc88245d5239377dc049d3e2e09ce1 100644 GIT binary patch delta 67 zcmV-J0KEU-RQXhpAp+7=v)ln>0R^E^2mun4ff-E#8qBlX0c8OJ=CeTqT@eAhv!4_q Z0S{^zb7f3vZgqG=Xkl(=WwW*wsT4>M7()O6 delta 51 zcmV-30L=gSRNqvPAp*Emv)ln>0R@Lq2mun4!4^#d8nUz70c8OJ%(FoQT@eAHv!4_q J0khi`o)q*J5?KHM diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.yaml index a23311cb66b..ebb64e03064 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.yaml @@ -878,6 +878,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.json b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.json index ac5df5bcebc..177b5b3c20a 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.json +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.json @@ -1438,7 +1438,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.pb b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.pb index 24ac839da4ca7dd1061d1c59b7ff69c7b41f6873..a17feb480f89798ba421bcd202616874b93c705e 100644 GIT binary patch delta 67 zcmV-J0KEV5U5s9kA_C-Hv)ut?0R@Cw2mun4{}@dI8qBlY0c8OJ=CeWrT@eAhv!E0r Z0S{^zb7f3vZgqG=Xkl(=WwW;xI~h*f7##or delta 51 zcmV-30L=f4Uh-X#A_B@?v)ut?0R`$=2mun4UJOkF8nUz80c8OJ%(FrRT@eAHv!E0r J0khl{Fd6JU5y$`l diff --git a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.yaml b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.yaml index 62ca88e65e2..2eff78ed0cd 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.yaml @@ -886,6 +886,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json index 6e31218a452..a562c92d1fe 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json +++ b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json @@ -1521,7 +1521,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.pb b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.pb index 7b46bd20ae7ec20de5bc76218c798a0a3d72bd29..012d2325a9971707b0b2ddf73b77c73d61d52138 100644 GIT binary patch delta 92 zcmewu*&Q`Ois^Oa<_(M~j7)7|lbaZI7>{mV&zQ={aX*NIQGiK;dGZ7)KUNJ!qcZ_u uRgBLzUtx(AWZuohH91XKZ*r2@C;lvn;#8l^ywVEijKsY3)XkpaD?|acU>`>S delta 75 zcmeB<`WQJuis@qH<_(M~j7)DrCpR(bFs|Obo-vh?<7f~EqX3fx^W^uueykddMw diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml index 8686f42531c..7b5008f31ff 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml @@ -938,6 +938,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json index 974e0d90235..661fbd423b8 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json +++ b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json @@ -1472,7 +1472,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.pb b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.pb index 6e53d582e10742637dfbab0fe64cd7b7ef3e1fac..9f1a340844b6c021517e790945399111e83d1c8e 100644 GIT binary patch delta 65 zcmV-H0KWhGR+U$f76JLO7i9qf-;;d-SOUyYu^40l0p_zj16>gVy8;T6&Jiw?$`tYs XY8Z26OlfX)ctdDmZf9k)u@%Y{G9DPr delta 49 zcmV-10M7rFSNm3w76IR}7i9qf#glyjSOT(8u^40l0nD>J16>gVp#ln%&Jiw?$`tam H))l`M&Fd1S diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml index 0cfdcea93fa..62f868d0c13 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml @@ -902,6 +902,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.json b/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.json index 8532d6e6c77..ec951ff67bb 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.json +++ b/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.json @@ -1521,7 +1521,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.pb b/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.pb index 58b2a586a1a3ea45e061d87ded56e2ebc52d2e4c..2e9cc214316b1f7ce542187ac6cf771986633782 100644 GIT binary patch delta 79 zcmewsIU#C-Jmc$)3aN}tZDEt!8FiSBhHg|$VPw2NS&BJ==}Z8a^KA1?mRLdN-Ar7Q hvxW60r;B~!&ypxk^~uaDt#Hmr%u7$*>?giL6aaUq97O;C delta 63 zcmbOb^(}IOJmbZU3aN}tZ$c-xGwLv{4&A7j!pL}ZvJ`U!)20A0=gj7tEU|*j3z@hk RXAA31P8a*MxmbLzC;;K67HI$g diff --git a/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.yaml b/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.yaml index df844e02e7d..542bc2ead14 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.yaml @@ -938,6 +938,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.json b/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.json index 6abff6ad6af..12b91a85fcf 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.json +++ b/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.json @@ -1379,7 +1379,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.pb b/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.pb index 96631251d04796e2c98a968627343480af6bef20..7be883eeac6f5f96adc04c675c01caa4d05e73f1 100644 GIT binary patch delta 66 zcmZ1;cQ8&c+oG6(i<66~%ut9qAU{QD^+v%|M#g8G%Nb(@nRhdBP39EPo6IWwi9buC WIMpXJue8EBBQY;Mb@LlxYiR(D9~8F$ delta 50 zcmX>Yw>(ZT+oG6(i<66~%ut9qAU{QD;zq$#M#eLn%Nb(@nHMr~O*WL(o6IWwX|te+ GfiwVY!43KV diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.yaml b/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.yaml index b154b298aa5..a76207e05eb 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.yaml @@ -834,6 +834,7 @@ spec: runAsGroup: 6 runAsNonRoot: true runAsUser: 2 + seLinuxChangePolicy: seLinuxChangePolicyValue seLinuxOptions: level: levelValue role: roleValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.json b/staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.json index 021ce494962..072f216ed86 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.json +++ b/staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.json @@ -1422,7 +1422,8 @@ "appArmorProfile": { "type": "typeValue", "localhostProfile": "localhostProfileValue" - } + }, + "seLinuxChangePolicy": "seLinuxChangePolicyValue" }, "imagePullSecrets": [ { diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.pb b/staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.pb index ff551bd183bf7d236ef7e50aa94fcb3c1e4adf08..3cc9b29777c97bab17e1e97efe958dab084af04f 100644 GIT binary patch delta 59 zcmdlMd?9#(1kRR910 delta 46 zcmV+}0MY--RIpT#A_9n1v#kMS0Rh*Oi2))3va_rKWdQ-qvl0Vc5dopIa1 Date: Tue, 8 Oct 2024 10:27:08 +0200 Subject: [PATCH 03/13] Add SELinuxChangePolicy validation --- pkg/api/pod/util.go | 34 +++++ pkg/api/pod/util_test.go | 141 ++++++++++++++++++++ pkg/apis/core/validation/validation.go | 31 +++++ pkg/apis/core/validation/validation_test.go | 76 +++++++++++ 4 files changed, 282 insertions(+) diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index 084e12b3bf0..03016151669 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -393,6 +393,8 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po opts.AllowRelaxedEnvironmentVariableValidation = useRelaxedEnvironmentVariableValidation(podSpec, oldPodSpec) opts.AllowRelaxedDNSSearchValidation = useRelaxedDNSSearchValidation(oldPodSpec) + opts.AllowOnlyRecursiveSELinuxChangePolicy = useOnlyRecursiveSELinuxChangePolicy(oldPodSpec) + if oldPodSpec != nil { // if old spec has status.hostIPs downwardAPI set, we must allow it opts.AllowHostIPsField = opts.AllowHostIPsField || hasUsedDownwardAPIFieldPathWithPodSpec(oldPodSpec, "status.hostIPs") @@ -723,6 +725,7 @@ func dropDisabledFields( dropPodLifecycleSleepAction(podSpec, oldPodSpec) dropImageVolumes(podSpec, oldPodSpec) + dropSELinuxChangePolicy(podSpec, oldPodSpec) } func dropPodLifecycleSleepAction(podSpec, oldPodSpec *api.PodSpec) { @@ -1361,3 +1364,34 @@ func imageVolumesInUse(podSpec *api.PodSpec) bool { return false } + +func dropSELinuxChangePolicy(podSpec, oldPodSpec *api.PodSpec) { + if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxChangePolicy) || seLinuxChangePolicyInUse(oldPodSpec) { + return + } + if podSpec == nil || podSpec.SecurityContext == nil { + return + } + podSpec.SecurityContext.SELinuxChangePolicy = nil +} + +func seLinuxChangePolicyInUse(podSpec *api.PodSpec) bool { + if podSpec == nil || podSpec.SecurityContext == nil { + return false + } + return podSpec.SecurityContext.SELinuxChangePolicy != nil +} + +func useOnlyRecursiveSELinuxChangePolicy(oldPodSpec *api.PodSpec) bool { + if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMount) { + // All policies are allowed + return false + } + + if seLinuxChangePolicyInUse(oldPodSpec) { + // The old pod spec has *any* policy: we need to keep that object update-able. + return false + } + // No feature gate + no value in the old object -> only Recursive is allowed + return true +} diff --git a/pkg/api/pod/util_test.go b/pkg/api/pod/util_test.go index a99deac1a4c..84985fa05ba 100644 --- a/pkg/api/pod/util_test.go +++ b/pkg/api/pod/util_test.go @@ -25,6 +25,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "k8s.io/component-base/featuregate" + "k8s.io/utils/ptr" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -3901,3 +3903,142 @@ func TestDropImageVolumes(t *testing.T) { }) } } + +func TestDropSELinuxChangePolicy(t *testing.T) { + podRecursive := &api.Pod{ + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{ + SELinuxChangePolicy: ptr.To(api.SELinuxChangePolicyRecursive), + }, + }, + } + podMountOption := &api.Pod{ + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{ + SELinuxChangePolicy: ptr.To(api.SELinuxChangePolicyMountOption), + }, + }, + } + podNull := &api.Pod{ + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{ + SELinuxChangePolicy: nil, + }, + }, + } + + tests := []struct { + name string + oldPod *api.Pod + newPod *api.Pod + gates []featuregate.Feature + wantPod *api.Pod + }{ + { + name: "no old pod, new pod with Recursive, all features disabled", + oldPod: nil, + newPod: podRecursive, + gates: nil, + wantPod: podNull, + }, + { + name: "no old pod, new pod with MountOption, all features disabled", + oldPod: nil, + newPod: podMountOption, + gates: nil, + wantPod: podNull, + }, + { + name: "old pod with Recursive, new pod with Recursive, all features disabled", + oldPod: podRecursive, + newPod: podRecursive, + gates: nil, + wantPod: podRecursive, + }, + { + name: "old pod with MountOption, new pod with Recursive, all features disabled", + oldPod: podMountOption, + newPod: podRecursive, + gates: nil, + wantPod: podRecursive, + }, + { + name: "no old pod, new pod with Recursive, SELinuxChangePolicy feature enabled", + oldPod: nil, + newPod: podRecursive, + gates: []featuregate.Feature{features.SELinuxChangePolicy}, + wantPod: podRecursive, + }, + { + name: "no old pod, new pod with MountOption, SELinuxChangePolicy feature enabled", + oldPod: nil, + newPod: podMountOption, + gates: []featuregate.Feature{features.SELinuxChangePolicy}, + wantPod: podMountOption, + }, + { + name: "old pod with Recursive, new pod with Recursive, SELinuxChangePolicy feature enabled", + oldPod: podRecursive, + newPod: podRecursive, + gates: []featuregate.Feature{features.SELinuxChangePolicy}, + wantPod: podRecursive, + }, + { + name: "old pod with MountOption, new pod with Recursive, SELinuxChangePolicy feature enabled", + oldPod: podMountOption, + newPod: podRecursive, + gates: []featuregate.Feature{features.SELinuxChangePolicy}, + wantPod: podRecursive, + }, + // In theory, SELinuxMount does not have any effect on dropping SELinuxChangePolicy field, but for completeness: + { + name: "no old pod, new pod with Recursive, SELinuxChangePolicy + SELinuxMount features enabled", + oldPod: nil, + newPod: podRecursive, + gates: []featuregate.Feature{features.SELinuxChangePolicy, features.SELinuxMount}, + wantPod: podRecursive, + }, + { + name: "no old pod, new pod with MountOption, SELinuxChangePolicy + SELinuxMount features enabled", + oldPod: nil, + newPod: podMountOption, + gates: []featuregate.Feature{features.SELinuxChangePolicy, features.SELinuxMount}, + wantPod: podMountOption, + }, + { + name: "old pod with Recursive, new pod with Recursive, SELinuxChangePolicy + SELinuxMount features enabled", + oldPod: podRecursive, + newPod: podRecursive, + gates: []featuregate.Feature{features.SELinuxChangePolicy, features.SELinuxMount}, + wantPod: podRecursive, + }, + { + name: "old pod with MountOption, new pod with Recursive, SELinuxChangePolicy + SELinuxMount features enabled", + oldPod: podMountOption, + newPod: podRecursive, + gates: []featuregate.Feature{features.SELinuxChangePolicy, features.SELinuxMount}, + wantPod: podRecursive, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + + for _, gate := range tc.gates { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, gate, true) + } + + oldPod := tc.oldPod.DeepCopy() + newPod := tc.newPod.DeepCopy() + DropDisabledPodFields(newPod, oldPod) + + // old pod should never be changed + if diff := cmp.Diff(oldPod, tc.oldPod); diff != "" { + t.Errorf("old pod changed: %s", diff) + } + + if diff := cmp.Diff(tc.wantPod, newPod); diff != "" { + t.Errorf("new pod changed (- want, + got): %s", diff) + } + }) + } +} diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index 3cb76ab2624..7d5527e881c 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -4058,6 +4058,8 @@ type PodValidationOptions struct { AllowRelaxedDNSSearchValidation bool // Allows zero value for Pod Lifecycle Sleep Action AllowPodLifecycleSleepActionZeroValue bool + // Allow only Recursive value of SELinuxChangePolicy. + AllowOnlyRecursiveSELinuxChangePolicy bool } // validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set, @@ -4356,6 +4358,9 @@ func validateWindows(spec *core.PodSpec, fldPath *field.Path) field.ErrorList { if securityContext.SupplementalGroupsPolicy != nil { allErrs = append(allErrs, field.Forbidden(fldPath.Child("securityContext").Child("supplementalGroupsPolicy"), "cannot be set for a windows pod")) } + if securityContext.SELinuxChangePolicy != nil { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("securityContext").Child("seLinuxChangePolicy"), "cannot be set for a windows pod")) + } } podshelper.VisitContainersWithPath(spec, fldPath, func(c *core.Container, cFldPath *field.Path) bool { // validate container security context @@ -4941,6 +4946,28 @@ func ValidateHostSysctl(sysctl string, securityContext *core.PodSecurityContext, return nil } +var validSELinuxChangePolicies = sets.New(core.SELinuxChangePolicyRecursive, core.SELinuxChangePolicyMountOption) + +func validateSELinuxChangePolicy(seLinuxChangePolicy *core.PodSELinuxChangePolicy, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { + if seLinuxChangePolicy == nil { + return nil + } + + allErrs := field.ErrorList{} + + if opts.AllowOnlyRecursiveSELinuxChangePolicy { + if *seLinuxChangePolicy != core.SELinuxChangePolicyRecursive { + allErrs = append(allErrs, field.NotSupported(fldPath, *seLinuxChangePolicy, []core.PodSELinuxChangePolicy{core.SELinuxChangePolicyRecursive})) + } + } else { + // Allow any valid SELinuxChangePolicy value. + if !validSELinuxChangePolicies.Has(*seLinuxChangePolicy) { + allErrs = append(allErrs, field.NotSupported(fldPath, *seLinuxChangePolicy, sets.List(validSELinuxChangePolicies))) + } + } + return allErrs +} + // validatePodSpecSecurityContext verifies the SecurityContext of a PodSpec, // whether that is defined in a Pod or in an embedded PodSpec (e.g. a // Deployment's pod template). @@ -4987,6 +5014,10 @@ func validatePodSpecSecurityContext(securityContext *core.PodSecurityContext, sp if securityContext.SupplementalGroupsPolicy != nil { allErrs = append(allErrs, validateSupplementalGroupsPolicy(securityContext.SupplementalGroupsPolicy, fldPath.Child("supplementalGroupsPolicy"))...) } + + if securityContext.SELinuxChangePolicy != nil { + allErrs = append(allErrs, validateSELinuxChangePolicy(securityContext.SELinuxChangePolicy, fldPath.Child("seLinuxChangePolicy"), opts)...) + } } return allErrs diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index d1649032573..a755f0cc8a4 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -20557,6 +20557,7 @@ func TestValidateOSFields(t *testing.T) { "SecurityContext.RunAsGroup", "SecurityContext.RunAsUser", "SecurityContext.SELinuxOptions", + "SecurityContext.SELinuxChangePolicy", "SecurityContext.SeccompProfile", "SecurityContext.ShareProcessNamespace", "SecurityContext.SupplementalGroups", @@ -25000,3 +25001,78 @@ func TestValidateContainerStatusAllocatedResourcesStatus(t *testing.T) { }) } } + +func TestValidateSELinuxChangePolicy(t *testing.T) { + tests := []struct { + name string + pod *core.Pod + allowOnlyRecursive bool + wantErrs field.ErrorList + }{ + { + name: "nil is valid", + pod: podtest.MakePod("pod", podtest.SetSecurityContext(&core.PodSecurityContext{ + SELinuxChangePolicy: nil, + })), + allowOnlyRecursive: false, + wantErrs: nil, + }, + { + name: "Recursive is always valid", + pod: podtest.MakePod("pod", podtest.SetSecurityContext(&core.PodSecurityContext{ + SELinuxChangePolicy: ptr.To(core.SELinuxChangePolicyRecursive), + })), + allowOnlyRecursive: false, + wantErrs: nil, + }, + { + name: "MountOption is not valid when AllowOnlyRecursiveSELinuxChangePolicy", + pod: podtest.MakePod("pod", podtest.SetSecurityContext(&core.PodSecurityContext{ + SELinuxChangePolicy: ptr.To(core.SELinuxChangePolicyMountOption), + })), + allowOnlyRecursive: true, + wantErrs: field.ErrorList{ + field.NotSupported( + field.NewPath("spec", "securityContext", "seLinuxChangePolicy"), + core.PodSELinuxChangePolicy("MountOption"), + []string{"Recursive"}), + }, + }, + { + name: "MountOption is valid when not AllowOnlyRecursiveSELinuxChangePolicy", + pod: podtest.MakePod("pod", podtest.SetSecurityContext(&core.PodSecurityContext{ + SELinuxChangePolicy: ptr.To(core.SELinuxChangePolicyMountOption), + })), + allowOnlyRecursive: false, + wantErrs: nil, + }, + { + name: "invalid value", + pod: podtest.MakePod("pod", podtest.SetSecurityContext(&core.PodSecurityContext{ + SELinuxChangePolicy: ptr.To(core.PodSELinuxChangePolicy("InvalidValue")), + })), + allowOnlyRecursive: false, + wantErrs: field.ErrorList{ + field.NotSupported(field.NewPath("spec", "securityContext", "seLinuxChangePolicy"), + core.PodSELinuxChangePolicy("InvalidValue"), + []string{"MountOption", "Recursive"}), + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + opts := PodValidationOptions{ + AllowOnlyRecursiveSELinuxChangePolicy: tc.allowOnlyRecursive, + } + errs := ValidatePodSpec(&tc.pod.Spec, &tc.pod.ObjectMeta, field.NewPath("spec"), opts) + if len(errs) == 0 { + errs = nil + } + if diff := cmp.Diff(tc.wantErrs, errs); diff != "" { + t.Errorf("unexpected field errors (-want, +got):\n%s", diff) + } + + }) + } +} From 8a400124f95c2afd481d910e2c4588049af26886 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 8 Oct 2024 13:22:47 +0200 Subject: [PATCH 04/13] Use SELinuxChangePolicy --- .../cache/desired_state_of_world.go | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world.go index 2262a6bf338..6cdf6ba641e 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world.go @@ -301,7 +301,7 @@ func (dsw *desiredStateOfWorld) AddPodToVolume( volumeName = util.GetUniqueVolumeNameFromSpecWithPod(podName, volumePlugin, volumeSpec) } - seLinuxFileLabel, pluginSupportsSELinuxContextMount, err := dsw.getSELinuxLabel(volumeSpec, seLinuxContainerContexts) + seLinuxFileLabel, pluginSupportsSELinuxContextMount, err := dsw.getSELinuxLabel(volumeSpec, seLinuxContainerContexts, pod.Spec.SecurityContext) if err != nil { return "", err } @@ -392,7 +392,7 @@ func (dsw *desiredStateOfWorld) AddPodToVolume( return volumeName, nil } -func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinuxContainerContexts []*v1.SELinuxOptions) (string, bool, error) { +func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinuxContainerContexts []*v1.SELinuxOptions, podSecurityContext *v1.PodSecurityContext) (string, bool, error) { var seLinuxFileLabel string var pluginSupportsSELinuxContextMount bool @@ -407,6 +407,20 @@ func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinux if err != nil { return "", false, err } + + if feature.DefaultFeatureGate.Enabled(features.SELinuxChangePolicy) && + podSecurityContext != nil && + podSecurityContext.SELinuxChangePolicy != nil && + *podSecurityContext.SELinuxChangePolicy == v1.SELinuxChangePolicyRecursive { + // The pod has opted into recursive SELinux label changes. Do not mount with -o context. + return "", pluginSupportsSELinuxContextMount, nil + } + + // Ignoring SELinuxMount feature gate: + // It allows value "SELinuxChangePolicy: MountOption" in the API server to be set. + // If the feature gate + field value is set in the API server, but the feature gate is disabled here in kubelet, + // kubelet would default to "", which means "MountOption" anyway. + seLinuxSupported := util.VolumeSupportsSELinuxMount(volumeSpec) if pluginSupportsSELinuxContextMount { // Ensure that a volume that can be mounted with "-o context=XYZ" is @@ -414,7 +428,7 @@ func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinux for _, containerContext := range seLinuxContainerContexts { newLabel, err := dsw.seLinuxTranslator.SELinuxOptionsToFileLabel(containerContext) if err != nil { - fullErr := fmt.Errorf("failed to construct SELinux label from context %q: %s", containerContext, err) + fullErr := fmt.Errorf("failed to construct SELinux label from context %q: %w", containerContext, err) accessMode := getVolumeAccessMode(volumeSpec) err := handleSELinuxMetricError( fullErr, From e4eedfe105ffa93a92a4afa490f62103fd26776e Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Wed, 9 Oct 2024 11:21:11 +0200 Subject: [PATCH 05/13] Refactor getSELinuxLabel Return early and reduce indentation --- .../cache/desired_state_of_world.go | 122 ++++++++---------- 1 file changed, 56 insertions(+), 66 deletions(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world.go index 6cdf6ba641e..e8563e4384a 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world.go @@ -393,75 +393,65 @@ func (dsw *desiredStateOfWorld) AddPodToVolume( } func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinuxContainerContexts []*v1.SELinuxOptions, podSecurityContext *v1.PodSecurityContext) (string, bool, error) { + if !feature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { + return "", false, nil + } + + if !dsw.seLinuxTranslator.SELinuxEnabled() { + return "", false, nil + } + + pluginSupportsSELinuxContextMount, err := dsw.getSELinuxMountSupport(volumeSpec) + if err != nil { + return "", false, err + } + + if feature.DefaultFeatureGate.Enabled(features.SELinuxChangePolicy) && + podSecurityContext != nil && + podSecurityContext.SELinuxChangePolicy != nil && + *podSecurityContext.SELinuxChangePolicy == v1.SELinuxChangePolicyRecursive { + // The pod has opted into recursive SELinux label changes. Do not mount with -o context. + return "", pluginSupportsSELinuxContextMount, nil + } + + if !pluginSupportsSELinuxContextMount { + return "", pluginSupportsSELinuxContextMount, nil + } + + seLinuxSupported := util.VolumeSupportsSELinuxMount(volumeSpec) var seLinuxFileLabel string - var pluginSupportsSELinuxContextMount bool - - if feature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { - var err error - - if !dsw.seLinuxTranslator.SELinuxEnabled() { - return "", false, nil - } - - pluginSupportsSELinuxContextMount, err = dsw.getSELinuxMountSupport(volumeSpec) + // Ensure that a volume that can be mounted with "-o context=XYZ" is + // used only by containers with the same SELinux contexts. + for _, containerContext := range seLinuxContainerContexts { + newLabel, err := dsw.seLinuxTranslator.SELinuxOptionsToFileLabel(containerContext) if err != nil { - return "", false, err - } - - if feature.DefaultFeatureGate.Enabled(features.SELinuxChangePolicy) && - podSecurityContext != nil && - podSecurityContext.SELinuxChangePolicy != nil && - *podSecurityContext.SELinuxChangePolicy == v1.SELinuxChangePolicyRecursive { - // The pod has opted into recursive SELinux label changes. Do not mount with -o context. - return "", pluginSupportsSELinuxContextMount, nil - } - - // Ignoring SELinuxMount feature gate: - // It allows value "SELinuxChangePolicy: MountOption" in the API server to be set. - // If the feature gate + field value is set in the API server, but the feature gate is disabled here in kubelet, - // kubelet would default to "", which means "MountOption" anyway. - - seLinuxSupported := util.VolumeSupportsSELinuxMount(volumeSpec) - if pluginSupportsSELinuxContextMount { - // Ensure that a volume that can be mounted with "-o context=XYZ" is - // used only by containers with the same SELinux contexts. - for _, containerContext := range seLinuxContainerContexts { - newLabel, err := dsw.seLinuxTranslator.SELinuxOptionsToFileLabel(containerContext) - if err != nil { - fullErr := fmt.Errorf("failed to construct SELinux label from context %q: %w", containerContext, err) - accessMode := getVolumeAccessMode(volumeSpec) - err := handleSELinuxMetricError( - fullErr, - seLinuxSupported, - seLinuxContainerContextWarnings.WithLabelValues(accessMode), - seLinuxContainerContextErrors.WithLabelValues(accessMode)) - if err != nil { - return "", false, err - } - } - if seLinuxFileLabel == "" { - seLinuxFileLabel = newLabel - continue - } - if seLinuxFileLabel != newLabel { - accessMode := getVolumeAccessMode(volumeSpec) - - fullErr := fmt.Errorf("volume %s is used with two different SELinux contexts in the same pod: %q, %q", volumeSpec.Name(), seLinuxFileLabel, newLabel) - err := handleSELinuxMetricError( - fullErr, - seLinuxSupported, - seLinuxPodContextMismatchWarnings.WithLabelValues(accessMode), - seLinuxPodContextMismatchErrors.WithLabelValues(accessMode)) - if err != nil { - return "", false, err - } - } + fullErr := fmt.Errorf("failed to construct SELinux label from context %q: %w", containerContext, err) + accessMode := getVolumeAccessMode(volumeSpec) + err := handleSELinuxMetricError( + fullErr, + seLinuxSupported, + seLinuxContainerContextWarnings.WithLabelValues(accessMode), + seLinuxContainerContextErrors.WithLabelValues(accessMode)) + if err != nil { + return "", false, err + } + } + if seLinuxFileLabel == "" { + seLinuxFileLabel = newLabel + continue + } + if seLinuxFileLabel != newLabel { + accessMode := getVolumeAccessMode(volumeSpec) + + fullErr := fmt.Errorf("volume %s is used with two different SELinux contexts in the same pod: %q, %q", volumeSpec.Name(), seLinuxFileLabel, newLabel) + err := handleSELinuxMetricError( + fullErr, + seLinuxSupported, + seLinuxPodContextMismatchWarnings.WithLabelValues(accessMode), + seLinuxPodContextMismatchErrors.WithLabelValues(accessMode)) + if err != nil { + return "", false, err } - } else { - // Volume plugin does not support SELinux context mount. - // DSW will track this volume with SELinux label "", i.e. no mount with - // -o context. - seLinuxFileLabel = "" } } return seLinuxFileLabel, pluginSupportsSELinuxContextMount, nil From db3d995c2af577dc646b7af10bf4504ab570d3e6 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 15 Oct 2024 10:46:02 +0200 Subject: [PATCH 06/13] Refactor AddPodToVolume unit tests with a single pod Refactor existing tests that run AddPodToVolume with a single pod / volume to a table. And add few extra tests, covering existing ReadWriteOncePod functionality. --- .../cache/desired_state_of_world_test.go | 319 +++++++++--------- 1 file changed, 155 insertions(+), 164 deletions(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go index 569d5ac48c2..46bb634485b 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/component-base/featuregate" featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" @@ -605,170 +606,6 @@ func Test_AddPodToVolume_WithEmptyDirSizeLimit(t *testing.T) { verifyDesiredSizeLimitInVolumeDsw(t, pod2Name, pod2DesiredSizeLimitMap, dsw) } -// Calls AddPodToVolume() with a volume that support SELinux, but is ReadWriteMany. -// Verifies newly added pod/volume exists via PodExistsInVolume() without SELinux context -// VolumeExists() and GetVolumesToMount() and no errors. -func Test_AddPodToVolume_Positive_SELinuxNoRWOP(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) - // Arrange - plugins := []volume.VolumePlugin{ - &volumetesting.FakeDeviceMountableVolumePlugin{ - FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{ - Plugin: volumetesting.FakeVolumePlugin{ - PluginName: "basic", - SupportsSELinux: true, - }, - }, - }, - } - volumePluginMgr := volume.VolumePluginMgr{} - fakeVolumeHost := volumetesting.NewFakeVolumeHost(t, - "", /* rootDir */ - nil, /* kubeClient */ - nil, /* plugins */ - ) - volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost) - seLinuxTranslator := util.NewFakeSELinuxLabelTranslator() - dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator) - seLinux := v1.SELinuxOptions{ - User: "system_u", - Role: "object_r", - Type: "container_t", - Level: "s0:c1,c2", - } - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - UID: "pod1uid", - }, - Spec: v1.PodSpec{ - SecurityContext: &v1.PodSecurityContext{ - SELinuxOptions: &seLinux, - }, - Volumes: []v1.Volume{ - { - Name: "volume-name", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "myClaim", - }, - }, - }, - }, - }, - } - - volumeSpec := &volume.Spec{ - PersistentVolume: &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basicPV", - }, - Spec: v1.PersistentVolumeSpec{ - AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteMany}, - }, - }, - } - podName := util.GetUniquePodName(pod) - seLinuxContainerContexts := []*v1.SELinuxOptions{&seLinux} - - // Act - generatedVolumeName, err := dsw.AddPodToVolume( - podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) - - // Assert - if err != nil { - t.Fatalf("AddPodToVolume failed. Expected: Actual: <%v>", err) - } - - verifyVolumeExistsDsw(t, generatedVolumeName, "" /* SELinux */, dsw) - verifyVolumeExistsInVolumesToMount( - t, generatedVolumeName, false /* expectReportedInUse */, dsw) - verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "" /* SELinux */, dsw) - verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw) -} - -// Calls AddPodToVolume() with a volume that does not support SELinux. -// Verifies newly added pod/volume exists via PodExistsInVolume() without SELinux context -// VolumeExists() and GetVolumesToMount() and no errors. -func Test_AddPodToVolume_Positive_NoSELinuxPlugin(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) - // Arrange - plugins := []volume.VolumePlugin{ - &volumetesting.FakeDeviceMountableVolumePlugin{ - FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{ - Plugin: volumetesting.FakeVolumePlugin{ - PluginName: "basic", - SupportsSELinux: false, - }, - }, - }, - } - volumePluginMgr := volume.VolumePluginMgr{} - fakeVolumeHost := volumetesting.NewFakeVolumeHost(t, - "", /* rootDir */ - nil, /* kubeClient */ - nil, /* plugins */ - ) - volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost) - seLinuxTranslator := util.NewFakeSELinuxLabelTranslator() - dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator) - seLinux := v1.SELinuxOptions{ - User: "system_u", - Role: "object_r", - Type: "container_t", - Level: "s0:c1,c2", - } - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - UID: "pod1uid", - }, - Spec: v1.PodSpec{ - SecurityContext: &v1.PodSecurityContext{ - SELinuxOptions: &seLinux, - }, - Volumes: []v1.Volume{ - { - Name: "volume-name", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "myClaim", - }, - }, - }, - }, - }, - } - - volumeSpec := &volume.Spec{ - PersistentVolume: &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basicPV", - }, - Spec: v1.PersistentVolumeSpec{ - AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, - }, - }, - } - podName := util.GetUniquePodName(pod) - seLinuxContainerContexts := []*v1.SELinuxOptions{&seLinux} - - // Act - generatedVolumeName, err := dsw.AddPodToVolume( - podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) - - // Assert - if err != nil { - t.Fatalf("AddPodToVolume failed. Expected: Actual: <%v>", err) - } - - verifyVolumeExistsDsw(t, generatedVolumeName, "" /* SELinux */, dsw) - verifyVolumeExistsInVolumesToMount( - t, generatedVolumeName, false /* expectReportedInUse */, dsw) - verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "" /* SELinux */, dsw) - verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw) -} - // Calls AddPodToVolume() twice to add two pods with the same SELinuxContext // to the same ReadWriteOncePod PV. // Verifies newly added pod/volume exists via PodExistsInVolume() @@ -978,6 +815,160 @@ func Test_AddPodToVolume_Negative_ExistingPodDifferentSELinuxRWOP(t *testing.T) verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) } +// Calls AddPodToVolume() in an empty DSW with various SELinux settings / access modes. +func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { + completeSELinuxOpts := v1.SELinuxOptions{ + User: "system_u", + Role: "object_r", + Type: "container_t", + Level: "s0:c1,c2", + } + completeSELinuxLabel := "system_u:object_r:container_file_t:s0:c1,c2" + + incompleteSELinuxOpts := v1.SELinuxOptions{ + Level: "s0:c1,c2", + } + + tests := []struct { + name string + featureGates []featuregate.Feature + volumePluginSupportsSELinux bool + volumeAccessMode v1.PersistentVolumeAccessMode + podSELinuxOptions *v1.SELinuxOptions + + expectError bool + expectedSELinuxLabel string + }{ + { + name: "ReadWriteOncePod with plugin that supports SELinux mount", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "ReadWriteOncePod incomplete SELinuxOptions", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &incompleteSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, // kubelet files the missing SELinuxOptions fields + }, + { + name: "ReadWriteOncePod with plugin that does not support SELinux mount", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumePluginSupportsSELinux: false, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: "", // The plugin does not support SELinux + }, + { + name: "ReadWriteMany with plugin that supports SELinux mount", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: "", // The plugin does not support SELinux + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + for _, feature := range tc.featureGates { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, feature, true) + } + // Arrange + plugins := []volume.VolumePlugin{ + &volumetesting.FakeDeviceMountableVolumePlugin{ + FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{ + Plugin: volumetesting.FakeVolumePlugin{ + PluginName: "basic", + SupportsSELinux: tc.volumePluginSupportsSELinux, + }, + }, + }, + } + volumePluginMgr := volume.VolumePluginMgr{} + fakeVolumeHost := volumetesting.NewFakeVolumeHost(t, + "", /* rootDir */ + nil, /* kubeClient */ + nil, /* plugins */ + ) + err := volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost) + if err != nil { + t.Fatalf("Failed to init volume plugins: %v", err) + } + seLinuxTranslator := util.NewFakeSELinuxLabelTranslator() + dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator) + + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + UID: "pod1uid", + }, + Spec: v1.PodSpec{ + SecurityContext: &v1.PodSecurityContext{ + SELinuxOptions: tc.podSELinuxOptions, + }, + Volumes: []v1.Volume{ + { + Name: "volume-name", + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: "myClaim", + }, + }, + }, + }, + }, + } + + volumeSpec := &volume.Spec{ + PersistentVolume: &v1.PersistentVolume{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basicPV", + }, + Spec: v1.PersistentVolumeSpec{ + AccessModes: []v1.PersistentVolumeAccessMode{tc.volumeAccessMode}, + }, + }, + } + podName := util.GetUniquePodName(pod) + seLinuxContainerContexts := []*v1.SELinuxOptions{tc.podSELinuxOptions} + + // Act + generatedVolumeName, err := dsw.AddPodToVolume( + podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) + + // Assert + if tc.expectError { + if err == nil { + t.Errorf("Expected AddPodToVolume to return error, got nil") + } + return + } + if err != nil { + t.Fatalf("AddPodToVolume failed. Expected: Actual: %v", err) + } + + verifyVolumeExistsDsw(t, generatedVolumeName, tc.expectedSELinuxLabel, dsw) + verifyVolumeExistsInVolumesToMount( + t, generatedVolumeName, false /* expectReportedInUse */, dsw) + verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, tc.expectedSELinuxLabel, dsw) + verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw) + }) + } +} + func verifyVolumeExistsDsw( t *testing.T, expectedVolumeName v1.UniqueVolumeName, expectedSELinuxContext string, dsw DesiredStateOfWorld) { volumeExists := dsw.VolumeExists(expectedVolumeName, expectedSELinuxContext) From db353e04852d030c5704fae274b790f96282453f Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 15 Oct 2024 11:11:17 +0200 Subject: [PATCH 07/13] Refactor AddPodToVolume unit tests with multiple pods Refactor existing tests that run AddPodToVolume with multiple pods to a table. --- .../cache/desired_state_of_world_test.go | 379 ++++++++---------- 1 file changed, 170 insertions(+), 209 deletions(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go index 46bb634485b..07f8f12e681 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go @@ -606,215 +606,6 @@ func Test_AddPodToVolume_WithEmptyDirSizeLimit(t *testing.T) { verifyDesiredSizeLimitInVolumeDsw(t, pod2Name, pod2DesiredSizeLimitMap, dsw) } -// Calls AddPodToVolume() twice to add two pods with the same SELinuxContext -// to the same ReadWriteOncePod PV. -// Verifies newly added pod/volume exists via PodExistsInVolume() -// VolumeExists() and GetVolumesToMount() and no errors. -func Test_AddPodToVolume_Positive_ExistingPodSameSELinuxRWOP(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) - // Arrange - plugins := []volume.VolumePlugin{ - &volumetesting.FakeDeviceMountableVolumePlugin{ - FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{ - Plugin: volumetesting.FakeVolumePlugin{ - PluginName: "basic", - SupportsSELinux: true, - }, - }, - }, - } - volumePluginMgr := volume.VolumePluginMgr{} - fakeVolumeHost := volumetesting.NewFakeVolumeHost(t, - "", /* rootDir */ - nil, /* kubeClient */ - nil, /* plugins */ - ) - volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost) - seLinuxTranslator := util.NewFakeSELinuxLabelTranslator() - dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator) - seLinux := v1.SELinuxOptions{ - User: "system_u", - Role: "object_r", - Type: "container_t", - Level: "s0:c1,c2", - } - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - UID: "pod1uid", - }, - Spec: v1.PodSpec{ - SecurityContext: &v1.PodSecurityContext{ - SELinuxOptions: &seLinux, - }, - Volumes: []v1.Volume{ - { - Name: "volume-name", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "myClaim", - }, - }, - }, - }, - }, - } - - volumeSpec := &volume.Spec{ - PersistentVolume: &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basicPV", - }, - Spec: v1.PersistentVolumeSpec{ - AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, - }, - }, - } - podName := util.GetUniquePodName(pod) - seLinuxContainerContexts := []*v1.SELinuxOptions{&seLinux} - - // Act - generatedVolumeName, err := dsw.AddPodToVolume( - podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) - - // Assert - if err != nil { - t.Fatalf("AddPodToVolume failed. Expected: Actual: <%v>", err) - } - - verifyVolumeExistsDsw(t, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) - verifyVolumeExistsInVolumesToMount( - t, generatedVolumeName, false /* expectReportedInUse */, dsw) - verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) - verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw) - - // Arrange: prepare a different pod with the same context - pod2 := pod.DeepCopy() - pod2.Name = "pod2" - pod2.UID = "pod2uid" - pod2Name := util.GetUniquePodName(pod) - - // Act - generatedVolumeName2, err := dsw.AddPodToVolume( - pod2Name, pod2, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) - // Assert - if err != nil { - t.Fatalf("Second AddPodToVolume failed. Expected: Actual: <%v>", err) - } - if generatedVolumeName2 != generatedVolumeName { - t.Errorf("Expected second generatedVolumeName %s, got %s", generatedVolumeName, generatedVolumeName2) - } - - verifyPodExistsInVolumeDsw(t, pod2Name, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) -} - -// Calls AddPodToVolume() twice to add two pods with different SELinuxContext -// to the same ReadWriteOncePod PV. -// Verifies newly added pod/volume exists via PodExistsInVolume() -// VolumeExists() and GetVolumesToMount() and no errors. -func Test_AddPodToVolume_Negative_ExistingPodDifferentSELinuxRWOP(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) - // Arrange - plugins := []volume.VolumePlugin{ - &volumetesting.FakeDeviceMountableVolumePlugin{ - FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{ - Plugin: volumetesting.FakeVolumePlugin{ - PluginName: "basic", - SupportsSELinux: true, - }, - }, - }, - } - volumePluginMgr := volume.VolumePluginMgr{} - fakeVolumeHost := volumetesting.NewFakeVolumeHost(t, - "", /* rootDir */ - nil, /* kubeClient */ - nil, /* plugins */ - ) - volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost) - seLinuxTranslator := util.NewFakeSELinuxLabelTranslator() - dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator) - seLinux1 := v1.SELinuxOptions{ - User: "system_u", - Role: "object_r", - Type: "container_t", - Level: "s0:c1,c2", - } - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - UID: "pod1uid", - }, - Spec: v1.PodSpec{ - SecurityContext: &v1.PodSecurityContext{ - SELinuxOptions: &seLinux1, - }, - Volumes: []v1.Volume{ - { - Name: "volume-name", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "myClaim", - }, - }, - }, - }, - }, - } - - volumeSpec := &volume.Spec{ - PersistentVolume: &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basicPV", - }, - Spec: v1.PersistentVolumeSpec{ - AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, - }, - }, - } - podName := util.GetUniquePodName(pod) - seLinuxContainerContexts := []*v1.SELinuxOptions{&seLinux1} - - // Act - generatedVolumeName, err := dsw.AddPodToVolume( - podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) - - // Assert - if err != nil { - t.Fatalf("AddPodToVolume failed. Expected: Actual: <%v>", err) - } - - verifyVolumeExistsDsw(t, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) - verifyVolumeExistsInVolumesToMount( - t, generatedVolumeName, false /* expectReportedInUse */, dsw) - verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) - verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw) - - // Arrange: prepare a different pod with the same context - seLinux2 := v1.SELinuxOptions{ - User: "system_u", - Role: "object_r", - Type: "container_t", - Level: "s0:c3,c4", - } - seLinuxContainerContexts2 := []*v1.SELinuxOptions{&seLinux2} - pod2 := pod.DeepCopy() - pod2.Name = "pod2" - pod2.UID = "pod2uid" - pod2.Spec.SecurityContext.SELinuxOptions = &seLinux2 - pod2Name := util.GetUniquePodName(pod2) - - // Act - _, err = dsw.AddPodToVolume( - pod2Name, pod2, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts2) - // Assert - if err == nil { - t.Fatalf("Second AddPodToVolume succeeded, expected a failure") - } - // Verify the original SELinux context is still in DSW - verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw) -} - // Calls AddPodToVolume() in an empty DSW with various SELinux settings / access modes. func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { completeSELinuxOpts := v1.SELinuxOptions{ @@ -969,6 +760,176 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { } } +// Calls AddPodToVolume() twice to add two pods with various SELinux settings and access modes. +func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { + completeSELinuxOpts := v1.SELinuxOptions{ + User: "system_u", + Role: "object_r", + Type: "container_t", + Level: "s0:c1,c2", + } + completeSELinuxLabel := "system_u:object_r:container_file_t:s0:c1,c2" + conflictingSELinuxOpts := v1.SELinuxOptions{ + User: "system_u", + Role: "object_r", + Type: "container_t", + Level: "s0:c98,c99", + } + + tests := []struct { + name string + featureGates []featuregate.Feature + volumeAccessMode v1.PersistentVolumeAccessMode + firstPodSELinuxOptions *v1.SELinuxOptions + secondPodSELinuxOptions *v1.SELinuxOptions + + expectError bool + expectedSELinuxLabel string + }{ + { + // Note: this is not a realistic scenario, two Pods can't use the same RWOP volume. + // But from AddPodToVolume perspective, it tests how SELinux is handled even for RWO / RWX volumes. + name: "ReadWriteOncePod with the same SELinux options", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + // Note: this is not a realistic scenario, two Pods can't use the same RWOP volume. + // But from AddPodToVolume perspective, it tests how SELinux is handled even for RWO / RWX volumes. + name: "ReadWriteOncePod with conflicting SELinux options", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &conflictingSELinuxOpts, + + expectError: true, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "ReadWriteMany with the same SELinux options", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: "", // RWX does not support SELinux mount (yet) + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + for _, feature := range tc.featureGates { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, feature, true) + } + // Arrange + plugins := []volume.VolumePlugin{ + &volumetesting.FakeDeviceMountableVolumePlugin{ + FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{ + Plugin: volumetesting.FakeVolumePlugin{ + PluginName: "basic", + SupportsSELinux: true, + }, + }, + }, + } + volumePluginMgr := volume.VolumePluginMgr{} + fakeVolumeHost := volumetesting.NewFakeVolumeHost(t, + "", /* rootDir */ + nil, /* kubeClient */ + nil, /* plugins */ + ) + err := volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost) + if err != nil { + t.Fatalf("Failed to init volume plugins: %v", err) + } + seLinuxTranslator := util.NewFakeSELinuxLabelTranslator() + dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + UID: "pod1uid", + }, + Spec: v1.PodSpec{ + SecurityContext: &v1.PodSecurityContext{ + SELinuxOptions: tc.firstPodSELinuxOptions, + }, + Volumes: []v1.Volume{ + { + Name: "volume-name", + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: "myClaim", + }, + }, + }, + }, + }, + } + + volumeSpec := &volume.Spec{ + PersistentVolume: &v1.PersistentVolume{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basicPV", + }, + Spec: v1.PersistentVolumeSpec{ + AccessModes: []v1.PersistentVolumeAccessMode{tc.volumeAccessMode}, + }, + }, + } + podName := util.GetUniquePodName(pod) + seLinuxContainerContexts := []*v1.SELinuxOptions{tc.firstPodSELinuxOptions} + + // Act + generatedVolumeName, err := dsw.AddPodToVolume( + podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) + + // Assert + if err != nil { + t.Fatalf("AddPodToVolume failed. Expected: Actual: <%v>", err) + } + + verifyVolumeExistsDsw(t, generatedVolumeName, tc.expectedSELinuxLabel, dsw) + verifyVolumeExistsInVolumesToMount( + t, generatedVolumeName, false /* expectReportedInUse */, dsw) + verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, tc.expectedSELinuxLabel, dsw) + verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw) + + // Arrange: prepare a different pod with the same context + pod2 := pod.DeepCopy() + pod2.Name = "pod2" + pod2.UID = "pod2uid" + pod2.Spec.SecurityContext.SELinuxOptions = tc.secondPodSELinuxOptions + pod2Name := util.GetUniquePodName(pod2) + seLinuxContainerContexts = []*v1.SELinuxOptions{tc.secondPodSELinuxOptions} + + // Act + generatedVolumeName2, err := dsw.AddPodToVolume( + pod2Name, pod2, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts) + // Assert + if tc.expectError { + if err == nil { + t.Errorf("Expected AddPodToVolume to return error, got nil") + } + // Verify the original SELinux context is still in DSW + verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, tc.expectedSELinuxLabel, dsw) + return + } + if err != nil { + t.Fatalf("Second AddPodToVolume failed. Expected: Actual: %v", err) + } + if generatedVolumeName2 != generatedVolumeName { + t.Errorf("Expected second generatedVolumeName %s, got %s", generatedVolumeName, generatedVolumeName2) + } + verifyPodExistsInVolumeDsw(t, pod2Name, generatedVolumeName, tc.expectedSELinuxLabel, dsw) + }) + } +} + func verifyVolumeExistsDsw( t *testing.T, expectedVolumeName v1.UniqueVolumeName, expectedSELinuxContext string, dsw DesiredStateOfWorld) { volumeExists := dsw.VolumeExists(expectedVolumeName, expectedSELinuxContext) From 89da53cdeb00859a581483443dafd04cb196f059 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 15 Oct 2024 11:12:34 +0200 Subject: [PATCH 08/13] Add SELinuxChangePolicy tests --- .../cache/desired_state_of_world_test.go | 194 ++++++++++++++++-- 1 file changed, 181 insertions(+), 13 deletions(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go index 07f8f12e681..1f4319fd43d 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go @@ -30,6 +30,7 @@ import ( volumetesting "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/kubernetes/pkg/volume/util" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" + "k8s.io/utils/ptr" ) // Calls AddPodToVolume() to add new pod to new volume @@ -626,12 +627,13 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { volumePluginSupportsSELinux bool volumeAccessMode v1.PersistentVolumeAccessMode podSELinuxOptions *v1.SELinuxOptions + podChangePolicy *v1.PodSELinuxChangePolicy expectError bool expectedSELinuxLabel string }{ { - name: "ReadWriteOncePod with plugin that supports SELinux mount", + name: "RWOP: ReadWriteOncePod with plugin that supports SELinux mount", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumePluginSupportsSELinux: true, volumeAccessMode: v1.ReadWriteOncePod, @@ -641,7 +643,7 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { expectedSELinuxLabel: completeSELinuxLabel, }, { - name: "ReadWriteOncePod incomplete SELinuxOptions", + name: "RWOP: ReadWriteOncePod incomplete SELinuxOptions", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumePluginSupportsSELinux: true, volumeAccessMode: v1.ReadWriteOncePod, @@ -651,7 +653,17 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { expectedSELinuxLabel: completeSELinuxLabel, // kubelet files the missing SELinuxOptions fields }, { - name: "ReadWriteOncePod with plugin that does not support SELinux mount", + name: "RWOP: ReadWriteOncePod no SELinuxOptions", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: nil, + + expectError: false, + expectedSELinuxLabel: "", + }, + { + name: "RWOP: ReadWriteOncePod with plugin that does not support SELinux mount", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumePluginSupportsSELinux: false, volumeAccessMode: v1.ReadWriteOncePod, @@ -661,14 +673,73 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { expectedSELinuxLabel: "", // The plugin does not support SELinux }, { - name: "ReadWriteMany with plugin that supports SELinux mount", + name: "RWOP: ReadWriteMany with plugin that supports SELinux mount", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumePluginSupportsSELinux: true, volumeAccessMode: v1.ReadWriteMany, podSELinuxOptions: &completeSELinuxOpts, expectError: false, - expectedSELinuxLabel: "", // The plugin does not support SELinux + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with the default policy", + // Enabled SELinuxChangePolicy does not change anything from when RWOP is enabled + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: nil, // emphasize the default value + + expectError: false, + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with Recursive policy", + // Enabled SELinuxChangePolicy does not change anything from when RWOP is enabled + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with MountOption policy", + // Enabled SELinuxChangePolicy does not change anything from when RWOP is enabled + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: "", // still not supported for RWX + }, + { + name: "RWOP+ChangePolicy: ReadWriteOncePod with Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", // "Recursive" is applied to RWOP volumes + }, + { + name: "RWOP+ChangePolicy: ReadWriteOncePod with MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &completeSELinuxOpts, + // This can happen when there is a version skew between kubelet and the API server + podChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, // the policy is ignored, but mounting with SELinux is the default }, } @@ -708,7 +779,8 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { }, Spec: v1.PodSpec{ SecurityContext: &v1.PodSecurityContext{ - SELinuxOptions: tc.podSELinuxOptions, + SELinuxOptions: tc.podSELinuxOptions, + SELinuxChangePolicy: tc.podChangePolicy, }, Volumes: []v1.Volume{ { @@ -782,14 +854,16 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { volumeAccessMode v1.PersistentVolumeAccessMode firstPodSELinuxOptions *v1.SELinuxOptions secondPodSELinuxOptions *v1.SELinuxOptions + firstChangePolicy *v1.PodSELinuxChangePolicy + secondChangePolicy *v1.PodSELinuxChangePolicy expectError bool expectedSELinuxLabel string }{ { - // Note: this is not a realistic scenario, two Pods can't use the same RWOP volume. + // Note: RWOP with two pods is not a realistic scenario. // But from AddPodToVolume perspective, it tests how SELinux is handled even for RWO / RWX volumes. - name: "ReadWriteOncePod with the same SELinux options", + name: "RWOP: ReadWriteOncePod with the same SELinux options", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumeAccessMode: v1.ReadWriteOncePod, firstPodSELinuxOptions: &completeSELinuxOpts, @@ -799,9 +873,7 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { expectedSELinuxLabel: completeSELinuxLabel, }, { - // Note: this is not a realistic scenario, two Pods can't use the same RWOP volume. - // But from AddPodToVolume perspective, it tests how SELinux is handled even for RWO / RWX volumes. - name: "ReadWriteOncePod with conflicting SELinux options", + name: "RWOP: ReadWriteOncePod with conflicting SELinux options", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumeAccessMode: v1.ReadWriteOncePod, firstPodSELinuxOptions: &completeSELinuxOpts, @@ -811,7 +883,7 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { expectedSELinuxLabel: completeSELinuxLabel, }, { - name: "ReadWriteMany with the same SELinux options", + name: "RWOP: ReadWriteMany with the same SELinux options", featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod}, volumeAccessMode: v1.ReadWriteMany, firstPodSELinuxOptions: &completeSELinuxOpts, @@ -820,6 +892,100 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { expectError: false, expectedSELinuxLabel: "", // RWX does not support SELinux mount (yet) }, + { + name: "RWOP+ChangePolicy: ReadWriteOncePod with the same SELinux options", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "RWOP+ChangePolicy: ReadWriteOncePod with the same SELinux options and same Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", // Recursive is applied to RWOP volumes + }, + { + name: "RWOP+ChangePolicy: ReadWriteOncePod with the same SELinux options and conflicting policies", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: nil, + + expectError: true, // Conflicting policies with RWOP are an error + expectedSELinuxLabel: "", // Recursive policy is applied to the first volume + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with the same SELinux options with Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", // The policy is ignored, but no mount is the default + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with the same SELinux options with MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), // This can happen when there is a version skew between kubelet and the API server + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: "", // The policy is ignored, but no mount is the default + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with the same SELinux options with conflicting policies", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", // The policy is ignored, no error is raised + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with conflicting SELinux options and Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &conflictingSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, // Conflicting SELinux options are allowed with recursive policy + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy: ReadWriteMany with conflicting SELinux options and MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &conflictingSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: "", // The policy is ignored, no error is raised + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -856,7 +1022,8 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { }, Spec: v1.PodSpec{ SecurityContext: &v1.PodSecurityContext{ - SELinuxOptions: tc.firstPodSELinuxOptions, + SELinuxOptions: tc.firstPodSELinuxOptions, + SELinuxChangePolicy: tc.firstChangePolicy, }, Volumes: []v1.Volume{ { @@ -904,6 +1071,7 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { pod2.Name = "pod2" pod2.UID = "pod2uid" pod2.Spec.SecurityContext.SELinuxOptions = tc.secondPodSELinuxOptions + pod2.Spec.SecurityContext.SELinuxChangePolicy = tc.secondChangePolicy pod2Name := util.GetUniquePodName(pod2) seLinuxContainerContexts = []*v1.SELinuxOptions{tc.secondPodSELinuxOptions} From 53e5335d3c1cfd6e79fb7384b095606f66a00798 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 15 Oct 2024 11:40:46 +0200 Subject: [PATCH 09/13] Add SELinuxMount tests --- .../cache/desired_state_of_world_test.go | 163 +++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go index 1f4319fd43d..a719483f469 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world_test.go @@ -727,7 +727,7 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { podChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), expectError: false, - expectedSELinuxLabel: "", // "Recursive" is applied to RWOP volumes + expectedSELinuxLabel: "", // "Recursive" is applied to RWOP volumes too }, { name: "RWOP+ChangePolicy: ReadWriteOncePod with MountOption policy", @@ -741,6 +741,61 @@ func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) { expectError: false, expectedSELinuxLabel: completeSELinuxLabel, // the policy is ignored, but mounting with SELinux is the default }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with the default policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: nil, // emphasize the default value + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteMany, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteOncePod with Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", // "Recursive" is applied to RWOP volumes too + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteOncePod with MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumePluginSupportsSELinux: true, + volumeAccessMode: v1.ReadWriteOncePod, + podSELinuxOptions: &completeSELinuxOpts, + podChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, } for _, tc := range tests { @@ -986,6 +1041,112 @@ func Test_AddPodToVolume_SELinux_MultiplePods(t *testing.T) { expectError: false, expectedSELinuxLabel: "", // The policy is ignored, no error is raised }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteOncePod with the same SELinux options", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteOncePod with the same SELinux options and same Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", // Recursive is applied to RWOP volumes + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteOncePod with the same SELinux options and conflicting policies", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteOncePod, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: nil, + + expectError: true, // Conflicting policies with RWOP are an error + expectedSELinuxLabel: "", // Recursive policy is applied to the first volume + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with the same SELinux options with Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with the same SELinux options with MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with the same SELinux options with default and MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: nil, // nil should default to MountOption + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: false, + expectedSELinuxLabel: completeSELinuxLabel, + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with the same SELinux options with conflicting policies", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &completeSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: true, + expectedSELinuxLabel: completeSELinuxLabel, // MountOption policy is applied to the first volume + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with conflicting SELinux options and Recursive policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &conflictingSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyRecursive), + + expectError: false, // Conflicting SELinux options are allowed with recursive policy + expectedSELinuxLabel: "", + }, + { + name: "RWOP+ChangePolicy+Mount: ReadWriteMany with conflicting SELinux options and MountOption policy", + featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod, features.SELinuxChangePolicy, features.SELinuxMount}, + volumeAccessMode: v1.ReadWriteMany, + firstPodSELinuxOptions: &completeSELinuxOpts, + secondPodSELinuxOptions: &conflictingSELinuxOpts, + firstChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + secondChangePolicy: ptr.To(v1.SELinuxChangePolicyMountOption), + + expectError: true, // SELinux options cannot conflict with MountOption policy + expectedSELinuxLabel: completeSELinuxLabel, // The SELinux label of the first pods is used + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { From 97b03e29b9117406573d4082bbb5a958f077c9e8 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 29 Oct 2024 13:35:20 +0100 Subject: [PATCH 10/13] Document getSELinuxLabel function --- .../volumemanager/cache/desired_state_of_world.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/kubelet/volumemanager/cache/desired_state_of_world.go b/pkg/kubelet/volumemanager/cache/desired_state_of_world.go index e8563e4384a..f59b58c4cfc 100644 --- a/pkg/kubelet/volumemanager/cache/desired_state_of_world.go +++ b/pkg/kubelet/volumemanager/cache/desired_state_of_world.go @@ -392,16 +392,16 @@ func (dsw *desiredStateOfWorld) AddPodToVolume( return volumeName, nil } -func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinuxContainerContexts []*v1.SELinuxOptions, podSecurityContext *v1.PodSecurityContext) (string, bool, error) { - if !feature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { - return "", false, nil - } - +// getSELinuxLabel returns the SELinux label for a given volume and combination of SELinux labels and bool indicating +// if the plugin supports mounting the volume with SELinux context. +// It returns error if the SELinux label cannot be constructed or when the volume is used with multiple SELinux +// labels. +func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinuxContainerContexts []*v1.SELinuxOptions, podSecurityContext *v1.PodSecurityContext) (seLinuxFileLabel string, pluginSupportsSELinuxContextMount bool, err error) { if !dsw.seLinuxTranslator.SELinuxEnabled() { return "", false, nil } - pluginSupportsSELinuxContextMount, err := dsw.getSELinuxMountSupport(volumeSpec) + pluginSupportsSELinuxContextMount, err = dsw.getSELinuxMountSupport(volumeSpec) if err != nil { return "", false, err } @@ -419,7 +419,6 @@ func (dsw *desiredStateOfWorld) getSELinuxLabel(volumeSpec *volume.Spec, seLinux } seLinuxSupported := util.VolumeSupportsSELinuxMount(volumeSpec) - var seLinuxFileLabel string // Ensure that a volume that can be mounted with "-o context=XYZ" is // used only by containers with the same SELinux contexts. for _, containerContext := range seLinuxContainerContexts { From 6e4504685f65ee00b8e1821236ca1465276969b4 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 29 Oct 2024 13:39:44 +0100 Subject: [PATCH 11/13] Fix access mode evaluation Now that SELinuxMount can support volumes with any access modes, length of the access modes does not need to be 1. That was requirement for RWOP volumes only. --- pkg/volume/util/selinux.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/volume/util/selinux.go b/pkg/volume/util/selinux.go index d6ea382031e..9f567dbef74 100644 --- a/pkg/volume/util/selinux.go +++ b/pkg/volume/util/selinux.go @@ -174,16 +174,20 @@ func VolumeSupportsSELinuxMount(volumeSpec *volume.Spec) bool { if volumeSpec.PersistentVolume == nil { return false } - if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 { - return false - } if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMount) { return true } - // Only SELinuxMountReadWriteOncePod feature enabled - if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) { + + // Only SELinuxMountReadWriteOncePod feature is enabled + if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 { + // RWOP volumes must be the only access mode of the volume return false } + if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) { + // Not a RWOP volume + return false + } + // RWOP volume return true } From d7daa688c9e282cebf4cd5201f0397a340faeb01 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Wed, 30 Oct 2024 17:15:52 +0100 Subject: [PATCH 12/13] Collect SELinux options only when needed Remove feature gate check from GetPodVolumeNames and collect SELinux options only when it's really needed. --- .../populator/desired_state_of_world_populator.go | 5 ++++- .../desired_state_of_world_populator_test.go | 10 +++++----- pkg/kubelet/volumemanager/volume_manager.go | 2 +- pkg/volume/util/util.go | 12 +++++------- pkg/volume/util/util_test.go | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go b/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go index 8fa56742f8e..504cbd4a469 100644 --- a/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go +++ b/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go @@ -27,7 +27,9 @@ import ( "sync" "time" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -299,7 +301,8 @@ func (dswp *desiredStateOfWorldPopulator) processPodVolumes( } allVolumesAdded := true - mounts, devices, seLinuxContainerContexts := util.GetPodVolumeNames(pod) + collectSELinuxOptions := utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) + mounts, devices, seLinuxContainerContexts := util.GetPodVolumeNames(pod, collectSELinuxOptions) // Process volume spec for each volume defined in pod for _, podVolume := range pod.Spec.Volumes { diff --git a/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator_test.go b/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator_test.go index 517e2479ee4..11ed7381b68 100644 --- a/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator_test.go +++ b/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator_test.go @@ -766,7 +766,7 @@ func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) { logger, _ := ktesting.NewTestContext(t) fakePodManager.AddPod(pod) - mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) + mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod, false /* collectSELinuxOptions */) _, volumeSpec, _, err := dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap) @@ -813,7 +813,7 @@ func TestCreateVolumeSpec_Valid_Nil_VolumeMounts(t *testing.T) { logger, _ := ktesting.NewTestContext(t) fakePodManager.AddPod(pod) - mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) + mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod, false /* collectSELinuxOptions */) _, volumeSpec, _, err := dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap) @@ -860,7 +860,7 @@ func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) { logger, _ := ktesting.NewTestContext(t) fakePodManager.AddPod(pod) - mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) + mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod, false /* collectSELinuxOptions */) _, volumeSpec, _, err := dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap) @@ -907,7 +907,7 @@ func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) { logger, _ := ktesting.NewTestContext(t) fakePodManager.AddPod(pod) - mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) + mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod, false /* collectSELinuxOptions */) _, volumeSpec, _, err := dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap) @@ -954,7 +954,7 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) { logger, _ := ktesting.NewTestContext(t) fakePodManager.AddPod(pod) - mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) + mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod, false /* collectSELinuxOptions */) _, volumeSpec, _, err := dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap) diff --git a/pkg/kubelet/volumemanager/volume_manager.go b/pkg/kubelet/volumemanager/volume_manager.go index 77a06361582..1b210bf546f 100644 --- a/pkg/kubelet/volumemanager/volume_manager.go +++ b/pkg/kubelet/volumemanager/volume_manager.go @@ -581,7 +581,7 @@ func filterUnmountedVolumes(mountedVolumes sets.Set[string], expectedVolumes []s // getExpectedVolumes returns a list of volumes that must be mounted in order to // consider the volume setup step for this pod satisfied. func getExpectedVolumes(pod *v1.Pod) []string { - mounts, devices, _ := util.GetPodVolumeNames(pod) + mounts, devices, _ := util.GetPodVolumeNames(pod, false /* collectSELinuxOptions */) return mounts.Union(devices).UnsortedList() } diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go index 9c50c7d41e7..c5ad14d36f2 100644 --- a/pkg/volume/util/util.go +++ b/pkg/volume/util/util.go @@ -32,12 +32,10 @@ import ( utypes "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/api/legacyscheme" podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util/types" @@ -512,16 +510,16 @@ func IsLocalEphemeralVolume(volume v1.Volume) bool { } // GetPodVolumeNames returns names of volumes that are used in a pod, -// either as filesystem mount or raw block device, together with list -// of all SELinux contexts of all containers that use the volumes. -func GetPodVolumeNames(pod *v1.Pod) (mounts sets.Set[string], devices sets.Set[string], seLinuxContainerContexts map[string][]*v1.SELinuxOptions) { +// either as filesystem mount or raw block device. +// To save another sweep through containers, SELinux options are optionally collected too. +func GetPodVolumeNames(pod *v1.Pod, collectSELinuxOptions bool) (mounts sets.Set[string], devices sets.Set[string], seLinuxContainerContexts map[string][]*v1.SELinuxOptions) { mounts = sets.New[string]() devices = sets.New[string]() seLinuxContainerContexts = make(map[string][]*v1.SELinuxOptions) podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(container *v1.Container, containerType podutil.ContainerType) bool { var seLinuxOptions *v1.SELinuxOptions - if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { + if collectSELinuxOptions { effectiveContainerSecurity := securitycontext.DetermineEffectiveSecurityContext(pod, container) if effectiveContainerSecurity != nil { // No DeepCopy, SELinuxOptions is already a copy of Pod's or container's SELinuxOptions @@ -532,7 +530,7 @@ func GetPodVolumeNames(pod *v1.Pod) (mounts sets.Set[string], devices sets.Set[s if container.VolumeMounts != nil { for _, mount := range container.VolumeMounts { mounts.Insert(mount.Name) - if seLinuxOptions != nil { + if seLinuxOptions != nil && collectSELinuxOptions { seLinuxContainerContexts[mount.Name] = append(seLinuxContainerContexts[mount.Name], seLinuxOptions.DeepCopy()) } } diff --git a/pkg/volume/util/util_test.go b/pkg/volume/util/util_test.go index 455283922a6..e0c1a153da3 100644 --- a/pkg/volume/util/util_test.go +++ b/pkg/volume/util/util_test.go @@ -945,7 +945,7 @@ func TestGetPodVolumeNames(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - mounts, devices, contexts := GetPodVolumeNames(test.pod) + mounts, devices, contexts := GetPodVolumeNames(test.pod, true /* collectSELinuxOptions */) if !mounts.Equal(test.expectedMounts) { t.Errorf("Expected mounts: %q, got %q", sets.List[string](mounts), sets.List[string](test.expectedMounts)) } From 09afd667d72c62ed667be0f6d09bd4f2ee03baef Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Wed, 30 Oct 2024 17:16:21 +0100 Subject: [PATCH 13/13] Remove useless comment seLinuxOptions are copied few lines below during `append()` --- pkg/volume/util/util.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go index c5ad14d36f2..0173902eb87 100644 --- a/pkg/volume/util/util.go +++ b/pkg/volume/util/util.go @@ -522,7 +522,6 @@ func GetPodVolumeNames(pod *v1.Pod, collectSELinuxOptions bool) (mounts sets.Set if collectSELinuxOptions { effectiveContainerSecurity := securitycontext.DetermineEffectiveSecurityContext(pod, container) if effectiveContainerSecurity != nil { - // No DeepCopy, SELinuxOptions is already a copy of Pod's or container's SELinuxOptions seLinuxOptions = effectiveContainerSecurity.SELinuxOptions } }