From b4f0ef22a2fb540789b027b51566426ee5d3c2fc Mon Sep 17 00:00:00 2001 From: Guillaume Doussin Date: Thu, 4 Jan 2024 10:56:59 +0100 Subject: [PATCH] feat: Reference AnalysisTemplates inside an AnalysisTemplate Signed-off-by: Guillaume Doussin --- docs/features/analysis.md | 178 ++ .../features/kustomize/rollout_cr_schema.json | 38 +- experiments/controller_test.go | 12 +- experiments/experiment.go | 99 +- experiments/experiment_test.go | 314 +++- experiments/replicaset_test.go | 4 +- manifests/crds/analysis-template-crd.yaml | 11 +- .../crds/cluster-analysis-template-crd.yaml | 11 +- manifests/install.yaml | 22 +- pkg/apiclient/rollout/rollout.swagger.json | 28 +- pkg/apis/api-rules/violation_exceptions.list | 1 + pkg/apis/rollouts/v1alpha1/analysis_types.go | 6 +- pkg/apis/rollouts/v1alpha1/generated.pb.go | 1651 +++++++++-------- pkg/apis/rollouts/v1alpha1/generated.proto | 27 +- .../rollouts/v1alpha1/openapi_generated.go | 87 +- pkg/apis/rollouts/v1alpha1/types.go | 4 +- .../v1alpha1/zz_generated.deepcopy.go | 39 +- .../validation/validation_references_test.go | 2 +- rollout/analysis.go | 74 +- rollout/analysis_test.go | 371 +++- rollout/bluegreen_test.go | 2 +- rollout/controller.go | 54 +- rollout/controller_test.go | 52 +- rollout/sync_test.go | 6 +- ui/src/models/rollout/generated/api.ts | 42 +- utils/analysis/helpers.go | 20 + utils/analysis/helpers_test.go | 80 + 27 files changed, 2221 insertions(+), 1014 deletions(-) diff --git a/docs/features/analysis.md b/docs/features/analysis.md index d300f0cbb0..4029164425 100644 --- a/docs/features/analysis.md +++ b/docs/features/analysis.md @@ -358,6 +358,184 @@ templates together. The controller combines the `metrics` and `args` fields of a * Multiple metrics in the templates have the same name * Two arguments with the same name have different default values no matter the argument value in Rollout +## Analysis Template referencing other Analysis Templates + +AnalysisTemplates and ClusterAnalysisTemplates may reference other templates. + +They can be combined with other metrics: + +=== "AnalysisTemplate" + + ```yaml + apiVersion: argoproj.io/v1alpha1 + kind: AnalysisTemplate + metadata: + name: error-rate + spec: + args: + - name: service-name + metrics: + - name: error-rate + interval: 5m + successCondition: result[0] <= 0.95 + failureLimit: 3 + provider: + prometheus: + address: http://prometheus.example.com:9090 + query: | + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code=~"5.*"}[5m] + )) / + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m] + )) + --- + apiVersion: argoproj.io/v1alpha1 + kind: AnalysisTemplate + metadata: + name: rates + spec: + args: + - name: service-name + metrics: + - name: success-rate + interval: 5m + successCondition: result[0] >= 0.95 + failureLimit: 3 + provider: + prometheus: + address: http://prometheus.example.com:9090 + query: | + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code!~"5.*"}[5m] + )) / + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m] + )) + templates: + - templateName: error-rate + clusterScope: false + ``` + +Or without additional metrics: + +=== "AnalysisTemplate" + + ```yaml + apiVersion: argoproj.io/v1alpha1 + kind: AnalysisTemplate + metadata: + name: success-rate + spec: + args: + - name: service-name + metrics: + - name: success-rate + interval: 5m + successCondition: result[0] >= 0.95 + failureLimit: 3 + provider: + prometheus: + address: http://prometheus.example.com:9090 + query: | + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code!~"5.*"}[5m] + )) / + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m] + )) + --- + apiVersion: argoproj.io/v1alpha1 + kind: AnalysisTemplate + metadata: + name: error-rate + spec: + args: + - name: service-name + metrics: + - name: error-rate + interval: 5m + successCondition: result[0] <= 0.95 + failureLimit: 3 + provider: + prometheus: + address: http://prometheus.example.com:9090 + query: | + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code=~"5.*"}[5m] + )) / + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m] + )) + --- + apiVersion: argoproj.io/v1alpha1 + kind: AnalysisTemplate + metadata: + name: rates + spec: + args: + - name: service-name + templates: + - templateName: success-rate + clusterScope: false + - templateName: error-rate + clusterScope: false + ``` + + The result in the AnalysisRun will have the aggregation of metrics of each template: + + === "AnalysisRun" + + ```yaml + # NOTE: Generated AnalysisRun from a single template referencing several templates + apiVersion: argoproj.io/v1alpha1 + kind: AnalysisRun + metadata: + name: guestbook-CurrentPodHash-templates-in-template + spec: + args: + - name: service-name + value: guestbook-svc.default.svc.cluster.local + metrics: + - name: success-rate + interval: 5m + successCondition: result[0] >= 0.95 + failureLimit: 3 + provider: + prometheus: + address: http://prometheus.example.com:9090 + query: | + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code!~"5.*"}[5m] + )) / + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m] + )) + - name: error-rate + interval: 5m + successCondition: result[0] <= 0.95 + failureLimit: 3 + provider: + prometheus: + address: http://prometheus.example.com:9090 + query: | + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code=~"5.*"}[5m] + )) / + sum(irate( + istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m] + )) + ``` + +!!! note + The same limitations as for the multiple templates feature apply. + The controller will error when merging the templates if: + + * Multiple metrics in the templates have the same name + * Two arguments with the same name have different default values no matter the argument value in Rollout + + However, if the same AnalysisTemplate is referenced several times along the chain of references, the controller will only keep it once and discard the other references. + ## Analysis Template Arguments AnalysisTemplates may declare a set of arguments that can be passed by Rollouts. The args can then be used as in metrics configuration and are resolved at the time the AnalysisRun is created. Argument placeholders are defined as diff --git a/docs/features/kustomize/rollout_cr_schema.json b/docs/features/kustomize/rollout_cr_schema.json index 815298b254..4dd0d72859 100644 --- a/docs/features/kustomize/rollout_cr_schema.json +++ b/docs/features/kustomize/rollout_cr_schema.json @@ -9250,11 +9250,24 @@ "type": "array", "x-kubernetes-patch-merge-key": "name", "x-kubernetes-patch-strategy": "merge" + }, + "templates": { + "items": { + "properties": { + "clusterScope": { + "type": "boolean" + }, + "templateName": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "templateName", + "x-kubernetes-patch-strategy": "merge" } }, - "required": [ - "metrics" - ], "type": "object" } }, @@ -13883,11 +13896,24 @@ "type": "array", "x-kubernetes-patch-merge-key": "name", "x-kubernetes-patch-strategy": "merge" + }, + "templates": { + "items": { + "properties": { + "clusterScope": { + "type": "boolean" + }, + "templateName": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "templateName", + "x-kubernetes-patch-strategy": "merge" } }, - "required": [ - "metrics" - ], "type": "object" } }, diff --git a/experiments/controller_test.go b/experiments/controller_test.go index 0103e03ce1..f351982bc6 100644 --- a/experiments/controller_test.go +++ b/experiments/controller_test.go @@ -301,7 +301,7 @@ func generateRSName(ex *v1alpha1.Experiment, template v1alpha1.TemplateSpec) str return fmt.Sprintf("%s-%s", ex.Name, template.Name) } -func calculatePatch(ex *v1alpha1.Experiment, patch string, templates []v1alpha1.TemplateStatus, condition *v1alpha1.ExperimentCondition) string { +func calculatePatch(ex *v1alpha1.Experiment, patch string, templates []v1alpha1.TemplateStatus, condition *v1alpha1.ExperimentCondition, analysisRuns []*v1alpha1.ExperimentAnalysisRunStatus) string { patchMap := make(map[string]any) err := json.Unmarshal([]byte(patch), &patchMap) if err != nil { @@ -316,6 +316,10 @@ func calculatePatch(ex *v1alpha1.Experiment, patch string, templates []v1alpha1. newStatus["conditions"] = []v1alpha1.ExperimentCondition{*condition} patchMap["status"] = newStatus } + if analysisRuns != nil { + newStatus["analysisRuns"] = analysisRuns + patchMap["status"] = newStatus + } patchBytes, err := json.Marshal(patchMap) if err != nil { @@ -804,7 +808,7 @@ func TestAddInvalidSpec(t *testing.T) { expectedPatch := calculatePatch(e, `{ "status":{ } - }`, nil, cond) + }`, nil, cond, nil) assert.JSONEq(t, expectedPatch, patch) } @@ -851,7 +855,7 @@ func TestUpdateInvalidSpec(t *testing.T) { expectedPatch := calculatePatch(e, `{ "status":{ } - }`, nil, cond) + }`, nil, cond, nil) assert.JSONEq(t, expectedPatch, patch) } @@ -891,7 +895,7 @@ func TestRemoveInvalidSpec(t *testing.T) { expectedPatch := calculatePatch(e, `{ "status":{ } - }`, templateStatus, cond) + }`, templateStatus, cond, nil) assert.JSONEq(t, expectedPatch, patch) } diff --git a/experiments/experiment.go b/experiments/experiment.go index e4f0f53ede..42ec14f28b 100644 --- a/experiments/experiment.go +++ b/experiments/experiment.go @@ -638,14 +638,13 @@ func (ec *experimentContext) assessAnalysisRuns() (v1alpha1.AnalysisPhase, strin func (ec *experimentContext) newAnalysisRun(analysis v1alpha1.ExperimentAnalysisTemplateRef, args []v1alpha1.Argument, dryRunMetrics []v1alpha1.DryRun, measurementRetentionMetrics []v1alpha1.MeasurementRetention) (*v1alpha1.AnalysisRun, error) { if analysis.ClusterScope { - clusterTemplate, err := ec.clusterAnalysisTemplateLister.Get(analysis.TemplateName) + analysisTemplates, clusterAnalysisTemplates, err := ec.getAnalysisTemplatesFromClusterAnalysis(analysis) if err != nil { return nil, err } name := fmt.Sprintf("%s-%s", ec.ex.Name, analysis.Name) - clusterAnalysisTemplates := []*v1alpha1.ClusterAnalysisTemplate{clusterTemplate} - run, err := analysisutil.NewAnalysisRunFromTemplates(nil, clusterAnalysisTemplates, args, dryRunMetrics, measurementRetentionMetrics, name, "", ec.ex.Namespace) + run, err := analysisutil.NewAnalysisRunFromTemplates(analysisTemplates, clusterAnalysisTemplates, args, dryRunMetrics, measurementRetentionMetrics, name, "", ec.ex.Namespace) if err != nil { return nil, err } @@ -656,14 +655,13 @@ func (ec *experimentContext) newAnalysisRun(analysis v1alpha1.ExperimentAnalysis run.OwnerReferences = []metav1.OwnerReference{*metav1.NewControllerRef(ec.ex, controllerKind)} return run, nil } else { - template, err := ec.analysisTemplateLister.AnalysisTemplates(ec.ex.Namespace).Get(analysis.TemplateName) + analysisTemplates, clusterAnalysisTemplates, err := ec.getAnalysisTemplatesFromAnalysis(analysis) if err != nil { return nil, err } name := fmt.Sprintf("%s-%s", ec.ex.Name, analysis.Name) - analysisTemplates := []*v1alpha1.AnalysisTemplate{template} - run, err := analysisutil.NewAnalysisRunFromTemplates(analysisTemplates, nil, args, dryRunMetrics, measurementRetentionMetrics, name, "", ec.ex.Namespace) + run, err := analysisutil.NewAnalysisRunFromTemplates(analysisTemplates, clusterAnalysisTemplates, args, dryRunMetrics, measurementRetentionMetrics, name, "", ec.ex.Namespace) if err != nil { return nil, err } @@ -676,6 +674,95 @@ func (ec *experimentContext) newAnalysisRun(analysis v1alpha1.ExperimentAnalysis } } +func (ec *experimentContext) getAnalysisTemplatesFromClusterAnalysis(analysis v1alpha1.ExperimentAnalysisTemplateRef) ([]*v1alpha1.AnalysisTemplate, []*v1alpha1.ClusterAnalysisTemplate, error) { + clusterTemplate, err := ec.clusterAnalysisTemplateLister.Get(analysis.TemplateName) + if err != nil { + return nil, nil, err + } + templates := make([]*v1alpha1.AnalysisTemplate, 0) + clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) + clusterTemplates = append(clusterTemplates, clusterTemplate) + + if clusterTemplate.Spec.Templates != nil { + innerTemplates, innerClusterTemplates, innerErr := ec.getAnalysisTemplatesFromRefs(&clusterTemplate.Spec.Templates) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } + uniqueTemplates, uniqueClusterTemplates := analysisutil.FilterUniqueTemplates(templates, clusterTemplates) + return uniqueTemplates, uniqueClusterTemplates, nil +} + +func (ec *experimentContext) getAnalysisTemplatesFromAnalysis(analysis v1alpha1.ExperimentAnalysisTemplateRef) ([]*v1alpha1.AnalysisTemplate, []*v1alpha1.ClusterAnalysisTemplate, error) { + template, err := ec.analysisTemplateLister.AnalysisTemplates(ec.ex.Namespace).Get(analysis.TemplateName) + if err != nil { + return nil, nil, err + } + templates := make([]*v1alpha1.AnalysisTemplate, 0) + clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) + templates = append(templates, template) + + if template.Spec.Templates != nil { + innerTemplates, innerClusterTemplates, innerErr := ec.getAnalysisTemplatesFromRefs(&template.Spec.Templates) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } + uniqueTemplates, uniqueClusterTemplates := analysisutil.FilterUniqueTemplates(templates, clusterTemplates) + return uniqueTemplates, uniqueClusterTemplates, nil +} + +func (ec *experimentContext) getAnalysisTemplatesFromRefs(templateRefs *[]v1alpha1.AnalysisTemplateRef) ([]*v1alpha1.AnalysisTemplate, []*v1alpha1.ClusterAnalysisTemplate, error) { + templates := make([]*v1alpha1.AnalysisTemplate, 0) + clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) + for _, templateRef := range *templateRefs { + if templateRef.ClusterScope { + template, err := ec.clusterAnalysisTemplateLister.Get(templateRef.TemplateName) + if err != nil { + if k8serrors.IsNotFound(err) { + ec.log.Warnf("ClusterAnalysisTemplate '%s' not found", templateRef.TemplateName) + } + return nil, nil, err + } + clusterTemplates = append(clusterTemplates, template) + // Look for nested templates + if template.Spec.Templates != nil { + innerTemplates, innerClusterTemplates, innerErr := ec.getAnalysisTemplatesFromRefs(&template.Spec.Templates) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } + } else { + template, err := ec.analysisTemplateLister.AnalysisTemplates(ec.ex.Namespace).Get(templateRef.TemplateName) + if err != nil { + if k8serrors.IsNotFound(err) { + ec.log.Warnf("AnalysisTemplate '%s' not found", templateRef.TemplateName) + } + return nil, nil, err + } + templates = append(templates, template) + // Look for nested templates + if template.Spec.Templates != nil { + innerTemplates, innerClusterTemplates, innerErr := ec.getAnalysisTemplatesFromRefs(&template.Spec.Templates) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } + } + + } + uniqueTemplates, uniqueClusterTemplates := analysisutil.FilterUniqueTemplates(templates, clusterTemplates) + return uniqueTemplates, uniqueClusterTemplates, nil +} + // verifyAnalysisTemplate verifies an AnalysisTemplate. For now, it simply means that it exists func (ec *experimentContext) verifyAnalysisTemplate(analysis v1alpha1.ExperimentAnalysisTemplateRef) error { _, err := ec.analysisTemplateLister.AnalysisTemplates(ec.ex.Namespace).Get(analysis.TemplateName) diff --git a/experiments/experiment_test.go b/experiments/experiment_test.go index 21fbeb530a..b0175b98fb 100644 --- a/experiments/experiment_test.go +++ b/experiments/experiment_test.go @@ -97,7 +97,7 @@ func TestSetExperimentToPending(t *testing.T) { "status":{ "phase": "Pending" } - }`, templateStatus, cond) + }`, templateStatus, cond, nil) assert.Equal(t, expectedPatch, patch) } @@ -281,7 +281,7 @@ func TestSuccessAfterDurationPasses(t *testing.T) { "status":{ "phase": "Successful" } - }`, templateStatuses, cond) + }`, templateStatuses, cond, nil) assert.JSONEq(t, expectedPatch, patch) } @@ -554,3 +554,313 @@ func TestServiceNameSet(t *testing.T) { assert.NotNil(t, exCtx.templateServices["bar"]) assert.Equal(t, exCtx.templateServices["bar"].Name, "service-name") } + +func TestCreatenalysisRunWithClusterTemplatesAndTemplateAndInnerTemplates(t *testing.T) { + + at := analysisTemplateWithNamespacedAnalysisRefs("bar", "bar2") + at2 := analysisTemplateWithClusterAnalysisRefs("bar2", "clusterbar", "clusterbar2") + cat := clusterAnalysisTemplateWithAnalysisRefs("clusterbar", "clusterbar2", "clusterbar3") + cat2 := clusterAnalysisTemplate("clusterbar2") + cat3 := clusterAnalysisTemplate("clusterbar3") + cat4 := clusterAnalysisTemplate("clusterbar4") + + templates := generateTemplates("bar") + e := newExperiment("foo", templates, "") + e.Spec.Analyses = []v1alpha1.ExperimentAnalysisTemplateRef{ + { + Name: "exp-bar", + TemplateName: "bar", + ClusterScope: false, + }, + { + Name: "exp-bar-2", + TemplateName: "clusterbar4", + ClusterScope: true, + }, + } + + e.Status = v1alpha1.ExperimentStatus{} + e.Status.AvailableAt = now() + e.Status.Phase = v1alpha1.AnalysisPhaseRunning + + cond := newCondition(conditions.ReplicaSetUpdatedReason, e) + + rs := templateToRS(e, templates[0], 0) + f := newFixture(t, e, rs, cat, cat2, cat3, cat4, at, at2) + defer f.Close() + + ar1 := &v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-exp-bar", + Namespace: metav1.NamespaceDefault, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(rs, controllerKind)}, + }, + Spec: v1alpha1.AnalysisRunSpec{ + Metrics: concatMultipleSlices([][]v1alpha1.Metric{at.Spec.Metrics, at2.Spec.Metrics, cat.Spec.Metrics, cat2.Spec.Metrics, cat3.Spec.Metrics}), + DryRun: concatMultipleSlices([][]v1alpha1.DryRun{at.Spec.DryRun, at2.Spec.DryRun, cat.Spec.DryRun, cat2.Spec.DryRun, cat3.Spec.DryRun}), + Args: at.Spec.Args, + MeasurementRetention: concatMultipleSlices([][]v1alpha1.MeasurementRetention{at.Spec.MeasurementRetention, at2.Spec.MeasurementRetention, cat.Spec.MeasurementRetention, cat2.Spec.MeasurementRetention, cat3.Spec.MeasurementRetention}), + }, + } + ar2 := &v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-exp-bar-2", + Namespace: metav1.NamespaceDefault, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(rs, controllerKind)}, + }, + Spec: v1alpha1.AnalysisRunSpec{ + Metrics: cat4.Spec.Metrics, + Args: cat4.Spec.Args, + DryRun: cat4.Spec.DryRun, + MeasurementRetention: cat4.Spec.MeasurementRetention, + }, + } + createdIndex1 := f.expectCreateAnalysisRunAction(ar1) + createdIndex2 := f.expectCreateAnalysisRunAction(ar2) + index := f.expectPatchExperimentAction(e) + + f.run(getKey(e, t)) + + createdAr1 := f.getCreatedAnalysisRun(createdIndex1) + createdAr2 := f.getCreatedAnalysisRun(createdIndex2) + + patch := f.getPatchedExperiment(index) + templateStatus := []v1alpha1.TemplateStatus{ + generateTemplatesStatus("bar", 0, 0, v1alpha1.TemplateStatusProgressing, nil), + } + analysisRun := []*v1alpha1.ExperimentAnalysisRunStatus{ + { + AnalysisRun: "foo-exp-bar", + Name: "exp-bar", + Phase: "Pending", + }, + { + AnalysisRun: "foo-exp-bar-2", + Name: "exp-bar-2", + Phase: "Pending", + }, + } + expectedPatch := calculatePatch(e, `{ + "status":{ + "phase": "Pending" + } + }`, templateStatus, cond, analysisRun) + assert.Equal(t, expectedPatch, patch) + + assert.Equal(t, "foo-exp-bar", createdAr1.Name) + assert.Len(t, createdAr1.Spec.Metrics, 5) + assert.Equal(t, "foo-exp-bar-2", createdAr2.Name) + assert.Len(t, createdAr2.Spec.Metrics, 1) +} + +func TestCreatenalysisRunWithTemplatesAndNoMetricsAtRoot(t *testing.T) { + + at := analysisTemplateWithOnlyNamespacedAnalysisRefs("bar", "bar2") + at2 := analysisTemplateWithClusterAnalysisRefs("bar2", "clusterbar", "clusterbar2") + cat := clusterAnalysisTemplateWithAnalysisRefs("clusterbar", "clusterbar2", "clusterbar3") + cat2 := clusterAnalysisTemplate("clusterbar2") + cat3 := clusterAnalysisTemplate("clusterbar3") + cat4 := clusterAnalysisTemplate("clusterbar4") + + templates := generateTemplates("bar") + e := newExperiment("foo", templates, "") + e.Spec.Analyses = []v1alpha1.ExperimentAnalysisTemplateRef{ + { + Name: "exp-bar", + TemplateName: "bar", + ClusterScope: false, + }, + { + Name: "exp-bar-2", + TemplateName: "clusterbar4", + ClusterScope: true, + }, + } + + e.Status = v1alpha1.ExperimentStatus{} + e.Status.AvailableAt = now() + e.Status.Phase = v1alpha1.AnalysisPhaseRunning + + cond := newCondition(conditions.ReplicaSetUpdatedReason, e) + + rs := templateToRS(e, templates[0], 0) + f := newFixture(t, e, rs, cat, cat2, cat3, cat4, at, at2) + defer f.Close() + + ar1 := &v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-exp-bar", + Namespace: metav1.NamespaceDefault, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(rs, controllerKind)}, + }, + Spec: v1alpha1.AnalysisRunSpec{ + Metrics: concatMultipleSlices([][]v1alpha1.Metric{at2.Spec.Metrics, cat.Spec.Metrics, cat2.Spec.Metrics, cat3.Spec.Metrics}), + DryRun: concatMultipleSlices([][]v1alpha1.DryRun{at2.Spec.DryRun, cat.Spec.DryRun, cat2.Spec.DryRun, cat3.Spec.DryRun}), + Args: at.Spec.Args, + MeasurementRetention: concatMultipleSlices([][]v1alpha1.MeasurementRetention{at2.Spec.MeasurementRetention, cat.Spec.MeasurementRetention, cat2.Spec.MeasurementRetention, cat3.Spec.MeasurementRetention}), + }, + } + ar2 := &v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-exp-bar-2", + Namespace: metav1.NamespaceDefault, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(rs, controllerKind)}, + }, + Spec: v1alpha1.AnalysisRunSpec{ + Metrics: cat4.Spec.Metrics, + Args: cat4.Spec.Args, + DryRun: cat4.Spec.DryRun, + MeasurementRetention: cat4.Spec.MeasurementRetention, + }, + } + createdIndex1 := f.expectCreateAnalysisRunAction(ar1) + createdIndex2 := f.expectCreateAnalysisRunAction(ar2) + index := f.expectPatchExperimentAction(e) + + f.run(getKey(e, t)) + + createdAr1 := f.getCreatedAnalysisRun(createdIndex1) + createdAr2 := f.getCreatedAnalysisRun(createdIndex2) + + patch := f.getPatchedExperiment(index) + templateStatus := []v1alpha1.TemplateStatus{ + generateTemplatesStatus("bar", 0, 0, v1alpha1.TemplateStatusProgressing, nil), + } + analysisRun := []*v1alpha1.ExperimentAnalysisRunStatus{ + { + AnalysisRun: "foo-exp-bar", + Name: "exp-bar", + Phase: "Pending", + }, + { + AnalysisRun: "foo-exp-bar-2", + Name: "exp-bar-2", + Phase: "Pending", + }, + } + expectedPatch := calculatePatch(e, `{ + "status":{ + "phase": "Pending" + } + }`, templateStatus, cond, analysisRun) + assert.Equal(t, expectedPatch, patch) + + assert.Equal(t, "foo-exp-bar", createdAr1.Name) + assert.Len(t, createdAr1.Spec.Metrics, 4) + assert.Equal(t, "foo-exp-bar-2", createdAr2.Name) + assert.Len(t, createdAr2.Spec.Metrics, 1) +} + +func concatMultipleSlices[T any](slices [][]T) []T { + var totalLen int + + for _, s := range slices { + totalLen += len(s) + } + + result := make([]T, totalLen) + + var i int + + for _, s := range slices { + i += copy(result[i:], s) + } + + return result +} + +func analysisTemplateWithNamespacedAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + return analysisTemplateWithAnalysisRefs(name, false, innerRefsName...) +} + +func analysisTemplateWithClusterAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + return analysisTemplateWithAnalysisRefs(name, true, innerRefsName...) +} + +func analysisTemplateWithAnalysisRefs(name string, clusterScope bool, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + templatesRefs := []v1alpha1.AnalysisTemplateRef{} + for _, innerTplName := range innerRefsName { + templatesRefs = append(templatesRefs, v1alpha1.AnalysisTemplateRef{ + TemplateName: innerTplName, + ClusterScope: clusterScope, + }) + } + return &v1alpha1.AnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{{ + Name: "example-" + name, + }}, + DryRun: []v1alpha1.DryRun{{ + MetricName: "example-" + name, + }}, + MeasurementRetention: []v1alpha1.MeasurementRetention{{ + MetricName: "example-" + name, + }}, + Templates: templatesRefs, + }, + } +} + +func analysisTemplateWithOnlyNamespacedAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + return analysisTemplateWithOnlyRefs(name, false, innerRefsName...) +} + +func analysisTemplateWithOnlyRefs(name string, clusterScope bool, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + templatesRefs := []v1alpha1.AnalysisTemplateRef{} + for _, innerTplName := range innerRefsName { + templatesRefs = append(templatesRefs, v1alpha1.AnalysisTemplateRef{ + TemplateName: innerTplName, + ClusterScope: clusterScope, + }) + } + return &v1alpha1.AnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{}, + DryRun: []v1alpha1.DryRun{}, + MeasurementRetention: []v1alpha1.MeasurementRetention{}, + Templates: templatesRefs, + }, + } +} + +func clusterAnalysisTemplate(name string) *v1alpha1.ClusterAnalysisTemplate { + return &v1alpha1.ClusterAnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{{ + Name: "clusterexample-" + name, + }}, + }, + } +} + +func clusterAnalysisTemplateWithAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.ClusterAnalysisTemplate { + templatesRefs := []v1alpha1.AnalysisTemplateRef{} + for _, innerTplName := range innerRefsName { + templatesRefs = append(templatesRefs, v1alpha1.AnalysisTemplateRef{ + TemplateName: innerTplName, + ClusterScope: true, + }) + } + return &v1alpha1.ClusterAnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{{ + Name: "clusterexample-" + name, + }}, + Templates: templatesRefs, + }, + } +} diff --git a/experiments/replicaset_test.go b/experiments/replicaset_test.go index 030414f2df..d74e628c50 100644 --- a/experiments/replicaset_test.go +++ b/experiments/replicaset_test.go @@ -41,7 +41,7 @@ func TestCreateMultipleRS(t *testing.T) { expectedPatch := calculatePatch(e, `{ "status":{ } - }`, templateStatus, cond) + }`, templateStatus, cond, nil) assert.JSONEq(t, expectedPatch, patch) } @@ -72,7 +72,7 @@ func TestCreateMissingRS(t *testing.T) { generateTemplatesStatus("bar", 0, 0, v1alpha1.TemplateStatusProgressing, now()), generateTemplatesStatus("baz", 0, 0, v1alpha1.TemplateStatusProgressing, now()), } - assert.JSONEq(t, calculatePatch(e, expectedPatch, templateStatuses, cond), patch) + assert.JSONEq(t, calculatePatch(e, expectedPatch, templateStatuses, cond, nil), patch) } func TestTemplateHasMultipleRS(t *testing.T) { diff --git a/manifests/crds/analysis-template-crd.yaml b/manifests/crds/analysis-template-crd.yaml index 9dbaa69c65..d1b0cba2d1 100644 --- a/manifests/crds/analysis-template-crd.yaml +++ b/manifests/crds/analysis-template-crd.yaml @@ -3008,8 +3008,15 @@ spec: - provider type: object type: array - required: - - metrics + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array type: object required: - spec diff --git a/manifests/crds/cluster-analysis-template-crd.yaml b/manifests/crds/cluster-analysis-template-crd.yaml index 9fadaef522..ba8af4b57a 100644 --- a/manifests/crds/cluster-analysis-template-crd.yaml +++ b/manifests/crds/cluster-analysis-template-crd.yaml @@ -3008,8 +3008,15 @@ spec: - provider type: object type: array - required: - - metrics + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array type: object required: - spec diff --git a/manifests/install.yaml b/manifests/install.yaml index 082042a0ca..c9e01d1cf1 100755 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -6162,8 +6162,15 @@ spec: - provider type: object type: array - required: - - metrics + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array type: object required: - spec @@ -9182,8 +9189,15 @@ spec: - provider type: object type: array - required: - - metrics + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array type: object required: - spec diff --git a/pkg/apiclient/rollout/rollout.swagger.json b/pkg/apiclient/rollout/rollout.swagger.json index b491f9d614..23904a42c9 100755 --- a/pkg/apiclient/rollout/rollout.swagger.json +++ b/pkg/apiclient/rollout/rollout.swagger.json @@ -693,6 +693,19 @@ }, "title": "AnalysisRunStrategy configuration for the analysis runs and experiments to retain" }, + "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisTemplateRef": { + "type": "object", + "properties": { + "templateName": { + "type": "string", + "title": "TemplateName name of template to use in AnalysisRun\n+optional" + }, + "clusterScope": { + "type": "boolean", + "title": "Whether to look for the templateName at cluster scope or namespace scope\n+optional" + } + } + }, "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AntiAffinity": { "type": "object", "properties": { @@ -1840,7 +1853,7 @@ "templates": { "type": "array", "items": { - "$ref": "#/definitions/github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutAnalysisTemplate" + "$ref": "#/definitions/github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisTemplateRef" }, "title": "Templates reference to a list of analysis templates to combine for an AnalysisRun\n+patchMergeKey=templateName\n+patchStrategy=merge" }, @@ -1900,19 +1913,6 @@ } } }, - "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutAnalysisTemplate": { - "type": "object", - "properties": { - "templateName": { - "type": "string", - "title": "TemplateName name of template to use in AnalysisRun\n+optional" - }, - "clusterScope": { - "type": "boolean", - "title": "Whether to look for the templateName at cluster scope or namespace scope\n+optional" - } - } - }, "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutCondition": { "type": "object", "properties": { diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list index e947b953c9..ff257adcab 100644 --- a/pkg/apis/api-rules/violation_exceptions.list +++ b/pkg/apis/api-rules/violation_exceptions.list @@ -9,6 +9,7 @@ API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,AnalysisTemplateSpec,DryRun API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,AnalysisTemplateSpec,MeasurementRetention API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,AnalysisTemplateSpec,Metrics +API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,AnalysisTemplateSpec,Templates API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,ApisixRoute,Rules API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,AppMeshVirtualService,Routes API rule violation: list_type_missing,github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1,CanaryStrategy,Steps diff --git a/pkg/apis/rollouts/v1alpha1/analysis_types.go b/pkg/apis/rollouts/v1alpha1/analysis_types.go index f7acbdc6cf..08ef18071f 100644 --- a/pkg/apis/rollouts/v1alpha1/analysis_types.go +++ b/pkg/apis/rollouts/v1alpha1/analysis_types.go @@ -56,7 +56,7 @@ type AnalysisTemplateSpec struct { // Metrics contains the list of metrics to query as part of an analysis run // +patchMergeKey=name // +patchStrategy=merge - Metrics []Metric `json:"metrics" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,1,rep,name=metrics"` + Metrics []Metric `json:"metrics,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,1,rep,name=metrics"` // Args are the list of arguments to the template // +patchMergeKey=name // +patchStrategy=merge @@ -72,6 +72,10 @@ type AnalysisTemplateSpec struct { // +patchStrategy=merge // +optional MeasurementRetention []MeasurementRetention `json:"measurementRetention,omitempty" patchStrategy:"merge" patchMergeKey:"metricName" protobuf:"bytes,4,rep,name=measurementRetention"` + // Templates reference to a list of analysis templates to combine with the rest of the metrics for an AnalysisRun + // +patchMergeKey=templateName + // +patchStrategy=merge + Templates []AnalysisTemplateRef `json:"templates,omitempty" patchStrategy:"merge" patchMergeKey:"templateName" protobuf:"bytes,5,rep,name=templates"` } // DurationString is a string representing a duration (e.g. 30s, 5m, 1h) diff --git a/pkg/apis/rollouts/v1alpha1/generated.pb.go b/pkg/apis/rollouts/v1alpha1/generated.pb.go index d4abc7d428..53e23a0087 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.pb.go +++ b/pkg/apis/rollouts/v1alpha1/generated.pb.go @@ -383,10 +383,38 @@ func (m *AnalysisTemplateList) XXX_DiscardUnknown() { var xxx_messageInfo_AnalysisTemplateList proto.InternalMessageInfo +func (m *AnalysisTemplateRef) Reset() { *m = AnalysisTemplateRef{} } +func (*AnalysisTemplateRef) ProtoMessage() {} +func (*AnalysisTemplateRef) Descriptor() ([]byte, []int) { + return fileDescriptor_e0e705f843545fab, []int{12} +} +func (m *AnalysisTemplateRef) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AnalysisTemplateRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *AnalysisTemplateRef) XXX_Merge(src proto.Message) { + xxx_messageInfo_AnalysisTemplateRef.Merge(m, src) +} +func (m *AnalysisTemplateRef) XXX_Size() int { + return m.Size() +} +func (m *AnalysisTemplateRef) XXX_DiscardUnknown() { + xxx_messageInfo_AnalysisTemplateRef.DiscardUnknown(m) +} + +var xxx_messageInfo_AnalysisTemplateRef proto.InternalMessageInfo + func (m *AnalysisTemplateSpec) Reset() { *m = AnalysisTemplateSpec{} } func (*AnalysisTemplateSpec) ProtoMessage() {} func (*AnalysisTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{12} + return fileDescriptor_e0e705f843545fab, []int{13} } func (m *AnalysisTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -414,7 +442,7 @@ var xxx_messageInfo_AnalysisTemplateSpec proto.InternalMessageInfo func (m *AntiAffinity) Reset() { *m = AntiAffinity{} } func (*AntiAffinity) ProtoMessage() {} func (*AntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{13} + return fileDescriptor_e0e705f843545fab, []int{14} } func (m *AntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -442,7 +470,7 @@ var xxx_messageInfo_AntiAffinity proto.InternalMessageInfo func (m *ApisixRoute) Reset() { *m = ApisixRoute{} } func (*ApisixRoute) ProtoMessage() {} func (*ApisixRoute) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{14} + return fileDescriptor_e0e705f843545fab, []int{15} } func (m *ApisixRoute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -470,7 +498,7 @@ var xxx_messageInfo_ApisixRoute proto.InternalMessageInfo func (m *ApisixTrafficRouting) Reset() { *m = ApisixTrafficRouting{} } func (*ApisixTrafficRouting) ProtoMessage() {} func (*ApisixTrafficRouting) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{15} + return fileDescriptor_e0e705f843545fab, []int{16} } func (m *ApisixTrafficRouting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -498,7 +526,7 @@ var xxx_messageInfo_ApisixTrafficRouting proto.InternalMessageInfo func (m *AppMeshTrafficRouting) Reset() { *m = AppMeshTrafficRouting{} } func (*AppMeshTrafficRouting) ProtoMessage() {} func (*AppMeshTrafficRouting) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{16} + return fileDescriptor_e0e705f843545fab, []int{17} } func (m *AppMeshTrafficRouting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -526,7 +554,7 @@ var xxx_messageInfo_AppMeshTrafficRouting proto.InternalMessageInfo func (m *AppMeshVirtualNodeGroup) Reset() { *m = AppMeshVirtualNodeGroup{} } func (*AppMeshVirtualNodeGroup) ProtoMessage() {} func (*AppMeshVirtualNodeGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{17} + return fileDescriptor_e0e705f843545fab, []int{18} } func (m *AppMeshVirtualNodeGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -554,7 +582,7 @@ var xxx_messageInfo_AppMeshVirtualNodeGroup proto.InternalMessageInfo func (m *AppMeshVirtualNodeReference) Reset() { *m = AppMeshVirtualNodeReference{} } func (*AppMeshVirtualNodeReference) ProtoMessage() {} func (*AppMeshVirtualNodeReference) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{18} + return fileDescriptor_e0e705f843545fab, []int{19} } func (m *AppMeshVirtualNodeReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -582,7 +610,7 @@ var xxx_messageInfo_AppMeshVirtualNodeReference proto.InternalMessageInfo func (m *AppMeshVirtualService) Reset() { *m = AppMeshVirtualService{} } func (*AppMeshVirtualService) ProtoMessage() {} func (*AppMeshVirtualService) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{19} + return fileDescriptor_e0e705f843545fab, []int{20} } func (m *AppMeshVirtualService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -610,7 +638,7 @@ var xxx_messageInfo_AppMeshVirtualService proto.InternalMessageInfo func (m *Argument) Reset() { *m = Argument{} } func (*Argument) ProtoMessage() {} func (*Argument) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{20} + return fileDescriptor_e0e705f843545fab, []int{21} } func (m *Argument) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -638,7 +666,7 @@ var xxx_messageInfo_Argument proto.InternalMessageInfo func (m *ArgumentValueFrom) Reset() { *m = ArgumentValueFrom{} } func (*ArgumentValueFrom) ProtoMessage() {} func (*ArgumentValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{21} + return fileDescriptor_e0e705f843545fab, []int{22} } func (m *ArgumentValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -666,7 +694,7 @@ var xxx_messageInfo_ArgumentValueFrom proto.InternalMessageInfo func (m *Authentication) Reset() { *m = Authentication{} } func (*Authentication) ProtoMessage() {} func (*Authentication) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{22} + return fileDescriptor_e0e705f843545fab, []int{23} } func (m *Authentication) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -694,7 +722,7 @@ var xxx_messageInfo_Authentication proto.InternalMessageInfo func (m *AwsResourceRef) Reset() { *m = AwsResourceRef{} } func (*AwsResourceRef) ProtoMessage() {} func (*AwsResourceRef) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{23} + return fileDescriptor_e0e705f843545fab, []int{24} } func (m *AwsResourceRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -722,7 +750,7 @@ var xxx_messageInfo_AwsResourceRef proto.InternalMessageInfo func (m *BlueGreenStatus) Reset() { *m = BlueGreenStatus{} } func (*BlueGreenStatus) ProtoMessage() {} func (*BlueGreenStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{24} + return fileDescriptor_e0e705f843545fab, []int{25} } func (m *BlueGreenStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -750,7 +778,7 @@ var xxx_messageInfo_BlueGreenStatus proto.InternalMessageInfo func (m *BlueGreenStrategy) Reset() { *m = BlueGreenStrategy{} } func (*BlueGreenStrategy) ProtoMessage() {} func (*BlueGreenStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{25} + return fileDescriptor_e0e705f843545fab, []int{26} } func (m *BlueGreenStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -778,7 +806,7 @@ var xxx_messageInfo_BlueGreenStrategy proto.InternalMessageInfo func (m *CanaryStatus) Reset() { *m = CanaryStatus{} } func (*CanaryStatus) ProtoMessage() {} func (*CanaryStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{26} + return fileDescriptor_e0e705f843545fab, []int{27} } func (m *CanaryStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -806,7 +834,7 @@ var xxx_messageInfo_CanaryStatus proto.InternalMessageInfo func (m *CanaryStep) Reset() { *m = CanaryStep{} } func (*CanaryStep) ProtoMessage() {} func (*CanaryStep) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{27} + return fileDescriptor_e0e705f843545fab, []int{28} } func (m *CanaryStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -834,7 +862,7 @@ var xxx_messageInfo_CanaryStep proto.InternalMessageInfo func (m *CanaryStrategy) Reset() { *m = CanaryStrategy{} } func (*CanaryStrategy) ProtoMessage() {} func (*CanaryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{28} + return fileDescriptor_e0e705f843545fab, []int{29} } func (m *CanaryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -862,7 +890,7 @@ var xxx_messageInfo_CanaryStrategy proto.InternalMessageInfo func (m *CloudWatchMetric) Reset() { *m = CloudWatchMetric{} } func (*CloudWatchMetric) ProtoMessage() {} func (*CloudWatchMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{29} + return fileDescriptor_e0e705f843545fab, []int{30} } func (m *CloudWatchMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -890,7 +918,7 @@ var xxx_messageInfo_CloudWatchMetric proto.InternalMessageInfo func (m *CloudWatchMetricDataQuery) Reset() { *m = CloudWatchMetricDataQuery{} } func (*CloudWatchMetricDataQuery) ProtoMessage() {} func (*CloudWatchMetricDataQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{30} + return fileDescriptor_e0e705f843545fab, []int{31} } func (m *CloudWatchMetricDataQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -918,7 +946,7 @@ var xxx_messageInfo_CloudWatchMetricDataQuery proto.InternalMessageInfo func (m *CloudWatchMetricStat) Reset() { *m = CloudWatchMetricStat{} } func (*CloudWatchMetricStat) ProtoMessage() {} func (*CloudWatchMetricStat) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{31} + return fileDescriptor_e0e705f843545fab, []int{32} } func (m *CloudWatchMetricStat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -946,7 +974,7 @@ var xxx_messageInfo_CloudWatchMetricStat proto.InternalMessageInfo func (m *CloudWatchMetricStatMetric) Reset() { *m = CloudWatchMetricStatMetric{} } func (*CloudWatchMetricStatMetric) ProtoMessage() {} func (*CloudWatchMetricStatMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{32} + return fileDescriptor_e0e705f843545fab, []int{33} } func (m *CloudWatchMetricStatMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -974,7 +1002,7 @@ var xxx_messageInfo_CloudWatchMetricStatMetric proto.InternalMessageInfo func (m *CloudWatchMetricStatMetricDimension) Reset() { *m = CloudWatchMetricStatMetricDimension{} } func (*CloudWatchMetricStatMetricDimension) ProtoMessage() {} func (*CloudWatchMetricStatMetricDimension) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{33} + return fileDescriptor_e0e705f843545fab, []int{34} } func (m *CloudWatchMetricStatMetricDimension) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1002,7 +1030,7 @@ var xxx_messageInfo_CloudWatchMetricStatMetricDimension proto.InternalMessageInf func (m *ClusterAnalysisTemplate) Reset() { *m = ClusterAnalysisTemplate{} } func (*ClusterAnalysisTemplate) ProtoMessage() {} func (*ClusterAnalysisTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{34} + return fileDescriptor_e0e705f843545fab, []int{35} } func (m *ClusterAnalysisTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1030,7 +1058,7 @@ var xxx_messageInfo_ClusterAnalysisTemplate proto.InternalMessageInfo func (m *ClusterAnalysisTemplateList) Reset() { *m = ClusterAnalysisTemplateList{} } func (*ClusterAnalysisTemplateList) ProtoMessage() {} func (*ClusterAnalysisTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{35} + return fileDescriptor_e0e705f843545fab, []int{36} } func (m *ClusterAnalysisTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1058,7 +1086,7 @@ var xxx_messageInfo_ClusterAnalysisTemplateList proto.InternalMessageInfo func (m *DatadogMetric) Reset() { *m = DatadogMetric{} } func (*DatadogMetric) ProtoMessage() {} func (*DatadogMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{36} + return fileDescriptor_e0e705f843545fab, []int{37} } func (m *DatadogMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1086,7 +1114,7 @@ var xxx_messageInfo_DatadogMetric proto.InternalMessageInfo func (m *DryRun) Reset() { *m = DryRun{} } func (*DryRun) ProtoMessage() {} func (*DryRun) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{37} + return fileDescriptor_e0e705f843545fab, []int{38} } func (m *DryRun) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1114,7 +1142,7 @@ var xxx_messageInfo_DryRun proto.InternalMessageInfo func (m *Experiment) Reset() { *m = Experiment{} } func (*Experiment) ProtoMessage() {} func (*Experiment) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{38} + return fileDescriptor_e0e705f843545fab, []int{39} } func (m *Experiment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1142,7 +1170,7 @@ var xxx_messageInfo_Experiment proto.InternalMessageInfo func (m *ExperimentAnalysisRunStatus) Reset() { *m = ExperimentAnalysisRunStatus{} } func (*ExperimentAnalysisRunStatus) ProtoMessage() {} func (*ExperimentAnalysisRunStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{39} + return fileDescriptor_e0e705f843545fab, []int{40} } func (m *ExperimentAnalysisRunStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1170,7 +1198,7 @@ var xxx_messageInfo_ExperimentAnalysisRunStatus proto.InternalMessageInfo func (m *ExperimentAnalysisTemplateRef) Reset() { *m = ExperimentAnalysisTemplateRef{} } func (*ExperimentAnalysisTemplateRef) ProtoMessage() {} func (*ExperimentAnalysisTemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{40} + return fileDescriptor_e0e705f843545fab, []int{41} } func (m *ExperimentAnalysisTemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1198,7 +1226,7 @@ var xxx_messageInfo_ExperimentAnalysisTemplateRef proto.InternalMessageInfo func (m *ExperimentCondition) Reset() { *m = ExperimentCondition{} } func (*ExperimentCondition) ProtoMessage() {} func (*ExperimentCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{41} + return fileDescriptor_e0e705f843545fab, []int{42} } func (m *ExperimentCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1226,7 +1254,7 @@ var xxx_messageInfo_ExperimentCondition proto.InternalMessageInfo func (m *ExperimentList) Reset() { *m = ExperimentList{} } func (*ExperimentList) ProtoMessage() {} func (*ExperimentList) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{42} + return fileDescriptor_e0e705f843545fab, []int{43} } func (m *ExperimentList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1254,7 +1282,7 @@ var xxx_messageInfo_ExperimentList proto.InternalMessageInfo func (m *ExperimentSpec) Reset() { *m = ExperimentSpec{} } func (*ExperimentSpec) ProtoMessage() {} func (*ExperimentSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{43} + return fileDescriptor_e0e705f843545fab, []int{44} } func (m *ExperimentSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1282,7 +1310,7 @@ var xxx_messageInfo_ExperimentSpec proto.InternalMessageInfo func (m *ExperimentStatus) Reset() { *m = ExperimentStatus{} } func (*ExperimentStatus) ProtoMessage() {} func (*ExperimentStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{44} + return fileDescriptor_e0e705f843545fab, []int{45} } func (m *ExperimentStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1310,7 +1338,7 @@ var xxx_messageInfo_ExperimentStatus proto.InternalMessageInfo func (m *FieldRef) Reset() { *m = FieldRef{} } func (*FieldRef) ProtoMessage() {} func (*FieldRef) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{45} + return fileDescriptor_e0e705f843545fab, []int{46} } func (m *FieldRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1338,7 +1366,7 @@ var xxx_messageInfo_FieldRef proto.InternalMessageInfo func (m *GraphiteMetric) Reset() { *m = GraphiteMetric{} } func (*GraphiteMetric) ProtoMessage() {} func (*GraphiteMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{46} + return fileDescriptor_e0e705f843545fab, []int{47} } func (m *GraphiteMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1366,7 +1394,7 @@ var xxx_messageInfo_GraphiteMetric proto.InternalMessageInfo func (m *HeaderRoutingMatch) Reset() { *m = HeaderRoutingMatch{} } func (*HeaderRoutingMatch) ProtoMessage() {} func (*HeaderRoutingMatch) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{47} + return fileDescriptor_e0e705f843545fab, []int{48} } func (m *HeaderRoutingMatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1394,7 +1422,7 @@ var xxx_messageInfo_HeaderRoutingMatch proto.InternalMessageInfo func (m *InfluxdbMetric) Reset() { *m = InfluxdbMetric{} } func (*InfluxdbMetric) ProtoMessage() {} func (*InfluxdbMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{48} + return fileDescriptor_e0e705f843545fab, []int{49} } func (m *InfluxdbMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1422,7 +1450,7 @@ var xxx_messageInfo_InfluxdbMetric proto.InternalMessageInfo func (m *IstioDestinationRule) Reset() { *m = IstioDestinationRule{} } func (*IstioDestinationRule) ProtoMessage() {} func (*IstioDestinationRule) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{49} + return fileDescriptor_e0e705f843545fab, []int{50} } func (m *IstioDestinationRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1450,7 +1478,7 @@ var xxx_messageInfo_IstioDestinationRule proto.InternalMessageInfo func (m *IstioTrafficRouting) Reset() { *m = IstioTrafficRouting{} } func (*IstioTrafficRouting) ProtoMessage() {} func (*IstioTrafficRouting) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{50} + return fileDescriptor_e0e705f843545fab, []int{51} } func (m *IstioTrafficRouting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1478,7 +1506,7 @@ var xxx_messageInfo_IstioTrafficRouting proto.InternalMessageInfo func (m *IstioVirtualService) Reset() { *m = IstioVirtualService{} } func (*IstioVirtualService) ProtoMessage() {} func (*IstioVirtualService) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{51} + return fileDescriptor_e0e705f843545fab, []int{52} } func (m *IstioVirtualService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1506,7 +1534,7 @@ var xxx_messageInfo_IstioVirtualService proto.InternalMessageInfo func (m *JobMetric) Reset() { *m = JobMetric{} } func (*JobMetric) ProtoMessage() {} func (*JobMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{52} + return fileDescriptor_e0e705f843545fab, []int{53} } func (m *JobMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1534,7 +1562,7 @@ var xxx_messageInfo_JobMetric proto.InternalMessageInfo func (m *KayentaMetric) Reset() { *m = KayentaMetric{} } func (*KayentaMetric) ProtoMessage() {} func (*KayentaMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{53} + return fileDescriptor_e0e705f843545fab, []int{54} } func (m *KayentaMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1562,7 +1590,7 @@ var xxx_messageInfo_KayentaMetric proto.InternalMessageInfo func (m *KayentaScope) Reset() { *m = KayentaScope{} } func (*KayentaScope) ProtoMessage() {} func (*KayentaScope) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{54} + return fileDescriptor_e0e705f843545fab, []int{55} } func (m *KayentaScope) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1590,7 +1618,7 @@ var xxx_messageInfo_KayentaScope proto.InternalMessageInfo func (m *KayentaThreshold) Reset() { *m = KayentaThreshold{} } func (*KayentaThreshold) ProtoMessage() {} func (*KayentaThreshold) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{55} + return fileDescriptor_e0e705f843545fab, []int{56} } func (m *KayentaThreshold) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1618,7 +1646,7 @@ var xxx_messageInfo_KayentaThreshold proto.InternalMessageInfo func (m *MangedRoutes) Reset() { *m = MangedRoutes{} } func (*MangedRoutes) ProtoMessage() {} func (*MangedRoutes) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{56} + return fileDescriptor_e0e705f843545fab, []int{57} } func (m *MangedRoutes) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1646,7 +1674,7 @@ var xxx_messageInfo_MangedRoutes proto.InternalMessageInfo func (m *Measurement) Reset() { *m = Measurement{} } func (*Measurement) ProtoMessage() {} func (*Measurement) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{57} + return fileDescriptor_e0e705f843545fab, []int{58} } func (m *Measurement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1674,7 +1702,7 @@ var xxx_messageInfo_Measurement proto.InternalMessageInfo func (m *MeasurementRetention) Reset() { *m = MeasurementRetention{} } func (*MeasurementRetention) ProtoMessage() {} func (*MeasurementRetention) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{58} + return fileDescriptor_e0e705f843545fab, []int{59} } func (m *MeasurementRetention) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1702,7 +1730,7 @@ var xxx_messageInfo_MeasurementRetention proto.InternalMessageInfo func (m *Metric) Reset() { *m = Metric{} } func (*Metric) ProtoMessage() {} func (*Metric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{59} + return fileDescriptor_e0e705f843545fab, []int{60} } func (m *Metric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1730,7 +1758,7 @@ var xxx_messageInfo_Metric proto.InternalMessageInfo func (m *MetricProvider) Reset() { *m = MetricProvider{} } func (*MetricProvider) ProtoMessage() {} func (*MetricProvider) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{60} + return fileDescriptor_e0e705f843545fab, []int{61} } func (m *MetricProvider) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1758,7 +1786,7 @@ var xxx_messageInfo_MetricProvider proto.InternalMessageInfo func (m *MetricResult) Reset() { *m = MetricResult{} } func (*MetricResult) ProtoMessage() {} func (*MetricResult) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{61} + return fileDescriptor_e0e705f843545fab, []int{62} } func (m *MetricResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1786,7 +1814,7 @@ var xxx_messageInfo_MetricResult proto.InternalMessageInfo func (m *NewRelicMetric) Reset() { *m = NewRelicMetric{} } func (*NewRelicMetric) ProtoMessage() {} func (*NewRelicMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{62} + return fileDescriptor_e0e705f843545fab, []int{63} } func (m *NewRelicMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1814,7 +1842,7 @@ var xxx_messageInfo_NewRelicMetric proto.InternalMessageInfo func (m *NginxTrafficRouting) Reset() { *m = NginxTrafficRouting{} } func (*NginxTrafficRouting) ProtoMessage() {} func (*NginxTrafficRouting) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{63} + return fileDescriptor_e0e705f843545fab, []int{64} } func (m *NginxTrafficRouting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1842,7 +1870,7 @@ var xxx_messageInfo_NginxTrafficRouting proto.InternalMessageInfo func (m *OAuth2Config) Reset() { *m = OAuth2Config{} } func (*OAuth2Config) ProtoMessage() {} func (*OAuth2Config) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{64} + return fileDescriptor_e0e705f843545fab, []int{65} } func (m *OAuth2Config) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1870,7 +1898,7 @@ var xxx_messageInfo_OAuth2Config proto.InternalMessageInfo func (m *ObjectRef) Reset() { *m = ObjectRef{} } func (*ObjectRef) ProtoMessage() {} func (*ObjectRef) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{65} + return fileDescriptor_e0e705f843545fab, []int{66} } func (m *ObjectRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1898,7 +1926,7 @@ var xxx_messageInfo_ObjectRef proto.InternalMessageInfo func (m *PauseCondition) Reset() { *m = PauseCondition{} } func (*PauseCondition) ProtoMessage() {} func (*PauseCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{66} + return fileDescriptor_e0e705f843545fab, []int{67} } func (m *PauseCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1926,7 +1954,7 @@ var xxx_messageInfo_PauseCondition proto.InternalMessageInfo func (m *PingPongSpec) Reset() { *m = PingPongSpec{} } func (*PingPongSpec) ProtoMessage() {} func (*PingPongSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{67} + return fileDescriptor_e0e705f843545fab, []int{68} } func (m *PingPongSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1954,7 +1982,7 @@ var xxx_messageInfo_PingPongSpec proto.InternalMessageInfo func (m *PodTemplateMetadata) Reset() { *m = PodTemplateMetadata{} } func (*PodTemplateMetadata) ProtoMessage() {} func (*PodTemplateMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{68} + return fileDescriptor_e0e705f843545fab, []int{69} } func (m *PodTemplateMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1984,7 +2012,7 @@ func (m *PreferredDuringSchedulingIgnoredDuringExecution) Reset() { } func (*PreferredDuringSchedulingIgnoredDuringExecution) ProtoMessage() {} func (*PreferredDuringSchedulingIgnoredDuringExecution) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{69} + return fileDescriptor_e0e705f843545fab, []int{70} } func (m *PreferredDuringSchedulingIgnoredDuringExecution) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2012,7 +2040,7 @@ var xxx_messageInfo_PreferredDuringSchedulingIgnoredDuringExecution proto.Intern func (m *PrometheusMetric) Reset() { *m = PrometheusMetric{} } func (*PrometheusMetric) ProtoMessage() {} func (*PrometheusMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{70} + return fileDescriptor_e0e705f843545fab, []int{71} } func (m *PrometheusMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2042,7 +2070,7 @@ func (m *RequiredDuringSchedulingIgnoredDuringExecution) Reset() { } func (*RequiredDuringSchedulingIgnoredDuringExecution) ProtoMessage() {} func (*RequiredDuringSchedulingIgnoredDuringExecution) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{71} + return fileDescriptor_e0e705f843545fab, []int{72} } func (m *RequiredDuringSchedulingIgnoredDuringExecution) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2070,7 +2098,7 @@ var xxx_messageInfo_RequiredDuringSchedulingIgnoredDuringExecution proto.Interna func (m *RollbackWindowSpec) Reset() { *m = RollbackWindowSpec{} } func (*RollbackWindowSpec) ProtoMessage() {} func (*RollbackWindowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{72} + return fileDescriptor_e0e705f843545fab, []int{73} } func (m *RollbackWindowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2098,7 +2126,7 @@ var xxx_messageInfo_RollbackWindowSpec proto.InternalMessageInfo func (m *Rollout) Reset() { *m = Rollout{} } func (*Rollout) ProtoMessage() {} func (*Rollout) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{73} + return fileDescriptor_e0e705f843545fab, []int{74} } func (m *Rollout) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2126,7 +2154,7 @@ var xxx_messageInfo_Rollout proto.InternalMessageInfo func (m *RolloutAnalysis) Reset() { *m = RolloutAnalysis{} } func (*RolloutAnalysis) ProtoMessage() {} func (*RolloutAnalysis) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{74} + return fileDescriptor_e0e705f843545fab, []int{75} } func (m *RolloutAnalysis) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2154,7 +2182,7 @@ var xxx_messageInfo_RolloutAnalysis proto.InternalMessageInfo func (m *RolloutAnalysisBackground) Reset() { *m = RolloutAnalysisBackground{} } func (*RolloutAnalysisBackground) ProtoMessage() {} func (*RolloutAnalysisBackground) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{75} + return fileDescriptor_e0e705f843545fab, []int{76} } func (m *RolloutAnalysisBackground) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2182,7 +2210,7 @@ var xxx_messageInfo_RolloutAnalysisBackground proto.InternalMessageInfo func (m *RolloutAnalysisRunStatus) Reset() { *m = RolloutAnalysisRunStatus{} } func (*RolloutAnalysisRunStatus) ProtoMessage() {} func (*RolloutAnalysisRunStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{76} + return fileDescriptor_e0e705f843545fab, []int{77} } func (m *RolloutAnalysisRunStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2207,34 +2235,6 @@ func (m *RolloutAnalysisRunStatus) XXX_DiscardUnknown() { var xxx_messageInfo_RolloutAnalysisRunStatus proto.InternalMessageInfo -func (m *RolloutAnalysisTemplate) Reset() { *m = RolloutAnalysisTemplate{} } -func (*RolloutAnalysisTemplate) ProtoMessage() {} -func (*RolloutAnalysisTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{77} -} -func (m *RolloutAnalysisTemplate) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RolloutAnalysisTemplate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *RolloutAnalysisTemplate) XXX_Merge(src proto.Message) { - xxx_messageInfo_RolloutAnalysisTemplate.Merge(m, src) -} -func (m *RolloutAnalysisTemplate) XXX_Size() int { - return m.Size() -} -func (m *RolloutAnalysisTemplate) XXX_DiscardUnknown() { - xxx_messageInfo_RolloutAnalysisTemplate.DiscardUnknown(m) -} - -var xxx_messageInfo_RolloutAnalysisTemplate proto.InternalMessageInfo - func (m *RolloutCondition) Reset() { *m = RolloutCondition{} } func (*RolloutCondition) ProtoMessage() {} func (*RolloutCondition) Descriptor() ([]byte, []int) { @@ -3232,6 +3232,7 @@ func init() { proto.RegisterType((*AnalysisRunStrategy)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisRunStrategy") proto.RegisterType((*AnalysisTemplate)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisTemplate") proto.RegisterType((*AnalysisTemplateList)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisTemplateList") + proto.RegisterType((*AnalysisTemplateRef)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisTemplateRef") proto.RegisterType((*AnalysisTemplateSpec)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AnalysisTemplateSpec") proto.RegisterType((*AntiAffinity)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.AntiAffinity") proto.RegisterType((*ApisixRoute)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.ApisixRoute") @@ -3304,7 +3305,6 @@ func init() { proto.RegisterType((*RolloutAnalysis)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutAnalysis") proto.RegisterType((*RolloutAnalysisBackground)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutAnalysisBackground") proto.RegisterType((*RolloutAnalysisRunStatus)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutAnalysisRunStatus") - proto.RegisterType((*RolloutAnalysisTemplate)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutAnalysisTemplate") proto.RegisterType((*RolloutCondition)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutCondition") proto.RegisterType((*RolloutExperimentStep)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutExperimentStep") proto.RegisterType((*RolloutExperimentStepAnalysisTemplateRef)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.RolloutExperimentStepAnalysisTemplateRef") @@ -3349,541 +3349,542 @@ func init() { } var fileDescriptor_e0e705f843545fab = []byte{ - // 8536 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x24, 0xd9, - 0x71, 0xd8, 0x35, 0x87, 0x43, 0x72, 0x6a, 0xb8, 0x24, 0xf7, 0xed, 0xee, 0x1d, 0x8f, 0x77, 0xb7, - 0xb3, 0xea, 0x73, 0x2e, 0x7b, 0xd6, 0x89, 0x94, 0xf6, 0xee, 0x92, 0x93, 0x4e, 0xb9, 0x64, 0x86, - 0xdc, 0xbd, 0xe5, 0x1e, 0xb9, 0xcb, 0xad, 0xe1, 0xde, 0xda, 0x92, 0xce, 0x56, 0x73, 0xe6, 0x71, - 0xd8, 0xcb, 0x99, 0xee, 0x51, 0x77, 0x0f, 0x77, 0x79, 0x3a, 0x58, 0x27, 0x0b, 0xa7, 0x28, 0x86, - 0x04, 0x2b, 0xb1, 0x85, 0x20, 0x48, 0x10, 0x28, 0x86, 0x01, 0x27, 0xb1, 0x7f, 0x04, 0x86, 0x83, - 0xe4, 0x87, 0x81, 0x08, 0x71, 0x6c, 0x2b, 0x40, 0x1c, 0xc8, 0x3f, 0x12, 0x39, 0x01, 0x4c, 0x47, - 0x74, 0xfe, 0x24, 0x48, 0x20, 0x24, 0x50, 0x60, 0x78, 0x7f, 0x04, 0xc1, 0xfb, 0xec, 0xd7, 0x3d, - 0x3d, 0x5c, 0x0e, 0xa7, 0xb9, 0x52, 0x12, 0xfd, 0x9b, 0x79, 0x55, 0xaf, 0xaa, 0xfa, 0x7d, 0xd6, - 0xab, 0x57, 0x55, 0x0f, 0xd6, 0x5a, 0x6e, 0xb4, 0xd3, 0xdb, 0x5a, 0x6c, 0xf8, 0x9d, 0x25, 0x27, - 0x68, 0xf9, 0xdd, 0xc0, 0xbf, 0xc7, 0x7f, 0x7c, 0x24, 0xf0, 0xdb, 0x6d, 0xbf, 0x17, 0x85, 0x4b, - 0xdd, 0xdd, 0xd6, 0x92, 0xd3, 0x75, 0xc3, 0x25, 0x5d, 0xb2, 0xf7, 0x31, 0xa7, 0xdd, 0xdd, 0x71, - 0x3e, 0xb6, 0xd4, 0xa2, 0x1e, 0x0d, 0x9c, 0x88, 0x36, 0x17, 0xbb, 0x81, 0x1f, 0xf9, 0xe4, 0x93, - 0x31, 0xb5, 0x45, 0x45, 0x8d, 0xff, 0xf8, 0x59, 0x55, 0x77, 0xb1, 0xbb, 0xdb, 0x5a, 0x64, 0xd4, - 0x16, 0x75, 0x89, 0xa2, 0xb6, 0xf0, 0x11, 0x43, 0x96, 0x96, 0xdf, 0xf2, 0x97, 0x38, 0xd1, 0xad, - 0xde, 0x36, 0xff, 0xc7, 0xff, 0xf0, 0x5f, 0x82, 0xd9, 0xc2, 0xf3, 0xbb, 0xaf, 0x85, 0x8b, 0xae, - 0xcf, 0x64, 0x5b, 0xda, 0x72, 0xa2, 0xc6, 0xce, 0xd2, 0x5e, 0x9f, 0x44, 0x0b, 0xb6, 0x81, 0xd4, - 0xf0, 0x03, 0x9a, 0x85, 0xf3, 0x4a, 0x8c, 0xd3, 0x71, 0x1a, 0x3b, 0xae, 0x47, 0x83, 0xfd, 0xf8, - 0xab, 0x3b, 0x34, 0x72, 0xb2, 0x6a, 0x2d, 0x0d, 0xaa, 0x15, 0xf4, 0xbc, 0xc8, 0xed, 0xd0, 0xbe, - 0x0a, 0x7f, 0xe9, 0x51, 0x15, 0xc2, 0xc6, 0x0e, 0xed, 0x38, 0x7d, 0xf5, 0x5e, 0x1e, 0x54, 0xaf, - 0x17, 0xb9, 0xed, 0x25, 0xd7, 0x8b, 0xc2, 0x28, 0x48, 0x57, 0xb2, 0xbf, 0x5f, 0x80, 0x52, 0x75, - 0xad, 0x56, 0x8f, 0x9c, 0xa8, 0x17, 0x92, 0x2f, 0x5b, 0x30, 0xdd, 0xf6, 0x9d, 0x66, 0xcd, 0x69, - 0x3b, 0x5e, 0x83, 0x06, 0xf3, 0xd6, 0x25, 0xeb, 0x72, 0xf9, 0xca, 0xda, 0xe2, 0x28, 0xfd, 0xb5, - 0x58, 0xbd, 0x1f, 0x22, 0x0d, 0xfd, 0x5e, 0xd0, 0xa0, 0x48, 0xb7, 0x6b, 0xe7, 0xbf, 0x7d, 0x50, - 0x79, 0xe2, 0xf0, 0xa0, 0x32, 0xbd, 0x66, 0x70, 0xc2, 0x04, 0x5f, 0xf2, 0x0d, 0x0b, 0xce, 0x36, - 0x1c, 0xcf, 0x09, 0xf6, 0x37, 0x9d, 0xa0, 0x45, 0xa3, 0x37, 0x03, 0xbf, 0xd7, 0x9d, 0x1f, 0x3b, - 0x05, 0x69, 0x9e, 0x96, 0xd2, 0x9c, 0x5d, 0x4e, 0xb3, 0xc3, 0x7e, 0x09, 0xb8, 0x5c, 0x61, 0xe4, - 0x6c, 0xb5, 0xa9, 0x29, 0x57, 0xe1, 0x34, 0xe5, 0xaa, 0xa7, 0xd9, 0x61, 0xbf, 0x04, 0xe4, 0x45, - 0x98, 0x74, 0xbd, 0x56, 0x40, 0xc3, 0x70, 0x7e, 0xfc, 0x92, 0x75, 0xb9, 0x54, 0x9b, 0x95, 0xd5, - 0x27, 0x57, 0x45, 0x31, 0x2a, 0xb8, 0xfd, 0x9b, 0x05, 0x38, 0x5b, 0x5d, 0xab, 0x6d, 0x06, 0xce, - 0xf6, 0xb6, 0xdb, 0x40, 0xbf, 0x17, 0xb9, 0x5e, 0xcb, 0x24, 0x60, 0x1d, 0x4d, 0x80, 0xbc, 0x0a, - 0xe5, 0x90, 0x06, 0x7b, 0x6e, 0x83, 0x6e, 0xf8, 0x41, 0xc4, 0x3b, 0xa5, 0x58, 0x3b, 0x27, 0xd1, - 0xcb, 0xf5, 0x18, 0x84, 0x26, 0x1e, 0xab, 0x16, 0xf8, 0x7e, 0x24, 0xe1, 0xbc, 0xcd, 0x4a, 0x71, - 0x35, 0x8c, 0x41, 0x68, 0xe2, 0x91, 0x15, 0x98, 0x73, 0x3c, 0xcf, 0x8f, 0x9c, 0xc8, 0xf5, 0xbd, - 0x8d, 0x80, 0x6e, 0xbb, 0x0f, 0xe4, 0x27, 0xce, 0xcb, 0xba, 0x73, 0xd5, 0x14, 0x1c, 0xfb, 0x6a, - 0x90, 0xaf, 0x5b, 0x30, 0x17, 0x46, 0x6e, 0x63, 0xd7, 0xf5, 0x68, 0x18, 0x2e, 0xfb, 0xde, 0xb6, - 0xdb, 0x9a, 0x2f, 0xf2, 0x6e, 0xbb, 0x39, 0x5a, 0xb7, 0xd5, 0x53, 0x54, 0x6b, 0xe7, 0x99, 0x48, - 0xe9, 0x52, 0xec, 0xe3, 0x4e, 0x3e, 0x0c, 0x25, 0xd9, 0xa2, 0x34, 0x9c, 0x9f, 0xb8, 0x54, 0xb8, - 0x5c, 0xaa, 0x9d, 0x39, 0x3c, 0xa8, 0x94, 0x56, 0x55, 0x21, 0xc6, 0x70, 0x7b, 0x05, 0xe6, 0xab, - 0x9d, 0x2d, 0x27, 0x0c, 0x9d, 0xa6, 0x1f, 0xa4, 0xba, 0xee, 0x32, 0x4c, 0x75, 0x9c, 0x6e, 0xd7, - 0xf5, 0x5a, 0xac, 0xef, 0x18, 0x9d, 0xe9, 0xc3, 0x83, 0xca, 0xd4, 0xba, 0x2c, 0x43, 0x0d, 0xb5, - 0xff, 0xc3, 0x18, 0x94, 0xab, 0x9e, 0xd3, 0xde, 0x0f, 0xdd, 0x10, 0x7b, 0x1e, 0xf9, 0x2c, 0x4c, - 0xb1, 0x55, 0xab, 0xe9, 0x44, 0x8e, 0x9c, 0xe9, 0x1f, 0x5d, 0x14, 0x8b, 0xc8, 0xa2, 0xb9, 0x88, - 0xc4, 0x9f, 0xcf, 0xb0, 0x17, 0xf7, 0x3e, 0xb6, 0x78, 0x6b, 0xeb, 0x1e, 0x6d, 0x44, 0xeb, 0x34, - 0x72, 0x6a, 0x44, 0xf6, 0x02, 0xc4, 0x65, 0xa8, 0xa9, 0x12, 0x1f, 0xc6, 0xc3, 0x2e, 0x6d, 0xc8, - 0x99, 0xbb, 0x3e, 0xe2, 0x0c, 0x89, 0x45, 0xaf, 0x77, 0x69, 0xa3, 0x36, 0x2d, 0x59, 0x8f, 0xb3, - 0x7f, 0xc8, 0x19, 0x91, 0xfb, 0x30, 0x11, 0xf2, 0xb5, 0x4c, 0x4e, 0xca, 0x5b, 0xf9, 0xb1, 0xe4, - 0x64, 0x6b, 0x33, 0x92, 0xe9, 0x84, 0xf8, 0x8f, 0x92, 0x9d, 0xfd, 0x1f, 0x2d, 0x38, 0x67, 0x60, - 0x57, 0x83, 0x56, 0xaf, 0x43, 0xbd, 0x88, 0x5c, 0x82, 0x71, 0xcf, 0xe9, 0x50, 0x39, 0xab, 0xb4, - 0xc8, 0x37, 0x9d, 0x0e, 0x45, 0x0e, 0x21, 0xcf, 0x43, 0x71, 0xcf, 0x69, 0xf7, 0x28, 0x6f, 0xa4, - 0x52, 0xed, 0x8c, 0x44, 0x29, 0xbe, 0xcd, 0x0a, 0x51, 0xc0, 0xc8, 0x7b, 0x50, 0xe2, 0x3f, 0xae, - 0x05, 0x7e, 0x27, 0xa7, 0x4f, 0x93, 0x12, 0xbe, 0xad, 0xc8, 0x8a, 0xe1, 0xa7, 0xff, 0x62, 0xcc, - 0xd0, 0xfe, 0x13, 0x0b, 0x66, 0x8d, 0x8f, 0x5b, 0x73, 0xc3, 0x88, 0x7c, 0xa6, 0x6f, 0xf0, 0x2c, - 0x1e, 0x6f, 0xf0, 0xb0, 0xda, 0x7c, 0xe8, 0xcc, 0xc9, 0x2f, 0x9d, 0x52, 0x25, 0xc6, 0xc0, 0xf1, - 0xa0, 0xe8, 0x46, 0xb4, 0x13, 0xce, 0x8f, 0x5d, 0x2a, 0x5c, 0x2e, 0x5f, 0x59, 0xcd, 0xad, 0x1b, - 0xe3, 0xf6, 0x5d, 0x65, 0xf4, 0x51, 0xb0, 0xb1, 0x7f, 0xab, 0x90, 0xe8, 0xbe, 0x75, 0x25, 0xc7, - 0x07, 0x16, 0x4c, 0xb4, 0x9d, 0x2d, 0xda, 0x16, 0x73, 0xab, 0x7c, 0xe5, 0x9d, 0xdc, 0x24, 0x51, - 0x3c, 0x16, 0xd7, 0x38, 0xfd, 0xab, 0x5e, 0x14, 0xec, 0xc7, 0xc3, 0x4b, 0x14, 0xa2, 0x64, 0x4e, - 0xfe, 0x8e, 0x05, 0xe5, 0x78, 0x55, 0x53, 0xcd, 0xb2, 0x95, 0xbf, 0x30, 0xf1, 0x62, 0x2a, 0x25, - 0xd2, 0x4b, 0xb4, 0x01, 0x41, 0x53, 0x96, 0x85, 0x8f, 0x43, 0xd9, 0xf8, 0x04, 0x32, 0x07, 0x85, - 0x5d, 0xba, 0x2f, 0x06, 0x3c, 0xb2, 0x9f, 0xe4, 0x7c, 0x62, 0x84, 0xcb, 0x21, 0xfd, 0x89, 0xb1, - 0xd7, 0xac, 0x85, 0x37, 0x60, 0x2e, 0xcd, 0x70, 0x98, 0xfa, 0xf6, 0x3f, 0x29, 0x26, 0x06, 0x26, - 0x5b, 0x08, 0x88, 0x0f, 0x93, 0x1d, 0x1a, 0x05, 0x6e, 0x43, 0x75, 0xd9, 0xca, 0x68, 0xad, 0xb4, - 0xce, 0x89, 0xc5, 0x1b, 0xa2, 0xf8, 0x1f, 0xa2, 0xe2, 0x42, 0x76, 0x60, 0xdc, 0x09, 0x5a, 0xaa, - 0x4f, 0xae, 0xe5, 0x33, 0x2d, 0xe3, 0xa5, 0xa2, 0x1a, 0xb4, 0x42, 0xe4, 0x1c, 0xc8, 0x12, 0x94, - 0x22, 0x1a, 0x74, 0x5c, 0xcf, 0x89, 0xc4, 0x0e, 0x3a, 0x55, 0x3b, 0x2b, 0xd1, 0x4a, 0x9b, 0x0a, - 0x80, 0x31, 0x0e, 0x69, 0xc3, 0x44, 0x33, 0xd8, 0xc7, 0x9e, 0x37, 0x3f, 0x9e, 0x47, 0x53, 0xac, - 0x70, 0x5a, 0xf1, 0x20, 0x15, 0xff, 0x51, 0xf2, 0x20, 0xbf, 0x6a, 0xc1, 0xf9, 0x0e, 0x75, 0xc2, - 0x5e, 0x40, 0xd9, 0x27, 0x20, 0x8d, 0xa8, 0xc7, 0x3a, 0x76, 0xbe, 0xc8, 0x99, 0xe3, 0xa8, 0xfd, - 0xd0, 0x4f, 0xb9, 0xf6, 0xac, 0x14, 0xe5, 0x7c, 0x16, 0x14, 0x33, 0xa5, 0x21, 0xef, 0x41, 0x39, - 0x8a, 0xda, 0xf5, 0x88, 0xe9, 0xc1, 0xad, 0xfd, 0xf9, 0x09, 0xbe, 0x78, 0x8d, 0xb8, 0xc2, 0x6c, - 0x6e, 0xae, 0x29, 0x82, 0xb5, 0x59, 0x36, 0x5b, 0x8c, 0x02, 0x34, 0xd9, 0xd9, 0xff, 0xbc, 0x08, - 0x67, 0xfb, 0xb6, 0x15, 0xf2, 0x0a, 0x14, 0xbb, 0x3b, 0x4e, 0xa8, 0xf6, 0x89, 0x8b, 0x6a, 0x91, - 0xda, 0x60, 0x85, 0x0f, 0x0f, 0x2a, 0x67, 0x54, 0x15, 0x5e, 0x80, 0x02, 0x99, 0x69, 0x6d, 0x1d, - 0x1a, 0x86, 0x4e, 0x4b, 0x6d, 0x1e, 0xc6, 0x20, 0xe5, 0xc5, 0xa8, 0xe0, 0xe4, 0xaf, 0x5b, 0x70, - 0x46, 0x0c, 0x58, 0xa4, 0x61, 0xaf, 0x1d, 0xb1, 0x0d, 0x92, 0x75, 0xca, 0x8d, 0x3c, 0x26, 0x87, - 0x20, 0x59, 0xbb, 0x20, 0xb9, 0x9f, 0x31, 0x4b, 0x43, 0x4c, 0xf2, 0x25, 0x77, 0xa1, 0x14, 0x46, - 0x4e, 0x10, 0xd1, 0x66, 0x35, 0xe2, 0xaa, 0x5c, 0xf9, 0xca, 0x4f, 0x1e, 0x6f, 0xe7, 0xd8, 0x74, - 0x3b, 0x54, 0xec, 0x52, 0x75, 0x45, 0x00, 0x63, 0x5a, 0xe4, 0x3d, 0x80, 0xa0, 0xe7, 0xd5, 0x7b, - 0x9d, 0x8e, 0x13, 0xec, 0x4b, 0xed, 0xee, 0xfa, 0x68, 0x9f, 0x87, 0x9a, 0x5e, 0xac, 0xe8, 0xc4, - 0x65, 0x68, 0xf0, 0x23, 0x5f, 0xb4, 0xe0, 0x8c, 0x98, 0x07, 0x4a, 0x82, 0x89, 0x9c, 0x25, 0x38, - 0xcb, 0x9a, 0x76, 0xc5, 0x64, 0x81, 0x49, 0x8e, 0xe4, 0x1d, 0x28, 0x37, 0xfc, 0x4e, 0xb7, 0x4d, - 0x45, 0xe3, 0x4e, 0x0e, 0xdd, 0xb8, 0x7c, 0xe8, 0x2e, 0xc7, 0x24, 0xd0, 0xa4, 0x67, 0xff, 0xbb, - 0xa4, 0x8e, 0xa3, 0x86, 0x34, 0xf9, 0x34, 0x3c, 0x1d, 0xf6, 0x1a, 0x0d, 0x1a, 0x86, 0xdb, 0xbd, - 0x36, 0xf6, 0xbc, 0xeb, 0x6e, 0x18, 0xf9, 0xc1, 0xfe, 0x9a, 0xdb, 0x71, 0x23, 0x3e, 0xa0, 0x8b, - 0xb5, 0xe7, 0x0e, 0x0f, 0x2a, 0x4f, 0xd7, 0x07, 0x21, 0xe1, 0xe0, 0xfa, 0xc4, 0x81, 0x67, 0x7a, - 0xde, 0x60, 0xf2, 0xe2, 0xf8, 0x51, 0x39, 0x3c, 0xa8, 0x3c, 0x73, 0x67, 0x30, 0x1a, 0x1e, 0x45, - 0xc3, 0xfe, 0xaf, 0x16, 0xdb, 0x86, 0xc4, 0x77, 0x6d, 0xd2, 0x4e, 0xb7, 0xcd, 0x96, 0xce, 0xd3, - 0x57, 0x8e, 0xa3, 0x84, 0x72, 0x8c, 0xf9, 0xec, 0xe5, 0x4a, 0xfe, 0x41, 0x1a, 0xb2, 0xfd, 0x5f, - 0x2c, 0x38, 0x9f, 0x46, 0x7e, 0x0c, 0x0a, 0x5d, 0x98, 0x54, 0xe8, 0x6e, 0xe6, 0xfb, 0xb5, 0x03, - 0xb4, 0xba, 0x2f, 0x8f, 0xf7, 0x7f, 0xeb, 0xff, 0xeb, 0x3a, 0x42, 0xbc, 0xe5, 0x17, 0x7e, 0x98, - 0x5b, 0xfe, 0xf8, 0x8f, 0xd2, 0x96, 0x6f, 0xff, 0xc3, 0x71, 0x98, 0xae, 0x7a, 0x91, 0x5b, 0xdd, - 0xde, 0x76, 0x3d, 0x37, 0xda, 0x27, 0x5f, 0x1d, 0x83, 0xa5, 0x6e, 0x40, 0xb7, 0x69, 0x10, 0xd0, - 0xe6, 0x4a, 0x2f, 0x70, 0xbd, 0x56, 0xbd, 0xb1, 0x43, 0x9b, 0xbd, 0xb6, 0xeb, 0xb5, 0x56, 0x5b, - 0x9e, 0xaf, 0x8b, 0xaf, 0x3e, 0xa0, 0x8d, 0x1e, 0xff, 0x24, 0x31, 0x29, 0x3a, 0xa3, 0x7d, 0xd2, - 0xc6, 0x70, 0x4c, 0x6b, 0x2f, 0x1f, 0x1e, 0x54, 0x96, 0x86, 0xac, 0x84, 0xc3, 0x7e, 0x1a, 0xf9, - 0xca, 0x18, 0x2c, 0x06, 0xf4, 0x73, 0x3d, 0xf7, 0xf8, 0xad, 0x21, 0x56, 0xad, 0xf6, 0x88, 0xbb, - 0xdb, 0x50, 0x3c, 0x6b, 0x57, 0x0e, 0x0f, 0x2a, 0x43, 0xd6, 0xc1, 0x21, 0xbf, 0xcb, 0xde, 0x80, - 0x72, 0xb5, 0xeb, 0x86, 0xee, 0x03, 0xf4, 0x7b, 0x11, 0x3d, 0xc6, 0xf9, 0xbd, 0x02, 0xc5, 0xa0, - 0xd7, 0xa6, 0x62, 0x6e, 0x97, 0x6a, 0x25, 0xb6, 0x0a, 0x21, 0x2b, 0x40, 0x51, 0x6e, 0xff, 0x3c, - 0x5b, 0x71, 0x39, 0xc9, 0x94, 0xe5, 0xe6, 0x1e, 0x14, 0x03, 0xc6, 0x44, 0x8e, 0xac, 0x51, 0x0f, - 0xb9, 0xb1, 0xd4, 0x52, 0x08, 0xf6, 0x13, 0x05, 0x0b, 0xfb, 0x77, 0xc6, 0xe0, 0x42, 0xb5, 0xdb, - 0x5d, 0xa7, 0xe1, 0x4e, 0x4a, 0x8a, 0x5f, 0xb4, 0x60, 0x66, 0xcf, 0x0d, 0xa2, 0x9e, 0xd3, 0x56, - 0xc6, 0x39, 0x21, 0x4f, 0x7d, 0x54, 0x79, 0x38, 0xb7, 0xb7, 0x13, 0xa4, 0x6b, 0xe4, 0xf0, 0xa0, - 0x32, 0x93, 0x2c, 0xc3, 0x14, 0x7b, 0xf2, 0xb7, 0x2d, 0x98, 0x93, 0x45, 0x37, 0xfd, 0x26, 0x35, - 0x8d, 0xbf, 0x77, 0xf2, 0x94, 0x49, 0x13, 0x17, 0x46, 0xbb, 0x74, 0x29, 0xf6, 0x09, 0x61, 0xff, - 0xf7, 0x31, 0x78, 0x6a, 0x00, 0x0d, 0xf2, 0x6b, 0x16, 0x9c, 0x17, 0x16, 0x63, 0x03, 0x84, 0x74, - 0x5b, 0xb6, 0xe6, 0x4f, 0xe7, 0x2d, 0x39, 0xb2, 0x29, 0x4e, 0xbd, 0x06, 0xad, 0xcd, 0xb3, 0xd5, - 0x70, 0x39, 0x83, 0x35, 0x66, 0x0a, 0xc4, 0x25, 0x15, 0x36, 0xe4, 0x94, 0xa4, 0x63, 0x8f, 0x45, - 0xd2, 0x7a, 0x06, 0x6b, 0xcc, 0x14, 0xc8, 0xfe, 0xab, 0xf0, 0xcc, 0x11, 0xe4, 0x1e, 0x3d, 0x39, - 0xed, 0x77, 0xf4, 0xa8, 0x4f, 0x8e, 0xb9, 0x63, 0xcc, 0x6b, 0x1b, 0x26, 0xf8, 0xd4, 0x51, 0x13, - 0x1b, 0xd8, 0xf6, 0xc7, 0xe7, 0x54, 0x88, 0x12, 0x62, 0xff, 0x8e, 0x05, 0x53, 0x43, 0x98, 0xfa, - 0x2a, 0x49, 0x53, 0x5f, 0xa9, 0xcf, 0xcc, 0x17, 0xf5, 0x9b, 0xf9, 0xde, 0x1c, 0xad, 0x37, 0x8e, - 0x63, 0xde, 0xfb, 0xbe, 0x05, 0x67, 0xfb, 0xcc, 0x81, 0x64, 0x07, 0xce, 0x77, 0xfd, 0xa6, 0x52, - 0x9b, 0xae, 0x3b, 0xe1, 0x0e, 0x87, 0xc9, 0xcf, 0x7b, 0x85, 0xf5, 0xe4, 0x46, 0x06, 0xfc, 0xe1, - 0x41, 0x65, 0x5e, 0x13, 0x49, 0x21, 0x60, 0x26, 0x45, 0xd2, 0x85, 0xa9, 0x6d, 0x97, 0xb6, 0x9b, - 0xf1, 0x10, 0x1c, 0x51, 0x41, 0xba, 0x26, 0xa9, 0x09, 0x4b, 0xb8, 0xfa, 0x87, 0x9a, 0x8b, 0xfd, - 0x03, 0x0b, 0x66, 0xaa, 0xbd, 0x68, 0x87, 0xa9, 0x07, 0x0d, 0x6e, 0x7c, 0x22, 0x1e, 0x14, 0x43, - 0xb7, 0xb5, 0xf7, 0x4a, 0x3e, 0x8b, 0x71, 0x9d, 0x91, 0x92, 0x37, 0x02, 0x5a, 0x37, 0xe5, 0x85, - 0x28, 0xd8, 0x90, 0x00, 0x26, 0x7c, 0xa7, 0x17, 0xed, 0x5c, 0x91, 0x9f, 0x3c, 0xe2, 0x41, 0xfc, - 0x16, 0xfb, 0x9c, 0x2b, 0x92, 0xa3, 0xd6, 0xd6, 0x44, 0x29, 0x4a, 0x4e, 0xf6, 0x17, 0x60, 0x26, - 0x79, 0xcd, 0x74, 0x8c, 0x31, 0xfb, 0x1c, 0x14, 0x9c, 0xc0, 0x93, 0x23, 0xb6, 0x2c, 0x11, 0x0a, - 0x55, 0xbc, 0x89, 0xac, 0x9c, 0xbc, 0x04, 0x53, 0xdb, 0xbd, 0x76, 0x9b, 0x55, 0x90, 0x77, 0x3a, - 0xfa, 0x14, 0x70, 0x4d, 0x96, 0xa3, 0xc6, 0xb0, 0xff, 0x7c, 0x1c, 0x66, 0x6b, 0xed, 0x1e, 0x7d, - 0x33, 0xa0, 0x54, 0x99, 0x3e, 0xaa, 0x30, 0xdb, 0x0d, 0xe8, 0x9e, 0x4b, 0xef, 0xd7, 0x69, 0x9b, - 0x36, 0x22, 0x3f, 0x90, 0xd2, 0x3c, 0x25, 0x09, 0xcd, 0x6e, 0x24, 0xc1, 0x98, 0xc6, 0x27, 0x6f, - 0xc0, 0x8c, 0xd3, 0x88, 0xdc, 0x3d, 0xaa, 0x29, 0x08, 0x71, 0x9f, 0x94, 0x14, 0x66, 0xaa, 0x09, - 0x28, 0xa6, 0xb0, 0xc9, 0x67, 0x60, 0x3e, 0x6c, 0x38, 0x6d, 0x7a, 0xa7, 0x2b, 0x59, 0x2d, 0xef, - 0xd0, 0xc6, 0xee, 0x86, 0xef, 0x7a, 0x91, 0x34, 0xb3, 0x5d, 0x92, 0x94, 0xe6, 0xeb, 0x03, 0xf0, - 0x70, 0x20, 0x05, 0xf2, 0x2f, 0x2c, 0x78, 0xae, 0x1b, 0xd0, 0x8d, 0xc0, 0xef, 0xf8, 0x6c, 0xa8, - 0xf5, 0x59, 0x7f, 0xa4, 0x15, 0xe4, 0xed, 0x11, 0x75, 0x29, 0x51, 0xd2, 0x7f, 0x65, 0xf1, 0xa1, - 0xc3, 0x83, 0xca, 0x73, 0x1b, 0x47, 0x09, 0x80, 0x47, 0xcb, 0x47, 0xfe, 0xa5, 0x05, 0x17, 0xbb, - 0x7e, 0x18, 0x1d, 0xf1, 0x09, 0xc5, 0x53, 0xfd, 0x04, 0xfb, 0xf0, 0xa0, 0x72, 0x71, 0xe3, 0x48, - 0x09, 0xf0, 0x11, 0x12, 0xda, 0x87, 0x65, 0x38, 0x6b, 0x8c, 0x3d, 0x69, 0xbb, 0x78, 0x1d, 0xce, - 0xa8, 0xc1, 0x10, 0xeb, 0x3e, 0xa5, 0xd8, 0x94, 0x55, 0x35, 0x81, 0x98, 0xc4, 0x65, 0xe3, 0x4e, - 0x0f, 0x45, 0x51, 0x3b, 0x35, 0xee, 0x36, 0x12, 0x50, 0x4c, 0x61, 0x93, 0x55, 0x38, 0x27, 0x4b, - 0x90, 0x76, 0xdb, 0x6e, 0xc3, 0x59, 0xf6, 0x7b, 0x72, 0xc8, 0x15, 0x6b, 0x4f, 0x1d, 0x1e, 0x54, - 0xce, 0x6d, 0xf4, 0x83, 0x31, 0xab, 0x0e, 0x59, 0x83, 0xf3, 0x4e, 0x2f, 0xf2, 0xf5, 0xf7, 0x5f, - 0xf5, 0xd8, 0x76, 0xda, 0xe4, 0x43, 0x6b, 0x4a, 0xec, 0xbb, 0xd5, 0x0c, 0x38, 0x66, 0xd6, 0x22, - 0x1b, 0x29, 0x6a, 0x75, 0xda, 0xf0, 0xbd, 0xa6, 0xe8, 0xe5, 0x62, 0x7c, 0x02, 0xab, 0x66, 0xe0, - 0x60, 0x66, 0x4d, 0xd2, 0x86, 0x99, 0x8e, 0xf3, 0xe0, 0x8e, 0xe7, 0xec, 0x39, 0x6e, 0x9b, 0x31, - 0x91, 0xe6, 0xb1, 0xc1, 0x46, 0x95, 0x5e, 0xe4, 0xb6, 0x17, 0x85, 0xdb, 0xc2, 0xe2, 0xaa, 0x17, - 0xdd, 0x0a, 0xea, 0x11, 0xd3, 0xd4, 0x85, 0x06, 0xb9, 0x9e, 0xa0, 0x85, 0x29, 0xda, 0xe4, 0x16, - 0x5c, 0xe0, 0xd3, 0x71, 0xc5, 0xbf, 0xef, 0xad, 0xd0, 0xb6, 0xb3, 0xaf, 0x3e, 0x60, 0x92, 0x7f, - 0xc0, 0xd3, 0x87, 0x07, 0x95, 0x0b, 0xf5, 0x2c, 0x04, 0xcc, 0xae, 0x47, 0x1c, 0x78, 0x26, 0x09, - 0x40, 0xba, 0xe7, 0x86, 0xae, 0xef, 0x09, 0x2b, 0xd4, 0x54, 0x6c, 0x85, 0xaa, 0x0f, 0x46, 0xc3, - 0xa3, 0x68, 0x90, 0xbf, 0x6b, 0xc1, 0xf9, 0xac, 0x69, 0x38, 0x5f, 0xca, 0xe3, 0xf2, 0x34, 0x35, - 0xb5, 0xc4, 0x88, 0xc8, 0x5c, 0x14, 0x32, 0x85, 0x20, 0xef, 0x5b, 0x30, 0xed, 0x18, 0x27, 0xe8, - 0x79, 0xc8, 0x63, 0xd7, 0x32, 0xcf, 0xe4, 0xb5, 0xb9, 0xc3, 0x83, 0x4a, 0xe2, 0x94, 0x8e, 0x09, - 0x8e, 0xe4, 0xef, 0x5b, 0x70, 0x21, 0x73, 0x8e, 0xcf, 0x97, 0x4f, 0xa3, 0x85, 0xf8, 0x20, 0xc9, - 0x5e, 0x73, 0xb2, 0xc5, 0x20, 0x5f, 0xb7, 0xf4, 0x56, 0xa6, 0xee, 0xd3, 0xe6, 0xa7, 0xb9, 0x68, - 0xb7, 0x47, 0x34, 0x1a, 0xc4, 0x5a, 0x93, 0x22, 0x5c, 0x3b, 0x67, 0xec, 0x8c, 0xaa, 0x10, 0xd3, - 0xec, 0xc9, 0xd7, 0x2c, 0xb5, 0x35, 0x6a, 0x89, 0xce, 0x9c, 0x96, 0x44, 0x24, 0xde, 0x69, 0xb5, - 0x40, 0x29, 0xe6, 0xe4, 0x67, 0x60, 0xc1, 0xd9, 0xf2, 0x83, 0x28, 0x73, 0xf2, 0xcd, 0xcf, 0xf0, - 0x69, 0x74, 0xf1, 0xf0, 0xa0, 0xb2, 0x50, 0x1d, 0x88, 0x85, 0x47, 0x50, 0xb0, 0x7f, 0xa3, 0x08, - 0xd3, 0xe2, 0x24, 0x24, 0xb7, 0xae, 0xdf, 0xb6, 0xe0, 0xd9, 0x46, 0x2f, 0x08, 0xa8, 0x17, 0xd5, - 0x23, 0xda, 0xed, 0xdf, 0xb8, 0xac, 0x53, 0xdd, 0xb8, 0x2e, 0x1d, 0x1e, 0x54, 0x9e, 0x5d, 0x3e, - 0x82, 0x3f, 0x1e, 0x29, 0x1d, 0xf9, 0xb7, 0x16, 0xd8, 0x12, 0xa1, 0xe6, 0x34, 0x76, 0x5b, 0x81, - 0xdf, 0xf3, 0x9a, 0xfd, 0x1f, 0x31, 0x76, 0xaa, 0x1f, 0xf1, 0xc2, 0xe1, 0x41, 0xc5, 0x5e, 0x7e, - 0xa4, 0x14, 0x78, 0x0c, 0x49, 0xc9, 0x9b, 0x70, 0x56, 0x62, 0x5d, 0x7d, 0xd0, 0xa5, 0x81, 0xcb, - 0xce, 0x1c, 0x52, 0x71, 0x8c, 0x5d, 0xb1, 0xd2, 0x08, 0xd8, 0x5f, 0x87, 0x84, 0x30, 0x79, 0x9f, - 0xba, 0xad, 0x9d, 0x48, 0xa9, 0x4f, 0x23, 0xfa, 0x5f, 0x49, 0xab, 0xc8, 0x5d, 0x41, 0xb3, 0x56, - 0x3e, 0x3c, 0xa8, 0x4c, 0xca, 0x3f, 0xa8, 0x38, 0x91, 0x9b, 0x30, 0x23, 0xce, 0xa9, 0x1b, 0xae, - 0xd7, 0xda, 0xf0, 0x3d, 0xe1, 0x44, 0x54, 0xaa, 0xbd, 0xa0, 0x36, 0xfc, 0x7a, 0x02, 0xfa, 0xf0, - 0xa0, 0x32, 0xad, 0x7e, 0x6f, 0xee, 0x77, 0x29, 0xa6, 0x6a, 0xdb, 0xbf, 0x37, 0x01, 0xa0, 0x86, - 0x2b, 0xed, 0x92, 0x0f, 0x43, 0x29, 0xa4, 0x91, 0xe0, 0x2a, 0x2f, 0x4e, 0xc4, 0x75, 0x97, 0x2a, - 0xc4, 0x18, 0x4e, 0x76, 0xa1, 0xd8, 0x75, 0x7a, 0x21, 0xcd, 0xe7, 0xfc, 0x20, 0x3b, 0x7f, 0x83, - 0x51, 0x14, 0x07, 0x53, 0xfe, 0x13, 0x05, 0x0f, 0xf2, 0x25, 0x0b, 0x80, 0x26, 0x3b, 0x6c, 0x64, - 0x03, 0x91, 0x64, 0x19, 0xf7, 0x29, 0x6b, 0x83, 0xda, 0xcc, 0xe1, 0x41, 0x05, 0x8c, 0xae, 0x37, - 0xd8, 0x92, 0xfb, 0x30, 0xe5, 0xa8, 0x35, 0x7f, 0xfc, 0x34, 0xd6, 0x7c, 0x7e, 0x5e, 0xd4, 0x83, - 0x56, 0x33, 0x23, 0x5f, 0xb1, 0x60, 0x26, 0xa4, 0x91, 0xec, 0x2a, 0xb6, 0xf2, 0x48, 0x85, 0x77, - 0xc4, 0x41, 0x57, 0x4f, 0xd0, 0x14, 0x2b, 0x68, 0xb2, 0x0c, 0x53, 0x7c, 0x95, 0x28, 0xd7, 0xa9, - 0xd3, 0xa4, 0x01, 0x37, 0x47, 0x48, 0x4d, 0x6a, 0x74, 0x51, 0x0c, 0x9a, 0x5a, 0x14, 0xa3, 0x0c, - 0x53, 0x7c, 0x95, 0x28, 0xeb, 0x6e, 0x10, 0xf8, 0x52, 0x94, 0xa9, 0x9c, 0x44, 0x31, 0x68, 0x6a, - 0x51, 0x8c, 0x32, 0x4c, 0xf1, 0xb5, 0xbf, 0x79, 0x06, 0x66, 0xd4, 0x44, 0x8a, 0x35, 0x7b, 0x61, - 0xfd, 0x1a, 0xa0, 0xd9, 0x2f, 0x9b, 0x40, 0x4c, 0xe2, 0xb2, 0xca, 0x62, 0xaa, 0x26, 0x15, 0x7b, - 0x5d, 0xb9, 0x6e, 0x02, 0x31, 0x89, 0x4b, 0x3a, 0x50, 0x0c, 0x23, 0xda, 0x55, 0x57, 0xec, 0x23, - 0xde, 0x00, 0xc7, 0xeb, 0x83, 0x61, 0x49, 0x60, 0xe4, 0x51, 0x70, 0xe1, 0x06, 0xdc, 0x28, 0x61, - 0xd3, 0x95, 0x93, 0x23, 0x9f, 0xf9, 0x99, 0x34, 0x17, 0x8b, 0xde, 0x48, 0x96, 0x61, 0x8a, 0x7d, - 0x86, 0xb2, 0x5f, 0x3c, 0x45, 0x65, 0xff, 0x53, 0x30, 0xd5, 0x71, 0x1e, 0xd4, 0x7b, 0x41, 0xeb, - 0xe4, 0x87, 0x0a, 0xe9, 0x32, 0x29, 0xa8, 0xa0, 0xa6, 0x47, 0xbe, 0x68, 0x19, 0x4b, 0x8e, 0xb8, - 0x4f, 0xbf, 0x9b, 0xef, 0x92, 0xa3, 0xf7, 0xca, 0x81, 0x8b, 0x4f, 0x9f, 0xea, 0x3d, 0xf5, 0xd8, - 0x55, 0x6f, 0xa6, 0x46, 0x8a, 0x09, 0xa2, 0xd5, 0xc8, 0xd2, 0xa9, 0xaa, 0x91, 0xcb, 0x09, 0x66, - 0x98, 0x62, 0xce, 0xe5, 0x11, 0x73, 0x4e, 0xcb, 0x03, 0xa7, 0x2a, 0x4f, 0x3d, 0xc1, 0x0c, 0x53, - 0xcc, 0x07, 0x9f, 0x37, 0xcb, 0xa7, 0x73, 0xde, 0x9c, 0xce, 0xe1, 0xbc, 0x79, 0xb4, 0x2a, 0x7e, - 0x66, 0x54, 0x55, 0x9c, 0xdc, 0x00, 0xd2, 0xdc, 0xf7, 0x9c, 0x8e, 0xdb, 0x90, 0x8b, 0x25, 0xdf, - 0x36, 0x67, 0xb8, 0x3d, 0x62, 0x41, 0x2e, 0x64, 0x64, 0xa5, 0x0f, 0x03, 0x33, 0x6a, 0x91, 0x08, - 0xa6, 0xba, 0x4a, 0xe3, 0x9a, 0xcd, 0x63, 0xf4, 0x2b, 0x0d, 0x4c, 0xb8, 0x49, 0xb0, 0x89, 0xa7, - 0x4a, 0x50, 0x73, 0x22, 0x6b, 0x70, 0xbe, 0xe3, 0x7a, 0x1b, 0x7e, 0x33, 0xdc, 0xa0, 0x81, 0xb4, - 0xb6, 0xd4, 0x69, 0x34, 0x3f, 0xc7, 0xdb, 0x86, 0x9f, 0xa0, 0xd7, 0x33, 0xe0, 0x98, 0x59, 0xcb, - 0xfe, 0x5f, 0x16, 0xcc, 0x2d, 0xb7, 0xfd, 0x5e, 0xf3, 0xae, 0x13, 0x35, 0x76, 0x84, 0x87, 0x00, - 0x79, 0x03, 0xa6, 0x5c, 0x2f, 0xa2, 0xc1, 0x9e, 0xd3, 0x96, 0xfb, 0x93, 0xad, 0xcc, 0xa7, 0xab, - 0xb2, 0xfc, 0xe1, 0x41, 0x65, 0x66, 0xa5, 0x17, 0x70, 0x2b, 0xb5, 0x58, 0xad, 0x50, 0xd7, 0x21, - 0xdf, 0xb4, 0xe0, 0xac, 0xf0, 0x31, 0x58, 0x71, 0x22, 0xe7, 0x76, 0x8f, 0x06, 0x2e, 0x55, 0x5e, - 0x06, 0x23, 0x2e, 0x54, 0x69, 0x59, 0x15, 0x83, 0xfd, 0x58, 0x51, 0x5f, 0x4f, 0x73, 0xc6, 0x7e, - 0x61, 0xec, 0x5f, 0x2a, 0xc0, 0xd3, 0x03, 0x69, 0x91, 0x05, 0x18, 0x73, 0x9b, 0xf2, 0xd3, 0x41, - 0xd2, 0x1d, 0x5b, 0x6d, 0xe2, 0x98, 0xdb, 0x24, 0x8b, 0x5c, 0xe7, 0x0c, 0x68, 0x18, 0xaa, 0x0b, - 0xe7, 0x92, 0x56, 0x0f, 0x65, 0x29, 0x1a, 0x18, 0xa4, 0x02, 0x45, 0xee, 0x2e, 0x2b, 0xcf, 0x13, - 0x5c, 0x8b, 0xe5, 0x9e, 0xa9, 0x28, 0xca, 0xc9, 0xcf, 0x5b, 0x00, 0x42, 0x40, 0x76, 0x1a, 0x91, - 0xbb, 0x24, 0xe6, 0xdb, 0x4c, 0x8c, 0xb2, 0x90, 0x32, 0xfe, 0x8f, 0x06, 0x57, 0xb2, 0x09, 0x13, - 0x4c, 0xa1, 0xf5, 0x9b, 0x27, 0xde, 0x14, 0xf9, 0x4d, 0xd4, 0x06, 0xa7, 0x81, 0x92, 0x16, 0x6b, - 0xab, 0x80, 0x46, 0xbd, 0xc0, 0x63, 0x4d, 0xcb, 0xb7, 0xc1, 0x29, 0x21, 0x05, 0xea, 0x52, 0x34, - 0x30, 0xec, 0x7f, 0x36, 0x06, 0xe7, 0xb3, 0x44, 0x67, 0xbb, 0xcd, 0x84, 0x90, 0x56, 0x1e, 0x8d, - 0x7f, 0x2a, 0xff, 0xf6, 0x91, 0xee, 0x32, 0xfa, 0x9a, 0x42, 0xfa, 0x0b, 0x4a, 0xbe, 0xe4, 0xa7, - 0x74, 0x0b, 0x8d, 0x9d, 0xb0, 0x85, 0x34, 0xe5, 0x54, 0x2b, 0x5d, 0x82, 0xf1, 0x90, 0xf5, 0x7c, - 0x21, 0x79, 0xdd, 0xc1, 0xfb, 0x88, 0x43, 0x18, 0x46, 0xcf, 0x73, 0x23, 0x19, 0x63, 0xa2, 0x31, - 0xee, 0x78, 0x6e, 0x84, 0x1c, 0x62, 0x7f, 0x63, 0x0c, 0x16, 0x06, 0x7f, 0x14, 0xf9, 0x86, 0x05, - 0xd0, 0x64, 0xc7, 0x95, 0x90, 0x3b, 0x6a, 0x0b, 0xf7, 0x22, 0xe7, 0xb4, 0xda, 0x70, 0x45, 0x71, - 0x8a, 0x7d, 0xcd, 0x74, 0x51, 0x88, 0x86, 0x20, 0xe4, 0x8a, 0x1a, 0xfa, 0xfc, 0xaa, 0x46, 0x4c, - 0x26, 0x5d, 0x67, 0x5d, 0x43, 0xd0, 0xc0, 0x62, 0xe7, 0x51, 0xcf, 0xe9, 0xd0, 0xb0, 0xeb, 0xe8, - 0x88, 0x1d, 0x7e, 0x1e, 0xbd, 0xa9, 0x0a, 0x31, 0x86, 0xdb, 0x6d, 0x78, 0xfe, 0x18, 0x72, 0xe6, - 0x14, 0x10, 0x61, 0xff, 0x0f, 0x0b, 0x9e, 0x5a, 0x6e, 0xf7, 0xc2, 0x88, 0x06, 0xff, 0xdf, 0xb8, - 0xee, 0xfd, 0x99, 0x05, 0xcf, 0x0c, 0xf8, 0xe6, 0xc7, 0xe0, 0xc1, 0xf7, 0x6e, 0xd2, 0x83, 0xef, - 0xce, 0xa8, 0x43, 0x3a, 0xf3, 0x3b, 0x06, 0x38, 0xf2, 0xfd, 0xeb, 0x02, 0x9c, 0x61, 0xcb, 0x56, - 0xd3, 0x6f, 0xe5, 0xb4, 0x71, 0x3e, 0x0f, 0xc5, 0xcf, 0xb1, 0x0d, 0x28, 0x3d, 0xc8, 0xf8, 0xae, - 0x84, 0x02, 0x46, 0xbe, 0x64, 0xc1, 0xe4, 0xe7, 0xe4, 0x9e, 0x2a, 0xce, 0x72, 0x23, 0x2e, 0x86, - 0x89, 0x6f, 0x58, 0x94, 0x3b, 0xa4, 0x88, 0xb3, 0xd0, 0xbe, 0x83, 0x6a, 0x2b, 0x55, 0x9c, 0xc9, - 0x8b, 0x30, 0xb9, 0xed, 0x07, 0x9d, 0x5e, 0xdb, 0x49, 0x07, 0xf7, 0x5d, 0x13, 0xc5, 0xa8, 0xe0, - 0x6c, 0x92, 0x3b, 0x5d, 0xf7, 0x6d, 0x1a, 0x84, 0xc2, 0xed, 0x3e, 0x31, 0xc9, 0xab, 0x1a, 0x82, - 0x06, 0x16, 0xaf, 0xd3, 0x6a, 0x05, 0xb4, 0xe5, 0x44, 0x7e, 0xc0, 0x77, 0x0e, 0xb3, 0x8e, 0x86, - 0xa0, 0x81, 0xb5, 0xf0, 0x09, 0x98, 0x36, 0x85, 0x1f, 0x2a, 0x66, 0xe3, 0x93, 0x20, 0x9d, 0x08, - 0x53, 0x4b, 0x92, 0x75, 0x9c, 0x25, 0xc9, 0xfe, 0xf7, 0x63, 0x60, 0x58, 0x87, 0x1e, 0xc3, 0x54, - 0xf7, 0x12, 0x53, 0x7d, 0x44, 0xcb, 0x86, 0x61, 0xeb, 0x1a, 0x14, 0xc1, 0xb6, 0x97, 0x8a, 0x60, - 0xbb, 0x99, 0x1b, 0xc7, 0xa3, 0x03, 0xd8, 0xbe, 0x6b, 0xc1, 0x33, 0x31, 0x72, 0xbf, 0xe1, 0xf6, - 0xd1, 0xeb, 0xf6, 0xab, 0x50, 0x76, 0xe2, 0x6a, 0x72, 0x62, 0x19, 0xe1, 0x43, 0x1a, 0x84, 0x26, - 0x5e, 0x1c, 0xfa, 0x50, 0x38, 0x61, 0xe8, 0xc3, 0xf8, 0xd1, 0xa1, 0x0f, 0xf6, 0x0f, 0xc6, 0xe0, - 0xb9, 0xfe, 0x2f, 0x53, 0x2b, 0xce, 0xf1, 0xbc, 0x20, 0x5e, 0x83, 0xe9, 0x48, 0x56, 0x30, 0xf6, - 0x4f, 0x1d, 0xca, 0xbc, 0x69, 0xc0, 0x30, 0x81, 0xc9, 0x6a, 0x36, 0xc4, 0x5a, 0x57, 0x6f, 0xf8, - 0x5d, 0x15, 0xb6, 0xa3, 0x6b, 0x2e, 0x1b, 0x30, 0x4c, 0x60, 0x6a, 0x9f, 0xe1, 0xf1, 0x53, 0xf7, - 0x19, 0xae, 0xc3, 0x05, 0xe5, 0x25, 0x79, 0xcd, 0x0f, 0xa4, 0xff, 0xbf, 0x5a, 0x41, 0xa6, 0x6a, - 0xcf, 0xc9, 0x2a, 0x17, 0x30, 0x0b, 0x09, 0xb3, 0xeb, 0xda, 0xdf, 0x2d, 0xc0, 0xb9, 0xb8, 0xd9, - 0x97, 0x7d, 0xaf, 0xe9, 0x72, 0x47, 0x9b, 0xd7, 0x61, 0x3c, 0xda, 0xef, 0xaa, 0xc6, 0xfe, 0x8b, - 0x4a, 0x9c, 0xcd, 0xfd, 0x2e, 0xeb, 0xed, 0xa7, 0x32, 0xaa, 0x70, 0xd3, 0x39, 0xaf, 0x44, 0xd6, - 0xf4, 0xec, 0x10, 0x3d, 0xf0, 0x4a, 0x72, 0x34, 0x3f, 0x3c, 0xa8, 0x64, 0x44, 0xf2, 0x2f, 0x6a, - 0x4a, 0xc9, 0x31, 0x4f, 0xee, 0xc1, 0x4c, 0xdb, 0x09, 0xa3, 0x3b, 0xdd, 0xa6, 0x13, 0xd1, 0x4d, - 0x57, 0xba, 0xb0, 0x0c, 0x17, 0x32, 0xa1, 0xef, 0xfa, 0xd7, 0x12, 0x94, 0x30, 0x45, 0x99, 0xec, - 0x01, 0x61, 0x25, 0x9b, 0x81, 0xe3, 0x85, 0xe2, 0xab, 0x18, 0xbf, 0xe1, 0xe3, 0x5f, 0xf4, 0xd1, - 0x79, 0xad, 0x8f, 0x1a, 0x66, 0x70, 0x20, 0x2f, 0xc0, 0x44, 0x40, 0x9d, 0x50, 0x6f, 0x07, 0x7a, - 0xfe, 0x23, 0x2f, 0x45, 0x09, 0x35, 0x27, 0xd4, 0xc4, 0x23, 0x26, 0xd4, 0x1f, 0x5b, 0x30, 0x13, - 0x77, 0xd3, 0x63, 0x50, 0x3d, 0x3a, 0x49, 0xd5, 0xe3, 0x7a, 0x5e, 0x4b, 0xe2, 0x00, 0x6d, 0xe3, - 0xf7, 0x27, 0xcc, 0xef, 0xe3, 0x01, 0x03, 0x9f, 0x87, 0x92, 0x9a, 0xd5, 0x4a, 0xa7, 0x1f, 0xd1, - 0x02, 0x91, 0xd0, 0xf6, 0x8c, 0x28, 0x3e, 0xc9, 0x04, 0x63, 0x7e, 0x4c, 0xd7, 0x69, 0x4a, 0x3d, - 0x46, 0x0e, 0x7b, 0xad, 0xeb, 0x28, 0xfd, 0x26, 0x4b, 0xd7, 0x51, 0x75, 0xc8, 0x1d, 0x78, 0xaa, - 0x1b, 0xf8, 0x3c, 0x96, 0x7c, 0x85, 0x3a, 0xcd, 0xb6, 0xeb, 0x51, 0x65, 0xe6, 0x11, 0xae, 0x26, - 0xcf, 0x1c, 0x1e, 0x54, 0x9e, 0xda, 0xc8, 0x46, 0xc1, 0x41, 0x75, 0x93, 0xd1, 0x88, 0xe3, 0xc7, - 0x88, 0x46, 0xfc, 0x1b, 0xda, 0x98, 0x4a, 0x43, 0x19, 0x13, 0xf8, 0xe9, 0xbc, 0xba, 0x32, 0x63, - 0x59, 0x8f, 0x87, 0x54, 0x55, 0x32, 0x45, 0xcd, 0x7e, 0xb0, 0xc5, 0x6e, 0xe2, 0x84, 0x16, 0xbb, - 0x38, 0xee, 0x62, 0xf2, 0x87, 0x19, 0x77, 0x31, 0xf5, 0x23, 0x15, 0x77, 0xf1, 0x41, 0x11, 0xe6, - 0xd2, 0x1a, 0xc8, 0xe9, 0xc7, 0x3a, 0xfe, 0x2d, 0x0b, 0xe6, 0xd4, 0xec, 0x11, 0x3c, 0xb5, 0xfe, - 0xbe, 0x96, 0xd3, 0xa4, 0x15, 0xba, 0x94, 0x4e, 0x41, 0xb1, 0x99, 0xe2, 0x86, 0x7d, 0xfc, 0xc9, - 0x3b, 0x50, 0xd6, 0x57, 0x16, 0x27, 0x0a, 0x7c, 0xe4, 0xb1, 0x79, 0xd5, 0x98, 0x04, 0x9a, 0xf4, - 0xc8, 0x07, 0x16, 0x40, 0x43, 0x6d, 0x73, 0x6a, 0x76, 0xdd, 0xce, 0x6b, 0x76, 0xe9, 0x0d, 0x34, - 0x56, 0x96, 0x75, 0x51, 0x88, 0x06, 0x63, 0xf2, 0x4b, 0xfc, 0xb2, 0x42, 0x6b, 0x77, 0x22, 0xb5, - 0xc5, 0xc8, 0x3e, 0xe5, 0x47, 0x28, 0xa6, 0xb1, 0x2a, 0x65, 0x80, 0x42, 0x4c, 0x08, 0x61, 0xbf, - 0x0e, 0xda, 0x0b, 0x98, 0x2d, 0x5b, 0xdc, 0x0f, 0x78, 0xc3, 0x89, 0x76, 0xe4, 0x10, 0xd4, 0xcb, - 0xd6, 0x35, 0x05, 0xc0, 0x18, 0xc7, 0xfe, 0x2c, 0xcc, 0xbc, 0x19, 0x38, 0xdd, 0x1d, 0x97, 0x5f, - 0x0a, 0xb0, 0xc3, 0xe7, 0x8b, 0x30, 0xe9, 0x34, 0x9b, 0x59, 0xd9, 0x52, 0xaa, 0xa2, 0x18, 0x15, - 0xfc, 0x58, 0xe7, 0x4c, 0xfb, 0xf7, 0x2c, 0x20, 0xf1, 0xc5, 0xaa, 0xeb, 0xb5, 0xd6, 0x9d, 0xa8, - 0xb1, 0xc3, 0xce, 0x47, 0x3b, 0xbc, 0x34, 0xeb, 0x7c, 0x74, 0x5d, 0x43, 0xd0, 0xc0, 0x22, 0xef, - 0x41, 0x59, 0xfc, 0x7b, 0x5b, 0x9f, 0xbe, 0x46, 0x77, 0x66, 0xe6, 0x1b, 0x0a, 0x97, 0x49, 0x8c, - 0xc2, 0xeb, 0x31, 0x07, 0x34, 0xd9, 0xb1, 0xa6, 0x5a, 0xf5, 0xb6, 0xdb, 0xbd, 0x07, 0xcd, 0xad, - 0xb8, 0xa9, 0xba, 0x81, 0xbf, 0xed, 0xb6, 0x69, 0xba, 0xa9, 0x36, 0x44, 0x31, 0x2a, 0xf8, 0xf1, - 0x9a, 0xea, 0x5f, 0x59, 0x70, 0x7e, 0x35, 0x8c, 0x5c, 0x7f, 0x85, 0x86, 0x11, 0xdb, 0x56, 0xd8, - 0xe2, 0xd3, 0x6b, 0x1f, 0xc7, 0xa1, 0x7f, 0x05, 0xe6, 0xe4, 0x25, 0x6f, 0x6f, 0x2b, 0xa4, 0x91, - 0xa1, 0xc7, 0xeb, 0x79, 0xbc, 0x9c, 0x82, 0x63, 0x5f, 0x0d, 0x46, 0x45, 0xde, 0xf6, 0xc6, 0x54, - 0x0a, 0x49, 0x2a, 0xf5, 0x14, 0x1c, 0xfb, 0x6a, 0xd8, 0xdf, 0x29, 0xc0, 0x39, 0xfe, 0x19, 0xa9, - 0x60, 0x9c, 0xaf, 0x0d, 0x0a, 0xc6, 0x19, 0x71, 0x2a, 0x73, 0x5e, 0x27, 0x08, 0xc5, 0xf9, 0x9b, - 0x16, 0xcc, 0x36, 0x93, 0x2d, 0x9d, 0x8f, 0xd1, 0x2b, 0xab, 0x0f, 0x85, 0x4f, 0x5b, 0xaa, 0x10, - 0xd3, 0xfc, 0xc9, 0x2f, 0x5b, 0x30, 0x9b, 0x14, 0x53, 0xad, 0xee, 0xa7, 0xd0, 0x48, 0xda, 0x09, - 0x3d, 0x59, 0x1e, 0x62, 0x5a, 0x04, 0xfb, 0x0f, 0xc6, 0x64, 0x97, 0x9e, 0x46, 0xa4, 0x09, 0xb9, - 0x0f, 0xa5, 0xa8, 0x1d, 0x8a, 0x42, 0xf9, 0xb5, 0x23, 0x9e, 0x08, 0x37, 0xd7, 0xea, 0xc2, 0xbf, - 0x22, 0x56, 0xda, 0x64, 0x09, 0x53, 0x3e, 0x15, 0x2f, 0xce, 0xb8, 0xd1, 0x95, 0x8c, 0x73, 0x39, - 0x8a, 0x6e, 0x2e, 0x6f, 0xa4, 0x19, 0xcb, 0x12, 0xc6, 0x58, 0xf1, 0xb2, 0x7f, 0xdd, 0x82, 0xd2, - 0x0d, 0x5f, 0xad, 0x23, 0x3f, 0x93, 0x83, 0xa1, 0x47, 0xeb, 0x83, 0xfa, 0x1e, 0x37, 0x3e, 0x62, - 0xbc, 0x91, 0x30, 0xf3, 0x3c, 0x6b, 0xd0, 0x5e, 0xe4, 0x49, 0xe3, 0x18, 0xa9, 0x1b, 0xfe, 0xd6, - 0x40, 0xdb, 0xec, 0xaf, 0x14, 0xe1, 0xcc, 0x5b, 0xce, 0x3e, 0xf5, 0x22, 0x67, 0xf8, 0x4d, 0xe2, - 0x55, 0x28, 0x3b, 0x5d, 0x7e, 0x51, 0x68, 0xe8, 0xf8, 0xb1, 0xe5, 0x24, 0x06, 0xa1, 0x89, 0x17, - 0x2f, 0x68, 0x22, 0xec, 0x23, 0x6b, 0x29, 0x5a, 0x4e, 0xc1, 0xb1, 0xaf, 0x06, 0xb9, 0x01, 0x44, - 0x46, 0x29, 0x57, 0x1b, 0x0d, 0xbf, 0xe7, 0x89, 0x25, 0x4d, 0x18, 0x55, 0xf4, 0x61, 0x73, 0xbd, - 0x0f, 0x03, 0x33, 0x6a, 0x91, 0xcf, 0xc0, 0x7c, 0x83, 0x53, 0x96, 0x47, 0x0f, 0x93, 0xa2, 0x38, - 0x7e, 0xea, 0x40, 0x8a, 0xe5, 0x01, 0x78, 0x38, 0x90, 0x02, 0x93, 0x34, 0x8c, 0xfc, 0xc0, 0x69, - 0x51, 0x93, 0xee, 0x44, 0x52, 0xd2, 0x7a, 0x1f, 0x06, 0x66, 0xd4, 0x22, 0x5f, 0x80, 0x52, 0xb4, - 0x13, 0xd0, 0x70, 0xc7, 0x6f, 0x37, 0xa5, 0x63, 0xc7, 0x88, 0x96, 0x36, 0xd9, 0xfb, 0x9b, 0x8a, - 0xaa, 0x31, 0xbc, 0x55, 0x11, 0xc6, 0x3c, 0x49, 0x00, 0x13, 0x61, 0xc3, 0xef, 0xd2, 0x50, 0xaa, - 0xec, 0x37, 0x72, 0xe1, 0xce, 0x2d, 0x47, 0x86, 0x8d, 0x8f, 0x73, 0x40, 0xc9, 0xc9, 0xfe, 0xdd, - 0x31, 0x98, 0x36, 0x11, 0x8f, 0xb1, 0x36, 0x7d, 0xc9, 0x82, 0xe9, 0x86, 0xef, 0x45, 0x81, 0xdf, - 0x16, 0xf6, 0xab, 0x7c, 0x34, 0x0a, 0x46, 0x6a, 0x85, 0x46, 0x8e, 0xdb, 0x36, 0x4c, 0x61, 0x06, - 0x1b, 0x4c, 0x30, 0x25, 0x5f, 0xb5, 0x60, 0x36, 0xf6, 0x03, 0x8c, 0x0d, 0x69, 0xb9, 0x0a, 0xa2, - 0x97, 0xfa, 0xab, 0x49, 0x4e, 0x98, 0x66, 0x6d, 0x6f, 0xc1, 0x5c, 0xba, 0xb7, 0x59, 0x53, 0x76, - 0x1d, 0x39, 0xd7, 0x0b, 0x71, 0x53, 0x6e, 0x38, 0x61, 0x88, 0x1c, 0x42, 0x5e, 0x82, 0xa9, 0x8e, - 0x13, 0xb4, 0x5c, 0xcf, 0x69, 0xf3, 0x56, 0x2c, 0x18, 0x0b, 0x92, 0x2c, 0x47, 0x8d, 0x61, 0x7f, - 0x14, 0xa6, 0xd7, 0x1d, 0xaf, 0x45, 0x9b, 0x72, 0x1d, 0x7e, 0x74, 0xac, 0xe3, 0x9f, 0x8e, 0x43, - 0xd9, 0x38, 0x9b, 0x9d, 0xfe, 0x39, 0x2b, 0x91, 0xc9, 0xa5, 0x90, 0x63, 0x26, 0x97, 0x4f, 0x01, - 0x6c, 0xbb, 0x9e, 0x1b, 0xee, 0x9c, 0x30, 0x47, 0x0c, 0xbf, 0xf8, 0xbe, 0xa6, 0x29, 0xa0, 0x41, - 0x2d, 0xbe, 0x5d, 0x2c, 0x1e, 0x91, 0x6e, 0xed, 0x03, 0xcb, 0xd8, 0x6e, 0x26, 0xf2, 0xf0, 0xa6, - 0x30, 0x3a, 0x66, 0x51, 0x6d, 0x3f, 0xe2, 0xe2, 0xe7, 0xa8, 0x5d, 0x69, 0x13, 0xa6, 0x02, 0x1a, - 0xf6, 0x3a, 0xf4, 0x44, 0xd9, 0x5c, 0xb8, 0x5f, 0x0b, 0xca, 0xfa, 0xa8, 0x29, 0x2d, 0xbc, 0x0e, - 0x67, 0x12, 0x22, 0x0c, 0x75, 0x7d, 0xe3, 0x43, 0xa6, 0x01, 0xe0, 0x24, 0x97, 0x39, 0xac, 0x2f, - 0xda, 0x46, 0x16, 0x17, 0xdd, 0x17, 0xc2, 0x7b, 0x49, 0xc0, 0xec, 0x1f, 0x4c, 0x80, 0x74, 0x10, - 0x38, 0xc6, 0x72, 0x65, 0x5e, 0x0b, 0x8e, 0x9d, 0xe0, 0x5a, 0xf0, 0x06, 0x4c, 0xbb, 0x9e, 0x1b, - 0xb9, 0x4e, 0x9b, 0x1b, 0x77, 0xe4, 0x76, 0xaa, 0xdc, 0xbb, 0xa7, 0x57, 0x0d, 0x58, 0x06, 0x9d, - 0x44, 0x5d, 0x72, 0x1b, 0x8a, 0x7c, 0xbf, 0x91, 0x03, 0x78, 0x78, 0x2f, 0x06, 0xee, 0xc0, 0x22, - 0x62, 0xbe, 0x04, 0x25, 0x7e, 0xf8, 0x10, 0x69, 0x6c, 0xf4, 0xf1, 0x5b, 0x8e, 0xe3, 0xf8, 0xf0, - 0x91, 0x82, 0x63, 0x5f, 0x0d, 0x46, 0x65, 0xdb, 0x71, 0xdb, 0xbd, 0x80, 0xc6, 0x54, 0x26, 0x92, - 0x54, 0xae, 0xa5, 0xe0, 0xd8, 0x57, 0x83, 0x6c, 0xc3, 0xb4, 0x2c, 0x13, 0x3e, 0x69, 0x93, 0x27, - 0xfc, 0x4a, 0xee, 0x7b, 0x78, 0xcd, 0xa0, 0x84, 0x09, 0xba, 0xa4, 0x07, 0x67, 0x5d, 0xaf, 0xe1, - 0x7b, 0x8d, 0x76, 0x2f, 0x74, 0xf7, 0x68, 0x1c, 0x70, 0x75, 0x12, 0x66, 0x17, 0x0e, 0x0f, 0x2a, - 0x67, 0x57, 0xd3, 0xe4, 0xb0, 0x9f, 0x03, 0xf9, 0xa2, 0x05, 0x17, 0x1a, 0xbe, 0x17, 0xf2, 0xbc, - 0x10, 0x7b, 0xf4, 0x6a, 0x10, 0xf8, 0x81, 0xe0, 0x5d, 0x3a, 0x21, 0x6f, 0x6e, 0x53, 0x5c, 0xce, - 0x22, 0x89, 0xd9, 0x9c, 0xc8, 0xbb, 0x30, 0xd5, 0x0d, 0xfc, 0x3d, 0xb7, 0x49, 0x03, 0xe9, 0xdf, - 0xb8, 0x96, 0x47, 0x9e, 0x9a, 0x0d, 0x49, 0x33, 0x5e, 0x7a, 0x54, 0x09, 0x6a, 0x7e, 0xf6, 0xff, - 0x2e, 0xc3, 0x4c, 0x12, 0x9d, 0xfc, 0x1c, 0x40, 0x37, 0xf0, 0x3b, 0x34, 0xda, 0xa1, 0x3a, 0x70, - 0xe6, 0xe6, 0xa8, 0xe9, 0x50, 0x14, 0x3d, 0xe5, 0x13, 0xc4, 0x96, 0x8b, 0xb8, 0x14, 0x0d, 0x8e, - 0x24, 0x80, 0xc9, 0x5d, 0xb1, 0xed, 0x4a, 0x2d, 0xe4, 0xad, 0x5c, 0x74, 0x26, 0xc9, 0x99, 0x47, - 0x7c, 0xc8, 0x22, 0x54, 0x8c, 0xc8, 0x16, 0x14, 0xee, 0xd3, 0xad, 0x7c, 0x62, 0xf1, 0xef, 0x52, - 0x79, 0x9a, 0xa9, 0x4d, 0x1e, 0x1e, 0x54, 0x0a, 0x77, 0xe9, 0x16, 0x32, 0xe2, 0xec, 0xbb, 0x9a, - 0xc2, 0x31, 0x40, 0x2e, 0x15, 0x6f, 0xe5, 0xe8, 0x65, 0x20, 0xbe, 0x4b, 0x16, 0xa1, 0x62, 0x44, - 0xde, 0x85, 0xd2, 0x7d, 0x67, 0x8f, 0x6e, 0x07, 0xbe, 0x17, 0x49, 0x47, 0xb4, 0x11, 0x63, 0x29, - 0xee, 0x2a, 0x72, 0x92, 0x2f, 0xdf, 0xde, 0x75, 0x21, 0xc6, 0xec, 0xc8, 0x1e, 0x4c, 0x79, 0xf4, - 0x3e, 0xd2, 0xb6, 0xdb, 0xc8, 0x27, 0x76, 0xe1, 0xa6, 0xa4, 0x26, 0x39, 0xf3, 0x7d, 0x4f, 0x95, - 0xa1, 0xe6, 0xc5, 0xfa, 0xf2, 0x9e, 0xbf, 0x25, 0x17, 0xaa, 0x11, 0xfb, 0x52, 0x9f, 0x4c, 0x45, - 0x5f, 0xde, 0xf0, 0xb7, 0x90, 0x11, 0x67, 0x73, 0xa4, 0xa1, 0xbd, 0xa0, 0xe4, 0x32, 0x75, 0x33, - 0x5f, 0xef, 0x2f, 0x31, 0x47, 0xe2, 0x52, 0x34, 0x38, 0xb2, 0xb6, 0x6d, 0x49, 0x63, 0xa5, 0x5c, - 0xa8, 0x46, 0x6c, 0xdb, 0xa4, 0xe9, 0x53, 0xb4, 0xad, 0x2a, 0x43, 0xcd, 0x8b, 0xf1, 0x75, 0xa5, - 0xe5, 0x2f, 0x9f, 0xa5, 0x2a, 0x69, 0x47, 0x14, 0x7c, 0x55, 0x19, 0x6a, 0x5e, 0xac, 0xbd, 0xc3, - 0xdd, 0xfd, 0xfb, 0x4e, 0x7b, 0xd7, 0xf5, 0x5a, 0x32, 0x10, 0x74, 0xd4, 0x94, 0xce, 0xbb, 0xfb, - 0x77, 0x05, 0x3d, 0xb3, 0xbd, 0xe3, 0x52, 0x34, 0x38, 0x92, 0xbf, 0x67, 0xc1, 0x44, 0xb7, 0xdd, - 0x6b, 0xb9, 0xde, 0xfc, 0x74, 0x1e, 0x1e, 0x42, 0xc9, 0x25, 0x77, 0x71, 0x83, 0x93, 0x16, 0x8a, - 0xe2, 0x4f, 0x6a, 0xa7, 0x46, 0x5e, 0xf8, 0x0b, 0x7f, 0x52, 0x99, 0xa7, 0x5e, 0xc3, 0x6f, 0xba, - 0x5e, 0x6b, 0xe9, 0x5e, 0xe8, 0x7b, 0x8b, 0xe8, 0xdc, 0x57, 0x3a, 0xba, 0x94, 0x69, 0xe1, 0xe3, - 0x50, 0x36, 0x48, 0x3c, 0x4a, 0xd1, 0x9b, 0x36, 0x15, 0xbd, 0x5f, 0x9f, 0x80, 0x69, 0x33, 0x91, - 0xe3, 0x31, 0xb4, 0x2f, 0x7d, 0xe2, 0x18, 0x1b, 0xe6, 0xc4, 0xc1, 0x8e, 0x98, 0xc6, 0xed, 0x91, - 0x32, 0x6f, 0xad, 0xe6, 0xa6, 0x70, 0xc7, 0x47, 0x4c, 0xa3, 0x30, 0xc4, 0x04, 0xd3, 0x21, 0x1c, - 0x4a, 0x98, 0xda, 0x2a, 0x14, 0xbb, 0x62, 0x52, 0x6d, 0x4d, 0xa8, 0x6a, 0x57, 0x00, 0xe2, 0x8c, - 0x83, 0xf2, 0x56, 0x51, 0xeb, 0xc3, 0x46, 0x26, 0x44, 0x03, 0x8b, 0xbc, 0x00, 0x13, 0x4c, 0xf5, - 0xa1, 0x4d, 0x19, 0xa7, 0xae, 0xcf, 0xf1, 0xd7, 0x78, 0x29, 0x4a, 0x28, 0x79, 0x8d, 0x69, 0xa9, - 0xb1, 0xc2, 0x22, 0xc3, 0xcf, 0xcf, 0xc7, 0x5a, 0x6a, 0x0c, 0xc3, 0x04, 0x26, 0x13, 0x9d, 0x32, - 0xfd, 0x82, 0xaf, 0x0d, 0x86, 0xe8, 0x5c, 0xe9, 0x40, 0x01, 0xe3, 0x76, 0xa5, 0x94, 0x3e, 0xc2, - 0xe7, 0x74, 0xd1, 0xb0, 0x2b, 0xa5, 0xe0, 0xd8, 0x57, 0x83, 0x7d, 0x8c, 0xbc, 0x10, 0x2d, 0x0b, - 0x6f, 0xe4, 0x01, 0x57, 0x99, 0x5f, 0x36, 0xcf, 0x5a, 0x39, 0xce, 0x21, 0x31, 0x6a, 0x8f, 0x7f, - 0xd8, 0x1a, 0xed, 0x58, 0xf4, 0x59, 0x98, 0x49, 0xee, 0x42, 0xb9, 0xdf, 0x7c, 0x7c, 0x65, 0x1c, - 0xce, 0xdd, 0x6c, 0xb9, 0x5e, 0x3a, 0x8b, 0x58, 0x56, 0x86, 0x7c, 0x6b, 0xe8, 0x0c, 0xf9, 0x3a, - 0xe0, 0x4d, 0xe6, 0x9f, 0xcf, 0x0e, 0x78, 0x53, 0x8f, 0x01, 0x24, 0x71, 0xc9, 0x1f, 0x5b, 0xf0, - 0xac, 0xd3, 0x14, 0xe7, 0x02, 0xa7, 0x2d, 0x4b, 0x8d, 0xc4, 0xce, 0x72, 0x46, 0x87, 0x23, 0xee, - 0xf2, 0xfd, 0x1f, 0xbf, 0x58, 0x3d, 0x82, 0xab, 0xe8, 0xf1, 0x9f, 0x90, 0x5f, 0xf0, 0xec, 0x51, - 0xa8, 0x78, 0xa4, 0xf8, 0xe4, 0xaf, 0xc0, 0x6c, 0xe2, 0x83, 0xa5, 0x25, 0xbc, 0x24, 0x2e, 0x2c, - 0xea, 0x49, 0x10, 0xa6, 0x71, 0x17, 0x6e, 0xc1, 0x87, 0x1e, 0x29, 0xe7, 0x50, 0x83, 0xed, 0xdb, - 0x16, 0x4c, 0x9b, 0x09, 0x7f, 0xc8, 0x4b, 0x30, 0x15, 0xf9, 0xbb, 0xd4, 0xbb, 0x13, 0x28, 0x6f, - 0x58, 0x3d, 0xd0, 0x37, 0x79, 0x39, 0xae, 0xa1, 0xc6, 0x60, 0xd8, 0x8d, 0xb6, 0x4b, 0xbd, 0x68, - 0xb5, 0x29, 0xbb, 0x59, 0x63, 0x2f, 0x8b, 0xf2, 0x15, 0xd4, 0x18, 0xc2, 0x81, 0x8d, 0xfd, 0xae, - 0xd3, 0x46, 0x40, 0x95, 0xef, 0xbc, 0xe1, 0xc0, 0x16, 0xc3, 0x30, 0x81, 0x49, 0x6c, 0x6d, 0xe2, - 0x1c, 0x8f, 0xef, 0x35, 0x52, 0x26, 0xc9, 0xdf, 0xb2, 0xa0, 0x24, 0x4c, 0xf4, 0x48, 0xb7, 0x53, - 0xfe, 0xab, 0x29, 0x23, 0x42, 0x75, 0x63, 0x35, 0xcb, 0x7f, 0xf5, 0x12, 0x8c, 0xef, 0xba, 0x9e, - 0xfa, 0x12, 0xbd, 0x2d, 0xbd, 0xe5, 0x7a, 0x4d, 0xe4, 0x10, 0xbd, 0x71, 0x15, 0x06, 0x6e, 0x5c, - 0x4b, 0x50, 0xd2, 0x5e, 0x1d, 0x72, 0xf9, 0xd7, 0xd6, 0x5b, 0xed, 0x05, 0x82, 0x31, 0x8e, 0xfd, - 0xab, 0x16, 0xcc, 0xf0, 0x00, 0xe9, 0xf8, 0x3c, 0xfc, 0xaa, 0x76, 0xb4, 0x12, 0x72, 0x3f, 0x97, - 0x74, 0xb4, 0x7a, 0x78, 0x50, 0x29, 0x8b, 0x90, 0xea, 0xa4, 0xdf, 0xd5, 0xa7, 0xa5, 0x11, 0x8d, - 0xbb, 0x83, 0x8d, 0x0d, 0x6d, 0xe3, 0x89, 0xc5, 0x54, 0x44, 0x30, 0xa6, 0x67, 0xbf, 0x07, 0xd3, - 0x66, 0xa4, 0x13, 0x79, 0x15, 0xca, 0x5d, 0xd7, 0x6b, 0x25, 0x23, 0x62, 0xf5, 0x45, 0xc3, 0x46, - 0x0c, 0x42, 0x13, 0x8f, 0x57, 0xf3, 0xe3, 0x6a, 0xa9, 0xfb, 0x89, 0x0d, 0xdf, 0xac, 0x16, 0xff, - 0xe1, 0x49, 0xf5, 0x33, 0x22, 0xea, 0x72, 0x4f, 0xaa, 0x9f, 0xc1, 0xe3, 0x87, 0x97, 0x54, 0x3f, - 0x4b, 0x98, 0xff, 0xbb, 0x92, 0xea, 0xff, 0x34, 0x0c, 0x9b, 0x70, 0x94, 0xed, 0xf5, 0xf7, 0xcd, - 0xac, 0x05, 0xba, 0xc5, 0x65, 0xda, 0x02, 0x09, 0xb5, 0xbf, 0x55, 0x80, 0xb9, 0xf4, 0x91, 0x3f, - 0x6f, 0x6f, 0x0a, 0xf2, 0x55, 0x0b, 0x66, 0x9c, 0x44, 0x72, 0xb7, 0x9c, 0x5e, 0xe8, 0x49, 0xd0, - 0x34, 0x92, 0x8b, 0x25, 0xca, 0x31, 0xc5, 0x9b, 0xfc, 0x05, 0x98, 0x8c, 0xdc, 0x0e, 0xf5, 0x7b, - 0xc2, 0x10, 0x58, 0x10, 0x07, 0xf2, 0x4d, 0x51, 0x84, 0x0a, 0xc6, 0x16, 0x65, 0x97, 0x6b, 0x50, - 0x01, 0x95, 0x6e, 0xb7, 0x73, 0xb1, 0xe5, 0x52, 0x94, 0xa3, 0xc6, 0x20, 0x0f, 0x60, 0x52, 0xf8, - 0x5d, 0x28, 0x07, 0x9b, 0xf5, 0x9c, 0x4c, 0x13, 0xc2, 0xb5, 0x23, 0xee, 0x02, 0xf1, 0x3f, 0x44, - 0xc5, 0xce, 0xfe, 0x28, 0x0c, 0x99, 0x81, 0xd5, 0xbe, 0x0a, 0x04, 0xfd, 0x76, 0x7b, 0xcb, 0x69, - 0xec, 0xde, 0x75, 0xbd, 0xa6, 0x7f, 0x9f, 0x2f, 0x45, 0x4b, 0x50, 0x0a, 0x64, 0x3c, 0x6a, 0x28, - 0x47, 0x8d, 0x5e, 0xcb, 0x54, 0xa0, 0x6a, 0x88, 0x31, 0x8e, 0xfd, 0x07, 0x63, 0x30, 0x29, 0x83, - 0xa7, 0x1f, 0x83, 0xdb, 0xff, 0x6e, 0xe2, 0x3e, 0x78, 0x35, 0x97, 0x98, 0xef, 0x81, 0x3e, 0xff, - 0x61, 0xca, 0xe7, 0xff, 0xad, 0x7c, 0xd8, 0x1d, 0xed, 0xf0, 0xff, 0xfb, 0x45, 0x98, 0x4d, 0x05, - 0xa3, 0x33, 0x5d, 0xbc, 0xcf, 0xcf, 0xf5, 0x4e, 0xae, 0xf1, 0xee, 0x3a, 0xd0, 0xe7, 0x68, 0x97, - 0xd7, 0x30, 0x91, 0x2f, 0xfb, 0x76, 0x6e, 0xef, 0x9c, 0xfc, 0x38, 0x75, 0xf6, 0xb0, 0xaf, 0x65, - 0x7c, 0xd3, 0x82, 0x73, 0x4e, 0xff, 0x43, 0x31, 0xd2, 0x66, 0x78, 0x3b, 0xf7, 0x17, 0x68, 0x6a, - 0xcf, 0x48, 0x21, 0xb3, 0xde, 0xe3, 0xc1, 0x2c, 0x51, 0xec, 0xff, 0x6c, 0xc1, 0xd3, 0x03, 0xd3, - 0x2a, 0xf0, 0xac, 0x5c, 0x41, 0x12, 0x2a, 0xd7, 0x8c, 0x9c, 0x93, 0xc7, 0xe8, 0xfb, 0xe3, 0x74, - 0x22, 0xa5, 0x34, 0x7b, 0xf2, 0x0a, 0x4c, 0x73, 0x1d, 0x8d, 0xad, 0x9e, 0x11, 0xed, 0xca, 0xeb, - 0x2f, 0x7e, 0x11, 0x52, 0x37, 0xca, 0x31, 0x81, 0x65, 0x7f, 0xd3, 0x82, 0xf9, 0x41, 0x39, 0x9a, - 0x8e, 0x61, 0x9c, 0xf9, 0xcb, 0xa9, 0xd0, 0x89, 0x4a, 0x5f, 0xe8, 0x44, 0xca, 0x3c, 0xa3, 0xa2, - 0x24, 0x0c, 0xcb, 0x48, 0xe1, 0x11, 0x91, 0x01, 0x5f, 0xb3, 0xe0, 0xa9, 0x01, 0x13, 0xbe, 0x2f, - 0x84, 0xc6, 0x3a, 0x71, 0x08, 0xcd, 0xd8, 0x71, 0x43, 0x68, 0xec, 0x3f, 0x2c, 0xc0, 0x9c, 0x94, - 0x27, 0x56, 0xd4, 0x5f, 0x4b, 0x04, 0xa0, 0xfc, 0x44, 0x2a, 0x00, 0xe5, 0x7c, 0x1a, 0xff, 0xc7, - 0xd1, 0x27, 0x3f, 0x5a, 0xd1, 0x27, 0x7f, 0x3e, 0x06, 0x17, 0x32, 0x53, 0x47, 0x91, 0xaf, 0x64, - 0xec, 0x5e, 0x77, 0x73, 0xce, 0x51, 0x75, 0xcc, 0xfd, 0x6b, 0xd4, 0x90, 0x8d, 0x5f, 0x36, 0x43, - 0x25, 0xc4, 0x6e, 0xb4, 0x7d, 0x0a, 0xd9, 0xb6, 0x86, 0x8c, 0x9a, 0xb0, 0x7f, 0xa1, 0x00, 0x97, - 0x8f, 0x4b, 0xe8, 0x47, 0x34, 0xaa, 0x2e, 0x4c, 0x44, 0xd5, 0x3d, 0x26, 0xcd, 0xe2, 0x54, 0x02, - 0xec, 0xfe, 0xc1, 0xb8, 0xde, 0xf6, 0xfa, 0xc7, 0xe7, 0xb1, 0x7c, 0x25, 0x26, 0x99, 0xf6, 0xa9, - 0xb2, 0x6e, 0xc7, 0x4b, 0xe1, 0x64, 0x5d, 0x14, 0x3f, 0x3c, 0xa8, 0x9c, 0x8d, 0x13, 0x98, 0xc8, - 0x42, 0x54, 0x95, 0xc8, 0x65, 0x98, 0x0a, 0x04, 0x54, 0xc5, 0x11, 0x49, 0x87, 0x13, 0x51, 0x86, - 0x1a, 0x4a, 0xbe, 0x60, 0xa8, 0xeb, 0xe3, 0xa7, 0x95, 0xa7, 0xe7, 0x28, 0x3f, 0x9a, 0x77, 0x60, - 0x2a, 0x54, 0xa9, 0xa1, 0x85, 0xe2, 0xf2, 0xf2, 0x31, 0xc3, 0xd3, 0xd8, 0x19, 0x5c, 0xe5, 0x89, - 0x16, 0xdf, 0xa7, 0xb3, 0x48, 0x6b, 0x92, 0xc4, 0xd6, 0xc7, 0x5f, 0x61, 0xe7, 0x87, 0xfe, 0xa3, - 0x2f, 0x89, 0x60, 0x52, 0x3e, 0x87, 0x2a, 0x2f, 0x20, 0xd7, 0x73, 0x0a, 0x45, 0x91, 0x8e, 0xca, - 0xfc, 0x54, 0xa9, 0xcc, 0x30, 0x8a, 0x95, 0xfd, 0x5d, 0x0b, 0xca, 0x72, 0x8c, 0x3c, 0x86, 0x38, - 0xbd, 0x7b, 0xc9, 0x38, 0xbd, 0xab, 0xb9, 0xac, 0x58, 0x03, 0x82, 0xf4, 0xee, 0xc1, 0xb4, 0x99, - 0xb3, 0x90, 0x7c, 0xca, 0x58, 0x71, 0xad, 0x51, 0xb2, 0x80, 0xa9, 0x35, 0x39, 0x5e, 0x8d, 0xed, - 0xdf, 0x28, 0xe9, 0x56, 0xe4, 0x67, 0x57, 0x73, 0xe4, 0x5b, 0x47, 0x8e, 0x7c, 0x73, 0xe0, 0x8d, - 0xe5, 0x3f, 0xf0, 0x6e, 0xc3, 0x94, 0x5a, 0x16, 0xa5, 0xf2, 0xf0, 0xbc, 0xe9, 0xb9, 0xcc, 0x34, - 0x10, 0x46, 0xcc, 0x98, 0x2e, 0xfc, 0x0c, 0x1a, 0x1b, 0x87, 0xd5, 0x72, 0xad, 0xc9, 0x90, 0x77, - 0xa1, 0x7c, 0xdf, 0x0f, 0x76, 0xdb, 0xbe, 0xc3, 0xf3, 0xf1, 0x43, 0x1e, 0x97, 0xe5, 0xda, 0xc0, - 0x2b, 0xc2, 0x47, 0xee, 0xc6, 0xf4, 0xd1, 0x64, 0x46, 0xaa, 0x30, 0xdb, 0x71, 0x3d, 0xa4, 0x4e, - 0x53, 0x87, 0xe3, 0x8d, 0x8b, 0x5c, 0xd8, 0x4a, 0xb5, 0x5e, 0x4f, 0x82, 0x31, 0x8d, 0xcf, 0x8d, - 0x3f, 0x41, 0xc2, 0xda, 0x20, 0x13, 0xde, 0x6e, 0x8c, 0x3e, 0x18, 0x93, 0x16, 0x0c, 0x11, 0x3f, - 0x91, 0x2c, 0xc7, 0x14, 0x6f, 0xf2, 0x79, 0x98, 0x0a, 0xd5, 0x43, 0x83, 0xc5, 0x1c, 0x0f, 0x1d, - 0xfa, 0xb1, 0x41, 0xdd, 0x95, 0xfa, 0xb5, 0x41, 0xcd, 0x90, 0xac, 0xc1, 0x79, 0x65, 0x3e, 0x49, - 0xbc, 0x99, 0x36, 0x11, 0xe7, 0xaf, 0xc2, 0x0c, 0x38, 0x66, 0xd6, 0x62, 0xaa, 0x1c, 0xcf, 0x05, - 0x2a, 0x2e, 0x27, 0x8d, 0xfb, 0x3c, 0x3e, 0xff, 0x9a, 0x28, 0xa1, 0x47, 0x45, 0x9b, 0x4e, 0x8d, - 0x10, 0x6d, 0x5a, 0x87, 0x0b, 0x69, 0x10, 0x4f, 0x4c, 0xc6, 0x73, 0xa1, 0x19, 0x5b, 0xe8, 0x46, - 0x16, 0x12, 0x66, 0xd7, 0x25, 0x77, 0xa1, 0x14, 0x50, 0x7e, 0xc8, 0xaa, 0x2a, 0xbf, 0xae, 0xa1, - 0x3d, 0x58, 0x51, 0x11, 0xc0, 0x98, 0x16, 0xeb, 0x77, 0x27, 0x99, 0x9d, 0xfa, 0x76, 0x8e, 0x2f, - 0x11, 0xcb, 0xbe, 0x1f, 0x90, 0x30, 0xd0, 0xfe, 0x37, 0xb3, 0x70, 0x26, 0x61, 0x03, 0x22, 0xcf, - 0x43, 0x91, 0x67, 0x6a, 0xe3, 0xab, 0xd5, 0x54, 0xbc, 0xa2, 0x8a, 0xc6, 0x11, 0x30, 0xf2, 0x8b, - 0x16, 0xcc, 0x76, 0x13, 0x77, 0x1a, 0x6a, 0x21, 0x1f, 0xd1, 0x70, 0x9a, 0xbc, 0x28, 0x31, 0xde, - 0x75, 0x48, 0x32, 0xc3, 0x34, 0x77, 0xb6, 0x1e, 0x48, 0x37, 0xf0, 0x36, 0x0d, 0x38, 0xb6, 0x54, - 0xf4, 0x34, 0x89, 0xe5, 0x24, 0x18, 0xd3, 0xf8, 0xac, 0x87, 0xf9, 0xd7, 0x8d, 0xf2, 0xda, 0x64, - 0x55, 0x11, 0xc0, 0x98, 0x16, 0x79, 0x03, 0x66, 0x64, 0x52, 0xe2, 0x0d, 0xbf, 0x79, 0xdd, 0x09, - 0x77, 0xe4, 0x09, 0x47, 0x9f, 0xc8, 0x96, 0x13, 0x50, 0x4c, 0x61, 0xf3, 0x6f, 0x8b, 0x33, 0x3f, - 0x73, 0x02, 0x13, 0xc9, 0x67, 0x2f, 0x96, 0x93, 0x60, 0x4c, 0xe3, 0x93, 0x97, 0x8c, 0x6d, 0x48, - 0x38, 0x0c, 0xe8, 0xd5, 0x20, 0x63, 0x2b, 0xaa, 0xc2, 0x6c, 0x8f, 0x1f, 0x08, 0x9b, 0x0a, 0x28, - 0xe7, 0xa3, 0x66, 0x78, 0x27, 0x09, 0xc6, 0x34, 0x3e, 0x79, 0x1d, 0xce, 0x04, 0x6c, 0xb1, 0xd5, - 0x04, 0x84, 0x17, 0x81, 0xbe, 0x24, 0x46, 0x13, 0x88, 0x49, 0x5c, 0xf2, 0x26, 0x9c, 0x8d, 0x73, - 0x78, 0x2a, 0x02, 0xc2, 0xad, 0x40, 0x27, 0x94, 0xab, 0xa6, 0x11, 0xb0, 0xbf, 0x0e, 0xf9, 0x6b, - 0x30, 0x67, 0xb4, 0xc4, 0xaa, 0xd7, 0xa4, 0x0f, 0x64, 0x9e, 0x45, 0xfe, 0x8c, 0xd3, 0x72, 0x0a, - 0x86, 0x7d, 0xd8, 0xe4, 0x13, 0x30, 0xd3, 0xf0, 0xdb, 0x6d, 0xbe, 0xc6, 0x89, 0x27, 0x17, 0x44, - 0x42, 0x45, 0x91, 0x7a, 0x32, 0x01, 0xc1, 0x14, 0x26, 0xb9, 0x01, 0xc4, 0xdf, 0x62, 0xea, 0x15, - 0x6d, 0xbe, 0x49, 0x3d, 0x2a, 0x35, 0x8e, 0x33, 0xc9, 0x20, 0x94, 0x5b, 0x7d, 0x18, 0x98, 0x51, - 0x8b, 0xe7, 0xa3, 0x33, 0x82, 0x76, 0x67, 0xf2, 0x78, 0x1a, 0x31, 0x6d, 0xbe, 0x78, 0x64, 0xc4, - 0x6e, 0x00, 0x13, 0x22, 0x26, 0x28, 0x9f, 0xcc, 0x8a, 0x66, 0xf6, 0xf5, 0x78, 0x8f, 0x10, 0xa5, - 0x28, 0x39, 0x91, 0x9f, 0x83, 0xd2, 0x96, 0x7a, 0x8a, 0x83, 0xa7, 0x53, 0x1c, 0x79, 0x5f, 0x4c, - 0xbd, 0x2a, 0x13, 0x1f, 0xcf, 0x35, 0x00, 0x63, 0x96, 0xe4, 0x05, 0x28, 0x5f, 0xdf, 0xa8, 0xea, - 0x51, 0x78, 0x96, 0xf7, 0xfe, 0x38, 0xab, 0x82, 0x26, 0x80, 0xcd, 0x30, 0xad, 0xbe, 0x91, 0xe4, - 0x4d, 0x79, 0x86, 0x36, 0xc6, 0xb0, 0xf9, 0xd5, 0x3f, 0xd6, 0xe7, 0xcf, 0xa5, 0xb0, 0x65, 0x39, - 0x6a, 0x0c, 0xf2, 0x0e, 0x94, 0xe5, 0x7e, 0xc1, 0xd7, 0xa6, 0xf3, 0x27, 0x0b, 0x08, 0xc7, 0x98, - 0x04, 0x9a, 0xf4, 0xf8, 0x9d, 0x2d, 0x7f, 0xa1, 0x80, 0x5e, 0xeb, 0xb5, 0xdb, 0xf3, 0x17, 0xf8, - 0xba, 0x19, 0xdf, 0xd9, 0xc6, 0x20, 0x34, 0xf1, 0xc8, 0xcb, 0xca, 0x85, 0xeb, 0xc9, 0xc4, 0x25, - 0xb6, 0x76, 0xe1, 0xd2, 0x4a, 0xf7, 0x80, 0x98, 0x91, 0xa7, 0x1e, 0xe1, 0x3b, 0xb5, 0x05, 0x0b, - 0x4a, 0xe3, 0xeb, 0x9f, 0x24, 0xf3, 0xf3, 0x09, 0x53, 0xc9, 0xc2, 0xdd, 0x81, 0x98, 0x78, 0x04, - 0x15, 0xb2, 0x05, 0x05, 0xa7, 0xbd, 0x35, 0xff, 0x74, 0x1e, 0xaa, 0x6b, 0x75, 0xad, 0x26, 0x47, - 0x14, 0xf7, 0xf3, 0xac, 0xae, 0xd5, 0x90, 0x11, 0x27, 0x2e, 0x8c, 0x3b, 0xed, 0xad, 0x70, 0x7e, - 0x81, 0xcf, 0xd9, 0xdc, 0x98, 0xc4, 0xc6, 0x83, 0xb5, 0x5a, 0x88, 0x9c, 0x85, 0xfd, 0xc5, 0x31, - 0x7d, 0x51, 0xa3, 0x93, 0x5b, 0xbf, 0x67, 0x4e, 0x20, 0x71, 0xdc, 0xb9, 0x95, 0xdb, 0x04, 0x92, - 0xea, 0xc5, 0x99, 0x81, 0xd3, 0xa7, 0xab, 0x97, 0x8c, 0x5c, 0xb2, 0x62, 0x25, 0x13, 0x77, 0x8b, - 0xd3, 0x73, 0x72, 0xc1, 0xb0, 0xbf, 0x05, 0xda, 0xe8, 0x97, 0x72, 0x7f, 0x0a, 0xa0, 0xe8, 0x86, - 0x91, 0xeb, 0xe7, 0x18, 0x27, 0x9d, 0xca, 0x78, 0xcd, 0xc3, 0x30, 0x38, 0x00, 0x05, 0x2b, 0xc6, - 0xd3, 0x6b, 0xb9, 0xde, 0x03, 0xf9, 0xf9, 0xb7, 0x73, 0xf7, 0x6b, 0x12, 0x3c, 0x39, 0x00, 0x05, - 0x2b, 0x72, 0x4f, 0x0c, 0xea, 0x42, 0x1e, 0x7d, 0x5d, 0x5d, 0xab, 0xa5, 0xf8, 0x25, 0x07, 0xf7, - 0x3d, 0x28, 0x84, 0x1d, 0x57, 0xaa, 0x4b, 0x23, 0xf2, 0xaa, 0xaf, 0xaf, 0x66, 0xf1, 0xaa, 0xaf, - 0xaf, 0x22, 0x63, 0x42, 0xbe, 0x6c, 0x01, 0x38, 0x9d, 0x2d, 0x27, 0x0c, 0x9d, 0xa6, 0xb6, 0xce, - 0x8c, 0xf8, 0x92, 0x45, 0x55, 0xd3, 0x4b, 0xb1, 0xe6, 0x9e, 0xbc, 0x31, 0x14, 0x0d, 0xce, 0xe4, - 0x5d, 0x98, 0x74, 0xc4, 0x53, 0x81, 0xd2, 0x29, 0x3d, 0x9f, 0xf7, 0x2f, 0x53, 0x12, 0x70, 0x33, - 0x8d, 0x04, 0xa1, 0x62, 0xc8, 0x78, 0x47, 0x81, 0x43, 0xb7, 0xdd, 0x5d, 0x69, 0x1c, 0xaa, 0x8f, - 0xfc, 0x98, 0x05, 0x23, 0x96, 0xc5, 0x5b, 0x82, 0x50, 0x31, 0x14, 0x2f, 0xc3, 0x3b, 0x9e, 0xa3, - 0x43, 0x0d, 0xf3, 0x09, 0x48, 0x35, 0x83, 0x17, 0x8d, 0x97, 0xe1, 0x4d, 0x46, 0x98, 0xe4, 0x4b, - 0xf6, 0x60, 0xc2, 0xe1, 0x8f, 0x98, 0xca, 0xa3, 0x18, 0xe6, 0xf1, 0x20, 0x6a, 0xaa, 0x0d, 0xf8, - 0xe2, 0x22, 0x9f, 0x4a, 0x95, 0xdc, 0xc8, 0xaf, 0x59, 0x30, 0x29, 0xfc, 0xa5, 0x99, 0x42, 0xca, - 0xbe, 0xfd, 0xb3, 0xa7, 0x90, 0x39, 0x5f, 0xfa, 0x72, 0x4b, 0x0f, 0xa0, 0x0f, 0x6b, 0x67, 0x50, - 0x51, 0x7a, 0xa4, 0x37, 0xb7, 0x92, 0x6e, 0xe1, 0x13, 0x30, 0x6d, 0x52, 0x19, 0xca, 0x9f, 0xfb, - 0xfb, 0x05, 0x00, 0xde, 0xd0, 0x22, 0xb9, 0x48, 0x87, 0xa7, 0xf9, 0xdd, 0xf1, 0x9b, 0x39, 0x3d, - 0x78, 0x68, 0xe4, 0x08, 0x01, 0x99, 0xd3, 0x77, 0xc7, 0x6f, 0xa2, 0x64, 0x42, 0x5a, 0x30, 0xde, - 0x75, 0xa2, 0x9d, 0xfc, 0x13, 0x92, 0x4c, 0x89, 0x28, 0xdb, 0x68, 0x07, 0x39, 0x03, 0xf2, 0xbe, - 0x15, 0xbb, 0xc6, 0x14, 0xf2, 0x71, 0x60, 0x50, 0x6d, 0xb6, 0x28, 0x9d, 0x61, 0x52, 0x09, 0x3b, - 0xd3, 0x2e, 0x32, 0x0b, 0x1f, 0x58, 0x30, 0x6d, 0xa2, 0x66, 0x74, 0xd3, 0xcf, 0x9a, 0xdd, 0x94, - 0x67, 0x7b, 0x98, 0x3d, 0xfe, 0xdf, 0x2c, 0x00, 0xec, 0x79, 0xf5, 0x5e, 0xa7, 0xc3, 0x94, 0x6e, - 0xed, 0xb6, 0x6e, 0x1d, 0xdb, 0x6d, 0x7d, 0x6c, 0x48, 0xb7, 0xf5, 0xc2, 0x50, 0x6e, 0xeb, 0xe3, - 0xc3, 0xbb, 0xad, 0x17, 0x07, 0xbb, 0xad, 0xdb, 0x5f, 0xb7, 0xe0, 0x6c, 0xdf, 0x6e, 0xc3, 0xf4, - 0xe0, 0xc0, 0xf7, 0xa3, 0x01, 0x2e, 0x8f, 0x18, 0x83, 0xd0, 0xc4, 0x23, 0x2b, 0x30, 0x27, 0x1f, - 0xb5, 0xa8, 0x77, 0xdb, 0x6e, 0x66, 0xb2, 0x98, 0xcd, 0x14, 0x1c, 0xfb, 0x6a, 0xd8, 0xdf, 0xb2, - 0xa0, 0x6c, 0x84, 0x98, 0xb3, 0xef, 0xe0, 0x7e, 0xaf, 0x52, 0x8c, 0xf8, 0x3d, 0x0f, 0x7e, 0x51, - 0x25, 0x60, 0xe2, 0xce, 0xb4, 0x65, 0xa4, 0x3c, 0x8f, 0xef, 0x4c, 0x59, 0x29, 0x4a, 0xa8, 0x48, - 0x66, 0x4d, 0xbb, 0xbc, 0xd1, 0x0b, 0x66, 0x32, 0x6b, 0xda, 0x45, 0x0e, 0xe1, 0xec, 0xd8, 0x81, - 0x40, 0xba, 0xb4, 0x1a, 0xcf, 0x87, 0x38, 0x41, 0x84, 0x02, 0x46, 0x9e, 0x83, 0x02, 0xf5, 0x9a, - 0xd2, 0x7a, 0xa1, 0x1f, 0xf8, 0xbc, 0xea, 0x35, 0x91, 0x95, 0xdb, 0xb7, 0x60, 0x5a, 0xb8, 0xf3, - 0xbe, 0x45, 0xf7, 0x8f, 0xfd, 0x62, 0x28, 0x1b, 0xed, 0xa9, 0x17, 0x43, 0x59, 0x75, 0x56, 0x6e, - 0xff, 0x63, 0x0b, 0x52, 0x6f, 0xdc, 0x18, 0xf7, 0x27, 0xd6, 0xc0, 0xfb, 0x13, 0xd3, 0xe6, 0x3e, - 0x76, 0xa4, 0xcd, 0xfd, 0x06, 0x90, 0x0e, 0x9b, 0x0a, 0x89, 0x17, 0x9d, 0xa4, 0xe1, 0x28, 0x4e, - 0x68, 0xd1, 0x87, 0x81, 0x19, 0xb5, 0xec, 0x7f, 0x24, 0x84, 0x35, 0x5f, 0xbd, 0x79, 0x74, 0x03, - 0xf4, 0xa0, 0xc8, 0x49, 0x49, 0xeb, 0xd9, 0x88, 0x96, 0xe7, 0xfe, 0xc4, 0x50, 0x71, 0x47, 0xca, - 0x29, 0xcf, 0xb9, 0xd9, 0x7f, 0x28, 0x64, 0x35, 0x9e, 0xc5, 0x39, 0x86, 0xac, 0x9d, 0xa4, 0xac, - 0xd7, 0xf3, 0x5a, 0x2b, 0xb3, 0x65, 0x24, 0x8b, 0x00, 0x5d, 0x1a, 0x34, 0xa8, 0x17, 0xa9, 0x40, - 0x9b, 0xa2, 0x0c, 0xf9, 0xd4, 0xa5, 0x68, 0x60, 0xd8, 0x5f, 0x63, 0x13, 0x28, 0x7e, 0x4b, 0x97, - 0x5c, 0x4e, 0xfb, 0x8a, 0xa6, 0x27, 0x87, 0x76, 0x15, 0x35, 0xc2, 0x2f, 0xc6, 0x1e, 0x11, 0x7e, - 0xf1, 0x22, 0x4c, 0x06, 0x7e, 0x9b, 0x56, 0x03, 0x2f, 0xed, 0xe0, 0x82, 0xac, 0x18, 0x6f, 0xa2, - 0x82, 0xdb, 0xbf, 0x62, 0xc1, 0x5c, 0x3a, 0x3e, 0x2c, 0x77, 0x07, 0x56, 0x33, 0x88, 0xbd, 0x30, - 0x7c, 0x10, 0xbb, 0xfd, 0x3e, 0x13, 0x32, 0x72, 0x1b, 0xbb, 0xae, 0x27, 0xe2, 0xbe, 0x59, 0xcb, - 0xbd, 0x08, 0x93, 0x54, 0xbe, 0x09, 0x2a, 0x8c, 0xc0, 0x5a, 0x48, 0xf5, 0x14, 0xa8, 0x82, 0x93, - 0x2a, 0xcc, 0xaa, 0xab, 0x2f, 0x65, 0xb9, 0x17, 0xf9, 0x2a, 0xb4, 0xa5, 0x70, 0x25, 0x09, 0xc6, - 0x34, 0xbe, 0xfd, 0x05, 0x28, 0x1b, 0x9b, 0x12, 0x5f, 0xbf, 0x1f, 0x38, 0x8d, 0x28, 0xbd, 0xee, - 0x5d, 0x65, 0x85, 0x28, 0x60, 0xfc, 0x82, 0x41, 0x84, 0xaf, 0xa4, 0xd6, 0x3d, 0x19, 0xb4, 0x22, - 0xa1, 0x8c, 0x58, 0x40, 0x5b, 0xf4, 0x81, 0xca, 0x48, 0xaf, 0x88, 0x21, 0x2b, 0x44, 0x01, 0xb3, - 0x5f, 0x82, 0x29, 0x95, 0x55, 0x88, 0xa7, 0xe6, 0x50, 0xc6, 0x6f, 0x33, 0x35, 0x87, 0x1f, 0x44, - 0xc8, 0x21, 0xf6, 0xdb, 0x30, 0xa5, 0x92, 0x1f, 0x3d, 0x1a, 0x9b, 0x2d, 0x45, 0xa1, 0xe7, 0x5e, - 0xf7, 0xc3, 0x48, 0x65, 0x6c, 0x12, 0xf7, 0x73, 0x37, 0x57, 0x79, 0x19, 0x6a, 0xa8, 0xfd, 0x67, - 0x16, 0x94, 0x37, 0x37, 0xd7, 0xf4, 0xb1, 0x1d, 0xe1, 0xc9, 0x50, 0xb4, 0x50, 0x75, 0x3b, 0xa2, - 0xa6, 0x23, 0x80, 0x58, 0xf8, 0x16, 0x0e, 0x0f, 0x2a, 0x4f, 0xd6, 0x33, 0x31, 0x70, 0x40, 0x4d, - 0xb2, 0x0a, 0xe7, 0x4c, 0x88, 0x8c, 0xa4, 0x97, 0x6b, 0x24, 0x7f, 0x44, 0xb6, 0xde, 0x0f, 0xc6, - 0xac, 0x3a, 0x69, 0x52, 0x72, 0xbb, 0x37, 0xdf, 0xa3, 0xad, 0xf7, 0x83, 0x31, 0xab, 0x8e, 0xfd, - 0x32, 0xcc, 0xa6, 0x6e, 0xa8, 0x8f, 0x91, 0xc1, 0xe4, 0x77, 0x0b, 0x30, 0x6d, 0x5e, 0x54, 0x1e, - 0x63, 0xfd, 0x3a, 0xfe, 0xb6, 0x90, 0x71, 0xb9, 0x58, 0x18, 0xf2, 0x72, 0xd1, 0xbc, 0xcd, 0x1d, - 0x3f, 0xdd, 0xdb, 0xdc, 0x62, 0x3e, 0xb7, 0xb9, 0x86, 0xd7, 0xc1, 0xc4, 0xe3, 0xf3, 0x3a, 0xf8, - 0xed, 0x22, 0xcc, 0x24, 0x53, 0x62, 0x1e, 0xa3, 0x27, 0x5f, 0xea, 0xeb, 0xc9, 0x21, 0x6f, 0x33, - 0x0a, 0xa3, 0xde, 0x66, 0x8c, 0x8f, 0x7a, 0x9b, 0x51, 0x3c, 0xc1, 0x6d, 0x46, 0xff, 0x5d, 0xc4, - 0xc4, 0xb1, 0xef, 0x22, 0x3e, 0xa9, 0xfd, 0x11, 0x27, 0x13, 0x0e, 0x3c, 0xb1, 0x3f, 0x22, 0x49, - 0x76, 0xc3, 0xb2, 0xdf, 0xcc, 0xf4, 0xeb, 0x9c, 0x7a, 0x84, 0xd5, 0x36, 0xc8, 0x74, 0x1f, 0x1c, - 0xfe, 0xc2, 0xf4, 0xc9, 0x21, 0x5c, 0x07, 0x5f, 0x85, 0xb2, 0x1c, 0x4f, 0x5c, 0xf9, 0x86, 0xa4, - 0xe2, 0x5e, 0x8f, 0x41, 0x68, 0xe2, 0xf1, 0xe7, 0xe4, 0xe3, 0x09, 0xc2, 0xef, 0xd5, 0xca, 0xa9, - 0xe7, 0xe4, 0x93, 0x60, 0x4c, 0xe3, 0xdb, 0x9f, 0x87, 0x0b, 0x99, 0x06, 0x14, 0x6e, 0xbc, 0xe6, - 0x7a, 0x21, 0x6d, 0x4a, 0x04, 0x43, 0x8c, 0xd4, 0x33, 0x14, 0x0b, 0x77, 0x07, 0x62, 0xe2, 0x11, - 0x54, 0xec, 0xdf, 0x2c, 0xc0, 0x4c, 0xf2, 0x2d, 0x52, 0x72, 0x5f, 0x9b, 0x5b, 0x73, 0xb1, 0xf4, - 0x0a, 0xb2, 0x46, 0x9a, 0xc5, 0x81, 0xd7, 0x34, 0xf7, 0xf9, 0xf8, 0xda, 0xd2, 0x39, 0x1f, 0x4f, - 0x8f, 0xb1, 0xbc, 0x1f, 0x91, 0xec, 0xf8, 0x73, 0xa3, 0x71, 0x44, 0xa6, 0x3c, 0xc7, 0xe7, 0xce, - 0x3d, 0x8e, 0x2c, 0xd4, 0xac, 0xd0, 0x60, 0xcb, 0xf6, 0x96, 0x3d, 0x1a, 0xb8, 0xdb, 0xae, 0x7e, - 0x47, 0x9d, 0xaf, 0xdc, 0x6f, 0xcb, 0x32, 0xd4, 0x50, 0xfb, 0xfd, 0x31, 0x28, 0xf1, 0x04, 0x52, - 0xd7, 0x02, 0xbf, 0xc3, 0x1f, 0xec, 0x0b, 0x8d, 0x33, 0x93, 0xec, 0xb6, 0x1b, 0xa3, 0xbe, 0x8a, - 0x19, 0x53, 0x94, 0xbe, 0xe2, 0x46, 0x09, 0x26, 0x38, 0x92, 0x2e, 0x4c, 0x6d, 0xcb, 0x84, 0xb7, - 0xb2, 0xef, 0x46, 0x4c, 0xda, 0xa8, 0xd2, 0xe7, 0x8a, 0x26, 0x50, 0xff, 0x50, 0x73, 0xb1, 0x1d, - 0x98, 0x4d, 0x65, 0x00, 0xc9, 0x3d, 0x4d, 0xee, 0xff, 0x1c, 0x87, 0x92, 0x0e, 0x54, 0x22, 0x1f, - 0x4f, 0x18, 0xb0, 0x4a, 0xb5, 0x0f, 0x19, 0xaf, 0x49, 0xed, 0xf8, 0xcd, 0x87, 0x07, 0x95, 0x59, - 0x8d, 0x9c, 0x32, 0x46, 0x3d, 0x07, 0x85, 0x5e, 0xd0, 0x4e, 0x9f, 0x50, 0xef, 0xe0, 0x1a, 0xb2, - 0x72, 0x33, 0xb8, 0xaa, 0xf0, 0x58, 0x83, 0xab, 0xd8, 0x2e, 0xb9, 0xe5, 0x37, 0xf7, 0xd3, 0xaf, - 0x4f, 0xd5, 0xfc, 0xe6, 0x3e, 0x72, 0x08, 0x79, 0x03, 0x66, 0x64, 0xc4, 0x98, 0xf9, 0x26, 0x7f, - 0x21, 0x76, 0x3b, 0xd8, 0x4c, 0x40, 0x31, 0x85, 0xcd, 0x76, 0xd9, 0x7b, 0xa1, 0xef, 0xf1, 0xe4, - 0xc7, 0x13, 0xc9, 0x3b, 0xca, 0x1b, 0xf5, 0x5b, 0x37, 0xb9, 0x21, 0x4d, 0x63, 0x24, 0x82, 0xd2, - 0x26, 0x1f, 0x19, 0x94, 0xb6, 0x22, 0x68, 0x33, 0x69, 0xf9, 0x8e, 0x32, 0x5d, 0xbb, 0xac, 0xe8, - 0xb2, 0xb2, 0x87, 0x07, 0x47, 0x98, 0x38, 0x75, 0xcd, 0xac, 0xf0, 0xbd, 0xd2, 0x0f, 0x2f, 0x7c, - 0xcf, 0xbe, 0x03, 0xb3, 0xa9, 0xfe, 0x53, 0x06, 0x0e, 0x2b, 0xdb, 0xc0, 0x71, 0xbc, 0xf7, 0xab, - 0xfe, 0xa9, 0x05, 0x67, 0xfb, 0x56, 0xa4, 0xe3, 0xc6, 0x51, 0xa6, 0xf7, 0xc6, 0xb1, 0x93, 0xef, - 0x8d, 0x85, 0xe1, 0xf6, 0xc6, 0xda, 0xd6, 0xb7, 0xbf, 0x77, 0xf1, 0x89, 0xef, 0x7c, 0xef, 0xe2, - 0x13, 0x7f, 0xf4, 0xbd, 0x8b, 0x4f, 0xbc, 0x7f, 0x78, 0xd1, 0xfa, 0xf6, 0xe1, 0x45, 0xeb, 0x3b, - 0x87, 0x17, 0xad, 0x3f, 0x3a, 0xbc, 0x68, 0xfd, 0xa7, 0xc3, 0x8b, 0xd6, 0xd7, 0xff, 0xf4, 0xe2, - 0x13, 0x9f, 0xfa, 0x64, 0xdc, 0x53, 0x4b, 0xaa, 0xa7, 0xf8, 0x8f, 0x8f, 0xa8, 0x7e, 0x59, 0xea, - 0xee, 0xb6, 0x96, 0x58, 0x4f, 0x2d, 0xe9, 0x12, 0xd5, 0x53, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, - 0x9b, 0x74, 0x0a, 0x77, 0x6d, 0xa4, 0x00, 0x00, + // 8545 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x64, 0xd7, + 0x75, 0x98, 0x1e, 0x87, 0x43, 0xce, 0x1c, 0x72, 0x49, 0xee, 0xdd, 0x5d, 0x89, 0xa2, 0xa4, 0x1d, + 0xf9, 0x29, 0x55, 0xa5, 0x58, 0x26, 0xed, 0x95, 0xd4, 0xca, 0x96, 0xab, 0x76, 0x86, 0xdc, 0xd5, + 0x72, 0x45, 0xee, 0x52, 0x67, 0xb8, 0xda, 0xc4, 0xb6, 0x12, 0x3f, 0xce, 0x5c, 0x0e, 0xdf, 0x72, + 0xe6, 0xbd, 0xf1, 0x7b, 0x6f, 0xb8, 0x4b, 0x59, 0x88, 0x65, 0x1b, 0x72, 0x9d, 0xd4, 0x46, 0xdc, + 0x26, 0x46, 0x51, 0xb4, 0x28, 0xdc, 0x20, 0x40, 0xda, 0x26, 0x3f, 0x8a, 0x20, 0x45, 0xfb, 0x23, + 0x40, 0x8d, 0xba, 0x49, 0x5d, 0xa0, 0x29, 0x9c, 0x1f, 0xad, 0xd3, 0x02, 0x61, 0x6a, 0xa6, 0x7f, + 0x5a, 0xb4, 0x30, 0x5a, 0xb8, 0x08, 0xb2, 0x3f, 0x8a, 0xe2, 0x7e, 0xbe, 0xfb, 0xde, 0xbc, 0x21, + 0x39, 0x9c, 0xc7, 0x95, 0xdb, 0xe4, 0xdf, 0xcc, 0x3d, 0xe7, 0x9e, 0x73, 0xde, 0xfd, 0x3c, 0xf7, + 0xdc, 0x73, 0xce, 0x85, 0xb5, 0x96, 0x1b, 0xed, 0xf4, 0xb6, 0x16, 0x1b, 0x7e, 0x67, 0xc9, 0x09, + 0x5a, 0x7e, 0x37, 0xf0, 0xef, 0xf2, 0x1f, 0x1f, 0x09, 0xfc, 0x76, 0xdb, 0xef, 0x45, 0xe1, 0x52, + 0x77, 0xb7, 0xb5, 0xe4, 0x74, 0xdd, 0x70, 0x49, 0x97, 0xec, 0x7d, 0xcc, 0x69, 0x77, 0x77, 0x9c, + 0x8f, 0x2d, 0xb5, 0xa8, 0x47, 0x03, 0x27, 0xa2, 0xcd, 0xc5, 0x6e, 0xe0, 0x47, 0x3e, 0xf9, 0x64, + 0x4c, 0x6d, 0x51, 0x51, 0xe3, 0x3f, 0x7e, 0x56, 0xd5, 0x5d, 0xec, 0xee, 0xb6, 0x16, 0x19, 0xb5, + 0x45, 0x5d, 0xa2, 0xa8, 0x2d, 0x7c, 0xc4, 0x90, 0xa5, 0xe5, 0xb7, 0xfc, 0x25, 0x4e, 0x74, 0xab, + 0xb7, 0xcd, 0xff, 0xf1, 0x3f, 0xfc, 0x97, 0x60, 0xb6, 0xf0, 0xcc, 0xee, 0x2b, 0xe1, 0xa2, 0xeb, + 0x33, 0xd9, 0x96, 0xb6, 0x9c, 0xa8, 0xb1, 0xb3, 0xb4, 0xd7, 0x27, 0xd1, 0x82, 0x6d, 0x20, 0x35, + 0xfc, 0x80, 0x66, 0xe1, 0xbc, 0x14, 0xe3, 0x74, 0x9c, 0xc6, 0x8e, 0xeb, 0xd1, 0x60, 0x3f, 0xfe, + 0xea, 0x0e, 0x8d, 0x9c, 0xac, 0x5a, 0x4b, 0x83, 0x6a, 0x05, 0x3d, 0x2f, 0x72, 0x3b, 0xb4, 0xaf, + 0xc2, 0x5f, 0x3a, 0xae, 0x42, 0xd8, 0xd8, 0xa1, 0x1d, 0xa7, 0xaf, 0xde, 0x8b, 0x83, 0xea, 0xf5, + 0x22, 0xb7, 0xbd, 0xe4, 0x7a, 0x51, 0x18, 0x05, 0xe9, 0x4a, 0xf6, 0x0f, 0x0b, 0x50, 0xae, 0xae, + 0xd5, 0xea, 0x91, 0x13, 0xf5, 0x42, 0xf2, 0x15, 0x0b, 0xa6, 0xdb, 0xbe, 0xd3, 0xac, 0x39, 0x6d, + 0xc7, 0x6b, 0xd0, 0x60, 0xde, 0x7a, 0xda, 0x7a, 0x6e, 0xea, 0xca, 0xda, 0xe2, 0x28, 0xfd, 0xb5, + 0x58, 0xbd, 0x17, 0x22, 0x0d, 0xfd, 0x5e, 0xd0, 0xa0, 0x48, 0xb7, 0x6b, 0x17, 0xbf, 0x7b, 0x50, + 0x79, 0xe4, 0xf0, 0xa0, 0x32, 0xbd, 0x66, 0x70, 0xc2, 0x04, 0x5f, 0xf2, 0x4d, 0x0b, 0xce, 0x37, + 0x1c, 0xcf, 0x09, 0xf6, 0x37, 0x9d, 0xa0, 0x45, 0xa3, 0xd7, 0x03, 0xbf, 0xd7, 0x9d, 0x1f, 0x3b, + 0x03, 0x69, 0x1e, 0x97, 0xd2, 0x9c, 0x5f, 0x4e, 0xb3, 0xc3, 0x7e, 0x09, 0xb8, 0x5c, 0x61, 0xe4, + 0x6c, 0xb5, 0xa9, 0x29, 0x57, 0xe1, 0x2c, 0xe5, 0xaa, 0xa7, 0xd9, 0x61, 0xbf, 0x04, 0xe4, 0x79, + 0x98, 0x74, 0xbd, 0x56, 0x40, 0xc3, 0x70, 0x7e, 0xfc, 0x69, 0xeb, 0xb9, 0x72, 0x6d, 0x56, 0x56, + 0x9f, 0x5c, 0x15, 0xc5, 0xa8, 0xe0, 0xf6, 0x6f, 0x16, 0xe0, 0x7c, 0x75, 0xad, 0xb6, 0x19, 0x38, + 0xdb, 0xdb, 0x6e, 0x03, 0xfd, 0x5e, 0xe4, 0x7a, 0x2d, 0x93, 0x80, 0x75, 0x34, 0x01, 0xf2, 0x32, + 0x4c, 0x85, 0x34, 0xd8, 0x73, 0x1b, 0x74, 0xc3, 0x0f, 0x22, 0xde, 0x29, 0xc5, 0xda, 0x05, 0x89, + 0x3e, 0x55, 0x8f, 0x41, 0x68, 0xe2, 0xb1, 0x6a, 0x81, 0xef, 0x47, 0x12, 0xce, 0xdb, 0xac, 0x1c, + 0x57, 0xc3, 0x18, 0x84, 0x26, 0x1e, 0x59, 0x81, 0x39, 0xc7, 0xf3, 0xfc, 0xc8, 0x89, 0x5c, 0xdf, + 0xdb, 0x08, 0xe8, 0xb6, 0x7b, 0x5f, 0x7e, 0xe2, 0xbc, 0xac, 0x3b, 0x57, 0x4d, 0xc1, 0xb1, 0xaf, + 0x06, 0xf9, 0x86, 0x05, 0x73, 0x61, 0xe4, 0x36, 0x76, 0x5d, 0x8f, 0x86, 0xe1, 0xb2, 0xef, 0x6d, + 0xbb, 0xad, 0xf9, 0x22, 0xef, 0xb6, 0x9b, 0xa3, 0x75, 0x5b, 0x3d, 0x45, 0xb5, 0x76, 0x91, 0x89, + 0x94, 0x2e, 0xc5, 0x3e, 0xee, 0xe4, 0xc3, 0x50, 0x96, 0x2d, 0x4a, 0xc3, 0xf9, 0x89, 0xa7, 0x0b, + 0xcf, 0x95, 0x6b, 0xe7, 0x0e, 0x0f, 0x2a, 0xe5, 0x55, 0x55, 0x88, 0x31, 0xdc, 0x5e, 0x81, 0xf9, + 0x6a, 0x67, 0xcb, 0x09, 0x43, 0xa7, 0xe9, 0x07, 0xa9, 0xae, 0x7b, 0x0e, 0x4a, 0x1d, 0xa7, 0xdb, + 0x75, 0xbd, 0x16, 0xeb, 0x3b, 0x46, 0x67, 0xfa, 0xf0, 0xa0, 0x52, 0x5a, 0x97, 0x65, 0xa8, 0xa1, + 0xf6, 0x7f, 0x1c, 0x83, 0xa9, 0xaa, 0xe7, 0xb4, 0xf7, 0x43, 0x37, 0xc4, 0x9e, 0x47, 0x3e, 0x0b, + 0x25, 0xb6, 0x6a, 0x35, 0x9d, 0xc8, 0x91, 0x33, 0xfd, 0xa3, 0x8b, 0x62, 0x11, 0x59, 0x34, 0x17, + 0x91, 0xf8, 0xf3, 0x19, 0xf6, 0xe2, 0xde, 0xc7, 0x16, 0x6f, 0x6d, 0xdd, 0xa5, 0x8d, 0x68, 0x9d, + 0x46, 0x4e, 0x8d, 0xc8, 0x5e, 0x80, 0xb8, 0x0c, 0x35, 0x55, 0xe2, 0xc3, 0x78, 0xd8, 0xa5, 0x0d, + 0x39, 0x73, 0xd7, 0x47, 0x9c, 0x21, 0xb1, 0xe8, 0xf5, 0x2e, 0x6d, 0xd4, 0xa6, 0x25, 0xeb, 0x71, + 0xf6, 0x0f, 0x39, 0x23, 0x72, 0x0f, 0x26, 0x42, 0xbe, 0x96, 0xc9, 0x49, 0x79, 0x2b, 0x3f, 0x96, + 0x9c, 0x6c, 0x6d, 0x46, 0x32, 0x9d, 0x10, 0xff, 0x51, 0xb2, 0xb3, 0xff, 0x93, 0x05, 0x17, 0x0c, + 0xec, 0x6a, 0xd0, 0xea, 0x75, 0xa8, 0x17, 0x91, 0xa7, 0x61, 0xdc, 0x73, 0x3a, 0x54, 0xce, 0x2a, + 0x2d, 0xf2, 0x4d, 0xa7, 0x43, 0x91, 0x43, 0xc8, 0x33, 0x50, 0xdc, 0x73, 0xda, 0x3d, 0xca, 0x1b, + 0xa9, 0x5c, 0x3b, 0x27, 0x51, 0x8a, 0x6f, 0xb1, 0x42, 0x14, 0x30, 0xf2, 0x2e, 0x94, 0xf9, 0x8f, + 0x6b, 0x81, 0xdf, 0xc9, 0xe9, 0xd3, 0xa4, 0x84, 0x6f, 0x29, 0xb2, 0x62, 0xf8, 0xe9, 0xbf, 0x18, + 0x33, 0xb4, 0xff, 0xc8, 0x82, 0x59, 0xe3, 0xe3, 0xd6, 0xdc, 0x30, 0x22, 0x9f, 0xe9, 0x1b, 0x3c, + 0x8b, 0x27, 0x1b, 0x3c, 0xac, 0x36, 0x1f, 0x3a, 0x73, 0xf2, 0x4b, 0x4b, 0xaa, 0xc4, 0x18, 0x38, + 0x1e, 0x14, 0xdd, 0x88, 0x76, 0xc2, 0xf9, 0xb1, 0xa7, 0x0b, 0xcf, 0x4d, 0x5d, 0x59, 0xcd, 0xad, + 0x1b, 0xe3, 0xf6, 0x5d, 0x65, 0xf4, 0x51, 0xb0, 0xb1, 0x7f, 0xab, 0x90, 0xe8, 0xbe, 0x75, 0x25, + 0xc7, 0xfb, 0x16, 0x4c, 0xb4, 0x9d, 0x2d, 0xda, 0x16, 0x73, 0x6b, 0xea, 0xca, 0xdb, 0xb9, 0x49, + 0xa2, 0x78, 0x2c, 0xae, 0x71, 0xfa, 0x57, 0xbd, 0x28, 0xd8, 0x8f, 0x87, 0x97, 0x28, 0x44, 0xc9, + 0x9c, 0xfc, 0x1d, 0x0b, 0xa6, 0xe2, 0x55, 0x4d, 0x35, 0xcb, 0x56, 0xfe, 0xc2, 0xc4, 0x8b, 0xa9, + 0x94, 0x48, 0x2f, 0xd1, 0x06, 0x04, 0x4d, 0x59, 0x16, 0x3e, 0x0e, 0x53, 0xc6, 0x27, 0x90, 0x39, + 0x28, 0xec, 0xd2, 0x7d, 0x31, 0xe0, 0x91, 0xfd, 0x24, 0x17, 0x13, 0x23, 0x5c, 0x0e, 0xe9, 0x4f, + 0x8c, 0xbd, 0x62, 0x2d, 0xbc, 0x06, 0x73, 0x69, 0x86, 0xc3, 0xd4, 0xb7, 0xff, 0x49, 0x31, 0x31, + 0x30, 0xd9, 0x42, 0x40, 0x7c, 0x98, 0xec, 0xd0, 0x28, 0x70, 0x1b, 0xaa, 0xcb, 0x56, 0x46, 0x6b, + 0xa5, 0x75, 0x4e, 0x2c, 0xde, 0x10, 0xc5, 0xff, 0x10, 0x15, 0x17, 0xb2, 0x03, 0xe3, 0x4e, 0xd0, + 0x52, 0x7d, 0x72, 0x2d, 0x9f, 0x69, 0x19, 0x2f, 0x15, 0xd5, 0xa0, 0x15, 0x22, 0xe7, 0x40, 0x96, + 0xa0, 0x1c, 0xd1, 0xa0, 0xe3, 0x7a, 0x4e, 0x24, 0x76, 0xd0, 0x52, 0xed, 0xbc, 0x44, 0x2b, 0x6f, + 0x2a, 0x00, 0xc6, 0x38, 0xa4, 0x0d, 0x13, 0xcd, 0x60, 0x1f, 0x7b, 0xde, 0xfc, 0x78, 0x1e, 0x4d, + 0xb1, 0xc2, 0x69, 0xc5, 0x83, 0x54, 0xfc, 0x47, 0xc9, 0x83, 0xfc, 0xaa, 0x05, 0x17, 0x3b, 0xd4, + 0x09, 0x7b, 0x01, 0x65, 0x9f, 0x80, 0x34, 0xa2, 0x1e, 0xeb, 0xd8, 0xf9, 0x22, 0x67, 0x8e, 0xa3, + 0xf6, 0x43, 0x3f, 0xe5, 0xda, 0x93, 0x52, 0x94, 0x8b, 0x59, 0x50, 0xcc, 0x94, 0x86, 0xbc, 0x0b, + 0x53, 0x51, 0xd4, 0xae, 0x47, 0x4c, 0x0f, 0x6e, 0xed, 0xcf, 0x4f, 0xf0, 0xc5, 0x6b, 0xc4, 0x15, + 0x66, 0x73, 0x73, 0x4d, 0x11, 0xac, 0xcd, 0xb2, 0xd9, 0x62, 0x14, 0xa0, 0xc9, 0xce, 0xfe, 0xe7, + 0x45, 0x38, 0xdf, 0xb7, 0xad, 0x90, 0x97, 0xa0, 0xd8, 0xdd, 0x71, 0x42, 0xb5, 0x4f, 0x5c, 0x56, + 0x8b, 0xd4, 0x06, 0x2b, 0x7c, 0x70, 0x50, 0x39, 0xa7, 0xaa, 0xf0, 0x02, 0x14, 0xc8, 0x4c, 0x6b, + 0xeb, 0xd0, 0x30, 0x74, 0x5a, 0x6a, 0xf3, 0x30, 0x06, 0x29, 0x2f, 0x46, 0x05, 0x27, 0x7f, 0xdd, + 0x82, 0x73, 0x62, 0xc0, 0x22, 0x0d, 0x7b, 0xed, 0x88, 0x6d, 0x90, 0xac, 0x53, 0x6e, 0xe4, 0x31, + 0x39, 0x04, 0xc9, 0xda, 0x25, 0xc9, 0xfd, 0x9c, 0x59, 0x1a, 0x62, 0x92, 0x2f, 0xb9, 0x03, 0xe5, + 0x30, 0x72, 0x82, 0x88, 0x36, 0xab, 0x11, 0x57, 0xe5, 0xa6, 0xae, 0xfc, 0xe4, 0xc9, 0x76, 0x8e, + 0x4d, 0xb7, 0x43, 0xc5, 0x2e, 0x55, 0x57, 0x04, 0x30, 0xa6, 0x45, 0xde, 0x05, 0x08, 0x7a, 0x5e, + 0xbd, 0xd7, 0xe9, 0x38, 0xc1, 0xbe, 0xd4, 0xee, 0xae, 0x8f, 0xf6, 0x79, 0xa8, 0xe9, 0xc5, 0x8a, + 0x4e, 0x5c, 0x86, 0x06, 0x3f, 0xf2, 0x45, 0x0b, 0xce, 0x89, 0x79, 0xa0, 0x24, 0x98, 0xc8, 0x59, + 0x82, 0xf3, 0xac, 0x69, 0x57, 0x4c, 0x16, 0x98, 0xe4, 0x48, 0xde, 0x86, 0xa9, 0x86, 0xdf, 0xe9, + 0xb6, 0xa9, 0x68, 0xdc, 0xc9, 0xa1, 0x1b, 0x97, 0x0f, 0xdd, 0xe5, 0x98, 0x04, 0x9a, 0xf4, 0xec, + 0x7f, 0x9f, 0xd4, 0x71, 0xd4, 0x90, 0x26, 0x9f, 0x86, 0xc7, 0xc3, 0x5e, 0xa3, 0x41, 0xc3, 0x70, + 0xbb, 0xd7, 0xc6, 0x9e, 0x77, 0xdd, 0x0d, 0x23, 0x3f, 0xd8, 0x5f, 0x73, 0x3b, 0x6e, 0xc4, 0x07, + 0x74, 0xb1, 0xf6, 0xd4, 0xe1, 0x41, 0xe5, 0xf1, 0xfa, 0x20, 0x24, 0x1c, 0x5c, 0x9f, 0x38, 0xf0, + 0x44, 0xcf, 0x1b, 0x4c, 0x5e, 0x1c, 0x3f, 0x2a, 0x87, 0x07, 0x95, 0x27, 0x6e, 0x0f, 0x46, 0xc3, + 0xa3, 0x68, 0xd8, 0xff, 0xcd, 0x62, 0xdb, 0x90, 0xf8, 0xae, 0x4d, 0xda, 0xe9, 0xb6, 0xd9, 0xd2, + 0x79, 0xf6, 0xca, 0x71, 0x94, 0x50, 0x8e, 0x31, 0x9f, 0xbd, 0x5c, 0xc9, 0x3f, 0x48, 0x43, 0xb6, + 0xff, 0xab, 0x05, 0x17, 0xd3, 0xc8, 0x0f, 0x41, 0xa1, 0x0b, 0x93, 0x0a, 0xdd, 0xcd, 0x7c, 0xbf, + 0x76, 0x80, 0x56, 0xf7, 0xf3, 0xc6, 0x80, 0x55, 0xa8, 0x48, 0xb7, 0xc9, 0x2b, 0x30, 0x1d, 0xc9, + 0xbf, 0x37, 0x63, 0xe5, 0x5c, 0x1b, 0x26, 0x36, 0x0d, 0x18, 0x26, 0x30, 0x59, 0xcd, 0x46, 0xbb, + 0x17, 0x46, 0x34, 0xa8, 0x37, 0xfc, 0xae, 0x58, 0x76, 0x4b, 0x71, 0xcd, 0x65, 0x03, 0x86, 0x09, + 0x4c, 0xfb, 0x6f, 0x14, 0xfb, 0xdb, 0xfd, 0xff, 0x77, 0x7d, 0x25, 0x56, 0x3f, 0x0a, 0x1f, 0xa4, + 0xfa, 0x31, 0xfe, 0x63, 0xa5, 0x7e, 0x7c, 0xc9, 0x62, 0x5a, 0x9c, 0x18, 0x00, 0xa1, 0x54, 0x8d, + 0xde, 0xcc, 0x77, 0x3a, 0x20, 0xdd, 0x36, 0x15, 0x43, 0xc9, 0x0b, 0x63, 0xb6, 0xf6, 0x3f, 0x1c, + 0x87, 0xe9, 0xaa, 0x17, 0xb9, 0xd5, 0xed, 0x6d, 0xd7, 0x73, 0xa3, 0x7d, 0xf2, 0xb5, 0x31, 0x58, + 0xea, 0x06, 0x74, 0x9b, 0x06, 0x01, 0x6d, 0xae, 0xf4, 0x02, 0xd7, 0x6b, 0xd5, 0x1b, 0x3b, 0xb4, + 0xd9, 0x6b, 0xbb, 0x5e, 0x6b, 0xb5, 0xe5, 0xf9, 0xba, 0xf8, 0xea, 0x7d, 0xda, 0xe8, 0xf1, 0x76, + 0x15, 0xab, 0x44, 0x67, 0x34, 0xd9, 0x37, 0x86, 0x63, 0x5a, 0x7b, 0xf1, 0xf0, 0xa0, 0xb2, 0x34, + 0x64, 0x25, 0x1c, 0xf6, 0xd3, 0xc8, 0x57, 0xc7, 0x60, 0x31, 0xa0, 0x9f, 0xeb, 0xb9, 0x27, 0x6f, + 0x0d, 0xb1, 0x8c, 0xb7, 0x47, 0xdc, 0xee, 0x87, 0xe2, 0x59, 0xbb, 0x72, 0x78, 0x50, 0x19, 0xb2, + 0x0e, 0x0e, 0xf9, 0x5d, 0xf6, 0x06, 0x4c, 0x55, 0xbb, 0x6e, 0xe8, 0xde, 0x47, 0xbf, 0x17, 0xd1, + 0x13, 0x18, 0x34, 0x2a, 0x50, 0x0c, 0x7a, 0x6d, 0x2a, 0x16, 0x98, 0x72, 0xad, 0xcc, 0x96, 0x65, + 0x64, 0x05, 0x28, 0xca, 0xed, 0x2f, 0xb1, 0x2d, 0x88, 0x93, 0x4c, 0x99, 0xb2, 0xee, 0x42, 0x31, + 0x60, 0x4c, 0xe4, 0xc8, 0x1a, 0xf5, 0xd4, 0x1f, 0x4b, 0x2d, 0x85, 0x60, 0x3f, 0x51, 0xb0, 0xb0, + 0xbf, 0x33, 0x06, 0x97, 0xaa, 0xdd, 0xee, 0x3a, 0x0d, 0x77, 0x52, 0x52, 0xfc, 0xa2, 0x05, 0x33, + 0x7b, 0x6e, 0x10, 0xf5, 0x9c, 0xb6, 0xb2, 0x56, 0x0a, 0x79, 0xea, 0xa3, 0xca, 0xc3, 0xb9, 0xbd, + 0x95, 0x20, 0x5d, 0x23, 0x87, 0x07, 0x95, 0x99, 0x64, 0x19, 0xa6, 0xd8, 0x93, 0xbf, 0x6d, 0xc1, + 0x9c, 0x2c, 0xba, 0xe9, 0x37, 0xa9, 0x69, 0x0d, 0xbf, 0x9d, 0xa7, 0x4c, 0x9a, 0xb8, 0xb0, 0x62, + 0xa6, 0x4b, 0xb1, 0x4f, 0x08, 0xfb, 0x7f, 0x8c, 0xc1, 0x63, 0x03, 0x68, 0x90, 0x5f, 0xb3, 0xe0, + 0xa2, 0x30, 0xa1, 0x1b, 0x20, 0xa4, 0xdb, 0xb2, 0x35, 0x7f, 0x3a, 0x6f, 0xc9, 0x91, 0x4d, 0x71, + 0xea, 0x35, 0x68, 0x6d, 0x9e, 0x2d, 0xc9, 0xcb, 0x19, 0xac, 0x31, 0x53, 0x20, 0x2e, 0xa9, 0x30, + 0xaa, 0xa7, 0x24, 0x1d, 0x7b, 0x28, 0x92, 0xd6, 0x33, 0x58, 0x63, 0xa6, 0x40, 0xf6, 0x5f, 0x85, + 0x27, 0x8e, 0x20, 0x77, 0xfc, 0xe4, 0xb4, 0xdf, 0xd6, 0xa3, 0x3e, 0x39, 0xe6, 0x4e, 0x30, 0xaf, + 0x6d, 0x98, 0xe0, 0x53, 0x47, 0x4d, 0x6c, 0x60, 0x7b, 0x30, 0x9f, 0x53, 0x21, 0x4a, 0x88, 0xfd, + 0x1d, 0x0b, 0x4a, 0x43, 0xd8, 0x3e, 0x2b, 0x49, 0xdb, 0x67, 0xb9, 0xcf, 0xee, 0x19, 0xf5, 0xdb, + 0x3d, 0x5f, 0x1f, 0xad, 0x37, 0x4e, 0x62, 0xef, 0xfc, 0xa1, 0x05, 0xe7, 0xfb, 0xec, 0xa3, 0x64, + 0x07, 0x2e, 0x76, 0xfd, 0xa6, 0xda, 0x4e, 0xaf, 0x3b, 0xe1, 0x0e, 0x87, 0xc9, 0xcf, 0x7b, 0x89, + 0xf5, 0xe4, 0x46, 0x06, 0xfc, 0xc1, 0x41, 0x65, 0x5e, 0x13, 0x49, 0x21, 0x60, 0x26, 0x45, 0xd2, + 0x85, 0xd2, 0xb6, 0x4b, 0xdb, 0xcd, 0x78, 0x08, 0x8e, 0xa8, 0xa5, 0x5d, 0x93, 0xd4, 0xc4, 0xd5, + 0x80, 0xfa, 0x87, 0x9a, 0x8b, 0xfd, 0x23, 0x0b, 0x66, 0xaa, 0xbd, 0x68, 0x87, 0xe9, 0x28, 0x0d, + 0x6e, 0x8d, 0x23, 0x1e, 0x14, 0x43, 0xb7, 0xb5, 0xf7, 0x52, 0x3e, 0x8b, 0x71, 0x9d, 0x91, 0x92, + 0x57, 0x24, 0x5a, 0x59, 0xe7, 0x85, 0x28, 0xd8, 0x90, 0x00, 0x26, 0x7c, 0xa7, 0x17, 0xed, 0x5c, + 0x91, 0x9f, 0x3c, 0xa2, 0x65, 0xe2, 0x16, 0xfb, 0x9c, 0x2b, 0x92, 0xa3, 0x56, 0x19, 0x45, 0x29, + 0x4a, 0x4e, 0xf6, 0x17, 0x60, 0x26, 0x79, 0xef, 0x76, 0x82, 0x31, 0xfb, 0x14, 0x14, 0x9c, 0xc0, + 0x93, 0x23, 0x76, 0x4a, 0x22, 0x14, 0xaa, 0x78, 0x13, 0x59, 0x39, 0x79, 0x01, 0x4a, 0xdb, 0xbd, + 0x76, 0x9b, 0x9f, 0x2b, 0xc4, 0x25, 0x97, 0x3e, 0x16, 0x5d, 0x93, 0xe5, 0xa8, 0x31, 0xec, 0x3f, + 0x1d, 0x87, 0xd9, 0x5a, 0xbb, 0x47, 0x5f, 0x0f, 0x28, 0x55, 0xb6, 0xa0, 0x2a, 0xcc, 0x76, 0x03, + 0xba, 0xe7, 0xd2, 0x7b, 0x75, 0xda, 0xa6, 0x8d, 0xc8, 0x0f, 0xa4, 0x34, 0x8f, 0x49, 0x42, 0xb3, + 0x1b, 0x49, 0x30, 0xa6, 0xf1, 0xc9, 0x6b, 0x30, 0xe3, 0x34, 0x22, 0x77, 0x8f, 0x6a, 0x0a, 0x42, + 0xdc, 0x47, 0x25, 0x85, 0x99, 0x6a, 0x02, 0x8a, 0x29, 0x6c, 0xf2, 0x19, 0x98, 0x0f, 0x1b, 0x4e, + 0x9b, 0xde, 0xee, 0x4a, 0x56, 0xcb, 0x3b, 0xb4, 0xb1, 0xbb, 0xe1, 0xbb, 0x5e, 0x24, 0xed, 0x8e, + 0x4f, 0x4b, 0x4a, 0xf3, 0xf5, 0x01, 0x78, 0x38, 0x90, 0x02, 0xf9, 0x17, 0x16, 0x3c, 0xd5, 0x0d, + 0xe8, 0x46, 0xe0, 0x77, 0x7c, 0x36, 0xd4, 0xfa, 0xcc, 0x61, 0xd2, 0x2c, 0xf4, 0xd6, 0x88, 0xba, + 0x94, 0x28, 0xe9, 0xbf, 0xc3, 0xf9, 0xd0, 0xe1, 0x41, 0xe5, 0xa9, 0x8d, 0xa3, 0x04, 0xc0, 0xa3, + 0xe5, 0x23, 0xff, 0xd2, 0x82, 0xcb, 0x5d, 0x3f, 0x8c, 0x8e, 0xf8, 0x84, 0xe2, 0x99, 0x7e, 0x82, + 0x7d, 0x78, 0x50, 0xb9, 0xbc, 0x71, 0xa4, 0x04, 0x78, 0x8c, 0x84, 0xf6, 0xe1, 0x14, 0x9c, 0x37, + 0xc6, 0x9e, 0x34, 0xe6, 0xbc, 0x0a, 0xe7, 0xd4, 0x60, 0x88, 0x75, 0x9f, 0x72, 0x6c, 0xdb, 0xab, + 0x9a, 0x40, 0x4c, 0xe2, 0xb2, 0x71, 0xa7, 0x87, 0xa2, 0xa8, 0x9d, 0x1a, 0x77, 0x1b, 0x09, 0x28, + 0xa6, 0xb0, 0xc9, 0x2a, 0x5c, 0x90, 0x25, 0x48, 0xbb, 0x6d, 0xb7, 0xe1, 0x2c, 0xfb, 0x3d, 0x39, + 0xe4, 0x8a, 0xb5, 0xc7, 0x0e, 0x0f, 0x2a, 0x17, 0x36, 0xfa, 0xc1, 0x98, 0x55, 0x87, 0xac, 0xc1, + 0x45, 0xa7, 0x17, 0xf9, 0xfa, 0xfb, 0xaf, 0x7a, 0x6c, 0x3b, 0x6d, 0xf2, 0xa1, 0x55, 0x12, 0xfb, + 0x6e, 0x35, 0x03, 0x8e, 0x99, 0xb5, 0xc8, 0x46, 0x8a, 0x5a, 0x9d, 0x36, 0x7c, 0xaf, 0x29, 0x7a, + 0xb9, 0x18, 0x1f, 0x03, 0xab, 0x19, 0x38, 0x98, 0x59, 0x93, 0xb4, 0x61, 0xa6, 0xe3, 0xdc, 0xbf, + 0xed, 0x39, 0x7b, 0x8e, 0xdb, 0x66, 0x4c, 0xa4, 0xbd, 0x70, 0xb0, 0x95, 0xa9, 0x17, 0xb9, 0xed, + 0x45, 0xe1, 0xc7, 0xb1, 0xb8, 0xea, 0x45, 0xb7, 0x82, 0x7a, 0xc4, 0x34, 0x75, 0xa1, 0x41, 0xae, + 0x27, 0x68, 0x61, 0x8a, 0x36, 0xb9, 0x05, 0x97, 0xf8, 0x74, 0x5c, 0xf1, 0xef, 0x79, 0x2b, 0xb4, + 0xed, 0xec, 0xab, 0x0f, 0x98, 0xe4, 0x1f, 0xf0, 0xf8, 0xe1, 0x41, 0xe5, 0x52, 0x3d, 0x0b, 0x01, + 0xb3, 0xeb, 0x11, 0x07, 0x9e, 0x48, 0x02, 0x90, 0xee, 0xb9, 0xa1, 0xeb, 0x7b, 0xc2, 0x2c, 0x57, + 0x8a, 0xcd, 0x72, 0xf5, 0xc1, 0x68, 0x78, 0x14, 0x0d, 0xf2, 0x77, 0x2d, 0xb8, 0x98, 0x35, 0x0d, + 0xe7, 0xcb, 0x79, 0xdc, 0x26, 0xa7, 0xa6, 0x96, 0x18, 0x11, 0x99, 0x8b, 0x42, 0xa6, 0x10, 0xe4, + 0x3d, 0x0b, 0xa6, 0x1d, 0xe3, 0x04, 0x3d, 0x0f, 0x79, 0xec, 0x5a, 0xe6, 0x99, 0xbc, 0x36, 0x77, + 0x78, 0x50, 0x49, 0x9c, 0xd2, 0x31, 0xc1, 0x91, 0xfc, 0x7d, 0x0b, 0x2e, 0x65, 0xce, 0xf1, 0xf9, + 0xa9, 0xb3, 0x68, 0x21, 0x3e, 0x48, 0xb2, 0xd7, 0x9c, 0x6c, 0x31, 0xc8, 0x37, 0x2c, 0xbd, 0x95, + 0xa9, 0x0b, 0xc6, 0xf9, 0x69, 0x2e, 0xda, 0x88, 0x06, 0x0f, 0x43, 0x8d, 0x52, 0x84, 0x6b, 0x17, + 0x8c, 0x9d, 0x51, 0x15, 0x62, 0x9a, 0x3d, 0xf9, 0xba, 0xa5, 0xb6, 0x46, 0x2d, 0xd1, 0xb9, 0xb3, + 0x92, 0x88, 0xc4, 0x3b, 0xad, 0x16, 0x28, 0xc5, 0x9c, 0xfc, 0x0c, 0x2c, 0x38, 0x5b, 0x7e, 0x10, + 0x65, 0x4e, 0xbe, 0xf9, 0x19, 0x3e, 0x8d, 0x2e, 0x1f, 0x1e, 0x54, 0x16, 0xaa, 0x03, 0xb1, 0xf0, + 0x08, 0x0a, 0xf6, 0x6f, 0x14, 0x61, 0x5a, 0x9c, 0x84, 0xe4, 0xd6, 0xf5, 0xdb, 0x16, 0x3c, 0xd9, + 0xe8, 0x05, 0x01, 0xf5, 0xa2, 0x7a, 0x44, 0xbb, 0xfd, 0x1b, 0x97, 0x75, 0xa6, 0x1b, 0xd7, 0xd3, + 0x87, 0x07, 0x95, 0x27, 0x97, 0x8f, 0xe0, 0x8f, 0x47, 0x4a, 0x47, 0xfe, 0x9d, 0x05, 0xb6, 0x44, + 0xa8, 0x39, 0x8d, 0xdd, 0x56, 0xe0, 0xf7, 0xbc, 0x66, 0xff, 0x47, 0x8c, 0x9d, 0xe9, 0x47, 0x3c, + 0x7b, 0x78, 0x50, 0xb1, 0x97, 0x8f, 0x95, 0x02, 0x4f, 0x20, 0x29, 0x79, 0x1d, 0xce, 0x4b, 0xac, + 0xab, 0xf7, 0xbb, 0x34, 0x70, 0xd9, 0x99, 0x43, 0x2a, 0x8e, 0xb1, 0x6f, 0x5a, 0x1a, 0x01, 0xfb, + 0xeb, 0x90, 0x10, 0x26, 0xef, 0x51, 0xb7, 0xb5, 0x13, 0x29, 0xf5, 0x69, 0x44, 0x87, 0x34, 0x69, + 0x15, 0xb9, 0x23, 0x68, 0xd6, 0xa6, 0x0e, 0x0f, 0x2a, 0x93, 0xf2, 0x0f, 0x2a, 0x4e, 0xe4, 0x26, + 0xcc, 0x88, 0x73, 0xea, 0x86, 0xeb, 0xb5, 0x36, 0x7c, 0x4f, 0x78, 0x55, 0x95, 0x6b, 0xcf, 0xaa, + 0x0d, 0xbf, 0x9e, 0x80, 0x3e, 0x38, 0xa8, 0x4c, 0xab, 0xdf, 0x9b, 0xfb, 0x5d, 0x8a, 0xa9, 0xda, + 0xf6, 0xef, 0x4e, 0x00, 0xa8, 0xe1, 0x4a, 0xbb, 0xe4, 0xc3, 0x50, 0x0e, 0x69, 0x24, 0xb8, 0xca, + 0x9b, 0x24, 0x71, 0xff, 0xa7, 0x0a, 0x31, 0x86, 0x93, 0x5d, 0x28, 0x76, 0x9d, 0x5e, 0x48, 0xf3, + 0x39, 0x3f, 0xc8, 0xce, 0xdf, 0x60, 0x14, 0xc5, 0xc1, 0x94, 0xff, 0x44, 0xc1, 0x83, 0x7c, 0xd9, + 0x02, 0xa0, 0xc9, 0x0e, 0x1b, 0xd9, 0x40, 0x24, 0x59, 0xc6, 0x7d, 0xca, 0xda, 0xa0, 0x36, 0x73, + 0x78, 0x50, 0x01, 0xa3, 0xeb, 0x0d, 0xb6, 0xe4, 0x1e, 0x94, 0x1c, 0xb5, 0xe6, 0x8f, 0x9f, 0xc5, + 0x9a, 0xcf, 0xcf, 0x8b, 0x7a, 0xd0, 0x6a, 0x66, 0xe4, 0xab, 0x16, 0xcc, 0x84, 0x34, 0x92, 0x5d, + 0xc5, 0x56, 0x1e, 0xa9, 0xf0, 0x8e, 0x38, 0xe8, 0xea, 0x09, 0x9a, 0x62, 0x05, 0x4d, 0x96, 0x61, + 0x8a, 0xaf, 0x12, 0xe5, 0x3a, 0x75, 0x9a, 0x34, 0xe0, 0xe6, 0x08, 0xa9, 0x49, 0x8d, 0x2e, 0x8a, + 0x41, 0x53, 0x8b, 0x62, 0x94, 0x61, 0x8a, 0xaf, 0x12, 0x65, 0xdd, 0x0d, 0x02, 0x5f, 0x8a, 0x52, + 0xca, 0x49, 0x14, 0x83, 0xa6, 0x16, 0xc5, 0x28, 0xc3, 0x14, 0x5f, 0xfb, 0x5b, 0xe7, 0x60, 0x46, + 0x4d, 0xa4, 0x58, 0xb3, 0x17, 0xd6, 0xaf, 0x01, 0x9a, 0xfd, 0xb2, 0x09, 0xc4, 0x24, 0x2e, 0xab, + 0x2c, 0xa6, 0x6a, 0x52, 0xb1, 0xd7, 0x95, 0xeb, 0x26, 0x10, 0x93, 0xb8, 0xa4, 0x03, 0xc5, 0x30, + 0xa2, 0x5d, 0xe5, 0x73, 0x30, 0xe2, 0x95, 0x78, 0xbc, 0x3e, 0x18, 0x96, 0x04, 0x46, 0x1e, 0x05, + 0x17, 0x6e, 0xc0, 0x8d, 0x12, 0x36, 0x5d, 0x39, 0x39, 0xf2, 0x99, 0x9f, 0x49, 0x73, 0xb1, 0xe8, + 0x8d, 0x64, 0x19, 0xa6, 0xd8, 0x67, 0x28, 0xfb, 0xc5, 0x33, 0x54, 0xf6, 0x3f, 0x05, 0xa5, 0x8e, + 0x73, 0xbf, 0xde, 0x0b, 0x5a, 0xa7, 0x3f, 0x54, 0x48, 0x1f, 0x52, 0x41, 0x05, 0x35, 0x3d, 0xf2, + 0x45, 0xcb, 0x58, 0x72, 0x84, 0x83, 0xc1, 0x9d, 0x7c, 0x97, 0x1c, 0xbd, 0x57, 0x0e, 0x5c, 0x7c, + 0xfa, 0x54, 0xef, 0xd2, 0x43, 0x57, 0xbd, 0x99, 0x1a, 0x29, 0x26, 0x88, 0x56, 0x23, 0xcb, 0x67, + 0xaa, 0x46, 0x2e, 0x27, 0x98, 0x61, 0x8a, 0x39, 0x97, 0x47, 0xcc, 0x39, 0x2d, 0x0f, 0x9c, 0xa9, + 0x3c, 0xf5, 0x04, 0x33, 0x4c, 0x31, 0x1f, 0x7c, 0xde, 0x9c, 0x3a, 0x9b, 0xf3, 0xe6, 0x74, 0x0e, + 0xe7, 0xcd, 0xa3, 0x55, 0xf1, 0x73, 0xa3, 0xaa, 0xe2, 0xe4, 0x06, 0x90, 0xe6, 0xbe, 0xe7, 0x74, + 0xdc, 0x86, 0x5c, 0x2c, 0xf9, 0xb6, 0x39, 0xc3, 0xed, 0x11, 0x0b, 0x72, 0x21, 0x23, 0x2b, 0x7d, + 0x18, 0x98, 0x51, 0x8b, 0x44, 0x50, 0xea, 0x2a, 0x8d, 0x6b, 0x36, 0x8f, 0xd1, 0xaf, 0x34, 0x30, + 0xe1, 0x37, 0xc2, 0x26, 0x9e, 0x2a, 0x41, 0xcd, 0x89, 0xac, 0xc1, 0xc5, 0x8e, 0xeb, 0x6d, 0xf8, + 0xcd, 0x70, 0x83, 0x06, 0xd2, 0xda, 0x52, 0xa7, 0xd1, 0xfc, 0x1c, 0x6f, 0x1b, 0x7e, 0x82, 0x5e, + 0xcf, 0x80, 0x63, 0x66, 0x2d, 0xfb, 0x7f, 0x5b, 0x30, 0xb7, 0xdc, 0xf6, 0x7b, 0xcd, 0x3b, 0x4e, + 0xd4, 0xd8, 0x11, 0x6e, 0x0a, 0xe4, 0x35, 0x28, 0xb9, 0x5e, 0x44, 0x83, 0x3d, 0xa7, 0x2d, 0xf7, + 0x27, 0x5b, 0x99, 0x4f, 0x57, 0x65, 0xf9, 0x83, 0x83, 0xca, 0xcc, 0x4a, 0x2f, 0xe0, 0x56, 0x6a, + 0xb1, 0x5a, 0xa1, 0xae, 0x43, 0xbe, 0x65, 0xc1, 0x79, 0xe1, 0xe8, 0xb0, 0xe2, 0x44, 0xce, 0x9b, + 0x3d, 0x1a, 0xb8, 0x54, 0xb9, 0x3a, 0x8c, 0xb8, 0x50, 0xa5, 0x65, 0x55, 0x0c, 0xf6, 0x63, 0x45, + 0x7d, 0x3d, 0xcd, 0x19, 0xfb, 0x85, 0xb1, 0x7f, 0xa9, 0x00, 0x8f, 0x0f, 0xa4, 0x45, 0x16, 0x60, + 0xcc, 0x6d, 0xca, 0x4f, 0x07, 0x49, 0x77, 0x6c, 0xb5, 0x89, 0x63, 0x6e, 0x93, 0x2c, 0x72, 0x9d, + 0x33, 0xa0, 0x61, 0xa8, 0x2e, 0x9c, 0xcb, 0x5a, 0x3d, 0x94, 0xa5, 0x68, 0x60, 0x90, 0x0a, 0x14, + 0xb9, 0xff, 0xb0, 0x3c, 0x4f, 0x70, 0x2d, 0x96, 0xbb, 0xea, 0xa2, 0x28, 0x27, 0x5f, 0xb2, 0x00, + 0x84, 0x80, 0xec, 0x34, 0x22, 0x77, 0x49, 0xcc, 0xb7, 0x99, 0x18, 0x65, 0x21, 0x65, 0xfc, 0x1f, + 0x0d, 0xae, 0x64, 0x13, 0x26, 0x98, 0x42, 0xeb, 0x37, 0x4f, 0xbd, 0x29, 0xf2, 0x9b, 0xa8, 0x0d, + 0x4e, 0x03, 0x25, 0x2d, 0xd6, 0x56, 0x01, 0x8d, 0x7a, 0x81, 0xc7, 0x9a, 0x96, 0x6f, 0x83, 0x25, + 0x21, 0x05, 0xea, 0x52, 0x34, 0x30, 0xec, 0x7f, 0x36, 0x06, 0x17, 0xb3, 0x44, 0x67, 0xbb, 0xcd, + 0x84, 0x90, 0x56, 0x1e, 0x8d, 0x7f, 0x2a, 0xff, 0xf6, 0x91, 0x3e, 0x3b, 0xfa, 0x9a, 0x42, 0x3a, + 0x50, 0x4a, 0xbe, 0xe4, 0xa7, 0x74, 0x0b, 0x8d, 0x9d, 0xb2, 0x85, 0x34, 0xe5, 0x54, 0x2b, 0x3d, + 0x0d, 0xe3, 0x21, 0xeb, 0xf9, 0x42, 0xf2, 0xba, 0x83, 0xf7, 0x11, 0x87, 0x30, 0x8c, 0x9e, 0xe7, + 0x46, 0x32, 0xe8, 0x46, 0x63, 0xdc, 0xf6, 0xdc, 0x08, 0x39, 0xc4, 0xfe, 0xe6, 0x18, 0x2c, 0x0c, + 0xfe, 0x28, 0xf2, 0x4d, 0x0b, 0xa0, 0xc9, 0x8e, 0x2b, 0x21, 0xf7, 0x5c, 0x17, 0x3e, 0x4e, 0xce, + 0x59, 0xb5, 0xe1, 0x8a, 0xe2, 0x14, 0x3b, 0xdf, 0xe9, 0xa2, 0x10, 0x0d, 0x41, 0xc8, 0x15, 0x35, + 0xf4, 0xf9, 0x55, 0x8d, 0x98, 0x4c, 0xba, 0xce, 0xba, 0x86, 0xa0, 0x81, 0xc5, 0xce, 0xa3, 0x9e, + 0xd3, 0xa1, 0x61, 0xd7, 0xd1, 0x21, 0x4c, 0xfc, 0x3c, 0x7a, 0x53, 0x15, 0x62, 0x0c, 0xb7, 0xdb, + 0xf0, 0xcc, 0x09, 0xe4, 0xcc, 0x29, 0x42, 0xc4, 0xfe, 0x9f, 0x16, 0x3c, 0x26, 0xdd, 0xcf, 0xfe, + 0xcc, 0xf8, 0x32, 0xfe, 0x89, 0x05, 0x4f, 0x0c, 0xf8, 0xe6, 0x87, 0xe0, 0xd2, 0xf8, 0x4e, 0xd2, + 0xa5, 0xf1, 0xf6, 0xa8, 0x43, 0x3a, 0xf3, 0x3b, 0x06, 0x78, 0x36, 0xfe, 0x9b, 0x02, 0x9c, 0x63, + 0xcb, 0x56, 0xd3, 0x6f, 0xe5, 0xb4, 0x71, 0x3e, 0x03, 0xc5, 0xcf, 0xb1, 0x0d, 0x28, 0x3d, 0xc8, + 0xf8, 0xae, 0x84, 0x02, 0x46, 0xbe, 0x6c, 0xc1, 0xe4, 0xe7, 0xe4, 0x9e, 0x2a, 0xce, 0x72, 0x23, + 0x2e, 0x86, 0x89, 0x6f, 0x58, 0x94, 0x3b, 0xa4, 0x08, 0x3c, 0xd1, 0x0e, 0x8c, 0x6a, 0x2b, 0x55, + 0x9c, 0xc9, 0xf3, 0x30, 0xb9, 0xed, 0x07, 0x9d, 0x5e, 0xdb, 0x49, 0x47, 0x3b, 0x5e, 0x13, 0xc5, + 0xa8, 0xe0, 0x6c, 0x92, 0x3b, 0x5d, 0xf7, 0x2d, 0x1a, 0x84, 0x22, 0x0e, 0x21, 0x31, 0xc9, 0xab, + 0x1a, 0x82, 0x06, 0x16, 0xaf, 0xd3, 0x6a, 0x05, 0xb4, 0xe5, 0x44, 0x7e, 0xc0, 0x77, 0x0e, 0xb3, + 0x8e, 0x86, 0xa0, 0x81, 0xb5, 0xf0, 0x09, 0x98, 0x36, 0x85, 0x1f, 0x2a, 0x88, 0xe5, 0x93, 0x20, + 0x3d, 0x19, 0x53, 0x4b, 0x92, 0x75, 0x92, 0x25, 0xc9, 0xfe, 0x0f, 0x63, 0x60, 0x58, 0x87, 0x1e, + 0xc2, 0x54, 0xf7, 0x12, 0x53, 0x7d, 0x44, 0xcb, 0x86, 0x61, 0xeb, 0x1a, 0x14, 0xd2, 0xb7, 0x97, + 0x0a, 0xe9, 0xbb, 0x99, 0x1b, 0xc7, 0xa3, 0x23, 0xfa, 0xbe, 0x6f, 0xc1, 0x13, 0x31, 0x72, 0xbf, + 0xe1, 0xf6, 0xf8, 0x75, 0xfb, 0x65, 0x98, 0x72, 0xe2, 0x6a, 0x72, 0x62, 0x19, 0xf1, 0x54, 0x1a, + 0x84, 0x26, 0x5e, 0x1c, 0x0b, 0x52, 0x38, 0x65, 0x2c, 0xc8, 0xf8, 0xd1, 0xb1, 0x20, 0xf6, 0x8f, + 0xc6, 0xe0, 0xa9, 0xfe, 0x2f, 0x33, 0x1d, 0xa4, 0x8f, 0xff, 0xb6, 0xb4, 0x0b, 0xf5, 0xd8, 0xa9, + 0x5d, 0xa8, 0x0b, 0x27, 0x75, 0xa1, 0xd6, 0x8e, 0xcb, 0xe3, 0x67, 0xee, 0xb8, 0x5c, 0x87, 0x4b, + 0xca, 0x4b, 0xf2, 0x9a, 0x1f, 0xc8, 0x80, 0x08, 0xb5, 0x82, 0x94, 0x6a, 0x4f, 0xc9, 0x2a, 0x97, + 0x30, 0x0b, 0x09, 0xb3, 0xeb, 0xda, 0xdf, 0x2f, 0xc0, 0x85, 0xb8, 0xd9, 0x97, 0x7d, 0xaf, 0xe9, + 0x72, 0x47, 0x9b, 0x57, 0x61, 0x3c, 0xda, 0xef, 0xaa, 0xc6, 0xfe, 0x8b, 0x4a, 0x9c, 0xcd, 0xfd, + 0x2e, 0xeb, 0xed, 0xc7, 0x32, 0xaa, 0x70, 0xd3, 0x39, 0xaf, 0x44, 0xd6, 0xf4, 0xec, 0x10, 0x3d, + 0xf0, 0x52, 0x72, 0x34, 0x3f, 0x38, 0xa8, 0x64, 0xa4, 0x36, 0x58, 0xd4, 0x94, 0x92, 0x63, 0x9e, + 0xdc, 0x85, 0x99, 0xb6, 0x13, 0x46, 0xb7, 0xbb, 0x4d, 0x27, 0xa2, 0x9b, 0xae, 0x74, 0x61, 0x19, + 0x2e, 0x86, 0x44, 0xdf, 0xf5, 0xaf, 0x25, 0x28, 0x61, 0x8a, 0x32, 0xd9, 0x03, 0xc2, 0x4a, 0x36, + 0x03, 0xc7, 0x0b, 0xc5, 0x57, 0x31, 0x7e, 0xc3, 0x07, 0x04, 0xe9, 0xa3, 0xf3, 0x5a, 0x1f, 0x35, + 0xcc, 0xe0, 0x40, 0x9e, 0x85, 0x89, 0x80, 0x3a, 0xa1, 0xde, 0x0e, 0xf4, 0xfc, 0x47, 0x5e, 0x8a, + 0x12, 0x6a, 0x4e, 0xa8, 0x89, 0x63, 0x26, 0xd4, 0x1f, 0x5a, 0x30, 0x13, 0x77, 0xd3, 0x43, 0x50, + 0x3d, 0x3a, 0x49, 0xd5, 0xe3, 0x7a, 0x5e, 0x4b, 0xe2, 0x00, 0x6d, 0xe3, 0x5f, 0x4f, 0x98, 0xdf, + 0xc7, 0xa3, 0x16, 0x3e, 0x6f, 0x3a, 0xb1, 0x5b, 0x79, 0x84, 0x92, 0x25, 0xb4, 0xbd, 0x23, 0xbd, + 0xd7, 0x99, 0xae, 0xd3, 0x94, 0x7a, 0x8c, 0x1c, 0xf6, 0x5a, 0xd7, 0x51, 0xfa, 0x4d, 0x96, 0xae, + 0xa3, 0xea, 0x90, 0xdb, 0xf0, 0x58, 0x37, 0xf0, 0x79, 0x70, 0xfd, 0x0a, 0x75, 0x9a, 0x6d, 0xd7, + 0xa3, 0xca, 0xcc, 0x23, 0x5c, 0x4d, 0x9e, 0x38, 0x3c, 0xa8, 0x3c, 0xb6, 0x91, 0x8d, 0x82, 0x83, + 0xea, 0x26, 0xc3, 0x33, 0xc7, 0x4f, 0x10, 0x9e, 0xf9, 0xf3, 0xda, 0x98, 0xaa, 0x23, 0x01, 0x3e, + 0x9d, 0x57, 0x57, 0x66, 0xc5, 0x04, 0xe8, 0x21, 0x55, 0x95, 0x4c, 0x51, 0xb3, 0x1f, 0x6c, 0xb1, + 0x9b, 0x38, 0xa5, 0xc5, 0x2e, 0x0e, 0xfe, 0x98, 0xfc, 0x20, 0x83, 0x3f, 0x4a, 0x3f, 0x4e, 0xc1, + 0x1f, 0xf6, 0xfb, 0x45, 0x98, 0x4b, 0x6b, 0x20, 0x67, 0x1f, 0xfc, 0xf9, 0xb7, 0x2c, 0x98, 0x53, + 0xb3, 0x47, 0xf0, 0xd4, 0xfa, 0xfb, 0x5a, 0x4e, 0x93, 0x56, 0xe8, 0x52, 0x3a, 0x27, 0xc7, 0x66, + 0x8a, 0x1b, 0xf6, 0xf1, 0x27, 0x6f, 0xc3, 0x94, 0xbe, 0xb2, 0x38, 0x55, 0x24, 0x28, 0x0f, 0x56, + 0xac, 0xc6, 0x24, 0xd0, 0xa4, 0x47, 0xde, 0xb7, 0x00, 0x1a, 0x6a, 0x9b, 0xcb, 0x29, 0xce, 0x26, + 0x63, 0x2b, 0x8e, 0x95, 0x65, 0x5d, 0x14, 0xa2, 0xc1, 0x98, 0xfc, 0x12, 0xbf, 0xac, 0xd0, 0xda, + 0x9d, 0xc8, 0xf5, 0x31, 0xb2, 0x4f, 0xf9, 0x11, 0x8a, 0x69, 0xac, 0x4a, 0x19, 0xa0, 0x10, 0x13, + 0x42, 0xd8, 0xaf, 0x82, 0xf6, 0x02, 0x66, 0xcb, 0x16, 0xf7, 0x03, 0xde, 0x70, 0xa2, 0x1d, 0x39, + 0x04, 0xf5, 0xb2, 0x75, 0x4d, 0x01, 0x30, 0xc6, 0xb1, 0x3f, 0x0b, 0x33, 0xaf, 0x07, 0x4e, 0x77, + 0xc7, 0xe5, 0x97, 0x02, 0xec, 0xf0, 0xf9, 0x3c, 0x4c, 0x3a, 0xcd, 0x66, 0x56, 0xfa, 0x98, 0xaa, + 0x28, 0x46, 0x05, 0x3f, 0xd1, 0x39, 0xd3, 0xfe, 0x5d, 0x0b, 0x48, 0x7c, 0xb1, 0xea, 0x7a, 0xad, + 0x75, 0x27, 0x6a, 0xec, 0xb0, 0xf3, 0xd1, 0x0e, 0x2f, 0xcd, 0x3a, 0x1f, 0x5d, 0xd7, 0x10, 0x34, + 0xb0, 0xc8, 0xbb, 0x30, 0x25, 0xfe, 0xbd, 0xa5, 0x4f, 0x5f, 0xa3, 0x3b, 0x33, 0xf3, 0x0d, 0x85, + 0xcb, 0x24, 0x46, 0xe1, 0xf5, 0x98, 0x03, 0x9a, 0xec, 0x58, 0x53, 0xad, 0x7a, 0xdb, 0xed, 0xde, + 0xfd, 0xe6, 0x56, 0xdc, 0x54, 0xdd, 0xc0, 0xdf, 0x76, 0xdb, 0x34, 0xdd, 0x54, 0x1b, 0xa2, 0x18, + 0x15, 0xfc, 0x64, 0x4d, 0xf5, 0xaf, 0x2c, 0xb8, 0xb8, 0x1a, 0x46, 0xae, 0xbf, 0x42, 0xc3, 0x88, + 0x6d, 0x2b, 0x6c, 0xf1, 0xe9, 0xb5, 0x4f, 0xe2, 0xd0, 0xbf, 0x02, 0x73, 0xf2, 0x92, 0xb7, 0xb7, + 0x15, 0xd2, 0xc8, 0xd0, 0xe3, 0xf5, 0x3c, 0x5e, 0x4e, 0xc1, 0xb1, 0xaf, 0x06, 0xa3, 0x22, 0x6f, + 0x7b, 0x63, 0x2a, 0x85, 0x24, 0x95, 0x7a, 0x0a, 0x8e, 0x7d, 0x35, 0xec, 0xef, 0x15, 0xe0, 0x02, + 0xff, 0x8c, 0x54, 0x30, 0xce, 0xd7, 0x07, 0x05, 0xe3, 0x8c, 0x38, 0x95, 0x39, 0xaf, 0x53, 0x84, + 0xe2, 0xfc, 0x4d, 0x0b, 0x66, 0x9b, 0xc9, 0x96, 0xce, 0xc7, 0xe8, 0x95, 0xd5, 0x87, 0xc2, 0xa7, + 0x2d, 0x55, 0x88, 0x69, 0xfe, 0xe4, 0x97, 0x2d, 0x98, 0x4d, 0x8a, 0xa9, 0x56, 0xf7, 0x33, 0x68, + 0x24, 0xed, 0x84, 0x9e, 0x2c, 0x0f, 0x31, 0x2d, 0x82, 0xfd, 0x7b, 0x63, 0xb2, 0x4b, 0xcf, 0x22, + 0xd2, 0x84, 0xdc, 0x83, 0x72, 0xd4, 0x0e, 0x45, 0xa1, 0xfc, 0xda, 0x11, 0x4f, 0x84, 0x9b, 0x6b, + 0x75, 0xe1, 0x5f, 0x11, 0x2b, 0x6d, 0xb2, 0x84, 0x29, 0x9f, 0x8a, 0x17, 0x67, 0xdc, 0xe8, 0x4a, + 0xc6, 0xb9, 0x1c, 0x45, 0x37, 0x97, 0x37, 0xd2, 0x8c, 0x65, 0x09, 0x63, 0xac, 0x78, 0xd9, 0xbf, + 0x6e, 0x41, 0xf9, 0x86, 0xaf, 0xd6, 0x91, 0x9f, 0xc9, 0xc1, 0xd0, 0xa3, 0xf5, 0x41, 0x7d, 0x8f, + 0x1b, 0x1f, 0x31, 0x5e, 0x4b, 0x98, 0x79, 0x9e, 0x34, 0x68, 0x2f, 0xf2, 0x2c, 0x7a, 0x8c, 0xd4, + 0x0d, 0x7f, 0x6b, 0xa0, 0x6d, 0xf6, 0x57, 0x8a, 0x70, 0xee, 0x0d, 0x67, 0x9f, 0x7a, 0x91, 0x33, + 0xfc, 0x26, 0xf1, 0x32, 0x4c, 0x39, 0x5d, 0x7e, 0x51, 0x68, 0xe8, 0xf8, 0xb1, 0xe5, 0x24, 0x06, + 0xa1, 0x89, 0x17, 0x2f, 0x68, 0x22, 0xec, 0x23, 0x6b, 0x29, 0x5a, 0x4e, 0xc1, 0xb1, 0xaf, 0x06, + 0xb9, 0x01, 0x44, 0x86, 0x4a, 0x57, 0x1b, 0x0d, 0xbf, 0xe7, 0x89, 0x25, 0x4d, 0x18, 0x55, 0xf4, + 0x61, 0x73, 0xbd, 0x0f, 0x03, 0x33, 0x6a, 0x91, 0xcf, 0xc0, 0x7c, 0x83, 0x53, 0x96, 0x47, 0x0f, + 0x93, 0xa2, 0x38, 0x7e, 0xea, 0x40, 0x8a, 0xe5, 0x01, 0x78, 0x38, 0x90, 0x02, 0x93, 0x34, 0x8c, + 0xfc, 0xc0, 0x69, 0x51, 0x93, 0xee, 0x44, 0x52, 0xd2, 0x7a, 0x1f, 0x06, 0x66, 0xd4, 0x22, 0x5f, + 0x80, 0x72, 0xb4, 0x13, 0xd0, 0x70, 0xc7, 0x6f, 0x37, 0xa5, 0x63, 0xc7, 0x88, 0x96, 0x36, 0xd9, + 0xfb, 0x9b, 0x8a, 0xaa, 0x31, 0xbc, 0x55, 0x11, 0xc6, 0x3c, 0x49, 0x00, 0x13, 0x61, 0xc3, 0xef, + 0xd2, 0x50, 0xaa, 0xec, 0x37, 0x72, 0xe1, 0xce, 0x2d, 0x47, 0x86, 0x8d, 0x8f, 0x73, 0x40, 0xc9, + 0xc9, 0xfe, 0x9d, 0x31, 0x98, 0x36, 0x11, 0x4f, 0xb0, 0x36, 0x7d, 0xd9, 0x82, 0xe9, 0x86, 0xef, + 0x45, 0x81, 0xdf, 0x8e, 0x53, 0x00, 0x8c, 0xae, 0x51, 0x30, 0x52, 0x2b, 0x34, 0x72, 0xdc, 0xb6, + 0x61, 0x0a, 0x33, 0xd8, 0x60, 0x82, 0x29, 0xf9, 0x9a, 0x05, 0xb3, 0xb1, 0x1f, 0x60, 0x6c, 0x48, + 0xcb, 0x55, 0x10, 0xbd, 0xd4, 0x5f, 0x4d, 0x72, 0xc2, 0x34, 0x6b, 0x7b, 0x0b, 0xe6, 0xd2, 0xbd, + 0xcd, 0x9a, 0xb2, 0xeb, 0xc8, 0xb9, 0x5e, 0x88, 0x9b, 0x72, 0xc3, 0x09, 0x43, 0xe4, 0x10, 0xf2, + 0x02, 0x94, 0x3a, 0x4e, 0xd0, 0x72, 0x3d, 0xa7, 0xcd, 0x5b, 0xb1, 0x60, 0x2c, 0x48, 0xb2, 0x1c, + 0x35, 0x86, 0xfd, 0x51, 0x98, 0x5e, 0x77, 0xbc, 0x16, 0x6d, 0xca, 0x75, 0xf8, 0xf8, 0x58, 0xc7, + 0x3f, 0x1e, 0x87, 0x29, 0xe3, 0x6c, 0x76, 0xf6, 0xe7, 0xac, 0x44, 0x6a, 0x9b, 0x42, 0x8e, 0xa9, + 0x6d, 0x3e, 0x05, 0xb0, 0xed, 0x7a, 0x6e, 0xb8, 0x73, 0xca, 0xa4, 0x39, 0xfc, 0xe2, 0xfb, 0x9a, + 0xa6, 0x80, 0x06, 0xb5, 0xf8, 0x76, 0xb1, 0x78, 0x44, 0xfe, 0xb9, 0xf7, 0x2d, 0x63, 0xbb, 0x99, + 0xc8, 0xc3, 0x9b, 0xc2, 0xe8, 0x98, 0x45, 0xb5, 0xfd, 0x88, 0x8b, 0x9f, 0xa3, 0x76, 0xa5, 0x4d, + 0x28, 0x05, 0x34, 0xec, 0x75, 0xe8, 0xa9, 0xd2, 0xdb, 0x70, 0xbf, 0x16, 0x94, 0xf5, 0x51, 0x53, + 0x5a, 0x78, 0x15, 0xce, 0x25, 0x44, 0x18, 0xea, 0xfa, 0xc6, 0x87, 0x4c, 0x03, 0xc0, 0x69, 0x2e, + 0x73, 0x58, 0x5f, 0xb4, 0x8d, 0xb4, 0x36, 0xba, 0x2f, 0x84, 0xf7, 0x92, 0x80, 0xd9, 0x3f, 0x9a, + 0x00, 0xe9, 0x20, 0x70, 0x82, 0xe5, 0xca, 0xbc, 0x16, 0x1c, 0x3b, 0xc5, 0xb5, 0xe0, 0x0d, 0x98, + 0x76, 0x3d, 0x37, 0x72, 0x9d, 0x36, 0x37, 0xee, 0xc8, 0xed, 0x54, 0xb9, 0x77, 0x4f, 0xaf, 0x1a, + 0xb0, 0x0c, 0x3a, 0x89, 0xba, 0xe4, 0x4d, 0x28, 0xf2, 0xfd, 0x46, 0x0e, 0xe0, 0xe1, 0xbd, 0x18, + 0xb8, 0x03, 0x8b, 0x88, 0xf9, 0x12, 0x94, 0xf8, 0xe1, 0x43, 0xe4, 0xf5, 0xd1, 0xc7, 0x6f, 0x39, + 0x8e, 0xe3, 0xc3, 0x47, 0x0a, 0x8e, 0x7d, 0x35, 0x18, 0x95, 0x6d, 0xc7, 0x6d, 0xf7, 0x02, 0x1a, + 0x53, 0x99, 0x48, 0x52, 0xb9, 0x96, 0x82, 0x63, 0x5f, 0x0d, 0xb2, 0x0d, 0xd3, 0xb2, 0x4c, 0xf8, + 0xa4, 0x4d, 0x9e, 0xf2, 0x2b, 0xb9, 0xef, 0xe1, 0x35, 0x83, 0x12, 0x26, 0xe8, 0x92, 0x1e, 0x9c, + 0x77, 0xbd, 0x86, 0xef, 0x35, 0xda, 0xbd, 0xd0, 0xdd, 0xa3, 0x71, 0xc0, 0xd5, 0x69, 0x98, 0x5d, + 0x3a, 0x3c, 0xa8, 0x9c, 0x5f, 0x4d, 0x93, 0xc3, 0x7e, 0x0e, 0xe4, 0x8b, 0x16, 0x5c, 0x6a, 0xf8, + 0x5e, 0xc8, 0xf3, 0x42, 0xec, 0xd1, 0xab, 0x41, 0xe0, 0x07, 0x82, 0x77, 0xf9, 0x94, 0xbc, 0xb9, + 0x4d, 0x71, 0x39, 0x8b, 0x24, 0x66, 0x73, 0x22, 0xef, 0x40, 0xa9, 0x1b, 0xf8, 0x7b, 0x6e, 0x93, + 0x06, 0xd2, 0xbf, 0x71, 0x2d, 0x8f, 0x64, 0x39, 0x1b, 0x92, 0x66, 0xbc, 0xf4, 0xa8, 0x12, 0xd4, + 0xfc, 0xec, 0xff, 0x33, 0x05, 0x33, 0x49, 0x74, 0xf2, 0x73, 0x00, 0xdd, 0xc0, 0xef, 0xd0, 0x68, + 0x87, 0xea, 0xc0, 0x99, 0x9b, 0xa3, 0xa6, 0x43, 0x51, 0xf4, 0x94, 0x4f, 0x10, 0x5b, 0x2e, 0xe2, + 0x52, 0x34, 0x38, 0x92, 0x00, 0x26, 0x77, 0xc5, 0xb6, 0x2b, 0xb5, 0x90, 0x37, 0x72, 0xd1, 0x99, + 0x24, 0x67, 0x1e, 0xf1, 0x21, 0x8b, 0x50, 0x31, 0x22, 0x5b, 0x50, 0xb8, 0x47, 0xb7, 0xf2, 0x89, + 0xc5, 0xbf, 0x43, 0xe5, 0x69, 0xa6, 0x36, 0x79, 0x78, 0x50, 0x29, 0xdc, 0xa1, 0x5b, 0xc8, 0x88, + 0xb3, 0xef, 0x6a, 0x0a, 0xc7, 0x00, 0xb9, 0x54, 0xbc, 0x91, 0xa3, 0x97, 0x81, 0xf8, 0x2e, 0x59, + 0x84, 0x8a, 0x11, 0x79, 0x07, 0xca, 0xf7, 0x9c, 0x3d, 0xba, 0x1d, 0xf8, 0x5e, 0x24, 0x1d, 0xd1, + 0x46, 0x8c, 0xa5, 0xb8, 0xa3, 0xc8, 0x49, 0xbe, 0x7c, 0x7b, 0xd7, 0x85, 0x18, 0xb3, 0x23, 0x7b, + 0x50, 0xf2, 0xe8, 0x3d, 0xa4, 0x6d, 0xb7, 0x91, 0x4f, 0xec, 0xc2, 0x4d, 0x49, 0x4d, 0x72, 0xe6, + 0xfb, 0x9e, 0x2a, 0x43, 0xcd, 0x8b, 0xf5, 0xe5, 0x5d, 0x7f, 0x4b, 0x2e, 0x54, 0x23, 0xf6, 0xa5, + 0x3e, 0x99, 0x8a, 0xbe, 0xbc, 0xe1, 0x6f, 0x21, 0x23, 0xce, 0xe6, 0x48, 0x43, 0x7b, 0x41, 0xc9, + 0x65, 0xea, 0x66, 0xbe, 0xde, 0x5f, 0x62, 0x8e, 0xc4, 0xa5, 0x68, 0x70, 0x64, 0x6d, 0xdb, 0x92, + 0xc6, 0x4a, 0xb9, 0x50, 0x8d, 0xd8, 0xb6, 0x49, 0xd3, 0xa7, 0x68, 0x5b, 0x55, 0x86, 0x9a, 0x17, + 0xe3, 0xeb, 0x4a, 0xcb, 0x5f, 0x3e, 0x4b, 0x55, 0xd2, 0x8e, 0x28, 0xf8, 0xaa, 0x32, 0xd4, 0xbc, + 0x58, 0x7b, 0x87, 0xbb, 0xfb, 0xf7, 0x9c, 0xf6, 0xae, 0xeb, 0xb5, 0x64, 0x20, 0xe8, 0xa8, 0x39, + 0xae, 0x77, 0xf7, 0xef, 0x08, 0x7a, 0x66, 0x7b, 0xc7, 0xa5, 0x68, 0x70, 0x24, 0x7f, 0xcf, 0x82, + 0x89, 0x6e, 0xbb, 0xd7, 0x72, 0xbd, 0xf9, 0xe9, 0x3c, 0x3c, 0x84, 0x92, 0x4b, 0xee, 0xe2, 0x06, + 0x27, 0x2d, 0x14, 0xc5, 0x9f, 0xd4, 0x4e, 0x8d, 0xbc, 0xf0, 0x17, 0xfe, 0xa8, 0x32, 0x4f, 0xbd, + 0x86, 0xdf, 0x74, 0xbd, 0xd6, 0xd2, 0xdd, 0xd0, 0xf7, 0x16, 0xd1, 0xb9, 0xa7, 0x74, 0x74, 0x29, + 0xd3, 0xc2, 0xc7, 0x61, 0xca, 0x20, 0x71, 0x9c, 0xa2, 0x37, 0x6d, 0x2a, 0x7a, 0xbf, 0x3e, 0x01, + 0xd3, 0x66, 0x66, 0xcb, 0x13, 0x68, 0x5f, 0xfa, 0xc4, 0x31, 0x36, 0xcc, 0x89, 0x83, 0x1d, 0x31, + 0x8d, 0xdb, 0x23, 0x65, 0xde, 0x5a, 0xcd, 0x4d, 0xe1, 0x8e, 0x8f, 0x98, 0x46, 0x61, 0x88, 0x09, + 0xa6, 0x43, 0x38, 0x94, 0x30, 0xb5, 0x55, 0x28, 0x76, 0xc5, 0xa4, 0xda, 0x9a, 0x50, 0xd5, 0xae, + 0x00, 0xc4, 0x29, 0x18, 0xe5, 0xad, 0xa2, 0xd6, 0x87, 0x8d, 0xd4, 0x90, 0x06, 0x16, 0x79, 0x16, + 0x26, 0x98, 0xea, 0x43, 0x9b, 0x32, 0x4e, 0x5d, 0x9f, 0xe3, 0xaf, 0xf1, 0x52, 0x94, 0x50, 0xf2, + 0x0a, 0xd3, 0x52, 0x63, 0x85, 0x45, 0x86, 0x9f, 0x5f, 0x8c, 0xb5, 0xd4, 0x18, 0x86, 0x09, 0x4c, + 0x26, 0x3a, 0x65, 0xfa, 0x05, 0x5f, 0x1b, 0x0c, 0xd1, 0xb9, 0xd2, 0x81, 0x02, 0xc6, 0xed, 0x4a, + 0x29, 0x7d, 0x84, 0xcf, 0xe9, 0xa2, 0x61, 0x57, 0x4a, 0xc1, 0xb1, 0xaf, 0x06, 0xfb, 0x18, 0x79, + 0x21, 0x3a, 0x25, 0xbc, 0x91, 0x07, 0x5c, 0x65, 0x7e, 0xc5, 0x3c, 0x6b, 0xe5, 0x38, 0x87, 0xc4, + 0xa8, 0x3d, 0xf9, 0x61, 0x6b, 0xb4, 0x63, 0xd1, 0x67, 0x61, 0x26, 0xb9, 0x0b, 0xe5, 0x7e, 0xf3, + 0xf1, 0xd5, 0x71, 0xb8, 0x70, 0xb3, 0xe5, 0x7a, 0xe9, 0x2c, 0x62, 0x59, 0x4f, 0x06, 0x58, 0x43, + 0x3f, 0x19, 0xa0, 0x03, 0xde, 0x64, 0x42, 0xfe, 0xec, 0x80, 0x37, 0xf5, 0x3a, 0x42, 0x12, 0x97, + 0xfc, 0xa1, 0x05, 0x4f, 0x3a, 0x4d, 0x71, 0x2e, 0x70, 0xda, 0xb2, 0xd4, 0xc8, 0x74, 0x2d, 0x67, + 0x74, 0x38, 0xe2, 0x2e, 0xdf, 0xff, 0xf1, 0x8b, 0xd5, 0x23, 0xb8, 0x8a, 0x1e, 0xff, 0x09, 0xf9, + 0x05, 0x4f, 0x1e, 0x85, 0x8a, 0x47, 0x8a, 0x4f, 0xfe, 0x0a, 0xcc, 0x26, 0x3e, 0x58, 0x5a, 0xc2, + 0xcb, 0xe2, 0xc2, 0xa2, 0x9e, 0x04, 0x61, 0x1a, 0x77, 0xe1, 0x16, 0x7c, 0xe8, 0x58, 0x39, 0x87, + 0x1a, 0x6c, 0xdf, 0xb5, 0x60, 0xda, 0x4c, 0xf8, 0x43, 0x5e, 0x80, 0x52, 0xe4, 0xef, 0x52, 0xef, + 0x76, 0xa0, 0xbc, 0x61, 0xf5, 0x40, 0xdf, 0xe4, 0xe5, 0xb8, 0x86, 0x1a, 0x83, 0x61, 0x37, 0xda, + 0x2e, 0xf5, 0xa2, 0xd5, 0xa6, 0xec, 0x66, 0x8d, 0xbd, 0x2c, 0xca, 0x57, 0x50, 0x63, 0x08, 0x07, + 0x36, 0xf6, 0xbb, 0x4e, 0x1b, 0x01, 0x55, 0xbe, 0xf3, 0x86, 0x03, 0x5b, 0x0c, 0xc3, 0x04, 0x26, + 0xb1, 0xb5, 0x89, 0x73, 0x3c, 0xbe, 0xd7, 0x48, 0x99, 0x24, 0x7f, 0xcb, 0x82, 0xb2, 0x30, 0xd1, + 0x23, 0xdd, 0x4e, 0xf9, 0xaf, 0xa6, 0x8c, 0x08, 0xd5, 0x8d, 0xd5, 0x2c, 0xff, 0xd5, 0xa7, 0x61, + 0x7c, 0xd7, 0xf5, 0xd4, 0x97, 0xe8, 0x6d, 0xe9, 0x0d, 0xd7, 0x6b, 0x22, 0x87, 0xe8, 0x8d, 0xab, + 0x30, 0x70, 0xe3, 0x5a, 0x82, 0xb2, 0xf6, 0xea, 0x90, 0xcb, 0xbf, 0xb6, 0xde, 0x6a, 0x2f, 0x10, + 0x8c, 0x71, 0xec, 0x5f, 0xb5, 0x60, 0x86, 0x07, 0x48, 0xc7, 0xe7, 0xe1, 0x97, 0xb5, 0xa3, 0x95, + 0x90, 0xfb, 0xa9, 0xa4, 0xa3, 0xd5, 0x83, 0x83, 0xca, 0x94, 0x08, 0xa9, 0x4e, 0xfa, 0x5d, 0x7d, + 0x5a, 0x1a, 0xd1, 0xb8, 0x3b, 0xd8, 0xd8, 0xd0, 0x36, 0x9e, 0x58, 0x4c, 0x45, 0x04, 0x63, 0x7a, + 0xf6, 0xbb, 0x30, 0x6d, 0x46, 0x3a, 0x91, 0x97, 0x61, 0xaa, 0xeb, 0x7a, 0xad, 0x64, 0x44, 0xac, + 0xbe, 0x68, 0xd8, 0x88, 0x41, 0x68, 0xe2, 0xf1, 0x6a, 0x7e, 0x5c, 0x2d, 0x75, 0x3f, 0xb1, 0xe1, + 0x9b, 0xd5, 0xe2, 0x3f, 0xfc, 0x95, 0x81, 0x8c, 0x88, 0xba, 0xdc, 0x5f, 0x19, 0xc8, 0xe0, 0xf1, + 0xc1, 0xbd, 0x32, 0x90, 0x25, 0xcc, 0xff, 0x5b, 0xaf, 0x0c, 0xfc, 0x34, 0x0c, 0x9b, 0x70, 0x94, + 0xed, 0xf5, 0xf7, 0xcc, 0xac, 0x05, 0xba, 0xc5, 0x65, 0xda, 0x02, 0x09, 0xb5, 0xbf, 0x5d, 0x80, + 0xb9, 0xf4, 0x91, 0x3f, 0x6f, 0x6f, 0x0a, 0xf2, 0x35, 0x0b, 0x66, 0x9c, 0x44, 0x72, 0xb7, 0x9c, + 0x9e, 0x2c, 0x4a, 0xd0, 0x34, 0x92, 0x8b, 0x25, 0xca, 0x31, 0xc5, 0x9b, 0xfc, 0x05, 0x98, 0x8c, + 0xdc, 0x0e, 0xf5, 0x7b, 0xc2, 0x10, 0x58, 0x10, 0x07, 0xf2, 0x4d, 0x51, 0x84, 0x0a, 0xc6, 0x16, + 0x65, 0x97, 0x6b, 0x50, 0x01, 0x95, 0x6e, 0xb7, 0x73, 0xb1, 0xe5, 0x52, 0x94, 0xa3, 0xc6, 0x20, + 0xf7, 0x61, 0x52, 0xf8, 0x5d, 0x28, 0x07, 0x9b, 0xf5, 0x9c, 0x4c, 0x13, 0xc2, 0xb5, 0x23, 0xee, + 0x02, 0xf1, 0x3f, 0x44, 0xc5, 0xce, 0xfe, 0x28, 0x0c, 0x99, 0x81, 0xd5, 0xbe, 0x0a, 0x04, 0xfd, + 0x76, 0x7b, 0xcb, 0x69, 0xec, 0xde, 0x71, 0xbd, 0xa6, 0x7f, 0x8f, 0x2f, 0x45, 0x4b, 0x50, 0x0e, + 0x64, 0x3c, 0x6a, 0x28, 0x47, 0x8d, 0x5e, 0xcb, 0x54, 0xa0, 0x6a, 0x88, 0x31, 0x8e, 0xfd, 0x7b, + 0x63, 0x30, 0x29, 0x83, 0xa7, 0x1f, 0x82, 0xdb, 0xff, 0x6e, 0xe2, 0x3e, 0x78, 0x35, 0x97, 0x98, + 0xef, 0x81, 0x3e, 0xff, 0x61, 0xca, 0xe7, 0xff, 0x8d, 0x7c, 0xd8, 0x1d, 0xed, 0xf0, 0xff, 0x9d, + 0x22, 0xcc, 0xa6, 0x82, 0xd1, 0x53, 0xc9, 0x9a, 0xad, 0x0f, 0x24, 0x59, 0x33, 0x09, 0x13, 0x09, + 0xbb, 0xdf, 0xcc, 0xed, 0xd1, 0x97, 0x3f, 0xcf, 0xdd, 0x3d, 0x6c, 0xee, 0xee, 0x6f, 0x59, 0x70, + 0xc1, 0xe9, 0x7f, 0x35, 0x47, 0xda, 0x0b, 0xdf, 0xcc, 0xfd, 0x39, 0x9e, 0xda, 0x13, 0x52, 0xc8, + 0xac, 0xc7, 0x89, 0x30, 0x4b, 0x14, 0xfb, 0xbf, 0x58, 0xf0, 0xf8, 0xc0, 0x94, 0x0a, 0x3c, 0x23, + 0x57, 0x90, 0x84, 0xca, 0xf5, 0x22, 0xe7, 0xc4, 0x31, 0xfa, 0xee, 0x38, 0x9d, 0x44, 0x29, 0xcd, + 0x9e, 0xbc, 0x04, 0xd3, 0x5c, 0x3f, 0x63, 0x2b, 0x67, 0x44, 0xbb, 0xf2, 0xea, 0x8b, 0x5f, 0x82, + 0xd4, 0x8d, 0x72, 0x4c, 0x60, 0xd9, 0xdf, 0xb2, 0x60, 0x7e, 0x50, 0x7e, 0xa6, 0x13, 0x18, 0x66, + 0xfe, 0x72, 0x2a, 0x6c, 0xa2, 0xd2, 0x17, 0x36, 0x91, 0x32, 0xcd, 0xa8, 0x08, 0x09, 0xc3, 0x2a, + 0x52, 0x38, 0x26, 0x2a, 0xe0, 0xf7, 0x0b, 0x30, 0x27, 0x45, 0x8c, 0x95, 0xe2, 0x57, 0x12, 0xc1, + 0x1e, 0x3f, 0x91, 0x0a, 0xf6, 0xb8, 0x98, 0xc6, 0xff, 0xf3, 0x48, 0x8f, 0x1f, 0xaf, 0x48, 0x8f, + 0x3f, 0x1d, 0x83, 0x4b, 0x99, 0x69, 0x9a, 0xc8, 0x57, 0x33, 0x76, 0x8a, 0x3b, 0x39, 0xe7, 0x83, + 0xd2, 0x41, 0xa1, 0x67, 0x1b, 0x1e, 0xf1, 0xcb, 0x66, 0x58, 0x82, 0x58, 0xfd, 0xb7, 0xcf, 0x20, + 0xb3, 0xd5, 0x90, 0x11, 0x0a, 0xf6, 0x2f, 0x14, 0xe0, 0xb9, 0x93, 0x12, 0xfa, 0x31, 0x8d, 0x60, + 0x0b, 0x13, 0x11, 0x6c, 0x0f, 0x69, 0x27, 0x3f, 0x93, 0x60, 0xb6, 0x7f, 0x30, 0xae, 0xb7, 0x99, + 0xfe, 0xf1, 0x79, 0x22, 0xbf, 0x84, 0x49, 0xa6, 0xe9, 0xa9, 0x0c, 0xd7, 0xf1, 0x52, 0x38, 0x59, + 0x17, 0xc5, 0x0f, 0x0e, 0x2a, 0xe7, 0xe3, 0x64, 0x21, 0xb2, 0x10, 0x55, 0x25, 0xf2, 0x1c, 0x94, + 0x02, 0x01, 0x55, 0x31, 0x3b, 0xd2, 0xb9, 0x43, 0x94, 0xa1, 0x86, 0x92, 0x2f, 0x18, 0xaa, 0xf1, + 0xf8, 0x59, 0xe5, 0xc4, 0x39, 0xca, 0x67, 0xe5, 0x6d, 0x28, 0x85, 0x2a, 0x0d, 0xb3, 0x50, 0x14, + 0x5e, 0x3c, 0x61, 0x28, 0x18, 0x3b, 0xef, 0xaa, 0x9c, 0xcc, 0xe2, 0xfb, 0x74, 0xc6, 0x66, 0x4d, + 0x92, 0xd8, 0xfa, 0xa8, 0x29, 0x6c, 0xea, 0xd0, 0x7f, 0xcc, 0x24, 0x11, 0x4c, 0xca, 0xb7, 0x58, + 0xe5, 0x65, 0xdf, 0x7a, 0x4e, 0x61, 0x1f, 0xd2, 0x29, 0x98, 0x9f, 0xe0, 0x94, 0xc9, 0x43, 0xb1, + 0xb2, 0xbf, 0x6f, 0xc1, 0x94, 0x1c, 0x23, 0x0f, 0x21, 0x26, 0xee, 0x6e, 0x32, 0x26, 0xee, 0x6a, + 0x2e, 0x2b, 0xd6, 0x80, 0x80, 0xb8, 0xbb, 0x30, 0x6d, 0xe6, 0x07, 0x24, 0x9f, 0x32, 0x56, 0x5c, + 0x6b, 0x94, 0x8c, 0x5b, 0x6a, 0x4d, 0x8e, 0x57, 0x63, 0xfb, 0x37, 0xca, 0xba, 0x15, 0xf9, 0x39, + 0xd1, 0x1c, 0xf9, 0xd6, 0x91, 0x23, 0xdf, 0x1c, 0x78, 0x63, 0xf9, 0x0f, 0xbc, 0x37, 0xa1, 0xa4, + 0x96, 0x45, 0xa9, 0x3c, 0x3c, 0x63, 0x7a, 0x09, 0x33, 0x0d, 0x84, 0x11, 0x33, 0xa6, 0x0b, 0x3f, + 0xef, 0xc5, 0x86, 0x58, 0xb5, 0x5c, 0x6b, 0x32, 0xe4, 0x1d, 0x98, 0xba, 0xe7, 0x07, 0xbb, 0x6d, + 0xdf, 0xe1, 0xb9, 0xef, 0x21, 0x8f, 0x8b, 0x69, 0x6d, 0x4c, 0x15, 0xa1, 0x1a, 0x77, 0x62, 0xfa, + 0x68, 0x32, 0x23, 0x55, 0x98, 0xed, 0xb8, 0x1e, 0x52, 0xa7, 0xa9, 0x43, 0xdf, 0xc6, 0x45, 0xde, + 0x69, 0xa5, 0xca, 0xae, 0x27, 0xc1, 0x98, 0xc6, 0xe7, 0x86, 0x96, 0x20, 0x71, 0xb2, 0x97, 0xc9, + 0x65, 0x37, 0x46, 0x1f, 0x8c, 0x49, 0x6b, 0x81, 0x88, 0x55, 0x48, 0x96, 0x63, 0x8a, 0x37, 0xf9, + 0x3c, 0x94, 0x42, 0xf5, 0xca, 0x61, 0x31, 0x47, 0x25, 0x5f, 0xbf, 0x74, 0xa8, 0xbb, 0x52, 0x3f, + 0x75, 0xa8, 0x19, 0x92, 0x35, 0xb8, 0xa8, 0x4c, 0x15, 0x89, 0x07, 0xdb, 0x26, 0xe2, 0x5c, 0x51, + 0x98, 0x01, 0xc7, 0xcc, 0x5a, 0x4c, 0x95, 0xe3, 0x79, 0x37, 0xc5, 0x45, 0xa0, 0x71, 0x77, 0xc6, + 0xe7, 0x5f, 0x13, 0x25, 0xf4, 0xa8, 0xc8, 0xce, 0xd2, 0x08, 0x91, 0x9d, 0x75, 0xb8, 0x94, 0x06, + 0xf1, 0x24, 0x60, 0x3c, 0xef, 0x98, 0xb1, 0x85, 0x6e, 0x64, 0x21, 0x61, 0x76, 0x5d, 0x72, 0x07, + 0xca, 0x01, 0xe5, 0x87, 0x9a, 0xaa, 0xf2, 0xa1, 0x1a, 0xda, 0x5b, 0x14, 0x15, 0x01, 0x8c, 0x69, + 0xb1, 0x7e, 0x77, 0x92, 0x99, 0xa0, 0xdf, 0xcc, 0xf1, 0x19, 0x64, 0xd9, 0xf7, 0x03, 0x92, 0xf3, + 0xd9, 0xff, 0x76, 0x16, 0xce, 0x25, 0xec, 0x2d, 0xe4, 0x19, 0x28, 0xf2, 0xac, 0x68, 0x7c, 0xb5, + 0x2a, 0xc5, 0x2b, 0xaa, 0x68, 0x1c, 0x01, 0x23, 0xbf, 0x68, 0xc1, 0x6c, 0x37, 0x71, 0x7f, 0xa0, + 0x16, 0xf2, 0x11, 0x8d, 0x94, 0xc9, 0x4b, 0x09, 0xe3, 0x0d, 0x85, 0x24, 0x33, 0x4c, 0x73, 0x67, + 0xeb, 0x81, 0x74, 0xb9, 0x6e, 0xd3, 0x80, 0x63, 0x4b, 0x45, 0x4f, 0x93, 0x58, 0x4e, 0x82, 0x31, + 0x8d, 0xcf, 0x7a, 0x98, 0x7f, 0xdd, 0x28, 0x4f, 0x5d, 0x56, 0x15, 0x01, 0x8c, 0x69, 0x91, 0xd7, + 0x60, 0x46, 0x26, 0x00, 0xde, 0xf0, 0x9b, 0xd7, 0x9d, 0x70, 0x47, 0x9e, 0x70, 0xf4, 0x89, 0x6c, + 0x39, 0x01, 0xc5, 0x14, 0x36, 0xff, 0xb6, 0x38, 0xcb, 0x32, 0x27, 0x30, 0x91, 0x7c, 0x62, 0x62, + 0x39, 0x09, 0xc6, 0x34, 0x3e, 0x79, 0xc1, 0xd8, 0x86, 0xc4, 0xe5, 0xbc, 0x5e, 0x0d, 0x32, 0xb6, + 0xa2, 0x2a, 0xcc, 0xf6, 0xf8, 0x81, 0xb0, 0xa9, 0x80, 0x72, 0x3e, 0x6a, 0x86, 0xb7, 0x93, 0x60, + 0x4c, 0xe3, 0x93, 0x57, 0xe1, 0x5c, 0xc0, 0x16, 0x5b, 0x4d, 0x40, 0xdc, 0xd8, 0xeb, 0x0b, 0x59, + 0x34, 0x81, 0x98, 0xc4, 0x25, 0xaf, 0xc3, 0xf9, 0x38, 0x5f, 0xa6, 0x22, 0x20, 0xae, 0xf0, 0x75, + 0xf2, 0xb6, 0x6a, 0x1a, 0x01, 0xfb, 0xeb, 0x90, 0xbf, 0x06, 0x73, 0x46, 0x4b, 0xac, 0x7a, 0x4d, + 0x7a, 0x5f, 0xe6, 0x34, 0xe4, 0x4f, 0x26, 0x2d, 0xa7, 0x60, 0xd8, 0x87, 0x4d, 0x3e, 0x01, 0x33, + 0x0d, 0xbf, 0xdd, 0xe6, 0x6b, 0x9c, 0x78, 0xde, 0x40, 0x24, 0x2f, 0x14, 0x69, 0x1e, 0x13, 0x10, + 0x4c, 0x61, 0x92, 0x1b, 0x40, 0xfc, 0x2d, 0xa6, 0x5e, 0xd1, 0xe6, 0xeb, 0xd4, 0xa3, 0x52, 0xe3, + 0x38, 0x97, 0x0c, 0xf8, 0xb8, 0xd5, 0x87, 0x81, 0x19, 0xb5, 0x78, 0xee, 0x37, 0x23, 0x40, 0x76, + 0x26, 0x8f, 0x77, 0x19, 0xd3, 0xe6, 0x8b, 0x63, 0xa3, 0x63, 0x03, 0x98, 0x10, 0xf1, 0x37, 0xf9, + 0x64, 0x31, 0x34, 0x33, 0x9d, 0xc7, 0x7b, 0x84, 0x28, 0x45, 0xc9, 0x89, 0xfc, 0x1c, 0x94, 0xb7, + 0xd4, 0xb3, 0x17, 0x3c, 0x75, 0xe1, 0xc8, 0xfb, 0x62, 0xea, 0x05, 0x97, 0xf8, 0x78, 0xae, 0x01, + 0x18, 0xb3, 0x24, 0xcf, 0xc2, 0xd4, 0xf5, 0x8d, 0xaa, 0x1e, 0x85, 0xe7, 0x79, 0xef, 0x8f, 0xb3, + 0x2a, 0x68, 0x02, 0xd8, 0x0c, 0xd3, 0xea, 0x1b, 0x49, 0xde, 0x4a, 0x67, 0x68, 0x63, 0x0c, 0x9b, + 0x5f, 0xb3, 0x63, 0x7d, 0xfe, 0x42, 0x0a, 0x5b, 0x96, 0xa3, 0xc6, 0x20, 0x6f, 0xc3, 0x94, 0xdc, + 0x2f, 0xf8, 0xda, 0x74, 0xf1, 0x74, 0xc1, 0xd7, 0x18, 0x93, 0x40, 0x93, 0x1e, 0xbf, 0x1f, 0xe5, + 0xaf, 0x01, 0xd0, 0x6b, 0xbd, 0x76, 0x7b, 0xfe, 0x12, 0x5f, 0x37, 0xe3, 0xfb, 0xd1, 0x18, 0x84, + 0x26, 0x1e, 0x79, 0x51, 0xb9, 0x4b, 0x3d, 0x9a, 0xb8, 0x30, 0xd6, 0xee, 0x52, 0x5a, 0xe9, 0x1e, + 0x10, 0x9f, 0xf1, 0xd8, 0x31, 0x7e, 0x4a, 0x5b, 0xb0, 0xa0, 0x34, 0xbe, 0xfe, 0x49, 0x32, 0x3f, + 0x9f, 0x30, 0x95, 0x2c, 0xdc, 0x19, 0x88, 0x89, 0x47, 0x50, 0x21, 0x5b, 0x50, 0x70, 0xda, 0x5b, + 0xf3, 0x8f, 0xe7, 0xa1, 0xba, 0x56, 0xd7, 0x6a, 0x72, 0x44, 0x71, 0x9f, 0xca, 0xea, 0x5a, 0x0d, + 0x19, 0x71, 0xe2, 0xc2, 0xb8, 0xd3, 0xde, 0x0a, 0xe7, 0x17, 0xf8, 0x9c, 0xcd, 0x8d, 0x49, 0x6c, + 0x3c, 0x58, 0xab, 0x85, 0xc8, 0x59, 0xd8, 0x5f, 0x1c, 0xd3, 0x97, 0x22, 0x3a, 0x91, 0xf4, 0xbb, + 0xe6, 0x04, 0x12, 0xc7, 0x9d, 0x5b, 0xb9, 0x4d, 0x20, 0xa9, 0x5e, 0x9c, 0x1b, 0x38, 0x7d, 0xba, + 0x7a, 0xc9, 0xc8, 0x25, 0x03, 0x55, 0x32, 0x49, 0xb6, 0x38, 0x3d, 0x27, 0x17, 0x0c, 0xfb, 0xdb, + 0xa0, 0x8d, 0x7e, 0x29, 0x57, 0xa3, 0x00, 0x8a, 0x6e, 0x18, 0xb9, 0x7e, 0x8e, 0x31, 0xc9, 0xa9, + 0xec, 0xd2, 0x3c, 0xe4, 0x81, 0x03, 0x50, 0xb0, 0x62, 0x3c, 0xbd, 0x96, 0xeb, 0xdd, 0x97, 0x9f, + 0xff, 0x66, 0xee, 0x3e, 0x44, 0x82, 0x27, 0x07, 0xa0, 0x60, 0x45, 0xee, 0x8a, 0x41, 0x5d, 0xc8, + 0xa3, 0xaf, 0xab, 0x6b, 0xb5, 0x14, 0xbf, 0xe4, 0xe0, 0xbe, 0x0b, 0x85, 0xb0, 0xe3, 0x4a, 0x75, + 0x69, 0x44, 0x5e, 0xf5, 0xf5, 0xd5, 0x2c, 0x5e, 0xf5, 0xf5, 0x55, 0x64, 0x4c, 0xc8, 0x57, 0x2c, + 0x00, 0xa7, 0xb3, 0xe5, 0x84, 0xa1, 0xd3, 0xd4, 0xd6, 0x99, 0x11, 0x5f, 0x8d, 0xa8, 0x6a, 0x7a, + 0x29, 0xd6, 0xdc, 0x6b, 0x36, 0x86, 0xa2, 0xc1, 0x99, 0xbc, 0x03, 0x93, 0x8e, 0x78, 0x96, 0x4f, + 0x3a, 0x80, 0xe7, 0xf3, 0xd6, 0x64, 0x4a, 0x02, 0x6e, 0xa6, 0x91, 0x20, 0x54, 0x0c, 0x19, 0xef, + 0x28, 0x70, 0xe8, 0xb6, 0xbb, 0x2b, 0x8d, 0x43, 0xf5, 0x91, 0x1f, 0x8e, 0x60, 0xc4, 0xb2, 0x78, + 0x4b, 0x10, 0x2a, 0x86, 0xe2, 0x59, 0x7a, 0xc7, 0x73, 0x74, 0x58, 0x5f, 0x3e, 0xc1, 0x9f, 0x66, + 0xa0, 0xa0, 0xf1, 0x2c, 0xbd, 0xc9, 0x08, 0x93, 0x7c, 0xc9, 0x1e, 0x4c, 0x38, 0xfc, 0xc1, 0x50, + 0x79, 0x14, 0xc3, 0x3c, 0x1e, 0x1f, 0x4d, 0xb5, 0x01, 0x5f, 0x5c, 0xe4, 0xb3, 0xa4, 0x92, 0x1b, + 0xf9, 0x35, 0x0b, 0x26, 0x85, 0x6f, 0x32, 0x53, 0x48, 0xd9, 0xb7, 0x7f, 0xf6, 0x0c, 0xb2, 0xd4, + 0x4b, 0xbf, 0x69, 0xe9, 0x6d, 0xf3, 0x61, 0xed, 0x78, 0x29, 0x4a, 0x8f, 0xf4, 0x9c, 0x56, 0xd2, + 0x2d, 0x7c, 0x02, 0xa6, 0x4d, 0x2a, 0x43, 0xf9, 0x4e, 0xff, 0xb0, 0x00, 0xc0, 0x1b, 0x5a, 0x24, + 0xf2, 0xe8, 0xf0, 0x94, 0xba, 0x3b, 0x7e, 0x33, 0xa7, 0xc7, 0x05, 0x8d, 0x7c, 0x1c, 0x20, 0xf3, + 0xe7, 0xee, 0xf8, 0x4d, 0x94, 0x4c, 0x48, 0x0b, 0xc6, 0xbb, 0x4e, 0xb4, 0x93, 0x7f, 0xf2, 0x8f, + 0x92, 0x88, 0x68, 0x8d, 0x76, 0x90, 0x33, 0x20, 0xef, 0x59, 0xb1, 0x1b, 0x4a, 0x21, 0x8f, 0xac, + 0xa0, 0x71, 0x9b, 0x2d, 0x4a, 0xc7, 0x93, 0x54, 0x72, 0xcc, 0xb4, 0x3b, 0xca, 0xc2, 0xfb, 0x16, + 0x4c, 0x9b, 0xa8, 0x19, 0xdd, 0xf4, 0xb3, 0x66, 0x37, 0xe5, 0xd9, 0x1e, 0x66, 0x8f, 0xff, 0x77, + 0x0b, 0x00, 0x7b, 0x5e, 0xbd, 0xd7, 0xe9, 0x30, 0xa5, 0x5b, 0xbb, 0x88, 0x5b, 0x27, 0x76, 0x11, + 0x1f, 0x1b, 0xd2, 0x45, 0xbc, 0x30, 0x94, 0x8b, 0xf8, 0xf8, 0xf0, 0x2e, 0xe2, 0xc5, 0xc1, 0x2e, + 0xe2, 0xf6, 0x37, 0x2c, 0x38, 0xdf, 0xb7, 0xdb, 0x30, 0x3d, 0x38, 0xf0, 0xfd, 0x68, 0x80, 0x7b, + 0x21, 0xc6, 0x20, 0x34, 0xf1, 0xc8, 0x0a, 0xcc, 0xc9, 0x07, 0x24, 0xea, 0xdd, 0xb6, 0x9b, 0x99, + 0x98, 0x65, 0x33, 0x05, 0xc7, 0xbe, 0x1a, 0xf6, 0xb7, 0x2d, 0x98, 0x32, 0xc2, 0xb9, 0xd9, 0x77, + 0x70, 0x1f, 0x53, 0x29, 0x46, 0xfc, 0x76, 0x06, 0xbf, 0xa8, 0x12, 0x30, 0x71, 0x67, 0xda, 0x32, + 0xd2, 0x8b, 0xc7, 0x77, 0xa6, 0xac, 0x14, 0x25, 0x54, 0x24, 0x8e, 0xa6, 0x5d, 0xde, 0xe8, 0x05, + 0x33, 0x71, 0x34, 0xed, 0x22, 0x87, 0x70, 0x76, 0xec, 0x40, 0x20, 0xdd, 0x47, 0x8d, 0xa7, 0x3a, + 0x9c, 0x20, 0x42, 0x01, 0x23, 0x4f, 0x41, 0x81, 0x7a, 0x4d, 0x69, 0xbd, 0xd0, 0x8f, 0x69, 0x5e, + 0xf5, 0x9a, 0xc8, 0xca, 0xed, 0x5b, 0x30, 0x2d, 0x5c, 0x67, 0xdf, 0xa0, 0xfb, 0x27, 0x7e, 0x9d, + 0x93, 0x8d, 0xf6, 0xd4, 0xeb, 0x9c, 0xac, 0x3a, 0x2b, 0xb7, 0xff, 0xb1, 0x05, 0xa9, 0xf7, 0x64, + 0x8c, 0xfb, 0x13, 0x6b, 0xe0, 0xfd, 0x89, 0x69, 0x73, 0x1f, 0x3b, 0xd2, 0xe6, 0x7e, 0x03, 0x48, + 0x87, 0x4d, 0x85, 0xc4, 0xeb, 0x49, 0xd2, 0x70, 0x14, 0x27, 0x8f, 0xe8, 0xc3, 0xc0, 0x8c, 0x5a, + 0xf6, 0x3f, 0x12, 0xc2, 0x9a, 0x2f, 0xcc, 0x1c, 0xdf, 0x00, 0x3d, 0x28, 0x72, 0x52, 0xd2, 0x7a, + 0x36, 0xa2, 0xe5, 0xb9, 0x3f, 0x09, 0x53, 0xdc, 0x91, 0x72, 0xca, 0x73, 0x6e, 0xf6, 0xef, 0x0b, + 0x59, 0x8d, 0x27, 0x68, 0x4e, 0x20, 0x6b, 0x27, 0x29, 0xeb, 0xf5, 0xbc, 0xd6, 0xca, 0x6c, 0x19, + 0xc9, 0x22, 0x40, 0x97, 0x06, 0x0d, 0xea, 0x45, 0x2a, 0xa8, 0xa5, 0x28, 0xc3, 0x2b, 0x75, 0x29, + 0x1a, 0x18, 0xf6, 0xd7, 0xd9, 0x04, 0x8a, 0xdf, 0xad, 0x25, 0xcf, 0xa5, 0xfd, 0x32, 0xd3, 0x93, + 0x43, 0xbb, 0x65, 0x1a, 0xa1, 0x0e, 0x63, 0xc7, 0x84, 0x3a, 0x3c, 0x0f, 0x93, 0x81, 0xdf, 0xa6, + 0xd5, 0xc0, 0x4b, 0x3b, 0x94, 0x20, 0x2b, 0xc6, 0x9b, 0xa8, 0xe0, 0xf6, 0xaf, 0x58, 0x30, 0x97, + 0x8e, 0xc5, 0xca, 0xdd, 0x59, 0xd4, 0x0c, 0x18, 0x2f, 0x0c, 0x1f, 0x30, 0x6e, 0xbf, 0xc7, 0x84, + 0x8c, 0xdc, 0xc6, 0xae, 0xeb, 0x89, 0x18, 0x6b, 0xd6, 0x72, 0xcf, 0xc3, 0x24, 0x95, 0xef, 0x6f, + 0x0a, 0x23, 0xb0, 0x16, 0x52, 0x3d, 0xbb, 0xa9, 0xe0, 0xa4, 0x0a, 0xb3, 0xea, 0xea, 0x4b, 0x59, + 0xee, 0x45, 0x6e, 0x08, 0x6d, 0x29, 0x5c, 0x49, 0x82, 0x31, 0x8d, 0x6f, 0x7f, 0x01, 0xa6, 0x8c, + 0x4d, 0x89, 0xaf, 0xdf, 0xf7, 0x9d, 0x46, 0x94, 0x5e, 0xf7, 0xae, 0xb2, 0x42, 0x14, 0x30, 0x7e, + 0xc1, 0x20, 0x42, 0x45, 0x52, 0xeb, 0x9e, 0x0c, 0x10, 0x91, 0x50, 0x46, 0x2c, 0xa0, 0x2d, 0x7a, + 0x5f, 0x65, 0x7f, 0x57, 0xc4, 0x90, 0x15, 0xa2, 0x80, 0xd9, 0x2f, 0x40, 0x49, 0x65, 0xf0, 0xe1, + 0x69, 0x30, 0x94, 0xf1, 0xdb, 0x4c, 0x83, 0xe1, 0x07, 0x11, 0x72, 0x88, 0xfd, 0x16, 0x94, 0x54, + 0xa2, 0xa1, 0xe3, 0xb1, 0xd9, 0x52, 0x14, 0x7a, 0xee, 0x75, 0x3f, 0x8c, 0x54, 0x76, 0x24, 0x71, + 0x3f, 0x77, 0x73, 0x95, 0x97, 0xa1, 0x86, 0xda, 0x7f, 0x62, 0xc1, 0xd4, 0xe6, 0xe6, 0x9a, 0x3e, + 0xb6, 0x23, 0x3c, 0x1a, 0x8a, 0x16, 0xaa, 0x6e, 0x47, 0xd4, 0x74, 0x04, 0x10, 0x0b, 0xdf, 0xc2, + 0xe1, 0x41, 0xe5, 0xd1, 0x7a, 0x26, 0x06, 0x0e, 0xa8, 0x49, 0x56, 0xe1, 0x82, 0x09, 0x91, 0x51, + 0xeb, 0x72, 0x8d, 0xe4, 0x0f, 0xb6, 0xd6, 0xfb, 0xc1, 0x98, 0x55, 0x27, 0x4d, 0x4a, 0x6e, 0xf7, + 0xe6, 0xdb, 0xaf, 0xf5, 0x7e, 0x30, 0x66, 0xd5, 0xb1, 0x5f, 0x84, 0xd9, 0xd4, 0x0d, 0xf5, 0x09, + 0xb2, 0x85, 0xfc, 0x4e, 0x01, 0xa6, 0xcd, 0x8b, 0xca, 0x13, 0xac, 0x5f, 0x27, 0xdf, 0x16, 0x32, + 0x2e, 0x17, 0x0b, 0x43, 0x5e, 0x2e, 0x9a, 0xb7, 0xb9, 0xe3, 0x67, 0x7b, 0x9b, 0x5b, 0xcc, 0xe7, + 0x36, 0xd7, 0xf0, 0x3a, 0x98, 0x78, 0x78, 0x5e, 0x07, 0xbf, 0x5d, 0x84, 0x99, 0x64, 0xfa, 0xc9, + 0x13, 0xf4, 0xe4, 0x0b, 0x7d, 0x3d, 0x39, 0xe4, 0x6d, 0x46, 0x61, 0xd4, 0xdb, 0x8c, 0xf1, 0x51, + 0x6f, 0x33, 0x8a, 0xa7, 0xb8, 0xcd, 0xe8, 0xbf, 0x8b, 0x98, 0x38, 0xf1, 0x5d, 0xc4, 0x27, 0xb5, + 0x3f, 0xe2, 0x64, 0xc2, 0x81, 0x27, 0xf6, 0x47, 0x24, 0xc9, 0x6e, 0x58, 0xf6, 0x9b, 0x99, 0x7e, + 0x94, 0xa5, 0x63, 0xac, 0xb6, 0x41, 0xa6, 0xfb, 0xe0, 0xf0, 0x17, 0xa6, 0x8f, 0x0e, 0xe1, 0x3a, + 0xf8, 0x32, 0x4c, 0xc9, 0xf1, 0xc4, 0x95, 0x6f, 0x48, 0x2a, 0xee, 0xf5, 0x18, 0x84, 0x26, 0x1e, + 0x7f, 0xba, 0x3d, 0xf9, 0xa0, 0x3f, 0xbf, 0x1c, 0x32, 0x9f, 0x6e, 0x4f, 0x82, 0x31, 0x8d, 0x6f, + 0x7f, 0x1e, 0x2e, 0x65, 0x1a, 0x50, 0xb8, 0xf1, 0x9a, 0xeb, 0x85, 0xb4, 0x29, 0x11, 0x0c, 0x31, + 0x52, 0x4f, 0x3e, 0x2c, 0xdc, 0x19, 0x88, 0x89, 0x47, 0x50, 0xb1, 0x7f, 0xb3, 0x00, 0x33, 0xc9, + 0x77, 0x3f, 0xc9, 0x3d, 0x6d, 0x6e, 0xcd, 0xc5, 0xd2, 0x2b, 0xc8, 0x1a, 0x29, 0x0d, 0x07, 0x5e, + 0xd3, 0xdc, 0xe3, 0xe3, 0x6b, 0x4b, 0xe7, 0x57, 0x3c, 0x3b, 0xc6, 0xf2, 0x7e, 0x44, 0xb2, 0xe3, + 0x4f, 0x7b, 0xc6, 0xd1, 0x8f, 0xf2, 0x1c, 0x9f, 0x3b, 0xf7, 0x38, 0x8a, 0x4f, 0xb3, 0x42, 0x83, + 0x2d, 0xdb, 0x5b, 0xf6, 0x68, 0xe0, 0x6e, 0xbb, 0xfa, 0xcd, 0x72, 0xbe, 0x72, 0xbf, 0x25, 0xcb, + 0x50, 0x43, 0xed, 0xf7, 0xc6, 0xa0, 0xcc, 0x93, 0x35, 0x5d, 0x0b, 0xfc, 0x0e, 0x7f, 0x1c, 0x2f, + 0x34, 0xce, 0x4c, 0xb2, 0xdb, 0x6e, 0x8c, 0xfa, 0x02, 0x65, 0x4c, 0x51, 0xfa, 0x66, 0x1b, 0x25, + 0x98, 0xe0, 0x48, 0xba, 0x50, 0xda, 0x96, 0xc9, 0x65, 0x65, 0xdf, 0x8d, 0x98, 0x20, 0x51, 0xa5, + 0xaa, 0x15, 0x4d, 0xa0, 0xfe, 0xa1, 0xe6, 0x62, 0x3b, 0x30, 0x9b, 0xca, 0xb6, 0x91, 0x7b, 0x4a, + 0xda, 0xff, 0x35, 0x0e, 0x65, 0x1d, 0x14, 0x44, 0x3e, 0x9e, 0x30, 0x60, 0x95, 0x6b, 0x1f, 0x32, + 0x5e, 0x6e, 0xda, 0xf1, 0x9b, 0x0f, 0x0e, 0x2a, 0xb3, 0x1a, 0x39, 0x65, 0x8c, 0x7a, 0x0a, 0x0a, + 0xbd, 0xa0, 0x9d, 0x3e, 0xa1, 0xde, 0xc6, 0x35, 0x64, 0xe5, 0x66, 0x20, 0x53, 0xe1, 0xa1, 0x06, + 0x32, 0xb1, 0x5d, 0x72, 0xcb, 0x6f, 0xee, 0xa7, 0x5f, 0x7a, 0xaa, 0xf9, 0xcd, 0x7d, 0xe4, 0x10, + 0xf2, 0x1a, 0xcc, 0xc8, 0xe8, 0x2c, 0xf3, 0xfd, 0xfb, 0x42, 0xec, 0x76, 0xb0, 0x99, 0x80, 0x62, + 0x0a, 0x9b, 0xed, 0xb2, 0x77, 0x43, 0xdf, 0xe3, 0x89, 0x86, 0x27, 0x92, 0x77, 0x94, 0x37, 0xea, + 0xb7, 0x6e, 0x72, 0x43, 0x9a, 0xc6, 0x48, 0x04, 0x80, 0x4d, 0x1e, 0x1b, 0x00, 0xb6, 0x22, 0x68, + 0x33, 0x69, 0xf9, 0x8e, 0x32, 0x5d, 0x7b, 0x4e, 0xd1, 0x65, 0x65, 0x0f, 0x0e, 0x8e, 0x30, 0x71, + 0xea, 0x9a, 0x59, 0xa1, 0x72, 0xe5, 0x0f, 0x2e, 0x54, 0xce, 0xbe, 0x0d, 0xb3, 0xa9, 0xfe, 0x53, + 0x06, 0x0e, 0x2b, 0xdb, 0xc0, 0x71, 0xb2, 0xb7, 0xa2, 0xfe, 0xa9, 0x05, 0xe7, 0xfb, 0x56, 0xa4, + 0x93, 0xc6, 0x2c, 0xa6, 0xf7, 0xc6, 0xb1, 0xd3, 0xef, 0x8d, 0x85, 0xe1, 0xf6, 0xc6, 0xda, 0xd6, + 0x77, 0x7f, 0x70, 0xf9, 0x91, 0xef, 0xfd, 0xe0, 0xf2, 0x23, 0x7f, 0xf0, 0x83, 0xcb, 0x8f, 0xbc, + 0x77, 0x78, 0xd9, 0xfa, 0xee, 0xe1, 0x65, 0xeb, 0x7b, 0x87, 0x97, 0xad, 0x3f, 0x38, 0xbc, 0x6c, + 0xfd, 0xe7, 0xc3, 0xcb, 0xd6, 0x37, 0xfe, 0xf8, 0xf2, 0x23, 0x9f, 0xfa, 0x64, 0xdc, 0x53, 0x4b, + 0xaa, 0xa7, 0xf8, 0x8f, 0x8f, 0xa8, 0x7e, 0x59, 0xea, 0xee, 0xb6, 0x96, 0x58, 0x4f, 0x2d, 0xe9, + 0x12, 0xd5, 0x53, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x94, 0x2c, 0x41, 0xea, 0xa4, 0x00, + 0x00, } func (m *ALBStatus) Marshal() (dAtA []byte, err error) { @@ -4569,6 +4570,42 @@ func (m *AnalysisTemplateList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AnalysisTemplateRef) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AnalysisTemplateRef) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AnalysisTemplateRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i-- + if m.ClusterScope { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + i -= len(m.TemplateName) + copy(dAtA[i:], m.TemplateName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TemplateName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *AnalysisTemplateSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4589,6 +4626,20 @@ func (m *AnalysisTemplateSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Templates) > 0 { + for iNdEx := len(m.Templates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Templates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if len(m.MeasurementRetention) > 0 { for iNdEx := len(m.MeasurementRetention) - 1; iNdEx >= 0; iNdEx-- { { @@ -8277,42 +8328,6 @@ func (m *RolloutAnalysisRunStatus) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } -func (m *RolloutAnalysisTemplate) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RolloutAnalysisTemplate) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RolloutAnalysisTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i-- - if m.ClusterScope { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - i -= len(m.TemplateName) - copy(dAtA[i:], m.TemplateName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.TemplateName))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *RolloutCondition) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -10595,6 +10610,18 @@ func (m *AnalysisTemplateList) Size() (n int) { return n } +func (m *AnalysisTemplateRef) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TemplateName) + n += 1 + l + sovGenerated(uint64(l)) + n += 2 + return n +} + func (m *AnalysisTemplateSpec) Size() (n int) { if m == nil { return 0 @@ -10625,6 +10652,12 @@ func (m *AnalysisTemplateSpec) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if len(m.Templates) > 0 { + for _, e := range m.Templates { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -11975,20 +12008,8 @@ func (m *RolloutAnalysisRunStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Status) n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *RolloutAnalysisTemplate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.TemplateName) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 + l = len(m.Message) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -12943,6 +12964,17 @@ func (this *AnalysisTemplateList) String() string { }, "") return s } +func (this *AnalysisTemplateRef) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AnalysisTemplateRef{`, + `TemplateName:` + fmt.Sprintf("%v", this.TemplateName) + `,`, + `ClusterScope:` + fmt.Sprintf("%v", this.ClusterScope) + `,`, + `}`, + }, "") + return s +} func (this *AnalysisTemplateSpec) String() string { if this == nil { return "nil" @@ -12967,11 +12999,17 @@ func (this *AnalysisTemplateSpec) String() string { repeatedStringForMeasurementRetention += strings.Replace(strings.Replace(f.String(), "MeasurementRetention", "MeasurementRetention", 1), `&`, ``, 1) + "," } repeatedStringForMeasurementRetention += "}" + repeatedStringForTemplates := "[]AnalysisTemplateRef{" + for _, f := range this.Templates { + repeatedStringForTemplates += strings.Replace(strings.Replace(f.String(), "AnalysisTemplateRef", "AnalysisTemplateRef", 1), `&`, ``, 1) + "," + } + repeatedStringForTemplates += "}" s := strings.Join([]string{`&AnalysisTemplateSpec{`, `Metrics:` + repeatedStringForMetrics + `,`, `Args:` + repeatedStringForArgs + `,`, `DryRun:` + repeatedStringForDryRun + `,`, `MeasurementRetention:` + repeatedStringForMeasurementRetention + `,`, + `Templates:` + repeatedStringForTemplates + `,`, `}`, }, "") return s @@ -13932,9 +13970,9 @@ func (this *RolloutAnalysis) String() string { if this == nil { return "nil" } - repeatedStringForTemplates := "[]RolloutAnalysisTemplate{" + repeatedStringForTemplates := "[]AnalysisTemplateRef{" for _, f := range this.Templates { - repeatedStringForTemplates += strings.Replace(strings.Replace(f.String(), "RolloutAnalysisTemplate", "RolloutAnalysisTemplate", 1), `&`, ``, 1) + "," + repeatedStringForTemplates += strings.Replace(strings.Replace(f.String(), "AnalysisTemplateRef", "AnalysisTemplateRef", 1), `&`, ``, 1) + "," } repeatedStringForTemplates += "}" repeatedStringForArgs := "[]AnalysisRunArgument{" @@ -13985,17 +14023,6 @@ func (this *RolloutAnalysisRunStatus) String() string { }, "") return s } -func (this *RolloutAnalysisTemplate) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RolloutAnalysisTemplate{`, - `TemplateName:` + fmt.Sprintf("%v", this.TemplateName) + `,`, - `ClusterScope:` + fmt.Sprintf("%v", this.ClusterScope) + `,`, - `}`, - }, "") - return s -} func (this *RolloutCondition) String() string { if this == nil { return "nil" @@ -16627,6 +16654,108 @@ func (m *AnalysisTemplateList) Unmarshal(dAtA []byte) error { } return nil } +func (m *AnalysisTemplateRef) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AnalysisTemplateRef: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AnalysisTemplateRef: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TemplateName", 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 + } + m.TemplateName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusterScope", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ClusterScope = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *AnalysisTemplateSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -16792,6 +16921,40 @@ func (m *AnalysisTemplateSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Templates = append(m.Templates, AnalysisTemplateRef{}) + if err := m.Templates[len(m.Templates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -28096,7 +28259,7 @@ func (m *RolloutAnalysis) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Templates = append(m.Templates, RolloutAnalysisTemplate{}) + m.Templates = append(m.Templates, AnalysisTemplateRef{}) if err := m.Templates[len(m.Templates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -28506,108 +28669,6 @@ func (m *RolloutAnalysisRunStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *RolloutAnalysisTemplate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RolloutAnalysisTemplate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RolloutAnalysisTemplate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TemplateName", 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 - } - m.TemplateName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterScope", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ClusterScope = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *RolloutCondition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/rollouts/v1alpha1/generated.proto b/pkg/apis/rollouts/v1alpha1/generated.proto index 8a9f2997f5..7bae04064c 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.proto +++ b/pkg/apis/rollouts/v1alpha1/generated.proto @@ -202,6 +202,16 @@ message AnalysisTemplateList { repeated AnalysisTemplate items = 2; } +message AnalysisTemplateRef { + // TemplateName name of template to use in AnalysisRun + // +optional + optional string templateName = 1; + + // Whether to look for the templateName at cluster scope or namespace scope + // +optional + optional bool clusterScope = 2; +} + // AnalysisTemplateSpec is the specification for a AnalysisTemplate resource message AnalysisTemplateSpec { // Metrics contains the list of metrics to query as part of an analysis run @@ -226,6 +236,11 @@ message AnalysisTemplateSpec { // +patchStrategy=merge // +optional repeated MeasurementRetention measurementRetention = 4; + + // Templates reference to a list of analysis templates to combine with the rest of the metrics for an AnalysisRun + // +patchMergeKey=templateName + // +patchStrategy=merge + repeated AnalysisTemplateRef templates = 5; } // AntiAffinity defines which inter-pod scheduling rule to use for anti-affinity injection @@ -1224,7 +1239,7 @@ message RolloutAnalysis { // Templates reference to a list of analysis templates to combine for an AnalysisRun // +patchMergeKey=templateName // +patchStrategy=merge - repeated RolloutAnalysisTemplate templates = 1; + repeated AnalysisTemplateRef templates = 1; // Args the arguments that will be added to the AnalysisRuns // +patchMergeKey=name @@ -1265,16 +1280,6 @@ message RolloutAnalysisRunStatus { optional string message = 3; } -message RolloutAnalysisTemplate { - // TemplateName name of template to use in AnalysisRun - // +optional - optional string templateName = 1; - - // Whether to look for the templateName at cluster scope or namespace scope - // +optional - optional bool clusterScope = 2; -} - // RolloutCondition describes the state of a rollout at a certain point. message RolloutCondition { // Type of deployment condition. diff --git a/pkg/apis/rollouts/v1alpha1/openapi_generated.go b/pkg/apis/rollouts/v1alpha1/openapi_generated.go index 49dc9c1f60..bb4f7463f8 100644 --- a/pkg/apis/rollouts/v1alpha1/openapi_generated.go +++ b/pkg/apis/rollouts/v1alpha1/openapi_generated.go @@ -40,6 +40,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunStrategy": schema_pkg_apis_rollouts_v1alpha1_AnalysisRunStrategy(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplate": schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplate(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateList": schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateList(ref), + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef": schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateRef(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateSpec": schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateSpec(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AntiAffinity": schema_pkg_apis_rollouts_v1alpha1_AntiAffinity(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.ApisixRoute": schema_pkg_apis_rollouts_v1alpha1_ApisixRoute(ref), @@ -105,7 +106,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysis": schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysis(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisBackground": schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisBackground(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisRunStatus": schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisRunStatus(ref), - "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisTemplate": schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisTemplate(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutCondition": schema_pkg_apis_rollouts_v1alpha1_RolloutCondition(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutExperimentStep": schema_pkg_apis_rollouts_v1alpha1_RolloutExperimentStep(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutExperimentStepAnalysisTemplateRef": schema_pkg_apis_rollouts_v1alpha1_RolloutExperimentStepAnalysisTemplateRef(ref), @@ -753,6 +753,33 @@ func schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateList(ref common.Reference } } +func schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "templateName": { + SchemaProps: spec.SchemaProps{ + Description: "TemplateName name of template to use in AnalysisRun", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "clusterScope": { + SchemaProps: spec.SchemaProps{ + Description: "Whether to look for the templateName at cluster scope or namespace scope", + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -840,12 +867,31 @@ func schema_pkg_apis_rollouts_v1alpha1_AnalysisTemplateSpec(ref common.Reference }, }, }, + "templates": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "templateName", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Templates reference to a list of analysis templates to combine with the rest of the metrics for an AnalysisRun", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef"), + }, + }, + }, + }, + }, }, - Required: []string{"metrics"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.Argument", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.DryRun", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MeasurementRetention", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.Metric"}, + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.Argument", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.DryRun", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MeasurementRetention", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.Metric"}, } } @@ -3695,7 +3741,7 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysis(ref common.ReferenceCallb Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisTemplate"), + Ref: ref("github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef"), }, }, }, @@ -3772,7 +3818,7 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysis(ref common.ReferenceCallb }, }, Dependencies: []string{ - "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunArgument", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunMetadata", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.DryRun", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MeasurementRetention", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisTemplate"}, + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunArgument", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunMetadata", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.DryRun", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MeasurementRetention"}, } } @@ -3797,7 +3843,7 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisBackground(ref common.Refe Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisTemplate"), + Ref: ref("github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef"), }, }, }, @@ -3881,7 +3927,7 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisBackground(ref common.Refe }, }, Dependencies: []string{ - "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunArgument", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunMetadata", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.DryRun", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MeasurementRetention", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutAnalysisTemplate"}, + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunArgument", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisRunMetadata", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.AnalysisTemplateRef", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.DryRun", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MeasurementRetention"}, } } @@ -3918,33 +3964,6 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisRunStatus(ref common.Refer } } -func schema_pkg_apis_rollouts_v1alpha1_RolloutAnalysisTemplate(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "templateName": { - SchemaProps: spec.SchemaProps{ - Description: "TemplateName name of template to use in AnalysisRun", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "clusterScope": { - SchemaProps: spec.SchemaProps{ - Description: "Whether to look for the templateName at cluster scope or namespace scope", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_rollouts_v1alpha1_RolloutCondition(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apis/rollouts/v1alpha1/types.go b/pkg/apis/rollouts/v1alpha1/types.go index e3c425cb0b..75be0b012a 100755 --- a/pkg/apis/rollouts/v1alpha1/types.go +++ b/pkg/apis/rollouts/v1alpha1/types.go @@ -703,7 +703,7 @@ type RolloutAnalysis struct { // Templates reference to a list of analysis templates to combine for an AnalysisRun // +patchMergeKey=templateName // +patchStrategy=merge - Templates []RolloutAnalysisTemplate `json:"templates,omitempty" patchStrategy:"merge" patchMergeKey:"templateName" protobuf:"bytes,1,rep,name=templates"` + Templates []AnalysisTemplateRef `json:"templates,omitempty" patchStrategy:"merge" patchMergeKey:"templateName" protobuf:"bytes,1,rep,name=templates"` // Args the arguments that will be added to the AnalysisRuns // +patchMergeKey=name // +patchStrategy=merge @@ -723,7 +723,7 @@ type RolloutAnalysis struct { AnalysisRunMetadata AnalysisRunMetadata `json:"analysisRunMetadata,omitempty" protobuf:"bytes,5,opt,name=analysisRunMetadata"` } -type RolloutAnalysisTemplate struct { +type AnalysisTemplateRef struct { //TemplateName name of template to use in AnalysisRun // +optional TemplateName string `json:"templateName" protobuf:"bytes,1,opt,name=templateName"` diff --git a/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go index 0b962704f3..653805d132 100644 --- a/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go @@ -375,6 +375,22 @@ func (in *AnalysisTemplateList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalysisTemplateRef) DeepCopyInto(out *AnalysisTemplateRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisTemplateRef. +func (in *AnalysisTemplateRef) DeepCopy() *AnalysisTemplateRef { + if in == nil { + return nil + } + out := new(AnalysisTemplateRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AnalysisTemplateSpec) DeepCopyInto(out *AnalysisTemplateSpec) { *out = *in @@ -402,6 +418,11 @@ func (in *AnalysisTemplateSpec) DeepCopyInto(out *AnalysisTemplateSpec) { *out = make([]MeasurementRetention, len(*in)) copy(*out, *in) } + if in.Templates != nil { + in, out := &in.Templates, &out.Templates + *out = make([]AnalysisTemplateRef, len(*in)) + copy(*out, *in) + } return } @@ -2047,7 +2068,7 @@ func (in *RolloutAnalysis) DeepCopyInto(out *RolloutAnalysis) { *out = *in if in.Templates != nil { in, out := &in.Templates, &out.Templates - *out = make([]RolloutAnalysisTemplate, len(*in)) + *out = make([]AnalysisTemplateRef, len(*in)) copy(*out, *in) } if in.Args != nil { @@ -2119,22 +2140,6 @@ func (in *RolloutAnalysisRunStatus) DeepCopy() *RolloutAnalysisRunStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RolloutAnalysisTemplate) DeepCopyInto(out *RolloutAnalysisTemplate) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutAnalysisTemplate. -func (in *RolloutAnalysisTemplate) DeepCopy() *RolloutAnalysisTemplate { - if in == nil { - return nil - } - out := new(RolloutAnalysisTemplate) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RolloutCondition) DeepCopyInto(out *RolloutCondition) { *out = *in diff --git a/pkg/apis/rollouts/validation/validation_references_test.go b/pkg/apis/rollouts/validation/validation_references_test.go index 4fc8349fdf..a8e12f0055 100644 --- a/pkg/apis/rollouts/validation/validation_references_test.go +++ b/pkg/apis/rollouts/validation/validation_references_test.go @@ -684,7 +684,7 @@ func TestValidateAnalysisTemplatesWithType(t *testing.T) { rollout := getAlbRollout("alb-ingress") rollout.Spec.Strategy.Canary.Steps = append(rollout.Spec.Strategy.Canary.Steps, v1alpha1.CanaryStep{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: "analysis-template-name", }, diff --git a/rollout/analysis.go b/rollout/analysis.go index 49583287f6..b0307b8d6e 100644 --- a/rollout/analysis.go +++ b/rollout/analysis.go @@ -431,30 +431,11 @@ func (c *rolloutContext) newAnalysisRunFromRollout(rolloutAnalysis *v1alpha1.Rol name := strings.Join(nameParts, "-") var run *v1alpha1.AnalysisRun var err error - templates := make([]*v1alpha1.AnalysisTemplate, 0) - clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) - for _, templateRef := range rolloutAnalysis.Templates { - if templateRef.ClusterScope { - template, err := c.clusterAnalysisTemplateLister.Get(templateRef.TemplateName) - if err != nil { - if k8serrors.IsNotFound(err) { - c.log.Warnf("ClusterAnalysisTemplate '%s' not found", templateRef.TemplateName) - } - return nil, err - } - clusterTemplates = append(clusterTemplates, template) - } else { - template, err := c.analysisTemplateLister.AnalysisTemplates(c.rollout.Namespace).Get(templateRef.TemplateName) - if err != nil { - if k8serrors.IsNotFound(err) { - c.log.Warnf("AnalysisTemplate '%s' not found", templateRef.TemplateName) - } - return nil, err - } - templates = append(templates, template) - } - + templates, clusterTemplates, err := c.getAnalysisTemplatesFromRefs(&rolloutAnalysis.Templates) + if err != nil { + return nil, err } + run, err = analysisutil.NewAnalysisRunFromTemplates(templates, clusterTemplates, args, rolloutAnalysis.DryRun, rolloutAnalysis.MeasurementRetention, name, "", c.rollout.Namespace) if err != nil { return nil, err @@ -478,6 +459,53 @@ func (c *rolloutContext) newAnalysisRunFromRollout(rolloutAnalysis *v1alpha1.Rol return run, nil } +func (c *rolloutContext) getAnalysisTemplatesFromRefs(templateRefs *[]v1alpha1.AnalysisTemplateRef) ([]*v1alpha1.AnalysisTemplate, []*v1alpha1.ClusterAnalysisTemplate, error) { + templates := make([]*v1alpha1.AnalysisTemplate, 0) + clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) + for _, templateRef := range *templateRefs { + if templateRef.ClusterScope { + template, err := c.clusterAnalysisTemplateLister.Get(templateRef.TemplateName) + if err != nil { + if k8serrors.IsNotFound(err) { + c.log.Warnf("ClusterAnalysisTemplate '%s' not found", templateRef.TemplateName) + } + return nil, nil, err + } + clusterTemplates = append(clusterTemplates, template) + // Look for nested templates + if template.Spec.Templates != nil { + innerTemplates, innerClusterTemplates, innerErr := c.getAnalysisTemplatesFromRefs(&template.Spec.Templates) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } + } else { + template, err := c.analysisTemplateLister.AnalysisTemplates(c.rollout.Namespace).Get(templateRef.TemplateName) + if err != nil { + if k8serrors.IsNotFound(err) { + c.log.Warnf("AnalysisTemplate '%s' not found", templateRef.TemplateName) + } + return nil, nil, err + } + templates = append(templates, template) + // Look for nested templates + if template.Spec.Templates != nil { + innerTemplates, innerClusterTemplates, innerErr := c.getAnalysisTemplatesFromRefs(&template.Spec.Templates) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } + } + + } + uniqueTemplates, uniqueClusterTemplates := analysisutil.FilterUniqueTemplates(templates, clusterTemplates) + return uniqueTemplates, uniqueClusterTemplates, nil +} + func (c *rolloutContext) deleteAnalysisRuns(ars []*v1alpha1.AnalysisRun) error { ctx := context.TODO() for i := range ars { diff --git a/rollout/analysis_test.go b/rollout/analysis_test.go index 624134fbb6..c56009cefc 100644 --- a/rollout/analysis_test.go +++ b/rollout/analysis_test.go @@ -43,6 +43,68 @@ func analysisTemplate(name string) *v1alpha1.AnalysisTemplate { } } +func analysisTemplateWithNamespacedAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + return analysisTemplateWithAnalysisRefs(name, false, innerRefsName...) +} + +func analysisTemplateWithClusterAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + return analysisTemplateWithAnalysisRefs(name, true, innerRefsName...) +} + +func analysisTemplateWithAnalysisRefs(name string, clusterScope bool, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + templatesRefs := []v1alpha1.AnalysisTemplateRef{} + for _, innerTplName := range innerRefsName { + templatesRefs = append(templatesRefs, v1alpha1.AnalysisTemplateRef{ + TemplateName: innerTplName, + ClusterScope: clusterScope, + }) + } + return &v1alpha1.AnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{{ + Name: "example-" + name, + }}, + DryRun: []v1alpha1.DryRun{{ + MetricName: "example-" + name, + }}, + MeasurementRetention: []v1alpha1.MeasurementRetention{{ + MetricName: "example-" + name, + }}, + Templates: templatesRefs, + }, + } +} + +func analysisTemplateWithOnlyNamespacedAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + return analysisTemplateWithOnlyRefs(name, false, innerRefsName...) +} + +func analysisTemplateWithOnlyRefs(name string, clusterScope bool, innerRefsName ...string) *v1alpha1.AnalysisTemplate { + templatesRefs := []v1alpha1.AnalysisTemplateRef{} + for _, innerTplName := range innerRefsName { + templatesRefs = append(templatesRefs, v1alpha1.AnalysisTemplateRef{ + TemplateName: innerTplName, + ClusterScope: clusterScope, + }) + } + return &v1alpha1.AnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{}, + DryRun: []v1alpha1.DryRun{}, + MeasurementRetention: []v1alpha1.MeasurementRetention{}, + Templates: templatesRefs, + }, + } +} + func clusterAnalysisTemplate(name string) *v1alpha1.ClusterAnalysisTemplate { return &v1alpha1.ClusterAnalysisTemplate{ ObjectMeta: metav1.ObjectMeta{ @@ -56,6 +118,40 @@ func clusterAnalysisTemplate(name string) *v1alpha1.ClusterAnalysisTemplate { } } +func clusterAnalysisTemplateWithUniqueMetric(name string) *v1alpha1.ClusterAnalysisTemplate { + return &v1alpha1.ClusterAnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{{ + Name: "clusterexample-" + name, + }}, + }, + } +} + +func clusterAnalysisTemplateWithAnalysisRefs(name string, innerRefsName ...string) *v1alpha1.ClusterAnalysisTemplate { + templatesRefs := []v1alpha1.AnalysisTemplateRef{} + for _, innerTplName := range innerRefsName { + templatesRefs = append(templatesRefs, v1alpha1.AnalysisTemplateRef{ + TemplateName: innerTplName, + ClusterScope: true, + }) + } + return &v1alpha1.ClusterAnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1alpha1.AnalysisTemplateSpec{ + Metrics: []v1alpha1.Metric{{ + Name: "clusterexample-" + name, + }}, + Templates: templatesRefs, + }, + } +} + func clusterAnalysisRun(cat *v1alpha1.ClusterAnalysisTemplate, analysisRunType string, r *v1alpha1.Rollout) *v1alpha1.AnalysisRun { labels := map[string]string{} podHash := hash.ComputePodTemplateHash(&r.Spec.Template, r.Status.CollisionCount) @@ -133,7 +229,7 @@ func TestCreateBackgroundAnalysisRun(t *testing.T) { ar := analysisRun(at, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -196,7 +292,7 @@ func TestCreateBackgroundAnalysisRunWithTemplates(t *testing.T) { ar := analysisRun(at, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, }, @@ -257,7 +353,7 @@ func TestCreateBackgroundAnalysisRunWithClusterTemplates(t *testing.T) { ar := clusterAnalysisRun(cat, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: cat.Name, ClusterScope: true, }}, @@ -313,7 +409,7 @@ func TestInvalidSpecMissingClusterTemplatesBackgroundAnalysis(t *testing.T) { r := newCanaryRollout("foo", 10, nil, nil, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) r.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "missing", ClusterScope: true, }}, @@ -367,7 +463,7 @@ func TestCreateBackgroundAnalysisRunWithClusterTemplatesAndTemplate(t *testing.T } r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: cat.Name, ClusterScope: true, }, { @@ -419,6 +515,169 @@ func TestCreateBackgroundAnalysisRunWithClusterTemplatesAndTemplate(t *testing.T assert.JSONEq(t, calculatePatch(r2, fmt.Sprintf(expectedPatch, expectedArName)), patch) } +func TestCreateBackgroundAnalysisRunWithClusterTemplatesAndTemplateAndInnerTemplates(t *testing.T) { + f := newFixture(t) + defer f.Close() + + steps := []v1alpha1.CanaryStep{{ + SetWeight: int32Ptr(10), + }} + at := analysisTemplateWithNamespacedAnalysisRefs("bar", "bar2") + at2 := analysisTemplateWithClusterAnalysisRefs("bar2", "clusterbar2", "clusterbar4") + cat := clusterAnalysisTemplateWithAnalysisRefs("clusterbar", "clusterbar2", "clusterbar3") + cat2 := clusterAnalysisTemplateWithUniqueMetric("clusterbar2") + cat3 := clusterAnalysisTemplateWithUniqueMetric("clusterbar3") + cat4 := clusterAnalysisTemplateWithUniqueMetric("clusterbar4") + r1 := newCanaryRollout("foo", 10, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) + r2 := bumpVersion(r1) + + ar := &v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "run1", + Namespace: metav1.NamespaceDefault, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(r1, controllerKind)}, + }, + Spec: v1alpha1.AnalysisRunSpec{ + Metrics: concatMultipleSlices([][]v1alpha1.Metric{at.Spec.Metrics, at2.Spec.Metrics, cat.Spec.Metrics, cat2.Spec.Metrics, cat3.Spec.Metrics, cat4.Spec.Metrics}), + Args: at.Spec.Args, + }, + } + r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ + RolloutAnalysis: v1alpha1.RolloutAnalysis{ + Templates: []v1alpha1.AnalysisTemplateRef{{ + TemplateName: cat.Name, + ClusterScope: true, + }, { + TemplateName: at.Name, + }}, + }, + } + rs1 := newReplicaSetWithStatus(r1, 10, 10) + rs2 := newReplicaSetWithStatus(r2, 0, 0) + f.kubeobjects = append(f.kubeobjects, rs1, rs2) + f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) + rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + + r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 10, 0, 10, false) + progressingCondition, _ := newProgressingCondition(conditions.ReplicaSetUpdatedReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + availableCondition, _ := newAvailableCondition(true) + conditions.SetRolloutCondition(&r2.Status, availableCondition) + completedCondition, _ := newCompletedCondition(false) + conditions.SetRolloutCondition(&r2.Status, completedCondition) + + f.rolloutLister = append(f.rolloutLister, r2) + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, cat, cat2, cat3, cat4) + f.analysisTemplateLister = append(f.analysisTemplateLister, at, at2) + f.objects = append(f.objects, r2, cat, at, at2, cat2, cat3, cat4) + + createdIndex := f.expectCreateAnalysisRunAction(ar) + f.expectUpdateReplicaSetAction(rs2) + index := f.expectPatchRolloutAction(r1) + + f.run(getKey(r2, t)) + createdAr := f.getCreatedAnalysisRun(createdIndex) + expectedArName := fmt.Sprintf("%s-%s-%s", r2.Name, rs2PodHash, "2") + assert.Equal(t, expectedArName, createdAr.Name) + assert.Len(t, createdAr.Spec.Metrics, 6) + + patch := f.getPatchedRollout(index) + expectedPatch := `{ + "status": { + "canary": { + "currentBackgroundAnalysisRunStatus": { + "name": "%s", + "status": "" + } + } + } + }` + assert.JSONEq(t, calculatePatch(r2, fmt.Sprintf(expectedPatch, expectedArName)), patch) +} + +// Test the case where the analysis template does't have metrics, but refences other templates +func TestCreateBackgroundAnalysisRunWithTemplatesAndNoMetrics(t *testing.T) { + f := newFixture(t) + defer f.Close() + + steps := []v1alpha1.CanaryStep{{ + SetWeight: int32Ptr(10), + }} + at := analysisTemplateWithOnlyNamespacedAnalysisRefs("bar", "bar2") + at2 := analysisTemplateWithClusterAnalysisRefs("bar2", "clusterbar2", "clusterbar4") + cat := clusterAnalysisTemplateWithAnalysisRefs("clusterbar", "clusterbar2", "clusterbar3") + cat2 := clusterAnalysisTemplateWithUniqueMetric("clusterbar2") + cat3 := clusterAnalysisTemplateWithUniqueMetric("clusterbar3") + cat4 := clusterAnalysisTemplateWithUniqueMetric("clusterbar4") + r1 := newCanaryRollout("foo", 10, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) + r2 := bumpVersion(r1) + + ar := &v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "run1", + Namespace: metav1.NamespaceDefault, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(r1, controllerKind)}, + }, + Spec: v1alpha1.AnalysisRunSpec{ + Metrics: concatMultipleSlices([][]v1alpha1.Metric{at.Spec.Metrics, at2.Spec.Metrics, cat.Spec.Metrics, cat2.Spec.Metrics, cat3.Spec.Metrics, cat4.Spec.Metrics}), + Args: at.Spec.Args, + }, + } + r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ + RolloutAnalysis: v1alpha1.RolloutAnalysis{ + Templates: []v1alpha1.AnalysisTemplateRef{{ + TemplateName: cat.Name, + ClusterScope: true, + }, { + TemplateName: at.Name, + }}, + }, + } + rs1 := newReplicaSetWithStatus(r1, 10, 10) + rs2 := newReplicaSetWithStatus(r2, 0, 0) + f.kubeobjects = append(f.kubeobjects, rs1, rs2) + f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) + rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + + r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 10, 0, 10, false) + progressingCondition, _ := newProgressingCondition(conditions.ReplicaSetUpdatedReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + availableCondition, _ := newAvailableCondition(true) + conditions.SetRolloutCondition(&r2.Status, availableCondition) + completedCondition, _ := newCompletedCondition(false) + conditions.SetRolloutCondition(&r2.Status, completedCondition) + + f.rolloutLister = append(f.rolloutLister, r2) + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, cat, cat2, cat3, cat4) + f.analysisTemplateLister = append(f.analysisTemplateLister, at, at2) + f.objects = append(f.objects, r2, cat, at, at2, cat2, cat3, cat4) + + createdIndex := f.expectCreateAnalysisRunAction(ar) + f.expectUpdateReplicaSetAction(rs2) + index := f.expectPatchRolloutAction(r1) + + f.run(getKey(r2, t)) + createdAr := f.getCreatedAnalysisRun(createdIndex) + expectedArName := fmt.Sprintf("%s-%s-%s", r2.Name, rs2PodHash, "2") + assert.Equal(t, expectedArName, createdAr.Name) + assert.Len(t, createdAr.Spec.Metrics, 5) + + patch := f.getPatchedRollout(index) + expectedPatch := `{ + "status": { + "canary": { + "currentBackgroundAnalysisRunStatus": { + "name": "%s", + "status": "" + } + } + } + }` + assert.JSONEq(t, calculatePatch(r2, fmt.Sprintf(expectedPatch, expectedArName)), patch) +} + // TestCreateAnalysisRunWithCollision ensures we will create an new analysis run with a new name // when there is a conflict (e.g. such as when there is a retry) func TestCreateAnalysisRunWithCollision(t *testing.T) { @@ -434,7 +693,7 @@ func TestCreateAnalysisRunWithCollision(t *testing.T) { ar := analysisRun(at, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -505,7 +764,7 @@ func TestCreateAnalysisRunWithCollisionAndSemanticEquality(t *testing.T) { ar := analysisRun(at, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -560,7 +819,7 @@ func TestCreateAnalysisRunOnAnalysisStep(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -621,7 +880,7 @@ func TestCreateAnalysisRunOnPromotedAnalysisStepIfPreviousStepWasAnalysisToo(t * at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -629,7 +888,7 @@ func TestCreateAnalysisRunOnPromotedAnalysisStepIfPreviousStepWasAnalysisToo(t * }, }, { Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -698,7 +957,7 @@ func TestFailCreateStepAnalysisRunIfInvalidTemplateRef(t *testing.T) { steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: "bad-template", }, @@ -749,7 +1008,7 @@ func TestFailCreateBackgroundAnalysisRunIfInvalidTemplateRef(t *testing.T) { r := newCanaryRollout("foo", 10, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) r.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: "bad-template", }, @@ -788,23 +1047,25 @@ func TestFailCreateBackgroundAnalysisRunIfMetricRepeated(t *testing.T) { }} at := analysisTemplate("bad-template") + at2 := analysisTemplate("bad-template-2") at.Spec.Metrics = append(at.Spec.Metrics, at.Spec.Metrics[0]) - f.analysisTemplateLister = append(f.analysisTemplateLister, at) + at2.Spec.Metrics = append(at2.Spec.Metrics, at2.Spec.Metrics[0]) + f.analysisTemplateLister = append(f.analysisTemplateLister, at, at2) r := newCanaryRollout("foo", 10, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) r.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, { - TemplateName: at.Name, + TemplateName: at2.Name, }, }, }, } f.rolloutLister = append(f.rolloutLister, r) - f.objects = append(f.objects, r, at) + f.objects = append(f.objects, r, at, at2) patchIndex := f.expectPatchRolloutAction(r) f.run(getKey(r, t)) @@ -816,7 +1077,7 @@ func TestFailCreateBackgroundAnalysisRunIfMetricRepeated(t *testing.T) { "message": "InvalidSpec: %s" } }` - errmsg := "The Rollout \"foo\" is invalid: spec.strategy.canary.analysis.templates: Invalid value: \"templateNames: [bad-template bad-template]\": two metrics have the same name 'example'" + errmsg := "The Rollout \"foo\" is invalid: spec.strategy.canary.analysis.templates: Invalid value: \"templateNames: [bad-template bad-template-2]\": two metrics have the same name 'example'" _, progressingCond := newProgressingCondition(conditions.ReplicaSetUpdatedReason, r, "") invalidSpecCond := conditions.NewRolloutCondition(v1alpha1.InvalidSpec, corev1.ConditionTrue, conditions.InvalidSpecReason, errmsg) invalidSpecBytes, _ := json.Marshal(invalidSpecCond) @@ -839,7 +1100,7 @@ func TestDoNothingWithAnalysisRunsWhileBackgroundAnalysisRunRunning(t *testing.T r2 := bumpVersion(r1) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -886,7 +1147,7 @@ func TestDoNothingWhileStepBasedAnalysisRunRunning(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -935,7 +1196,7 @@ func TestCancelOlderAnalysisRuns(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1003,7 +1264,7 @@ func TestDeleteAnalysisRunsWithNoMatchingRS(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1059,7 +1320,7 @@ func TestDeleteAnalysisRunsAfterRSDelete(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1116,7 +1377,7 @@ func TestIncrementStepAfterSuccessfulAnalysisRun(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1180,7 +1441,7 @@ func TestPausedOnInconclusiveBackgroundAnalysisRun(t *testing.T) { ar := analysisRun(at, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1240,7 +1501,7 @@ func TestPausedStepAfterInconclusiveAnalysisRun(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1303,7 +1564,7 @@ func TestErrorConditionAfterErrorAnalysisRunStep(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1378,7 +1639,7 @@ func TestErrorConditionAfterErrorAnalysisRunBackground(t *testing.T) { r2 := bumpVersion(r1) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1446,7 +1707,7 @@ func TestCancelAnalysisRunsWhenAborted(t *testing.T) { at := analysisTemplate("bar") steps := []v1alpha1.CanaryStep{{ Analysis: &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1513,7 +1774,7 @@ func TestCancelBackgroundAnalysisRunWhenRolloutIsCompleted(t *testing.T) { r2 := bumpVersion(r1) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1559,7 +1820,7 @@ func TestDoNotCreateBackgroundAnalysisRunAfterInconclusiveRun(t *testing.T) { r2 := bumpVersion(r1) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1614,7 +1875,7 @@ func TestDoNotCreateBackgroundAnalysisRunOnNewCanaryRollout(t *testing.T) { r1 := newCanaryRollout("foo", 1, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) r1.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1649,7 +1910,7 @@ func TestDoNotCreateBackgroundAnalysisRunOnNewCanaryRolloutStableRSEmpty(t *test r1 := newCanaryRollout("foo", 1, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) r1.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -1679,7 +1940,7 @@ func TestCreatePrePromotionAnalysisRun(t *testing.T) { r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -1737,7 +1998,7 @@ func TestDoNotCreatePrePromotionAnalysisAfterPromotionRollout(t *testing.T) { r1 := newBlueGreenRollout("foo", 1, nil, "bar", "") r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "test", }}, } @@ -1786,7 +2047,7 @@ func TestDoNotCreatePrePromotionAnalysisRunOnNewRollout(t *testing.T) { r := newBlueGreenRollout("foo", 1, nil, "active", "") r.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "test", }}, } @@ -1819,7 +2080,7 @@ func TestDoNotCreatePrePromotionAnalysisRunOnNotReadyReplicaSet(t *testing.T) { r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "test", }}, } @@ -1861,7 +2122,7 @@ func TestRolloutPrePromotionAnalysisBecomesInconclusive(t *testing.T) { r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -1931,7 +2192,7 @@ func TestRolloutPrePromotionAnalysisSwitchServiceAfterSuccess(t *testing.T) { r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(true) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -1996,7 +2257,7 @@ func TestRolloutPrePromotionAnalysisHonorAutoPromotionSeconds(t *testing.T) { r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.AutoPromotionSeconds = 10 r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2061,7 +2322,7 @@ func TestRolloutPrePromotionAnalysisDoNothingOnInconclusiveAnalysis(t *testing.T r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2115,7 +2376,7 @@ func TestAbortRolloutOnErrorPrePromotionAnalysis(t *testing.T) { r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2185,7 +2446,7 @@ func TestCreatePostPromotionAnalysisRun(t *testing.T) { r1 := newBlueGreenRollout("foo", 1, nil, "active", "") r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PostPromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2232,7 +2493,7 @@ func TestRolloutPostPromotionAnalysisSuccess(t *testing.T) { r1 := newBlueGreenRollout("foo", 1, nil, "active", "") r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PostPromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2290,7 +2551,7 @@ func TestPostPromotionAnalysisRunHandleInconclusive(t *testing.T) { r1 := newBlueGreenRollout("foo", 1, nil, "active", "") r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PostPromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2353,7 +2614,7 @@ func TestAbortRolloutOnErrorPostPromotionAnalysis(t *testing.T) { r1 := newBlueGreenRollout("foo", 1, nil, "active", "") r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PostPromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: at.Name, }}, } @@ -2430,7 +2691,7 @@ func TestCreateAnalysisRunWithCustomAnalysisRunMetadataAndROCopyLabels(t *testin ar := analysisRun(at, v1alpha1.RolloutTypeBackgroundRunLabel, r2) r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -2468,3 +2729,21 @@ func TestCreateAnalysisRunWithCustomAnalysisRunMetadataAndROCopyLabels(t *testin assert.Equal(t, "testLabelValue", createdAr.Labels["testLabelKey"]) assert.Equal(t, "1234", createdAr.Labels["my-label"]) } + +func concatMultipleSlices[T any](slices [][]T) []T { + var totalLen int + + for _, s := range slices { + totalLen += len(s) + } + + result := make([]T, totalLen) + + var i int + + for _, s := range slices { + i += copy(result[i:], s) + } + + return result +} diff --git a/rollout/bluegreen_test.go b/rollout/bluegreen_test.go index cff894e8ca..2ff9515fe3 100644 --- a/rollout/bluegreen_test.go +++ b/rollout/bluegreen_test.go @@ -428,7 +428,7 @@ func TestBlueGreenHandlePause(t *testing.T) { r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r2 := bumpVersion(r1) r2.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "test", }}, } diff --git a/rollout/controller.go b/rollout/controller.go index 1d7d8cde92..972cea882c 100644 --- a/rollout/controller.go +++ b/rollout/controller.go @@ -795,38 +795,64 @@ func (c *rolloutContext) getReferencedRolloutAnalyses() (*[]validation.AnalysisT } func (c *rolloutContext) getReferencedAnalysisTemplates(rollout *v1alpha1.Rollout, rolloutAnalysis *v1alpha1.RolloutAnalysis, templateType validation.AnalysisTemplateType, canaryStepIndex int) (*validation.AnalysisTemplatesWithType, error) { - templates := make([]*v1alpha1.AnalysisTemplate, 0) - clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) fldPath := validation.GetAnalysisTemplateWithTypeFieldPath(templateType, canaryStepIndex) - for _, templateRef := range rolloutAnalysis.Templates { + templates, clusterTemplates, err := c.getReferencedAnalysisTemplatesFromRef(&rolloutAnalysis.Templates, fldPath) + + return &validation.AnalysisTemplatesWithType{ + AnalysisTemplates: templates, + ClusterAnalysisTemplates: clusterTemplates, + TemplateType: templateType, + CanaryStepIndex: canaryStepIndex, + }, err +} + +func (c *rolloutContext) getReferencedAnalysisTemplatesFromRef(templateRefs *[]v1alpha1.AnalysisTemplateRef, fieldPath *field.Path) ([]*v1alpha1.AnalysisTemplate, []*v1alpha1.ClusterAnalysisTemplate, error) { + templates := make([]*v1alpha1.AnalysisTemplate, 0) + clusterTemplates := make([]*v1alpha1.ClusterAnalysisTemplate, 0) + for _, templateRef := range *templateRefs { if templateRef.ClusterScope { template, err := c.clusterAnalysisTemplateLister.Get(templateRef.TemplateName) if err != nil { if k8serrors.IsNotFound(err) { - return nil, field.Invalid(fldPath, templateRef.TemplateName, fmt.Sprintf("ClusterAnalysisTemplate '%s' not found", templateRef.TemplateName)) + return nil, nil, field.Invalid(fieldPath, templateRef.TemplateName, fmt.Sprintf("ClusterAnalysisTemplate '%s' not found", templateRef.TemplateName)) } - return nil, err + return nil, nil, err } clusterTemplates = append(clusterTemplates, template) + // Look for nested templates + if template.Spec.Templates != nil { + innerFldPath := field.NewPath("spec", "templates") + innerTemplates, innerClusterTemplates, innerErr := c.getReferencedAnalysisTemplatesFromRef(&template.Spec.Templates, innerFldPath) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } } else { template, err := c.analysisTemplateLister.AnalysisTemplates(c.rollout.Namespace).Get(templateRef.TemplateName) if err != nil { if k8serrors.IsNotFound(err) { - return nil, field.Invalid(fldPath, templateRef.TemplateName, fmt.Sprintf("AnalysisTemplate '%s' not found", templateRef.TemplateName)) + return nil, nil, field.Invalid(fieldPath, templateRef.TemplateName, fmt.Sprintf("AnalysisTemplate '%s' not found", templateRef.TemplateName)) } - return nil, err + return nil, nil, err } templates = append(templates, template) + // Look for nested templates + if template.Spec.Templates != nil { + innerFldPath := field.NewPath("spec", "templates") + innerTemplates, innerClusterTemplates, innerErr := c.getReferencedAnalysisTemplatesFromRef(&template.Spec.Templates, innerFldPath) + if innerErr != nil { + return nil, nil, innerErr + } + clusterTemplates = append(clusterTemplates, innerClusterTemplates...) + templates = append(templates, innerTemplates...) + } } } - - return &validation.AnalysisTemplatesWithType{ - AnalysisTemplates: templates, - ClusterAnalysisTemplates: clusterTemplates, - TemplateType: templateType, - CanaryStepIndex: canaryStepIndex, - }, nil + uniqueTemplates, uniqueClusterTemplates := analysisutil.FilterUniqueTemplates(templates, clusterTemplates) + return uniqueTemplates, uniqueClusterTemplates, nil } func (c *rolloutContext) getReferencedIngresses() (*[]ingressutil.Ingress, error) { diff --git a/rollout/controller_test.go b/rollout/controller_test.go index a637d68f29..325f30516d 100644 --- a/rollout/controller_test.go +++ b/rollout/controller_test.go @@ -1579,7 +1579,7 @@ func TestGetReferencedAnalyses(t *testing.T) { defer f.Close() rolloutAnalysisFail := v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "does-not-exist", ClusterScope: false, }}, @@ -1638,12 +1638,12 @@ func TestGetReferencedAnalyses(t *testing.T) { }) } -func TestGetReferencedAnalysisTemplate(t *testing.T) { +func TestGetReferencedClusterAnalysisTemplate(t *testing.T) { f := newFixture(t) defer f.Close() r := newBlueGreenRollout("rollout", 1, nil, "active-service", "preview-service") roAnalysisTemplate := &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{{ + Templates: []v1alpha1.AnalysisTemplateRef{{ TemplateName: "cluster-analysis-template-name", ClusterScope: true, }}, @@ -1668,6 +1668,52 @@ func TestGetReferencedAnalysisTemplate(t *testing.T) { }) } +func TestGetInnerReferencedAnalysisTemplate(t *testing.T) { + f := newFixture(t) + defer f.Close() + r := newBlueGreenRollout("rollout", 1, nil, "active-service", "preview-service") + roAnalysisTemplate := &v1alpha1.RolloutAnalysis{ + Templates: []v1alpha1.AnalysisTemplateRef{{ + TemplateName: "first-cluster-analysis-template-name", + ClusterScope: true, + }}, + } + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, clusterAnalysisTemplateWithAnalysisRefs("first-cluster-analysis-template-name", "second-cluster-analysis-template-name", "third-cluster-analysis-template-name")) + + t.Run("get inner referenced analysisTemplate - fail", func(t *testing.T) { + c, _, _ := f.newController(noResyncPeriodFunc) + roCtx, err := c.newRolloutContext(r) + assert.NoError(t, err) + _, err = roCtx.getReferencedAnalysisTemplates(r, roAnalysisTemplate, validation.PrePromotionAnalysis, 0) + expectedErr := field.Invalid(field.NewPath("spec", "templates"), "second-cluster-analysis-template-name", "ClusterAnalysisTemplate 'second-cluster-analysis-template-name' not found") + assert.Error(t, err) + assert.Equal(t, expectedErr.Error(), err.Error()) + }) + + t.Run("get inner referenced analysisTemplate second level - fail", func(t *testing.T) { + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, clusterAnalysisTemplate("second-cluster-analysis-template-name")) + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, clusterAnalysisTemplateWithAnalysisRefs("third-cluster-analysis-template-name", "fourth-cluster-analysis-template-name")) + c, _, _ := f.newController(noResyncPeriodFunc) + roCtx, err := c.newRolloutContext(r) + assert.NoError(t, err) + _, err = roCtx.getReferencedAnalysisTemplates(r, roAnalysisTemplate, validation.PrePromotionAnalysis, 0) + expectedErr := field.Invalid(field.NewPath("spec", "templates"), "fourth-cluster-analysis-template-name", "ClusterAnalysisTemplate 'fourth-cluster-analysis-template-name' not found") + assert.Error(t, err) + assert.Equal(t, expectedErr.Error(), err.Error()) + }) + + t.Run("get inner referenced analysisTemplate - success", func(t *testing.T) { + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, clusterAnalysisTemplate("second-cluster-analysis-template-name")) + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, clusterAnalysisTemplateWithAnalysisRefs("third-cluster-analysis-template-name", "fourth-cluster-analysis-template-name")) + f.clusterAnalysisTemplateLister = append(f.clusterAnalysisTemplateLister, clusterAnalysisTemplate("fourth-cluster-analysis-template-name")) + c, _, _ := f.newController(noResyncPeriodFunc) + roCtx, err := c.newRolloutContext(r) + assert.NoError(t, err) + _, err = roCtx.getReferencedAnalysisTemplates(r, roAnalysisTemplate, validation.PrePromotionAnalysis, 0) + assert.NoError(t, err) + }) +} + func TestGetReferencedIngressesALB(t *testing.T) { f := newFixture(t) defer f.Close() diff --git a/rollout/sync_test.go b/rollout/sync_test.go index a77fc358cb..c4c88d9851 100644 --- a/rollout/sync_test.go +++ b/rollout/sync_test.go @@ -313,7 +313,7 @@ func TestCanaryPromoteFull(t *testing.T) { r1 := newCanaryRollout("foo", 10, nil, steps, int32Ptr(0), intstr.FromInt(10), intstr.FromInt(0)) r1.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ RolloutAnalysis: v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, @@ -359,14 +359,14 @@ func TestBlueGreenPromoteFull(t *testing.T) { r1 := newBlueGreenRollout("foo", 10, nil, "active", "preview") r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false) r1.Spec.Strategy.BlueGreen.PrePromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, }, } r1.Spec.Strategy.BlueGreen.PostPromotionAnalysis = &v1alpha1.RolloutAnalysis{ - Templates: []v1alpha1.RolloutAnalysisTemplate{ + Templates: []v1alpha1.AnalysisTemplateRef{ { TemplateName: at.Name, }, diff --git a/ui/src/models/rollout/generated/api.ts b/ui/src/models/rollout/generated/api.ts index 254fc390a1..b9cdd3cde5 100755 --- a/ui/src/models/rollout/generated/api.ts +++ b/ui/src/models/rollout/generated/api.ts @@ -319,6 +319,25 @@ export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1AnalysisRun */ unsuccessfulRunHistoryLimit?: number; } +/** + * + * @export + * @interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1AnalysisTemplateRef + */ +export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1AnalysisTemplateRef { + /** + * + * @type {string} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1AnalysisTemplateRef + */ + templateName?: string; + /** + * + * @type {boolean} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1AnalysisTemplateRef + */ + clusterScope?: boolean; +} /** * * @export @@ -1891,10 +1910,10 @@ export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1Rollout { export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnalysis { /** * - * @type {Array} + * @type {Array} * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnalysis */ - templates?: Array; + templates?: Array; /** * * @type {Array} @@ -1964,25 +1983,6 @@ export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnal */ message?: string; } -/** - * - * @export - * @interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnalysisTemplate - */ -export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnalysisTemplate { - /** - * - * @type {string} - * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnalysisTemplate - */ - templateName?: string; - /** - * - * @type {boolean} - * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutAnalysisTemplate - */ - clusterScope?: boolean; -} /** * RolloutCondition describes the state of a rollout at a certain point. * @export diff --git a/utils/analysis/helpers.go b/utils/analysis/helpers.go index 6e95bd47fa..13ab1730f5 100644 --- a/utils/analysis/helpers.go +++ b/utils/analysis/helpers.go @@ -580,3 +580,23 @@ func GetInstanceID(obj runtime.Object) string { } return "" } + +func FilterUniqueTemplates(templates []*v1alpha1.AnalysisTemplate, clusterTemplates []*v1alpha1.ClusterAnalysisTemplate) ([]*v1alpha1.AnalysisTemplate, []*v1alpha1.ClusterAnalysisTemplate) { + uniqueTemplates := []*v1alpha1.AnalysisTemplate{} + uniqueClusterTemplates := []*v1alpha1.ClusterAnalysisTemplate{} + seenTemplates := map[string]bool{} + seenClusterTemplates := map[string]bool{} + for _, template := range templates { + if !seenTemplates[template.Name] { + seenTemplates[template.Name] = true + uniqueTemplates = append(uniqueTemplates, template) + } + } + for _, clusterTemplate := range clusterTemplates { + if !seenClusterTemplates[clusterTemplate.Name] { + seenClusterTemplates[clusterTemplate.Name] = true + uniqueClusterTemplates = append(uniqueClusterTemplates, clusterTemplate) + } + } + return uniqueTemplates, uniqueClusterTemplates +} diff --git a/utils/analysis/helpers_test.go b/utils/analysis/helpers_test.go index 207f5fa023..5927d788bb 100644 --- a/utils/analysis/helpers_test.go +++ b/utils/analysis/helpers_test.go @@ -1082,3 +1082,83 @@ func TestGetMeasurementRetentionMetrics(t *testing.T) { assert.Equal(t, len(measurementRetentionMetricNamesMap), 0) }) } + +func TestAnalysisTemplateFiltering(t *testing.T) { + t.Run("FilterAnalysisTemplates is returning empty arrays when empty arrays are provided in parameters", func(t *testing.T) { + + analysisTemplates := []*v1alpha1.AnalysisTemplate{} + clusterAnalysisTemplates := []*v1alpha1.ClusterAnalysisTemplate{} + + filteredAnalysisTemplates, filteredClusterAnalysisTemplates := FilterUniqueTemplates(analysisTemplates, clusterAnalysisTemplates) + + assert.Equal(t, len(filteredAnalysisTemplates), 0) + assert.Equal(t, len(filteredClusterAnalysisTemplates), 0) + + }) + + t.Run("FilterAnalysisTemplates is not filtering analysisTemplates duplications if there are none in the reference tree", func(t *testing.T) { + + analysisTemplates := []*v1alpha1.AnalysisTemplate{ + analysisTemplate("foo"), + analysisTemplate("bar"), + analysisTemplate("foo-2"), + analysisTemplate("foo-3"), + } + clusterAnalysisTemplates := []*v1alpha1.ClusterAnalysisTemplate{ + clusterAnalysisTemplate("cluster-foo"), + clusterAnalysisTemplate("cluster-bar"), + clusterAnalysisTemplate("cluster-foo-2"), + clusterAnalysisTemplate("cluster-foo-3"), + } + + filteredAnalysisTemplates, filteredClusterAnalysisTemplates := FilterUniqueTemplates(analysisTemplates, clusterAnalysisTemplates) + + assert.Equal(t, len(filteredAnalysisTemplates), 4) + assert.Equal(t, len(filteredClusterAnalysisTemplates), 4) + + }) + t.Run("FilterAnalysisTemplates is filtering analysisTemplates duplications in the reference tree", func(t *testing.T) { + + analysisTemplates := []*v1alpha1.AnalysisTemplate{ + analysisTemplate("foo"), + analysisTemplate("foo"), + analysisTemplate("foo-2"), + analysisTemplate("foo-3"), + analysisTemplate("foo-3"), + } + clusterAnalysisTemplates := []*v1alpha1.ClusterAnalysisTemplate{ + clusterAnalysisTemplate("cluster-foo"), + clusterAnalysisTemplate("cluster-foo"), + clusterAnalysisTemplate("cluster-bar"), + clusterAnalysisTemplate("cluster-bar"), + clusterAnalysisTemplate("cluster-bar"), + clusterAnalysisTemplate("cluster-bar"), + clusterAnalysisTemplate("cluster-foo-2"), + clusterAnalysisTemplate("cluster-foo-2"), + clusterAnalysisTemplate("cluster-foo-2"), + clusterAnalysisTemplate("cluster-foo-3"), + } + + filteredAnalysisTemplates, filteredClusterAnalysisTemplates := FilterUniqueTemplates(analysisTemplates, clusterAnalysisTemplates) + + assert.Equal(t, len(filteredAnalysisTemplates), 3) + assert.Equal(t, len(filteredClusterAnalysisTemplates), 4) + + }) +} + +func analysisTemplate(name string) *v1alpha1.AnalysisTemplate { + return &v1alpha1.AnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } +} + +func clusterAnalysisTemplate(name string) *v1alpha1.ClusterAnalysisTemplate { + return &v1alpha1.ClusterAnalysisTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } +}