From c8215f972502435e6bc5b232823ecb6df919f952 Mon Sep 17 00:00:00 2001 From: Alex Collins Date: Wed, 20 Jan 2021 11:10:14 -0800 Subject: [PATCH] feat(controller)!: Key-only artifacts. Fixes #3184 (#4618) Signed-off-by: Alex Collins Co-authored-by: Saravanan Balasubramanian <33908564+sarabala1979@users.noreply.github.com> --- api/jsonschema/schema.json | 10 - api/openapi-spec/swagger.json | 10 - config/config.go | 78 ++ config/config_test.go | 54 + docs/artifact-repository-ref.md | 4 +- docs/fields.md | 28 + docs/key-only-artifacts.md | 61 + examples/key-only-artifact.yaml | 38 + .../argoproj.io_clusterworkflowtemplates.yaml | 60 - .../crds/full/argoproj.io_cronworkflows.yaml | 60 - .../argoproj.io_workfloweventbindings.yaml | 10 - .../base/crds/full/argoproj.io_workflows.yaml | 200 --- .../full/argoproj.io_workflowtemplates.yaml | 60 - mkdocs.yml | 1 + pkg/apis/workflow/v1alpha1/generated.pb.go | 1084 +++++++++-------- .../workflow/v1alpha1/openapi_generated.go | 32 +- pkg/apis/workflow/v1alpha1/workflow_types.go | 267 ++-- .../workflow/v1alpha1/workflow_types_test.go | 286 ++++- .../v1alpha1/zz_generated.deepcopy.go | 30 +- server/artifacts/artifact_server.go | 17 +- server/artifacts/artifact_server_test.go | 29 +- test/e2e/functional_test.go | 13 + .../e2e/testdata/artifact-repository-ref.yaml | 30 +- workflow/common/util.go | 20 +- workflow/controller/scope.go | 44 +- workflow/controller/workflowpod.go | 125 +- workflow/controller/workflowpod_test.go | 24 - workflow/executor/executor.go | 120 +- 28 files changed, 1457 insertions(+), 1338 deletions(-) create mode 100644 docs/key-only-artifacts.md create mode 100644 examples/key-only-artifact.yaml diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json index 973557a66cd1..82560d693fac 100644 --- a/api/jsonschema/schema.json +++ b/api/jsonschema/schema.json @@ -3340,7 +3340,6 @@ } }, "required": [ - "bucket", "key" ], "type": "object" @@ -3478,7 +3477,6 @@ } }, "required": [ - "addresses", "path" ], "type": "object" @@ -3936,10 +3934,6 @@ } }, "required": [ - "endpoint", - "bucket", - "accessKeySecret", - "secretKeySecret", "key" ], "type": "object" @@ -4202,10 +4196,6 @@ } }, "required": [ - "endpoint", - "bucket", - "accessKeySecret", - "secretKeySecret", "key" ], "type": "object" diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 3e60b55550e2..271178dbe27e 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -6741,7 +6741,6 @@ "description": "GCSArtifact is the location of a GCS artifact", "type": "object", "required": [ - "bucket", "key" ], "properties": { @@ -6848,7 +6847,6 @@ "description": "HDFSArtifact is the location of an HDFS artifact", "type": "object", "required": [ - "addresses", "path" ], "properties": { @@ -7329,10 +7327,6 @@ "description": "OSSArtifact is the location of an Alibaba Cloud OSS artifact", "type": "object", "required": [ - "endpoint", - "bucket", - "accessKeySecret", - "secretKeySecret", "key" ], "properties": { @@ -7575,10 +7569,6 @@ "description": "S3Artifact is the location of an S3 artifact", "type": "object", "required": [ - "endpoint", - "bucket", - "accessKeySecret", - "secretKeySecret", "key" ], "properties": { diff --git a/config/config.go b/config/config.go index d0cec26874ec..f432872d78c2 100644 --- a/config/config.go +++ b/config/config.go @@ -2,12 +2,14 @@ package config import ( "fmt" + "path" apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo/workflow/common" ) var EmptyConfigFunc = func() interface{} { return &Config{} } @@ -138,6 +140,41 @@ func (a *ArtifactRepository) IsArchiveLogs() bool { return a != nil && a.ArchiveLogs != nil && *a.ArchiveLogs } +type ArtifactRepositoryType interface { + IntoArtifactLocation(l *wfv1.ArtifactLocation) +} + +func (a *ArtifactRepository) Get() ArtifactRepositoryType { + if a == nil { + return nil + } else if a.Artifactory != nil { + return a.Artifactory + } else if a.GCS != nil { + return a.GCS + } else if a.HDFS != nil { + return a.HDFS + } else if a.OSS != nil { + return a.OSS + } else if a.S3 != nil { + return a.S3 + } + return nil +} + +// ToArtifactLocation returns the artifact location set with default template key: +// key = `{{workflow.name}}/{{pod.name}}` +func (a *ArtifactRepository) ToArtifactLocation() *wfv1.ArtifactLocation { + if a == nil { + return nil + } + l := &wfv1.ArtifactLocation{ArchiveLogs: a.ArchiveLogs} + v := a.Get() + if v != nil { + v.IntoArtifactLocation(l) + } + return l +} + type PersistConfig struct { NodeStatusOffload bool `json:"nodeStatusOffLoad,omitempty"` // Archive workflows to persistence. @@ -212,6 +249,14 @@ type S3ArtifactRepository struct { KeyPrefix string `json:"keyPrefix,omitempty"` } +func (r *S3ArtifactRepository) IntoArtifactLocation(l *wfv1.ArtifactLocation) { + k := r.KeyFormat + if k == "" { + k = path.Join(r.KeyPrefix, common.DefaultArchivePattern) + } + l.S3 = &wfv1.S3Artifact{S3Bucket: r.S3Bucket, Key: k} +} + // OSSArtifactRepository defines the controller configuration for an OSS artifact repository type OSSArtifactRepository struct { wfv1.OSSBucket `json:",inline"` @@ -220,6 +265,14 @@ type OSSArtifactRepository struct { KeyFormat string `json:"keyFormat,omitempty"` } +func (r *OSSArtifactRepository) IntoArtifactLocation(l *wfv1.ArtifactLocation) { + k := r.KeyFormat + if k == "" { + k = common.DefaultArchivePattern + } + l.OSS = &wfv1.OSSArtifact{OSSBucket: r.OSSBucket, Key: k} +} + // GCSArtifactRepository defines the controller configuration for a GCS artifact repository type GCSArtifactRepository struct { wfv1.GCSBucket `json:",inline"` @@ -228,6 +281,14 @@ type GCSArtifactRepository struct { KeyFormat string `json:"keyFormat,omitempty"` } +func (r *GCSArtifactRepository) IntoArtifactLocation(l *wfv1.ArtifactLocation) { + k := r.KeyFormat + if k == "" { + k = common.DefaultArchivePattern + } + l.GCS = &wfv1.GCSArtifact{GCSBucket: r.GCSBucket, Key: k} +} + // ArtifactoryArtifactRepository defines the controller configuration for an artifactory artifact repository type ArtifactoryArtifactRepository struct { wfv1.ArtifactoryAuth `json:",inline"` @@ -235,6 +296,15 @@ type ArtifactoryArtifactRepository struct { RepoURL string `json:"repoURL,omitempty"` } +func (r *ArtifactoryArtifactRepository) IntoArtifactLocation(l *wfv1.ArtifactLocation) { + u := "" + if r.RepoURL != "" { + u = r.RepoURL + "/" + } + u = fmt.Sprintf("%s%s", u, common.DefaultArchivePattern) + l.Artifactory = &wfv1.ArtifactoryArtifact{ArtifactoryAuth: r.ArtifactoryAuth, URL: u} +} + // HDFSArtifactRepository defines the controller configuration for an HDFS artifact repository type HDFSArtifactRepository struct { wfv1.HDFSConfig `json:",inline"` @@ -246,6 +316,14 @@ type HDFSArtifactRepository struct { Force bool `json:"force,omitempty"` } +func (r *HDFSArtifactRepository) IntoArtifactLocation(l *wfv1.ArtifactLocation) { + p := r.PathFormat + if p == "" { + p = common.DefaultArchivePattern + } + l.HDFS = &wfv1.HDFSArtifact{HDFSConfig: r.HDFSConfig, Path: p, Force: r.Force} +} + // MetricsConfig defines a config for a metrics server type MetricsConfig struct { // Enabled controls metric emission. Default is true, set "enabled: false" to turn off diff --git a/config/config_test.go b/config/config_test.go index 3a1cf57029c3..c917332164c9 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -7,6 +7,60 @@ import ( "k8s.io/utils/pointer" ) +func TestArtifactRepository(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + var r *ArtifactRepository + assert.Nil(t, r.Get()) + l := r.ToArtifactLocation() + assert.Nil(t, l) + }) + t.Run("ArchiveLogs", func(t *testing.T) { + r := &ArtifactRepository{Artifactory: &ArtifactoryArtifactRepository{}, ArchiveLogs: pointer.BoolPtr(true)} + l := r.ToArtifactLocation() + assert.Equal(t, pointer.BoolPtr(true), l.ArchiveLogs) + }) + t.Run("Artifactory", func(t *testing.T) { + r := &ArtifactRepository{Artifactory: &ArtifactoryArtifactRepository{RepoURL: "http://my-repo"}} + assert.IsType(t, &ArtifactoryArtifactRepository{}, r.Get()) + l := r.ToArtifactLocation() + if assert.NotNil(t, l.Artifactory) { + assert.Equal(t, "http://my-repo/{{workflow.name}}/{{pod.name}}", l.Artifactory.URL) + } + }) + t.Run("GCS", func(t *testing.T) { + r := &ArtifactRepository{GCS: &GCSArtifactRepository{}} + assert.IsType(t, &GCSArtifactRepository{}, r.Get()) + l := r.ToArtifactLocation() + if assert.NotNil(t, l.GCS) { + assert.Equal(t, "{{workflow.name}}/{{pod.name}}", l.GCS.Key) + } + }) + t.Run("HDFS", func(t *testing.T) { + r := &ArtifactRepository{HDFS: &HDFSArtifactRepository{}} + assert.IsType(t, &HDFSArtifactRepository{}, r.Get()) + l := r.ToArtifactLocation() + if assert.NotNil(t, l.HDFS) { + assert.Equal(t, "{{workflow.name}}/{{pod.name}}", l.HDFS.Path) + } + }) + t.Run("OSS", func(t *testing.T) { + r := &ArtifactRepository{OSS: &OSSArtifactRepository{}} + assert.IsType(t, &OSSArtifactRepository{}, r.Get()) + l := r.ToArtifactLocation() + if assert.NotNil(t, l.OSS) { + assert.Equal(t, "{{workflow.name}}/{{pod.name}}", l.OSS.Key) + } + }) + t.Run("S3", func(t *testing.T) { + r := &ArtifactRepository{S3: &S3ArtifactRepository{KeyPrefix: "my-key-prefix"}} + assert.IsType(t, &S3ArtifactRepository{}, r.Get()) + l := r.ToArtifactLocation() + if assert.NotNil(t, l.S3) { + assert.Equal(t, "my-key-prefix/{{workflow.name}}/{{pod.name}}", l.S3.Key) + } + }) +} + func TestArtifactRepository_IsArchiveLogs(t *testing.T) { assert.False(t, (&ArtifactRepository{}).IsArchiveLogs()) assert.False(t, (&ArtifactRepository{ArchiveLogs: pointer.BoolPtr(false)}).IsArchiveLogs()) diff --git a/docs/artifact-repository-ref.md b/docs/artifact-repository-ref.md index c5104d847ac3..d55cb6169adc 100644 --- a/docs/artifact-repository-ref.md +++ b/docs/artifact-repository-ref.md @@ -15,7 +15,7 @@ metadata: # if you want to use this config map by default - name it "artifact-repositories" name: artifact-repositories annotations: - # if you want to use a specific key, put that's key into this annotation + # v3.0 and after - if you want to use a specific key, put that's key into this annotation workflows.argoproj.io/default-artifact-repository: default-v1 data: default-v1: | @@ -40,4 +40,6 @@ spec: key: my-key # default can be set by the annotation ``` +This feature gives maximum benefit when used with [key-only artifacts](key-only-artifacts.md). + Reference: [fields.md#artifactrepositoryref](fields.md#artifactrepositoryref). \ No newline at end of file diff --git a/docs/fields.md b/docs/fields.md index 6b74be4aa7c5..66c852944d02 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -140,6 +140,8 @@ Workflow is the definition of a workflow resource - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -477,6 +479,8 @@ WorkflowSpec is the specification of a Workflow. - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -832,6 +836,8 @@ CronWorkflowSpec is the specification of a CronWorkflow - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -1145,6 +1151,8 @@ WorkflowTemplateSpec is a spec of WorkflowTemplate. - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -1755,6 +1763,8 @@ Template is a reusable and composable unit of execution in a workflow - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -2091,6 +2101,8 @@ Outputs hold parameters, artifacts, and results from a step - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`map-reduce.yaml`](https://github.com/argoproj/argo/blob/master/examples/map-reduce.yaml) - [`memoize-simple.yaml`](https://github.com/argoproj/argo/blob/master/examples/memoize-simple.yaml) @@ -2193,6 +2205,8 @@ Artifact indicates an artifact to place at a specified path - [`input-artifact-s3.yaml`](https://github.com/argoproj/argo/blob/master/examples/input-artifact-s3.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`map-reduce.yaml`](https://github.com/argoproj/argo/blob/master/examples/map-reduce.yaml) - [`nested-workflow.yaml`](https://github.com/argoproj/argo/blob/master/examples/nested-workflow.yaml) @@ -2536,6 +2550,8 @@ DAGTemplate is a template subtype for directed acyclic graph templates - [`exit-handler-dag-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/exit-handler-dag-level.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`map-reduce.yaml`](https://github.com/argoproj/argo/blob/master/examples/map-reduce.yaml) @@ -2680,6 +2696,8 @@ Inputs are the mechanism for passing parameters, artifacts, volumes from one tem - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -2913,6 +2931,8 @@ Pod metdata - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -3828,6 +3848,8 @@ DAGTask represents a node in the graph during DAG execution - [`exit-handler-dag-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/exit-handler-dag-level.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`map-reduce.yaml`](https://github.com/argoproj/argo/blob/master/examples/map-reduce.yaml) @@ -4211,6 +4233,8 @@ ObjectMeta is metadata that all persisted resources must have, which includes al - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -4744,6 +4768,8 @@ A single application container that you want to run within a pod. - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) @@ -5393,6 +5419,8 @@ PersistentVolumeClaimSpec describes the common attributes of storage devices and - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo/blob/master/examples/k8s-wait-wf.yaml) +- [`key-only-artifact.yaml`](https://github.com/argoproj/argo/blob/master/examples/key-only-artifact.yaml) + - [`loops-dag.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-dag.yaml) - [`loops-maps.yaml`](https://github.com/argoproj/argo/blob/master/examples/loops-maps.yaml) diff --git a/docs/key-only-artifacts.md b/docs/key-only-artifacts.md new file mode 100644 index 000000000000..e1f6ab01d480 --- /dev/null +++ b/docs/key-only-artifacts.md @@ -0,0 +1,61 @@ +# Key-Only Artifacts + +![Alpha](assets/alpha.svg) + +> v3.0 and after + +A key-only artifact is an input or output artifact where you only specific the key, omitting the bucket, secrets etc. When these are omitted, the bucket/secrets from the configured artifact repository is used. + +This allows you to move the configuration of the artifact repository out of the workflow specification. + +This is closely related to [artifact repository ref](artifact-repository-ref.md). You'll want to use them together for maximum benefit. + +This should probably be your default if you're using v3.0: + +* Reduces the size of workflows (improved performance). +* User owned artifact repository set-up configuration (simplified management). +* Decouples the artifact location configuration from the workflow. Allowing you to re-configure the artifact repository without changing your workflows or templates. + +Example: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: key-only-artifacts- +spec: + entrypoint: main + templates: + - name: main + dag: + tasks: + - name: generate + template: generate + - name: consume + template: consume + dependencies: + - generate + - name: generate + container: + image: argoproj/argosay:v2 + args: [ echo, hello, /mnt/file ] + outputs: + artifacts: + - name: file + path: /mnt/file + s3: + key: my-file + - name: consume + container: + image: argoproj/argosay:v2 + args: [cat, /tmp/file] + inputs: + artifacts: + - name: file + path: /tmp/file + s3: + key: my-file +``` + +!!! WARNING + The location data is not longer stored in `/status/nodes`. Any tooling that relies on this will need to be updated. \ No newline at end of file diff --git a/examples/key-only-artifact.yaml b/examples/key-only-artifact.yaml new file mode 100644 index 000000000000..34669579d143 --- /dev/null +++ b/examples/key-only-artifact.yaml @@ -0,0 +1,38 @@ +# this example shows how to use key-only artifacts - introduced in v3.0 +# https://argoproj.github.io/argo/key-only-artifacts/ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: key-only-artifacts- +spec: + entrypoint: main + templates: + - name: main + dag: + tasks: + - name: generate + template: generate + - name: consume + template: consume + dependencies: + - generate + - name: generate + container: + image: argoproj/argosay:v2 + args: [ echo, hello, /mnt/file ] + outputs: + artifacts: + - name: file + path: /mnt/file + s3: + key: my-file + - name: consume + container: + image: argoproj/argosay:v2 + args: [cat, /tmp/file] + inputs: + artifacts: + - name: file + path: /tmp/file + s3: + key: my-file diff --git a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml index 06125a3aa62b..793207a68d6b 100644 --- a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml @@ -359,7 +359,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -467,7 +466,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -527,11 +525,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -588,11 +582,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -1255,7 +1245,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1361,7 +1350,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1414,11 +1402,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object raw: properties: @@ -1471,11 +1455,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object type: object arguments: @@ -1547,7 +1527,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1655,7 +1634,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1715,11 +1693,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -1776,11 +1750,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -2450,7 +2420,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -2558,7 +2527,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -2618,11 +2586,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -2679,11 +2643,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3425,7 +3385,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3533,7 +3492,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -3593,11 +3551,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -3654,11 +3608,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3876,7 +3826,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3984,7 +3933,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -4044,11 +3992,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -4105,11 +4049,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml index 65ea67f45d79..64747801fed9 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -380,7 +380,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -488,7 +487,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -548,11 +546,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -609,11 +603,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -1276,7 +1266,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1382,7 +1371,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1435,11 +1423,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object raw: properties: @@ -1492,11 +1476,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object type: object arguments: @@ -1568,7 +1548,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1676,7 +1655,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1736,11 +1714,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -1797,11 +1771,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -2471,7 +2441,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -2579,7 +2548,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -2639,11 +2607,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -2700,11 +2664,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3446,7 +3406,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3554,7 +3513,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -3614,11 +3572,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -3675,11 +3629,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3897,7 +3847,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -4005,7 +3954,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -4065,11 +4013,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -4126,11 +4070,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string diff --git a/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml b/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml index 7cc173568bc6..5bd2404932e2 100644 --- a/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml +++ b/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml @@ -102,7 +102,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -210,7 +209,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -270,11 +268,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -331,11 +325,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string diff --git a/manifests/base/crds/full/argoproj.io_workflows.yaml b/manifests/base/crds/full/argoproj.io_workflows.yaml index 34e3fc9892e5..b75ef5c168b2 100644 --- a/manifests/base/crds/full/argoproj.io_workflows.yaml +++ b/manifests/base/crds/full/argoproj.io_workflows.yaml @@ -369,7 +369,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -477,7 +476,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -537,11 +535,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -598,11 +592,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -1265,7 +1255,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1371,7 +1360,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1424,11 +1412,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object raw: properties: @@ -1481,11 +1465,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object type: object arguments: @@ -1557,7 +1537,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1665,7 +1644,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1725,11 +1703,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -1786,11 +1760,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -2460,7 +2430,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -2568,7 +2537,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -2628,11 +2596,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -2689,11 +2653,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3435,7 +3395,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3543,7 +3502,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -3603,11 +3561,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -3664,11 +3618,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3886,7 +3836,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3994,7 +3943,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -4054,11 +4002,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -4115,11 +4059,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -7080,7 +7020,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -7188,7 +7127,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -7248,11 +7186,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -7309,11 +7243,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -7448,7 +7378,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -7556,7 +7485,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -7616,11 +7544,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -7677,11 +7601,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -7847,7 +7767,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -7955,7 +7874,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -8015,11 +7933,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -8076,11 +7990,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -9134,7 +9044,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -9240,7 +9149,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -9293,11 +9201,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object raw: properties: @@ -9350,11 +9254,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object type: object arguments: @@ -9426,7 +9326,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -9534,7 +9433,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -9594,11 +9492,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -9655,11 +9549,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -10330,7 +10220,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -10438,7 +10327,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -10498,11 +10386,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -10559,11 +10443,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -11306,7 +11186,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -11414,7 +11293,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -11474,11 +11352,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -11535,11 +11409,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -11757,7 +11627,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -11865,7 +11734,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -11925,11 +11793,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -11986,11 +11850,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -14332,7 +14192,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -14440,7 +14299,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -14500,11 +14358,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -14561,11 +14415,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -15228,7 +15078,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -15334,7 +15183,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -15387,11 +15235,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object raw: properties: @@ -15444,11 +15288,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object type: object arguments: @@ -15520,7 +15360,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -15628,7 +15467,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -15688,11 +15526,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -15749,11 +15583,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -16423,7 +16253,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -16531,7 +16360,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -16591,11 +16419,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -16652,11 +16476,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -17398,7 +17218,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -17506,7 +17325,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -17566,11 +17384,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -17627,11 +17441,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -17849,7 +17659,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -17957,7 +17766,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -18017,11 +17825,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -18078,11 +17882,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string diff --git a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml index b6edcf19f927..ffba63e6f318 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml @@ -358,7 +358,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -466,7 +465,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -526,11 +524,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -587,11 +581,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -1254,7 +1244,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1360,7 +1349,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1413,11 +1401,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object raw: properties: @@ -1470,11 +1454,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object type: object arguments: @@ -1546,7 +1526,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -1654,7 +1633,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -1714,11 +1692,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -1775,11 +1749,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -2449,7 +2419,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -2557,7 +2526,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -2617,11 +2585,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -2678,11 +2642,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3424,7 +3384,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3532,7 +3491,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -3592,11 +3550,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -3653,11 +3607,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string @@ -3875,7 +3825,6 @@ spec: - key type: object required: - - bucket - key type: object git: @@ -3983,7 +3932,6 @@ spec: path: type: string required: - - addresses - path type: object http: @@ -4043,11 +3991,7 @@ spec: - key type: object required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object path: type: string @@ -4104,11 +4048,7 @@ spec: useSDKCreds: type: boolean required: - - accessKeySecret - - bucket - - endpoint - key - - secretKeySecret type: object subPath: type: string diff --git a/mkdocs.yml b/mkdocs.yml index ab6b373b1925..b90bae912960 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,6 +41,7 @@ nav: - work-avoidance.md - enhanced-depends-logic.md - artifact-repository-ref.md + - key-only-artifacts.md - resource-duration.md - estimated-duration.md - workflow-pod-security-context.md diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index bb3d4a3cf844..0d8157d208b4 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -2807,480 +2807,479 @@ func init() { } var fileDescriptor_c23edafa7e7ea072 = []byte{ - // 7558 bytes of a gzipped FileDescriptorProto + // 7551 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5b, 0x6c, 0x24, 0x59, 0x96, 0x50, 0xa7, 0xed, 0xb4, 0x33, 0x4f, 0xda, 0x65, 0xfb, 0xd6, 0x2b, 0xdb, 0x55, 0x5d, 0xae, 0x8d, 0xde, 0x6e, 0x75, 0x41, 0xaf, 0xbd, 0x5d, 0x35, 0x0d, 0xbd, 0xdb, 0xdb, 0x0f, 0xa7, 0x5f, 0xe5, 0xae, 0xf2, 0xa3, 0x4f, 0xba, 0xaa, 0xd8, 0xae, 0x56, 0x37, 0xe1, 0xcc, 0xeb, 0xcc, 0x28, - 0x67, 0x46, 0x64, 0x47, 0x44, 0xda, 0xed, 0x6e, 0x10, 0xbd, 0x23, 0x96, 0x65, 0xd9, 0x5d, 0x01, - 0x42, 0x0b, 0x83, 0x56, 0xbc, 0x24, 0x56, 0xfc, 0x2c, 0xe2, 0x03, 0xc1, 0x0f, 0xd2, 0x7e, 0x20, - 0x40, 0xc3, 0x4a, 0x88, 0xe1, 0x8b, 0x91, 0x18, 0x79, 0xa6, 0xcd, 0xcf, 0x8c, 0x60, 0x18, 0xf1, - 0x81, 0x90, 0x4a, 0x48, 0xa0, 0xfb, 0x8c, 0x1b, 0x91, 0x91, 0x55, 0x76, 0xa4, 0xab, 0x34, 0x62, - 0xe6, 0x2f, 0xe3, 0x9c, 0x73, 0xcf, 0xb9, 0xef, 0x7b, 0x5e, 0xf7, 0x26, 0x2c, 0x36, 0x9c, 0xb0, - 0xd9, 0xdd, 0x99, 0xab, 0x79, 0xed, 0x79, 0xdb, 0x6f, 0x78, 0x1d, 0xdf, 0x7b, 0xc4, 0x7f, 0xcc, - 0x77, 0xf6, 0x1a, 0xf3, 0x76, 0xc7, 0x09, 0xe6, 0x0f, 0x3c, 0x7f, 0x6f, 0xb7, 0xe5, 0x1d, 0xcc, - 0xef, 0xbf, 0x61, 0xb7, 0x3a, 0x4d, 0xfb, 0x8d, 0xf9, 0x06, 0x75, 0xa9, 0x6f, 0x87, 0xb4, 0x3e, - 0xd7, 0xf1, 0xbd, 0xd0, 0x23, 0xb7, 0x22, 0x26, 0x73, 0x8a, 0x09, 0xff, 0x31, 0xd7, 0xd9, 0x6b, - 0xcc, 0x31, 0x26, 0x73, 0x8a, 0xc9, 0x9c, 0x62, 0x32, 0xf3, 0x4b, 0x86, 0xe4, 0x86, 0xc7, 0x04, - 0x32, 0x5e, 0x3b, 0xdd, 0x5d, 0xfe, 0xc5, 0x3f, 0xf8, 0x2f, 0x21, 0x63, 0xc6, 0xda, 0x7b, 0x2b, - 0x98, 0x73, 0x3c, 0x56, 0xa5, 0xf9, 0x9a, 0xe7, 0xd3, 0xf9, 0xfd, 0x9e, 0x7a, 0xcc, 0xdc, 0x30, - 0x68, 0x3a, 0x5e, 0xcb, 0xa9, 0x1d, 0xce, 0xef, 0xbf, 0xb1, 0x43, 0xc3, 0xde, 0x2a, 0xcf, 0x7c, - 0x23, 0x22, 0x6d, 0xdb, 0xb5, 0xa6, 0xe3, 0x52, 0xff, 0x30, 0x6a, 0x72, 0x9b, 0x86, 0x76, 0x9a, - 0x80, 0xf9, 0x7e, 0xa5, 0xfc, 0xae, 0x1b, 0x3a, 0x6d, 0xda, 0x53, 0xe0, 0xcf, 0x3c, 0xad, 0x40, - 0x50, 0x6b, 0xd2, 0xb6, 0xdd, 0x53, 0xee, 0x56, 0xbf, 0x72, 0xdd, 0xd0, 0x69, 0xcd, 0x3b, 0x6e, - 0x18, 0x84, 0x7e, 0xb2, 0x90, 0xb5, 0x0c, 0xa3, 0x0b, 0x6d, 0xaf, 0xeb, 0x86, 0xe4, 0x6d, 0xc8, - 0xef, 0xdb, 0xad, 0x2e, 0x2d, 0xe7, 0xae, 0xe7, 0x5e, 0x2b, 0x56, 0x5e, 0xf9, 0xf6, 0xd1, 0xec, - 0x0b, 0xc7, 0x47, 0xb3, 0xf9, 0xfb, 0x0c, 0xf8, 0xf8, 0x68, 0xf6, 0x02, 0x75, 0x6b, 0x5e, 0xdd, - 0x71, 0x1b, 0xf3, 0x8f, 0x02, 0xcf, 0x9d, 0xdb, 0xe8, 0xb6, 0x77, 0xa8, 0x8f, 0xa2, 0x8c, 0xf5, - 0x47, 0x43, 0x30, 0xb9, 0xe0, 0xd7, 0x9a, 0xce, 0x3e, 0xad, 0x86, 0x8c, 0x7f, 0xe3, 0x90, 0x3c, - 0x84, 0xe1, 0xd0, 0xf6, 0x39, 0xbb, 0xd2, 0xcd, 0xf7, 0xe7, 0x32, 0x8c, 0xf7, 0xdc, 0xb6, 0xed, - 0x2b, 0x76, 0x95, 0xb1, 0xe3, 0xa3, 0xd9, 0xe1, 0x6d, 0xdb, 0x47, 0xc6, 0x95, 0x7c, 0x0a, 0x23, - 0xae, 0xe7, 0xd2, 0xf2, 0x10, 0xe7, 0xbe, 0x90, 0x89, 0xfb, 0x86, 0xe7, 0xea, 0xda, 0x56, 0x0a, - 0xc7, 0x47, 0xb3, 0x23, 0x0c, 0x82, 0x9c, 0x31, 0xab, 0xfd, 0x17, 0x4e, 0xa7, 0x3c, 0x3c, 0x40, - 0xed, 0x3f, 0x72, 0x3a, 0xf1, 0xda, 0x7f, 0xe4, 0x74, 0x90, 0x71, 0xb5, 0x7e, 0x92, 0x83, 0xe2, - 0x82, 0xdf, 0xe8, 0xb6, 0xa9, 0x1b, 0x06, 0xc4, 0x07, 0xe8, 0xd8, 0xbe, 0xdd, 0xa6, 0x21, 0xf5, - 0x83, 0x72, 0xee, 0xfa, 0xf0, 0x6b, 0xa5, 0x9b, 0xef, 0x66, 0x92, 0xb8, 0xa5, 0xd8, 0x54, 0x88, - 0x1c, 0x3e, 0xd0, 0xa0, 0x00, 0x0d, 0x29, 0xc4, 0x85, 0xa2, 0xed, 0x87, 0xce, 0xae, 0x5d, 0x0b, - 0x83, 0xf2, 0x10, 0x17, 0xf9, 0x4e, 0x26, 0x91, 0x0b, 0x92, 0x4b, 0x65, 0x5a, 0x4a, 0x2c, 0x2a, - 0x48, 0x80, 0x91, 0x08, 0xeb, 0x3f, 0x8c, 0x40, 0x41, 0x21, 0xc8, 0x75, 0x18, 0x71, 0xed, 0xb6, - 0x9a, 0x69, 0xe3, 0xb2, 0xe0, 0xc8, 0x86, 0xdd, 0x66, 0xbd, 0x6f, 0xb7, 0x29, 0xa3, 0xe8, 0xd8, - 0x61, 0x93, 0x0f, 0xaf, 0x41, 0xb1, 0x65, 0x87, 0x4d, 0xe4, 0x18, 0x72, 0x15, 0x46, 0xda, 0x5e, - 0x9d, 0xf2, 0x01, 0xca, 0x8b, 0xd1, 0x5b, 0xf7, 0xea, 0x14, 0x39, 0x94, 0x95, 0xdf, 0xf5, 0xbd, - 0x76, 0x79, 0x24, 0x5e, 0x7e, 0xc5, 0xf7, 0xda, 0xc8, 0x31, 0xe4, 0x77, 0x72, 0x30, 0xa5, 0xaa, - 0x77, 0xd7, 0xab, 0xd9, 0xa1, 0xe3, 0xb9, 0xe5, 0x3c, 0x1f, 0xed, 0xe5, 0x81, 0x3a, 0x42, 0x31, - 0xab, 0x94, 0xa5, 0xd4, 0xa9, 0x24, 0x06, 0x7b, 0x04, 0x93, 0x9b, 0x00, 0x8d, 0x96, 0xb7, 0x63, - 0xb7, 0x58, 0x1f, 0x94, 0x47, 0x79, 0xad, 0xf5, 0x10, 0xae, 0x6a, 0x0c, 0x1a, 0x54, 0x64, 0x0f, - 0xc6, 0x6c, 0xb1, 0xe4, 0xca, 0x63, 0xbc, 0xde, 0x4b, 0x19, 0xeb, 0x1d, 0x5b, 0xb6, 0x95, 0xd2, - 0xf1, 0xd1, 0xec, 0x98, 0x04, 0xa2, 0x92, 0x40, 0x5e, 0x87, 0x82, 0xd7, 0x61, 0x55, 0xb5, 0x5b, - 0xe5, 0xc2, 0xf5, 0xdc, 0x6b, 0x85, 0xca, 0x94, 0xac, 0x5e, 0x61, 0x53, 0xc2, 0x51, 0x53, 0x90, - 0x1b, 0x30, 0x16, 0x74, 0x77, 0xd8, 0x68, 0x95, 0x8b, 0xbc, 0x2d, 0x93, 0x92, 0x78, 0xac, 0x2a, - 0xc0, 0xa8, 0xf0, 0xe4, 0x4d, 0x28, 0xf9, 0xb4, 0xd6, 0xf5, 0x03, 0xca, 0x86, 0xaf, 0x0c, 0x9c, - 0xf7, 0x79, 0x49, 0x5e, 0xc2, 0x08, 0x85, 0x26, 0x9d, 0xf5, 0x9f, 0x46, 0xa1, 0xa7, 0x5f, 0xc9, - 0x1b, 0x50, 0x92, 0xf5, 0xbd, 0xeb, 0x35, 0x02, 0x3e, 0xbd, 0x0a, 0x95, 0x49, 0xc6, 0x67, 0x21, - 0x02, 0xa3, 0x49, 0x43, 0x1e, 0xc0, 0x50, 0x70, 0x4b, 0xee, 0x22, 0xef, 0x65, 0xea, 0xbf, 0xea, - 0x2d, 0xbd, 0x04, 0x46, 0x8f, 0x8f, 0x66, 0x87, 0xaa, 0xb7, 0x70, 0x28, 0xb8, 0xc5, 0xf6, 0x8f, - 0x86, 0x13, 0x0e, 0xb4, 0x7f, 0xac, 0x3a, 0xa1, 0x66, 0xcd, 0xf7, 0x8f, 0x55, 0x27, 0x44, 0xc6, - 0x95, 0xed, 0x7e, 0xcd, 0x30, 0xec, 0xf0, 0xe9, 0x9d, 0x75, 0xf7, 0xbb, 0xbd, 0xbd, 0xbd, 0xa5, - 0xd9, 0xf3, 0xf5, 0xc3, 0x20, 0xc8, 0x19, 0x93, 0x2f, 0x59, 0x4f, 0x0a, 0x9c, 0xe7, 0x1f, 0xca, - 0x75, 0x71, 0x7b, 0xa0, 0x75, 0xe1, 0xf9, 0x87, 0x5a, 0x9c, 0x1c, 0x13, 0x8d, 0x40, 0x53, 0x1a, - 0x6f, 0x5d, 0x7d, 0x37, 0xe0, 0xcb, 0x20, 0x73, 0xeb, 0x96, 0x56, 0xaa, 0x89, 0xd6, 0x2d, 0xad, - 0x54, 0x91, 0x33, 0x66, 0x63, 0xe3, 0xdb, 0x07, 0x72, 0xd5, 0x64, 0x1b, 0x1b, 0xb4, 0x0f, 0xe2, - 0x63, 0x83, 0xf6, 0x01, 0x32, 0xae, 0x8c, 0xb9, 0x17, 0x04, 0x7c, 0x91, 0x64, 0x65, 0xbe, 0x59, - 0xad, 0xc6, 0x99, 0x6f, 0x56, 0xab, 0xc8, 0xb8, 0xf2, 0x59, 0x55, 0x0b, 0xf8, 0xa2, 0xca, 0x3c, - 0xab, 0x16, 0x13, 0xcc, 0x57, 0x17, 0xab, 0xc8, 0xb8, 0x5a, 0x9f, 0xc1, 0x45, 0x85, 0x41, 0xda, - 0xf1, 0x02, 0x87, 0x0f, 0x0d, 0xdd, 0x25, 0xf3, 0x50, 0xac, 0x79, 0xee, 0xae, 0xd3, 0x58, 0xb7, - 0x3b, 0x72, 0xd3, 0xd6, 0xbb, 0xfd, 0xa2, 0x42, 0x60, 0x44, 0x43, 0x5e, 0x82, 0xe1, 0x3d, 0x7a, - 0x28, 0x77, 0xef, 0x92, 0x24, 0x1d, 0xbe, 0x43, 0x0f, 0x91, 0xc1, 0x7f, 0xb5, 0xf0, 0xad, 0x7f, - 0x38, 0xfb, 0xc2, 0x57, 0xdf, 0xbb, 0xfe, 0x82, 0xf5, 0x87, 0x43, 0x70, 0x25, 0x55, 0x66, 0x35, - 0xb4, 0xc3, 0x6e, 0x40, 0xfe, 0x41, 0x0e, 0x2e, 0xda, 0x69, 0x78, 0xa9, 0x56, 0x7c, 0x30, 0xd0, - 0x94, 0x8c, 0x71, 0xac, 0xbc, 0x24, 0xeb, 0x99, 0xde, 0x09, 0x98, 0x5e, 0x0f, 0xd6, 0x37, 0xec, - 0xc4, 0x0a, 0x3a, 0x76, 0x8d, 0xca, 0x06, 0xeb, 0xbe, 0xd9, 0x50, 0x08, 0x8c, 0x68, 0xd8, 0xde, - 0x58, 0xa7, 0xbb, 0x76, 0xb7, 0x25, 0x36, 0x87, 0x42, 0xb4, 0x37, 0x2e, 0x09, 0x30, 0x2a, 0xbc, - 0xd1, 0x4f, 0x7f, 0x9c, 0x83, 0xf3, 0x29, 0x0b, 0x89, 0x75, 0x74, 0xd7, 0x6f, 0xc9, 0x31, 0xd1, - 0x1d, 0x7d, 0x0f, 0xef, 0x22, 0x83, 0x93, 0xdf, 0xca, 0xc1, 0xa4, 0xb1, 0xb2, 0x16, 0xba, 0xf2, - 0x48, 0xcd, 0x7e, 0x56, 0xc4, 0x78, 0x55, 0x2e, 0x4b, 0x89, 0x93, 0x09, 0x04, 0x26, 0xa5, 0x5a, - 0xff, 0x39, 0x07, 0x49, 0x22, 0x62, 0xc3, 0xb9, 0x6e, 0x40, 0x7d, 0xd6, 0x35, 0x55, 0x5a, 0xf3, - 0x69, 0x28, 0x07, 0xf5, 0x95, 0x39, 0xa1, 0xc9, 0xb2, 0x5a, 0xcc, 0x31, 0xbd, 0x7d, 0x6e, 0xff, - 0x8d, 0x39, 0x41, 0x71, 0x87, 0x1e, 0x56, 0x69, 0x8b, 0x32, 0x1e, 0x15, 0x72, 0x7c, 0x34, 0x7b, - 0xee, 0x5e, 0x8c, 0x01, 0x26, 0x18, 0x32, 0x11, 0x1d, 0x3b, 0x08, 0x0e, 0x3c, 0xbf, 0x2e, 0x45, - 0x0c, 0x9d, 0x5a, 0xc4, 0x56, 0x8c, 0x01, 0x26, 0x18, 0x5a, 0xff, 0x26, 0x07, 0x63, 0x15, 0xbb, - 0xb6, 0xe7, 0xed, 0xee, 0xb2, 0x53, 0xb2, 0xde, 0xf5, 0x85, 0x2e, 0x21, 0xc6, 0x44, 0x9f, 0x92, - 0x4b, 0x12, 0x8e, 0x9a, 0x82, 0x6c, 0xc3, 0xa8, 0xe8, 0x0e, 0x59, 0xa9, 0x5f, 0x36, 0x2a, 0xa5, - 0x35, 0x78, 0x3e, 0x1c, 0x4c, 0x83, 0x9f, 0x13, 0x1a, 0xfc, 0xdc, 0x9a, 0x1b, 0x6e, 0x32, 0xad, - 0xd8, 0x71, 0x1b, 0x15, 0x38, 0x3e, 0x9a, 0x1d, 0x5d, 0xe1, 0x3c, 0x50, 0xf2, 0x62, 0x07, 0x6a, - 0xdb, 0xfe, 0x5c, 0x89, 0xe3, 0x73, 0xac, 0x18, 0x1d, 0xa8, 0xeb, 0x11, 0x0a, 0x4d, 0x3a, 0xeb, - 0x13, 0xc8, 0x2f, 0xda, 0xb5, 0x26, 0x25, 0xf7, 0x92, 0x8b, 0xbd, 0x74, 0xf3, 0xb5, 0xb4, 0xde, - 0xd2, 0x0b, 0xdf, 0xec, 0xb0, 0x89, 0x7e, 0x5b, 0x82, 0xf5, 0xc3, 0x1c, 0x5c, 0x5e, 0x6c, 0x75, - 0x83, 0x90, 0xfa, 0x0f, 0xe4, 0xbc, 0xda, 0xa6, 0xed, 0x4e, 0xcb, 0x0e, 0x29, 0xf9, 0xf3, 0x50, - 0x60, 0xd6, 0x53, 0xdd, 0x0e, 0x6d, 0x29, 0xb1, 0x7f, 0x57, 0xf0, 0x99, 0xc9, 0xa8, 0x59, 0x1d, - 0x36, 0x77, 0x1e, 0xd1, 0x5a, 0xb8, 0x4e, 0x43, 0x3b, 0xd2, 0x96, 0x22, 0x18, 0x6a, 0xae, 0x64, - 0x0f, 0x46, 0x82, 0x0e, 0xad, 0xc9, 0x8e, 0x5e, 0xcb, 0x34, 0xf9, 0x93, 0xd5, 0xae, 0x76, 0x68, - 0x2d, 0x52, 0x2d, 0xd9, 0x17, 0x72, 0x21, 0xd6, 0xff, 0xc8, 0xc1, 0x95, 0x3e, 0x4d, 0xbd, 0xeb, - 0x04, 0x21, 0xf9, 0xb8, 0xa7, 0xb9, 0x73, 0x27, 0x6b, 0x2e, 0x2b, 0xcd, 0x1b, 0xab, 0x67, 0x95, - 0x82, 0x18, 0x4d, 0xfd, 0x0c, 0xf2, 0x4e, 0x48, 0xdb, 0x4a, 0xab, 0xbf, 0x9b, 0xa9, 0xad, 0x7d, - 0xaa, 0x5f, 0x99, 0x50, 0x56, 0xe1, 0x1a, 0x13, 0x81, 0x42, 0x92, 0xf5, 0xef, 0x73, 0xc0, 0x06, - 0xbd, 0xee, 0x48, 0x2d, 0x6c, 0x24, 0x3c, 0xec, 0x28, 0xed, 0x5e, 0xed, 0xaa, 0x23, 0xdb, 0x87, - 0x1d, 0x66, 0x46, 0x4e, 0x68, 0x42, 0x06, 0x40, 0x4e, 0x4a, 0x3e, 0x81, 0xd1, 0x80, 0x6f, 0xf8, - 0x72, 0x07, 0x5d, 0x91, 0x85, 0x46, 0xc5, 0x31, 0xf0, 0xf8, 0x68, 0xf6, 0x44, 0xb6, 0xf7, 0x9c, - 0xe6, 0x2d, 0xca, 0xa1, 0xe4, 0xca, 0xf6, 0xdc, 0x36, 0x0d, 0x02, 0xbb, 0x41, 0xe5, 0x7a, 0xd0, - 0x7b, 0xee, 0xba, 0x00, 0xa3, 0xc2, 0x5b, 0xbf, 0x0e, 0xb0, 0xe8, 0xb9, 0xa1, 0xe3, 0x76, 0xe9, - 0xa6, 0x4b, 0x5e, 0x86, 0x3c, 0xf5, 0x7d, 0xcf, 0x97, 0xba, 0xa4, 0x6e, 0xfe, 0x32, 0x03, 0xa2, - 0xc0, 0x91, 0x57, 0xd9, 0x3a, 0x76, 0x5a, 0xb4, 0xce, 0x6b, 0x5f, 0xa8, 0x9c, 0x53, 0xb5, 0x5f, - 0xe1, 0x50, 0x94, 0x58, 0x6b, 0x0e, 0xc6, 0x16, 0x99, 0xa9, 0x4d, 0x7d, 0xc6, 0xd7, 0x34, 0xb6, - 0x27, 0x62, 0xc6, 0xb6, 0x32, 0xaa, 0xb7, 0xe1, 0xe2, 0xa2, 0x4f, 0xd9, 0x4c, 0xbb, 0x55, 0xe9, - 0xd6, 0xf6, 0x68, 0x28, 0x34, 0xed, 0x80, 0xbc, 0x0d, 0x13, 0x1e, 0x9f, 0xe5, 0x77, 0xbd, 0xda, - 0x9e, 0xe3, 0x36, 0xe4, 0x41, 0x72, 0x51, 0x72, 0x99, 0xd8, 0x34, 0x91, 0x18, 0xa7, 0xb5, 0xfe, - 0x64, 0x08, 0xc6, 0x17, 0x7d, 0xcf, 0x55, 0x63, 0xfb, 0x1c, 0x56, 0x5f, 0x23, 0xb6, 0xfa, 0xb2, - 0x99, 0x57, 0x66, 0x95, 0xfb, 0xad, 0x3c, 0xe2, 0xe9, 0x79, 0x24, 0xf4, 0xee, 0xd5, 0xc1, 0x45, - 0x71, 0x76, 0xd1, 0x90, 0xc6, 0x27, 0x96, 0xf5, 0xdd, 0x1c, 0x4c, 0x99, 0xe4, 0xcf, 0x61, 0x7d, - 0xef, 0xc6, 0xd7, 0xf7, 0xc2, 0xc0, 0x4d, 0xec, 0xb3, 0xa8, 0xff, 0x4f, 0x3e, 0xde, 0x34, 0xd6, - 0xcd, 0xcc, 0x6a, 0x1e, 0x3f, 0x30, 0x00, 0xb2, 0x7d, 0x0b, 0x03, 0x6d, 0xa8, 0x7c, 0x38, 0x7f, - 0x51, 0x56, 0x62, 0xdc, 0x84, 0x3e, 0x4e, 0x7c, 0x63, 0x4c, 0x38, 0x3b, 0x6e, 0x83, 0x5a, 0x93, - 0xd6, 0xbb, 0x2d, 0xa5, 0x7a, 0xe9, 0x8e, 0xab, 0x4a, 0x38, 0x6a, 0x0a, 0xf2, 0x31, 0x4c, 0xd7, - 0x3c, 0xb7, 0xd6, 0xf5, 0x7d, 0xea, 0xd6, 0x0e, 0xb7, 0xb8, 0xaf, 0x4f, 0x6e, 0x07, 0x73, 0xb2, - 0xd8, 0xf4, 0x62, 0x92, 0xe0, 0x71, 0x1a, 0x10, 0x7b, 0x19, 0x09, 0x93, 0x37, 0xe8, 0x50, 0xb7, - 0xce, 0xad, 0xb2, 0x82, 0x69, 0xf2, 0x72, 0x30, 0x2a, 0x3c, 0xb9, 0x07, 0x97, 0x83, 0x90, 0x29, - 0x48, 0x6e, 0x63, 0x89, 0xda, 0xf5, 0x96, 0xe3, 0x32, 0x75, 0xc5, 0x73, 0xeb, 0x01, 0x37, 0xb4, - 0x86, 0x2b, 0x57, 0x8e, 0x8f, 0x66, 0x2f, 0x57, 0xd3, 0x49, 0xb0, 0x5f, 0x59, 0xf2, 0x09, 0xcc, - 0x04, 0xdd, 0x5a, 0x8d, 0x06, 0xc1, 0x6e, 0xb7, 0xf5, 0x81, 0xb7, 0x13, 0xdc, 0x76, 0x02, 0xa6, - 0x6b, 0xdd, 0x75, 0xda, 0x4e, 0xc8, 0x8d, 0xa9, 0x7c, 0xe5, 0xda, 0xf1, 0xd1, 0xec, 0x4c, 0xb5, - 0x2f, 0x15, 0x3e, 0x81, 0x03, 0x41, 0xb8, 0x24, 0x36, 0xb2, 0x1e, 0xde, 0x63, 0x9c, 0xf7, 0xcc, - 0xf1, 0xd1, 0xec, 0xa5, 0x95, 0x54, 0x0a, 0xec, 0x53, 0x92, 0x8d, 0x60, 0xe8, 0xb4, 0xe9, 0x17, - 0x9e, 0x4b, 0xb9, 0xc5, 0x64, 0x8c, 0xe0, 0xb6, 0x84, 0xa3, 0xa6, 0x20, 0x8f, 0xa2, 0xc9, 0xc7, - 0x16, 0x85, 0x34, 0x83, 0x4e, 0xbf, 0x5b, 0x5d, 0x38, 0x3e, 0x9a, 0x9d, 0x7a, 0x60, 0x70, 0x62, - 0x0b, 0x0b, 0x63, 0xbc, 0xad, 0x7f, 0x37, 0x04, 0xa4, 0x77, 0x23, 0x20, 0x77, 0x60, 0xd4, 0xae, - 0x85, 0xce, 0x3e, 0x95, 0x7e, 0xba, 0x97, 0xd3, 0x54, 0x23, 0x21, 0x0a, 0xe9, 0x2e, 0x65, 0x33, - 0x84, 0x46, 0xbb, 0xc7, 0x02, 0x2f, 0x8a, 0x92, 0x05, 0xf1, 0x60, 0xba, 0x65, 0x07, 0xa1, 0x9a, - 0xab, 0x75, 0xd6, 0x64, 0xb9, 0x49, 0xfe, 0xa9, 0x93, 0x35, 0x8a, 0x95, 0xa8, 0x5c, 0x64, 0x33, - 0xf7, 0x6e, 0x92, 0x11, 0xf6, 0xf2, 0x26, 0x3e, 0x40, 0x4d, 0x1d, 0x91, 0x6c, 0x8f, 0xcc, 0xee, - 0x69, 0xd4, 0x27, 0x6d, 0xb4, 0xf5, 0x6b, 0x50, 0x80, 0x86, 0x14, 0xeb, 0xc7, 0xa3, 0x30, 0xb6, - 0xb4, 0xb0, 0xba, 0x6d, 0x07, 0x7b, 0x27, 0x70, 0xfc, 0xb1, 0x09, 0x21, 0x95, 0x8d, 0xe4, 0x92, - 0x56, 0x4a, 0x08, 0x6a, 0x0a, 0xe2, 0x41, 0xd1, 0x56, 0x6e, 0x54, 0xb9, 0xe5, 0xbf, 0x9b, 0xd1, - 0xb0, 0x91, 0x5c, 0x4c, 0x37, 0xa6, 0x04, 0x61, 0x24, 0x83, 0x04, 0x50, 0x52, 0xc2, 0x99, 0x11, - 0x3a, 0x32, 0x88, 0x6f, 0x3b, 0xe2, 0x23, 0xfc, 0x21, 0x06, 0x00, 0x4d, 0x29, 0xe4, 0x1b, 0x30, - 0x5e, 0xa7, 0x6c, 0xe7, 0xa0, 0x6e, 0xcd, 0xa1, 0x6c, 0x93, 0x18, 0x66, 0xfd, 0xc2, 0x36, 0xcb, - 0x25, 0x03, 0x8e, 0x31, 0x2a, 0xf2, 0x08, 0x8a, 0x07, 0x4e, 0xd8, 0xe4, 0x7b, 0x7a, 0x79, 0x94, - 0x0f, 0xf5, 0xaf, 0x64, 0xaa, 0x28, 0xe3, 0x10, 0x75, 0xcb, 0x03, 0xc5, 0x13, 0x23, 0xf6, 0xcc, - 0x08, 0x66, 0x1f, 0xdc, 0xd7, 0xcc, 0x77, 0x83, 0x62, 0xbc, 0x00, 0x47, 0x60, 0x44, 0x43, 0x02, - 0x18, 0x67, 0x1f, 0x55, 0xfa, 0x59, 0x97, 0xad, 0x10, 0xe9, 0x2d, 0xc9, 0xe6, 0x81, 0x56, 0x4c, - 0x44, 0x8f, 0x3c, 0x30, 0xd8, 0x62, 0x4c, 0x08, 0x9b, 0x7d, 0x07, 0x4d, 0xea, 0x4a, 0x97, 0xa4, - 0x9e, 0x7d, 0x0f, 0x9a, 0xd4, 0x45, 0x8e, 0x21, 0x1e, 0x5f, 0x1f, 0x52, 0xf9, 0xe3, 0xbe, 0xc8, - 0xac, 0x5e, 0xc1, 0x48, 0x87, 0xac, 0x9c, 0x93, 0x8b, 0x43, 0x7e, 0xa3, 0x21, 0x82, 0xa9, 0x8e, - 0x9e, 0xbb, 0xfc, 0xb9, 0x13, 0x96, 0x4b, 0xbc, 0x52, 0x7a, 0xa7, 0xd8, 0xe4, 0x50, 0x94, 0x58, - 0xe1, 0x34, 0x60, 0x83, 0x1b, 0x94, 0xc7, 0xe3, 0x0a, 0xac, 0x98, 0x01, 0x01, 0x2a, 0xbc, 0xf5, - 0xaf, 0x73, 0x50, 0x62, 0xeb, 0x4d, 0xad, 0x91, 0x57, 0x61, 0x34, 0xb4, 0xfd, 0x86, 0xb4, 0xae, - 0x0d, 0x11, 0xdb, 0x1c, 0x8a, 0x12, 0x4b, 0x6c, 0xc8, 0x87, 0x76, 0xb0, 0xa7, 0xf4, 0x8a, 0x5f, - 0xcb, 0xd4, 0x6c, 0xb9, 0xd0, 0x23, 0x95, 0x82, 0x7d, 0x05, 0x28, 0x38, 0x93, 0xd7, 0xa0, 0xc0, - 0xce, 0x81, 0x15, 0x3b, 0x50, 0xbe, 0x8f, 0x71, 0xb6, 0xb0, 0x57, 0x24, 0x0c, 0x35, 0xd6, 0x7a, - 0x13, 0xf2, 0xcb, 0xfb, 0xd4, 0xe5, 0x07, 0x44, 0x20, 0x8d, 0xcb, 0xa4, 0x45, 0xad, 0x8c, 0x4e, - 0xd4, 0x14, 0xd6, 0xc7, 0x70, 0x6e, 0xf9, 0x73, 0x5a, 0xeb, 0x86, 0x9e, 0x2f, 0x8c, 0x50, 0xf2, - 0x01, 0x90, 0x80, 0xfa, 0xfb, 0x4e, 0x8d, 0x2e, 0xd4, 0x6a, 0x4c, 0xf9, 0xde, 0x88, 0xf6, 0x9f, - 0x19, 0xc9, 0x89, 0x54, 0x7b, 0x28, 0x30, 0xa5, 0x94, 0xf5, 0xf7, 0x72, 0x50, 0x32, 0xbc, 0x67, - 0x6c, 0xf7, 0x69, 0x2c, 0x56, 0x85, 0x6a, 0x2e, 0x15, 0xa1, 0x77, 0xb3, 0xba, 0xe4, 0x04, 0x97, - 0x68, 0xd5, 0x68, 0x10, 0x46, 0x32, 0x9e, 0xe2, 0x56, 0xb3, 0xfe, 0x65, 0x0e, 0xa2, 0x72, 0x6c, - 0xdc, 0x77, 0xa2, 0xaa, 0x19, 0xe3, 0x2e, 0xf9, 0x4a, 0x2c, 0xf9, 0x2a, 0x07, 0x97, 0xe3, 0x8d, - 0xe5, 0x06, 0xfd, 0xe9, 0x9d, 0x25, 0xb3, 0x52, 0xc0, 0xe5, 0x6a, 0x3a, 0x37, 0xec, 0x27, 0xc6, - 0xba, 0x0f, 0xf9, 0x55, 0xbb, 0xdb, 0xa0, 0x27, 0x32, 0x8b, 0xd8, 0x2c, 0xf2, 0xa9, 0xdd, 0x0a, - 0xd5, 0x61, 0x29, 0x67, 0x11, 0x4a, 0x18, 0x6a, 0xac, 0xf5, 0x47, 0x23, 0x50, 0x32, 0x9c, 0xe8, - 0x6c, 0x03, 0xf0, 0x69, 0xc7, 0x4b, 0x1e, 0x3f, 0x48, 0x3b, 0x1e, 0x72, 0x0c, 0x9b, 0x6e, 0x3e, - 0xdd, 0x77, 0x02, 0xc7, 0x73, 0x93, 0xc7, 0x0f, 0x4a, 0x38, 0x6a, 0x0a, 0x32, 0x0b, 0xf9, 0x3a, - 0xed, 0x84, 0x4d, 0x3e, 0x99, 0x47, 0x2a, 0x45, 0x56, 0xd5, 0x25, 0x06, 0x40, 0x01, 0x67, 0x04, - 0xbb, 0x34, 0xac, 0x35, 0xcb, 0x23, 0x7c, 0xcb, 0xe6, 0x04, 0x2b, 0x0c, 0x80, 0x02, 0x9e, 0xe2, - 0x02, 0xcb, 0x3f, 0x7b, 0x17, 0xd8, 0xe8, 0x19, 0xbb, 0xc0, 0x48, 0x07, 0xce, 0x07, 0x41, 0x73, - 0xcb, 0x77, 0xf6, 0xed, 0x90, 0x46, 0xb3, 0x67, 0xec, 0x34, 0x72, 0x2e, 0x1f, 0x1f, 0xcd, 0x9e, - 0xaf, 0x56, 0x6f, 0x27, 0xb9, 0x60, 0x1a, 0x6b, 0x52, 0x85, 0x8b, 0x8e, 0x1b, 0xd0, 0x5a, 0xd7, - 0xa7, 0x6b, 0x0d, 0xd7, 0xf3, 0xe9, 0x6d, 0x2f, 0x60, 0xec, 0x64, 0x6c, 0x4a, 0xbb, 0x72, 0xd7, - 0xd2, 0x88, 0x30, 0xbd, 0xac, 0xf5, 0x27, 0x39, 0x18, 0x37, 0xe3, 0x06, 0x24, 0x00, 0x68, 0x2e, - 0xad, 0x54, 0xc5, 0x56, 0x22, 0x57, 0xf8, 0x7b, 0x99, 0xc3, 0x11, 0x82, 0x4d, 0xa4, 0x2f, 0x45, - 0x30, 0x34, 0xc4, 0x9c, 0x20, 0xf4, 0xf9, 0x32, 0xe4, 0x77, 0x3d, 0xbf, 0x46, 0xe5, 0x1e, 0xaa, - 0x57, 0xc9, 0x0a, 0x03, 0xa2, 0xc0, 0x59, 0x3f, 0xcc, 0x81, 0x21, 0x81, 0xfc, 0x25, 0x98, 0x60, - 0x32, 0xee, 0xf8, 0x3b, 0xb1, 0xd6, 0x54, 0x32, 0xb7, 0x46, 0x73, 0x8a, 0xdc, 0x0e, 0x31, 0x30, - 0xc6, 0xe5, 0x91, 0x3f, 0x0d, 0x45, 0xbb, 0x5e, 0xf7, 0x69, 0x10, 0x50, 0x71, 0xc4, 0x14, 0x85, - 0xb3, 0x70, 0x41, 0x01, 0x31, 0xc2, 0xb3, 0x65, 0xd8, 0xac, 0xef, 0x06, 0x6c, 0x66, 0x4b, 0x0b, - 0x4d, 0x2f, 0x43, 0x26, 0x84, 0xc1, 0x51, 0x53, 0x58, 0xbf, 0x37, 0x02, 0x71, 0xd9, 0xa4, 0x0e, - 0x93, 0x7b, 0xfe, 0xce, 0x22, 0x77, 0x68, 0x66, 0x71, 0x2d, 0x9f, 0x3f, 0x3e, 0x9a, 0x9d, 0xbc, - 0x13, 0xe7, 0x80, 0x49, 0x96, 0x52, 0xca, 0x1d, 0x7a, 0x18, 0xda, 0x3b, 0x59, 0x36, 0x4c, 0x25, - 0xc5, 0xe4, 0x80, 0x49, 0x96, 0xe4, 0x4d, 0x28, 0xed, 0xf9, 0x3b, 0x6a, 0x91, 0x27, 0xfd, 0xb9, - 0x77, 0x22, 0x14, 0x9a, 0x74, 0xac, 0x0b, 0xf7, 0xfc, 0x1d, 0xb6, 0x29, 0xaa, 0x28, 0xb8, 0xee, - 0xc2, 0x3b, 0x12, 0x8e, 0x9a, 0x82, 0x74, 0x80, 0xec, 0xa9, 0xde, 0xd3, 0xee, 0x5b, 0xb9, 0x17, - 0x9d, 0xdc, 0xfb, 0x7b, 0x89, 0x1d, 0xa6, 0x77, 0x7a, 0xf8, 0x60, 0x0a, 0x6f, 0xf2, 0xeb, 0x70, - 0x79, 0xcf, 0xdf, 0x91, 0x47, 0xc5, 0x96, 0xef, 0xb8, 0x35, 0xa7, 0x13, 0x0b, 0x7f, 0xeb, 0xe3, - 0xe4, 0x4e, 0x3a, 0x19, 0xf6, 0x2b, 0x6f, 0xfd, 0x3e, 0x5b, 0xc7, 0x46, 0x74, 0xf3, 0x69, 0x51, - 0x92, 0x5d, 0x18, 0x6b, 0x52, 0xbb, 0x4e, 0x7d, 0xa5, 0xfb, 0xbc, 0x9d, 0x6d, 0x55, 0x70, 0x1e, - 0x91, 0x66, 0x26, 0xbe, 0x03, 0x54, 0xcc, 0xad, 0x4d, 0x18, 0x15, 0xb0, 0x13, 0xd8, 0x41, 0xfa, - 0x24, 0x1c, 0x7a, 0x82, 0x83, 0xf0, 0x5b, 0x39, 0x28, 0x72, 0x73, 0xba, 0xc1, 0x74, 0x6a, 0x5d, - 0x64, 0xf8, 0x09, 0x87, 0xe7, 0x2e, 0x8c, 0x89, 0x73, 0x3f, 0xe0, 0x67, 0x52, 0xd6, 0xb6, 0x8a, - 0x9c, 0xa1, 0xa8, 0xad, 0x42, 0xa7, 0x08, 0x50, 0x31, 0xb7, 0xfe, 0x7b, 0x0e, 0x46, 0xd7, 0xdc, - 0x4e, 0xf7, 0x67, 0x24, 0xbd, 0x65, 0x1d, 0x46, 0x98, 0x25, 0x14, 0x4f, 0xa2, 0x1a, 0xaf, 0xbc, - 0x62, 0x26, 0x50, 0x95, 0xe3, 0x09, 0x54, 0x68, 0x1f, 0x28, 0xe7, 0xb3, 0x28, 0x63, 0x84, 0xfb, - 0x5a, 0x30, 0x72, 0xd7, 0x71, 0xf7, 0x4e, 0x36, 0x4f, 0x82, 0x9a, 0xd7, 0xe9, 0x99, 0x27, 0x55, - 0x06, 0x44, 0x81, 0x53, 0xf3, 0x7f, 0x38, 0x7d, 0xfe, 0x5b, 0xdf, 0xcc, 0xc1, 0xf4, 0x3a, 0x6d, - 0x7b, 0xce, 0x17, 0x76, 0xe4, 0x3b, 0x67, 0x85, 0x9a, 0x4e, 0x28, 0x1d, 0xdf, 0xba, 0xd0, 0x6d, - 0x27, 0x44, 0x06, 0x7f, 0x8a, 0x2e, 0xca, 0x43, 0xc6, 0x6c, 0xab, 0xdc, 0x88, 0xf6, 0xac, 0x28, - 0x64, 0xac, 0x10, 0x18, 0xd1, 0x58, 0xff, 0x34, 0x07, 0x63, 0xa2, 0x12, 0x54, 0xf1, 0xce, 0xf5, - 0xe1, 0xfd, 0x10, 0xf2, 0xbc, 0x9c, 0xdc, 0x6d, 0x7f, 0x35, 0x9b, 0x81, 0xc6, 0x38, 0x08, 0x8d, - 0x8c, 0xff, 0x44, 0xc1, 0x93, 0xa9, 0xcd, 0x6d, 0xfb, 0xf3, 0x05, 0x1d, 0x29, 0xd0, 0x6a, 0xf3, - 0x3a, 0x87, 0xa2, 0xc4, 0x5a, 0x5f, 0x0d, 0x43, 0x41, 0xb9, 0x8e, 0xc8, 0x6f, 0xe6, 0xa0, 0x64, - 0xbb, 0xae, 0x17, 0xda, 0xc2, 0xb3, 0x22, 0x26, 0xf9, 0x46, 0xa6, 0x8a, 0x29, 0xa6, 0x73, 0x0b, - 0x11, 0xc3, 0x65, 0x37, 0xf4, 0x0f, 0xa3, 0x4d, 0xdf, 0xc0, 0xa0, 0x29, 0x97, 0x7c, 0x06, 0xa3, - 0x2d, 0x7b, 0x87, 0xb6, 0xd4, 0x9c, 0x5f, 0x1b, 0xac, 0x06, 0x77, 0x39, 0x2f, 0x21, 0x5c, 0xf7, - 0x83, 0x00, 0xa2, 0x14, 0x34, 0xf3, 0x2e, 0x4c, 0x25, 0x2b, 0x4a, 0xa6, 0x8c, 0xf1, 0x13, 0x43, - 0x76, 0x21, 0xb6, 0x9d, 0xa9, 0x09, 0x3f, 0xf4, 0x56, 0x6e, 0xe6, 0x57, 0xa0, 0x64, 0x88, 0x39, - 0x4d, 0x51, 0xeb, 0x43, 0x28, 0xad, 0xd3, 0xd0, 0x77, 0x6a, 0x9c, 0xc1, 0xd3, 0x66, 0xcd, 0x89, - 0x76, 0xd4, 0x2f, 0xd8, 0x24, 0x64, 0x2c, 0x03, 0xe2, 0x01, 0x74, 0x7c, 0xaf, 0x4d, 0xc3, 0x26, - 0xed, 0xaa, 0x11, 0xcd, 0xa6, 0xfc, 0x6d, 0x69, 0x36, 0xc2, 0x17, 0x10, 0x7d, 0xa3, 0x21, 0xc2, - 0xba, 0x01, 0xf9, 0xf5, 0x6e, 0x48, 0x3f, 0x7f, 0xfa, 0xaa, 0xb7, 0x1e, 0xc2, 0x38, 0x27, 0xbd, - 0xed, 0xb5, 0xd8, 0x86, 0xc2, 0xda, 0xd6, 0x66, 0xdf, 0x49, 0xbb, 0x89, 0x13, 0xa1, 0xc0, 0xb1, - 0x99, 0xdd, 0xf4, 0x5a, 0x75, 0xea, 0xcb, 0x1e, 0xd0, 0x23, 0x7a, 0x9b, 0x43, 0x51, 0x62, 0xad, - 0x1f, 0xe5, 0xa0, 0xc4, 0x0b, 0xca, 0x8d, 0xa0, 0x05, 0x63, 0x4d, 0x21, 0x47, 0xf6, 0x42, 0x36, - 0x6f, 0xbf, 0x59, 0x61, 0xe3, 0x90, 0x14, 0x00, 0x54, 0x22, 0x98, 0xb4, 0x03, 0xdb, 0x09, 0x99, - 0xb4, 0xa1, 0x33, 0x97, 0xf6, 0x40, 0x70, 0x46, 0x25, 0xc2, 0xfa, 0x67, 0x53, 0x00, 0x1b, 0x5e, - 0x9d, 0xca, 0xa6, 0xce, 0xc0, 0x90, 0x53, 0x97, 0x9d, 0x08, 0xb2, 0xd0, 0xd0, 0xda, 0x12, 0x0e, - 0x39, 0x75, 0x3d, 0x2a, 0x43, 0x7d, 0xf7, 0xe2, 0x37, 0xa1, 0x54, 0x77, 0x82, 0x4e, 0xcb, 0x3e, - 0xdc, 0x48, 0xd1, 0xd4, 0x96, 0x22, 0x14, 0x9a, 0x74, 0xe4, 0x75, 0x19, 0x2f, 0x15, 0x5a, 0x5a, - 0x39, 0x11, 0x2f, 0x2d, 0xb0, 0xea, 0x19, 0xa1, 0xd2, 0xb7, 0x60, 0x5c, 0xf9, 0x06, 0xb9, 0x94, - 0x3c, 0x2f, 0x75, 0x41, 0x45, 0x4f, 0xb6, 0x0d, 0x1c, 0xc6, 0x28, 0x93, 0xbe, 0xcb, 0xd1, 0xe7, - 0xe2, 0xbb, 0x5c, 0x82, 0xa9, 0x20, 0xf4, 0x7c, 0x5a, 0x57, 0x14, 0x6b, 0x4b, 0x65, 0x12, 0x6b, - 0xe8, 0x54, 0x35, 0x81, 0xc7, 0x9e, 0x12, 0x64, 0x0b, 0x2e, 0x1c, 0x24, 0x42, 0xd1, 0xbc, 0xf1, - 0xe7, 0x39, 0xa7, 0xab, 0x92, 0xd3, 0x85, 0x07, 0x29, 0x34, 0x98, 0x5a, 0x92, 0xbc, 0x0d, 0x13, - 0xaa, 0x9a, 0xfc, 0xa8, 0x2c, 0x5f, 0xe0, 0xac, 0xb4, 0x2d, 0xb3, 0x6d, 0x22, 0x31, 0x4e, 0x4b, - 0x7e, 0x19, 0xf2, 0x9d, 0xa6, 0x1d, 0x50, 0xe9, 0xea, 0x54, 0x7e, 0xa4, 0xfc, 0x16, 0x03, 0x3e, - 0x3e, 0x9a, 0x2d, 0xb2, 0x31, 0xe3, 0x1f, 0x28, 0x08, 0xc9, 0x4d, 0x80, 0x1d, 0xaf, 0xeb, 0xd6, - 0x6d, 0xff, 0x70, 0x6d, 0x49, 0x46, 0x3a, 0xb4, 0x0e, 0x53, 0xd1, 0x18, 0x34, 0xa8, 0xcc, 0xa0, - 0x75, 0xf1, 0xc9, 0x41, 0x6b, 0xf2, 0x10, 0x8a, 0x3c, 0x2a, 0x44, 0xeb, 0x0b, 0xa1, 0x74, 0x5b, - 0x9e, 0x26, 0x80, 0xa0, 0x4f, 0xe6, 0xaa, 0x62, 0x82, 0x11, 0x3f, 0xf2, 0x09, 0xc0, 0xae, 0xe3, - 0x3a, 0x41, 0x93, 0x73, 0x2f, 0x9d, 0x9a, 0xbb, 0x6e, 0xe7, 0x8a, 0xe6, 0x82, 0x06, 0x47, 0xf2, - 0x31, 0x4c, 0xd3, 0x20, 0x74, 0xda, 0x76, 0x48, 0xeb, 0x3a, 0x6d, 0xa5, 0xcc, 0x03, 0x61, 0x3a, - 0x2e, 0xb7, 0x9c, 0x24, 0x78, 0x9c, 0x06, 0xc4, 0x5e, 0x46, 0xe4, 0x2d, 0x28, 0x74, 0x7c, 0xaf, - 0xc1, 0x0c, 0xcb, 0xf2, 0x4c, 0x6c, 0xba, 0x14, 0xb6, 0x24, 0xfc, 0xb1, 0xf1, 0x1b, 0x35, 0x35, - 0xf9, 0x6f, 0x39, 0x98, 0xf6, 0x69, 0xe0, 0x75, 0xfd, 0x1a, 0x0d, 0x74, 0xc5, 0x2e, 0xf2, 0x4d, - 0xe9, 0x7e, 0xc6, 0x84, 0x73, 0xb5, 0xd3, 0xcc, 0x61, 0x92, 0xb1, 0x38, 0x65, 0xa9, 0x6a, 0x70, - 0x0f, 0xfe, 0x71, 0x1a, 0xf0, 0x9b, 0xdf, 0x9f, 0x9d, 0xed, 0xbd, 0xe3, 0xa0, 0x99, 0xb3, 0x99, - 0xfe, 0xd7, 0xbe, 0x3f, 0x3b, 0xa5, 0xbe, 0xa3, 0x7e, 0xea, 0x69, 0x17, 0x3b, 0x42, 0x3a, 0x5e, - 0x7d, 0x6d, 0x4b, 0xfa, 0x97, 0xf5, 0x11, 0xb2, 0xc5, 0x80, 0x28, 0x70, 0xe4, 0x35, 0x28, 0xd4, - 0x6d, 0xda, 0xf6, 0x5c, 0x5a, 0x2f, 0x4f, 0x44, 0xae, 0xb7, 0x25, 0x09, 0x43, 0x8d, 0x25, 0x9f, - 0xc2, 0xa8, 0xc3, 0xd5, 0xff, 0xf2, 0x39, 0x3e, 0x61, 0xb2, 0x99, 0x19, 0xc2, 0x82, 0x10, 0x69, - 0x4e, 0xe2, 0x37, 0x4a, 0xb6, 0xa4, 0x06, 0x63, 0x5e, 0x37, 0xe4, 0x12, 0x26, 0xb9, 0x84, 0x6c, - 0x0e, 0xeb, 0x4d, 0xc1, 0x43, 0x64, 0x3d, 0xcb, 0x0f, 0x54, 0x9c, 0x59, 0x7b, 0x6b, 0x4d, 0xa7, - 0x55, 0xf7, 0xa9, 0x5b, 0x9e, 0xe2, 0x3e, 0x0b, 0xde, 0xde, 0x45, 0x09, 0x43, 0x8d, 0x25, 0x7f, - 0x16, 0x26, 0xbc, 0x6e, 0xc8, 0x57, 0x2f, 0x1b, 0xe5, 0xa0, 0x3c, 0xcd, 0xc9, 0xa7, 0x79, 0x3a, - 0x86, 0x89, 0xc0, 0x38, 0x1d, 0xdb, 0xcf, 0x9b, 0x5e, 0x10, 0xb2, 0x0f, 0xbe, 0xa5, 0x5d, 0x8a, - 0xef, 0xe7, 0xb7, 0x0d, 0x1c, 0xc6, 0x28, 0xc9, 0xef, 0xe4, 0x60, 0xba, 0x9d, 0x54, 0xdb, 0xcb, - 0x97, 0x79, 0x67, 0xac, 0x64, 0x54, 0xfc, 0x12, 0xdc, 0x44, 0x68, 0xb1, 0x07, 0x8c, 0xbd, 0x72, - 0x79, 0xa6, 0x66, 0x70, 0xe8, 0xd6, 0x9a, 0xbe, 0xe7, 0xc6, 0x6b, 0xf4, 0x22, 0xaf, 0xd1, 0x46, - 0xf6, 0x15, 0x93, 0xc6, 0xb5, 0xf2, 0xe2, 0xf1, 0xd1, 0xec, 0xc5, 0x54, 0x14, 0xa6, 0xd7, 0x63, - 0x66, 0x09, 0x2e, 0xa5, 0xaf, 0xba, 0xa7, 0x29, 0x9d, 0xc3, 0xa6, 0xd2, 0xb9, 0x02, 0x2f, 0xf6, - 0xad, 0x14, 0xdb, 0xb2, 0x95, 0xf2, 0x92, 0x8b, 0x6f, 0xd9, 0x3d, 0x9a, 0xc7, 0x39, 0x18, 0x37, - 0xef, 0x9f, 0xf0, 0xe0, 0x82, 0x91, 0xf7, 0x4b, 0x3c, 0x28, 0x7a, 0xd5, 0xb3, 0x08, 0x2e, 0x6c, - 0x56, 0x7b, 0x82, 0x0b, 0x1a, 0x84, 0x91, 0x8c, 0xa7, 0x05, 0x17, 0xfe, 0xc5, 0x10, 0x44, 0xe5, - 0xc8, 0xeb, 0x50, 0xa0, 0x6e, 0xbd, 0xe3, 0x39, 0x6e, 0x98, 0x0c, 0xcb, 0x2c, 0x4b, 0x38, 0x6a, - 0x0a, 0x23, 0x14, 0x31, 0xf4, 0xc4, 0x50, 0x44, 0x13, 0x26, 0x6d, 0x9e, 0x7e, 0x10, 0xf9, 0x90, - 0x87, 0x4f, 0xe5, 0x43, 0xd6, 0xe9, 0xa8, 0x71, 0x2e, 0x98, 0x64, 0xcb, 0x24, 0x05, 0x51, 0x71, - 0x2e, 0x69, 0x24, 0x93, 0xa4, 0x6a, 0x9c, 0x0b, 0x26, 0xd9, 0x5a, 0xff, 0x6a, 0x08, 0xd4, 0xbe, - 0xf2, 0xb3, 0xe0, 0x09, 0x21, 0x16, 0x8c, 0xfa, 0x34, 0x50, 0xd9, 0xcd, 0x45, 0xb1, 0x77, 0x23, - 0x87, 0xa0, 0xc4, 0xb0, 0x6d, 0x95, 0x7e, 0xee, 0x84, 0x8b, 0x5e, 0x5d, 0x69, 0xbd, 0x7c, 0x5b, - 0x5d, 0x96, 0x30, 0xd4, 0x58, 0xeb, 0x00, 0x26, 0x58, 0xbb, 0x5a, 0x2d, 0xda, 0xaa, 0x86, 0xb4, - 0x13, 0x90, 0x5d, 0xc8, 0x07, 0xec, 0xc7, 0x40, 0xa6, 0x48, 0x94, 0xd3, 0x41, 0x3b, 0x86, 0xcb, - 0x84, 0xf1, 0x45, 0xc1, 0xde, 0xfa, 0x2f, 0x43, 0x50, 0xd4, 0x3d, 0x7a, 0x02, 0x3f, 0xcc, 0xcd, - 0x28, 0xab, 0x5b, 0xcc, 0xf1, 0xb2, 0x91, 0xd1, 0xcd, 0x54, 0xc2, 0x05, 0xf7, 0x50, 0x24, 0xed, - 0xea, 0xf4, 0x6e, 0xf2, 0x7a, 0xdc, 0x61, 0x77, 0xc9, 0x74, 0x16, 0x19, 0xf4, 0xd2, 0x73, 0xb7, - 0x07, 0x45, 0xfe, 0x63, 0x45, 0xdd, 0x6b, 0xca, 0x3a, 0x77, 0xee, 0x2b, 0x2e, 0xc2, 0x01, 0xaf, - 0x3f, 0x31, 0xe2, 0x9f, 0xb8, 0x8f, 0x94, 0x3f, 0xd1, 0x7d, 0xa4, 0x1b, 0x30, 0x42, 0xdd, 0x6e, - 0x9b, 0xe7, 0x1a, 0x14, 0xf9, 0xc9, 0x31, 0xb2, 0xec, 0x76, 0xdb, 0xf1, 0xc6, 0x70, 0x12, 0x6b, - 0x05, 0x98, 0x5e, 0xb1, 0xba, 0x48, 0xde, 0x81, 0x42, 0x20, 0x77, 0x40, 0xd9, 0xb9, 0xbf, 0xa0, - 0xc3, 0xbb, 0x12, 0xfe, 0xf8, 0x68, 0x76, 0x82, 0x13, 0x2b, 0x00, 0xea, 0x22, 0xd6, 0x6f, 0x8d, - 0x80, 0x61, 0x4d, 0x9f, 0x60, 0x98, 0xea, 0x09, 0x07, 0xc9, 0xfb, 0x59, 0x1d, 0x24, 0xca, 0xeb, - 0x20, 0xe6, 0x77, 0xdc, 0x27, 0xc2, 0xea, 0xd1, 0xa4, 0xad, 0x8e, 0x1c, 0x57, 0x5d, 0x8f, 0xdb, - 0xb4, 0xd5, 0x41, 0x8e, 0xd1, 0xa9, 0x08, 0x23, 0x7d, 0x53, 0x11, 0x1e, 0x42, 0xbe, 0x61, 0x77, - 0x1b, 0x54, 0x3a, 0xe1, 0xb3, 0x39, 0xb9, 0x78, 0x54, 0x55, 0x38, 0xb9, 0xf8, 0x4f, 0x14, 0x3c, - 0xd9, 0x5c, 0x6a, 0x2a, 0xbf, 0xb1, 0x34, 0x04, 0xb3, 0xcd, 0x25, 0xed, 0x7d, 0x16, 0x73, 0x49, - 0x7f, 0x62, 0xc4, 0x9f, 0x69, 0x6a, 0x35, 0x91, 0xf6, 0x2a, 0x23, 0x82, 0xbf, 0x96, 0x31, 0xa3, - 0x82, 0xf3, 0x10, 0x9a, 0x9a, 0xfc, 0x40, 0xc5, 0xd9, 0x9a, 0x87, 0x92, 0x71, 0x25, 0x87, 0xf5, - 0xaf, 0x4e, 0xbf, 0x34, 0xfa, 0x77, 0xc9, 0x0e, 0x6d, 0xe4, 0x18, 0xeb, 0x0f, 0x86, 0x41, 0xeb, - 0xc5, 0x66, 0xae, 0x84, 0x5d, 0x33, 0xb2, 0xf7, 0x63, 0x89, 0x5b, 0x9e, 0x8b, 0x12, 0xcb, 0xac, - 0xc7, 0x36, 0xf5, 0x1b, 0xfa, 0xf4, 0x96, 0x6b, 0x5e, 0x5b, 0x8f, 0xeb, 0x26, 0x12, 0xe3, 0xb4, - 0xec, 0xec, 0x6c, 0xdb, 0xae, 0xb3, 0x4b, 0x83, 0x30, 0x19, 0xdc, 0x5a, 0x97, 0x70, 0xd4, 0x14, - 0x64, 0x15, 0xa6, 0x03, 0x1a, 0x6e, 0x1e, 0xb8, 0xd4, 0xd7, 0x09, 0x65, 0x32, 0xc3, 0xf0, 0x45, - 0x65, 0x2c, 0x54, 0x93, 0x04, 0xd8, 0x5b, 0x86, 0x5b, 0xe2, 0x22, 0xb9, 0x4f, 0x27, 0x6a, 0xc9, - 0x85, 0x1d, 0x59, 0xe2, 0x09, 0x3c, 0xf6, 0x94, 0x60, 0x5c, 0x76, 0x6d, 0xa7, 0xd5, 0xf5, 0x69, - 0xc4, 0x65, 0x34, 0xce, 0x65, 0x25, 0x81, 0xc7, 0x9e, 0x12, 0x3c, 0x2e, 0xde, 0xb2, 0x1b, 0x41, - 0x79, 0xcc, 0x88, 0x8b, 0x33, 0x00, 0x0a, 0xb8, 0xf5, 0xf7, 0x73, 0x30, 0x81, 0x34, 0xf4, 0x0f, - 0x17, 0x76, 0x99, 0xa5, 0x18, 0x1e, 0x92, 0xdf, 0xcd, 0xc1, 0x94, 0xeb, 0xd5, 0xe9, 0x82, 0x1b, - 0x3a, 0x0a, 0x38, 0xd0, 0x25, 0x20, 0xce, 0x7e, 0x23, 0xc1, 0x51, 0xa4, 0x06, 0x26, 0xa1, 0xd8, - 0x23, 0xd9, 0xba, 0x0c, 0x17, 0x53, 0x19, 0x58, 0x7f, 0x65, 0x58, 0xd6, 0x5c, 0x8f, 0xf7, 0x87, - 0x90, 0x6f, 0xf1, 0x34, 0xc9, 0x5c, 0xc6, 0x5b, 0x1e, 0xbc, 0x7b, 0x44, 0x1e, 0xa5, 0xe0, 0x44, - 0x96, 0xa0, 0xe4, 0x33, 0x19, 0x32, 0x89, 0x55, 0xcc, 0x3e, 0x2b, 0xba, 0x34, 0xa9, 0x51, 0x8f, - 0xe3, 0x9f, 0x68, 0x16, 0x23, 0x2e, 0x8c, 0xed, 0x88, 0x8b, 0x2b, 0x52, 0xcd, 0xca, 0xb6, 0x30, - 0xe5, 0xe5, 0x17, 0x7e, 0x7e, 0xa9, 0x9b, 0x30, 0x8f, 0xa3, 0x9f, 0xa8, 0x84, 0x90, 0x16, 0x14, - 0x6c, 0x35, 0x72, 0x23, 0x03, 0x84, 0x9f, 0x63, 0x13, 0x43, 0xa8, 0x0e, 0x7a, 0xa4, 0xb4, 0x04, - 0xeb, 0x5b, 0x39, 0x80, 0xe8, 0x6e, 0x26, 0xd9, 0x83, 0x42, 0x70, 0x2b, 0xa6, 0x4e, 0x67, 0xcc, - 0x36, 0x93, 0x4c, 0x8c, 0x3c, 0x24, 0x09, 0x41, 0x2d, 0xe0, 0x69, 0xba, 0xf4, 0x5f, 0xcf, 0x83, - 0x2e, 0xf5, 0x8c, 0x54, 0xe9, 0x57, 0x99, 0x1a, 0xd6, 0x88, 0x2e, 0x00, 0x69, 0x3a, 0xe4, 0x50, - 0x94, 0x58, 0xa6, 0x8a, 0xa9, 0x64, 0x08, 0xb9, 0xab, 0xf0, 0xfe, 0x54, 0x79, 0x13, 0xa8, 0xb1, - 0x69, 0xca, 0x79, 0xfe, 0xb9, 0x29, 0xe7, 0xa3, 0xcf, 0x44, 0x39, 0x67, 0xf6, 0x9a, 0xef, 0xb5, - 0xe8, 0x02, 0x6e, 0x48, 0x57, 0x9e, 0xb6, 0xd7, 0x50, 0x80, 0x51, 0xe1, 0xc9, 0x9b, 0x50, 0xea, - 0x06, 0xb4, 0xba, 0x74, 0x67, 0xd1, 0xa7, 0xf5, 0x40, 0xe6, 0x99, 0x68, 0xe7, 0xee, 0xbd, 0x08, - 0x85, 0x26, 0x1d, 0xf9, 0xc7, 0x39, 0x28, 0xd7, 0xf8, 0x25, 0x0e, 0x31, 0x40, 0x6b, 0xbb, 0x1b, - 0x5e, 0xb8, 0xe5, 0xd3, 0x80, 0xba, 0xa1, 0xcc, 0x5f, 0xfe, 0x20, 0x63, 0x06, 0x7f, 0xca, 0xcd, - 0x90, 0xca, 0xd5, 0xe3, 0xa3, 0xd9, 0xf2, 0x62, 0x1f, 0x79, 0xd8, 0xb7, 0x26, 0xd6, 0x5f, 0xcd, - 0xc1, 0xb9, 0x6a, 0xcd, 0x77, 0x3a, 0xa1, 0x3e, 0x0b, 0x37, 0xf8, 0x3d, 0xb0, 0xd0, 0x66, 0xfb, - 0x93, 0x5c, 0x31, 0x2f, 0xf5, 0xc9, 0x04, 0x10, 0x44, 0xb1, 0x3b, 0xa1, 0x02, 0x84, 0x11, 0x0b, - 0x36, 0x23, 0xc5, 0x69, 0x9b, 0x9c, 0xb9, 0x55, 0x0e, 0x45, 0x89, 0xb5, 0x1e, 0xc1, 0x54, 0x95, - 0xb6, 0xed, 0x4e, 0x93, 0x67, 0xe6, 0x88, 0xa0, 0xc0, 0x3c, 0x14, 0x03, 0x05, 0x4b, 0x5e, 0x40, - 0xd5, 0xc4, 0x18, 0xd1, 0x90, 0x57, 0x44, 0xcc, 0x42, 0x85, 0xf4, 0x8b, 0x42, 0x6b, 0x10, 0x81, - 0x8e, 0x00, 0x15, 0xce, 0x3a, 0x80, 0xf1, 0xa8, 0x38, 0xdd, 0x25, 0x0d, 0x98, 0xac, 0x19, 0x89, - 0x0d, 0xd1, 0x3d, 0xd3, 0x93, 0xe7, 0x40, 0xf0, 0xa4, 0x8e, 0xc5, 0x38, 0x13, 0x4c, 0x72, 0xb5, - 0xfe, 0x57, 0x0e, 0x26, 0xb5, 0x64, 0xe9, 0x3c, 0xe8, 0x24, 0xe3, 0x2c, 0xcb, 0x19, 0xd3, 0x61, - 0xe3, 0x9d, 0xf7, 0x84, 0x58, 0x4b, 0x27, 0x19, 0x6b, 0x39, 0x6b, 0x89, 0x3d, 0x5e, 0x8f, 0x3f, - 0x1c, 0x82, 0x82, 0xce, 0xc7, 0xfd, 0x10, 0xf2, 0x5c, 0x7d, 0x1b, 0xec, 0x60, 0xe4, 0xaa, 0x20, - 0x0a, 0x4e, 0x8c, 0x25, 0x77, 0x5c, 0x67, 0xbe, 0x51, 0x59, 0x14, 0x96, 0xa0, 0xed, 0x87, 0x28, - 0x38, 0x91, 0x3b, 0x30, 0x4c, 0xdd, 0xba, 0x3c, 0x21, 0x4f, 0xcf, 0x90, 0x5f, 0xb1, 0x5e, 0x76, - 0xeb, 0xc8, 0xb8, 0xf0, 0xab, 0x62, 0x9e, 0xdf, 0xb6, 0x43, 0xa9, 0xf9, 0x47, 0x57, 0xc5, 0x38, - 0x14, 0x25, 0xd6, 0xfa, 0x9f, 0x43, 0x30, 0x5a, 0xed, 0xee, 0xb0, 0xb3, 0xfe, 0xef, 0xe4, 0xe0, - 0x7c, 0x32, 0x84, 0x11, 0x4d, 0xcc, 0xdb, 0x67, 0x72, 0x95, 0x11, 0xe9, 0x6e, 0xe5, 0x8a, 0xac, - 0xca, 0xf9, 0x14, 0x24, 0xa6, 0xd5, 0x20, 0x76, 0x71, 0x6c, 0xf8, 0x19, 0x5d, 0xdb, 0x34, 0xf2, - 0xfb, 0x87, 0xce, 0x24, 0xbf, 0x7f, 0xa2, 0x5f, 0x6e, 0xbf, 0xf5, 0x6f, 0x47, 0x00, 0x44, 0x9f, - 0x6f, 0x76, 0xc2, 0x93, 0x18, 0x93, 0x6f, 0xc1, 0xb8, 0x7a, 0x4e, 0x67, 0x23, 0x8a, 0x0c, 0x6a, - 0xd7, 0xed, 0xaa, 0x81, 0xc3, 0x18, 0x25, 0x33, 0xaf, 0xa9, 0x1b, 0xfa, 0x87, 0xe2, 0xd4, 0x1f, - 0x89, 0x9b, 0xd7, 0xcb, 0x1a, 0x83, 0x06, 0x15, 0x99, 0x8b, 0x39, 0x8f, 0xc4, 0x1d, 0x80, 0x73, - 0x4f, 0x70, 0xfc, 0xbc, 0x0d, 0x13, 0xfa, 0x6b, 0xc5, 0x69, 0xa9, 0xb4, 0x2a, 0x6d, 0xa3, 0x6c, - 0x99, 0x48, 0x8c, 0xd3, 0x92, 0x77, 0xe1, 0x5c, 0x3c, 0x59, 0x57, 0x9e, 0x8f, 0x97, 0x64, 0xe9, - 0x73, 0xf1, 0x1c, 0x5f, 0x4c, 0x50, 0xb3, 0x79, 0x5e, 0xf7, 0x0f, 0xb1, 0xeb, 0xca, 0x83, 0x52, - 0xcf, 0xf3, 0x25, 0x0e, 0x45, 0x89, 0x65, 0x5d, 0xc8, 0x4a, 0x52, 0x5f, 0xc0, 0xf9, 0x89, 0x58, - 0x88, 0xba, 0xb0, 0x6a, 0xe0, 0x30, 0x46, 0xc9, 0x24, 0x48, 0x4b, 0x1e, 0xe2, 0x2b, 0x29, 0x61, - 0x8b, 0x77, 0xe0, 0x9c, 0x17, 0x37, 0x9e, 0x44, 0x04, 0xeb, 0x1b, 0x27, 0x9c, 0xaa, 0xb1, 0xb2, - 0x22, 0x1b, 0x36, 0x61, 0x6b, 0x25, 0xf8, 0x5b, 0xe7, 0x61, 0xba, 0xda, 0xed, 0x74, 0x5a, 0x0e, - 0xad, 0x6b, 0xdf, 0x8a, 0xf5, 0x1e, 0x4c, 0xca, 0x7b, 0x60, 0xfa, 0x80, 0x3d, 0xd5, 0x65, 0x71, - 0xeb, 0x88, 0x9d, 0x18, 0x71, 0xa7, 0x33, 0x71, 0x93, 0xc7, 0x62, 0x56, 0x87, 0x98, 0x79, 0x08, - 0x8a, 0x15, 0x92, 0x7a, 0xaa, 0x3e, 0x54, 0x69, 0x06, 0x83, 0x24, 0xde, 0xf0, 0xc8, 0xbc, 0xd8, - 0x67, 0xcd, 0xf4, 0x04, 0xeb, 0xc7, 0x39, 0x48, 0xf7, 0xe7, 0x93, 0xcf, 0x7a, 0x9b, 0xb9, 0x34, - 0x58, 0x33, 0x65, 0x0c, 0xa1, 0x7f, 0x4b, 0xed, 0x78, 0x4b, 0xdf, 0xcf, 0xde, 0x52, 0x29, 0xaa, - 0xb7, 0xbd, 0xff, 0x3b, 0x07, 0xa5, 0xed, 0xed, 0xbb, 0xda, 0x4c, 0x44, 0xb8, 0x14, 0x88, 0x9b, - 0x7c, 0x0b, 0xbb, 0x21, 0xf5, 0x17, 0xbd, 0x76, 0xa7, 0x45, 0xf5, 0xe4, 0x90, 0xd7, 0xeb, 0xaa, - 0xa9, 0x14, 0xd8, 0xa7, 0x24, 0x59, 0x83, 0xf3, 0x26, 0x46, 0xda, 0xf7, 0xbc, 0x51, 0x79, 0x99, - 0x71, 0xdd, 0x8b, 0xc6, 0xb4, 0x32, 0x49, 0x56, 0xd2, 0xc8, 0x97, 0xcf, 0x2f, 0xf5, 0xb0, 0x92, - 0x68, 0x4c, 0x2b, 0x63, 0x6d, 0x42, 0xc9, 0x78, 0xd8, 0x8b, 0xbc, 0x0f, 0x53, 0x35, 0xaf, 0xdd, - 0xf1, 0x69, 0x10, 0x38, 0x9e, 0x7b, 0x97, 0xee, 0xd3, 0x96, 0x6c, 0x32, 0x37, 0xc6, 0x17, 0x13, - 0x38, 0xec, 0xa1, 0xb6, 0xfe, 0xf9, 0x15, 0xd0, 0xb7, 0xc3, 0x7e, 0x7e, 0xc7, 0x2c, 0x53, 0x9e, - 0x46, 0x4d, 0xc7, 0x6b, 0xf3, 0x83, 0xc7, 0x6b, 0xf5, 0x5e, 0x9c, 0x88, 0xd9, 0x36, 0xa2, 0x98, - 0xed, 0xe8, 0x19, 0xc4, 0x6c, 0xb5, 0x9a, 0xd9, 0x13, 0xb7, 0xfd, 0xed, 0x1c, 0x8c, 0xbb, 0x5e, - 0x9d, 0x2a, 0xad, 0x9c, 0xfb, 0x99, 0x4a, 0x37, 0x37, 0x07, 0xea, 0x44, 0x11, 0x8c, 0x94, 0x1c, - 0x45, 0xb8, 0x5e, 0x1f, 0x54, 0x26, 0x0a, 0x63, 0xa2, 0xc9, 0x8a, 0xe1, 0xf5, 0x10, 0xd7, 0xdc, - 0xae, 0xa6, 0x19, 0x13, 0x4f, 0xf3, 0x67, 0x90, 0x3d, 0x43, 0xdb, 0x2a, 0x0e, 0xe0, 0xc0, 0x50, - 0xd9, 0x7d, 0x86, 0xd7, 0x51, 0xdd, 0x80, 0x8d, 0x14, 0x2f, 0x0b, 0x46, 0x45, 0x28, 0x5f, 0x3e, - 0xc8, 0xc5, 0xbd, 0xdc, 0x22, 0xcc, 0x8f, 0x12, 0x43, 0x1a, 0x2a, 0x14, 0x53, 0xe2, 0x9d, 0x5b, - 0xc9, 0x1c, 0xc8, 0xd2, 0xd1, 0x9d, 0xf4, 0x58, 0x0c, 0xf9, 0xc0, 0xb4, 0x44, 0xc7, 0x4f, 0x62, - 0x89, 0x4e, 0xf4, 0xb5, 0x42, 0x1b, 0x30, 0x1a, 0x70, 0x3b, 0x97, 0xe7, 0x2f, 0x94, 0x6e, 0x2e, - 0x66, 0x3b, 0x48, 0x62, 0xa6, 0xb2, 0xe8, 0x1d, 0x01, 0x43, 0xc9, 0x9e, 0x78, 0x50, 0x50, 0x49, - 0x16, 0x32, 0x05, 0x62, 0x39, 0xa3, 0xb3, 0x2b, 0xee, 0xa3, 0x56, 0x97, 0x9d, 0x04, 0x14, 0xb5, - 0x10, 0xf2, 0x10, 0x86, 0xeb, 0x76, 0x43, 0x26, 0x43, 0xbc, 0x9f, 0xf9, 0xf6, 0x9e, 0x12, 0xc3, - 0xed, 0x96, 0xa5, 0x85, 0x55, 0x64, 0x5c, 0xc9, 0x5e, 0x74, 0xbb, 0x7d, 0x6a, 0x90, 0x03, 0x38, - 0xae, 0x02, 0x09, 0xab, 0xbc, 0xe7, 0x7e, 0xfc, 0x32, 0x8c, 0xed, 0x7b, 0xad, 0x6e, 0x5b, 0x66, - 0x51, 0x94, 0x6e, 0xce, 0xa4, 0x8d, 0xf6, 0x7d, 0x4e, 0x12, 0x6d, 0x02, 0xe2, 0x3b, 0x40, 0x55, - 0x96, 0x7c, 0x33, 0x07, 0xe7, 0xd8, 0xd2, 0xd1, 0xf3, 0x20, 0x28, 0x93, 0x01, 0x66, 0xea, 0xbd, - 0x80, 0x1d, 0xad, 0x6a, 0x86, 0x69, 0x45, 0x78, 0x2d, 0x26, 0x01, 0x13, 0x12, 0x49, 0x07, 0x0a, - 0x81, 0x53, 0xa7, 0x35, 0xdb, 0x0f, 0xca, 0xe7, 0xcf, 0x4c, 0x7a, 0xe4, 0x7b, 0x94, 0xbc, 0x51, - 0x4b, 0x21, 0x7f, 0x99, 0xbf, 0xf9, 0x24, 0x5f, 0xb8, 0x93, 0xef, 0x1a, 0x5e, 0x38, 0xcb, 0x77, - 0x0d, 0xcf, 0x8b, 0x07, 0x9f, 0x62, 0x12, 0x30, 0x29, 0x92, 0xfc, 0x46, 0x0e, 0x2e, 0x8a, 0x6b, - 0xee, 0xc9, 0x37, 0x0e, 0x2e, 0x66, 0xb4, 0xa4, 0x79, 0xc6, 0xc7, 0x42, 0x1a, 0x4b, 0x4c, 0x97, - 0x44, 0xbe, 0x84, 0x09, 0xdf, 0x74, 0xc5, 0xf3, 0xe4, 0x9a, 0x81, 0xbc, 0xce, 0xfa, 0x95, 0x44, - 0x9e, 0xd8, 0x13, 0x03, 0x61, 0x5c, 0x16, 0x79, 0x03, 0x4a, 0x1d, 0xb9, 0xb9, 0x39, 0x41, 0x9b, - 0xe7, 0xe5, 0x0c, 0x8b, 0x43, 0x78, 0x2b, 0x02, 0xa3, 0x49, 0x43, 0xee, 0x41, 0x29, 0xf4, 0x5a, - 0xd4, 0x97, 0x59, 0xe4, 0x65, 0x3e, 0x5f, 0xae, 0xa5, 0x4d, 0xfe, 0x6d, 0x4d, 0x16, 0xf9, 0x20, - 0x23, 0x58, 0x80, 0x26, 0x1f, 0x66, 0x09, 0xaa, 0x47, 0x30, 0x7c, 0x6e, 0xa8, 0xbe, 0x18, 0xb7, - 0x04, 0xab, 0x26, 0x12, 0xe3, 0xb4, 0x64, 0x15, 0xa6, 0x3b, 0xbe, 0xe3, 0xf9, 0x4e, 0x78, 0xb8, - 0xd8, 0xb2, 0x83, 0x80, 0x33, 0x10, 0x89, 0x74, 0x3a, 0xfe, 0xb4, 0x95, 0x24, 0xc0, 0xde, 0x32, - 0xe4, 0x35, 0x28, 0x28, 0x60, 0xf9, 0x0a, 0x57, 0xef, 0xc6, 0x45, 0x12, 0x9e, 0x80, 0xa1, 0xc6, - 0xf6, 0xb9, 0xb3, 0x7b, 0x35, 0xcb, 0x9d, 0x5d, 0x52, 0x87, 0xab, 0x76, 0x37, 0xf4, 0xf8, 0x75, - 0x95, 0x78, 0x91, 0x6d, 0x6f, 0x8f, 0xba, 0xe5, 0xeb, 0xfc, 0x78, 0xbb, 0x7e, 0x7c, 0x34, 0x7b, - 0x75, 0xe1, 0x09, 0x74, 0xf8, 0x44, 0x2e, 0xa4, 0x0d, 0x05, 0x2a, 0xef, 0x1d, 0x97, 0x7f, 0x61, - 0x80, 0x73, 0x25, 0x7e, 0x79, 0x59, 0x65, 0x45, 0x08, 0x18, 0x6a, 0x11, 0x64, 0x1b, 0x4a, 0x4d, - 0x2f, 0x08, 0x17, 0x5a, 0x8e, 0x1d, 0xd0, 0xa0, 0xfc, 0x12, 0x9f, 0x27, 0xa9, 0x47, 0xe2, 0x6d, - 0x45, 0x16, 0x4d, 0x93, 0xdb, 0x51, 0x49, 0x34, 0xd9, 0x10, 0xca, 0xdd, 0xee, 0x5d, 0x3e, 0x6a, - 0x9e, 0x1b, 0xd2, 0xcf, 0xc3, 0xf2, 0x35, 0xde, 0x96, 0x57, 0xd3, 0x38, 0x6f, 0x79, 0xf5, 0x6a, - 0x9c, 0x5a, 0x6c, 0x0c, 0x09, 0x20, 0x26, 0x79, 0x32, 0x93, 0xbf, 0xe3, 0xd5, 0xab, 0x1d, 0x5a, - 0xdb, 0xb2, 0xc3, 0x5a, 0xb3, 0x3c, 0x1b, 0xf7, 0x9a, 0x6c, 0x19, 0x38, 0x8c, 0x51, 0x92, 0x1a, - 0x8c, 0xb5, 0x45, 0x72, 0x7e, 0xf9, 0xe5, 0x01, 0xd4, 0x47, 0x99, 0xe0, 0x2f, 0x0e, 0x1f, 0xf9, - 0x81, 0x8a, 0x33, 0xf9, 0xdb, 0x39, 0x98, 0x4c, 0xe4, 0x8f, 0x95, 0x7f, 0x71, 0x90, 0x23, 0x2f, - 0xce, 0xab, 0xf2, 0x2a, 0xef, 0xa4, 0x38, 0xf0, 0x71, 0x2f, 0x08, 0x93, 0x95, 0x10, 0xad, 0xe7, - 0xf7, 0x63, 0xca, 0xaf, 0x0c, 0xd4, 0x7a, 0xce, 0x43, 0xb5, 0x9e, 0x7f, 0xa0, 0xe2, 0x4c, 0x6e, - 0xc0, 0x58, 0xe8, 0xb4, 0xa9, 0xd7, 0x0d, 0xcb, 0xaf, 0xc6, 0x03, 0x22, 0xdb, 0x02, 0x8c, 0x0a, - 0x3f, 0xf3, 0x1e, 0x4c, 0xf7, 0x28, 0xc4, 0xa7, 0xba, 0xbe, 0xf1, 0x03, 0x66, 0x00, 0x1b, 0x26, - 0xc8, 0x59, 0x1b, 0x6e, 0xab, 0x30, 0x2d, 0x5f, 0xcc, 0x66, 0xda, 0x52, 0xab, 0xab, 0x9f, 0xc3, - 0x33, 0x22, 0xe7, 0x98, 0x24, 0xc0, 0xde, 0x32, 0x6c, 0xc6, 0xd6, 0xc4, 0x7b, 0x68, 0x22, 0x55, - 0x7c, 0x24, 0xee, 0xa4, 0x5a, 0x34, 0x70, 0x18, 0xa3, 0xb4, 0xfe, 0x49, 0x0e, 0x26, 0x62, 0x27, - 0xf7, 0x99, 0x47, 0x55, 0x56, 0x80, 0xb4, 0x1d, 0xdf, 0xf7, 0x7c, 0xa1, 0xfe, 0xac, 0xb3, 0x3d, - 0x29, 0x90, 0xd7, 0xe2, 0xf9, 0x75, 0xcc, 0xf5, 0x1e, 0x2c, 0xa6, 0x94, 0xb0, 0x7e, 0x73, 0x18, - 0xa2, 0x4c, 0x20, 0x7d, 0x07, 0x39, 0xd7, 0xf7, 0x0e, 0xf2, 0xeb, 0x50, 0x78, 0x14, 0x78, 0xee, - 0x56, 0x74, 0x53, 0x59, 0x0f, 0xc5, 0x07, 0xd5, 0xcd, 0x0d, 0x4e, 0xa9, 0x29, 0x38, 0xf5, 0x67, - 0x2b, 0x4e, 0x2b, 0xec, 0xbd, 0xcf, 0xfb, 0xc1, 0x87, 0x02, 0x8e, 0x9a, 0x82, 0x3f, 0xba, 0xb6, - 0x4f, 0xb5, 0xcf, 0x31, 0x7a, 0x74, 0x8d, 0x01, 0x51, 0xe0, 0xc8, 0x3c, 0x14, 0xb5, 0xcb, 0x52, - 0x7a, 0x50, 0x75, 0x4f, 0x69, 0xd7, 0x26, 0x46, 0x34, 0x5c, 0x13, 0x93, 0x6e, 0x39, 0x69, 0x7d, - 0xae, 0x64, 0xd4, 0x61, 0x13, 0xbe, 0x3d, 0xb1, 0x4d, 0x2b, 0x30, 0x6a, 0x29, 0x66, 0x4e, 0x58, - 0xfe, 0x84, 0x39, 0x61, 0x6c, 0x1c, 0xc6, 0xee, 0x53, 0x9f, 0x3f, 0x2f, 0x70, 0x03, 0xc6, 0xf6, - 0xc5, 0xcf, 0x64, 0x36, 0xa9, 0xa4, 0x40, 0x85, 0x67, 0xbd, 0xb1, 0xd3, 0x75, 0x5a, 0xf5, 0xa5, - 0x68, 0x69, 0xe8, 0xde, 0xa8, 0x28, 0x04, 0x46, 0x34, 0xac, 0x40, 0x83, 0x29, 0xaa, 0xed, 0xb6, - 0x13, 0x26, 0xef, 0xe7, 0xad, 0x2a, 0x04, 0x46, 0x34, 0xe4, 0x55, 0x18, 0x6d, 0x38, 0xe1, 0xb6, - 0xdd, 0x48, 0x46, 0x2e, 0x56, 0x39, 0x14, 0x25, 0x96, 0x3b, 0xc5, 0x9d, 0x70, 0xdb, 0xa7, 0xdc, - 0xc9, 0xd6, 0x73, 0x3f, 0x65, 0xd5, 0xc0, 0x61, 0x8c, 0x92, 0x57, 0xc9, 0x93, 0x2d, 0x93, 0xce, - 0xea, 0xa8, 0x4a, 0x0a, 0x81, 0x11, 0x0d, 0x9b, 0x55, 0x35, 0xaf, 0xdd, 0x71, 0x5a, 0x32, 0xb3, - 0xc8, 0x98, 0x55, 0x8b, 0x12, 0x8e, 0x9a, 0x82, 0x51, 0xb3, 0x7d, 0x61, 0xd7, 0xf3, 0xdb, 0xc9, - 0xa7, 0xa6, 0xb6, 0x24, 0x1c, 0x35, 0x85, 0x75, 0x1f, 0x26, 0xc4, 0xfa, 0x58, 0x6c, 0xd9, 0x4e, - 0x7b, 0x75, 0x91, 0x2c, 0xf7, 0x64, 0xaa, 0xdd, 0x48, 0xc9, 0x54, 0xbb, 0x18, 0x2b, 0x94, 0x92, - 0xb1, 0xf6, 0xc7, 0x43, 0x50, 0x78, 0x8e, 0x2f, 0xef, 0xd5, 0x62, 0x2f, 0xef, 0x9d, 0xc1, 0x33, - 0x6d, 0x69, 0xaf, 0xee, 0xed, 0x25, 0x5e, 0xdd, 0x5b, 0x1c, 0x30, 0x29, 0xf3, 0x89, 0x2f, 0xee, - 0xfd, 0x28, 0x07, 0xfa, 0x9e, 0x0f, 0xdf, 0x10, 0x2a, 0x8e, 0xcb, 0x83, 0x99, 0xcf, 0xbe, 0x33, - 0xbd, 0x58, 0x67, 0xae, 0x0f, 0xd4, 0x4a, 0xb3, 0xea, 0x7d, 0x1f, 0x12, 0xfd, 0x61, 0x0e, 0xca, - 0x69, 0x05, 0x9e, 0xc3, 0x2b, 0x83, 0x6e, 0xfc, 0x95, 0xc1, 0xb5, 0x33, 0x6b, 0x6c, 0x9f, 0xd7, - 0x06, 0xbf, 0xd7, 0xa7, 0xa9, 0xfc, 0x9d, 0xbf, 0x4f, 0xd5, 0x81, 0x90, 0x1b, 0x20, 0xee, 0x20, - 0xb8, 0xa6, 0x1f, 0x26, 0x9f, 0xc2, 0x68, 0xc0, 0x23, 0x7f, 0x72, 0x6c, 0xdf, 0xce, 0x78, 0x32, - 0x30, 0x16, 0xd2, 0x1b, 0xc4, 0x7f, 0xa3, 0x64, 0x6b, 0x7d, 0x27, 0x07, 0xe3, 0xcf, 0xf1, 0x8d, - 0xc8, 0x9d, 0xf8, 0xe8, 0xbd, 0x33, 0xd0, 0xe8, 0xf5, 0x19, 0xb1, 0xdf, 0xbf, 0x02, 0xb1, 0xb7, - 0x19, 0x89, 0x0b, 0x45, 0xa5, 0x7b, 0xa9, 0xf4, 0xec, 0x77, 0x06, 0x72, 0xb8, 0x46, 0xdb, 0xbf, - 0x82, 0x04, 0x18, 0x89, 0x48, 0x04, 0x51, 0x87, 0x4e, 0x14, 0x44, 0x7d, 0xee, 0xce, 0xfc, 0x74, - 0x5b, 0x76, 0xe4, 0x99, 0xd8, 0xb2, 0x57, 0xcf, 0xdc, 0x96, 0x7d, 0xe9, 0xd9, 0xdb, 0xb2, 0x86, - 0xb3, 0x2f, 0x3f, 0x80, 0xb3, 0xef, 0x4b, 0xb8, 0xb0, 0x1f, 0x1d, 0xbd, 0x7a, 0xbe, 0xc8, 0x87, - 0xef, 0x6e, 0xa4, 0x5a, 0xb0, 0x4c, 0x8d, 0x08, 0x42, 0xea, 0x86, 0xc6, 0xa1, 0x1d, 0x5d, 0x26, - 0xbd, 0x9f, 0xc2, 0x0e, 0x53, 0x85, 0x24, 0x5d, 0x3d, 0x63, 0x27, 0x70, 0xf5, 0xfc, 0x41, 0xdf, - 0x87, 0xed, 0x0b, 0x67, 0xfe, 0xb0, 0xfd, 0x8b, 0xa7, 0x7e, 0xd4, 0xfe, 0x95, 0xc8, 0xdd, 0x2b, - 0x22, 0xf2, 0xe9, 0x8e, 0xda, 0xdf, 0x4b, 0x86, 0x59, 0x80, 0xf7, 0x76, 0x75, 0x60, 0x35, 0xe3, - 0x0c, 0x42, 0x2d, 0xa5, 0x01, 0x42, 0x2d, 0x09, 0x3f, 0xdc, 0xf8, 0x19, 0xf9, 0xe1, 0x5c, 0x98, - 0x72, 0xda, 0x76, 0x83, 0x6e, 0x75, 0x5b, 0x2d, 0x91, 0x80, 0x18, 0x94, 0x27, 0x38, 0xef, 0xd4, - 0xf4, 0xb2, 0xbb, 0x5e, 0xcd, 0x6e, 0x25, 0x9f, 0x12, 0xd5, 0x59, 0xd6, 0x6b, 0x09, 0x4e, 0xd8, - 0xc3, 0x9b, 0x4d, 0x4b, 0x7e, 0x61, 0x90, 0x86, 0xac, 0xb7, 0x79, 0x14, 0x42, 0xfe, 0x1d, 0xca, - 0xed, 0x08, 0x8c, 0x26, 0x0d, 0xb9, 0x03, 0xc5, 0xba, 0x1b, 0xc8, 0xb4, 0xe2, 0x49, 0xbe, 0x4b, - 0xfd, 0x12, 0xdb, 0xdb, 0x96, 0x36, 0xaa, 0x3a, 0xa1, 0xf8, 0x6a, 0xca, 0x8d, 0x53, 0x8d, 0xc7, - 0xa8, 0x3c, 0x59, 0xe7, 0xcc, 0xe4, 0x7b, 0x53, 0x22, 0x6c, 0x70, 0xbd, 0x8f, 0x2b, 0x69, 0x69, - 0x43, 0x3d, 0x8f, 0x35, 0x21, 0xc5, 0xc9, 0x57, 0xa4, 0x22, 0x0e, 0xc6, 0x5b, 0x89, 0xd3, 0x4f, - 0x7c, 0x2b, 0xf1, 0x1e, 0x5c, 0x0e, 0xc3, 0x56, 0x2c, 0x1a, 0x2d, 0x2f, 0x1b, 0xf3, 0x9b, 0xe7, - 0x79, 0xf1, 0xbc, 0xee, 0xf6, 0xf6, 0xdd, 0x34, 0x12, 0xec, 0x57, 0x96, 0x87, 0x65, 0xc3, 0x96, - 0x76, 0x25, 0x5f, 0x1b, 0x24, 0x2c, 0x1b, 0x85, 0xfd, 0x65, 0x58, 0x36, 0x02, 0xa0, 0x29, 0x85, - 0x6c, 0xf6, 0x73, 0xa2, 0x9f, 0xe7, 0x7b, 0xcc, 0xe9, 0x5d, 0xe2, 0xa6, 0x17, 0xf6, 0xc2, 0x13, - 0xbd, 0xb0, 0x3d, 0x5e, 0xe3, 0x8b, 0xa7, 0xf0, 0x1a, 0x3f, 0xe4, 0xb7, 0x89, 0x57, 0x17, 0xa5, - 0xc7, 0x3d, 0x9b, 0xc6, 0xc6, 0x6f, 0xfd, 0x88, 0xcc, 0x09, 0xfe, 0x13, 0x05, 0x4f, 0xb2, 0x05, - 0x17, 0x3a, 0x5e, 0xbd, 0xc7, 0xe9, 0xcc, 0x5d, 0xec, 0xc6, 0x6b, 0x00, 0x5b, 0x29, 0x34, 0x98, - 0x5a, 0x92, 0x6f, 0xe0, 0x11, 0x9c, 0x5f, 0x3e, 0xcf, 0xcb, 0x0d, 0x3c, 0x02, 0xa3, 0x49, 0x93, - 0xf4, 0xc1, 0xbe, 0xf8, 0xcc, 0x7c, 0xb0, 0x33, 0xcf, 0xc1, 0x07, 0x7b, 0xe5, 0xc4, 0x3e, 0xd8, - 0xbf, 0x08, 0xe7, 0x3b, 0x5e, 0x7d, 0xc9, 0x09, 0xfc, 0x2e, 0x4f, 0x39, 0xae, 0x74, 0xeb, 0x0d, - 0x1a, 0x72, 0x27, 0x6e, 0xe9, 0xe6, 0x4d, 0xb3, 0x92, 0xe2, 0xcf, 0xf4, 0xe6, 0xe4, 0x9f, 0xe9, - 0xf1, 0x45, 0x9e, 0x28, 0xc5, 0xed, 0x1e, 0x9e, 0x3a, 0x92, 0x82, 0xc4, 0x34, 0x39, 0xa6, 0x0b, - 0xf8, 0xfa, 0x33, 0x73, 0x01, 0xbf, 0x0f, 0x85, 0xa0, 0xd9, 0x0d, 0xeb, 0xde, 0x81, 0xcb, 0xbd, - 0xf9, 0x45, 0xfd, 0x38, 0x79, 0xa1, 0x2a, 0xe1, 0x8f, 0x8f, 0x66, 0xa7, 0xd4, 0x6f, 0xc3, 0xca, - 0x97, 0x10, 0xf2, 0xb7, 0xfa, 0xe4, 0x6c, 0x5a, 0x67, 0x9c, 0xb3, 0x79, 0xf9, 0x54, 0xf9, 0x9a, - 0x69, 0xae, 0xed, 0x97, 0x7f, 0x1a, 0x5c, 0xdb, 0xbf, 0x9b, 0x83, 0x89, 0x7d, 0xd3, 0x71, 0x22, - 0x3d, 0xee, 0xd9, 0x02, 0x75, 0x31, 0x17, 0x4c, 0xc5, 0x62, 0x7b, 0x55, 0x0c, 0xf4, 0x38, 0x09, - 0xc0, 0xb8, 0xf0, 0xde, 0xb0, 0xe1, 0x2b, 0xcf, 0x2f, 0x6c, 0x38, 0xb8, 0x5b, 0xfd, 0x3f, 0x4e, - 0xc3, 0xb9, 0xc4, 0xa3, 0xe5, 0xfa, 0xbd, 0x92, 0xdc, 0x49, 0xdf, 0x2b, 0x89, 0x3d, 0x28, 0x32, - 0xf4, 0x4c, 0x1f, 0x14, 0x19, 0x7e, 0x3e, 0x0f, 0x8a, 0x4c, 0x3d, 0x8b, 0x07, 0x45, 0xa6, 0x4f, - 0xf5, 0xa0, 0x88, 0xf1, 0xa0, 0xcb, 0xc8, 0x53, 0x1e, 0x74, 0x59, 0x80, 0x49, 0x95, 0xe5, 0x46, - 0xe5, 0x83, 0x12, 0xc2, 0x91, 0xaa, 0xef, 0xb6, 0x2c, 0xc6, 0xd1, 0x98, 0xa4, 0x27, 0x7f, 0x01, - 0xf2, 0x2e, 0x2f, 0x38, 0x3a, 0xc0, 0x63, 0x64, 0xf1, 0x89, 0xc4, 0xd5, 0x72, 0xf9, 0x1e, 0x98, - 0x4a, 0x80, 0xc8, 0x73, 0xd8, 0x63, 0xf5, 0x03, 0x85, 0x50, 0xf2, 0x31, 0x94, 0xbd, 0xdd, 0xdd, - 0x96, 0x67, 0xd7, 0xa3, 0x47, 0x4f, 0x94, 0x6f, 0x57, 0x24, 0xec, 0x5e, 0x97, 0x0c, 0xca, 0x9b, - 0x7d, 0xe8, 0xb0, 0x2f, 0x07, 0x66, 0x3d, 0x4d, 0xc6, 0x1f, 0x09, 0x0a, 0xca, 0x45, 0xde, 0xcc, - 0x3f, 0x77, 0x16, 0xcd, 0x8c, 0xbf, 0x48, 0x24, 0x1b, 0x1c, 0xdd, 0x2a, 0x8a, 0x63, 0x31, 0x59, - 0x13, 0xe2, 0xc3, 0xa5, 0x4e, 0x9a, 0x6d, 0x19, 0xc8, 0x34, 0xb4, 0x27, 0x59, 0xb8, 0xd7, 0xa4, - 0x94, 0x4b, 0xa9, 0xd6, 0x69, 0x80, 0x7d, 0x38, 0x9b, 0xcf, 0xa1, 0x14, 0x9e, 0xd9, 0x73, 0x28, - 0xf1, 0xbf, 0x0f, 0x98, 0x78, 0x1e, 0x7f, 0x1f, 0x40, 0x7e, 0x92, 0xfa, 0x0a, 0x8f, 0x30, 0xc9, - 0x3e, 0x3a, 0x8b, 0xc1, 0xfe, 0xa9, 0x7b, 0x89, 0xe7, 0xef, 0xe6, 0x60, 0x46, 0x4c, 0xa9, 0xb4, - 0x7f, 0x9c, 0x92, 0xc9, 0x64, 0x67, 0xe0, 0xca, 0xe7, 0xe1, 0xc1, 0x6a, 0x4c, 0x10, 0xf7, 0x3d, - 0x3f, 0x41, 0x38, 0xf9, 0xed, 0x14, 0x15, 0x62, 0x72, 0x00, 0x87, 0x45, 0xfa, 0xdb, 0x2e, 0xe7, - 0x8f, 0x4f, 0xa2, 0x35, 0xfc, 0xa3, 0xbe, 0x2e, 0x14, 0xc2, 0x6b, 0xb4, 0x75, 0x76, 0x2e, 0x14, - 0xf3, 0xcd, 0x99, 0xd3, 0x38, 0x52, 0x66, 0x0e, 0xc5, 0xf3, 0x72, 0x7d, 0x1f, 0x37, 0xbc, 0x67, - 0x1e, 0xe3, 0x59, 0xdf, 0x17, 0x8c, 0xf6, 0x47, 0xf3, 0x61, 0xc5, 0xdf, 0xc8, 0xc1, 0x85, 0xb4, - 0x8d, 0x2c, 0xa5, 0x16, 0xd5, 0x78, 0x2d, 0x06, 0xf3, 0xda, 0x9a, 0x75, 0x38, 0x9b, 0x27, 0x77, - 0xfe, 0xe6, 0xa8, 0xe1, 0x69, 0x0e, 0x69, 0xe7, 0xe7, 0x29, 0xde, 0x99, 0x52, 0xbc, 0x63, 0x7f, - 0x08, 0x92, 0x7f, 0x8e, 0x7f, 0x08, 0x32, 0x9a, 0xe1, 0x0f, 0x41, 0xc6, 0x9e, 0xe7, 0x1f, 0x82, - 0x14, 0x4e, 0xf8, 0x87, 0x20, 0xc5, 0x9f, 0x9a, 0x3f, 0x04, 0xb1, 0xbe, 0xce, 0xc1, 0xd4, 0xff, - 0xef, 0xff, 0xa3, 0xf8, 0x03, 0x23, 0xd4, 0xfb, 0x1c, 0xff, 0x40, 0xf1, 0x51, 0x3c, 0x78, 0xb6, - 0x7c, 0x26, 0x8d, 0xec, 0x13, 0x44, 0xfb, 0x0c, 0xd2, 0xcc, 0xf7, 0x93, 0xdd, 0x3d, 0x8c, 0xe5, - 0x24, 0x0d, 0x9d, 0x38, 0x27, 0xe9, 0xff, 0xa6, 0xf4, 0x2a, 0x3f, 0xdb, 0xbf, 0x7c, 0x56, 0x7f, - 0xed, 0x76, 0x21, 0xed, 0xaf, 0xdd, 0x12, 0x7f, 0xe5, 0x96, 0xfc, 0x6b, 0xaf, 0xa1, 0x67, 0xf8, - 0xd7, 0x5e, 0x13, 0x50, 0x32, 0xff, 0x9a, 0x7f, 0xee, 0xdb, 0x5f, 0x5f, 0x7b, 0xe1, 0x3b, 0x5f, - 0x5f, 0x7b, 0xe1, 0xbb, 0x5f, 0x5f, 0x7b, 0xe1, 0xab, 0xe3, 0x6b, 0xb9, 0x6f, 0x1f, 0x5f, 0xcb, - 0x7d, 0xe7, 0xf8, 0x5a, 0xee, 0xbb, 0xc7, 0xd7, 0x72, 0x3f, 0x38, 0xbe, 0x96, 0xfb, 0x1b, 0xff, - 0xf5, 0xda, 0x0b, 0x1f, 0x15, 0x54, 0xdb, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x8d, - 0xf7, 0x18, 0xff, 0x82, 0x00, 0x00, + 0x67, 0x46, 0x64, 0x47, 0x44, 0xda, 0xed, 0xee, 0x45, 0xcc, 0x8e, 0x58, 0x86, 0x65, 0x77, 0x25, + 0x10, 0x5a, 0x18, 0xb4, 0xe2, 0x25, 0xb1, 0xe2, 0x67, 0x57, 0x08, 0xf1, 0x89, 0xb4, 0x1f, 0x08, + 0xd0, 0x30, 0x12, 0x62, 0xf8, 0x62, 0x24, 0x46, 0x9e, 0x69, 0xf3, 0x33, 0x23, 0x18, 0x46, 0x7c, + 0x20, 0xa4, 0x12, 0x12, 0xe8, 0x3e, 0xe3, 0x46, 0x64, 0x64, 0x95, 0x1d, 0xe9, 0x2a, 0x8d, 0x98, + 0xf9, 0xcb, 0x38, 0xe7, 0xdc, 0x73, 0xee, 0xfb, 0x9e, 0xd7, 0xbd, 0x09, 0x8b, 0x0d, 0x27, 0x6c, + 0x76, 0x77, 0xe6, 0x6a, 0x5e, 0x7b, 0xde, 0xf6, 0x1b, 0x5e, 0xc7, 0xf7, 0x1e, 0xf1, 0x1f, 0xf3, + 0x9d, 0xbd, 0xc6, 0xbc, 0xdd, 0x71, 0x82, 0xf9, 0x03, 0xcf, 0xdf, 0xdb, 0x6d, 0x79, 0x07, 0xf3, + 0xfb, 0x6f, 0xd8, 0xad, 0x4e, 0xd3, 0x7e, 0x63, 0xbe, 0x41, 0x5d, 0xea, 0xdb, 0x21, 0xad, 0xcf, + 0x75, 0x7c, 0x2f, 0xf4, 0xc8, 0xad, 0x88, 0xc9, 0x9c, 0x62, 0xc2, 0x7f, 0xcc, 0x75, 0xf6, 0x1a, + 0x73, 0x8c, 0xc9, 0x9c, 0x62, 0x32, 0xa7, 0x98, 0xcc, 0xfc, 0x8a, 0x21, 0xb9, 0xe1, 0x31, 0x81, + 0x8c, 0xd7, 0x4e, 0x77, 0x97, 0x7f, 0xf1, 0x0f, 0xfe, 0x4b, 0xc8, 0x98, 0xb1, 0xf6, 0xde, 0x0a, + 0xe6, 0x1c, 0x8f, 0x55, 0x69, 0xbe, 0xe6, 0xf9, 0x74, 0x7e, 0xbf, 0xa7, 0x1e, 0x33, 0x37, 0x0c, + 0x9a, 0x8e, 0xd7, 0x72, 0x6a, 0x87, 0xf3, 0xfb, 0x6f, 0xec, 0xd0, 0xb0, 0xb7, 0xca, 0x33, 0x5f, + 0x8b, 0x48, 0xdb, 0x76, 0xad, 0xe9, 0xb8, 0xd4, 0x3f, 0x8c, 0x9a, 0xdc, 0xa6, 0xa1, 0x9d, 0x26, + 0x60, 0xbe, 0x5f, 0x29, 0xbf, 0xeb, 0x86, 0x4e, 0x9b, 0xf6, 0x14, 0xf8, 0x0b, 0x4f, 0x2b, 0x10, + 0xd4, 0x9a, 0xb4, 0x6d, 0xf7, 0x94, 0xbb, 0xd5, 0xaf, 0x5c, 0x37, 0x74, 0x5a, 0xf3, 0x8e, 0x1b, + 0x06, 0xa1, 0x9f, 0x2c, 0x64, 0x2d, 0xc3, 0xe8, 0x42, 0xdb, 0xeb, 0xba, 0x21, 0x79, 0x1b, 0xf2, + 0xfb, 0x76, 0xab, 0x4b, 0xcb, 0xb9, 0xeb, 0xb9, 0xd7, 0x8a, 0x95, 0x57, 0xbe, 0x7d, 0x34, 0xfb, + 0xc2, 0xf1, 0xd1, 0x6c, 0xfe, 0x3e, 0x03, 0x3e, 0x3e, 0x9a, 0xbd, 0x40, 0xdd, 0x9a, 0x57, 0x77, + 0xdc, 0xc6, 0xfc, 0xa3, 0xc0, 0x73, 0xe7, 0x36, 0xba, 0xed, 0x1d, 0xea, 0xa3, 0x28, 0x63, 0xfd, + 0xc9, 0x10, 0x4c, 0x2e, 0xf8, 0xb5, 0xa6, 0xb3, 0x4f, 0xab, 0x21, 0xe3, 0xdf, 0x38, 0x24, 0x0f, + 0x61, 0x38, 0xb4, 0x7d, 0xce, 0xae, 0x74, 0xf3, 0xfd, 0xb9, 0x0c, 0xe3, 0x3d, 0xb7, 0x6d, 0xfb, + 0x8a, 0x5d, 0x65, 0xec, 0xf8, 0x68, 0x76, 0x78, 0xdb, 0xf6, 0x91, 0x71, 0x25, 0x9f, 0xc2, 0x88, + 0xeb, 0xb9, 0xb4, 0x3c, 0xc4, 0xb9, 0x2f, 0x64, 0xe2, 0xbe, 0xe1, 0xb9, 0xba, 0xb6, 0x95, 0xc2, + 0xf1, 0xd1, 0xec, 0x08, 0x83, 0x20, 0x67, 0xcc, 0x6a, 0xff, 0x85, 0xd3, 0x29, 0x0f, 0x0f, 0x50, + 0xfb, 0x8f, 0x9c, 0x4e, 0xbc, 0xf6, 0x1f, 0x39, 0x1d, 0x64, 0x5c, 0xad, 0x9f, 0xe6, 0xa0, 0xb8, + 0xe0, 0x37, 0xba, 0x6d, 0xea, 0x86, 0x01, 0xf1, 0x01, 0x3a, 0xb6, 0x6f, 0xb7, 0x69, 0x48, 0xfd, + 0xa0, 0x9c, 0xbb, 0x3e, 0xfc, 0x5a, 0xe9, 0xe6, 0xbb, 0x99, 0x24, 0x6e, 0x29, 0x36, 0x15, 0x22, + 0x87, 0x0f, 0x34, 0x28, 0x40, 0x43, 0x0a, 0x71, 0xa1, 0x68, 0xfb, 0xa1, 0xb3, 0x6b, 0xd7, 0xc2, + 0xa0, 0x3c, 0xc4, 0x45, 0xbe, 0x93, 0x49, 0xe4, 0x82, 0xe4, 0x52, 0x99, 0x96, 0x12, 0x8b, 0x0a, + 0x12, 0x60, 0x24, 0xc2, 0xfa, 0x0f, 0x23, 0x50, 0x50, 0x08, 0x72, 0x1d, 0x46, 0x5c, 0xbb, 0xad, + 0x66, 0xda, 0xb8, 0x2c, 0x38, 0xb2, 0x61, 0xb7, 0x59, 0xef, 0xdb, 0x6d, 0xca, 0x28, 0x3a, 0x76, + 0xd8, 0xe4, 0xc3, 0x6b, 0x50, 0x6c, 0xd9, 0x61, 0x13, 0x39, 0x86, 0x5c, 0x85, 0x91, 0xb6, 0x57, + 0xa7, 0x7c, 0x80, 0xf2, 0x62, 0xf4, 0xd6, 0xbd, 0x3a, 0x45, 0x0e, 0x65, 0xe5, 0x77, 0x7d, 0xaf, + 0x5d, 0x1e, 0x89, 0x97, 0x5f, 0xf1, 0xbd, 0x36, 0x72, 0x0c, 0xf9, 0xbd, 0x1c, 0x4c, 0xa9, 0xea, + 0xdd, 0xf5, 0x6a, 0x76, 0xe8, 0x78, 0x6e, 0x39, 0xcf, 0x47, 0x7b, 0x79, 0xa0, 0x8e, 0x50, 0xcc, + 0x2a, 0x65, 0x29, 0x75, 0x2a, 0x89, 0xc1, 0x1e, 0xc1, 0xe4, 0x26, 0x40, 0xa3, 0xe5, 0xed, 0xd8, + 0x2d, 0xd6, 0x07, 0xe5, 0x51, 0x5e, 0x6b, 0x3d, 0x84, 0xab, 0x1a, 0x83, 0x06, 0x15, 0xd9, 0x83, + 0x31, 0x5b, 0x2c, 0xb9, 0xf2, 0x18, 0xaf, 0xf7, 0x52, 0xc6, 0x7a, 0xc7, 0x96, 0x6d, 0xa5, 0x74, + 0x7c, 0x34, 0x3b, 0x26, 0x81, 0xa8, 0x24, 0x90, 0xd7, 0xa1, 0xe0, 0x75, 0x58, 0x55, 0xed, 0x56, + 0xb9, 0x70, 0x3d, 0xf7, 0x5a, 0xa1, 0x32, 0x25, 0xab, 0x57, 0xd8, 0x94, 0x70, 0xd4, 0x14, 0xe4, + 0x06, 0x8c, 0x05, 0xdd, 0x1d, 0x36, 0x5a, 0xe5, 0x22, 0x6f, 0xcb, 0xa4, 0x24, 0x1e, 0xab, 0x0a, + 0x30, 0x2a, 0x3c, 0x79, 0x13, 0x4a, 0x3e, 0xad, 0x75, 0xfd, 0x80, 0xb2, 0xe1, 0x2b, 0x03, 0xe7, + 0x7d, 0x5e, 0x92, 0x97, 0x30, 0x42, 0xa1, 0x49, 0x67, 0xfd, 0xa7, 0x51, 0xe8, 0xe9, 0x57, 0xf2, + 0x06, 0x94, 0x64, 0x7d, 0xef, 0x7a, 0x8d, 0x80, 0x4f, 0xaf, 0x42, 0x65, 0x92, 0xf1, 0x59, 0x88, + 0xc0, 0x68, 0xd2, 0x90, 0x07, 0x30, 0x14, 0xdc, 0x92, 0xbb, 0xc8, 0x7b, 0x99, 0xfa, 0xaf, 0x7a, + 0x4b, 0x2f, 0x81, 0xd1, 0xe3, 0xa3, 0xd9, 0xa1, 0xea, 0x2d, 0x1c, 0x0a, 0x6e, 0xb1, 0xfd, 0xa3, + 0xe1, 0x84, 0x03, 0xed, 0x1f, 0xab, 0x4e, 0xa8, 0x59, 0xf3, 0xfd, 0x63, 0xd5, 0x09, 0x91, 0x71, + 0x65, 0xbb, 0x5f, 0x33, 0x0c, 0x3b, 0x7c, 0x7a, 0x67, 0xdd, 0xfd, 0x6e, 0x6f, 0x6f, 0x6f, 0x69, + 0xf6, 0x7c, 0xfd, 0x30, 0x08, 0x72, 0xc6, 0xe4, 0x4b, 0xd6, 0x93, 0x02, 0xe7, 0xf9, 0x87, 0x72, + 0x5d, 0xdc, 0x1e, 0x68, 0x5d, 0x78, 0xfe, 0xa1, 0x16, 0x27, 0xc7, 0x44, 0x23, 0xd0, 0x94, 0xc6, + 0x5b, 0x57, 0xdf, 0x0d, 0xf8, 0x32, 0xc8, 0xdc, 0xba, 0xa5, 0x95, 0x6a, 0xa2, 0x75, 0x4b, 0x2b, + 0x55, 0xe4, 0x8c, 0xd9, 0xd8, 0xf8, 0xf6, 0x81, 0x5c, 0x35, 0xd9, 0xc6, 0x06, 0xed, 0x83, 0xf8, + 0xd8, 0xa0, 0x7d, 0x80, 0x8c, 0x2b, 0x63, 0xee, 0x05, 0x01, 0x5f, 0x24, 0x59, 0x99, 0x6f, 0x56, + 0xab, 0x71, 0xe6, 0x9b, 0xd5, 0x2a, 0x32, 0xae, 0x7c, 0x56, 0xd5, 0x02, 0xbe, 0xa8, 0x32, 0xcf, + 0xaa, 0xc5, 0x04, 0xf3, 0xd5, 0xc5, 0x2a, 0x32, 0xae, 0xd6, 0x67, 0x70, 0x51, 0x61, 0x90, 0x76, + 0xbc, 0xc0, 0xe1, 0x43, 0x43, 0x77, 0xc9, 0x3c, 0x14, 0x6b, 0x9e, 0xbb, 0xeb, 0x34, 0xd6, 0xed, + 0x8e, 0xdc, 0xb4, 0xf5, 0x6e, 0xbf, 0xa8, 0x10, 0x18, 0xd1, 0x90, 0x97, 0x60, 0x78, 0x8f, 0x1e, + 0xca, 0xdd, 0xbb, 0x24, 0x49, 0x87, 0xef, 0xd0, 0x43, 0x64, 0xf0, 0x5f, 0x2f, 0x7c, 0xeb, 0x1f, + 0xcf, 0xbe, 0xf0, 0xf5, 0xef, 0x5f, 0x7f, 0xc1, 0xfa, 0xe3, 0x21, 0xb8, 0x92, 0x2a, 0xb3, 0x1a, + 0xda, 0x61, 0x37, 0x20, 0xff, 0x28, 0x07, 0x17, 0xed, 0x34, 0xbc, 0x54, 0x2b, 0x3e, 0x18, 0x68, + 0x4a, 0xc6, 0x38, 0x56, 0x5e, 0x92, 0xf5, 0x4c, 0xef, 0x04, 0x4c, 0xaf, 0x07, 0xeb, 0x1b, 0x76, + 0x62, 0x05, 0x1d, 0xbb, 0x46, 0x65, 0x83, 0x75, 0xdf, 0x6c, 0x28, 0x04, 0x46, 0x34, 0x6c, 0x6f, + 0xac, 0xd3, 0x5d, 0xbb, 0xdb, 0x12, 0x9b, 0x43, 0x21, 0xda, 0x1b, 0x97, 0x04, 0x18, 0x15, 0xde, + 0xe8, 0xa7, 0x3f, 0xcb, 0xc1, 0xf9, 0x94, 0x85, 0xc4, 0x3a, 0xba, 0xeb, 0xb7, 0xe4, 0x98, 0xe8, + 0x8e, 0xbe, 0x87, 0x77, 0x91, 0xc1, 0xc9, 0x37, 0x73, 0x30, 0x69, 0xac, 0xac, 0x85, 0xae, 0x3c, + 0x52, 0xb3, 0x9f, 0x15, 0x31, 0x5e, 0x95, 0xcb, 0x52, 0xe2, 0x64, 0x02, 0x81, 0x49, 0xa9, 0xd6, + 0x7f, 0xce, 0x41, 0x92, 0x88, 0xd8, 0x70, 0xae, 0x1b, 0x50, 0x9f, 0x75, 0x4d, 0x95, 0xd6, 0x7c, + 0x1a, 0xca, 0x41, 0x7d, 0x65, 0x4e, 0x68, 0xb2, 0xac, 0x16, 0x73, 0x4c, 0x6f, 0x9f, 0xdb, 0x7f, + 0x63, 0x4e, 0x50, 0xdc, 0xa1, 0x87, 0x55, 0xda, 0xa2, 0x8c, 0x47, 0x85, 0x1c, 0x1f, 0xcd, 0x9e, + 0xbb, 0x17, 0x63, 0x80, 0x09, 0x86, 0x4c, 0x44, 0xc7, 0x0e, 0x82, 0x03, 0xcf, 0xaf, 0x4b, 0x11, + 0x43, 0xa7, 0x16, 0xb1, 0x15, 0x63, 0x80, 0x09, 0x86, 0xd6, 0xbf, 0xc9, 0xc1, 0x58, 0xc5, 0xae, + 0xed, 0x79, 0xbb, 0xbb, 0xec, 0x94, 0xac, 0x77, 0x7d, 0xa1, 0x4b, 0x88, 0x31, 0xd1, 0xa7, 0xe4, + 0x92, 0x84, 0xa3, 0xa6, 0x20, 0xdb, 0x30, 0x2a, 0xba, 0x43, 0x56, 0xea, 0x57, 0x8d, 0x4a, 0x69, + 0x0d, 0x9e, 0x0f, 0x07, 0xd3, 0xe0, 0xe7, 0x84, 0x06, 0x3f, 0xb7, 0xe6, 0x86, 0x9b, 0x4c, 0x2b, + 0x76, 0xdc, 0x46, 0x05, 0x8e, 0x8f, 0x66, 0x47, 0x57, 0x38, 0x0f, 0x94, 0xbc, 0xd8, 0x81, 0xda, + 0xb6, 0x3f, 0x57, 0xe2, 0xf8, 0x1c, 0x2b, 0x46, 0x07, 0xea, 0x7a, 0x84, 0x42, 0x93, 0xce, 0xfa, + 0x04, 0xf2, 0x8b, 0x76, 0xad, 0x49, 0xc9, 0xbd, 0xe4, 0x62, 0x2f, 0xdd, 0x7c, 0x2d, 0xad, 0xb7, + 0xf4, 0xc2, 0x37, 0x3b, 0x6c, 0xa2, 0xdf, 0x96, 0x60, 0xfd, 0x28, 0x07, 0x97, 0x17, 0x5b, 0xdd, + 0x20, 0xa4, 0xfe, 0x03, 0x39, 0xaf, 0xb6, 0x69, 0xbb, 0xd3, 0xb2, 0x43, 0x4a, 0xfe, 0x32, 0x14, + 0x98, 0xf5, 0x54, 0xb7, 0x43, 0x5b, 0x4a, 0xec, 0xdf, 0x15, 0x7c, 0x66, 0x32, 0x6a, 0x56, 0x87, + 0xcd, 0x9d, 0x47, 0xb4, 0x16, 0xae, 0xd3, 0xd0, 0x8e, 0xb4, 0xa5, 0x08, 0x86, 0x9a, 0x2b, 0xd9, + 0x83, 0x91, 0xa0, 0x43, 0x6b, 0xb2, 0xa3, 0xd7, 0x32, 0x4d, 0xfe, 0x64, 0xb5, 0xab, 0x1d, 0x5a, + 0x8b, 0x54, 0x4b, 0xf6, 0x85, 0x5c, 0x88, 0xf5, 0x3f, 0x72, 0x70, 0xa5, 0x4f, 0x53, 0xef, 0x3a, + 0x41, 0x48, 0x3e, 0xee, 0x69, 0xee, 0xdc, 0xc9, 0x9a, 0xcb, 0x4a, 0xf3, 0xc6, 0xea, 0x59, 0xa5, + 0x20, 0x46, 0x53, 0x3f, 0x83, 0xbc, 0x13, 0xd2, 0xb6, 0xd2, 0xea, 0xef, 0x66, 0x6a, 0x6b, 0x9f, + 0xea, 0x57, 0x26, 0x94, 0x55, 0xb8, 0xc6, 0x44, 0xa0, 0x90, 0x64, 0xfd, 0xfb, 0x1c, 0xb0, 0x41, + 0xaf, 0x3b, 0x52, 0x0b, 0x1b, 0x09, 0x0f, 0x3b, 0x4a, 0xbb, 0x57, 0xbb, 0xea, 0xc8, 0xf6, 0x61, + 0x87, 0x99, 0x91, 0x13, 0x9a, 0x90, 0x01, 0x90, 0x93, 0x92, 0x4f, 0x60, 0x34, 0xe0, 0x1b, 0xbe, + 0xdc, 0x41, 0x57, 0x64, 0xa1, 0x51, 0x71, 0x0c, 0x3c, 0x3e, 0x9a, 0x3d, 0x91, 0xed, 0x3d, 0xa7, + 0x79, 0x8b, 0x72, 0x28, 0xb9, 0xb2, 0x3d, 0xb7, 0x4d, 0x83, 0xc0, 0x6e, 0x50, 0xb9, 0x1e, 0xf4, + 0x9e, 0xbb, 0x2e, 0xc0, 0xa8, 0xf0, 0xd6, 0x6f, 0x02, 0x2c, 0x7a, 0x6e, 0xe8, 0xb8, 0x5d, 0xba, + 0xe9, 0x92, 0x97, 0x21, 0x4f, 0x7d, 0xdf, 0xf3, 0xa5, 0x2e, 0xa9, 0x9b, 0xbf, 0xcc, 0x80, 0x28, + 0x70, 0xe4, 0x55, 0xb6, 0x8e, 0x9d, 0x16, 0xad, 0xf3, 0xda, 0x17, 0x2a, 0xe7, 0x54, 0xed, 0x57, + 0x38, 0x14, 0x25, 0xd6, 0x9a, 0x83, 0xb1, 0x45, 0x66, 0x6a, 0x53, 0x9f, 0xf1, 0x35, 0x8d, 0xed, + 0x89, 0x98, 0xb1, 0xad, 0x8c, 0xea, 0x6d, 0xb8, 0xb8, 0xe8, 0x53, 0x36, 0xd3, 0x6e, 0x55, 0xba, + 0xb5, 0x3d, 0x1a, 0x0a, 0x4d, 0x3b, 0x20, 0x6f, 0xc3, 0x84, 0xc7, 0x67, 0xf9, 0x5d, 0xaf, 0xb6, + 0xe7, 0xb8, 0x0d, 0x79, 0x90, 0x5c, 0x94, 0x5c, 0x26, 0x36, 0x4d, 0x24, 0xc6, 0x69, 0xad, 0xef, + 0x0c, 0xc1, 0xf8, 0xa2, 0xef, 0xb9, 0x6a, 0x6c, 0x9f, 0xc3, 0xea, 0x6b, 0xc4, 0x56, 0x5f, 0x36, + 0xf3, 0xca, 0xac, 0x72, 0xbf, 0x95, 0x47, 0x3c, 0x3d, 0x8f, 0x84, 0xde, 0xbd, 0x3a, 0xb8, 0x28, + 0xce, 0x2e, 0x1a, 0xd2, 0xf8, 0xc4, 0xb2, 0xbe, 0x97, 0x83, 0x29, 0x93, 0xfc, 0x39, 0xac, 0xef, + 0xdd, 0xf8, 0xfa, 0x5e, 0x18, 0xb8, 0x89, 0x7d, 0x16, 0xf5, 0xff, 0xc9, 0xc7, 0x9b, 0xc6, 0xba, + 0x99, 0x59, 0xcd, 0xe3, 0x07, 0x06, 0x40, 0xb6, 0x6f, 0x61, 0xa0, 0x0d, 0x95, 0x0f, 0xe7, 0x2f, + 0xcb, 0x4a, 0x8c, 0x9b, 0xd0, 0xc7, 0x89, 0x6f, 0x8c, 0x09, 0x67, 0xc7, 0x6d, 0x50, 0x6b, 0xd2, + 0x7a, 0xb7, 0xa5, 0x54, 0x2f, 0xdd, 0x71, 0x55, 0x09, 0x47, 0x4d, 0x41, 0x3e, 0x86, 0xe9, 0x9a, + 0xe7, 0xd6, 0xba, 0xbe, 0x4f, 0xdd, 0xda, 0xe1, 0x16, 0xf7, 0xf5, 0xc9, 0xed, 0x60, 0x4e, 0x16, + 0x9b, 0x5e, 0x4c, 0x12, 0x3c, 0x4e, 0x03, 0x62, 0x2f, 0x23, 0x61, 0xf2, 0x06, 0x1d, 0xea, 0xd6, + 0xb9, 0x55, 0x56, 0x30, 0x4d, 0x5e, 0x0e, 0x46, 0x85, 0x27, 0xf7, 0xe0, 0x72, 0x10, 0x32, 0x05, + 0xc9, 0x6d, 0x2c, 0x51, 0xbb, 0xde, 0x72, 0x5c, 0xa6, 0xae, 0x78, 0x6e, 0x3d, 0xe0, 0x86, 0xd6, + 0x70, 0xe5, 0xca, 0xf1, 0xd1, 0xec, 0xe5, 0x6a, 0x3a, 0x09, 0xf6, 0x2b, 0x4b, 0x3e, 0x81, 0x99, + 0xa0, 0x5b, 0xab, 0xd1, 0x20, 0xd8, 0xed, 0xb6, 0x3e, 0xf0, 0x76, 0x82, 0xdb, 0x4e, 0xc0, 0x74, + 0xad, 0xbb, 0x4e, 0xdb, 0x09, 0xb9, 0x31, 0x95, 0xaf, 0x5c, 0x3b, 0x3e, 0x9a, 0x9d, 0xa9, 0xf6, + 0xa5, 0xc2, 0x27, 0x70, 0x20, 0x08, 0x97, 0xc4, 0x46, 0xd6, 0xc3, 0x7b, 0x8c, 0xf3, 0x9e, 0x39, + 0x3e, 0x9a, 0xbd, 0xb4, 0x92, 0x4a, 0x81, 0x7d, 0x4a, 0xb2, 0x11, 0x0c, 0x9d, 0x36, 0xfd, 0xc2, + 0x73, 0x29, 0xb7, 0x98, 0x8c, 0x11, 0xdc, 0x96, 0x70, 0xd4, 0x14, 0xe4, 0x51, 0x34, 0xf9, 0xd8, + 0xa2, 0x90, 0x66, 0xd0, 0xe9, 0x77, 0xab, 0x0b, 0xc7, 0x47, 0xb3, 0x53, 0x0f, 0x0c, 0x4e, 0x6c, + 0x61, 0x61, 0x8c, 0xb7, 0xf5, 0xef, 0x86, 0x80, 0xf4, 0x6e, 0x04, 0xe4, 0x0e, 0x8c, 0xda, 0xb5, + 0xd0, 0xd9, 0xa7, 0xd2, 0x4f, 0xf7, 0x72, 0x9a, 0x6a, 0x24, 0x44, 0x21, 0xdd, 0xa5, 0x6c, 0x86, + 0xd0, 0x68, 0xf7, 0x58, 0xe0, 0x45, 0x51, 0xb2, 0x20, 0x1e, 0x4c, 0xb7, 0xec, 0x20, 0x54, 0x73, + 0xb5, 0xce, 0x9a, 0x2c, 0x37, 0xc9, 0x3f, 0x77, 0xb2, 0x46, 0xb1, 0x12, 0x95, 0x8b, 0x6c, 0xe6, + 0xde, 0x4d, 0x32, 0xc2, 0x5e, 0xde, 0xc4, 0x07, 0xa8, 0xa9, 0x23, 0x92, 0xed, 0x91, 0xd9, 0x3d, + 0x8d, 0xfa, 0xa4, 0x8d, 0xb6, 0x7e, 0x0d, 0x0a, 0xd0, 0x90, 0x62, 0xfd, 0x64, 0x14, 0xc6, 0x96, + 0x16, 0x56, 0xb7, 0xed, 0x60, 0xef, 0x04, 0x8e, 0x3f, 0x36, 0x21, 0xa4, 0xb2, 0x91, 0x5c, 0xd2, + 0x4a, 0x09, 0x41, 0x4d, 0x41, 0x3c, 0x28, 0xda, 0xca, 0x8d, 0x2a, 0xb7, 0xfc, 0x77, 0x33, 0x1a, + 0x36, 0x92, 0x8b, 0xe9, 0xc6, 0x94, 0x20, 0x8c, 0x64, 0x90, 0x00, 0x4a, 0x4a, 0x38, 0x33, 0x42, + 0x47, 0x06, 0xf1, 0x6d, 0x47, 0x7c, 0x84, 0x3f, 0xc4, 0x00, 0xa0, 0x29, 0x85, 0x7c, 0x0d, 0xc6, + 0xeb, 0x94, 0xed, 0x1c, 0xd4, 0xad, 0x39, 0x94, 0x6d, 0x12, 0xc3, 0xac, 0x5f, 0xd8, 0x66, 0xb9, + 0x64, 0xc0, 0x31, 0x46, 0x45, 0x1e, 0x41, 0xf1, 0xc0, 0x09, 0x9b, 0x7c, 0x4f, 0x2f, 0x8f, 0xf2, + 0xa1, 0xfe, 0xb5, 0x4c, 0x15, 0x65, 0x1c, 0xa2, 0x6e, 0x79, 0xa0, 0x78, 0x62, 0xc4, 0x9e, 0x19, + 0xc1, 0xec, 0x83, 0xfb, 0x9a, 0xf9, 0x6e, 0x50, 0x8c, 0x17, 0xe0, 0x08, 0x8c, 0x68, 0x48, 0x00, + 0xe3, 0xec, 0xa3, 0x4a, 0x3f, 0xeb, 0xb2, 0x15, 0x22, 0xbd, 0x25, 0xd9, 0x3c, 0xd0, 0x8a, 0x89, + 0xe8, 0x91, 0x07, 0x06, 0x5b, 0x8c, 0x09, 0x61, 0xb3, 0xef, 0xa0, 0x49, 0x5d, 0xe9, 0x92, 0xd4, + 0xb3, 0xef, 0x41, 0x93, 0xba, 0xc8, 0x31, 0xc4, 0xe3, 0xeb, 0x43, 0x2a, 0x7f, 0xdc, 0x17, 0x99, + 0xd5, 0x2b, 0x18, 0xe9, 0x90, 0x95, 0x73, 0x72, 0x71, 0xc8, 0x6f, 0x34, 0x44, 0x30, 0xd5, 0xd1, + 0x73, 0x97, 0x3f, 0x77, 0xc2, 0x72, 0x89, 0x57, 0x4a, 0xef, 0x14, 0x9b, 0x1c, 0x8a, 0x12, 0x2b, + 0x9c, 0x06, 0x6c, 0x70, 0x83, 0xf2, 0x78, 0x5c, 0x81, 0x15, 0x33, 0x20, 0x40, 0x85, 0xb7, 0xfe, + 0x75, 0x0e, 0x4a, 0x6c, 0xbd, 0xa9, 0x35, 0xf2, 0x2a, 0x8c, 0x86, 0xb6, 0xdf, 0x90, 0xd6, 0xb5, + 0x21, 0x62, 0x9b, 0x43, 0x51, 0x62, 0x89, 0x0d, 0xf9, 0xd0, 0x0e, 0xf6, 0x94, 0x5e, 0xf1, 0x1b, + 0x99, 0x9a, 0x2d, 0x17, 0x7a, 0xa4, 0x52, 0xb0, 0xaf, 0x00, 0x05, 0x67, 0xf2, 0x1a, 0x14, 0xd8, + 0x39, 0xb0, 0x62, 0x07, 0xca, 0xf7, 0x31, 0xce, 0x16, 0xf6, 0x8a, 0x84, 0xa1, 0xc6, 0x5a, 0x6f, + 0x42, 0x7e, 0x79, 0x9f, 0xba, 0xfc, 0x80, 0x08, 0xa4, 0x71, 0x99, 0xb4, 0xa8, 0x95, 0xd1, 0x89, + 0x9a, 0xc2, 0xfa, 0x18, 0xce, 0x2d, 0x7f, 0x4e, 0x6b, 0xdd, 0xd0, 0xf3, 0x85, 0x11, 0x4a, 0x3e, + 0x00, 0x12, 0x50, 0x7f, 0xdf, 0xa9, 0xd1, 0x85, 0x5a, 0x8d, 0x29, 0xdf, 0x1b, 0xd1, 0xfe, 0x33, + 0x23, 0x39, 0x91, 0x6a, 0x0f, 0x05, 0xa6, 0x94, 0xb2, 0xfe, 0x41, 0x0e, 0x4a, 0x86, 0xf7, 0x8c, + 0xed, 0x3e, 0x8d, 0xc5, 0xaa, 0x50, 0xcd, 0xa5, 0x22, 0xf4, 0x6e, 0x56, 0x97, 0x9c, 0xe0, 0x12, + 0xad, 0x1a, 0x0d, 0xc2, 0x48, 0xc6, 0x53, 0xdc, 0x6a, 0xd6, 0xbf, 0xc8, 0x41, 0x54, 0x8e, 0x8d, + 0xfb, 0x4e, 0x54, 0x35, 0x63, 0xdc, 0x25, 0x5f, 0x89, 0x25, 0xbf, 0x05, 0x97, 0xe3, 0x6d, 0xe5, + 0xf6, 0xfc, 0xe9, 0x7d, 0x25, 0x42, 0x69, 0x49, 0xe7, 0x84, 0xfd, 0x44, 0x58, 0xf7, 0x21, 0xbf, + 0x6a, 0x77, 0x1b, 0xf4, 0x44, 0x16, 0x11, 0x9b, 0x40, 0x3e, 0xb5, 0x5b, 0xa1, 0x3a, 0x27, 0xe5, + 0x04, 0x42, 0x09, 0x43, 0x8d, 0xb5, 0xfe, 0x64, 0x04, 0x4a, 0x86, 0xff, 0x9c, 0xad, 0x7d, 0x9f, + 0x76, 0xbc, 0xe4, 0xc9, 0x83, 0xb4, 0xe3, 0x21, 0xc7, 0xb0, 0x99, 0xe6, 0xd3, 0x7d, 0x27, 0x70, + 0x3c, 0x37, 0x79, 0xf2, 0xa0, 0x84, 0xa3, 0xa6, 0x20, 0xb3, 0x90, 0xaf, 0xd3, 0x4e, 0xd8, 0xe4, + 0xf3, 0x78, 0xa4, 0x52, 0x64, 0x55, 0x5d, 0x62, 0x00, 0x14, 0x70, 0x46, 0xb0, 0x4b, 0xc3, 0x5a, + 0xb3, 0x3c, 0xc2, 0x77, 0x6b, 0x4e, 0xb0, 0xc2, 0x00, 0x28, 0xe0, 0x29, 0xde, 0xaf, 0xfc, 0xb3, + 0xf7, 0x7e, 0x8d, 0x9e, 0xb1, 0xf7, 0x8b, 0x74, 0xe0, 0x7c, 0x10, 0x34, 0xb7, 0x7c, 0x67, 0xdf, + 0x0e, 0x69, 0x34, 0x73, 0xc6, 0x4e, 0x23, 0xe7, 0xf2, 0xf1, 0xd1, 0xec, 0xf9, 0x6a, 0xf5, 0x76, + 0x92, 0x0b, 0xa6, 0xb1, 0x26, 0x55, 0xb8, 0xe8, 0xb8, 0x01, 0xad, 0x75, 0x7d, 0xba, 0xd6, 0x70, + 0x3d, 0x9f, 0xde, 0xf6, 0x02, 0xc6, 0x4e, 0x86, 0xa5, 0xb4, 0x17, 0x77, 0x2d, 0x8d, 0x08, 0xd3, + 0xcb, 0x5a, 0xdf, 0xc9, 0xc1, 0xb8, 0x19, 0x32, 0x20, 0x01, 0x40, 0x73, 0x69, 0xa5, 0x2a, 0x76, + 0x11, 0xb9, 0xb8, 0xdf, 0xcb, 0x1c, 0x89, 0x10, 0x6c, 0x22, 0x55, 0x29, 0x82, 0xa1, 0x21, 0xe6, + 0x04, 0x51, 0xcf, 0x97, 0x21, 0xbf, 0xeb, 0xf9, 0x35, 0x2a, 0xb7, 0x4f, 0xbd, 0x4a, 0x56, 0x18, + 0x10, 0x05, 0xce, 0xfa, 0x51, 0x0e, 0x0c, 0x09, 0xe4, 0xaf, 0xc2, 0x04, 0x93, 0x71, 0xc7, 0xdf, + 0x89, 0xb5, 0xa6, 0x92, 0xb9, 0x35, 0x9a, 0x53, 0xe4, 0x71, 0x88, 0x81, 0x31, 0x2e, 0x8f, 0xfc, + 0x79, 0x28, 0xda, 0xf5, 0xba, 0x4f, 0x83, 0x80, 0x8a, 0xd3, 0xa5, 0x28, 0xfc, 0x84, 0x0b, 0x0a, + 0x88, 0x11, 0x9e, 0x2d, 0xc3, 0x66, 0x7d, 0x37, 0x60, 0x33, 0x5b, 0x1a, 0x67, 0x7a, 0x19, 0x32, + 0x21, 0x0c, 0x8e, 0x9a, 0xc2, 0xfa, 0x83, 0x11, 0x88, 0xcb, 0x26, 0x75, 0x98, 0xdc, 0xf3, 0x77, + 0x16, 0xb9, 0x2f, 0x33, 0x8b, 0x57, 0xf9, 0xfc, 0xf1, 0xd1, 0xec, 0xe4, 0x9d, 0x38, 0x07, 0x4c, + 0xb2, 0x94, 0x52, 0xee, 0xd0, 0xc3, 0xd0, 0xde, 0xc9, 0xb2, 0x59, 0x2a, 0x29, 0x26, 0x07, 0x4c, + 0xb2, 0x24, 0x6f, 0x42, 0x69, 0xcf, 0xdf, 0x51, 0x8b, 0x3c, 0xe9, 0xca, 0xbd, 0x13, 0xa1, 0xd0, + 0xa4, 0x63, 0x5d, 0xb8, 0xe7, 0xef, 0xb0, 0x4d, 0x51, 0x05, 0xc0, 0x75, 0x17, 0xde, 0x91, 0x70, + 0xd4, 0x14, 0xa4, 0x03, 0x64, 0x4f, 0xf5, 0x9e, 0xf6, 0xdc, 0xca, 0xbd, 0xe8, 0xe4, 0x8e, 0xdf, + 0x4b, 0xec, 0x1c, 0xbd, 0xd3, 0xc3, 0x07, 0x53, 0x78, 0x93, 0xdf, 0x84, 0xcb, 0x7b, 0xfe, 0x8e, + 0x3c, 0x2a, 0xb6, 0x7c, 0xc7, 0xad, 0x39, 0x9d, 0x58, 0xe4, 0x7b, 0x56, 0x56, 0xf7, 0xf2, 0x9d, + 0x74, 0x32, 0xec, 0x57, 0xde, 0xfa, 0x43, 0xb6, 0x8e, 0x8d, 0xc0, 0xe6, 0xd3, 0x02, 0x24, 0xbb, + 0x30, 0xd6, 0xa4, 0x76, 0x9d, 0xfa, 0x4a, 0xed, 0x79, 0x3b, 0xdb, 0xaa, 0xe0, 0x3c, 0x22, 0xa5, + 0x4c, 0x7c, 0x07, 0xa8, 0x98, 0x5b, 0x9b, 0x30, 0x2a, 0x60, 0x27, 0x30, 0x81, 0xf4, 0x49, 0x38, + 0xf4, 0x04, 0xdf, 0xe0, 0xb7, 0x72, 0x50, 0xe4, 0x96, 0x74, 0x83, 0xa9, 0xd3, 0xba, 0xc8, 0xf0, + 0x13, 0x0e, 0xcf, 0x5d, 0x18, 0x13, 0x47, 0x7e, 0xc0, 0xcf, 0xa4, 0xac, 0x6d, 0x15, 0xe9, 0x42, + 0x51, 0x5b, 0x85, 0x3a, 0x11, 0xa0, 0x62, 0x6e, 0xfd, 0xf7, 0x1c, 0x8c, 0xae, 0xb9, 0x9d, 0xee, + 0xcf, 0x49, 0x66, 0xcb, 0x3a, 0x8c, 0x30, 0x23, 0x28, 0x9e, 0x3f, 0x35, 0x5e, 0x79, 0xc5, 0xcc, + 0x9d, 0x2a, 0xc7, 0x73, 0xa7, 0xd0, 0x3e, 0x50, 0x7e, 0x67, 0x51, 0xc6, 0x88, 0xf4, 0xb5, 0x60, + 0xe4, 0xae, 0xe3, 0xee, 0x9d, 0x6c, 0x9e, 0x04, 0x35, 0xaf, 0xd3, 0x33, 0x4f, 0xaa, 0x0c, 0x88, + 0x02, 0xa7, 0xe6, 0xff, 0x70, 0xfa, 0xfc, 0xb7, 0xbe, 0x91, 0x83, 0xe9, 0x75, 0xda, 0xf6, 0x9c, + 0x2f, 0xec, 0xc8, 0x6d, 0xce, 0x0a, 0x35, 0x9d, 0x50, 0xfa, 0xbc, 0x75, 0xa1, 0xdb, 0x4e, 0x88, + 0x0c, 0xfe, 0x14, 0x35, 0x94, 0x47, 0x8b, 0xd9, 0x56, 0xb9, 0x11, 0xed, 0x59, 0x51, 0xb4, 0x58, + 0x21, 0x30, 0xa2, 0xb1, 0xfe, 0x34, 0x07, 0x63, 0xa2, 0x12, 0x54, 0xf1, 0xce, 0xf5, 0xe1, 0xfd, + 0x10, 0xf2, 0xbc, 0x9c, 0xdc, 0x6d, 0x7f, 0x3d, 0x9b, 0x6d, 0xc6, 0x38, 0x08, 0x8d, 0x8c, 0xff, + 0x44, 0xc1, 0x93, 0x69, 0xcc, 0x6d, 0xfb, 0xf3, 0x05, 0x1d, 0x24, 0xd0, 0x1a, 0xf3, 0x3a, 0x87, + 0xa2, 0xc4, 0x5a, 0x5f, 0x1f, 0x86, 0x82, 0xf2, 0x1a, 0x91, 0xdf, 0xc9, 0x41, 0xc9, 0x76, 0x5d, + 0x2f, 0xb4, 0x85, 0x53, 0x45, 0x4c, 0xf2, 0x8d, 0x4c, 0x15, 0x53, 0x4c, 0xe7, 0x16, 0x22, 0x86, + 0xcb, 0x6e, 0xe8, 0x1f, 0x46, 0x9b, 0xbe, 0x81, 0x41, 0x53, 0x2e, 0xf9, 0x0c, 0x46, 0x5b, 0xf6, + 0x0e, 0x6d, 0xa9, 0x39, 0xbf, 0x36, 0x58, 0x0d, 0xee, 0x72, 0x5e, 0x42, 0xb8, 0xee, 0x07, 0x01, + 0x44, 0x29, 0x68, 0xe6, 0x5d, 0x98, 0x4a, 0x56, 0x94, 0x4c, 0x19, 0xe3, 0x27, 0x86, 0xec, 0x42, + 0x6c, 0x3b, 0x53, 0x13, 0x7e, 0xe8, 0xad, 0xdc, 0xcc, 0xaf, 0x41, 0xc9, 0x10, 0x73, 0x9a, 0xa2, + 0xd6, 0x87, 0x50, 0x5a, 0xa7, 0xa1, 0xef, 0xd4, 0x38, 0x83, 0xa7, 0xcd, 0x9a, 0x13, 0xed, 0xa8, + 0x5f, 0xb0, 0x49, 0xc8, 0x58, 0x06, 0xc4, 0x03, 0xe8, 0xf8, 0x5e, 0x9b, 0x86, 0x4d, 0xda, 0x55, + 0x23, 0x9a, 0x4d, 0xf9, 0xdb, 0xd2, 0x6c, 0x84, 0x1b, 0x20, 0xfa, 0x46, 0x43, 0x84, 0x75, 0x03, + 0xf2, 0xeb, 0xdd, 0x90, 0x7e, 0xfe, 0xf4, 0x55, 0x6f, 0x3d, 0x84, 0x71, 0x4e, 0x7a, 0xdb, 0x6b, + 0xb1, 0x0d, 0x85, 0xb5, 0xad, 0xcd, 0xbe, 0x93, 0x76, 0x13, 0x27, 0x42, 0x81, 0x63, 0x33, 0xbb, + 0xe9, 0xb5, 0xea, 0xd4, 0x97, 0x3d, 0xa0, 0x47, 0xf4, 0x36, 0x87, 0xa2, 0xc4, 0x5a, 0x3f, 0xce, + 0x41, 0x89, 0x17, 0x94, 0x1b, 0x41, 0x0b, 0xc6, 0x9a, 0x42, 0x8e, 0xec, 0x85, 0x6c, 0x8e, 0x7e, + 0xb3, 0xc2, 0xc6, 0x21, 0x29, 0x00, 0xa8, 0x44, 0x30, 0x69, 0x07, 0xb6, 0x13, 0x32, 0x69, 0x43, + 0x67, 0x2e, 0xed, 0x81, 0xe0, 0x8c, 0x4a, 0x84, 0xf5, 0xcf, 0xa7, 0x00, 0x36, 0xbc, 0x3a, 0x95, + 0x4d, 0x9d, 0x81, 0x21, 0xa7, 0x2e, 0x3b, 0x11, 0x64, 0xa1, 0xa1, 0xb5, 0x25, 0x1c, 0x72, 0xea, + 0x7a, 0x54, 0x86, 0xfa, 0xee, 0xc5, 0x6f, 0x42, 0xa9, 0xee, 0x04, 0x9d, 0x96, 0x7d, 0xb8, 0x91, + 0xa2, 0xa9, 0x2d, 0x45, 0x28, 0x34, 0xe9, 0xc8, 0xeb, 0x32, 0x54, 0x2a, 0xb4, 0xb4, 0x72, 0x22, + 0x54, 0x5a, 0x60, 0xd5, 0x33, 0xa2, 0xa4, 0x6f, 0xc1, 0xb8, 0x72, 0x0b, 0x72, 0x29, 0x79, 0x5e, + 0xea, 0x82, 0x0a, 0x9c, 0x6c, 0x1b, 0x38, 0x8c, 0x51, 0x26, 0xdd, 0x96, 0xa3, 0xcf, 0xc5, 0x6d, + 0xb9, 0x04, 0x53, 0x41, 0xe8, 0xf9, 0xb4, 0xae, 0x28, 0xd6, 0x96, 0xca, 0x24, 0xd6, 0xd0, 0xa9, + 0x6a, 0x02, 0x8f, 0x3d, 0x25, 0xc8, 0x16, 0x5c, 0x38, 0x48, 0x44, 0xa1, 0x79, 0xe3, 0xcf, 0x73, + 0x4e, 0x57, 0x25, 0xa7, 0x0b, 0x0f, 0x52, 0x68, 0x30, 0xb5, 0x24, 0x79, 0x1b, 0x26, 0x54, 0x35, + 0xf9, 0x51, 0x59, 0xbe, 0xc0, 0x59, 0x69, 0x5b, 0x66, 0xdb, 0x44, 0x62, 0x9c, 0x96, 0xfc, 0x2a, + 0xe4, 0x3b, 0x4d, 0x3b, 0xa0, 0xd2, 0xcb, 0xa9, 0x5c, 0x48, 0xf9, 0x2d, 0x06, 0x7c, 0x7c, 0x34, + 0x5b, 0x64, 0x63, 0xc6, 0x3f, 0x50, 0x10, 0x92, 0x9b, 0x00, 0x3b, 0x5e, 0xd7, 0xad, 0xdb, 0xfe, + 0xe1, 0xda, 0x92, 0x0c, 0x72, 0x68, 0x1d, 0xa6, 0xa2, 0x31, 0x68, 0x50, 0x99, 0xf1, 0xea, 0xe2, + 0x93, 0xe3, 0xd5, 0xe4, 0x21, 0x14, 0x79, 0x40, 0x88, 0xd6, 0x17, 0x42, 0xe9, 0xb1, 0x3c, 0x4d, + 0xec, 0x40, 0x9f, 0xcc, 0x55, 0xc5, 0x04, 0x23, 0x7e, 0xe4, 0x13, 0x80, 0x5d, 0xc7, 0x75, 0x82, + 0x26, 0xe7, 0x5e, 0x3a, 0x35, 0x77, 0xdd, 0xce, 0x15, 0xcd, 0x05, 0x0d, 0x8e, 0xe4, 0x63, 0x98, + 0xa6, 0x41, 0xe8, 0xb4, 0xed, 0x90, 0xd6, 0x75, 0xc6, 0x4a, 0x99, 0xc7, 0xc0, 0x74, 0x48, 0x6e, + 0x39, 0x49, 0xf0, 0x38, 0x0d, 0x88, 0xbd, 0x8c, 0xc8, 0x5b, 0x50, 0xe8, 0xf8, 0x5e, 0x83, 0x19, + 0x96, 0xe5, 0x99, 0xd8, 0x74, 0x29, 0x6c, 0x49, 0xf8, 0x63, 0xe3, 0x37, 0x6a, 0x6a, 0xf2, 0xdf, + 0x72, 0x30, 0xed, 0xd3, 0xc0, 0xeb, 0xfa, 0x35, 0x1a, 0xe8, 0x8a, 0x5d, 0xe4, 0x9b, 0xd2, 0xfd, + 0x8c, 0xb9, 0xe6, 0x6a, 0xa7, 0x99, 0xc3, 0x24, 0x63, 0x71, 0xca, 0x52, 0xd5, 0xe0, 0x1e, 0xfc, + 0xe3, 0x34, 0xe0, 0x37, 0x7e, 0x30, 0x3b, 0xdb, 0x7b, 0xbd, 0x41, 0x33, 0x67, 0x33, 0xfd, 0x6f, + 0xfe, 0x60, 0x76, 0x4a, 0x7d, 0x47, 0xfd, 0xd4, 0xd3, 0x2e, 0x76, 0x84, 0x74, 0xbc, 0xfa, 0xda, + 0x96, 0x74, 0x2d, 0xeb, 0x23, 0x64, 0x8b, 0x01, 0x51, 0xe0, 0xc8, 0x6b, 0x50, 0xa8, 0xdb, 0xb4, + 0xed, 0xb9, 0xb4, 0x5e, 0x9e, 0x88, 0x5c, 0x6f, 0x4b, 0x12, 0x86, 0x1a, 0x4b, 0x3e, 0x85, 0x51, + 0x87, 0xab, 0xff, 0xe5, 0x73, 0x7c, 0xc2, 0x64, 0x33, 0x33, 0x84, 0x05, 0x21, 0x32, 0x9c, 0xc4, + 0x6f, 0x94, 0x6c, 0x49, 0x0d, 0xc6, 0xbc, 0x6e, 0xc8, 0x25, 0x4c, 0x72, 0x09, 0xd9, 0x7c, 0xd5, + 0x9b, 0x82, 0x87, 0x48, 0x78, 0x96, 0x1f, 0xa8, 0x38, 0xb3, 0xf6, 0xd6, 0x9a, 0x4e, 0xab, 0xee, + 0x53, 0xb7, 0x3c, 0xc5, 0x7d, 0x16, 0xbc, 0xbd, 0x8b, 0x12, 0x86, 0x1a, 0x4b, 0xfe, 0x22, 0x4c, + 0x78, 0xdd, 0x90, 0xaf, 0x5e, 0x36, 0xca, 0x41, 0x79, 0x9a, 0x93, 0x4f, 0xf3, 0x4c, 0x0c, 0x13, + 0x81, 0x71, 0x3a, 0xb6, 0x9f, 0x37, 0xbd, 0x20, 0x64, 0x1f, 0x7c, 0x4b, 0xbb, 0x14, 0xdf, 0xcf, + 0x6f, 0x1b, 0x38, 0x8c, 0x51, 0x92, 0xdf, 0xcb, 0xc1, 0x74, 0x3b, 0xa9, 0xb6, 0x97, 0x2f, 0xf3, + 0xce, 0x58, 0xc9, 0xa8, 0xf8, 0x25, 0xb8, 0x89, 0xa8, 0x62, 0x0f, 0x18, 0x7b, 0xe5, 0xf2, 0x24, + 0xcd, 0xe0, 0xd0, 0xad, 0x35, 0x7d, 0xcf, 0x8d, 0xd7, 0xe8, 0x45, 0x5e, 0xa3, 0x8d, 0xec, 0x2b, + 0x26, 0x8d, 0x6b, 0xe5, 0xc5, 0xe3, 0xa3, 0xd9, 0x8b, 0xa9, 0x28, 0x4c, 0xaf, 0xc7, 0xcc, 0x12, + 0x5c, 0x4a, 0x5f, 0x75, 0x4f, 0x53, 0x3a, 0x87, 0x4d, 0xa5, 0x73, 0x05, 0x5e, 0xec, 0x5b, 0x29, + 0xb6, 0x65, 0x2b, 0xe5, 0x25, 0x17, 0xdf, 0xb2, 0x7b, 0x34, 0x8f, 0x73, 0x30, 0x6e, 0x5e, 0x3d, + 0xe1, 0x71, 0x05, 0x23, 0xe5, 0x97, 0x78, 0x50, 0xf4, 0xaa, 0x67, 0x11, 0x57, 0xd8, 0xac, 0xf6, + 0xc4, 0x15, 0x34, 0x08, 0x23, 0x19, 0x4f, 0x8b, 0x2b, 0xfc, 0xe9, 0x10, 0x44, 0xe5, 0xc8, 0xeb, + 0x50, 0xa0, 0x6e, 0xbd, 0xe3, 0x39, 0x6e, 0x98, 0x8c, 0xc8, 0x2c, 0x4b, 0x38, 0x6a, 0x0a, 0x23, + 0x0a, 0x31, 0xf4, 0xc4, 0x28, 0x44, 0x1d, 0x26, 0x6d, 0x9e, 0x79, 0x10, 0xf9, 0x90, 0x87, 0x4f, + 0xed, 0x50, 0x5b, 0x88, 0x73, 0xc0, 0x24, 0x4b, 0x26, 0x25, 0x88, 0x8a, 0x72, 0x29, 0x23, 0xa7, + 0x96, 0x52, 0x8d, 0x73, 0xc0, 0x24, 0x4b, 0xeb, 0x5f, 0x0d, 0x81, 0xda, 0x4f, 0x7e, 0x1e, 0x3c, + 0x20, 0xc4, 0x82, 0x51, 0x9f, 0x06, 0x2a, 0xa1, 0xb9, 0x28, 0xf6, 0x6c, 0xe4, 0x10, 0x94, 0x18, + 0xb6, 0x9d, 0xd2, 0xcf, 0x9d, 0x70, 0xd1, 0xab, 0x2b, 0x6d, 0x97, 0x6f, 0xa7, 0xcb, 0x12, 0x86, + 0x1a, 0x6b, 0x1d, 0xc0, 0x04, 0x6b, 0x57, 0xab, 0x45, 0x5b, 0xd5, 0x90, 0x76, 0x02, 0xb2, 0x0b, + 0xf9, 0x80, 0xfd, 0x18, 0xc8, 0x04, 0x89, 0xd2, 0x38, 0x68, 0xc7, 0x70, 0x95, 0x30, 0xbe, 0x28, + 0xd8, 0x5b, 0xff, 0x65, 0x08, 0x8a, 0xba, 0x47, 0x4f, 0xe0, 0x7f, 0xb9, 0x19, 0x25, 0x72, 0x8b, + 0xb9, 0x5d, 0x36, 0x92, 0xb8, 0x99, 0x2a, 0xb8, 0xe0, 0x1e, 0x8a, 0x3c, 0x5d, 0x9d, 0xd1, 0x4d, + 0x5e, 0x8f, 0x3b, 0xea, 0x2e, 0x99, 0x4e, 0x22, 0x83, 0x5e, 0x7a, 0xec, 0xf6, 0xa0, 0xc8, 0x7f, + 0xac, 0xa8, 0xab, 0x4c, 0x59, 0xe7, 0xce, 0x7d, 0xc5, 0x45, 0x38, 0xde, 0xf5, 0x27, 0x46, 0xfc, + 0x13, 0x57, 0x90, 0xf2, 0x27, 0xba, 0x82, 0x74, 0x03, 0x46, 0xa8, 0xdb, 0x6d, 0xf3, 0xf4, 0x82, + 0x22, 0x3f, 0x31, 0x46, 0x96, 0xdd, 0x6e, 0x3b, 0xde, 0x18, 0x4e, 0x62, 0xad, 0x00, 0xd3, 0x27, + 0x56, 0x17, 0xc9, 0x3b, 0x50, 0x08, 0xe4, 0xce, 0x27, 0x3b, 0xf7, 0x97, 0x74, 0x44, 0x57, 0xc2, + 0x1f, 0x1f, 0xcd, 0x4e, 0x70, 0x62, 0x05, 0x40, 0x5d, 0xc4, 0xfa, 0xe6, 0x08, 0x18, 0x56, 0xf4, + 0x09, 0x86, 0xa9, 0x9e, 0x70, 0x8c, 0xbc, 0x9f, 0xd5, 0x31, 0xa2, 0xbc, 0x0d, 0x62, 0x7e, 0xc7, + 0x7d, 0x21, 0xac, 0x1e, 0x4d, 0xda, 0xea, 0xc8, 0x71, 0xd5, 0xf5, 0xb8, 0x4d, 0x5b, 0x1d, 0xe4, + 0x18, 0x9d, 0x7d, 0x30, 0xd2, 0x37, 0xfb, 0xe0, 0x21, 0xe4, 0x1b, 0x76, 0xb7, 0x41, 0xa5, 0xf3, + 0x3d, 0x9b, 0x73, 0x8b, 0x47, 0x53, 0x85, 0x73, 0x8b, 0xff, 0x44, 0xc1, 0x93, 0xcd, 0xa5, 0xa6, + 0xf2, 0x17, 0x4b, 0x03, 0x30, 0xdb, 0x5c, 0xd2, 0x5e, 0x67, 0x31, 0x97, 0xf4, 0x27, 0x46, 0xfc, + 0x99, 0x86, 0x56, 0x13, 0x99, 0xae, 0x32, 0x12, 0xf8, 0x1b, 0x19, 0x93, 0x28, 0x38, 0x0f, 0xa1, + 0xa1, 0xc9, 0x0f, 0x54, 0x9c, 0xad, 0x79, 0x28, 0x19, 0xb7, 0x70, 0x58, 0xff, 0xea, 0x8c, 0x4b, + 0xa3, 0x7f, 0x97, 0xec, 0xd0, 0x46, 0x8e, 0xb1, 0xfe, 0x68, 0x18, 0xb4, 0x3e, 0x6c, 0xa6, 0x47, + 0xd8, 0x35, 0x23, 0x61, 0x3f, 0x96, 0xab, 0xe5, 0xb9, 0x28, 0xb1, 0xcc, 0x6a, 0x6c, 0x53, 0xbf, + 0xa1, 0x4f, 0x6d, 0xb9, 0xe6, 0xb5, 0xd5, 0xb8, 0x6e, 0x22, 0x31, 0x4e, 0xcb, 0xce, 0xcc, 0xb6, + 0xed, 0x3a, 0xbb, 0x34, 0x08, 0x93, 0x41, 0xad, 0x75, 0x09, 0x47, 0x4d, 0x41, 0x56, 0x61, 0x3a, + 0xa0, 0xe1, 0xe6, 0x81, 0x4b, 0x7d, 0x9d, 0x43, 0x26, 0x93, 0x0a, 0x5f, 0x54, 0x46, 0x42, 0x35, + 0x49, 0x80, 0xbd, 0x65, 0xb8, 0x05, 0x2e, 0xf2, 0xf9, 0x74, 0x6e, 0x96, 0x5c, 0xd8, 0x91, 0x05, + 0x9e, 0xc0, 0x63, 0x4f, 0x09, 0xc6, 0x65, 0xd7, 0x76, 0x5a, 0x5d, 0x9f, 0x46, 0x5c, 0x46, 0xe3, + 0x5c, 0x56, 0x12, 0x78, 0xec, 0x29, 0xc1, 0xe3, 0xe1, 0x2d, 0xbb, 0x11, 0x94, 0xc7, 0x8c, 0x78, + 0x38, 0x03, 0xa0, 0x80, 0x5b, 0xff, 0x30, 0x07, 0x13, 0x48, 0x43, 0xff, 0x70, 0x61, 0x97, 0x59, + 0x88, 0xe1, 0x21, 0xf9, 0xfd, 0x1c, 0x4c, 0xb9, 0x5e, 0x9d, 0x2e, 0xb8, 0xa1, 0xa3, 0x80, 0x03, + 0xdd, 0xfb, 0xe1, 0xec, 0x37, 0x12, 0x1c, 0x45, 0x36, 0x60, 0x12, 0x8a, 0x3d, 0x92, 0xad, 0xcb, + 0x70, 0x31, 0x95, 0x81, 0xf5, 0xd7, 0x87, 0x65, 0xcd, 0xf5, 0x78, 0x7f, 0x08, 0xf9, 0x16, 0xcf, + 0x8c, 0xcc, 0x65, 0xbc, 0xd8, 0xc1, 0xbb, 0x47, 0xa4, 0x4e, 0x0a, 0x4e, 0x64, 0x09, 0x4a, 0x3e, + 0x93, 0x21, 0xf3, 0x56, 0xc5, 0xec, 0xb3, 0xa2, 0x7b, 0x92, 0x1a, 0xf5, 0x38, 0xfe, 0x89, 0x66, + 0x31, 0xe2, 0xc2, 0xd8, 0x8e, 0xb8, 0xab, 0x22, 0xd5, 0xab, 0x6c, 0x0b, 0x53, 0xde, 0x77, 0xe1, + 0xe7, 0x97, 0xba, 0xfc, 0xf2, 0x38, 0xfa, 0x89, 0x4a, 0x08, 0x69, 0x41, 0xc1, 0x56, 0x23, 0x37, + 0x32, 0x40, 0xd8, 0x39, 0x36, 0x31, 0x84, 0xea, 0xa0, 0x47, 0x4a, 0x4b, 0xb0, 0xbe, 0x95, 0x03, + 0x88, 0xae, 0x63, 0x92, 0x3d, 0x28, 0x04, 0xb7, 0x62, 0x6a, 0x74, 0xc6, 0x04, 0x33, 0xc9, 0xc4, + 0x48, 0x3d, 0x92, 0x10, 0xd4, 0x02, 0x9e, 0xa6, 0x43, 0x7f, 0x33, 0x0f, 0xba, 0xd4, 0x33, 0x52, + 0xa1, 0x5f, 0x65, 0x6a, 0x58, 0x23, 0xba, 0xf3, 0xa3, 0xe9, 0x90, 0x43, 0x51, 0x62, 0x99, 0x2a, + 0xa6, 0x92, 0x20, 0xe4, 0xae, 0xc2, 0xfb, 0x53, 0xe5, 0x4b, 0xa0, 0xc6, 0xa6, 0x29, 0xe5, 0xf9, + 0xe7, 0xa2, 0x94, 0x8f, 0x9e, 0xb9, 0x52, 0xce, 0xec, 0x33, 0xdf, 0x6b, 0xd1, 0x05, 0xdc, 0x90, + 0xae, 0x3b, 0x6d, 0x9f, 0xa1, 0x00, 0xa3, 0xc2, 0x93, 0x37, 0xa1, 0xd4, 0x0d, 0x68, 0x75, 0xe9, + 0xce, 0xa2, 0x4f, 0xeb, 0x81, 0xcc, 0x2b, 0xd1, 0xce, 0xdc, 0x7b, 0x11, 0x0a, 0x4d, 0x3a, 0xf2, + 0x4f, 0x73, 0x50, 0xae, 0xf1, 0xfb, 0x1a, 0x62, 0x60, 0xd6, 0x76, 0x37, 0xbc, 0x70, 0xcb, 0xa7, + 0x01, 0x75, 0x43, 0x99, 0xaa, 0xfc, 0x41, 0xc6, 0x64, 0xfd, 0x94, 0x4b, 0x20, 0x95, 0xab, 0xc7, + 0x47, 0xb3, 0xe5, 0xc5, 0x3e, 0xf2, 0xb0, 0x6f, 0x4d, 0xac, 0xbf, 0x91, 0x83, 0x73, 0xd5, 0x9a, + 0xef, 0x74, 0x42, 0x7d, 0x06, 0x6e, 0xf0, 0x2b, 0x5f, 0xa1, 0xcd, 0xf6, 0x25, 0xb9, 0x52, 0x5e, + 0xea, 0x13, 0xf9, 0x17, 0x44, 0xb1, 0xeb, 0x9f, 0x02, 0x84, 0x11, 0x0b, 0x36, 0x13, 0xc5, 0x29, + 0x9b, 0x9c, 0xb1, 0x55, 0x0e, 0x45, 0x89, 0xb5, 0x1e, 0xc1, 0x54, 0x95, 0xb6, 0xed, 0x4e, 0x93, + 0x67, 0xe2, 0x88, 0x20, 0xc0, 0x3c, 0x14, 0x03, 0x05, 0x4b, 0xde, 0x35, 0xd5, 0xc4, 0x18, 0xd1, + 0x90, 0x57, 0x44, 0x8c, 0x42, 0x85, 0xf0, 0x8b, 0x42, 0x5b, 0x10, 0x81, 0x8d, 0x00, 0x15, 0xce, + 0x3a, 0x80, 0xf1, 0xa8, 0x38, 0xdd, 0x25, 0x0d, 0x98, 0xac, 0x19, 0x89, 0x0c, 0xd1, 0x95, 0xd2, + 0x93, 0xe7, 0x3c, 0xf0, 0x89, 0xb7, 0x18, 0x67, 0x82, 0x49, 0xae, 0xd6, 0xff, 0xca, 0xc1, 0xa4, + 0x96, 0x2c, 0x9d, 0x05, 0x9d, 0x64, 0x5c, 0x65, 0x39, 0x63, 0xe6, 0x6b, 0xbc, 0xf3, 0x9e, 0x10, + 0x5b, 0xe9, 0x24, 0x63, 0x2b, 0x67, 0x2d, 0xb1, 0xc7, 0xcb, 0xf1, 0xc7, 0x43, 0x50, 0xd0, 0xa9, + 0xb7, 0x1f, 0x42, 0x9e, 0xab, 0x6d, 0x83, 0x1d, 0x88, 0x5c, 0x05, 0x44, 0xc1, 0x89, 0xb1, 0xe4, + 0x8e, 0xea, 0xcc, 0x97, 0x27, 0x8b, 0xc2, 0x02, 0xb4, 0xfd, 0x10, 0x05, 0x27, 0x72, 0x07, 0x86, + 0xa9, 0x5b, 0x97, 0x27, 0xe3, 0xe9, 0x19, 0xf2, 0xdb, 0xd4, 0xcb, 0x6e, 0x1d, 0x19, 0x17, 0x7e, + 0x2b, 0xcc, 0xf3, 0xdb, 0x76, 0x28, 0x35, 0xfe, 0xe8, 0x56, 0x18, 0x87, 0xa2, 0xc4, 0x5a, 0xff, + 0x73, 0x08, 0x46, 0xab, 0xdd, 0x1d, 0x76, 0xc6, 0xff, 0xbd, 0x1c, 0x9c, 0x4f, 0x86, 0x2c, 0xa2, + 0x89, 0x79, 0xfb, 0x4c, 0x6e, 0x2d, 0x22, 0xdd, 0xad, 0x5c, 0x91, 0x55, 0x39, 0x9f, 0x82, 0xc4, + 0xb4, 0x1a, 0xc4, 0xee, 0x88, 0x0d, 0x3f, 0xa3, 0x1b, 0x9a, 0x46, 0x2a, 0xff, 0xd0, 0x99, 0xa4, + 0xf2, 0x4f, 0xf4, 0x4b, 0xe3, 0xb7, 0xfe, 0xed, 0x08, 0x80, 0xe8, 0xf3, 0xcd, 0x4e, 0x78, 0x12, + 0x23, 0xf2, 0x2d, 0x18, 0x57, 0x2f, 0xe7, 0x6c, 0x44, 0x91, 0x40, 0xed, 0xaa, 0x5d, 0x35, 0x70, + 0x18, 0xa3, 0x64, 0x66, 0x35, 0x75, 0x43, 0xff, 0x50, 0x9c, 0xf6, 0x23, 0x71, 0xb3, 0x7a, 0x59, + 0x63, 0xd0, 0xa0, 0x22, 0x73, 0x31, 0xa7, 0x91, 0x48, 0xf7, 0x3f, 0xf7, 0x04, 0x87, 0xcf, 0xdb, + 0x30, 0xa1, 0xbf, 0x56, 0x9c, 0x96, 0x4a, 0xa3, 0xd2, 0xb6, 0xc9, 0x96, 0x89, 0xc4, 0x38, 0x2d, + 0x79, 0x17, 0xce, 0xc5, 0x93, 0x73, 0xe5, 0xf9, 0x78, 0x49, 0x96, 0x3e, 0x17, 0xcf, 0xe9, 0xc5, + 0x04, 0x35, 0x9b, 0xe7, 0x75, 0xff, 0x10, 0xbb, 0xae, 0x3c, 0x28, 0xf5, 0x3c, 0x5f, 0xe2, 0x50, + 0x94, 0x58, 0xd6, 0x85, 0xac, 0x24, 0xf5, 0x05, 0x9c, 0x9f, 0x88, 0x85, 0xa8, 0x0b, 0xab, 0x06, + 0x0e, 0x63, 0x94, 0x4c, 0x82, 0xb4, 0xe0, 0x21, 0xbe, 0x92, 0x12, 0x36, 0x78, 0x07, 0xce, 0x79, + 0x71, 0xa3, 0x49, 0x44, 0xac, 0xbe, 0x76, 0xc2, 0xa9, 0x1a, 0x2b, 0x2b, 0xb2, 0x5f, 0x13, 0x36, + 0x56, 0x82, 0xbf, 0x75, 0x1e, 0xa6, 0xab, 0xdd, 0x4e, 0xa7, 0xe5, 0xd0, 0xba, 0xf6, 0xa9, 0x58, + 0xef, 0xc1, 0xa4, 0xbc, 0xf2, 0xa5, 0x0f, 0xd8, 0x53, 0xdd, 0x0b, 0xb7, 0x8e, 0xd8, 0x89, 0x11, + 0x77, 0x32, 0x13, 0x37, 0x79, 0x2c, 0x66, 0x75, 0x84, 0x99, 0x87, 0xa0, 0x58, 0x21, 0xa9, 0xa7, + 0xea, 0x43, 0x95, 0x56, 0x30, 0x48, 0xa2, 0x0d, 0x8f, 0xc4, 0x8b, 0x7d, 0xd6, 0x4c, 0x47, 0xb0, + 0x7e, 0x92, 0x83, 0x74, 0xff, 0x3d, 0xf9, 0xac, 0xb7, 0x99, 0x4b, 0x83, 0x35, 0x53, 0xc6, 0x0c, + 0xfa, 0xb7, 0xd4, 0x8e, 0xb7, 0xf4, 0xfd, 0xec, 0x2d, 0x95, 0xa2, 0x7a, 0xdb, 0xfb, 0xbf, 0x73, + 0x50, 0xda, 0xde, 0xbe, 0xab, 0xcd, 0x43, 0x84, 0x4b, 0x81, 0xb8, 0xb4, 0xb7, 0xb0, 0x1b, 0x52, + 0x7f, 0xd1, 0x6b, 0x77, 0x5a, 0x54, 0x4f, 0x0e, 0x79, 0x93, 0xae, 0x9a, 0x4a, 0x81, 0x7d, 0x4a, + 0x92, 0x35, 0x38, 0x6f, 0x62, 0xa4, 0x5d, 0xcf, 0x1b, 0x95, 0x97, 0x19, 0xd6, 0xbd, 0x68, 0x4c, + 0x2b, 0x93, 0x64, 0x25, 0x8d, 0x7b, 0xf9, 0xd2, 0x52, 0x0f, 0x2b, 0x89, 0xc6, 0xb4, 0x32, 0xd6, + 0x26, 0x94, 0x8c, 0x37, 0xbc, 0xc8, 0xfb, 0x30, 0x55, 0xf3, 0xda, 0x1d, 0x9f, 0x06, 0x81, 0xe3, + 0xb9, 0x77, 0xe9, 0x3e, 0x6d, 0xc9, 0x26, 0x73, 0x23, 0x7c, 0x31, 0x81, 0xc3, 0x1e, 0x6a, 0xeb, + 0x5f, 0x5e, 0x01, 0x7d, 0x11, 0xec, 0x17, 0xd7, 0xc9, 0x32, 0xe5, 0x65, 0xd4, 0x74, 0x7c, 0x36, + 0x3f, 0x78, 0x7c, 0x56, 0xef, 0xc5, 0x89, 0x18, 0x6d, 0x23, 0x8a, 0xd1, 0x8e, 0x9e, 0x41, 0x8c, + 0x56, 0xab, 0x99, 0x3d, 0x71, 0xda, 0xdf, 0xcd, 0xc1, 0xb8, 0xeb, 0xd5, 0xa9, 0xd2, 0xca, 0xb9, + 0x7f, 0xa9, 0x74, 0x73, 0x73, 0xa0, 0x4e, 0x14, 0xc1, 0x47, 0xc9, 0x51, 0x84, 0xe7, 0xf5, 0x41, + 0x65, 0xa2, 0x30, 0x26, 0x9a, 0xac, 0x18, 0xde, 0x0e, 0x71, 0xa3, 0xed, 0x6a, 0x9a, 0x31, 0xf1, + 0x34, 0x3f, 0x06, 0xd9, 0x33, 0xb4, 0xad, 0xe2, 0x00, 0x8e, 0x0b, 0x95, 0xcd, 0x67, 0x78, 0x1b, + 0xd5, 0x65, 0xd7, 0x48, 0xf1, 0xb2, 0x60, 0x54, 0x84, 0xee, 0xe5, 0xdb, 0x5b, 0xdc, 0xbb, 0x2d, + 0xc2, 0xfa, 0x28, 0x31, 0xa4, 0xa1, 0x42, 0x30, 0x25, 0xde, 0xb9, 0x95, 0xcc, 0x01, 0x2c, 0x1d, + 0xd5, 0x49, 0x8f, 0xc1, 0x90, 0x0f, 0x4c, 0x4b, 0x74, 0xfc, 0x24, 0x96, 0xe8, 0x44, 0x5f, 0x2b, + 0xb4, 0x01, 0xa3, 0x01, 0xb7, 0x73, 0x79, 0xbe, 0x42, 0xe9, 0xe6, 0x62, 0xb6, 0x83, 0x24, 0x66, + 0x2a, 0x8b, 0xde, 0x11, 0x30, 0x94, 0xec, 0x89, 0x07, 0x05, 0x95, 0x54, 0x21, 0x53, 0x1e, 0x96, + 0x33, 0x3a, 0xb9, 0xe2, 0xbe, 0x69, 0x75, 0xb9, 0x49, 0x40, 0x51, 0x0b, 0x21, 0x0f, 0x61, 0xb8, + 0x6e, 0x37, 0x64, 0xf2, 0xc3, 0xfb, 0x99, 0x2f, 0xea, 0x29, 0x31, 0xdc, 0x6e, 0x59, 0x5a, 0x58, + 0x45, 0xc6, 0x95, 0xec, 0x45, 0x17, 0xd9, 0xa7, 0x06, 0x39, 0x80, 0xe3, 0x2a, 0x90, 0xb0, 0xca, + 0x7b, 0xae, 0xc2, 0x2f, 0xc3, 0xd8, 0xbe, 0xd7, 0xea, 0xb6, 0x65, 0xd6, 0x44, 0xe9, 0xe6, 0x4c, + 0xda, 0x68, 0xdf, 0xe7, 0x24, 0xd1, 0x26, 0x20, 0xbe, 0x03, 0x54, 0x65, 0xc9, 0x37, 0x72, 0x70, + 0x8e, 0x2d, 0x1d, 0x3d, 0x0f, 0x82, 0x32, 0x19, 0x60, 0xa6, 0xde, 0x0b, 0xd8, 0xd1, 0xaa, 0x66, + 0x98, 0x56, 0x84, 0xd7, 0x62, 0x12, 0x30, 0x21, 0x91, 0x74, 0xa0, 0x10, 0x38, 0x75, 0x5a, 0xb3, + 0xfd, 0xa0, 0x7c, 0xfe, 0xcc, 0xa4, 0x47, 0x3e, 0x47, 0xc9, 0x1b, 0xb5, 0x14, 0xf2, 0xd7, 0xf8, + 0xf3, 0x4e, 0xf2, 0x31, 0x3b, 0xf9, 0x84, 0xe1, 0x85, 0xb3, 0x7c, 0xc2, 0x50, 0x38, 0xf0, 0xe2, + 0x12, 0x30, 0x29, 0x92, 0xfc, 0x76, 0x0e, 0x2e, 0x8a, 0x1b, 0xed, 0xc9, 0xe7, 0x0c, 0x2e, 0x66, + 0xb4, 0xa4, 0x79, 0x86, 0xc7, 0x42, 0x1a, 0x4b, 0x4c, 0x97, 0x44, 0xbe, 0x84, 0x09, 0xdf, 0x74, + 0xc1, 0xf3, 0x64, 0x9a, 0x81, 0xbc, 0xcd, 0xfa, 0x41, 0x44, 0x9e, 0xc8, 0x13, 0x03, 0x61, 0x5c, + 0x16, 0x79, 0x03, 0x4a, 0x1d, 0xb9, 0xb9, 0x39, 0x41, 0x9b, 0xe7, 0xe1, 0x0c, 0x8b, 0x43, 0x78, + 0x2b, 0x02, 0xa3, 0x49, 0x43, 0xee, 0x41, 0x29, 0xf4, 0x5a, 0xd4, 0x97, 0x59, 0xe3, 0x65, 0x3e, + 0x5f, 0xae, 0xa5, 0x4d, 0xfe, 0x6d, 0x4d, 0x16, 0xf9, 0x20, 0x23, 0x58, 0x80, 0x26, 0x1f, 0x66, + 0x09, 0xaa, 0xf7, 0x2e, 0x7c, 0x6e, 0xa8, 0xbe, 0x18, 0xb7, 0x04, 0xab, 0x26, 0x12, 0xe3, 0xb4, + 0x64, 0x15, 0xa6, 0x3b, 0xbe, 0xe3, 0xf9, 0x4e, 0x78, 0xb8, 0xd8, 0xb2, 0x83, 0x80, 0x33, 0x10, + 0x89, 0x73, 0x3a, 0xee, 0xb4, 0x95, 0x24, 0xc0, 0xde, 0x32, 0xe4, 0x35, 0x28, 0x28, 0x60, 0xf9, + 0x0a, 0x57, 0xef, 0xc6, 0x45, 0xd2, 0x9d, 0x80, 0xa1, 0xc6, 0xf6, 0xb9, 0x9e, 0x7b, 0x35, 0xcb, + 0xf5, 0x5c, 0x52, 0x87, 0xab, 0x76, 0x37, 0xf4, 0xf8, 0xf5, 0x94, 0x78, 0x91, 0x6d, 0x6f, 0x8f, + 0xba, 0xe5, 0xeb, 0xfc, 0x78, 0xbb, 0x7e, 0x7c, 0x34, 0x7b, 0x75, 0xe1, 0x09, 0x74, 0xf8, 0x44, + 0x2e, 0xa4, 0x0d, 0x05, 0x2a, 0xaf, 0x18, 0x97, 0x7f, 0x69, 0x80, 0x73, 0x25, 0x7e, 0x4f, 0x59, + 0x65, 0x43, 0x08, 0x18, 0x6a, 0x11, 0x64, 0x1b, 0x4a, 0x4d, 0x2f, 0x08, 0x17, 0x5a, 0x8e, 0x1d, + 0xd0, 0xa0, 0xfc, 0x12, 0x9f, 0x27, 0xa9, 0x47, 0xe2, 0x6d, 0x45, 0x16, 0x4d, 0x93, 0xdb, 0x51, + 0x49, 0x34, 0xd9, 0x10, 0xca, 0x5d, 0xee, 0x5d, 0x3e, 0x6a, 0x9e, 0x1b, 0xd2, 0xcf, 0xc3, 0xf2, + 0x35, 0xde, 0x96, 0x57, 0xd3, 0x38, 0x6f, 0x79, 0xf5, 0x6a, 0x9c, 0x5a, 0xfb, 0xdc, 0x4d, 0x20, + 0x26, 0x79, 0x32, 0x93, 0xbf, 0xe3, 0xd5, 0xab, 0x1d, 0x5a, 0xdb, 0xb2, 0xc3, 0x5a, 0xb3, 0x3c, + 0x1b, 0xf7, 0x9a, 0x6c, 0x19, 0x38, 0x8c, 0x51, 0x92, 0x1a, 0x8c, 0xb5, 0x45, 0x32, 0x7e, 0xf9, + 0xe5, 0x01, 0xd4, 0x47, 0x99, 0xd0, 0x2f, 0x0e, 0x1f, 0xf9, 0x81, 0x8a, 0x33, 0xf9, 0xbb, 0x39, + 0x98, 0x4c, 0xe4, 0x8b, 0x95, 0x7f, 0x79, 0x90, 0x23, 0x2f, 0xce, 0xab, 0xf2, 0x2a, 0xef, 0xa4, + 0x38, 0xf0, 0x71, 0x2f, 0x08, 0x93, 0x95, 0x10, 0xad, 0xe7, 0xf7, 0x61, 0xca, 0xaf, 0x0c, 0xd4, + 0x7a, 0xce, 0x43, 0xb5, 0x9e, 0x7f, 0xa0, 0xe2, 0x4c, 0x6e, 0xc0, 0x58, 0xe8, 0xb4, 0xa9, 0xd7, + 0x0d, 0xcb, 0xaf, 0xc6, 0x03, 0x22, 0xdb, 0x02, 0x8c, 0x0a, 0x3f, 0xf3, 0x1e, 0x4c, 0xf7, 0x28, + 0xc4, 0xa7, 0xba, 0xae, 0xf1, 0x43, 0x66, 0x00, 0x1b, 0x26, 0xc8, 0x59, 0x1b, 0x6e, 0xab, 0x30, + 0x2d, 0x1f, 0xc7, 0x66, 0xda, 0x52, 0xab, 0xab, 0x5f, 0xbe, 0x33, 0x22, 0xe6, 0x98, 0x24, 0xc0, + 0xde, 0x32, 0x6c, 0xc6, 0xd6, 0xc4, 0xd3, 0x67, 0x22, 0x35, 0x7c, 0x24, 0xee, 0xa4, 0x5a, 0x34, + 0x70, 0x18, 0xa3, 0xb4, 0xfe, 0x59, 0x0e, 0x26, 0x62, 0x27, 0xf7, 0x99, 0x47, 0x55, 0x56, 0x80, + 0xb4, 0x1d, 0xdf, 0xf7, 0x7c, 0xa1, 0xfe, 0xac, 0xb3, 0x3d, 0x29, 0x90, 0xd7, 0xe0, 0xf9, 0xf5, + 0xcb, 0xf5, 0x1e, 0x2c, 0xa6, 0x94, 0xb0, 0x7e, 0x67, 0x18, 0xa2, 0x0c, 0x20, 0x7d, 0xe7, 0x38, + 0xd7, 0xf7, 0xce, 0xf1, 0xeb, 0x50, 0x78, 0x14, 0x78, 0xee, 0x56, 0x74, 0x33, 0x59, 0x0f, 0xc5, + 0x07, 0xd5, 0xcd, 0x0d, 0x4e, 0xa9, 0x29, 0x38, 0xf5, 0x67, 0x2b, 0x4e, 0x2b, 0xec, 0xbd, 0xbf, + 0xfb, 0xc1, 0x87, 0x02, 0x8e, 0x9a, 0x82, 0xbf, 0xaf, 0xb6, 0x4f, 0xb5, 0xcf, 0x31, 0x7a, 0x5f, + 0x8d, 0x01, 0x51, 0xe0, 0xc8, 0x3c, 0x14, 0xb5, 0xcb, 0x52, 0x7a, 0x50, 0x75, 0x4f, 0x69, 0xd7, + 0x26, 0x46, 0x34, 0x5c, 0x13, 0x93, 0x6e, 0x39, 0x69, 0x7d, 0xae, 0x64, 0xd4, 0x61, 0x13, 0xbe, + 0x3d, 0xb1, 0x4d, 0x2b, 0x30, 0x6a, 0x29, 0x66, 0x2e, 0x58, 0xfe, 0x84, 0xb9, 0x60, 0x6c, 0x1c, + 0xc6, 0xee, 0x53, 0x9f, 0x3f, 0x27, 0x70, 0x03, 0xc6, 0xf6, 0xc5, 0xcf, 0x64, 0xf6, 0xa8, 0xa4, + 0x40, 0x85, 0x67, 0xbd, 0xb1, 0xd3, 0x75, 0x5a, 0xf5, 0xa5, 0x68, 0x69, 0xe8, 0xde, 0xa8, 0x28, + 0x04, 0x46, 0x34, 0xac, 0x40, 0x83, 0x29, 0xaa, 0xed, 0xb6, 0x13, 0x26, 0xef, 0xe3, 0xad, 0x2a, + 0x04, 0x46, 0x34, 0xe4, 0x55, 0x18, 0x6d, 0x38, 0xe1, 0xb6, 0xdd, 0x48, 0x46, 0x2e, 0x56, 0x39, + 0x14, 0x25, 0x96, 0x3b, 0xc5, 0x9d, 0x70, 0xdb, 0xa7, 0xdc, 0xc9, 0xd6, 0x73, 0x1f, 0x65, 0xd5, + 0xc0, 0x61, 0x8c, 0x92, 0x57, 0xc9, 0x93, 0x2d, 0x93, 0xce, 0xea, 0xa8, 0x4a, 0x0a, 0x81, 0x11, + 0x0d, 0x9b, 0x55, 0x35, 0xaf, 0xdd, 0x71, 0x5a, 0x32, 0xa3, 0xc8, 0x98, 0x55, 0x8b, 0x12, 0x8e, + 0x9a, 0x82, 0x51, 0xb3, 0x7d, 0x61, 0xd7, 0xf3, 0xdb, 0xc9, 0x57, 0xa5, 0xb6, 0x24, 0x1c, 0x35, + 0x85, 0x75, 0x1f, 0x26, 0xc4, 0xfa, 0x58, 0x6c, 0xd9, 0x4e, 0x7b, 0x75, 0x91, 0x2c, 0xf7, 0x64, + 0xa8, 0xdd, 0x48, 0xc9, 0x50, 0xbb, 0x18, 0x2b, 0x94, 0x92, 0xa9, 0xf6, 0x67, 0x43, 0x50, 0x78, + 0x8e, 0x8f, 0xec, 0xd5, 0x62, 0x8f, 0xec, 0x9d, 0xc1, 0x8b, 0x6c, 0x69, 0x0f, 0xec, 0xed, 0x25, + 0x1e, 0xd8, 0x5b, 0x1c, 0x30, 0x19, 0xf3, 0x89, 0x8f, 0xeb, 0xfd, 0x38, 0x07, 0xfa, 0x5e, 0x0f, + 0xdf, 0x10, 0x2a, 0x8e, 0xcb, 0x83, 0x99, 0xcf, 0xbe, 0x33, 0xbd, 0x58, 0x67, 0xae, 0x0f, 0xd4, + 0x4a, 0xb3, 0xea, 0x7d, 0xdf, 0x0c, 0xfd, 0x51, 0x0e, 0xca, 0x69, 0x05, 0x9e, 0xc3, 0x83, 0x82, + 0x6e, 0xfc, 0x41, 0xc1, 0xb5, 0x33, 0x6b, 0x6c, 0x9f, 0x87, 0x05, 0xbf, 0xdf, 0xa7, 0xa9, 0xfc, + 0x49, 0xbf, 0x4f, 0xd5, 0x81, 0x90, 0x1b, 0x20, 0xee, 0x20, 0xb8, 0xa6, 0x1f, 0x26, 0x9f, 0xc2, + 0x68, 0xc0, 0x23, 0x7f, 0x72, 0x6c, 0xdf, 0xce, 0x78, 0x32, 0x30, 0x16, 0xd2, 0x1b, 0xc4, 0x7f, + 0xa3, 0x64, 0x6b, 0x7d, 0x37, 0x07, 0xe3, 0xcf, 0xf1, 0x39, 0xc8, 0x9d, 0xf8, 0xe8, 0xbd, 0x33, + 0xd0, 0xe8, 0xf5, 0x19, 0xb1, 0x3f, 0xbc, 0x02, 0xb1, 0x67, 0x18, 0x89, 0x0b, 0x45, 0xa5, 0x7b, + 0xa9, 0xb4, 0xec, 0x77, 0x06, 0x72, 0xb8, 0x46, 0xdb, 0xbf, 0x82, 0x04, 0x18, 0x89, 0x48, 0x04, + 0x51, 0x87, 0x4e, 0x14, 0x44, 0x7d, 0xee, 0xce, 0xfc, 0x74, 0x5b, 0x76, 0xe4, 0x99, 0xd8, 0xb2, + 0x57, 0xcf, 0xdc, 0x96, 0x7d, 0xe9, 0xd9, 0xdb, 0xb2, 0x86, 0xb3, 0x2f, 0x3f, 0x80, 0xb3, 0xef, + 0x4b, 0xb8, 0xb0, 0x1f, 0x1d, 0xbd, 0x7a, 0xbe, 0xc8, 0x37, 0xee, 0x6e, 0xa4, 0x5a, 0xb0, 0x4c, + 0x8d, 0x08, 0x42, 0xea, 0x86, 0xc6, 0xa1, 0x1d, 0x5d, 0x1e, 0xbd, 0x9f, 0xc2, 0x0e, 0x53, 0x85, + 0x24, 0x5d, 0x3d, 0x63, 0x27, 0x70, 0xf5, 0xfc, 0x51, 0xdf, 0x37, 0xec, 0x0b, 0x67, 0xfe, 0x86, + 0xfd, 0x8b, 0xa7, 0x7e, 0xbf, 0xfe, 0x95, 0xc8, 0xdd, 0x2b, 0x22, 0xf2, 0xe9, 0x8e, 0xda, 0x3f, + 0x48, 0x86, 0x59, 0x80, 0xf7, 0x76, 0x75, 0x60, 0x35, 0xe3, 0x0c, 0x42, 0x2d, 0xa5, 0x01, 0x42, + 0x2d, 0x09, 0x3f, 0xdc, 0xf8, 0x19, 0xf9, 0xe1, 0x5c, 0x98, 0x72, 0xda, 0x76, 0x83, 0x6e, 0x75, + 0x5b, 0x2d, 0x91, 0x80, 0x18, 0x94, 0x27, 0x38, 0xef, 0xd4, 0xf4, 0xb2, 0xbb, 0x5e, 0xcd, 0x6e, + 0x25, 0x5f, 0x0d, 0xd5, 0xd9, 0xd5, 0x6b, 0x09, 0x4e, 0xd8, 0xc3, 0x9b, 0x4d, 0x4b, 0x7e, 0x41, + 0x90, 0x86, 0xac, 0xb7, 0x79, 0x14, 0x42, 0xfe, 0xf3, 0xc9, 0xed, 0x08, 0x8c, 0x26, 0x0d, 0xb9, + 0x03, 0xc5, 0xba, 0x1b, 0xc8, 0x74, 0xe2, 0x49, 0xbe, 0x4b, 0xfd, 0x0a, 0xdb, 0xdb, 0x96, 0x36, + 0xaa, 0x3a, 0x91, 0xf8, 0x6a, 0xca, 0x0d, 0x53, 0x8d, 0xc7, 0xa8, 0x3c, 0x59, 0xe7, 0xcc, 0xe4, + 0xfb, 0x52, 0x22, 0x6c, 0x70, 0xbd, 0x8f, 0x2b, 0x69, 0x69, 0x43, 0x3d, 0x87, 0x35, 0x21, 0xc5, + 0xc9, 0x57, 0xa3, 0x22, 0x0e, 0xc6, 0xb3, 0x88, 0xd3, 0x4f, 0x7c, 0x16, 0xf1, 0x1e, 0x5c, 0x0e, + 0xc3, 0x56, 0x2c, 0x1a, 0x2d, 0x2f, 0x17, 0xf3, 0x9b, 0xe6, 0x79, 0xf1, 0x28, 0xdd, 0xf6, 0xf6, + 0xdd, 0x34, 0x12, 0xec, 0x57, 0x96, 0x87, 0x65, 0xc3, 0x96, 0x76, 0x25, 0x5f, 0x1b, 0x24, 0x2c, + 0x1b, 0x85, 0xfd, 0x65, 0x58, 0x36, 0x02, 0xa0, 0x29, 0x85, 0x6c, 0xf6, 0x73, 0xa2, 0x9f, 0xe7, + 0x7b, 0xcc, 0xe9, 0x5d, 0xe2, 0xa6, 0x17, 0xf6, 0xc2, 0x13, 0xbd, 0xb0, 0x3d, 0x5e, 0xe3, 0x8b, + 0xa7, 0xf0, 0x1a, 0x3f, 0xe4, 0xb7, 0x87, 0x57, 0x17, 0xa5, 0xc7, 0x3d, 0x9b, 0xc6, 0xc6, 0x6f, + 0xfb, 0x88, 0xcc, 0x09, 0xfe, 0x13, 0x05, 0x4f, 0xb2, 0x05, 0x17, 0x3a, 0x5e, 0xbd, 0xc7, 0xe9, + 0xcc, 0x5d, 0xec, 0xc6, 0xed, 0xff, 0xad, 0x14, 0x1a, 0x4c, 0x2d, 0xc9, 0x37, 0xf0, 0x08, 0xce, + 0x2f, 0x9b, 0xe7, 0xe5, 0x06, 0x1e, 0x81, 0xd1, 0xa4, 0x49, 0xfa, 0x60, 0x5f, 0x7c, 0x66, 0x3e, + 0xd8, 0x99, 0xe7, 0xe0, 0x83, 0xbd, 0x72, 0x62, 0x1f, 0xec, 0x5f, 0x81, 0xf3, 0x1d, 0xaf, 0xbe, + 0xe4, 0x04, 0x7e, 0x97, 0xa7, 0x1c, 0x57, 0xba, 0xf5, 0x06, 0x0d, 0xb9, 0x13, 0xb7, 0x74, 0xf3, + 0xa6, 0x59, 0x49, 0xf1, 0xbf, 0x79, 0x73, 0xf2, 0x7f, 0xf3, 0xf8, 0x22, 0x4f, 0x94, 0xe2, 0x76, + 0x0f, 0x4f, 0x1d, 0x49, 0x41, 0x62, 0x9a, 0x1c, 0xd3, 0x05, 0x7c, 0xfd, 0x99, 0xb9, 0x80, 0xdf, + 0x87, 0x42, 0xd0, 0xec, 0x86, 0x75, 0xef, 0xc0, 0xe5, 0xde, 0xfc, 0xa2, 0x7e, 0x87, 0xbc, 0x50, + 0x95, 0xf0, 0xc7, 0x47, 0xb3, 0x53, 0xea, 0xb7, 0x61, 0xe5, 0x4b, 0x08, 0xf9, 0x3b, 0x7d, 0x72, + 0x36, 0xad, 0x33, 0xce, 0xd9, 0xbc, 0x7c, 0xaa, 0x7c, 0xcd, 0x34, 0xd7, 0xf6, 0xcb, 0x3f, 0x0b, + 0xae, 0xed, 0xdf, 0xcf, 0xc1, 0xc4, 0xbe, 0xe9, 0x38, 0x91, 0x1e, 0xf7, 0x6c, 0x81, 0xba, 0x98, + 0x0b, 0xa6, 0x62, 0xb1, 0xbd, 0x2a, 0x06, 0x7a, 0x9c, 0x04, 0x60, 0x5c, 0x78, 0x6f, 0xd8, 0xf0, + 0x95, 0xe7, 0x17, 0x36, 0x1c, 0xdc, 0xad, 0xfe, 0x1f, 0xa7, 0xe1, 0x5c, 0xe2, 0x7d, 0x72, 0xfd, + 0x3e, 0x49, 0xee, 0xa4, 0xef, 0x93, 0xc4, 0x1e, 0x10, 0x19, 0x7a, 0xa6, 0x0f, 0x88, 0x0c, 0x3f, + 0x9f, 0x07, 0x44, 0xa6, 0x9e, 0xc5, 0x03, 0x22, 0xd3, 0xa7, 0x7a, 0x40, 0xc4, 0x78, 0xc0, 0x65, + 0xe4, 0x29, 0x0f, 0xb8, 0x2c, 0xc0, 0xa4, 0xca, 0x72, 0xa3, 0xf2, 0x01, 0x09, 0xe1, 0x48, 0xd5, + 0x7f, 0xae, 0xb4, 0x18, 0x47, 0x63, 0x92, 0x9e, 0xfc, 0x16, 0xe4, 0x5d, 0x5e, 0x70, 0x74, 0x80, + 0xc7, 0xc7, 0xe2, 0x13, 0x89, 0xab, 0xe5, 0xf2, 0xfd, 0x2f, 0x95, 0x00, 0x91, 0xe7, 0xb0, 0xc7, + 0xea, 0x07, 0x0a, 0xa1, 0xe4, 0x63, 0x28, 0x7b, 0xbb, 0xbb, 0x2d, 0xcf, 0xae, 0x47, 0x8f, 0x9c, + 0x28, 0xdf, 0xae, 0x48, 0xd8, 0xbd, 0x2e, 0x19, 0x94, 0x37, 0xfb, 0xd0, 0x61, 0x5f, 0x0e, 0xcc, + 0x7a, 0x9a, 0x8c, 0x3f, 0x0a, 0x14, 0x94, 0x8b, 0xbc, 0x99, 0x7f, 0xe9, 0x2c, 0x9a, 0x19, 0x7f, + 0x81, 0x48, 0x36, 0x58, 0xf7, 0x7c, 0x02, 0x8b, 0xc9, 0x9a, 0x10, 0x1f, 0x2e, 0x75, 0xd2, 0x6c, + 0xcb, 0x40, 0xa6, 0xa1, 0x3d, 0xc9, 0xc2, 0xbd, 0x26, 0xa5, 0x5c, 0x4a, 0xb5, 0x4e, 0x03, 0xec, + 0xc3, 0xd9, 0x7c, 0xfe, 0xa4, 0xf0, 0xcc, 0x9e, 0x3f, 0x89, 0xff, 0x53, 0xc0, 0xc4, 0xf3, 0xf8, + 0xa7, 0x00, 0xf2, 0xd3, 0xd4, 0x57, 0x77, 0x84, 0x49, 0xf6, 0xd1, 0x59, 0x0c, 0xf6, 0xcf, 0xdc, + 0xcb, 0x3b, 0x7f, 0x3f, 0x07, 0x33, 0x62, 0x4a, 0xa5, 0xfd, 0xb9, 0x94, 0x4c, 0x26, 0x3b, 0x03, + 0x57, 0x3e, 0x0f, 0x0f, 0x56, 0x63, 0x82, 0xb8, 0xef, 0xf9, 0x09, 0xc2, 0xc9, 0xef, 0xa6, 0xa8, + 0x10, 0x93, 0x03, 0x38, 0x2c, 0xd2, 0xdf, 0x72, 0x39, 0x7f, 0x7c, 0x12, 0xad, 0xe1, 0x9f, 0xf4, + 0x75, 0xa1, 0x10, 0x5e, 0xa3, 0xad, 0xb3, 0x73, 0xa1, 0x98, 0x6f, 0xcc, 0x9c, 0xc6, 0x91, 0x32, + 0x73, 0x28, 0x9e, 0x93, 0xeb, 0xfb, 0x98, 0xe1, 0x3d, 0xf3, 0x18, 0xcf, 0xfa, 0x9e, 0x60, 0xb4, + 0x3f, 0x9a, 0x0f, 0x29, 0xfe, 0x76, 0x0e, 0x2e, 0xa4, 0x6d, 0x64, 0x29, 0xb5, 0xa8, 0xc6, 0x6b, + 0x31, 0x98, 0xd7, 0xd6, 0xac, 0xc3, 0xd9, 0x3c, 0xb1, 0xf3, 0xb7, 0x47, 0x0d, 0x4f, 0x73, 0x48, + 0x3b, 0xbf, 0x48, 0xf1, 0xce, 0x94, 0xe2, 0x1d, 0xfb, 0xef, 0x8f, 0xfc, 0x73, 0xfc, 0xef, 0x8f, + 0xd1, 0x0c, 0xff, 0xfd, 0x31, 0xf6, 0x3c, 0xff, 0xfb, 0xa3, 0x70, 0xc2, 0xff, 0xfe, 0x28, 0xfe, + 0xcc, 0xfc, 0xf7, 0x87, 0xf5, 0x55, 0x0e, 0xa6, 0xfe, 0x7f, 0xff, 0xcb, 0xc4, 0x1f, 0x1a, 0xa1, + 0xde, 0xe7, 0xf8, 0x5f, 0x89, 0x8f, 0xe2, 0xc1, 0xb3, 0xe5, 0x33, 0x69, 0x64, 0x9f, 0x20, 0xda, + 0x67, 0x90, 0x66, 0xbe, 0x9f, 0xec, 0xee, 0x61, 0x2c, 0x27, 0x69, 0xe8, 0xc4, 0x39, 0x49, 0xff, + 0x37, 0xa5, 0x57, 0xf9, 0xd9, 0xfe, 0xe5, 0xb3, 0xfa, 0x17, 0xb7, 0x0b, 0x69, 0xff, 0xe2, 0x96, + 0xf8, 0xd7, 0xb6, 0xe4, 0xbf, 0x78, 0x0d, 0x3d, 0xc3, 0x7f, 0xf1, 0x9a, 0x80, 0x92, 0xf9, 0x2f, + 0xfc, 0x73, 0xdf, 0xfe, 0xea, 0xda, 0x0b, 0xdf, 0xfd, 0xea, 0xda, 0x0b, 0xdf, 0xfb, 0xea, 0xda, + 0x0b, 0x5f, 0x3f, 0xbe, 0x96, 0xfb, 0xf6, 0xf1, 0xb5, 0xdc, 0x77, 0x8f, 0xaf, 0xe5, 0xbe, 0x77, + 0x7c, 0x2d, 0xf7, 0xc3, 0xe3, 0x6b, 0xb9, 0xbf, 0xf5, 0x5f, 0xaf, 0xbd, 0xf0, 0x51, 0x41, 0xb5, + 0xed, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x7b, 0xca, 0x8e, 0xea, 0x82, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -4645,16 +4644,18 @@ func (m *GCSBucket) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.ServiceAccountKeySecret.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.ServiceAccountKeySecret != nil { + { + size, err := m.ServiceAccountKeySecret.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 } - i-- - dAtA[i] = 0x12 i -= len(m.Bucket) copy(dAtA[i:], m.Bucket) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Bucket))) @@ -5891,26 +5892,30 @@ func (m *OSSBucket) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.SecretKeySecret.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.SecretKeySecret != nil { + { + size, err := m.SecretKeySecret.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 } - i-- - dAtA[i] = 0x22 - { - size, err := m.AccessKeySecret.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.AccessKeySecret != nil { + { + size, err := m.AccessKeySecret.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a } - i-- - dAtA[i] = 0x1a i -= len(m.Bucket) copy(dAtA[i:], m.Bucket) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Bucket))) @@ -6508,26 +6513,30 @@ func (m *S3Bucket) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(len(m.RoleARN))) i-- dAtA[i] = 0x3a - { - size, err := m.SecretKeySecret.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.SecretKeySecret != nil { + { + size, err := m.SecretKeySecret.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 } - i-- - dAtA[i] = 0x32 - { - size, err := m.AccessKeySecret.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.AccessKeySecret != nil { + { + size, err := m.AccessKeySecret.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a } - i-- - dAtA[i] = 0x2a if m.Insecure != nil { i-- if *m.Insecure { @@ -9555,8 +9564,10 @@ func (m *GCSBucket) Size() (n int) { _ = l l = len(m.Bucket) n += 1 + l + sovGenerated(uint64(l)) - l = m.ServiceAccountKeySecret.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.ServiceAccountKeySecret != nil { + l = m.ServiceAccountKeySecret.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -10022,10 +10033,14 @@ func (m *OSSBucket) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Bucket) n += 1 + l + sovGenerated(uint64(l)) - l = m.AccessKeySecret.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.SecretKeySecret.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.AccessKeySecret != nil { + l = m.AccessKeySecret.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.SecretKeySecret != nil { + l = m.SecretKeySecret.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -10258,10 +10273,14 @@ func (m *S3Bucket) Size() (n int) { if m.Insecure != nil { n += 2 } - l = m.AccessKeySecret.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.SecretKeySecret.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.AccessKeySecret != nil { + l = m.AccessKeySecret.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.SecretKeySecret != nil { + l = m.SecretKeySecret.Size() + n += 1 + l + sovGenerated(uint64(l)) + } l = len(m.RoleARN) n += 1 + l + sovGenerated(uint64(l)) n += 2 @@ -11489,7 +11508,7 @@ func (this *GCSBucket) String() string { } s := strings.Join([]string{`&GCSBucket{`, `Bucket:` + fmt.Sprintf("%v", this.Bucket) + `,`, - `ServiceAccountKeySecret:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ServiceAccountKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1), `&`, ``, 1) + `,`, + `ServiceAccountKeySecret:` + strings.Replace(fmt.Sprintf("%v", this.ServiceAccountKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1) + `,`, `}`, }, "") return s @@ -11842,8 +11861,8 @@ func (this *OSSBucket) String() string { s := strings.Join([]string{`&OSSBucket{`, `Endpoint:` + fmt.Sprintf("%v", this.Endpoint) + `,`, `Bucket:` + fmt.Sprintf("%v", this.Bucket) + `,`, - `AccessKeySecret:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.AccessKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1), `&`, ``, 1) + `,`, - `SecretKeySecret:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.SecretKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1), `&`, ``, 1) + `,`, + `AccessKeySecret:` + strings.Replace(fmt.Sprintf("%v", this.AccessKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1) + `,`, + `SecretKeySecret:` + strings.Replace(fmt.Sprintf("%v", this.SecretKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1) + `,`, `}`, }, "") return s @@ -12010,8 +12029,8 @@ func (this *S3Bucket) String() string { `Bucket:` + fmt.Sprintf("%v", this.Bucket) + `,`, `Region:` + fmt.Sprintf("%v", this.Region) + `,`, `Insecure:` + valueToStringGenerated(this.Insecure) + `,`, - `AccessKeySecret:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.AccessKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1), `&`, ``, 1) + `,`, - `SecretKeySecret:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.SecretKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1), `&`, ``, 1) + `,`, + `AccessKeySecret:` + strings.Replace(fmt.Sprintf("%v", this.AccessKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1) + `,`, + `SecretKeySecret:` + strings.Replace(fmt.Sprintf("%v", this.SecretKeySecret), "SecretKeySelector", "v1.SecretKeySelector", 1) + `,`, `RoleARN:` + fmt.Sprintf("%v", this.RoleARN) + `,`, `UseSDKCreds:` + fmt.Sprintf("%v", this.UseSDKCreds) + `,`, `CreateBucketIfNotPresent:` + strings.Replace(this.CreateBucketIfNotPresent.String(), "CreateS3BucketOptions", "CreateS3BucketOptions", 1) + `,`, @@ -16787,6 +16806,9 @@ func (m *GCSBucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.ServiceAccountKeySecret == nil { + m.ServiceAccountKeySecret = &v1.SecretKeySelector{} + } if err := m.ServiceAccountKeySecret.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -20941,6 +20963,9 @@ func (m *OSSBucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.AccessKeySecret == nil { + m.AccessKeySecret = &v1.SecretKeySelector{} + } if err := m.AccessKeySecret.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -20974,6 +20999,9 @@ func (m *OSSBucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.SecretKeySecret == nil { + m.SecretKeySecret = &v1.SecretKeySelector{} + } if err := m.SecretKeySecret.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -22881,6 +22909,9 @@ func (m *S3Bucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.AccessKeySecret == nil { + m.AccessKeySecret = &v1.SecretKeySelector{} + } if err := m.AccessKeySecret.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -22914,6 +22945,9 @@ func (m *S3Bucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.SecretKeySecret == nil { + m.SecretKeySecret = &v1.SecretKeySelector{} + } if err := m.SecretKeySecret.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index 66ab7ee26104..29078f6ffe25 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -1229,7 +1229,6 @@ func schema_pkg_apis_workflow_v1alpha1_GCSArtifact(ref common.ReferenceCallback) "bucket": { SchemaProps: spec.SchemaProps{ Description: "Bucket is the name of the bucket", - Default: "", Type: []string{"string"}, Format: "", }, @@ -1237,7 +1236,6 @@ func schema_pkg_apis_workflow_v1alpha1_GCSArtifact(ref common.ReferenceCallback) "serviceAccountKeySecret": { SchemaProps: spec.SchemaProps{ Description: "ServiceAccountKeySecret is the secret selector to the bucket's service account key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, @@ -1250,7 +1248,7 @@ func schema_pkg_apis_workflow_v1alpha1_GCSArtifact(ref common.ReferenceCallback) }, }, }, - Required: []string{"bucket", "key"}, + Required: []string{"key"}, }, }, Dependencies: []string{ @@ -1268,7 +1266,6 @@ func schema_pkg_apis_workflow_v1alpha1_GCSBucket(ref common.ReferenceCallback) c "bucket": { SchemaProps: spec.SchemaProps{ Description: "Bucket is the name of the bucket", - Default: "", Type: []string{"string"}, Format: "", }, @@ -1276,12 +1273,10 @@ func schema_pkg_apis_workflow_v1alpha1_GCSBucket(ref common.ReferenceCallback) c "serviceAccountKeySecret": { SchemaProps: spec.SchemaProps{ Description: "ServiceAccountKeySecret is the secret selector to the bucket's service account key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, }, - Required: []string{"bucket"}, }, }, Dependencies: []string{ @@ -1480,7 +1475,7 @@ func schema_pkg_apis_workflow_v1alpha1_HDFSArtifact(ref common.ReferenceCallback }, }, }, - Required: []string{"addresses", "path"}, + Required: []string{"path"}, }, }, Dependencies: []string{ @@ -1557,7 +1552,6 @@ func schema_pkg_apis_workflow_v1alpha1_HDFSConfig(ref common.ReferenceCallback) }, }, }, - Required: []string{"addresses"}, }, }, Dependencies: []string{ @@ -2374,7 +2368,6 @@ func schema_pkg_apis_workflow_v1alpha1_OSSArtifact(ref common.ReferenceCallback) "endpoint": { SchemaProps: spec.SchemaProps{ Description: "Endpoint is the hostname of the bucket endpoint", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2382,7 +2375,6 @@ func schema_pkg_apis_workflow_v1alpha1_OSSArtifact(ref common.ReferenceCallback) "bucket": { SchemaProps: spec.SchemaProps{ Description: "Bucket is the name of the bucket", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2390,14 +2382,12 @@ func schema_pkg_apis_workflow_v1alpha1_OSSArtifact(ref common.ReferenceCallback) "accessKeySecret": { SchemaProps: spec.SchemaProps{ Description: "AccessKeySecret is the secret selector to the bucket's access key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, "secretKeySecret": { SchemaProps: spec.SchemaProps{ Description: "SecretKeySecret is the secret selector to the bucket's secret key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, @@ -2410,7 +2400,7 @@ func schema_pkg_apis_workflow_v1alpha1_OSSArtifact(ref common.ReferenceCallback) }, }, }, - Required: []string{"endpoint", "bucket", "accessKeySecret", "secretKeySecret", "key"}, + Required: []string{"key"}, }, }, Dependencies: []string{ @@ -2428,7 +2418,6 @@ func schema_pkg_apis_workflow_v1alpha1_OSSBucket(ref common.ReferenceCallback) c "endpoint": { SchemaProps: spec.SchemaProps{ Description: "Endpoint is the hostname of the bucket endpoint", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2436,7 +2425,6 @@ func schema_pkg_apis_workflow_v1alpha1_OSSBucket(ref common.ReferenceCallback) c "bucket": { SchemaProps: spec.SchemaProps{ Description: "Bucket is the name of the bucket", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2444,19 +2432,16 @@ func schema_pkg_apis_workflow_v1alpha1_OSSBucket(ref common.ReferenceCallback) c "accessKeySecret": { SchemaProps: spec.SchemaProps{ Description: "AccessKeySecret is the secret selector to the bucket's access key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, "secretKeySecret": { SchemaProps: spec.SchemaProps{ Description: "SecretKeySecret is the secret selector to the bucket's secret key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, }, - Required: []string{"endpoint", "bucket", "accessKeySecret", "secretKeySecret"}, }, }, Dependencies: []string{ @@ -2875,7 +2860,6 @@ func schema_pkg_apis_workflow_v1alpha1_S3Artifact(ref common.ReferenceCallback) "endpoint": { SchemaProps: spec.SchemaProps{ Description: "Endpoint is the hostname of the bucket endpoint", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2883,7 +2867,6 @@ func schema_pkg_apis_workflow_v1alpha1_S3Artifact(ref common.ReferenceCallback) "bucket": { SchemaProps: spec.SchemaProps{ Description: "Bucket is the name of the bucket", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2905,14 +2888,12 @@ func schema_pkg_apis_workflow_v1alpha1_S3Artifact(ref common.ReferenceCallback) "accessKeySecret": { SchemaProps: spec.SchemaProps{ Description: "AccessKeySecret is the secret selector to the bucket's access key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, "secretKeySecret": { SchemaProps: spec.SchemaProps{ Description: "SecretKeySecret is the secret selector to the bucket's secret key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, @@ -2945,7 +2926,7 @@ func schema_pkg_apis_workflow_v1alpha1_S3Artifact(ref common.ReferenceCallback) }, }, }, - Required: []string{"endpoint", "bucket", "accessKeySecret", "secretKeySecret", "key"}, + Required: []string{"key"}, }, }, Dependencies: []string{ @@ -2963,7 +2944,6 @@ func schema_pkg_apis_workflow_v1alpha1_S3Bucket(ref common.ReferenceCallback) co "endpoint": { SchemaProps: spec.SchemaProps{ Description: "Endpoint is the hostname of the bucket endpoint", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2971,7 +2951,6 @@ func schema_pkg_apis_workflow_v1alpha1_S3Bucket(ref common.ReferenceCallback) co "bucket": { SchemaProps: spec.SchemaProps{ Description: "Bucket is the name of the bucket", - Default: "", Type: []string{"string"}, Format: "", }, @@ -2993,14 +2972,12 @@ func schema_pkg_apis_workflow_v1alpha1_S3Bucket(ref common.ReferenceCallback) co "accessKeySecret": { SchemaProps: spec.SchemaProps{ Description: "AccessKeySecret is the secret selector to the bucket's access key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, "secretKeySecret": { SchemaProps: spec.SchemaProps{ Description: "SecretKeySecret is the secret selector to the bucket's secret key", - Default: map[string]interface{}{}, Ref: ref("k8s.io/api/core/v1.SecretKeySelector"), }, }, @@ -3025,7 +3002,6 @@ func schema_pkg_apis_workflow_v1alpha1_S3Bucket(ref common.ReferenceCallback) co }, }, }, - Required: []string{"endpoint", "bucket", "accessKeySecret", "secretKeySecret"}, }, }, Dependencies: []string{ diff --git a/pkg/apis/workflow/v1alpha1/workflow_types.go b/pkg/apis/workflow/v1alpha1/workflow_types.go index 1cb51bb2faee..c8b914581d90 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" "hash/fnv" + "net/url" + "path" "reflect" "sort" "strings" @@ -825,21 +827,13 @@ type ZipStrategy struct{} // save/load the directory appropriately. type NoneStrategy struct{} -// ArtifactLocationType is the type of artifact location -type ArtifactLocationType string +type ArtifactLocationType interface { + HasLocation() bool + GetKey() (string, error) + SetKey(key string) error +} -// ArtifactLocationType -const ( - ArtifactLocationS3 ArtifactLocationType = "S3" - ArtifactLocationGit ArtifactLocationType = "Git" - ArtifactLocationHTTP ArtifactLocationType = "HTTP" - ArtifactLocationArtifactory ArtifactLocationType = "Artifactory" - ArtifactLocationHDFS ArtifactLocationType = "HDFS" - ArtifactLocationRaw ArtifactLocationType = "Raw" - ArtifactLocationOSS ArtifactLocationType = "OSS" - ArtifactLocationGCS ArtifactLocationType = "GCS" - ArtifactLocationUnknown ArtifactLocationType = "" -) +var keyUnsupportedErr = fmt.Errorf("key unsupported") // ArtifactLocation describes a location for a single or multiple artifacts. // It is used as single artifact in the context of inputs/outputs (e.g. outputs.artifacts.artname). @@ -874,70 +868,114 @@ type ArtifactLocation struct { GCS *GCSArtifact `json:"gcs,omitempty" protobuf:"bytes,9,opt,name=gcs"` } -// HasLocation whether or not an artifact has a location defined -func (a *ArtifactLocation) HasLocation() bool { - return a.S3.HasLocation() || - a.Git.HasLocation() || - a.HTTP.HasLocation() || - a.Artifactory.HasLocation() || - a.Raw.HasLocation() || - a.HDFS.HasLocation() || - a.OSS.HasLocation() || - a.GCS.HasLocation() +func (a *ArtifactLocation) Get() ArtifactLocationType { + if a == nil { + return nil + } else if a.Artifactory != nil { + return a.Artifactory + } else if a.Git != nil { + return a.Git + } else if a.GCS != nil { + return a.GCS + } else if a.HDFS != nil { + return a.HDFS + } else if a.HTTP != nil { + return a.HTTP + } else if a.OSS != nil { + return a.OSS + } else if a.Raw != nil { + return a.Raw + } else if a.S3 != nil { + return a.S3 + } + return nil } -func (a *ArtifactLocation) GetType() ArtifactLocationType { - - if a.S3 != nil { - return ArtifactLocationS3 +// SetType sets the type of the artifact to type the argument. +// Any existing value is deleted. +func (a *ArtifactLocation) SetType(x ArtifactLocationType) error { + switch v := x.(type) { + case *ArtifactoryArtifact: + a.Artifactory = &ArtifactoryArtifact{} + case *GCSArtifact: + a.GCS = &GCSArtifact{} + case *HDFSArtifact: + a.HDFS = &HDFSArtifact{} + case *HTTPArtifact: + a.HTTP = &HTTPArtifact{} + case *OSSArtifact: + a.OSS = &OSSArtifact{} + case *RawArtifact: + a.Raw = &RawArtifact{} + case *S3Artifact: + a.S3 = &S3Artifact{} + default: + return fmt.Errorf("set type not supported for type: %v", reflect.TypeOf(v)) } + return nil +} - if a.Git != nil { - return ArtifactLocationGit - } +func (a *ArtifactLocation) HasLocationOrKey() bool { + return a.HasLocation() || a.HasKey() +} - if a.HTTP != nil { - return ArtifactLocationHTTP - } +// HasKey returns whether or not an artifact has a key. They may or may not also HasLocation. +func (a *ArtifactLocation) HasKey() bool { + key, _ := a.GetKey() + return key != "" +} - if a.Artifactory != nil { - return ArtifactLocationArtifactory +// set the key to a new value, use path.Join to combine items +func (a *ArtifactLocation) SetKey(key string) error { + v := a.Get() + if v == nil { + return keyUnsupportedErr } + return v.SetKey(key) +} - if a.HDFS != nil { - return ArtifactLocationHDFS +func (a *ArtifactLocation) AppendToKey(x string) error { + key, err := a.GetKey() + if err != nil { + return err } + return a.SetKey(path.Join(key, x)) +} - if a.Raw != nil { - return ArtifactLocationRaw +// Relocate copies all location info from the parameter, except the key. +// But only if it does not have a location already. +func (a *ArtifactLocation) Relocate(l *ArtifactLocation) error { + if a.HasLocation() { + return nil } - - if a.OSS != nil { - return ArtifactLocationOSS + if l == nil { + return fmt.Errorf("template artifact location not set") } - - if a.GCS != nil { - return ArtifactLocationGCS + key, err := a.GetKey() + if err != nil { + return err } - - return ArtifactLocationUnknown - + *a = *l.DeepCopy() + return a.SetKey(key) } -func (a *ArtifactLocation) GetKey() string { - if a.S3 != nil { - return a.S3.Key - } +// HasLocation whether or not an artifact has a *full* location defined +// An artifact that has a location implicitly has a key (i.e. HasKey() == true). +func (a *ArtifactLocation) HasLocation() bool { + v := a.Get() + return v != nil && v.HasLocation() +} - if a.OSS != nil { - return a.OSS.Key - } +func (a *ArtifactLocation) IsArchiveLogs() bool { + return a != nil && a.ArchiveLogs != nil && *a.ArchiveLogs +} - if a.GCS != nil { - return a.GCS.Key +func (a *ArtifactLocation) GetKey() (string, error) { + v := a.Get() + if v == nil { + return "", keyUnsupportedErr } - - return "" + return v.GetKey() } // +protobuf.options.(gogoproto.goproto_stringer)=false @@ -1730,10 +1768,10 @@ func (n NodeStatus) GetDuration() time.Duration { // S3Bucket contains the access information required for interfacing with an S3 bucket type S3Bucket struct { // Endpoint is the hostname of the bucket endpoint - Endpoint string `json:"endpoint" protobuf:"bytes,1,opt,name=endpoint"` + Endpoint string `json:"endpoint,omitempty" protobuf:"bytes,1,opt,name=endpoint"` // Bucket is the name of the bucket - Bucket string `json:"bucket" protobuf:"bytes,2,opt,name=bucket"` + Bucket string `json:"bucket,omitempty" protobuf:"bytes,2,opt,name=bucket"` // Region contains the optional bucket region Region string `json:"region,omitempty" protobuf:"bytes,3,opt,name=region"` @@ -1742,10 +1780,10 @@ type S3Bucket struct { Insecure *bool `json:"insecure,omitempty" protobuf:"varint,4,opt,name=insecure"` // AccessKeySecret is the secret selector to the bucket's access key - AccessKeySecret apiv1.SecretKeySelector `json:"accessKeySecret" protobuf:"bytes,5,opt,name=accessKeySecret"` + AccessKeySecret *apiv1.SecretKeySelector `json:"accessKeySecret,omitempty" protobuf:"bytes,5,opt,name=accessKeySecret"` // SecretKeySecret is the secret selector to the bucket's secret key - SecretKeySecret apiv1.SecretKeySelector `json:"secretKeySecret" protobuf:"bytes,6,opt,name=secretKeySecret"` + SecretKeySecret *apiv1.SecretKeySelector `json:"secretKeySecret,omitempty" protobuf:"bytes,6,opt,name=secretKeySecret"` // RoleARN is the Amazon Resource Name (ARN) of the role to assume. RoleARN string `json:"roleARN,omitempty" protobuf:"bytes,7,opt,name=roleARN"` @@ -1771,6 +1809,15 @@ type S3Artifact struct { Key string `json:"key" protobuf:"bytes,2,opt,name=key"` } +func (s *S3Artifact) GetKey() (string, error) { + return s.Key, nil +} + +func (s *S3Artifact) SetKey(key string) error { + s.Key = key + return nil +} + func (s *S3Artifact) HasLocation() bool { return s != nil && s.Endpoint != "" && s.Bucket != "" && s.Key != "" } @@ -1807,6 +1854,14 @@ func (g *GitArtifact) HasLocation() bool { return g != nil && g.Repo != "" } +func (g *GitArtifact) GetKey() (string, error) { + return "", keyUnsupportedErr +} + +func (g *GitArtifact) SetKey(string) error { + return keyUnsupportedErr +} + func (g *GitArtifact) GetDepth() int { if g == nil || g.Depth == nil { return 0 @@ -1833,6 +1888,23 @@ type ArtifactoryArtifact struct { //func (a *ArtifactoryArtifact) String() string { // return a.URL //} +func (a *ArtifactoryArtifact) GetKey() (string, error) { + u, err := url.Parse(a.URL) + if err != nil { + return "", err + } + return u.Path, nil +} + +func (a *ArtifactoryArtifact) SetKey(key string) error { + u, err := url.Parse(a.URL) + if err != nil { + return err + } + u.Path = key + a.URL = u.String() + return nil +} func (a *ArtifactoryArtifact) HasLocation() bool { return a != nil && a.URL != "" @@ -1849,6 +1921,15 @@ type HDFSArtifact struct { Force bool `json:"force,omitempty" protobuf:"varint,3,opt,name=force"` } +func (h *HDFSArtifact) GetKey() (string, error) { + return h.Path, nil +} + +func (g *HDFSArtifact) SetKey(key string) error { + g.Path = key + return nil +} + func (h *HDFSArtifact) HasLocation() bool { return h != nil && len(h.Addresses) > 0 } @@ -1858,7 +1939,7 @@ type HDFSConfig struct { HDFSKrbConfig `json:",inline" protobuf:"bytes,1,opt,name=hDFSKrbConfig"` // Addresses is accessible addresses of HDFS name nodes - Addresses []string `json:"addresses" protobuf:"bytes,2,rep,name=addresses"` + Addresses []string `json:"addresses,omitempty" protobuf:"bytes,2,rep,name=addresses"` // HDFSUser is the user to access HDFS file system. // It is ignored if either ccache or keytab is used. @@ -1898,6 +1979,14 @@ type RawArtifact struct { Data string `json:"data" protobuf:"bytes,1,opt,name=data"` } +func (r *RawArtifact) GetKey() (string, error) { + return "", keyUnsupportedErr +} + +func (r *RawArtifact) SetKey(string) error { + return keyUnsupportedErr +} + func (r *RawArtifact) HasLocation() bool { return r != nil } @@ -1920,6 +2009,24 @@ type HTTPArtifact struct { Headers []Header `json:"headers,omitempty" protobuf:"bytes,2,opt,name=headers"` } +func (h *HTTPArtifact) GetKey() (string, error) { + u, err := url.Parse(h.URL) + if err != nil { + return "", err + } + return u.Path, nil +} + +func (g *HTTPArtifact) SetKey(key string) error { + u, err := url.Parse(g.URL) + if err != nil { + return err + } + u.Path = key + g.URL = u.String() + return nil +} + func (h *HTTPArtifact) HasLocation() bool { return h != nil && h.URL != "" } @@ -1928,10 +2035,10 @@ func (h *HTTPArtifact) HasLocation() bool { type GCSBucket struct { // Bucket is the name of the bucket - Bucket string `json:"bucket" protobuf:"bytes,1,opt,name=bucket"` + Bucket string `json:"bucket,omitempty" protobuf:"bytes,1,opt,name=bucket"` // ServiceAccountKeySecret is the secret selector to the bucket's service account key - ServiceAccountKeySecret apiv1.SecretKeySelector `json:"serviceAccountKeySecret,omitempty" protobuf:"bytes,2,opt,name=serviceAccountKeySecret"` + ServiceAccountKeySecret *apiv1.SecretKeySelector `json:"serviceAccountKeySecret,omitempty" protobuf:"bytes,2,opt,name=serviceAccountKeySecret"` } // GCSArtifact is the location of a GCS artifact @@ -1942,6 +2049,15 @@ type GCSArtifact struct { Key string `json:"key" protobuf:"bytes,2,opt,name=key"` } +func (g *GCSArtifact) GetKey() (string, error) { + return g.Key, nil +} + +func (g *GCSArtifact) SetKey(key string) error { + g.Key = key + return nil +} + func (g *GCSArtifact) HasLocation() bool { return g != nil && g.Bucket != "" && g.Key != "" } @@ -1949,16 +2065,16 @@ func (g *GCSArtifact) HasLocation() bool { // OSSBucket contains the access information required for interfacing with an Alibaba Cloud OSS bucket type OSSBucket struct { // Endpoint is the hostname of the bucket endpoint - Endpoint string `json:"endpoint" protobuf:"bytes,1,opt,name=endpoint"` + Endpoint string `json:"endpoint,omitempty" protobuf:"bytes,1,opt,name=endpoint"` // Bucket is the name of the bucket - Bucket string `json:"bucket" protobuf:"bytes,2,opt,name=bucket"` + Bucket string `json:"bucket,omitempty" protobuf:"bytes,2,opt,name=bucket"` // AccessKeySecret is the secret selector to the bucket's access key - AccessKeySecret apiv1.SecretKeySelector `json:"accessKeySecret" protobuf:"bytes,3,opt,name=accessKeySecret"` + AccessKeySecret *apiv1.SecretKeySelector `json:"accessKeySecret,omitempty" protobuf:"bytes,3,opt,name=accessKeySecret"` // SecretKeySecret is the secret selector to the bucket's secret key - SecretKeySecret apiv1.SecretKeySelector `json:"secretKeySecret" protobuf:"bytes,4,opt,name=secretKeySecret"` + SecretKeySecret *apiv1.SecretKeySelector `json:"secretKeySecret,omitempty" protobuf:"bytes,4,opt,name=secretKeySecret"` } // OSSArtifact is the location of an Alibaba Cloud OSS artifact @@ -1969,6 +2085,15 @@ type OSSArtifact struct { Key string `json:"key" protobuf:"bytes,2,opt,name=key"` } +func (o *OSSArtifact) GetKey() (string, error) { + return o.Key, nil +} + +func (o *OSSArtifact) SetKey(key string) error { + o.Key = key + return nil +} + func (o *OSSArtifact) HasLocation() bool { return o != nil && o.Bucket != "" && o.Endpoint != "" && o.Key != "" } diff --git a/pkg/apis/workflow/v1alpha1/workflow_types_test.go b/pkg/apis/workflow/v1alpha1/workflow_types_test.go index 1014497d77da..6b793395b14c 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types_test.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types_test.go @@ -73,29 +73,271 @@ func TestWorkflowHappenedBetween(t *testing.T) { Status: WorkflowStatus{FinishedAt: metav1.Time{Time: t2}}})) } +func TestArtifactLocation_IsArchiveLogs(t *testing.T) { + var l *ArtifactLocation + assert.False(t, l.IsArchiveLogs()) + assert.False(t, (&ArtifactLocation{}).IsArchiveLogs()) + assert.False(t, (&ArtifactLocation{ArchiveLogs: pointer.BoolPtr(false)}).IsArchiveLogs()) + assert.True(t, (&ArtifactLocation{ArchiveLogs: pointer.BoolPtr(true)}).IsArchiveLogs()) +} + func TestArtifactLocation_HasLocation(t *testing.T) { - assert.False(t, (&ArtifactLocation{}).HasLocation()) - assert.False(t, (&ArtifactLocation{ArchiveLogs: pointer.BoolPtr(true)}).HasLocation()) - assert.True(t, (&ArtifactLocation{S3: &S3Artifact{Key: "my-key", S3Bucket: S3Bucket{Endpoint: "my-endpoint", Bucket: "my-bucket"}}}).HasLocation()) - assert.True(t, (&ArtifactLocation{Git: &GitArtifact{Repo: "my-repo"}}).HasLocation()) - assert.True(t, (&ArtifactLocation{HTTP: &HTTPArtifact{URL: "my-url"}}).HasLocation()) - assert.True(t, (&ArtifactLocation{Artifactory: &ArtifactoryArtifact{URL: "my-url"}}).HasLocation()) - assert.True(t, (&ArtifactLocation{Raw: &RawArtifact{Data: "my-data"}}).HasLocation()) - assert.True(t, (&ArtifactLocation{HDFS: &HDFSArtifact{HDFSConfig: HDFSConfig{Addresses: []string{"my-address"}}}}).HasLocation()) - assert.True(t, (&ArtifactLocation{OSS: &OSSArtifact{Key: "my-key", OSSBucket: OSSBucket{Endpoint: "my-endpoint", Bucket: "my-bucket"}}}).HasLocation()) - assert.True(t, (&ArtifactLocation{GCS: &GCSArtifact{Key: "my-key", GCSBucket: GCSBucket{Bucket: "my-bucket"}}}).HasLocation()) -} - -func TestArtifactLocation_GetType(t *testing.T) { - assert.Equal(t, ArtifactLocationUnknown, (&ArtifactLocation{}).GetType()) - assert.Equal(t, ArtifactLocationS3, (&ArtifactLocation{S3: &S3Artifact{Key: "my-key", S3Bucket: S3Bucket{Endpoint: "my-endpoint", Bucket: "my-bucket"}}}).GetType()) - assert.Equal(t, ArtifactLocationGit, (&ArtifactLocation{Git: &GitArtifact{Repo: "my-repo"}}).GetType()) - assert.Equal(t, ArtifactLocationHTTP, (&ArtifactLocation{HTTP: &HTTPArtifact{URL: "my-url"}}).GetType()) - assert.Equal(t, ArtifactLocationArtifactory, (&ArtifactLocation{Artifactory: &ArtifactoryArtifact{URL: "my-url"}}).GetType()) - assert.Equal(t, ArtifactLocationRaw, (&ArtifactLocation{Raw: &RawArtifact{Data: "my-data"}}).GetType()) - assert.Equal(t, ArtifactLocationHDFS, (&ArtifactLocation{HDFS: &HDFSArtifact{HDFSConfig: HDFSConfig{Addresses: []string{"my-address"}}}}).GetType()) - assert.Equal(t, ArtifactLocationOSS, (&ArtifactLocation{OSS: &OSSArtifact{Key: "my-key", OSSBucket: OSSBucket{Endpoint: "my-endpoint", Bucket: "my-bucket"}}}).GetType()) - assert.Equal(t, ArtifactLocationGCS, (&ArtifactLocation{GCS: &GCSArtifact{Key: "my-key", GCSBucket: GCSBucket{Bucket: "my-bucket"}}}).GetType()) + var l *ArtifactLocation + assert.False(t, l.HasLocation(), "Nil") +} + +func TestArtifactoryArtifact(t *testing.T) { + a := &ArtifactoryArtifact{URL: "http://my-host"} + assert.True(t, a.HasLocation()) + assert.NoError(t, a.SetKey("my-key")) + key, err := a.GetKey() + assert.NoError(t, err) + assert.Equal(t, "http://my-host/my-key", a.URL) + assert.Equal(t, "/my-key", key, "has leading slash") +} + +func TestGitArtifact(t *testing.T) { + a := &GitArtifact{Repo: "my-repo"} + assert.True(t, a.HasLocation()) + assert.Error(t, a.SetKey("my-key")) + _, err := a.GetKey() + assert.Error(t, err) +} + +func TestGCSArtifact(t *testing.T) { + a := &GCSArtifact{Key: "my-key", GCSBucket: GCSBucket{Bucket: "my-bucket"}} + assert.True(t, a.HasLocation()) + assert.NoError(t, a.SetKey("my-key")) + key, err := a.GetKey() + assert.NoError(t, err) + assert.Equal(t, "my-key", key) +} + +func TestHDFSArtifact(t *testing.T) { + a := &HDFSArtifact{HDFSConfig: HDFSConfig{Addresses: []string{"my-address"}}} + assert.True(t, a.HasLocation()) + assert.NoError(t, a.SetKey("my-key")) + key, err := a.GetKey() + assert.NoError(t, err) + assert.Equal(t, "my-key", a.Path) + assert.Equal(t, "my-key", key) +} + +func TestHTTPArtifact(t *testing.T) { + a := &HTTPArtifact{URL: "http://my-host"} + assert.True(t, a.HasLocation()) + assert.NoError(t, a.SetKey("my-key")) + key, err := a.GetKey() + assert.NoError(t, err) + assert.Equal(t, "http://my-host/my-key", a.URL) + assert.Equal(t, "/my-key", key, "has leading slack") +} + +func TestOSSArtifact(t *testing.T) { + a := &OSSArtifact{Key: "my-key", OSSBucket: OSSBucket{Endpoint: "my-endpoint", Bucket: "my-bucket"}} + assert.True(t, a.HasLocation()) + assert.NoError(t, a.SetKey("my-key")) + key, err := a.GetKey() + assert.NoError(t, err) + assert.Equal(t, "my-key", key) +} + +func TestRawArtifact(t *testing.T) { + a := &RawArtifact{Data: "my-data"} + assert.True(t, a.HasLocation()) + assert.Error(t, a.SetKey("my-key")) + _, err := a.GetKey() + assert.Error(t, err) +} + +func TestS3Artifact(t *testing.T) { + a := &S3Artifact{Key: "my-key", S3Bucket: S3Bucket{Endpoint: "my-endpoint", Bucket: "my-bucket"}} + assert.True(t, a.HasLocation()) + assert.NoError(t, a.SetKey("my-key")) + key, err := a.GetKey() + assert.NoError(t, err) + assert.Equal(t, "my-key", key) +} + +func TestArtifactLocation_Relocate(t *testing.T) { + t.Run("Error", func(t *testing.T) { + var l *ArtifactLocation + assert.EqualError(t, l.Relocate(nil), "template artifact location not set") + assert.Error(t, l.Relocate(&ArtifactLocation{})) + assert.Error(t, (&ArtifactLocation{}).Relocate(nil)) + assert.Error(t, (&ArtifactLocation{}).Relocate(&ArtifactLocation{})) + assert.Error(t, (&ArtifactLocation{}).Relocate(&ArtifactLocation{S3: &S3Artifact{}})) + assert.Error(t, (&ArtifactLocation{S3: &S3Artifact{}}).Relocate(&ArtifactLocation{})) + }) + t.Run("HasLocation", func(t *testing.T) { + l := &ArtifactLocation{S3: &S3Artifact{S3Bucket: S3Bucket{Bucket: "my-bucket", Endpoint: "my-endpoint"}, Key: "my-key"}} + assert.NoError(t, l.Relocate(&ArtifactLocation{S3: &S3Artifact{S3Bucket: S3Bucket{Bucket: "other-bucket"}}})) + assert.Equal(t, "my-endpoint", l.S3.Endpoint, "endpoint is unchanged") + assert.Equal(t, "my-bucket", l.S3.Bucket, "bucket is unchanged") + assert.Equal(t, "my-key", l.S3.Key, "key is unchanged") + }) + t.Run("NotHasLocation", func(t *testing.T) { + l := &ArtifactLocation{S3: &S3Artifact{Key: "my-key"}} + assert.NoError(t, l.Relocate(&ArtifactLocation{S3: &S3Artifact{S3Bucket: S3Bucket{Bucket: "my-bucket"}, Key: "other-key"}})) + assert.Equal(t, "my-bucket", l.S3.Bucket, "bucket copied from argument") + assert.Equal(t, "my-key", l.S3.Key, "key is unchanged") + }) +} + +func TestArtifactLocation_Get(t *testing.T) { + var l *ArtifactLocation + assert.Nil(t, l.Get()) + assert.Nil(t, (&ArtifactLocation{}).Get()) + assert.IsType(t, &GitArtifact{}, (&ArtifactLocation{Git: &GitArtifact{}}).Get()) + assert.IsType(t, &GCSArtifact{}, (&ArtifactLocation{GCS: &GCSArtifact{}}).Get()) + assert.IsType(t, &HDFSArtifact{}, (&ArtifactLocation{HDFS: &HDFSArtifact{}}).Get()) + assert.IsType(t, &HTTPArtifact{}, (&ArtifactLocation{HTTP: &HTTPArtifact{}}).Get()) + assert.IsType(t, &OSSArtifact{}, (&ArtifactLocation{OSS: &OSSArtifact{}}).Get()) + assert.IsType(t, &RawArtifact{}, (&ArtifactLocation{Raw: &RawArtifact{}}).Get()) + assert.IsType(t, &S3Artifact{}, (&ArtifactLocation{S3: &S3Artifact{}}).Get()) +} + +func TestArtifactLocation_SetType(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + l := &ArtifactLocation{} + assert.Error(t, l.SetType(nil)) + }) + t.Run("Artifactory", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&ArtifactoryArtifact{})) + assert.NotNil(t, l.Artifactory) + }) + t.Run("GCS", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&GCSArtifact{})) + assert.NotNil(t, l.GCS) + }) + t.Run("HDFS", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&HDFSArtifact{})) + assert.NotNil(t, l.HDFS) + }) + t.Run("HTTP", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&HTTPArtifact{})) + assert.NotNil(t, l.HTTP) + }) + t.Run("OSS", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&OSSArtifact{})) + assert.NotNil(t, l.OSS) + }) + t.Run("Raw", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&RawArtifact{})) + assert.NotNil(t, l.Raw) + }) + t.Run("S3", func(t *testing.T) { + l := &ArtifactLocation{} + assert.NoError(t, l.SetType(&S3Artifact{})) + assert.NotNil(t, l.S3) + }) +} + +func TestArtifactLocation_Key(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + var l *ArtifactLocation + assert.False(t, l.HasKey()) + _, err := l.GetKey() + assert.Error(t, err, "cannot get nil") + err = l.SetKey("my-file") + assert.Error(t, err, "cannot set nil") + }) + t.Run("Empty", func(t *testing.T) { + // unlike nil, empty is actually invalid + l := &ArtifactLocation{} + assert.False(t, l.HasKey()) + _, err := l.GetKey() + assert.Error(t, err, "cannot get empty") + err = l.SetKey("my-file") + assert.Error(t, err, "cannot set empty") + }) + t.Run("Artifactory", func(t *testing.T) { + l := &ArtifactLocation{Artifactory: &ArtifactoryArtifact{URL: "http://my-host/my-dir?a=1"}} + err := l.AppendToKey("my-file") + assert.NoError(t, err) + assert.Equal(t, "http://my-host/my-dir/my-file?a=1", l.Artifactory.URL, "appends to Artifactory path") + }) + t.Run("Git", func(t *testing.T) { + l := &ArtifactLocation{Git: &GitArtifact{}} + assert.False(t, l.HasKey()) + _, err := l.GetKey() + assert.Error(t, err) + err = l.SetKey("my-file") + assert.Error(t, err, "cannot set Git key") + }) + t.Run("GCS", func(t *testing.T) { + l := &ArtifactLocation{GCS: &GCSArtifact{Key: "my-dir"}} + err := l.AppendToKey("my-file") + assert.NoError(t, err) + assert.Equal(t, "my-dir/my-file", l.GCS.Key, "appends to GCS key") + }) + t.Run("HDFS", func(t *testing.T) { + l := &ArtifactLocation{HDFS: &HDFSArtifact{Path: "my-path"}} + err := l.AppendToKey("my-file") + assert.NoError(t, err) + assert.Equal(t, "my-path/my-file", l.HDFS.Path, "appends to HDFS path") + }) + t.Run("HTTP", func(t *testing.T) { + l := &ArtifactLocation{HTTP: &HTTPArtifact{URL: "http://my-host/my-dir?a=1"}} + err := l.AppendToKey("my-file") + assert.NoError(t, err) + assert.Equal(t, "http://my-host/my-dir/my-file?a=1", l.HTTP.URL, "appends to HTTP URL path") + }) + t.Run("OSS", func(t *testing.T) { + l := &ArtifactLocation{OSS: &OSSArtifact{Key: "my-dir"}} + err := l.AppendToKey("my-file") + assert.NoError(t, err) + assert.Equal(t, "my-dir/my-file", l.OSS.Key, "appends to OSS key") + }) + t.Run("Raw", func(t *testing.T) { + l := &ArtifactLocation{Raw: &RawArtifact{}} + assert.False(t, l.HasKey()) + _, err := l.GetKey() + assert.Error(t, err, "cannot get raw key") + err = l.SetKey("my-file") + assert.Error(t, err, "cannot set raw key") + }) + t.Run("S3", func(t *testing.T) { + l := &ArtifactLocation{S3: &S3Artifact{Key: "my-dir"}} + err := l.AppendToKey("my-file") + assert.NoError(t, err) + assert.Equal(t, "my-dir/my-file", l.S3.Key, "appends to S3 key") + }) +} + +func TestArtifactRepositoryRef_GetConfigMapOr(t *testing.T) { + var r *ArtifactRepositoryRef + assert.Equal(t, "my-cm", r.GetConfigMapOr("my-cm")) + assert.Equal(t, "my-cm", (&ArtifactRepositoryRef{}).GetConfigMapOr("my-cm")) + assert.Equal(t, "my-cm", (&ArtifactRepositoryRef{ConfigMap: "my-cm"}).GetConfigMapOr("")) +} + +func TestArtifactRepositoryRef_GetKeyOr(t *testing.T) { + var r *ArtifactRepositoryRef + assert.Equal(t, "", r.GetKeyOr("")) + assert.Equal(t, "my-key", (&ArtifactRepositoryRef{}).GetKeyOr("my-key")) + assert.Equal(t, "my-key", (&ArtifactRepositoryRef{Key: "my-key"}).GetKeyOr("")) +} + +func TestArtifactRepositoryRef_String(t *testing.T) { + var l *ArtifactRepositoryRef + assert.Equal(t, "nil", l.String()) + assert.Equal(t, "#", (&ArtifactRepositoryRef{}).String()) + assert.Equal(t, "my-cm#my-key", (&ArtifactRepositoryRef{ConfigMap: "my-cm", Key: "my-key"}).String()) +} + +func TestArtifactRepositoryRefStatus_String(t *testing.T) { + var l *ArtifactRepositoryRefStatus + assert.Equal(t, "nil", l.String()) + assert.Equal(t, "/#", (&ArtifactRepositoryRefStatus{}).String()) + assert.Equal(t, "default-artifact-repository", (&ArtifactRepositoryRefStatus{Default: true}).String()) + assert.Equal(t, "my-ns/my-cm#my-key", (&ArtifactRepositoryRefStatus{Namespace: "my-ns", ArtifactRepositoryRef: ArtifactRepositoryRef{ConfigMap: "my-cm", Key: "my-key"}}).String()) } func TestArtifact_GetArchive(t *testing.T) { diff --git a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go index 6f2138b1f0bd..5b655c0409f9 100644 --- a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go @@ -735,7 +735,11 @@ func (in *GCSArtifact) DeepCopy() *GCSArtifact { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GCSBucket) DeepCopyInto(out *GCSBucket) { *out = *in - in.ServiceAccountKeySecret.DeepCopyInto(&out.ServiceAccountKeySecret) + if in.ServiceAccountKeySecret != nil { + in, out := &in.ServiceAccountKeySecret, &out.ServiceAccountKeySecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } return } @@ -1302,8 +1306,16 @@ func (in *OSSArtifact) DeepCopy() *OSSArtifact { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OSSBucket) DeepCopyInto(out *OSSBucket) { *out = *in - in.AccessKeySecret.DeepCopyInto(&out.AccessKeySecret) - in.SecretKeySecret.DeepCopyInto(&out.SecretKeySecret) + if in.AccessKeySecret != nil { + in, out := &in.AccessKeySecret, &out.AccessKeySecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + if in.SecretKeySecret != nil { + in, out := &in.SecretKeySecret, &out.SecretKeySecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } return } @@ -1626,8 +1638,16 @@ func (in *S3Bucket) DeepCopyInto(out *S3Bucket) { *out = new(bool) **out = **in } - in.AccessKeySecret.DeepCopyInto(&out.AccessKeySecret) - in.SecretKeySecret.DeepCopyInto(&out.SecretKeySecret) + if in.AccessKeySecret != nil { + in, out := &in.AccessKeySecret, &out.AccessKeySecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + if in.SecretKeySecret != nil { + in, out := &in.SecretKeySecret, &out.SecretKeySecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } if in.CreateBucketIfNotPresent != nil { in, out := &in.CreateBucketIfNotPresent, &out.CreateBucketIfNotPresent *out = new(CreateS3BucketOptions) diff --git a/server/artifacts/artifact_server.go b/server/artifacts/artifact_server.go index 1e3cc0f0e090..0565f711edd4 100644 --- a/server/artifacts/artifact_server.go +++ b/server/artifacts/artifact_server.go @@ -134,6 +134,20 @@ func (a *ArtifactServer) returnArtifact(ctx context.Context, w http.ResponseWrit return fmt.Errorf("artifact not found") } + ref, err := a.artifactRepositories.Resolve(ctx, wf.Spec.ArtifactRepositoryRef, wf.Namespace) + if err != nil { + return err + } + ar, err := a.artifactRepositories.Get(ctx, ref) + if err != nil { + return err + } + l := ar.ToArtifactLocation() + err = art.Relocate(l) + if err != nil { + return err + } + driver, err := a.artDriverFactory(ctx, art, resources{kubeClient, wf.Namespace}) if err != nil { return err @@ -167,7 +181,8 @@ func (a *ArtifactServer) returnArtifact(ctx context.Context, w http.ResponseWrit contentLength := strconv.FormatInt(stats.Size(), 10) log.WithFields(log.Fields{"size": contentLength}).Debug("Artifact file size") - w.Header().Add("Content-Disposition", fmt.Sprintf(`filename="%s"`, path.Base(art.GetKey()))) + key, _ := art.GetKey() + w.Header().Add("Content-Disposition", fmt.Sprintf(`filename="%s"`, path.Base(key))) w.WriteHeader(200) http.ServeContent(w, r, "", time.Time{}, file) diff --git a/server/artifacts/artifact_server_test.go b/server/artifacts/artifact_server_test.go index 6072885216dd..91375b1c03e5 100644 --- a/server/artifacts/artifact_server_test.go +++ b/server/artifacts/artifact_server_test.go @@ -67,6 +67,7 @@ func newServer() *ArtifactServer { Name: "my-s3-artifact", ArtifactLocation: wfv1.ArtifactLocation{ S3: &wfv1.S3Artifact{ + // S3 is a configured artifact repo, so does not need key Key: "my-wf/my-node/my-s3-artifact.tgz", }, }, @@ -75,6 +76,10 @@ func newServer() *ArtifactServer { Name: "my-gcs-artifact", ArtifactLocation: wfv1.ArtifactLocation{ GCS: &wfv1.GCSArtifact{ + // GCS is not a configured artifact repo, so must have bucket + GCSBucket: wfv1.GCSBucket{ + Bucket: "my-bucket", + }, Key: "my-wf/my-node/my-gcs-artifact", }, }, @@ -82,7 +87,11 @@ func newServer() *ArtifactServer { { Name: "my-oss-artifact", ArtifactLocation: wfv1.ArtifactLocation{ - GCS: &wfv1.GCSArtifact{ + OSS: &wfv1.OSSArtifact{ + // OSS is not a configured artifact repo, so must have bucket + OSSBucket: wfv1.OSSBucket{ + Bucket: "my-bucket", + }, Key: "my-wf/my-node/my-oss-artifact.zip", }, }, @@ -103,7 +112,16 @@ func newServer() *ArtifactServer { return &fakeArtifactDriver{data: []byte("my-data")}, nil } - return newArtifactServer(gatekeeper, hydratorfake.Noop, a, instanceid.NewService(instanceId), fakeArtifactDriverFactory, armocks.DummyArtifactRepositories(&config.ArtifactRepository{})) + artifactRepositories := armocks.DummyArtifactRepositories(&config.ArtifactRepository{ + S3: &config.S3ArtifactRepository{ + S3Bucket: wfv1.S3Bucket{ + Endpoint: "my-endpoint", + Bucket: "my-bucket", + }, + }, + }) + + return newArtifactServer(gatekeeper, hydratorfake.Noop, a, instanceid.NewService(instanceId), fakeArtifactDriverFactory, artifactRepositories) } func TestArtifactServer_GetArtifact(t *testing.T) { @@ -133,9 +151,10 @@ func TestArtifactServer_GetArtifact(t *testing.T) { r.URL = mustParse(fmt.Sprintf("/artifacts/my-ns/my-wf/my-node/%s", tt.artifactName)) w := &testhttp.TestResponseWriter{} s.GetArtifact(w, r) - assert.Equal(t, 200, w.StatusCode) - assert.Equal(t, fmt.Sprintf(`filename="%s"`, tt.fileName), w.Header().Get("Content-Disposition")) - assert.Equal(t, "my-data", w.Output) + if assert.Equal(t, 200, w.StatusCode) { + assert.Equal(t, fmt.Sprintf(`filename="%s"`, tt.fileName), w.Header().Get("Content-Disposition")) + assert.Equal(t, "my-data", w.Output) + } }) } } diff --git a/test/e2e/functional_test.go b/test/e2e/functional_test.go index c86fd33dbed4..8c7791cdc327 100644 --- a/test/e2e/functional_test.go +++ b/test/e2e/functional_test.go @@ -409,6 +409,19 @@ func (s *FunctionalSuite) TestArtifactRepositoryRef() { Then(). ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { assert.Equal(t, wfv1.NodeSucceeded, status.Phase) + if assert.NotEmpty(t, status.ArtifactRepositoryRef) { + assert.Equal(t, "argo", status.ArtifactRepositoryRef.Namespace) + assert.Equal(t, "artifact-repositories", status.ArtifactRepositoryRef.ConfigMap) + assert.Equal(t, "my-key", status.ArtifactRepositoryRef.Key) + assert.False(t, status.ArtifactRepositoryRef.Default) + } + // these should never be set because we must get them from the artifactRepositoryRef + generated := status.Nodes.FindByDisplayName("generate").Outputs.Artifacts[0].S3 + assert.Empty(t, generated.Bucket) + assert.NotEmpty(t, generated.Key) + consumed := status.Nodes.FindByDisplayName("consume").Inputs.Artifacts[0].S3 + assert.Empty(t, consumed.Bucket) + assert.NotEmpty(t, consumed.Key) }) } diff --git a/test/e2e/testdata/artifact-repository-ref.yaml b/test/e2e/testdata/artifact-repository-ref.yaml index 9502924562f9..29ae21188698 100644 --- a/test/e2e/testdata/artifact-repository-ref.yaml +++ b/test/e2e/testdata/artifact-repository-ref.yaml @@ -3,25 +3,43 @@ kind: Workflow metadata: name: artifact-repository-ref labels: - argo-e2e: true + argo-e2e: "true" spec: entrypoint: main artifactRepositoryRef: key: my-key templates: - name: main + dag: + tasks: + - name: generate + template: generate + - name: consume + template: consume + dependencies: + - generate + - name: generate container: image: argoproj/argosay:v2 args: - echo - hello - - /tmp/file - inputs: + - /mnt/file + outputs: artifacts: - name: file - path: /tmp/file - optional: true - outputs: + path: /mnt/file + s3: + key: my-file + - name: consume + container: + image: argoproj/argosay:v2 + args: + - cat + - /tmp/file + inputs: artifacts: - name: file path: /tmp/file + s3: + key: my-file diff --git a/workflow/common/util.go b/workflow/common/util.go index ead4e7ac3ae8..4e27bd1ab6e6 100644 --- a/workflow/common/util.go +++ b/workflow/common/util.go @@ -271,11 +271,10 @@ func ProcessArgs(tmpl *wfv1.Template, args wfv1.ArgumentsProvider, globalParams, } // Performs substitutions of input artifacts - newInputArtifacts := make([]wfv1.Artifact, len(newTmpl.Inputs.Artifacts)) - for i, inArt := range newTmpl.Inputs.Artifacts { + artifacts := newTmpl.Inputs.Artifacts + for i, inArt := range artifacts { // if artifact has hard-wired location, we prefer that - if inArt.HasLocation() { - newInputArtifacts[i] = inArt + if inArt.HasLocationOrKey() { continue } argArt := args.GetArtifactByName(inArt.Name) @@ -284,20 +283,17 @@ func ProcessArgs(tmpl *wfv1.Template, args wfv1.ArgumentsProvider, globalParams, if argArt == nil { return nil, errors.Errorf(errors.CodeBadRequest, "inputs.artifacts.%s was not supplied", inArt.Name) } - if !argArt.HasLocation() && !validateOnly { + if !argArt.HasLocationOrKey() && !validateOnly { return nil, errors.Errorf(errors.CodeBadRequest, "inputs.artifacts.%s missing location information", inArt.Name) } } if argArt != nil { - argArt.Path = inArt.Path - argArt.Mode = inArt.Mode - argArt.RecurseMode = inArt.RecurseMode - newInputArtifacts[i] = *argArt - } else { - newInputArtifacts[i] = inArt + artifacts[i] = *argArt + artifacts[i].Path = inArt.Path + artifacts[i].Mode = inArt.Mode + artifacts[i].RecurseMode = inArt.RecurseMode } } - newTmpl.Inputs.Artifacts = newInputArtifacts return SubstituteParams(newTmpl, globalParams, localParams) } diff --git a/workflow/controller/scope.go b/workflow/controller/scope.go index da9ec05443c8..e9900b54e48a 100644 --- a/workflow/controller/scope.go +++ b/workflow/controller/scope.go @@ -1,8 +1,6 @@ package controller import ( - "net/url" - "path" "strings" "github.com/valyala/fasttemplate" @@ -92,47 +90,7 @@ func (s *wfScope) resolveArtifact(v string, subPath string) (*wfv1.Artifact, err // Copy resolved artifact pointer before adding subpath copyArt := valArt.DeepCopy() - - locationType := copyArt.ArtifactLocation.GetType() - - if locationType == "" { - return nil, errors.Errorf(errors.CodeBadRequest, "No artifact location found for reference: {{%s}}", v) - } - - switch locationType { - case wfv1.ArtifactLocationS3: - copyArt.S3.Key = path.Join(copyArt.S3.Key, resolvedSubPath) - - case wfv1.ArtifactLocationHDFS: - copyArt.HDFS.Path = path.Join(copyArt.HDFS.Path, resolvedSubPath) - - case wfv1.ArtifactLocationOSS: - copyArt.OSS.Key = path.Join(copyArt.OSS.Key, resolvedSubPath) - - case wfv1.ArtifactLocationGCS: - copyArt.GCS.Key = path.Join(copyArt.GCS.Key, resolvedSubPath) - - case wfv1.ArtifactLocationArtifactory: - u, err := url.Parse(copyArt.Artifactory.URL) - if err != nil { - return nil, err - } - u.Path = path.Join(u.Path, resolvedSubPath) - copyArt.Artifactory.URL = u.String() - - case wfv1.ArtifactLocationHTTP: - u, err := url.Parse(copyArt.HTTP.URL) - if err != nil { - return nil, err - } - u.Path = path.Join(u.Path, resolvedSubPath) - copyArt.HTTP.URL = u.String() - - default: - return nil, errors.Errorf(errors.CodeBadRequest, "Artifact location of type {{%s}} does not support SubPath resolution", locationType) - } - - return copyArt, nil + return copyArt, copyArt.AppendToKey(resolvedSubPath) } return &valArt, nil diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 774437b67329..bb6a680c332b 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "path" "path/filepath" "strconv" "time" @@ -227,10 +226,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin pod.Spec.ShareProcessNamespace = pointer.BoolPtr(true) } - err = woc.addArchiveLocation(tmpl) - if err != nil { - return nil, err - } + woc.addArchiveLocation(tmpl) err = woc.setupServiceAccount(ctx, pod, tmpl) if err != nil { @@ -869,7 +865,7 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.T if art.Path == "" { return errors.Errorf(errors.CodeBadRequest, "inputs.artifacts.%s did not specify a path", art.Name) } - if !art.HasLocation() && art.Optional { + if !art.HasLocationOrKey() && art.Optional { woc.log.Infof("skip volume mount of %s (%s): optional artifact was not provided", art.Name, art.Path) continue @@ -936,101 +932,22 @@ func addOutputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.Template) { // information configured in the controller, for the purposes of archiving outputs. This is skipped // for templates which do not need to archive anything, or have explicitly set an archive location // in the template. -func (woc *wfOperationCtx) addArchiveLocation(tmpl *wfv1.Template) error { - // needLocation keeps track if the workflow needs to have an archive location set. - // If so, and one was not supplied (or defaulted), we will return error - var needLocation bool - - if tmpl.ArchiveLocation != nil { - if tmpl.ArchiveLocation.S3 != nil || tmpl.ArchiveLocation.Artifactory != nil || tmpl.ArchiveLocation.HDFS != nil || tmpl.ArchiveLocation.OSS != nil || tmpl.ArchiveLocation.GCS != nil { - // User explicitly set the location. nothing else to do. - return nil - } - if tmpl.ArchiveLocation.ArchiveLogs != nil && *tmpl.ArchiveLocation.ArchiveLogs { - needLocation = true - } +func (woc *wfOperationCtx) addArchiveLocation(tmpl *wfv1.Template) { + if tmpl.ArchiveLocation.HasLocation() { + // User explicitly set the location. nothing else to do. + return } - for _, art := range tmpl.Outputs.Artifacts { + needLocation := woc.artifactRepository.IsArchiveLogs() + for _, art := range append(tmpl.Inputs.Artifacts, tmpl.Outputs.Artifacts...) { if !art.HasLocation() { needLocation = true - break } } - if woc.artifactRepository.IsArchiveLogs() { - needLocation = true - } + woc.log.WithField("needLocation", needLocation).Debug() if !needLocation { - woc.log.Debugf("archive location unnecessary") - return nil - } - tmpl.ArchiveLocation = &wfv1.ArtifactLocation{ - ArchiveLogs: woc.artifactRepository.ArchiveLogs, - } - // artifact location is defaulted using the following formula: - // //.tgz - // (e.g. myworkflowartifacts/argo-wf-fhljp/argo-wf-fhljp-123291312382/src.tgz) - if s3Location := woc.artifactRepository.S3; s3Location != nil { - woc.log.Debugf("Setting s3 artifact repository information") - artLocationKey := s3Location.KeyFormat - // NOTE: we use unresolved variables, will get substituted later - if artLocationKey == "" { - artLocationKey = path.Join(s3Location.KeyPrefix, common.DefaultArchivePattern) - } - tmpl.ArchiveLocation.S3 = &wfv1.S3Artifact{ - S3Bucket: s3Location.S3Bucket, - Key: artLocationKey, - } - } else if woc.artifactRepository.Artifactory != nil { - woc.log.Debugf("Setting artifactory artifact repository information") - repoURL := "" - if woc.artifactRepository.Artifactory.RepoURL != "" { - repoURL = woc.artifactRepository.Artifactory.RepoURL + "/" - } - artURL := fmt.Sprintf("%s%s", repoURL, common.DefaultArchivePattern) - tmpl.ArchiveLocation.Artifactory = &wfv1.ArtifactoryArtifact{ - ArtifactoryAuth: woc.artifactRepository.Artifactory.ArtifactoryAuth, - URL: artURL, - } - } else if hdfsLocation := woc.artifactRepository.HDFS; hdfsLocation != nil { - woc.log.Debugf("Setting HDFS artifact repository information") - tmpl.ArchiveLocation.HDFS = &wfv1.HDFSArtifact{ - HDFSConfig: hdfsLocation.HDFSConfig, - Path: hdfsLocation.PathFormat, - Force: hdfsLocation.Force, - } - } else if ossLocation := woc.artifactRepository.OSS; ossLocation != nil { - woc.log.Debugf("Setting OSS artifact repository information") - artLocationKey := ossLocation.KeyFormat - // NOTE: we use unresolved variables, will get substituted later - if artLocationKey == "" { - artLocationKey = path.Join(ossLocation.KeyFormat, common.DefaultArchivePattern) - } - tmpl.ArchiveLocation.OSS = &wfv1.OSSArtifact{ - OSSBucket: wfv1.OSSBucket{ - Bucket: ossLocation.Bucket, - Endpoint: ossLocation.Endpoint, - AccessKeySecret: ossLocation.AccessKeySecret, - SecretKeySecret: ossLocation.SecretKeySecret, - }, - Key: artLocationKey, - } - } else if gcsLocation := woc.artifactRepository.GCS; gcsLocation != nil { - woc.log.Debugf("Setting GCS artifact repository information") - artLocationKey := gcsLocation.KeyFormat - if artLocationKey == "" { - artLocationKey = common.DefaultArchivePattern - } - tmpl.ArchiveLocation.GCS = &wfv1.GCSArtifact{ - GCSBucket: wfv1.GCSBucket{ - Bucket: gcsLocation.Bucket, - ServiceAccountKeySecret: gcsLocation.ServiceAccountKeySecret, - }, - Key: artLocationKey, - } - } else { - return errors.Errorf(errors.CodeBadRequest, "controller is not configured with a default archive location") + return } - return nil + tmpl.ArchiveLocation = woc.artifactRepository.ToArtifactLocation() } // setupServiceAccount sets up service account and token. @@ -1208,8 +1125,8 @@ func createArchiveLocationSecret(tmpl *wfv1.Template, volMap map[string]apiv1.Vo return } if s3ArtRepo := tmpl.ArchiveLocation.S3; s3ArtRepo != nil { - createSecretVal(volMap, &s3ArtRepo.AccessKeySecret, uniqueKeyMap) - createSecretVal(volMap, &s3ArtRepo.SecretKeySecret, uniqueKeyMap) + createSecretVal(volMap, s3ArtRepo.AccessKeySecret, uniqueKeyMap) + createSecretVal(volMap, s3ArtRepo.SecretKeySecret, uniqueKeyMap) } else if hdfsArtRepo := tmpl.ArchiveLocation.HDFS; hdfsArtRepo != nil { createSecretVal(volMap, hdfsArtRepo.KrbKeytabSecret, uniqueKeyMap) createSecretVal(volMap, hdfsArtRepo.KrbCCacheSecret, uniqueKeyMap) @@ -1221,17 +1138,17 @@ func createArchiveLocationSecret(tmpl *wfv1.Template, volMap map[string]apiv1.Vo createSecretVal(volMap, gitRepo.PasswordSecret, uniqueKeyMap) createSecretVal(volMap, gitRepo.SSHPrivateKeySecret, uniqueKeyMap) } else if ossRepo := tmpl.ArchiveLocation.OSS; ossRepo != nil { - createSecretVal(volMap, &ossRepo.AccessKeySecret, uniqueKeyMap) - createSecretVal(volMap, &ossRepo.SecretKeySecret, uniqueKeyMap) + createSecretVal(volMap, ossRepo.AccessKeySecret, uniqueKeyMap) + createSecretVal(volMap, ossRepo.SecretKeySecret, uniqueKeyMap) } else if gcsRepo := tmpl.ArchiveLocation.GCS; gcsRepo != nil { - createSecretVal(volMap, &gcsRepo.ServiceAccountKeySecret, uniqueKeyMap) + createSecretVal(volMap, gcsRepo.ServiceAccountKeySecret, uniqueKeyMap) } } func createSecretVolume(volMap map[string]apiv1.Volume, art wfv1.Artifact, keyMap map[string]bool) { if art.S3 != nil { - createSecretVal(volMap, &art.S3.AccessKeySecret, keyMap) - createSecretVal(volMap, &art.S3.SecretKeySecret, keyMap) + createSecretVal(volMap, art.S3.AccessKeySecret, keyMap) + createSecretVal(volMap, art.S3.SecretKeySecret, keyMap) } else if art.Git != nil { createSecretVal(volMap, art.Git.UsernameSecret, keyMap) createSecretVal(volMap, art.Git.PasswordSecret, keyMap) @@ -1243,10 +1160,10 @@ func createSecretVolume(volMap map[string]apiv1.Volume, art wfv1.Artifact, keyMa createSecretVal(volMap, art.HDFS.KrbCCacheSecret, keyMap) createSecretVal(volMap, art.HDFS.KrbKeytabSecret, keyMap) } else if art.OSS != nil { - createSecretVal(volMap, &art.OSS.AccessKeySecret, keyMap) - createSecretVal(volMap, &art.OSS.SecretKeySecret, keyMap) + createSecretVal(volMap, art.OSS.AccessKeySecret, keyMap) + createSecretVal(volMap, art.OSS.SecretKeySecret, keyMap) } else if art.GCS != nil { - createSecretVal(volMap, &art.GCS.ServiceAccountKeySecret, keyMap) + createSecretVal(volMap, art.GCS.ServiceAccountKeySecret, keyMap) } } diff --git a/workflow/controller/workflowpod_test.go b/workflow/controller/workflowpod_test.go index 8e129d8ae997..ac2b1aab3444 100644 --- a/workflow/controller/workflowpod_test.go +++ b/workflow/controller/workflowpod_test.go @@ -140,20 +140,6 @@ script: ls -al ` -var scriptTemplateWithOptionalInputArtifactNotProvided = ` -name: script-with-input-artifact -inputs: - artifacts: - - name: manifest - path: /manifest - optional: true -script: - image: alpine:latest - command: [sh] - source: | - ls -al -` - // TestScriptTemplateWithVolume ensure we can a script pod with input artifacts func TestScriptTemplateWithoutVolumeOptionalArtifact(t *testing.T) { volumeMount := apiv1.VolumeMount{ @@ -209,16 +195,6 @@ func TestScriptTemplateWithoutVolumeOptionalArtifact(t *testing.T) { assert.NotContains(t, pod.Spec.Containers[1].VolumeMounts, volumeMount) assert.Contains(t, pod.Spec.Containers[1].VolumeMounts, customVolumeMount) assert.Contains(t, pod.Spec.InitContainers[0].VolumeMounts, customVolumeMountForInit) - - // Ensure that volume mount is not created when artifact is not provided - tmpl = unmarshalTemplate(scriptTemplateWithOptionalInputArtifactNotProvided) - woc = newWoc() - mainCtr = tmpl.Script.Container - mainCtr.Args = append(mainCtr.Args, common.ExecutorScriptSourcePath) - - pod, err = woc.createWorkflowPod(ctx, tmpl.Name, mainCtr, tmpl, &createWorkflowPodOpts{}) - assert.NoError(t, err) - assert.NotContains(t, pod.Spec.Containers[1].VolumeMounts, volumeMount) } // TestWFLevelServiceAccount verifies the ability to carry forward the service account name diff --git a/workflow/executor/executor.go b/workflow/executor/executor.go index fedbfeb9fb09..fa84646bc87e 100644 --- a/workflow/executor/executor.go +++ b/workflow/executor/executor.go @@ -11,7 +11,6 @@ import ( "fmt" "io" "io/ioutil" - "net/url" "os" "os/signal" "path" @@ -145,7 +144,7 @@ func (we *WorkflowExecutor) LoadArtifacts(ctx context.Context) error { log.Infof("Downloading artifact: %s", art.Name) - if !art.HasLocation() { + if !art.HasLocationOrKey() { if art.Optional { log.Warnf("Ignoring optional artifact '%s' which was not supplied", art.Name) continue @@ -153,7 +152,11 @@ func (we *WorkflowExecutor) LoadArtifacts(ctx context.Context) error { return errors.Errorf("required artifact %s not supplied", art.Name) } } - artDriver, err := we.InitDriver(ctx, &art) + driverArt, err := we.newDriverArt(&art) + if err != nil { + return err + } + artDriver, err := we.InitDriver(ctx, driverArt) if err != nil { return err } @@ -179,7 +182,7 @@ func (we *WorkflowExecutor) LoadArtifacts(ctx context.Context) error { // the file is a tarball or not. If it is, it is first extracted then renamed to // the desired location. If not, it is simply renamed to the location. tempArtPath := artPath + ".tmp" - err = artDriver.Load(&art, tempArtPath) + err = artDriver.Load(driverArt, tempArtPath) if err != nil { if art.Optional && errors.IsCode(errors.CodeNotFound, err) { log.Infof("Skipping optional input artifact that was not found: %s", art.Name) @@ -296,47 +299,32 @@ func (we *WorkflowExecutor) saveArtifact(ctx context.Context, mainCtrID string, } return err } - if !art.HasLocation() { - // If user did not explicitly set an artifact destination location in the template, - // use the default archive location (appended with the filename). - if we.Template.ArchiveLocation == nil { - return errors.Errorf(errors.CodeBadRequest, "Unable to determine path to store %s. No archive location", art.Name) + return we.saveArtifactFromFile(ctx, art, fileName, localArtPath) +} + +// fileBase is probably path.Base(filePath), but can be something else +func (we *WorkflowExecutor) saveArtifactFromFile(ctx context.Context, art *wfv1.Artifact, fileName, localArtPath string) error { + if !art.HasKey() { + key, err := we.Template.ArchiveLocation.GetKey() + if err != nil { + return err } - if we.Template.ArchiveLocation.S3 != nil { - shallowCopy := *we.Template.ArchiveLocation.S3 - art.S3 = &shallowCopy - art.S3.Key = path.Join(art.S3.Key, fileName) - } else if we.Template.ArchiveLocation.Artifactory != nil { - shallowCopy := *we.Template.ArchiveLocation.Artifactory - art.Artifactory = &shallowCopy - artifactoryURL, urlParseErr := url.Parse(art.Artifactory.URL) - if urlParseErr != nil { - return urlParseErr - } - artifactoryURL.Path = path.Join(artifactoryURL.Path, fileName) - art.Artifactory.URL = artifactoryURL.String() - } else if we.Template.ArchiveLocation.HDFS != nil { - shallowCopy := *we.Template.ArchiveLocation.HDFS - art.HDFS = &shallowCopy - art.HDFS.Path = path.Join(art.HDFS.Path, fileName) - } else if we.Template.ArchiveLocation.OSS != nil { - shallowCopy := *we.Template.ArchiveLocation.OSS - art.OSS = &shallowCopy - art.OSS.Key = path.Join(art.OSS.Key, fileName) - } else if we.Template.ArchiveLocation.GCS != nil { - shallowCopy := *we.Template.ArchiveLocation.GCS - art.GCS = &shallowCopy - art.GCS.Key = path.Join(art.GCS.Key, fileName) - } else { - return errors.Errorf(errors.CodeBadRequest, "Unable to determine path to store %s. Archive location provided no information", art.Name) + if err = art.SetType(we.Template.ArchiveLocation.Get()); err != nil { + return err + } + if err := art.SetKey(path.Join(key, fileName)); err != nil { + return err } } - - artDriver, err := we.InitDriver(ctx, art) + driverArt, err := we.newDriverArt(art) if err != nil { return err } - err = artDriver.Save(localArtPath, art) + artDriver, err := we.InitDriver(ctx, driverArt) + if err != nil { + return err + } + err = artDriver.Save(localArtPath, driverArt) if err != nil { return err } @@ -469,8 +457,8 @@ func (we *WorkflowExecutor) isBaseImagePath(path string) bool { if path == inArt.Path { // The input artifact may have been optional and not supplied. If this is the case, the file won't exist on // the input artifact volume. Since this function was called, we know that we want to use this path as an - // ourput artifact, so we should look for it in the base image path. - if inArt.Optional && !inArt.HasLocation() { + // output artifact, so we should look for it in the base image path. + if inArt.Optional && !inArt.HasLocationOrKey() { return true } return false @@ -547,7 +535,7 @@ func (we *WorkflowExecutor) SaveParameters(ctx context.Context) error { // SaveLogs saves logs func (we *WorkflowExecutor) SaveLogs(ctx context.Context) (*wfv1.Artifact, error) { - if we.Template.ArchiveLocation == nil || we.Template.ArchiveLocation.ArchiveLogs == nil || !*we.Template.ArchiveLocation.ArchiveLogs { + if !we.Template.ArchiveLocation.IsArchiveLogs() { return nil, nil } log.Infof("Saving logs") @@ -566,48 +554,12 @@ func (we *WorkflowExecutor) SaveLogs(ctx context.Context) (*wfv1.Artifact, error if err != nil { return nil, err } - art := wfv1.Artifact{ - Name: "main-logs", - ArtifactLocation: *we.Template.ArchiveLocation, - } - if we.Template.ArchiveLocation.S3 != nil { - shallowCopy := *we.Template.ArchiveLocation.S3 - art.S3 = &shallowCopy - art.S3.Key = path.Join(art.S3.Key, fileName) - } else if we.Template.ArchiveLocation.Artifactory != nil { - shallowCopy := *we.Template.ArchiveLocation.Artifactory - art.Artifactory = &shallowCopy - artifactoryURL, urlParseErr := url.Parse(art.Artifactory.URL) - if urlParseErr != nil { - return nil, urlParseErr - } - artifactoryURL.Path = path.Join(artifactoryURL.Path, fileName) - art.Artifactory.URL = artifactoryURL.String() - } else if we.Template.ArchiveLocation.HDFS != nil { - shallowCopy := *we.Template.ArchiveLocation.HDFS - art.HDFS = &shallowCopy - art.HDFS.Path = path.Join(art.HDFS.Path, fileName) - } else if we.Template.ArchiveLocation.GCS != nil { - shallowCopy := *we.Template.ArchiveLocation.GCS - art.GCS = &shallowCopy - art.GCS.Key = path.Join(art.GCS.Key, fileName) - } else if we.Template.ArchiveLocation.OSS != nil { - shallowCopy := *we.Template.ArchiveLocation.OSS - art.OSS = &shallowCopy - art.OSS.Key = path.Join(art.OSS.Key, fileName) - } else { - return nil, errors.Errorf(errors.CodeBadRequest, "Unable to determine path to store %s. Archive location provided no information", art.Name) - } - artDriver, err := we.InitDriver(ctx, &art) - if err != nil { - return nil, err - } - err = artDriver.Save(mainLog, &art) + art := &wfv1.Artifact{Name: "main-logs"} + err = we.saveArtifactFromFile(ctx, art, fileName, mainLog) if err != nil { return nil, err } - - return &art, nil + return art, nil } // GetSecret will retrieve the Secrets from VolumeMount @@ -638,6 +590,12 @@ func (we *WorkflowExecutor) saveLogToFile(ctx context.Context, mainCtrID, path s return nil } +func (we *WorkflowExecutor) newDriverArt(art *wfv1.Artifact) (*wfv1.Artifact, error) { + driverArt := art.DeepCopy() + err := driverArt.Relocate(we.Template.ArchiveLocation) + return driverArt, err +} + // InitDriver initializes an instance of an artifact driver func (we *WorkflowExecutor) InitDriver(ctx context.Context, art *wfv1.Artifact) (artifact.ArtifactDriver, error) { driver, err := artifact.NewDriver(ctx, art, we)