diff --git a/Makefile b/Makefile index e8cb603826aa..d0bb8005b459 100644 --- a/Makefile +++ b/Makefile @@ -593,6 +593,7 @@ prepare-release: check-version-warning clean codegen manifests publish-release: check-version-warning clis checksums git push git push $(GIT_REMOTE) $(VERSION) + endif .PHONY: check-version-warning diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json index 6bede921ad7d..0b9146744ec0 100644 --- a/api/jsonschema/schema.json +++ b/api/jsonschema/schema.json @@ -2811,6 +2811,87 @@ }, "type": "object" }, + "io.argoproj.workflow.v1alpha1.ArtifactPaths": { + "description": "ArtifactPaths expands a step from a collection of artifacts", + "properties": { + "archive": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ArchiveStrategy", + "description": "Archive controls how the artifact will be saved to the artifact repository." + }, + "archiveLogs": { + "description": "ArchiveLogs indicates if the container logs should be archived", + "type": "boolean" + }, + "artifactory": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ArtifactoryArtifact", + "description": "Artifactory contains artifactory artifact location details" + }, + "from": { + "description": "From allows an artifact to reference an artifact from a previous step", + "type": "string" + }, + "gcs": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.GCSArtifact", + "description": "GCS contains GCS artifact location details" + }, + "git": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.GitArtifact", + "description": "Git contains git artifact location details" + }, + "globalName": { + "description": "GlobalName exports an output artifact to the global scope, making it available as '{{io.argoproj.workflow.v1alpha1.outputs.artifacts.XXXX}} and in workflow.status.outputs.artifacts", + "type": "string" + }, + "hdfs": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.HDFSArtifact", + "description": "HDFS contains HDFS artifact location details" + }, + "http": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.HTTPArtifact", + "description": "HTTP contains HTTP artifact location details" + }, + "mode": { + "description": "mode bits to use on this file, must be a value between 0 and 0777 set when loading input artifacts.", + "type": "integer" + }, + "name": { + "description": "name of the artifact. must be unique within a template's inputs/outputs.", + "type": "string" + }, + "optional": { + "description": "Make Artifacts optional, if Artifacts doesn't generate or exist", + "type": "boolean" + }, + "oss": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.OSSArtifact", + "description": "OSS contains OSS artifact location details" + }, + "path": { + "description": "Path is the container path to the artifact", + "type": "string" + }, + "raw": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact", + "description": "Raw contains raw artifact location details" + }, + "recurseMode": { + "description": "If mode is set, apply the permission recursively into the artifact if it is a folder", + "type": "boolean" + }, + "s3": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.S3Artifact", + "description": "S3 contains S3 artifact location details" + }, + "subPath": { + "description": "SubPath allows an artifact to be sourced from a subpath within the specified source", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, "io.argoproj.workflow.v1alpha1.ArtifactRepositoryRef": { "properties": { "configMap": { @@ -3298,6 +3379,37 @@ ], "type": "object" }, + "io.argoproj.workflow.v1alpha1.Data": { + "description": "Data is a data template", + "properties": { + "source": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.DataSource", + "description": "Source sources external data into a data template" + }, + "transformation": { + "description": "Transformation applies a set of transformations", + "items": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.TransformationStep" + }, + "type": "array" + } + }, + "required": [ + "source", + "transformation" + ], + "type": "object" + }, + "io.argoproj.workflow.v1alpha1.DataSource": { + "description": "DataSource sources external data into a data template", + "properties": { + "artifactPaths": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ArtifactPaths", + "description": "ArtifactPaths is a data transformation that collects a list of artifact paths" + } + }, + "type": "object" + }, "io.argoproj.workflow.v1alpha1.Event": { "properties": { "selector": { @@ -4198,9 +4310,6 @@ "type": "boolean" } }, - "required": [ - "key" - ], "type": "object" }, "io.argoproj.workflow.v1alpha1.ScriptTemplate": { @@ -4577,6 +4686,10 @@ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.DAGTemplate", "description": "DAG template subtype which runs a DAG" }, + "data": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Data", + "description": "Data is a data template" + }, "executor": { "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ExecutorConfig", "description": "Executor holds configurations of the executor container." @@ -4740,6 +4853,18 @@ }, "type": "object" }, + "io.argoproj.workflow.v1alpha1.TransformationStep": { + "properties": { + "expression": { + "description": "Expression defines an expr expression to apply", + "type": "string" + } + }, + "required": [ + "expression" + ], + "type": "object" + }, "io.argoproj.workflow.v1alpha1.UpdateCronWorkflowRequest": { "properties": { "cronWorkflow": { diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 21ad68571c4d..6626cf20acc0 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -6229,6 +6229,87 @@ } } }, + "io.argoproj.workflow.v1alpha1.ArtifactPaths": { + "description": "ArtifactPaths expands a step from a collection of artifacts", + "type": "object", + "required": [ + "name" + ], + "properties": { + "archive": { + "description": "Archive controls how the artifact will be saved to the artifact repository.", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ArchiveStrategy" + }, + "archiveLogs": { + "description": "ArchiveLogs indicates if the container logs should be archived", + "type": "boolean" + }, + "artifactory": { + "description": "Artifactory contains artifactory artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ArtifactoryArtifact" + }, + "from": { + "description": "From allows an artifact to reference an artifact from a previous step", + "type": "string" + }, + "gcs": { + "description": "GCS contains GCS artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.GCSArtifact" + }, + "git": { + "description": "Git contains git artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.GitArtifact" + }, + "globalName": { + "description": "GlobalName exports an output artifact to the global scope, making it available as '{{io.argoproj.workflow.v1alpha1.outputs.artifacts.XXXX}} and in workflow.status.outputs.artifacts", + "type": "string" + }, + "hdfs": { + "description": "HDFS contains HDFS artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.HDFSArtifact" + }, + "http": { + "description": "HTTP contains HTTP artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.HTTPArtifact" + }, + "mode": { + "description": "mode bits to use on this file, must be a value between 0 and 0777 set when loading input artifacts.", + "type": "integer" + }, + "name": { + "description": "name of the artifact. must be unique within a template's inputs/outputs.", + "type": "string" + }, + "optional": { + "description": "Make Artifacts optional, if Artifacts doesn't generate or exist", + "type": "boolean" + }, + "oss": { + "description": "OSS contains OSS artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.OSSArtifact" + }, + "path": { + "description": "Path is the container path to the artifact", + "type": "string" + }, + "raw": { + "description": "Raw contains raw artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact" + }, + "recurseMode": { + "description": "If mode is set, apply the permission recursively into the artifact if it is a folder", + "type": "boolean" + }, + "s3": { + "description": "S3 contains S3 artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.S3Artifact" + }, + "subPath": { + "description": "SubPath allows an artifact to be sourced from a subpath within the specified source", + "type": "string" + } + } + }, "io.argoproj.workflow.v1alpha1.ArtifactRepositoryRef": { "type": "object", "properties": { @@ -6712,6 +6793,37 @@ } } }, + "io.argoproj.workflow.v1alpha1.Data": { + "description": "Data is a data template", + "type": "object", + "required": [ + "source", + "transformation" + ], + "properties": { + "source": { + "description": "Source sources external data into a data template", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.DataSource" + }, + "transformation": { + "description": "Transformation applies a set of transformations", + "type": "array", + "items": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.TransformationStep" + } + } + } + }, + "io.argoproj.workflow.v1alpha1.DataSource": { + "description": "DataSource sources external data into a data template", + "type": "object", + "properties": { + "artifactPaths": { + "description": "ArtifactPaths is a data transformation that collects a list of artifact paths", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ArtifactPaths" + } + } + }, "io.argoproj.workflow.v1alpha1.Event": { "type": "object", "required": [ @@ -7571,9 +7683,6 @@ "io.argoproj.workflow.v1alpha1.S3Artifact": { "description": "S3Artifact is the location of an S3 artifact", "type": "object", - "required": [ - "key" - ], "properties": { "accessKeySecret": { "description": "AccessKeySecret is the secret selector to the bucket's access key", @@ -7995,6 +8104,10 @@ "description": "DAG template subtype which runs a DAG", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.DAGTemplate" }, + "data": { + "description": "Data is a data template", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Data" + }, "executor": { "description": "Executor holds configurations of the executor container.", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.ExecutorConfig" @@ -8154,6 +8267,18 @@ } } }, + "io.argoproj.workflow.v1alpha1.TransformationStep": { + "type": "object", + "required": [ + "expression" + ], + "properties": { + "expression": { + "description": "Expression defines an expr expression to apply", + "type": "string" + } + } + }, "io.argoproj.workflow.v1alpha1.UpdateCronWorkflowRequest": { "type": "object", "properties": { diff --git a/cmd/argoexec/commands/data.go b/cmd/argoexec/commands/data.go new file mode 100644 index 000000000000..c25daf08645d --- /dev/null +++ b/cmd/argoexec/commands/data.go @@ -0,0 +1,20 @@ +package commands + +import ( + "context" + + "github.com/spf13/cobra" +) + +func NewDataCommand() *cobra.Command { + command := cobra.Command{ + Use: "data", + Short: "Process data", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + wfExecutor := initExecutor() + return wfExecutor.Data(ctx) + }, + } + return &command +} diff --git a/cmd/argoexec/commands/root.go b/cmd/argoexec/commands/root.go index 1214b2c01718..7bbe8569a9f3 100644 --- a/cmd/argoexec/commands/root.go +++ b/cmd/argoexec/commands/root.go @@ -64,6 +64,7 @@ func NewRootCommand() *cobra.Command { command.AddCommand(NewInitCommand()) command.AddCommand(NewResourceCommand()) command.AddCommand(NewWaitCommand()) + command.AddCommand(NewDataCommand()) command.AddCommand(cmd.NewVersionCmd(CLIName)) clientConfig = kubecli.AddKubectlFlagsToCmd(&command) diff --git a/config/config.go b/config/config.go index ee9f2d1e7bd6..8a8a8647688a 100644 --- a/config/config.go +++ b/config/config.go @@ -365,7 +365,7 @@ type MetricsConfig struct { } type WorkflowRestrictions struct { - TemplateReferencing TemplateReferencing `json:"templateReferencing"` + TemplateReferencing TemplateReferencing `json:"templateReferencing,omitempty"` } type TemplateReferencing string diff --git a/docs/data-sourcing-and-transformation.md b/docs/data-sourcing-and-transformation.md new file mode 100644 index 000000000000..a86463a04c3e --- /dev/null +++ b/docs/data-sourcing-and-transformation.md @@ -0,0 +1,60 @@ +# Data Sourcing and Transformations + +![alpha](assets/alpha.svg) + +> v3.1 and after + +#### Development + +We have intentionally made this feature available with only bare-bones functionality. Our hope is that we are able to build this feature with our community's feedback. If you have ideas and use cases for this feature, please open an [enhancement proposal](https://github.com/argoproj/argo-workflows/issues/new?assignees=&labels=enhancement&template=enhancement_proposal.md) on GitHub. + +Additionally, please take a look at our current ideas at the bottom of this document. + +## Introduction +Users often source and transform data as part of their workflows. The `data` template provides first-class support for these common operations. + +`data` templates can best be understood by looking at a common data sourcing and transformation operation in `bash`: + +```bash +$ find -r . | grep ".pdf" | sed "s/foo/foo.ready/" +``` + +Such operations consist of two main parts: +* A "source" of data: `find -r .` +* A series of "transformations" which transform the output of the source serially: `| grep ".pdf" | sed "s/foo/foo.ready/"` + +This operation, for example, could be useful in sourcing a potential list of files to be processed and filtering and manipulating the list as desired. + +In Argo, this operation would be written as: + +```yaml +- name: generate-artifacts + data: + source: # Define a source for the data, only a single "source" is permitted + artifactPaths: # A predefined source: Generate a list of all artifact paths in a given repository + s3: # Source from an S3 bucket + bucket: test + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + transformation: # The source is then passed to be transformed by transformations defined here + - expression: "filter(data, {# endsWith \".pdf\"})" + - expression: "map(data, {# + \".ready\"})" +``` + +## Spec + +A `data` template must always contain a `source`. Current available sources: + +* `artifactPaths`: generates a list of artifact paths from the artifact repository specified + +A `data` template may contain any number of transformations (or zero). The transformations will be applied serially in order. Current available transformations: + +* `expression`: an [`expr`](https://github.com/antonmedv/expr) expression. See language definition [here](https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md). When defining `expr` expressions Argo will pass the available data to the environment as a variable called `data` (see example above). + + We understand that the `expression` transformation is limited. We intend to greatly expand the functionality of this template with our community's feedback. Please see the link at the top of this document to submit ideas or use cases for this feature. diff --git a/docs/fields.md b/docs/fields.md index 03316a1ae3b3..db1f7916ef8f 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -80,6 +80,8 @@ Workflow is the definition of a workflow resource - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -427,6 +429,8 @@ WorkflowSpec is the specification of a Workflow. - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -792,6 +796,8 @@ CronWorkflowSpec is the specification of a CronWorkflow - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -1115,6 +1121,8 @@ WorkflowTemplateSpec is a spec of WorkflowTemplate. - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -1428,6 +1436,8 @@ Arguments to a template - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`exit-code-output-variable.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-code-output-variable.yaml) - [`exit-handler-dag-level.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-handler-dag-level.yaml) @@ -1764,6 +1774,8 @@ Template is a reusable and composable unit of execution in a workflow - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -1979,6 +1991,7 @@ Template is a reusable and composable unit of execution in a workflow |`container`|[`Container`](#container)|Container is the main container image to run in the pod| |`daemon`|`boolean`|Deamon will allow a workflow to proceed to the next step so long as the container reaches readiness| |`dag`|[`DAGTemplate`](#dagtemplate)|DAG template subtype which runs a DAG| +|`data`|[`Data`](#data)|Data is a data template| |`executor`|[`ExecutorConfig`](#executorconfig)|Executor holds configurations of the executor container.| |`hostAliases`|`Array<`[`HostAlias`](#hostalias)`>`|HostAliases is an optional list of hosts and IPs that will be injected into the pod spec| |`initContainers`|`Array<`[`UserContainer`](#usercontainer)`>`|InitContainers is a list of containers which run before the main container.| @@ -2149,6 +2162,8 @@ Outputs hold parameters, artifacts, and results from a step - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`fun-with-gifs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/fun-with-gifs.yaml) - [`global-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/global-outputs.yaml) @@ -2249,6 +2264,8 @@ Artifact indicates an artifact to place at a specified path - [`ci.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/ci.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`fun-with-gifs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/fun-with-gifs.yaml) - [`global-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/global-outputs.yaml) @@ -2356,6 +2373,8 @@ Parameter indicate a passed string parameter to a service template with an optio - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`exit-code-output-variable.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-code-output-variable.yaml) - [`exit-handler-dag-level.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-handler-dag-level.yaml) @@ -2650,6 +2669,37 @@ DAGTemplate is a template subtype for directed acyclic graph templates |`target`|`string`|Target are one or more names of targets to execute in a DAG| |`tasks`|`Array<`[`DAGTask`](#dagtask)`>`|Tasks are a list of DAG tasks| +## Data + +Data is a data template + +
+Examples with this field (click to open) +
+ +- [`artifact-path-placeholders.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/artifact-path-placeholders.yaml) + +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + +- [`input-artifact-raw.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/input-artifact-raw.yaml) + +- [`k8s-set-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-set-owner-reference.yaml) + +- [`memoize-simple.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/memoize-simple.yaml) + +- [`resource-delete-with-flags.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/resource-delete-with-flags.yaml) + +- [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/synchronization-tmpl-level.yaml) + +- [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/synchronization-wf-level.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`source`|[`DataSource`](#datasource)|Source sources external data into a data template| +|`transformation`|`Array<`[`TransformationStep`](#transformationstep)`>`|Transformation applies a set of transformations| + ## UserContainer UserContainer is a container specified by a user. @@ -2740,6 +2790,8 @@ Inputs are the mechanism for passing parameters, artifacts, volumes from one tem - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`exit-code-output-variable.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-code-output-variable.yaml) - [`exit-handler-dag-level.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-handler-dag-level.yaml) @@ -3019,6 +3071,8 @@ WorkflowStep is a reference to a template to execute in a series of step - [`dag-diamond-steps.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-diamond-steps.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`exit-code-output-variable.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-code-output-variable.yaml) - [`exit-handler-step-level.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/exit-handler-step-level.yaml) @@ -3474,6 +3528,8 @@ ValueFrom describes a location in which to obtain the value to a parameter - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`global-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/global-outputs.yaml) - [`handle-large-output-results.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/handle-large-output-results.yaml) @@ -3680,6 +3736,70 @@ DAGTask represents a node in the graph during DAG execution |`withParam`|`string`|WithParam expands a task into multiple parallel tasks from the value in the parameter, which is expected to be a JSON list.| |`withSequence`|[`Sequence`](#sequence)|WithSequence expands a task into a numeric sequence| +## DataSource + +DataSource sources external data into a data template + +
+Examples with this field (click to open) +
+ +- [`coinflip-recursive.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/coinflip-recursive.yaml) + +- [`coinflip.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/coinflip.yaml) + +- [`colored-logs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/colored-logs.yaml) + +- [`cron-backfill.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/cron-backfill.yaml) + +- [`dag-coinflip.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-coinflip.yaml) + +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + +- [`loops-param-result.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/loops-param-result.yaml) + +- [`map-reduce.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/map-reduce.yaml) + +- [`parameter-aggregation-script.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/parameter-aggregation-script.yaml) + +- [`parameter-aggregation.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/parameter-aggregation.yaml) + +- [`pod-spec-from-previous-step.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/pod-spec-from-previous-step.yaml) + +- [`recursive-for-loop.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/recursive-for-loop.yaml) + +- [`retry-script.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/retry-script.yaml) + +- [`scripts-bash.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/scripts-bash.yaml) + +- [`scripts-javascript.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/scripts-javascript.yaml) + +- [`scripts-python.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/scripts-python.yaml) + +- [`work-avoidance.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/work-avoidance.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`artifactPaths`|[`ArtifactPaths`](#artifactpaths)|ArtifactPaths is a data transformation that collects a list of artifact paths| + +## TransformationStep + +_No description available_ + +
+Examples with this field (click to open) +
+ +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`expression`|`string`|Expression defines an expr expression to apply| + ## Cache Cache is the configuration for the type of cache to be used @@ -3879,6 +3999,39 @@ Amount represent a numeric amount. - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) +## ArtifactPaths + +ArtifactPaths expands a step from a collection of artifacts + +
+Examples with this field (click to open) +
+ +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`archive`|[`ArchiveStrategy`](#archivestrategy)|Archive controls how the artifact will be saved to the artifact repository.| +|`archiveLogs`|`boolean`|ArchiveLogs indicates if the container logs should be archived| +|`artifactory`|[`ArtifactoryArtifact`](#artifactoryartifact)|Artifactory contains artifactory artifact location details| +|`from`|`string`|From allows an artifact to reference an artifact from a previous step| +|`gcs`|[`GCSArtifact`](#gcsartifact)|GCS contains GCS artifact location details| +|`git`|[`GitArtifact`](#gitartifact)|Git contains git artifact location details| +|`globalName`|`string`|GlobalName exports an output artifact to the global scope, making it available as '{{io.argoproj.workflow.v1alpha1.outputs.artifacts.XXXX}} and in workflow.status.outputs.artifacts| +|`hdfs`|[`HDFSArtifact`](#hdfsartifact)|HDFS contains HDFS artifact location details| +|`http`|[`HTTPArtifact`](#httpartifact)|HTTP contains HTTP artifact location details| +|`mode`|`integer`|mode bits to use on this file, must be a value between 0 and 0777 set when loading input artifacts.| +|`name`|`string`|name of the artifact. must be unique within a template's inputs/outputs.| +|`optional`|`boolean`|Make Artifacts optional, if Artifacts doesn't generate or exist| +|`oss`|[`OSSArtifact`](#ossartifact)|OSS contains OSS artifact location details| +|`path`|`string`|Path is the container path to the artifact| +|`raw`|[`RawArtifact`](#rawartifact)|Raw contains raw artifact location details| +|`recurseMode`|`boolean`|If mode is set, apply the permission recursively into the artifact if it is a folder| +|`s3`|[`S3Artifact`](#s3artifact)|S3 contains S3 artifact location details| +|`subPath`|`string`|SubPath allows an artifact to be sourced from a subpath within the specified source| + # External Fields @@ -3968,6 +4121,8 @@ ObjectMeta is metadata that all persisted resources must have, which includes al - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -4527,6 +4682,8 @@ A single application container that you want to run within a pod. - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -5154,6 +5311,8 @@ PersistentVolumeClaimSpec describes the common attributes of storage devices and - [`dag-task-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dag-task-level-timeout.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`default-pdb-support.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/default-pdb-support.yaml) - [`dns-config.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/dns-config.yaml) @@ -5789,6 +5948,8 @@ EnvVarSource represents a source for the value of an EnvVar. - [`custom-metrics.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/custom-metrics.yaml) +- [`data-transformations.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/data-transformations.yaml) + - [`global-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/global-outputs.yaml) - [`handle-large-output-results.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/handle-large-output-results.yaml) diff --git a/examples/data-transformations.yaml b/examples/data-transformations.yaml new file mode 100644 index 000000000000..b26fc617deb8 --- /dev/null +++ b/examples/data-transformations.yaml @@ -0,0 +1,70 @@ +# See doc docs/data-sourcing-and-transformation.md +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: data-transformations- +spec: + entrypoint: data-transformations + templates: + - name: data-transformations + steps: + - - name: generate-artifact + template: generate-artifacts + - - name: process-artifact + template: process-message + withParam: "{{steps.generate-artifact.outputs.result}}" + arguments: + artifacts: + - name: file + s3: + bucket: test + key: "{{item}}" + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + + parameters: + - name: file-name + value: "{{item}}" + + - name: generate-artifacts + data: + source: + artifactPaths: + name: test-bucket + s3: + bucket: test + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + + transformation: + - expression: "filter(data, {# endsWith \".py\"})" + + - name: process-message + inputs: + parameters: + - name: file-name + artifacts: + - name: file + path: /file + container: + image: alpine:latest + command: [sh, -c] + args: ["cat /file && echo \"{{inputs.parameters.file-name}}.processed\" | tee /tmp/f.txt"] + outputs: + parameters: + - name: processed + valueFrom: + path: /tmp/f.txt + diff --git a/go.mod b/go.mod index 0db5363ac5f1..645944fb40b5 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v2.1.5+incompatible github.com/antonmedv/expr v1.8.8 github.com/argoproj/argo-events v1.2.0 - github.com/argoproj/pkg v0.5.0 + github.com/argoproj/pkg v0.6.0 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/blushft/go-diagrams v0.0.0-20201006005127-c78c821223d9 github.com/colinmarc/hdfs v1.1.4-0.20180805212432-9746310a4d31 diff --git a/go.sum b/go.sum index 630426901132..1a070c190ea7 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,8 @@ github.com/ardielle/ardielle-go v1.5.2/go.mod h1:I4hy1n795cUhaVt/ojz83SNVCYIGsAF github.com/ardielle/ardielle-tools v1.5.4/go.mod h1:oZN+JRMnqGiIhrzkRN9l26Cej9dEx4jeNG6A+AdkShk= github.com/argoproj/argo-events v1.2.0 h1:CjF8hVUkeflhaOt9uWjJK6ai6b4pw0CCUUmOnmhWnNY= github.com/argoproj/argo-events v1.2.0/go.mod h1:eY+egQNBLXAz/AF4mqgHsMMa4Aur7frHjUfBg+RpX04= -github.com/argoproj/pkg v0.5.0 h1:w4WgsUAX7QydPTD+Fdae2CHsZymrmAJPXFegIIuzRXQ= -github.com/argoproj/pkg v0.5.0/go.mod h1:DmT4fN1ihGS0VBa0kHwpL+hoRAi8WdMFsUDa1QTZd+M= +github.com/argoproj/pkg v0.6.0 h1:q6413Dtl8keWXjScb99GD5tzTuZugXQeTnd/+mRj3yI= +github.com/argoproj/pkg v0.6.0/go.mod h1:DmT4fN1ihGS0VBa0kHwpL+hoRAi8WdMFsUDa1QTZd+M= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= diff --git a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml index 9961cfc41979..ac6555406386 100644 --- a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml @@ -585,8 +585,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -1494,8 +1492,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object type: object automountServiceAccountToken: @@ -2348,8 +2344,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -2457,6 +2451,320 @@ spec: required: - tasks type: object + data: + properties: + source: + properties: + artifactPaths: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + transformation: + items: + properties: + expression: + type: string + required: + - expression + type: object + type: array + required: + - source + - transformation + type: object executor: properties: serviceAccountName: @@ -3314,8 +3622,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -3757,8 +4063,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key 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 2ae4acac4b32..cfd1c762b83f 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -606,8 +606,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -1515,8 +1513,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object type: object automountServiceAccountToken: @@ -2369,8 +2365,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -2478,6 +2472,320 @@ spec: required: - tasks type: object + data: + properties: + source: + properties: + artifactPaths: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + transformation: + items: + properties: + expression: + type: string + required: + - expression + type: object + type: array + required: + - source + - transformation + type: object executor: properties: serviceAccountName: @@ -3335,8 +3643,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -3778,8 +4084,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key 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 aa9bdbe89c43..22dac298c6a7 100644 --- a/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml +++ b/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml @@ -328,8 +328,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key 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 724f1728648b..c52202c97f44 100644 --- a/manifests/base/crds/full/argoproj.io_workflows.yaml +++ b/manifests/base/crds/full/argoproj.io_workflows.yaml @@ -594,8 +594,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -1503,8 +1501,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object type: object automountServiceAccountToken: @@ -2357,8 +2353,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -2466,6 +2460,320 @@ spec: required: - tasks type: object + data: + properties: + source: + properties: + artifactPaths: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + transformation: + items: + properties: + expression: + type: string + required: + - expression + type: object + type: array + required: + - source + - transformation + type: object executor: properties: serviceAccountName: @@ -3323,8 +3631,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -3766,8 +4072,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -6938,8 +7242,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -7298,8 +7600,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -7683,8 +7983,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -8949,8 +9247,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object type: object automountServiceAccountToken: @@ -9803,8 +10099,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -9912,6 +10206,320 @@ spec: required: - tasks type: object + data: + properties: + source: + properties: + artifactPaths: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + transformation: + items: + properties: + expression: + type: string + required: + - expression + type: object + type: array + required: + - source + - transformation + type: object executor: properties: serviceAccountName: @@ -10769,8 +11377,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -11212,8 +11818,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -13766,8 +14370,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -14675,8 +15277,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object type: object automountServiceAccountToken: @@ -15529,8 +16129,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -15638,6 +16236,320 @@ spec: required: - tasks type: object + data: + properties: + source: + properties: + artifactPaths: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + transformation: + items: + properties: + expression: + type: string + required: + - expression + type: object + type: array + required: + - source + - transformation + type: object executor: properties: serviceAccountName: @@ -16495,8 +17407,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -16938,8 +17848,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key 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 0fdf56ff4750..6d4d0d585de1 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml @@ -584,8 +584,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -1493,8 +1491,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object type: object automountServiceAccountToken: @@ -2347,8 +2343,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -2456,6 +2450,320 @@ spec: required: - tasks type: object + data: + properties: + source: + properties: + artifactPaths: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + from: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + depth: + format: int64 + type: integer + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + transformation: + items: + properties: + expression: + type: string + required: + - expression + type: object + type: array + required: + - source + - transformation + type: object executor: properties: serviceAccountName: @@ -3313,8 +3621,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string @@ -3756,8 +4062,6 @@ spec: type: object useSDKCreds: type: boolean - required: - - key type: object subPath: type: string diff --git a/pkg/apis/workflow/v1alpha1/data_types.go b/pkg/apis/workflow/v1alpha1/data_types.go new file mode 100644 index 000000000000..135cae559b42 --- /dev/null +++ b/pkg/apis/workflow/v1alpha1/data_types.go @@ -0,0 +1,40 @@ +package v1alpha1 + +// Data is a data template +type Data struct { + // Source sources external data into a data template + Source DataSource `json:"source" protobuf:"bytes,1,opt,name=source"` + + // Transformation applies a set of transformations + Transformation Transformation `json:"transformation" protobuf:"bytes,2,rep,name=transformation"` +} + +func (ds *DataSource) GetArtifactIfNeeded() (*Artifact, bool) { + if ds.ArtifactPaths != nil { + return &ds.ArtifactPaths.Artifact, true + } + return nil, false +} + +type Transformation []TransformationStep + +type TransformationStep struct { + // Expression defines an expr expression to apply + Expression string `json:"expression" protobuf:"bytes,1,opt,name=expression"` +} + +// DataSource sources external data into a data template +type DataSource struct { + // ArtifactPaths is a data transformation that collects a list of artifact paths + ArtifactPaths *ArtifactPaths `json:"artifactPaths,omitempty" protobuf:"bytes,1,opt,name=artifactPaths"` +} + +// ArtifactPaths expands a step from a collection of artifacts +type ArtifactPaths struct { + // Artifact is the artifact location from which to source the artifacts, it can be a directory + Artifact `json:",inline" protobuf:"bytes,1,opt,name=artifact"` +} + +type DataSourceProcessor interface { + ProcessArtifactPaths(*ArtifactPaths) (interface{}, error) +} diff --git a/pkg/apis/workflow/v1alpha1/data_types_test.go b/pkg/apis/workflow/v1alpha1/data_types_test.go new file mode 100644 index 000000000000..6f59edca6131 --- /dev/null +++ b/pkg/apis/workflow/v1alpha1/data_types_test.go @@ -0,0 +1,15 @@ +package v1alpha1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetArtifactIfNeeded(t *testing.T) { + data := &DataSource{ArtifactPaths: &ArtifactPaths{Artifact{Name: "foo"}}} + art, needed := data.GetArtifactIfNeeded() + if assert.True(t, needed) { + assert.Equal(t, "foo", art.Name) + } +} diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index eab989de0fd1..a43ccfdc01e5 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -176,10 +176,38 @@ func (m *ArtifactLocation) XXX_DiscardUnknown() { var xxx_messageInfo_ArtifactLocation proto.InternalMessageInfo +func (m *ArtifactPaths) Reset() { *m = ArtifactPaths{} } +func (*ArtifactPaths) ProtoMessage() {} +func (*ArtifactPaths) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{5} +} +func (m *ArtifactPaths) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ArtifactPaths) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ArtifactPaths) XXX_Merge(src proto.Message) { + xxx_messageInfo_ArtifactPaths.Merge(m, src) +} +func (m *ArtifactPaths) XXX_Size() int { + return m.Size() +} +func (m *ArtifactPaths) XXX_DiscardUnknown() { + xxx_messageInfo_ArtifactPaths.DiscardUnknown(m) +} + +var xxx_messageInfo_ArtifactPaths proto.InternalMessageInfo + func (m *ArtifactRepositoryRef) Reset() { *m = ArtifactRepositoryRef{} } func (*ArtifactRepositoryRef) ProtoMessage() {} func (*ArtifactRepositoryRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{5} + return fileDescriptor_724696e352c3df5f, []int{6} } func (m *ArtifactRepositoryRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -207,7 +235,7 @@ var xxx_messageInfo_ArtifactRepositoryRef proto.InternalMessageInfo func (m *ArtifactRepositoryRefStatus) Reset() { *m = ArtifactRepositoryRefStatus{} } func (*ArtifactRepositoryRefStatus) ProtoMessage() {} func (*ArtifactRepositoryRefStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{6} + return fileDescriptor_724696e352c3df5f, []int{7} } func (m *ArtifactRepositoryRefStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -235,7 +263,7 @@ var xxx_messageInfo_ArtifactRepositoryRefStatus proto.InternalMessageInfo func (m *ArtifactoryArtifact) Reset() { *m = ArtifactoryArtifact{} } func (*ArtifactoryArtifact) ProtoMessage() {} func (*ArtifactoryArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{7} + return fileDescriptor_724696e352c3df5f, []int{8} } func (m *ArtifactoryArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -263,7 +291,7 @@ var xxx_messageInfo_ArtifactoryArtifact proto.InternalMessageInfo func (m *ArtifactoryAuth) Reset() { *m = ArtifactoryAuth{} } func (*ArtifactoryAuth) ProtoMessage() {} func (*ArtifactoryAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{8} + return fileDescriptor_724696e352c3df5f, []int{9} } func (m *ArtifactoryAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -291,7 +319,7 @@ var xxx_messageInfo_ArtifactoryAuth proto.InternalMessageInfo func (m *Backoff) Reset() { *m = Backoff{} } func (*Backoff) ProtoMessage() {} func (*Backoff) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{9} + return fileDescriptor_724696e352c3df5f, []int{10} } func (m *Backoff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -319,7 +347,7 @@ var xxx_messageInfo_Backoff proto.InternalMessageInfo func (m *Cache) Reset() { *m = Cache{} } func (*Cache) ProtoMessage() {} func (*Cache) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{10} + return fileDescriptor_724696e352c3df5f, []int{11} } func (m *Cache) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -347,7 +375,7 @@ var xxx_messageInfo_Cache proto.InternalMessageInfo func (m *ClusterWorkflowTemplate) Reset() { *m = ClusterWorkflowTemplate{} } func (*ClusterWorkflowTemplate) ProtoMessage() {} func (*ClusterWorkflowTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{11} + return fileDescriptor_724696e352c3df5f, []int{12} } func (m *ClusterWorkflowTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -375,7 +403,7 @@ var xxx_messageInfo_ClusterWorkflowTemplate proto.InternalMessageInfo func (m *ClusterWorkflowTemplateList) Reset() { *m = ClusterWorkflowTemplateList{} } func (*ClusterWorkflowTemplateList) ProtoMessage() {} func (*ClusterWorkflowTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{12} + return fileDescriptor_724696e352c3df5f, []int{13} } func (m *ClusterWorkflowTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -403,7 +431,7 @@ var xxx_messageInfo_ClusterWorkflowTemplateList proto.InternalMessageInfo func (m *Condition) Reset() { *m = Condition{} } func (*Condition) ProtoMessage() {} func (*Condition) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{13} + return fileDescriptor_724696e352c3df5f, []int{14} } func (m *Condition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -431,7 +459,7 @@ var xxx_messageInfo_Condition proto.InternalMessageInfo func (m *ContinueOn) Reset() { *m = ContinueOn{} } func (*ContinueOn) ProtoMessage() {} func (*ContinueOn) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{14} + return fileDescriptor_724696e352c3df5f, []int{15} } func (m *ContinueOn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -459,7 +487,7 @@ var xxx_messageInfo_ContinueOn proto.InternalMessageInfo func (m *Counter) Reset() { *m = Counter{} } func (*Counter) ProtoMessage() {} func (*Counter) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{15} + return fileDescriptor_724696e352c3df5f, []int{16} } func (m *Counter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -487,7 +515,7 @@ var xxx_messageInfo_Counter proto.InternalMessageInfo func (m *CreateS3BucketOptions) Reset() { *m = CreateS3BucketOptions{} } func (*CreateS3BucketOptions) ProtoMessage() {} func (*CreateS3BucketOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{16} + return fileDescriptor_724696e352c3df5f, []int{17} } func (m *CreateS3BucketOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -515,7 +543,7 @@ var xxx_messageInfo_CreateS3BucketOptions proto.InternalMessageInfo func (m *CronWorkflow) Reset() { *m = CronWorkflow{} } func (*CronWorkflow) ProtoMessage() {} func (*CronWorkflow) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{17} + return fileDescriptor_724696e352c3df5f, []int{18} } func (m *CronWorkflow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -543,7 +571,7 @@ var xxx_messageInfo_CronWorkflow proto.InternalMessageInfo func (m *CronWorkflowList) Reset() { *m = CronWorkflowList{} } func (*CronWorkflowList) ProtoMessage() {} func (*CronWorkflowList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{18} + return fileDescriptor_724696e352c3df5f, []int{19} } func (m *CronWorkflowList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -571,7 +599,7 @@ var xxx_messageInfo_CronWorkflowList proto.InternalMessageInfo func (m *CronWorkflowSpec) Reset() { *m = CronWorkflowSpec{} } func (*CronWorkflowSpec) ProtoMessage() {} func (*CronWorkflowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{19} + return fileDescriptor_724696e352c3df5f, []int{20} } func (m *CronWorkflowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -599,7 +627,7 @@ var xxx_messageInfo_CronWorkflowSpec proto.InternalMessageInfo func (m *CronWorkflowStatus) Reset() { *m = CronWorkflowStatus{} } func (*CronWorkflowStatus) ProtoMessage() {} func (*CronWorkflowStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{20} + return fileDescriptor_724696e352c3df5f, []int{21} } func (m *CronWorkflowStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -627,7 +655,7 @@ var xxx_messageInfo_CronWorkflowStatus proto.InternalMessageInfo func (m *DAGTask) Reset() { *m = DAGTask{} } func (*DAGTask) ProtoMessage() {} func (*DAGTask) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{21} + return fileDescriptor_724696e352c3df5f, []int{22} } func (m *DAGTask) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -655,7 +683,7 @@ var xxx_messageInfo_DAGTask proto.InternalMessageInfo func (m *DAGTemplate) Reset() { *m = DAGTemplate{} } func (*DAGTemplate) ProtoMessage() {} func (*DAGTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{22} + return fileDescriptor_724696e352c3df5f, []int{23} } func (m *DAGTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -680,10 +708,66 @@ func (m *DAGTemplate) XXX_DiscardUnknown() { var xxx_messageInfo_DAGTemplate proto.InternalMessageInfo +func (m *Data) Reset() { *m = Data{} } +func (*Data) ProtoMessage() {} +func (*Data) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{24} +} +func (m *Data) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Data) XXX_Merge(src proto.Message) { + xxx_messageInfo_Data.Merge(m, src) +} +func (m *Data) XXX_Size() int { + return m.Size() +} +func (m *Data) XXX_DiscardUnknown() { + xxx_messageInfo_Data.DiscardUnknown(m) +} + +var xxx_messageInfo_Data proto.InternalMessageInfo + +func (m *DataSource) Reset() { *m = DataSource{} } +func (*DataSource) ProtoMessage() {} +func (*DataSource) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{25} +} +func (m *DataSource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DataSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DataSource) XXX_Merge(src proto.Message) { + xxx_messageInfo_DataSource.Merge(m, src) +} +func (m *DataSource) XXX_Size() int { + return m.Size() +} +func (m *DataSource) XXX_DiscardUnknown() { + xxx_messageInfo_DataSource.DiscardUnknown(m) +} + +var xxx_messageInfo_DataSource proto.InternalMessageInfo + func (m *Event) Reset() { *m = Event{} } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{23} + return fileDescriptor_724696e352c3df5f, []int{26} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -711,7 +795,7 @@ var xxx_messageInfo_Event proto.InternalMessageInfo func (m *ExecutorConfig) Reset() { *m = ExecutorConfig{} } func (*ExecutorConfig) ProtoMessage() {} func (*ExecutorConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{24} + return fileDescriptor_724696e352c3df5f, []int{27} } func (m *ExecutorConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -739,7 +823,7 @@ var xxx_messageInfo_ExecutorConfig proto.InternalMessageInfo func (m *GCSArtifact) Reset() { *m = GCSArtifact{} } func (*GCSArtifact) ProtoMessage() {} func (*GCSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{25} + return fileDescriptor_724696e352c3df5f, []int{28} } func (m *GCSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -767,7 +851,7 @@ var xxx_messageInfo_GCSArtifact proto.InternalMessageInfo func (m *GCSBucket) Reset() { *m = GCSBucket{} } func (*GCSBucket) ProtoMessage() {} func (*GCSBucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{26} + return fileDescriptor_724696e352c3df5f, []int{29} } func (m *GCSBucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -795,7 +879,7 @@ var xxx_messageInfo_GCSBucket proto.InternalMessageInfo func (m *Gauge) Reset() { *m = Gauge{} } func (*Gauge) ProtoMessage() {} func (*Gauge) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{27} + return fileDescriptor_724696e352c3df5f, []int{30} } func (m *Gauge) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -823,7 +907,7 @@ var xxx_messageInfo_Gauge proto.InternalMessageInfo func (m *GitArtifact) Reset() { *m = GitArtifact{} } func (*GitArtifact) ProtoMessage() {} func (*GitArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{28} + return fileDescriptor_724696e352c3df5f, []int{31} } func (m *GitArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -851,7 +935,7 @@ var xxx_messageInfo_GitArtifact proto.InternalMessageInfo func (m *HDFSArtifact) Reset() { *m = HDFSArtifact{} } func (*HDFSArtifact) ProtoMessage() {} func (*HDFSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{29} + return fileDescriptor_724696e352c3df5f, []int{32} } func (m *HDFSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -879,7 +963,7 @@ var xxx_messageInfo_HDFSArtifact proto.InternalMessageInfo func (m *HDFSConfig) Reset() { *m = HDFSConfig{} } func (*HDFSConfig) ProtoMessage() {} func (*HDFSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{30} + return fileDescriptor_724696e352c3df5f, []int{33} } func (m *HDFSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -907,7 +991,7 @@ var xxx_messageInfo_HDFSConfig proto.InternalMessageInfo func (m *HDFSKrbConfig) Reset() { *m = HDFSKrbConfig{} } func (*HDFSKrbConfig) ProtoMessage() {} func (*HDFSKrbConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{31} + return fileDescriptor_724696e352c3df5f, []int{34} } func (m *HDFSKrbConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -935,7 +1019,7 @@ var xxx_messageInfo_HDFSKrbConfig proto.InternalMessageInfo func (m *HTTPArtifact) Reset() { *m = HTTPArtifact{} } func (*HTTPArtifact) ProtoMessage() {} func (*HTTPArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{32} + return fileDescriptor_724696e352c3df5f, []int{35} } func (m *HTTPArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -963,7 +1047,7 @@ var xxx_messageInfo_HTTPArtifact proto.InternalMessageInfo func (m *Header) Reset() { *m = Header{} } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{33} + return fileDescriptor_724696e352c3df5f, []int{36} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -991,7 +1075,7 @@ var xxx_messageInfo_Header proto.InternalMessageInfo func (m *Histogram) Reset() { *m = Histogram{} } func (*Histogram) ProtoMessage() {} func (*Histogram) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{34} + return fileDescriptor_724696e352c3df5f, []int{37} } func (m *Histogram) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1019,7 +1103,7 @@ var xxx_messageInfo_Histogram proto.InternalMessageInfo func (m *Inputs) Reset() { *m = Inputs{} } func (*Inputs) ProtoMessage() {} func (*Inputs) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{35} + return fileDescriptor_724696e352c3df5f, []int{38} } func (m *Inputs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1047,7 +1131,7 @@ var xxx_messageInfo_Inputs proto.InternalMessageInfo func (m *Item) Reset() { *m = Item{} } func (*Item) ProtoMessage() {} func (*Item) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{36} + return fileDescriptor_724696e352c3df5f, []int{39} } func (m *Item) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1075,7 +1159,7 @@ var xxx_messageInfo_Item proto.InternalMessageInfo func (m *Link) Reset() { *m = Link{} } func (*Link) ProtoMessage() {} func (*Link) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{37} + return fileDescriptor_724696e352c3df5f, []int{40} } func (m *Link) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1103,7 +1187,7 @@ var xxx_messageInfo_Link proto.InternalMessageInfo func (m *MemoizationStatus) Reset() { *m = MemoizationStatus{} } func (*MemoizationStatus) ProtoMessage() {} func (*MemoizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{38} + return fileDescriptor_724696e352c3df5f, []int{41} } func (m *MemoizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1131,7 +1215,7 @@ var xxx_messageInfo_MemoizationStatus proto.InternalMessageInfo func (m *Memoize) Reset() { *m = Memoize{} } func (*Memoize) ProtoMessage() {} func (*Memoize) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{39} + return fileDescriptor_724696e352c3df5f, []int{42} } func (m *Memoize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1159,7 +1243,7 @@ var xxx_messageInfo_Memoize proto.InternalMessageInfo func (m *Metadata) Reset() { *m = Metadata{} } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{40} + return fileDescriptor_724696e352c3df5f, []int{43} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1187,7 +1271,7 @@ var xxx_messageInfo_Metadata proto.InternalMessageInfo func (m *MetricLabel) Reset() { *m = MetricLabel{} } func (*MetricLabel) ProtoMessage() {} func (*MetricLabel) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{41} + return fileDescriptor_724696e352c3df5f, []int{44} } func (m *MetricLabel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1215,7 +1299,7 @@ var xxx_messageInfo_MetricLabel proto.InternalMessageInfo func (m *Metrics) Reset() { *m = Metrics{} } func (*Metrics) ProtoMessage() {} func (*Metrics) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{42} + return fileDescriptor_724696e352c3df5f, []int{45} } func (m *Metrics) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1243,7 +1327,7 @@ var xxx_messageInfo_Metrics proto.InternalMessageInfo func (m *Mutex) Reset() { *m = Mutex{} } func (*Mutex) ProtoMessage() {} func (*Mutex) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{43} + return fileDescriptor_724696e352c3df5f, []int{46} } func (m *Mutex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1271,7 +1355,7 @@ var xxx_messageInfo_Mutex proto.InternalMessageInfo func (m *MutexHolding) Reset() { *m = MutexHolding{} } func (*MutexHolding) ProtoMessage() {} func (*MutexHolding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{44} + return fileDescriptor_724696e352c3df5f, []int{47} } func (m *MutexHolding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1299,7 +1383,7 @@ var xxx_messageInfo_MutexHolding proto.InternalMessageInfo func (m *MutexStatus) Reset() { *m = MutexStatus{} } func (*MutexStatus) ProtoMessage() {} func (*MutexStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{45} + return fileDescriptor_724696e352c3df5f, []int{48} } func (m *MutexStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1327,7 +1411,7 @@ var xxx_messageInfo_MutexStatus proto.InternalMessageInfo func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} func (*NodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{46} + return fileDescriptor_724696e352c3df5f, []int{49} } func (m *NodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1355,7 +1439,7 @@ var xxx_messageInfo_NodeStatus proto.InternalMessageInfo func (m *NodeSynchronizationStatus) Reset() { *m = NodeSynchronizationStatus{} } func (*NodeSynchronizationStatus) ProtoMessage() {} func (*NodeSynchronizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{47} + return fileDescriptor_724696e352c3df5f, []int{50} } func (m *NodeSynchronizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1383,7 +1467,7 @@ var xxx_messageInfo_NodeSynchronizationStatus proto.InternalMessageInfo func (m *NoneStrategy) Reset() { *m = NoneStrategy{} } func (*NoneStrategy) ProtoMessage() {} func (*NoneStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{48} + return fileDescriptor_724696e352c3df5f, []int{51} } func (m *NoneStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1411,7 +1495,7 @@ var xxx_messageInfo_NoneStrategy proto.InternalMessageInfo func (m *OSSArtifact) Reset() { *m = OSSArtifact{} } func (*OSSArtifact) ProtoMessage() {} func (*OSSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{49} + return fileDescriptor_724696e352c3df5f, []int{52} } func (m *OSSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1439,7 +1523,7 @@ var xxx_messageInfo_OSSArtifact proto.InternalMessageInfo func (m *OSSBucket) Reset() { *m = OSSBucket{} } func (*OSSBucket) ProtoMessage() {} func (*OSSBucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{50} + return fileDescriptor_724696e352c3df5f, []int{53} } func (m *OSSBucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1467,7 +1551,7 @@ var xxx_messageInfo_OSSBucket proto.InternalMessageInfo func (m *Outputs) Reset() { *m = Outputs{} } func (*Outputs) ProtoMessage() {} func (*Outputs) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{51} + return fileDescriptor_724696e352c3df5f, []int{54} } func (m *Outputs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1495,7 +1579,7 @@ var xxx_messageInfo_Outputs proto.InternalMessageInfo func (m *ParallelSteps) Reset() { *m = ParallelSteps{} } func (*ParallelSteps) ProtoMessage() {} func (*ParallelSteps) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{52} + return fileDescriptor_724696e352c3df5f, []int{55} } func (m *ParallelSteps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1523,7 +1607,7 @@ var xxx_messageInfo_ParallelSteps proto.InternalMessageInfo func (m *Parameter) Reset() { *m = Parameter{} } func (*Parameter) ProtoMessage() {} func (*Parameter) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{53} + return fileDescriptor_724696e352c3df5f, []int{56} } func (m *Parameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1551,7 +1635,7 @@ var xxx_messageInfo_Parameter proto.InternalMessageInfo func (m *PodGC) Reset() { *m = PodGC{} } func (*PodGC) ProtoMessage() {} func (*PodGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{54} + return fileDescriptor_724696e352c3df5f, []int{57} } func (m *PodGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1579,7 +1663,7 @@ var xxx_messageInfo_PodGC proto.InternalMessageInfo func (m *Prometheus) Reset() { *m = Prometheus{} } func (*Prometheus) ProtoMessage() {} func (*Prometheus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{55} + return fileDescriptor_724696e352c3df5f, []int{58} } func (m *Prometheus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1607,7 +1691,7 @@ var xxx_messageInfo_Prometheus proto.InternalMessageInfo func (m *RawArtifact) Reset() { *m = RawArtifact{} } func (*RawArtifact) ProtoMessage() {} func (*RawArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{56} + return fileDescriptor_724696e352c3df5f, []int{59} } func (m *RawArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1635,7 +1719,7 @@ var xxx_messageInfo_RawArtifact proto.InternalMessageInfo func (m *ResourceTemplate) Reset() { *m = ResourceTemplate{} } func (*ResourceTemplate) ProtoMessage() {} func (*ResourceTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{57} + return fileDescriptor_724696e352c3df5f, []int{60} } func (m *ResourceTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1663,7 +1747,7 @@ var xxx_messageInfo_ResourceTemplate proto.InternalMessageInfo func (m *RetryAffinity) Reset() { *m = RetryAffinity{} } func (*RetryAffinity) ProtoMessage() {} func (*RetryAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{58} + return fileDescriptor_724696e352c3df5f, []int{61} } func (m *RetryAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1691,7 +1775,7 @@ var xxx_messageInfo_RetryAffinity proto.InternalMessageInfo func (m *RetryNodeAntiAffinity) Reset() { *m = RetryNodeAntiAffinity{} } func (*RetryNodeAntiAffinity) ProtoMessage() {} func (*RetryNodeAntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{59} + return fileDescriptor_724696e352c3df5f, []int{62} } func (m *RetryNodeAntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1719,7 +1803,7 @@ var xxx_messageInfo_RetryNodeAntiAffinity proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{60} + return fileDescriptor_724696e352c3df5f, []int{63} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1747,7 +1831,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *S3Artifact) Reset() { *m = S3Artifact{} } func (*S3Artifact) ProtoMessage() {} func (*S3Artifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{61} + return fileDescriptor_724696e352c3df5f, []int{64} } func (m *S3Artifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1775,7 +1859,7 @@ var xxx_messageInfo_S3Artifact proto.InternalMessageInfo func (m *S3Bucket) Reset() { *m = S3Bucket{} } func (*S3Bucket) ProtoMessage() {} func (*S3Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{62} + return fileDescriptor_724696e352c3df5f, []int{65} } func (m *S3Bucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1803,7 +1887,7 @@ var xxx_messageInfo_S3Bucket proto.InternalMessageInfo func (m *ScriptTemplate) Reset() { *m = ScriptTemplate{} } func (*ScriptTemplate) ProtoMessage() {} func (*ScriptTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{63} + return fileDescriptor_724696e352c3df5f, []int{66} } func (m *ScriptTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1831,7 +1915,7 @@ var xxx_messageInfo_ScriptTemplate proto.InternalMessageInfo func (m *SemaphoreHolding) Reset() { *m = SemaphoreHolding{} } func (*SemaphoreHolding) ProtoMessage() {} func (*SemaphoreHolding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{64} + return fileDescriptor_724696e352c3df5f, []int{67} } func (m *SemaphoreHolding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1859,7 +1943,7 @@ var xxx_messageInfo_SemaphoreHolding proto.InternalMessageInfo func (m *SemaphoreRef) Reset() { *m = SemaphoreRef{} } func (*SemaphoreRef) ProtoMessage() {} func (*SemaphoreRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{65} + return fileDescriptor_724696e352c3df5f, []int{68} } func (m *SemaphoreRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1887,7 +1971,7 @@ var xxx_messageInfo_SemaphoreRef proto.InternalMessageInfo func (m *SemaphoreStatus) Reset() { *m = SemaphoreStatus{} } func (*SemaphoreStatus) ProtoMessage() {} func (*SemaphoreStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{66} + return fileDescriptor_724696e352c3df5f, []int{69} } func (m *SemaphoreStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1915,7 +1999,7 @@ var xxx_messageInfo_SemaphoreStatus proto.InternalMessageInfo func (m *Sequence) Reset() { *m = Sequence{} } func (*Sequence) ProtoMessage() {} func (*Sequence) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{67} + return fileDescriptor_724696e352c3df5f, []int{70} } func (m *Sequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1943,7 +2027,7 @@ var xxx_messageInfo_Sequence proto.InternalMessageInfo func (m *Submit) Reset() { *m = Submit{} } func (*Submit) ProtoMessage() {} func (*Submit) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{68} + return fileDescriptor_724696e352c3df5f, []int{71} } func (m *Submit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1971,7 +2055,7 @@ var xxx_messageInfo_Submit proto.InternalMessageInfo func (m *SubmitOpts) Reset() { *m = SubmitOpts{} } func (*SubmitOpts) ProtoMessage() {} func (*SubmitOpts) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{69} + return fileDescriptor_724696e352c3df5f, []int{72} } func (m *SubmitOpts) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1999,7 +2083,7 @@ var xxx_messageInfo_SubmitOpts proto.InternalMessageInfo func (m *SuppliedValueFrom) Reset() { *m = SuppliedValueFrom{} } func (*SuppliedValueFrom) ProtoMessage() {} func (*SuppliedValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{70} + return fileDescriptor_724696e352c3df5f, []int{73} } func (m *SuppliedValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2027,7 +2111,7 @@ var xxx_messageInfo_SuppliedValueFrom proto.InternalMessageInfo func (m *SuspendTemplate) Reset() { *m = SuspendTemplate{} } func (*SuspendTemplate) ProtoMessage() {} func (*SuspendTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{71} + return fileDescriptor_724696e352c3df5f, []int{74} } func (m *SuspendTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2055,7 +2139,7 @@ var xxx_messageInfo_SuspendTemplate proto.InternalMessageInfo func (m *Synchronization) Reset() { *m = Synchronization{} } func (*Synchronization) ProtoMessage() {} func (*Synchronization) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{72} + return fileDescriptor_724696e352c3df5f, []int{75} } func (m *Synchronization) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2083,7 +2167,7 @@ var xxx_messageInfo_Synchronization proto.InternalMessageInfo func (m *SynchronizationStatus) Reset() { *m = SynchronizationStatus{} } func (*SynchronizationStatus) ProtoMessage() {} func (*SynchronizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{73} + return fileDescriptor_724696e352c3df5f, []int{76} } func (m *SynchronizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2111,7 +2195,7 @@ var xxx_messageInfo_SynchronizationStatus proto.InternalMessageInfo func (m *TTLStrategy) Reset() { *m = TTLStrategy{} } func (*TTLStrategy) ProtoMessage() {} func (*TTLStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{74} + return fileDescriptor_724696e352c3df5f, []int{77} } func (m *TTLStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2139,7 +2223,7 @@ var xxx_messageInfo_TTLStrategy proto.InternalMessageInfo func (m *TarStrategy) Reset() { *m = TarStrategy{} } func (*TarStrategy) ProtoMessage() {} func (*TarStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{75} + return fileDescriptor_724696e352c3df5f, []int{78} } func (m *TarStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2167,7 +2251,7 @@ var xxx_messageInfo_TarStrategy proto.InternalMessageInfo func (m *Template) Reset() { *m = Template{} } func (*Template) ProtoMessage() {} func (*Template) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{76} + return fileDescriptor_724696e352c3df5f, []int{79} } func (m *Template) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2195,7 +2279,7 @@ var xxx_messageInfo_Template proto.InternalMessageInfo func (m *TemplateRef) Reset() { *m = TemplateRef{} } func (*TemplateRef) ProtoMessage() {} func (*TemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{77} + return fileDescriptor_724696e352c3df5f, []int{80} } func (m *TemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2220,10 +2304,38 @@ func (m *TemplateRef) XXX_DiscardUnknown() { var xxx_messageInfo_TemplateRef proto.InternalMessageInfo +func (m *TransformationStep) Reset() { *m = TransformationStep{} } +func (*TransformationStep) ProtoMessage() {} +func (*TransformationStep) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{81} +} +func (m *TransformationStep) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TransformationStep) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *TransformationStep) XXX_Merge(src proto.Message) { + xxx_messageInfo_TransformationStep.Merge(m, src) +} +func (m *TransformationStep) XXX_Size() int { + return m.Size() +} +func (m *TransformationStep) XXX_DiscardUnknown() { + xxx_messageInfo_TransformationStep.DiscardUnknown(m) +} + +var xxx_messageInfo_TransformationStep proto.InternalMessageInfo + func (m *UserContainer) Reset() { *m = UserContainer{} } func (*UserContainer) ProtoMessage() {} func (*UserContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{78} + return fileDescriptor_724696e352c3df5f, []int{82} } func (m *UserContainer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2251,7 +2363,7 @@ var xxx_messageInfo_UserContainer proto.InternalMessageInfo func (m *ValueFrom) Reset() { *m = ValueFrom{} } func (*ValueFrom) ProtoMessage() {} func (*ValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{79} + return fileDescriptor_724696e352c3df5f, []int{83} } func (m *ValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2279,7 +2391,7 @@ var xxx_messageInfo_ValueFrom proto.InternalMessageInfo func (m *Version) Reset() { *m = Version{} } func (*Version) ProtoMessage() {} func (*Version) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{80} + return fileDescriptor_724696e352c3df5f, []int{84} } func (m *Version) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2307,7 +2419,7 @@ var xxx_messageInfo_Version proto.InternalMessageInfo func (m *VolumeClaimGC) Reset() { *m = VolumeClaimGC{} } func (*VolumeClaimGC) ProtoMessage() {} func (*VolumeClaimGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{81} + return fileDescriptor_724696e352c3df5f, []int{85} } func (m *VolumeClaimGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2335,7 +2447,7 @@ var xxx_messageInfo_VolumeClaimGC proto.InternalMessageInfo func (m *Workflow) Reset() { *m = Workflow{} } func (*Workflow) ProtoMessage() {} func (*Workflow) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{82} + return fileDescriptor_724696e352c3df5f, []int{86} } func (m *Workflow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2363,7 +2475,7 @@ var xxx_messageInfo_Workflow proto.InternalMessageInfo func (m *WorkflowEventBinding) Reset() { *m = WorkflowEventBinding{} } func (*WorkflowEventBinding) ProtoMessage() {} func (*WorkflowEventBinding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{83} + return fileDescriptor_724696e352c3df5f, []int{87} } func (m *WorkflowEventBinding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2391,7 +2503,7 @@ var xxx_messageInfo_WorkflowEventBinding proto.InternalMessageInfo func (m *WorkflowEventBindingList) Reset() { *m = WorkflowEventBindingList{} } func (*WorkflowEventBindingList) ProtoMessage() {} func (*WorkflowEventBindingList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{84} + return fileDescriptor_724696e352c3df5f, []int{88} } func (m *WorkflowEventBindingList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2419,7 +2531,7 @@ var xxx_messageInfo_WorkflowEventBindingList proto.InternalMessageInfo func (m *WorkflowEventBindingSpec) Reset() { *m = WorkflowEventBindingSpec{} } func (*WorkflowEventBindingSpec) ProtoMessage() {} func (*WorkflowEventBindingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{85} + return fileDescriptor_724696e352c3df5f, []int{89} } func (m *WorkflowEventBindingSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2447,7 +2559,7 @@ var xxx_messageInfo_WorkflowEventBindingSpec proto.InternalMessageInfo func (m *WorkflowList) Reset() { *m = WorkflowList{} } func (*WorkflowList) ProtoMessage() {} func (*WorkflowList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{86} + return fileDescriptor_724696e352c3df5f, []int{90} } func (m *WorkflowList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2475,7 +2587,7 @@ var xxx_messageInfo_WorkflowList proto.InternalMessageInfo func (m *WorkflowSpec) Reset() { *m = WorkflowSpec{} } func (*WorkflowSpec) ProtoMessage() {} func (*WorkflowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{87} + return fileDescriptor_724696e352c3df5f, []int{91} } func (m *WorkflowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2503,7 +2615,7 @@ var xxx_messageInfo_WorkflowSpec proto.InternalMessageInfo func (m *WorkflowStatus) Reset() { *m = WorkflowStatus{} } func (*WorkflowStatus) ProtoMessage() {} func (*WorkflowStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{88} + return fileDescriptor_724696e352c3df5f, []int{92} } func (m *WorkflowStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2531,7 +2643,7 @@ var xxx_messageInfo_WorkflowStatus proto.InternalMessageInfo func (m *WorkflowStep) Reset() { *m = WorkflowStep{} } func (*WorkflowStep) ProtoMessage() {} func (*WorkflowStep) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{89} + return fileDescriptor_724696e352c3df5f, []int{93} } func (m *WorkflowStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2559,7 +2671,7 @@ var xxx_messageInfo_WorkflowStep proto.InternalMessageInfo func (m *WorkflowTemplate) Reset() { *m = WorkflowTemplate{} } func (*WorkflowTemplate) ProtoMessage() {} func (*WorkflowTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{90} + return fileDescriptor_724696e352c3df5f, []int{94} } func (m *WorkflowTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2587,7 +2699,7 @@ var xxx_messageInfo_WorkflowTemplate proto.InternalMessageInfo func (m *WorkflowTemplateList) Reset() { *m = WorkflowTemplateList{} } func (*WorkflowTemplateList) ProtoMessage() {} func (*WorkflowTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{91} + return fileDescriptor_724696e352c3df5f, []int{95} } func (m *WorkflowTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2615,7 +2727,7 @@ var xxx_messageInfo_WorkflowTemplateList proto.InternalMessageInfo func (m *WorkflowTemplateRef) Reset() { *m = WorkflowTemplateRef{} } func (*WorkflowTemplateRef) ProtoMessage() {} func (*WorkflowTemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{92} + return fileDescriptor_724696e352c3df5f, []int{96} } func (m *WorkflowTemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2643,7 +2755,7 @@ var xxx_messageInfo_WorkflowTemplateRef proto.InternalMessageInfo func (m *WorkflowTemplateSpec) Reset() { *m = WorkflowTemplateSpec{} } func (*WorkflowTemplateSpec) ProtoMessage() {} func (*WorkflowTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{93} + return fileDescriptor_724696e352c3df5f, []int{97} } func (m *WorkflowTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2671,7 +2783,7 @@ var xxx_messageInfo_WorkflowTemplateSpec proto.InternalMessageInfo func (m *ZipStrategy) Reset() { *m = ZipStrategy{} } func (*ZipStrategy) ProtoMessage() {} func (*ZipStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{94} + return fileDescriptor_724696e352c3df5f, []int{98} } func (m *ZipStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2702,6 +2814,7 @@ func init() { proto.RegisterType((*Arguments)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Arguments") proto.RegisterType((*Artifact)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Artifact") proto.RegisterType((*ArtifactLocation)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ArtifactLocation") + proto.RegisterType((*ArtifactPaths)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ArtifactPaths") proto.RegisterType((*ArtifactRepositoryRef)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ArtifactRepositoryRef") proto.RegisterType((*ArtifactRepositoryRefStatus)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ArtifactRepositoryRefStatus") proto.RegisterType((*ArtifactoryArtifact)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ArtifactoryArtifact") @@ -2720,6 +2833,8 @@ func init() { proto.RegisterType((*CronWorkflowStatus)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.CronWorkflowStatus") proto.RegisterType((*DAGTask)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.DAGTask") proto.RegisterType((*DAGTemplate)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.DAGTemplate") + proto.RegisterType((*Data)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Data") + proto.RegisterType((*DataSource)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.DataSource") proto.RegisterType((*Event)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Event") proto.RegisterType((*ExecutorConfig)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ExecutorConfig") proto.RegisterType((*GCSArtifact)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.GCSArtifact") @@ -2779,6 +2894,7 @@ func init() { proto.RegisterType((*Template)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Template") proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Template.NodeSelectorEntry") proto.RegisterType((*TemplateRef)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.TemplateRef") + proto.RegisterType((*TransformationStep)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.TransformationStep") proto.RegisterType((*UserContainer)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.UserContainer") proto.RegisterType((*ValueFrom)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ValueFrom") proto.RegisterType((*Version)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Version") @@ -2807,481 +2923,491 @@ func init() { } var fileDescriptor_724696e352c3df5f = []byte{ - // 7577 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x24, 0xd7, - 0xb5, 0x90, 0x7b, 0xa4, 0x91, 0x66, 0xce, 0x48, 0x2b, 0xe9, 0xee, 0xd7, 0x58, 0x5e, 0xaf, 0xf6, - 0xb5, 0x9f, 0x5d, 0x5e, 0x70, 0xa4, 0xe7, 0x5d, 0x1b, 0x0c, 0x2e, 0xde, 0x8b, 0x46, 0x5a, 0x69, - 0x77, 0xb5, 0xfa, 0xf0, 0x19, 0xed, 0xba, 0x62, 0x1b, 0x93, 0xd6, 0xcc, 0xd5, 0x4c, 0x5b, 0x33, - 0xdd, 0xed, 0xee, 0x1e, 0x69, 0x65, 0xaf, 0xf3, 0xc2, 0x03, 0xde, 0x73, 0x08, 0x21, 0x90, 0x4a, - 0x05, 0x27, 0xfc, 0x49, 0x01, 0x01, 0x0a, 0x52, 0x14, 0xa1, 0xf8, 0x15, 0xfe, 0x42, 0x55, 0x28, - 0x7e, 0x90, 0xaa, 0x40, 0xc5, 0x55, 0x80, 0x42, 0xc4, 0xe7, 0x1f, 0xf8, 0x97, 0x90, 0x5a, 0xa0, - 0x8a, 0xba, 0x9f, 0xfd, 0x31, 0x3d, 0xbb, 0xd2, 0x6e, 0x6b, 0x9d, 0xaa, 0xf0, 0x6f, 0xe6, 0x9c, - 0x73, 0xcf, 0xb9, 0x9f, 0xe7, 0xde, 0xf3, 0x71, 0x6f, 0xc3, 0x46, 0xcb, 0x0e, 0xdb, 0xbd, 0xad, - 0xd9, 0x86, 0xdb, 0x9d, 0xb3, 0xfc, 0x96, 0xeb, 0xf9, 0xee, 0x7b, 0xfc, 0xc7, 0xe7, 0xf6, 0x5c, - 0x7f, 0x67, 0xbb, 0xe3, 0xee, 0x05, 0x73, 0xbb, 0x57, 0xe7, 0xbc, 0x9d, 0xd6, 0x9c, 0xe5, 0xd9, - 0xc1, 0x9c, 0x82, 0xce, 0xed, 0xbe, 0x6c, 0x75, 0xbc, 0xb6, 0xf5, 0xf2, 0x5c, 0x8b, 0x3a, 0xd4, - 0xb7, 0x42, 0xda, 0x9c, 0xf5, 0x7c, 0x37, 0x74, 0xc9, 0xe7, 0x23, 0x8e, 0xb3, 0x8a, 0x23, 0xff, - 0xf1, 0xe7, 0x34, 0xc7, 0xd9, 0xdd, 0xab, 0xb3, 0xde, 0x4e, 0x6b, 0x96, 0x71, 0x9c, 0x55, 0xd0, - 0x59, 0xc5, 0x71, 0xfa, 0x73, 0xb1, 0x3a, 0xb5, 0xdc, 0x96, 0x3b, 0xc7, 0x19, 0x6f, 0xf5, 0xb6, - 0xf9, 0x3f, 0xfe, 0x87, 0xff, 0x12, 0x02, 0xa7, 0xcd, 0x9d, 0xd7, 0x82, 0x59, 0xdb, 0x65, 0xf5, - 0x9b, 0x6b, 0xb8, 0x3e, 0x9d, 0xdb, 0xed, 0xab, 0xd4, 0xf4, 0xe5, 0x18, 0x8d, 0xe7, 0x76, 0xec, - 0xc6, 0xfe, 0xdc, 0xee, 0xcb, 0x5b, 0x34, 0xec, 0xaf, 0xff, 0xf4, 0x2b, 0x11, 0x69, 0xd7, 0x6a, - 0xb4, 0x6d, 0x87, 0xfa, 0xfb, 0x51, 0xfb, 0xbb, 0x34, 0xb4, 0xb2, 0x04, 0xcc, 0x0d, 0x2a, 0xe5, - 0xf7, 0x9c, 0xd0, 0xee, 0xd2, 0xbe, 0x02, 0x7f, 0xe2, 0x61, 0x05, 0x82, 0x46, 0x9b, 0x76, 0xad, - 0xbe, 0x72, 0x57, 0x07, 0x95, 0xeb, 0x85, 0x76, 0x67, 0xce, 0x76, 0xc2, 0x20, 0xf4, 0xd3, 0x85, - 0xcc, 0x6b, 0x30, 0x32, 0xdf, 0x75, 0x7b, 0x4e, 0x48, 0x5e, 0x87, 0xe2, 0xae, 0xd5, 0xe9, 0xd1, - 0xaa, 0x71, 0xc9, 0x78, 0xb1, 0x5c, 0x7b, 0xfe, 0x47, 0x07, 0x33, 0x4f, 0x1d, 0x1e, 0xcc, 0x14, - 0xef, 0x30, 0xe0, 0xfd, 0x83, 0x99, 0x33, 0xd4, 0x69, 0xb8, 0x4d, 0xdb, 0x69, 0xcd, 0xbd, 0x17, - 0xb8, 0xce, 0xec, 0x5a, 0xaf, 0xbb, 0x45, 0x7d, 0x14, 0x65, 0xcc, 0x9f, 0x14, 0x60, 0x62, 0xde, - 0x6f, 0xb4, 0xed, 0x5d, 0x5a, 0x0f, 0x19, 0xff, 0xd6, 0x3e, 0x69, 0xc3, 0x50, 0x68, 0xf9, 0x9c, - 0x5d, 0xe5, 0xca, 0xea, 0xec, 0xe3, 0x0e, 0xfe, 0xec, 0xa6, 0xe5, 0x2b, 0xde, 0xb5, 0xd1, 0xc3, - 0x83, 0x99, 0xa1, 0x4d, 0xcb, 0x47, 0x26, 0x82, 0x74, 0x60, 0xd8, 0x71, 0x1d, 0x5a, 0x2d, 0x70, - 0x51, 0x6b, 0x8f, 0x2f, 0x6a, 0xcd, 0x75, 0x74, 0x3b, 0x6a, 0xa5, 0xc3, 0x83, 0x99, 0x61, 0x06, - 0x41, 0x2e, 0x85, 0xb5, 0xeb, 0x03, 0xdb, 0xab, 0x0e, 0xe5, 0xd5, 0xae, 0xb7, 0x6c, 0x2f, 0xd9, - 0xae, 0xb7, 0x6c, 0x0f, 0x99, 0x08, 0xf3, 0x2b, 0x05, 0x28, 0xcf, 0xfb, 0xad, 0x5e, 0x97, 0x3a, - 0x61, 0x40, 0x7e, 0x1f, 0xc0, 0xb3, 0x7c, 0xab, 0x4b, 0x43, 0xea, 0x07, 0x55, 0xe3, 0xd2, 0xd0, - 0x8b, 0x95, 0x2b, 0x2b, 0x8f, 0x2f, 0x7e, 0x43, 0xf1, 0xac, 0x11, 0x39, 0xe4, 0xa0, 0x41, 0x01, - 0xc6, 0x44, 0x92, 0x0f, 0xa1, 0x6c, 0xf9, 0xa1, 0xbd, 0x6d, 0x35, 0xc2, 0xa0, 0x5a, 0xe0, 0xf2, - 0x6f, 0x3e, 0xbe, 0xfc, 0x79, 0xc9, 0xb2, 0x36, 0x25, 0xc5, 0x97, 0x15, 0x24, 0xc0, 0x48, 0x9e, - 0xf9, 0xdf, 0x86, 0xa1, 0xa4, 0x10, 0xe4, 0x12, 0x0c, 0x3b, 0x56, 0x57, 0x4d, 0xd5, 0x31, 0x59, - 0x70, 0x78, 0xcd, 0xea, 0xb2, 0x41, 0xb2, 0xba, 0x94, 0x51, 0x78, 0x56, 0xd8, 0xe6, 0x53, 0x22, - 0x46, 0xb1, 0x61, 0x85, 0x6d, 0xe4, 0x18, 0x72, 0x01, 0x86, 0xbb, 0x6e, 0x93, 0xf2, 0x71, 0x2c, - 0x8a, 0x41, 0x5e, 0x75, 0x9b, 0x14, 0x39, 0x94, 0x95, 0xdf, 0xf6, 0xdd, 0x6e, 0x75, 0x38, 0x59, - 0x7e, 0xc9, 0x77, 0xbb, 0xc8, 0x31, 0xe4, 0x13, 0x03, 0x26, 0x55, 0xf5, 0x6e, 0xb9, 0x0d, 0x2b, - 0xb4, 0x5d, 0xa7, 0x5a, 0xe4, 0x93, 0x02, 0xf3, 0xeb, 0x15, 0xc5, 0xb9, 0x56, 0x95, 0x55, 0x98, - 0x4c, 0x63, 0xb0, 0xaf, 0x16, 0xe4, 0x0a, 0x40, 0xab, 0xe3, 0x6e, 0x59, 0x1d, 0xd6, 0x21, 0xd5, - 0x11, 0xde, 0x04, 0x3d, 0xb8, 0xcb, 0x1a, 0x83, 0x31, 0x2a, 0x72, 0x17, 0x46, 0x2d, 0xb1, 0x80, - 0xab, 0xa3, 0xbc, 0x11, 0x6f, 0xe4, 0xd1, 0x88, 0x84, 0x46, 0xa8, 0x55, 0x0e, 0x0f, 0x66, 0x46, - 0x25, 0x10, 0x95, 0x38, 0xf2, 0x12, 0x94, 0x5c, 0x8f, 0xd5, 0xdb, 0xea, 0x54, 0x4b, 0x97, 0x8c, - 0x17, 0x4b, 0xb5, 0x49, 0x59, 0xd7, 0xd2, 0xba, 0x84, 0xa3, 0xa6, 0x20, 0x97, 0x61, 0x34, 0xe8, - 0x6d, 0xb1, 0x71, 0xac, 0x96, 0x79, 0xc3, 0x26, 0x24, 0xf1, 0x68, 0x5d, 0x80, 0x51, 0xe1, 0xc9, - 0xab, 0x50, 0xf1, 0x69, 0xa3, 0xe7, 0x07, 0x94, 0x0d, 0x6c, 0x15, 0x38, 0xef, 0xd3, 0x92, 0xbc, - 0x82, 0x11, 0x0a, 0xe3, 0x74, 0xe6, 0x0f, 0x47, 0xa1, 0xaf, 0x93, 0xc9, 0xcb, 0x50, 0x91, 0xf5, - 0xbd, 0xe5, 0xb6, 0x02, 0x3e, 0xf1, 0x4a, 0xb5, 0x09, 0xc6, 0x67, 0x3e, 0x02, 0x63, 0x9c, 0x86, - 0x34, 0xa1, 0x10, 0x5c, 0x95, 0x3a, 0xe9, 0xd6, 0xe3, 0x77, 0x66, 0xfd, 0xaa, 0x5e, 0x29, 0x23, - 0x87, 0x07, 0x33, 0x85, 0xfa, 0x55, 0x2c, 0x04, 0x57, 0x99, 0x36, 0x6a, 0xd9, 0x61, 0x7e, 0xda, - 0x68, 0xd9, 0x0e, 0xb5, 0x1c, 0xae, 0x8d, 0x96, 0xed, 0x10, 0x99, 0x08, 0xa6, 0x65, 0xdb, 0x61, - 0xe8, 0xf1, 0x25, 0x91, 0x8b, 0x96, 0xbd, 0xbe, 0xb9, 0xb9, 0xa1, 0x65, 0xf1, 0x05, 0xc8, 0x20, - 0xc8, 0xa5, 0x90, 0x8f, 0x0d, 0xd6, 0xe3, 0x02, 0xe9, 0xfa, 0xfb, 0x72, 0x65, 0xdd, 0xce, 0x6f, - 0x65, 0xb9, 0xfe, 0xbe, 0x16, 0x2e, 0x07, 0x52, 0x23, 0x30, 0x2e, 0x9a, 0x37, 0xbc, 0xb9, 0x1d, - 0xf0, 0x85, 0x94, 0x4f, 0xc3, 0x17, 0x97, 0xea, 0xa9, 0x86, 0x2f, 0x2e, 0xd5, 0x91, 0x4b, 0x61, - 0x03, 0xea, 0x5b, 0x7b, 0x72, 0x11, 0xe6, 0x30, 0xa0, 0x68, 0xed, 0x25, 0x07, 0x14, 0xad, 0x3d, - 0x64, 0x22, 0x98, 0x24, 0x37, 0x08, 0xf8, 0x9a, 0xcb, 0x45, 0xd2, 0x7a, 0xbd, 0x9e, 0x94, 0xb4, - 0x5e, 0xaf, 0x23, 0x13, 0xc1, 0x27, 0x69, 0x23, 0xe0, 0x0b, 0x36, 0x9f, 0x49, 0xba, 0x90, 0x92, - 0xb4, 0xbc, 0x50, 0x47, 0x26, 0xc2, 0x7c, 0x1f, 0xce, 0x2a, 0x0c, 0x52, 0xcf, 0x0d, 0x6c, 0x3e, - 0x9c, 0x74, 0x9b, 0xcc, 0x41, 0xb9, 0xe1, 0x3a, 0xdb, 0x76, 0x6b, 0xd5, 0xf2, 0xe4, 0xbe, 0xa1, - 0x37, 0x9c, 0x05, 0x85, 0xc0, 0x88, 0x86, 0x3c, 0x0b, 0x43, 0x3b, 0x74, 0x5f, 0x6e, 0x20, 0x15, - 0x49, 0x3a, 0xb4, 0x42, 0xf7, 0x91, 0xc1, 0xff, 0x74, 0xe9, 0x93, 0xef, 0xce, 0x3c, 0xf5, 0xe5, - 0x7f, 0x7f, 0xe9, 0x29, 0xf3, 0x9f, 0x14, 0xe0, 0x99, 0x4c, 0x99, 0xf5, 0xd0, 0x0a, 0x7b, 0x01, - 0xf9, 0xbe, 0x01, 0x67, 0xad, 0x2c, 0xbc, 0x3c, 0x1a, 0xbd, 0x99, 0xdf, 0x9c, 0x4e, 0xb0, 0xaf, - 0x3d, 0x2b, 0x2b, 0x9d, 0xdd, 0x23, 0x98, 0x5d, 0x29, 0xd6, 0x51, 0x6c, 0x07, 0x0d, 0x3c, 0xab, - 0x41, 0x65, 0xeb, 0x75, 0x47, 0xad, 0x29, 0x04, 0x46, 0x34, 0x4c, 0x23, 0x37, 0xe9, 0xb6, 0xd5, - 0xeb, 0x08, 0x2d, 0x54, 0x8a, 0x34, 0xf2, 0xa2, 0x00, 0xa3, 0xc2, 0xc7, 0x3a, 0xed, 0x5f, 0x19, - 0x70, 0x3a, 0x63, 0x25, 0xb2, 0x5e, 0xef, 0xf9, 0x1d, 0x39, 0x40, 0xba, 0xd7, 0x6f, 0xe3, 0x2d, - 0x64, 0x70, 0xf2, 0x4d, 0x03, 0x26, 0x62, 0x4b, 0x73, 0xbe, 0x27, 0xb7, 0xf8, 0x9c, 0xb6, 0xab, - 0x04, 0xe3, 0xda, 0x79, 0x29, 0x7e, 0x22, 0x85, 0xc0, 0x74, 0x15, 0xcc, 0x9f, 0x1a, 0x90, 0x26, - 0x22, 0x16, 0x9c, 0xea, 0x05, 0xd4, 0x67, 0xfd, 0x54, 0xa7, 0x0d, 0x9f, 0x86, 0x72, 0xb8, 0x9f, - 0x9f, 0x15, 0xe7, 0x74, 0x56, 0x8b, 0x59, 0x66, 0x95, 0xcc, 0xee, 0xbe, 0x3c, 0x2b, 0x28, 0x56, - 0xe8, 0x7e, 0x9d, 0x76, 0x28, 0xe3, 0x51, 0x23, 0x87, 0x07, 0x33, 0xa7, 0x6e, 0x27, 0x18, 0x60, - 0x8a, 0x21, 0x13, 0xe1, 0x59, 0x41, 0xb0, 0xe7, 0xfa, 0x4d, 0x29, 0xa2, 0x70, 0x6c, 0x11, 0x1b, - 0x09, 0x06, 0x98, 0x62, 0x68, 0xfe, 0x73, 0x03, 0x46, 0x6b, 0x56, 0x63, 0xc7, 0xdd, 0xde, 0x66, - 0x1b, 0x75, 0xb3, 0xe7, 0x8b, 0x83, 0x8e, 0x18, 0x20, 0xbd, 0x51, 0x2f, 0x4a, 0x38, 0x6a, 0x0a, - 0xb2, 0x09, 0x23, 0xa2, 0x3b, 0x64, 0xa5, 0x7e, 0x27, 0x56, 0x29, 0x6d, 0x9f, 0xf0, 0xe1, 0x60, - 0xf6, 0xc9, 0xac, 0xb0, 0x4f, 0x66, 0x6f, 0x38, 0xe1, 0x3a, 0x3b, 0xe6, 0xdb, 0x4e, 0xab, 0x06, - 0x87, 0x07, 0x33, 0x23, 0x4b, 0x9c, 0x07, 0x4a, 0x5e, 0x6c, 0x4f, 0xef, 0x5a, 0x77, 0x95, 0x38, - 0x3e, 0xe1, 0xca, 0xd1, 0x9e, 0xbe, 0x1a, 0xa1, 0x30, 0x4e, 0x67, 0xbe, 0x0b, 0xc5, 0x05, 0xab, - 0xd1, 0xa6, 0xe4, 0x76, 0x5a, 0x0d, 0x54, 0xae, 0xbc, 0x98, 0xd5, 0x5b, 0x5a, 0x25, 0xc4, 0x3b, - 0x6c, 0x7c, 0x90, 0xb2, 0x30, 0x7f, 0x61, 0xc0, 0xf9, 0x85, 0x4e, 0x2f, 0x08, 0xa9, 0xff, 0xa6, - 0x9c, 0x57, 0x9b, 0xb4, 0xeb, 0x75, 0xac, 0x90, 0x92, 0x2f, 0x42, 0x89, 0xd9, 0x86, 0x4d, 0x2b, - 0xb4, 0xa4, 0xc4, 0xc1, 0x5d, 0xc1, 0x67, 0x26, 0xa3, 0x66, 0x75, 0x58, 0xdf, 0x7a, 0x8f, 0x36, - 0xc2, 0x55, 0x1a, 0x5a, 0xd1, 0xe9, 0x2d, 0x82, 0xa1, 0xe6, 0x4a, 0xee, 0xc2, 0x70, 0xe0, 0xd1, - 0x86, 0xec, 0xe8, 0x3b, 0x8f, 0xbf, 0x12, 0xd2, 0x6d, 0xa8, 0x7b, 0xb4, 0x11, 0x1d, 0x82, 0xd9, - 0x3f, 0xe4, 0x12, 0xcd, 0xff, 0x6d, 0xc0, 0x33, 0x03, 0xda, 0x7d, 0xcb, 0x0e, 0x42, 0xf2, 0x4e, - 0x5f, 0xdb, 0x67, 0x8f, 0xd6, 0x76, 0x56, 0x9a, 0xb7, 0x5c, 0x4f, 0x31, 0x05, 0x89, 0xb5, 0xfb, - 0x4b, 0x50, 0xb4, 0x43, 0xda, 0x55, 0xc6, 0xc8, 0x17, 0x1e, 0xbf, 0xe1, 0x03, 0xda, 0x52, 0x1b, - 0x57, 0xd6, 0xf0, 0x0d, 0x26, 0x0f, 0x85, 0x58, 0xf3, 0x5f, 0x1a, 0xc0, 0xa6, 0x43, 0xd3, 0x96, - 0x47, 0xc4, 0xe1, 0x70, 0xdf, 0x53, 0x46, 0x89, 0x52, 0xbe, 0xc3, 0x9b, 0xfb, 0x1e, 0x33, 0x9f, - 0xc7, 0x35, 0x21, 0x03, 0x20, 0x27, 0x25, 0xef, 0xc2, 0x48, 0xc0, 0x37, 0x09, 0xa9, 0x68, 0x97, - 0x64, 0xa1, 0x11, 0xb1, 0x75, 0xdc, 0x3f, 0x98, 0x39, 0x92, 0xcf, 0x61, 0x56, 0xf3, 0x16, 0xe5, - 0x50, 0x72, 0x65, 0xaa, 0xb9, 0x4b, 0x83, 0xc0, 0x6a, 0x51, 0xb9, 0x52, 0xb4, 0x6a, 0x5e, 0x15, - 0x60, 0x54, 0x78, 0xf3, 0x0b, 0x00, 0x0b, 0xae, 0x13, 0xda, 0x4e, 0x8f, 0xae, 0x3b, 0xe4, 0x39, - 0x28, 0x52, 0xdf, 0x77, 0x7d, 0x79, 0xd0, 0xd5, 0xcd, 0xbf, 0xc6, 0x80, 0x28, 0x70, 0xe4, 0x05, - 0xb6, 0xc2, 0xed, 0x0e, 0x6d, 0xf2, 0xda, 0x97, 0x6a, 0xa7, 0x54, 0xed, 0x97, 0x38, 0x14, 0x25, - 0xd6, 0x9c, 0x85, 0xd1, 0x05, 0xb7, 0xe7, 0x84, 0xd4, 0x67, 0x7c, 0xe3, 0x4e, 0x86, 0xf1, 0x84, - 0x93, 0x41, 0x39, 0x13, 0x36, 0xe1, 0xec, 0x82, 0x4f, 0xd9, 0xb4, 0xbb, 0x5a, 0xeb, 0x35, 0x76, - 0x68, 0x28, 0xcc, 0x80, 0x80, 0xbc, 0x0e, 0xe3, 0x2e, 0x9f, 0xff, 0xb7, 0xdc, 0xc6, 0x8e, 0xed, - 0xb4, 0xe4, 0x7e, 0x73, 0x56, 0x72, 0x19, 0x5f, 0x8f, 0x23, 0x31, 0x49, 0x6b, 0xfe, 0xe7, 0x02, - 0x8c, 0x2d, 0xf8, 0xae, 0xa3, 0xc6, 0xf6, 0x09, 0xac, 0xcb, 0x30, 0xb1, 0x2e, 0x73, 0xb0, 0x0a, - 0xe3, 0xf5, 0x1f, 0xb4, 0x26, 0xc9, 0x3d, 0x3d, 0xa9, 0x84, 0x51, 0xb0, 0x99, 0xb3, 0x5c, 0xce, - 0x3b, 0x1a, 0xec, 0xe4, 0x94, 0x33, 0xff, 0x8b, 0x01, 0x93, 0x71, 0xf2, 0x27, 0xa0, 0x06, 0x82, - 0xa4, 0x1a, 0x58, 0xcb, 0xb7, 0xbd, 0x03, 0xd6, 0xfe, 0x57, 0x46, 0x92, 0xed, 0x64, 0x03, 0x40, - 0x3e, 0x31, 0x60, 0x6c, 0x2f, 0x06, 0x90, 0x8d, 0x5d, 0xcb, 0x4f, 0x23, 0xf3, 0x51, 0xff, 0x6d, - 0x59, 0xa3, 0xb1, 0x38, 0xf4, 0x7e, 0xea, 0x3f, 0x26, 0x6a, 0xc2, 0x36, 0xef, 0xa0, 0xd1, 0xa6, - 0xcd, 0x5e, 0x47, 0x9d, 0xea, 0x74, 0x97, 0xd6, 0x25, 0x1c, 0x35, 0x05, 0x79, 0x07, 0xa6, 0x1a, - 0xae, 0xd3, 0xe8, 0xf9, 0x3e, 0x75, 0x1a, 0xfb, 0x1b, 0xdc, 0x2f, 0x2a, 0x55, 0xc8, 0xac, 0x2c, - 0x36, 0xb5, 0x90, 0x26, 0xb8, 0x9f, 0x05, 0xc4, 0x7e, 0x46, 0xc2, 0x86, 0x0f, 0x3c, 0xea, 0x34, - 0xb9, 0x31, 0x59, 0x8a, 0xdb, 0xf0, 0x1c, 0x8c, 0x0a, 0x4f, 0x6e, 0xc3, 0xf9, 0x20, 0x64, 0xc7, - 0x2d, 0xa7, 0xb5, 0x48, 0xad, 0x66, 0xc7, 0x76, 0xd8, 0xe1, 0xc7, 0x75, 0x9a, 0x01, 0xb7, 0x08, - 0x87, 0x6a, 0xcf, 0x1c, 0x1e, 0xcc, 0x9c, 0xaf, 0x67, 0x93, 0xe0, 0xa0, 0xb2, 0xe4, 0x5d, 0x98, - 0x0e, 0x7a, 0x8d, 0x06, 0x0d, 0x82, 0xed, 0x5e, 0xe7, 0xa6, 0xbb, 0x15, 0x5c, 0xb7, 0x03, 0x76, - 0x72, 0xbb, 0x65, 0x77, 0xed, 0x90, 0x1b, 0x7a, 0xc5, 0xda, 0xc5, 0xc3, 0x83, 0x99, 0xe9, 0xfa, - 0x40, 0x2a, 0x7c, 0x00, 0x07, 0x82, 0x70, 0x4e, 0x28, 0xbf, 0x3e, 0xde, 0xa3, 0x9c, 0xf7, 0xf4, - 0xe1, 0xc1, 0xcc, 0xb9, 0xa5, 0x4c, 0x0a, 0x1c, 0x50, 0x92, 0x8d, 0x60, 0x68, 0x77, 0xe9, 0x07, - 0xae, 0x43, 0xb9, 0xcd, 0x16, 0x1b, 0xc1, 0x4d, 0x09, 0x47, 0x4d, 0x41, 0xde, 0x8b, 0x66, 0x22, - 0x5b, 0x2e, 0xd2, 0xf6, 0x3a, 0xbe, 0x86, 0x3b, 0x73, 0x78, 0x30, 0x33, 0xf9, 0x66, 0x8c, 0x13, - 0x5b, 0x72, 0x98, 0xe0, 0x6d, 0xfe, 0xa4, 0x00, 0xa4, 0x5f, 0x45, 0x90, 0x15, 0x18, 0xb1, 0x1a, - 0xa1, 0xbd, 0x4b, 0xa5, 0xb3, 0xf2, 0xb9, 0xac, 0x83, 0x96, 0x10, 0x85, 0x74, 0x9b, 0xb2, 0x19, - 0x42, 0x23, 0xbd, 0x32, 0xcf, 0x8b, 0xa2, 0x64, 0x41, 0x5c, 0x98, 0xea, 0x58, 0x41, 0xa8, 0xe6, - 0x6a, 0x93, 0x35, 0x59, 0x2a, 0xd6, 0x3f, 0x76, 0xb4, 0x46, 0xb1, 0x12, 0xb5, 0xb3, 0x6c, 0xe6, - 0xde, 0x4a, 0x33, 0xc2, 0x7e, 0xde, 0xe4, 0xf7, 0x01, 0x1a, 0x6a, 0x5b, 0x65, 0xaa, 0x34, 0x27, - 0x77, 0xab, 0xde, 0xaa, 0xa3, 0xbd, 0x43, 0x83, 0x02, 0x8c, 0x89, 0x34, 0xff, 0xf1, 0x28, 0x8c, - 0x2e, 0xce, 0x2f, 0x6f, 0x5a, 0xc1, 0xce, 0x11, 0x1c, 0x9e, 0x6c, 0x76, 0xc8, 0xd3, 0x4a, 0x7a, - 0x7d, 0xab, 0x53, 0x0c, 0x6a, 0x0a, 0x72, 0x0f, 0xca, 0x96, 0x72, 0x2c, 0xcb, 0x6d, 0x62, 0x25, - 0x0f, 0x03, 0x4a, 0xb2, 0x8c, 0xfb, 0x72, 0x25, 0x08, 0x23, 0x81, 0xe4, 0xcb, 0x06, 0x54, 0x54, - 0x55, 0x98, 0x1d, 0x3c, 0x9c, 0x5b, 0x88, 0x20, 0x62, 0x2a, 0x7c, 0x3a, 0x31, 0x00, 0xc6, 0x45, - 0x92, 0x57, 0x60, 0xac, 0x49, 0x99, 0x86, 0xa1, 0x4e, 0xc3, 0xa6, 0x4c, 0x99, 0x0c, 0xb1, 0x2e, - 0x63, 0x4a, 0x75, 0x31, 0x06, 0xc7, 0x04, 0x15, 0xd9, 0x83, 0xf2, 0x9e, 0x1d, 0xb6, 0xf9, 0x46, - 0x50, 0x1d, 0xe1, 0x53, 0x62, 0xe9, 0xf1, 0x6b, 0xcd, 0xd8, 0x45, 0x3d, 0xf6, 0xa6, 0x12, 0x80, - 0x91, 0x2c, 0x66, 0x94, 0xb3, 0x3f, 0xdc, 0x31, 0xcf, 0x55, 0x48, 0x39, 0x59, 0x80, 0x23, 0x30, - 0xa2, 0x61, 0x5d, 0x3c, 0xc6, 0xfe, 0xd5, 0xe9, 0xfb, 0x3d, 0xb6, 0xae, 0xa4, 0x97, 0x27, 0x07, - 0x7f, 0xbd, 0xe2, 0x28, 0x3a, 0xeb, 0xcd, 0x98, 0x0c, 0x4c, 0x48, 0x64, 0x73, 0x76, 0xaf, 0x4d, - 0x1d, 0xe9, 0xa6, 0xd5, 0x73, 0xf6, 0xcd, 0x36, 0x75, 0x90, 0x63, 0xc8, 0x3d, 0xbe, 0xc4, 0xe4, - 0x99, 0x93, 0xfb, 0x67, 0x73, 0xf1, 0x94, 0x46, 0xe7, 0xd8, 0xda, 0x29, 0xb9, 0xbe, 0xe4, 0x7f, - 0x8c, 0xc9, 0x63, 0xc7, 0x57, 0xd7, 0xb9, 0x76, 0xd7, 0x0e, 0xab, 0x15, 0x5e, 0x43, 0xad, 0x79, - 0xd6, 0x39, 0x14, 0x25, 0x56, 0xf8, 0x37, 0xd8, 0x24, 0x08, 0xaa, 0x63, 0xc9, 0x43, 0xb4, 0x98, - 0x29, 0x01, 0x2a, 0xbc, 0xf9, 0xaf, 0x0d, 0xa8, 0xb0, 0x25, 0xab, 0x96, 0xd9, 0x0b, 0x30, 0x12, - 0x5a, 0x7e, 0x4b, 0xda, 0xfe, 0x31, 0x11, 0x9b, 0x1c, 0x8a, 0x12, 0x4b, 0x1c, 0x28, 0x86, 0x56, - 0xb0, 0xa3, 0x4e, 0x30, 0x37, 0x1e, 0xbf, 0x0f, 0xa4, 0xe2, 0x88, 0x0e, 0x2f, 0xec, 0x5f, 0x80, - 0x42, 0x0c, 0x79, 0x11, 0x4a, 0x6c, 0x93, 0x59, 0xb2, 0x02, 0xe5, 0xb3, 0x19, 0x63, 0x8a, 0x62, - 0x49, 0xc2, 0x50, 0x63, 0xcd, 0x57, 0xa1, 0x78, 0x6d, 0x97, 0x3a, 0x7c, 0xf7, 0x09, 0xa4, 0x1d, - 0x9c, 0x36, 0xfe, 0x95, 0x7d, 0x8c, 0x9a, 0xc2, 0x7c, 0x07, 0x4e, 0x5d, 0xbb, 0x4b, 0x1b, 0xbd, - 0xd0, 0xf5, 0x85, 0xbd, 0x4c, 0x6e, 0x02, 0x09, 0xa8, 0xbf, 0x6b, 0x37, 0xe8, 0x7c, 0xa3, 0xc1, - 0xac, 0x81, 0xb5, 0x48, 0x9f, 0x4d, 0x4b, 0x4e, 0xa4, 0xde, 0x47, 0x81, 0x19, 0xa5, 0xcc, 0x7f, - 0x60, 0x40, 0x25, 0xe6, 0x02, 0x64, 0xda, 0xac, 0xb5, 0x50, 0x17, 0xb6, 0x82, 0x3c, 0x72, 0xad, - 0xe4, 0xe2, 0x64, 0x14, 0x2c, 0xa3, 0xa5, 0xa6, 0x41, 0x18, 0x09, 0x7c, 0x88, 0xa3, 0xd0, 0xfc, - 0x81, 0x01, 0x51, 0x39, 0x36, 0x23, 0xb6, 0xa2, 0x7a, 0xc6, 0x66, 0x84, 0xe4, 0x2b, 0xb1, 0xe4, - 0x1e, 0x9c, 0x4f, 0x36, 0x9c, 0xfb, 0x21, 0x8e, 0xef, 0xe3, 0x11, 0xc7, 0xa3, 0x6c, 0x4e, 0x38, - 0x48, 0x84, 0x79, 0x07, 0x8a, 0xcb, 0x56, 0xaf, 0x45, 0x8f, 0x64, 0xaf, 0xb1, 0xd9, 0xe4, 0x53, - 0xab, 0x13, 0xaa, 0x1d, 0x59, 0xce, 0x26, 0x94, 0x30, 0xd4, 0x58, 0xf3, 0xfb, 0xc3, 0x50, 0x89, - 0x05, 0x18, 0x98, 0x8a, 0xf0, 0xa9, 0xe7, 0xa6, 0xb7, 0x35, 0xa4, 0x9e, 0x8b, 0x1c, 0xc3, 0xa6, - 0x9d, 0x4f, 0x77, 0xed, 0xc0, 0x76, 0x9d, 0xf4, 0xb6, 0x86, 0x12, 0x8e, 0x9a, 0x82, 0xcc, 0x40, - 0xb1, 0x49, 0xbd, 0xb0, 0xcd, 0x27, 0xf5, 0x70, 0xad, 0xcc, 0xaa, 0xba, 0xc8, 0x00, 0x28, 0xe0, - 0x8c, 0x60, 0x9b, 0x86, 0x8d, 0x76, 0x75, 0x98, 0xeb, 0x7b, 0x4e, 0xb0, 0xc4, 0x00, 0x28, 0xe0, - 0x19, 0x5e, 0xbb, 0xe2, 0xc9, 0x7b, 0xed, 0x46, 0x72, 0xf6, 0xda, 0x11, 0x0f, 0x4e, 0x07, 0x41, - 0x7b, 0xc3, 0xb7, 0x77, 0xad, 0x90, 0x46, 0x33, 0x67, 0xf4, 0x38, 0x72, 0xce, 0x1f, 0x1e, 0xcc, - 0x9c, 0xae, 0xd7, 0xaf, 0xa7, 0xb9, 0x60, 0x16, 0x6b, 0x52, 0x87, 0xb3, 0xb6, 0x13, 0xd0, 0x46, - 0xcf, 0xa7, 0x37, 0x5a, 0x8e, 0xeb, 0xd3, 0xeb, 0x6e, 0xc0, 0xd8, 0xc9, 0x88, 0x9e, 0x76, 0x45, - 0xdf, 0xc8, 0x22, 0xc2, 0xec, 0xb2, 0xe6, 0xa7, 0x06, 0x8c, 0xc5, 0x63, 0x25, 0x6c, 0x57, 0x83, - 0xf6, 0xe2, 0x52, 0x5d, 0xe8, 0x14, 0xb9, 0xd4, 0x6f, 0xe5, 0x13, 0x90, 0x11, 0x3c, 0xa3, 0x53, - 0x59, 0x04, 0xc3, 0x98, 0xcc, 0x23, 0x04, 0x96, 0x9f, 0x83, 0xe2, 0xb6, 0xeb, 0x37, 0xa8, 0xd4, - 0xac, 0x7a, 0xcd, 0x2c, 0x31, 0x20, 0x0a, 0x9c, 0xf9, 0x4b, 0x03, 0x62, 0x12, 0xc8, 0x5f, 0x31, - 0x60, 0x9c, 0x09, 0x59, 0xf1, 0xb7, 0x12, 0x6d, 0x5b, 0xcf, 0xa7, 0x6d, 0x9a, 0x6d, 0xe4, 0x2b, - 0x49, 0x80, 0x31, 0x29, 0x9c, 0xfc, 0x71, 0x28, 0x5b, 0xcd, 0xa6, 0x4f, 0x83, 0x80, 0x8a, 0x3d, - 0xa9, 0x2c, 0x7c, 0x9f, 0xf3, 0x0a, 0x88, 0x11, 0x9e, 0x2d, 0xd1, 0x76, 0x73, 0x3b, 0x60, 0xb3, - 0x5e, 0x9a, 0x88, 0x7a, 0x89, 0x32, 0x21, 0x0c, 0x8e, 0x9a, 0xc2, 0xfc, 0xda, 0x30, 0x24, 0x65, - 0x93, 0x26, 0x4c, 0xec, 0xf8, 0x5b, 0x0b, 0xdc, 0x3f, 0xfb, 0x28, 0x9e, 0xf2, 0xd3, 0x87, 0x07, - 0x33, 0x13, 0x2b, 0x49, 0x0e, 0x98, 0x66, 0x29, 0xa5, 0xac, 0xd0, 0xfd, 0xd0, 0xda, 0x7a, 0x14, - 0x45, 0xaa, 0xa4, 0xc4, 0x39, 0x60, 0x9a, 0x25, 0x79, 0x15, 0x2a, 0x3b, 0xfe, 0x96, 0x52, 0x00, - 0x69, 0xf7, 0xf4, 0x4a, 0x84, 0xc2, 0x38, 0x1d, 0xeb, 0xc2, 0x1d, 0x7f, 0x8b, 0x29, 0x4c, 0x95, - 0x71, 0xa0, 0xbb, 0x70, 0x45, 0xc2, 0x51, 0x53, 0x10, 0x0f, 0xc8, 0x8e, 0xea, 0x3d, 0xed, 0x8d, - 0x96, 0x7a, 0xea, 0xe8, 0xce, 0xec, 0x73, 0x6c, 0xc3, 0x5d, 0xe9, 0xe3, 0x83, 0x19, 0xbc, 0xc9, - 0x17, 0xe0, 0xfc, 0x8e, 0xbf, 0x25, 0xb7, 0x91, 0x0d, 0xdf, 0x76, 0x1a, 0xb6, 0x97, 0xc8, 0x2e, - 0x98, 0x91, 0xd5, 0x3d, 0xbf, 0x92, 0x4d, 0x86, 0x83, 0xca, 0x9b, 0x7f, 0x8b, 0xad, 0xf1, 0x58, - 0x20, 0xf8, 0x61, 0x11, 0xa0, 0x00, 0x46, 0xdb, 0xd4, 0x6a, 0x52, 0x5f, 0x1d, 0x96, 0xae, 0xe7, - 0xb0, 0x44, 0x38, 0xc3, 0xe8, 0x5c, 0x27, 0xfe, 0x07, 0xa8, 0x24, 0x99, 0xeb, 0x30, 0x22, 0x60, - 0x47, 0x30, 0xc4, 0xf4, 0x96, 0x59, 0x78, 0x80, 0x8b, 0xf3, 0x7b, 0x06, 0x94, 0xb9, 0x71, 0xdf, - 0x62, 0x87, 0x75, 0x5d, 0x64, 0xe8, 0x01, 0xbb, 0x6c, 0x00, 0xa3, 0xe2, 0x6c, 0x10, 0xf0, 0xcd, - 0x2b, 0x97, 0x86, 0x8b, 0xd4, 0xaf, 0xa8, 0xe1, 0xe2, 0x10, 0x12, 0xa0, 0x92, 0x64, 0xfe, 0x61, - 0x01, 0x46, 0x6e, 0x38, 0x5e, 0xef, 0x37, 0x3e, 0xfd, 0x68, 0x15, 0x86, 0x99, 0x25, 0x96, 0xcc, - 0x92, 0x1b, 0xab, 0x3d, 0x1f, 0xcf, 0x90, 0xab, 0x26, 0x33, 0xe4, 0xd0, 0xda, 0x53, 0x5e, 0x76, - 0x51, 0x26, 0x16, 0xfe, 0xec, 0xc0, 0xf0, 0x2d, 0xdb, 0xd9, 0x39, 0xda, 0x74, 0x0a, 0x1a, 0xae, - 0xd7, 0x37, 0x9d, 0xea, 0x0c, 0x88, 0x02, 0xa7, 0xd6, 0xcc, 0x50, 0xf6, 0x9a, 0x31, 0xff, 0xc0, - 0x80, 0xa9, 0x55, 0xda, 0x75, 0xed, 0x0f, 0xac, 0x28, 0x48, 0xc0, 0x0a, 0xb5, 0xed, 0x50, 0x7a, - 0xf8, 0x75, 0xa1, 0xeb, 0x76, 0x88, 0x0c, 0xfe, 0x90, 0x63, 0x2d, 0x8f, 0xa7, 0x33, 0xf5, 0xba, - 0x16, 0xe9, 0xb9, 0x28, 0x9e, 0xae, 0x10, 0x18, 0xd1, 0x98, 0x3f, 0x34, 0x60, 0x54, 0x54, 0x82, - 0x2a, 0xde, 0xc6, 0x00, 0xde, 0x6d, 0x28, 0xf2, 0x72, 0x52, 0x43, 0x2f, 0xe7, 0x60, 0x12, 0x32, - 0x76, 0xe2, 0xb8, 0xc7, 0x7f, 0xa2, 0x10, 0xc0, 0x8e, 0xe3, 0x5d, 0xeb, 0xee, 0xbc, 0x8e, 0x8f, - 0xe8, 0xe3, 0xf8, 0x2a, 0x87, 0xa2, 0xc4, 0x9a, 0xdf, 0x19, 0x82, 0x92, 0x72, 0x7e, 0x91, 0x6f, - 0x18, 0x50, 0xb1, 0x1c, 0xc7, 0x0d, 0x2d, 0xe1, 0x1b, 0x12, 0x6b, 0xe1, 0xed, 0xc7, 0xaf, 0xa5, - 0x92, 0x30, 0x3b, 0x1f, 0x71, 0xbf, 0xe6, 0x84, 0xfe, 0x7e, 0xb4, 0x85, 0xc4, 0x30, 0x18, 0xaf, - 0x04, 0xf9, 0x12, 0x8c, 0x74, 0xac, 0x2d, 0xda, 0x51, 0x4b, 0xe3, 0x4e, 0x8e, 0xd5, 0xb9, 0xc5, - 0x19, 0x8b, 0x9a, 0xe8, 0x1e, 0x12, 0x40, 0x94, 0x52, 0xa7, 0x7f, 0x17, 0x26, 0xd3, 0xb5, 0x26, - 0x93, 0xb1, 0x61, 0x16, 0x23, 0x7b, 0x26, 0xa1, 0x1c, 0xd5, 0xba, 0x28, 0xbc, 0x66, 0x4c, 0xff, - 0x29, 0xa8, 0xc4, 0xc4, 0x1c, 0xa7, 0xa8, 0xf9, 0x06, 0x54, 0x56, 0x69, 0xe8, 0xdb, 0x0d, 0xce, - 0xe0, 0x61, 0x93, 0xeb, 0x48, 0xfa, 0xf9, 0x8f, 0xf8, 0x64, 0x65, 0x3c, 0x03, 0x72, 0x0f, 0xc0, - 0xf3, 0xdd, 0x2e, 0x0d, 0xdb, 0xb4, 0xa7, 0x06, 0x3b, 0x87, 0x33, 0xe7, 0x86, 0xe6, 0x29, 0xbc, - 0x14, 0xd1, 0x7f, 0x8c, 0xc9, 0x33, 0x2f, 0x43, 0x71, 0xb5, 0x17, 0xd2, 0xbb, 0x0f, 0x57, 0x15, - 0xe6, 0xdb, 0x30, 0xc6, 0x49, 0xaf, 0xbb, 0x1d, 0xa6, 0x85, 0x58, 0x4b, 0xbb, 0xec, 0x7f, 0xda, - 0x78, 0xe3, 0x44, 0x28, 0x70, 0x6c, 0x05, 0xb4, 0xdd, 0x4e, 0x93, 0xfa, 0xb2, 0x3f, 0xf4, 0xf8, - 0x5e, 0xe7, 0x50, 0x94, 0x58, 0xf3, 0x2f, 0x14, 0xa0, 0xc2, 0x0b, 0x4a, 0xed, 0xb1, 0x0f, 0xa3, - 0x6d, 0x21, 0x47, 0x76, 0x49, 0x0e, 0x41, 0x8e, 0x78, 0xed, 0x63, 0xbb, 0xb1, 0x00, 0xa0, 0x92, - 0xc7, 0x44, 0xef, 0x59, 0x76, 0xc8, 0x44, 0x17, 0x4e, 0x56, 0xf4, 0x9b, 0x42, 0x0c, 0x2a, 0x79, - 0xe6, 0x7f, 0x9d, 0x00, 0x58, 0x73, 0x9b, 0x54, 0x76, 0xc2, 0x34, 0x14, 0xec, 0xa6, 0xec, 0x5e, - 0x90, 0x85, 0x0a, 0x37, 0x16, 0xb1, 0x60, 0x37, 0xf5, 0x78, 0x15, 0x06, 0xaa, 0xf6, 0x57, 0xa1, - 0xd2, 0xb4, 0x03, 0xaf, 0x63, 0xed, 0xaf, 0x65, 0x1c, 0x16, 0x17, 0x23, 0x14, 0xc6, 0xe9, 0xc8, - 0x4b, 0x32, 0xce, 0x2c, 0x0e, 0x8a, 0xd5, 0x54, 0x9c, 0xb9, 0xc4, 0xaa, 0x17, 0x0b, 0x31, 0xbf, - 0x06, 0x63, 0xca, 0xef, 0xc9, 0xa5, 0x14, 0x79, 0xa9, 0x33, 0x2a, 0x82, 0xb4, 0x19, 0xc3, 0x61, - 0x82, 0xb2, 0xcf, 0x4b, 0x3b, 0xf2, 0xe4, 0xbd, 0xb4, 0xaf, 0xc3, 0xb8, 0xfa, 0xcb, 0xf7, 0xbb, - 0xea, 0x19, 0x5e, 0x7b, 0x6d, 0xc4, 0x6c, 0xc6, 0x91, 0x98, 0xa4, 0x25, 0xbf, 0x03, 0x45, 0xaf, - 0x6d, 0x05, 0x54, 0xfa, 0x4b, 0x95, 0x93, 0xa9, 0xb8, 0xc1, 0x80, 0xf7, 0x0f, 0x66, 0xca, 0xac, - 0xa7, 0xf8, 0x1f, 0x14, 0x84, 0xe4, 0x0a, 0xc0, 0x96, 0xdb, 0x73, 0x9a, 0x96, 0xbf, 0x7f, 0x63, - 0x51, 0xc6, 0x58, 0xf4, 0xa9, 0xa4, 0xa6, 0x31, 0x18, 0xa3, 0x8a, 0x87, 0xd8, 0xcb, 0x0f, 0x0e, - 0xb1, 0x93, 0xb7, 0xa1, 0xcc, 0xe3, 0x51, 0xb4, 0x39, 0x1f, 0x4a, 0x6f, 0xe7, 0x71, 0x42, 0x17, - 0x7a, 0x7b, 0xad, 0x2b, 0x26, 0x18, 0xf1, 0x23, 0xef, 0x02, 0x6c, 0xdb, 0x8e, 0x1d, 0xb4, 0x39, - 0xf7, 0xca, 0xb1, 0xb9, 0xeb, 0x76, 0x2e, 0x69, 0x2e, 0x18, 0xe3, 0x48, 0xde, 0x81, 0x29, 0x1a, - 0x84, 0x76, 0xd7, 0x0a, 0x69, 0x53, 0xa7, 0xdf, 0x54, 0x79, 0x08, 0x4e, 0x47, 0x04, 0xaf, 0xa5, - 0x09, 0xee, 0x67, 0x01, 0xb1, 0x9f, 0x11, 0x79, 0x0d, 0x4a, 0x9e, 0xef, 0xb6, 0x98, 0x45, 0x59, - 0x9d, 0xe6, 0xdd, 0x78, 0x41, 0x19, 0x40, 0x1b, 0x12, 0x7e, 0x3f, 0xf6, 0x1b, 0x35, 0x35, 0xf9, - 0x95, 0x01, 0x53, 0x3e, 0x0d, 0xdc, 0x9e, 0xdf, 0xa0, 0x81, 0xae, 0xd8, 0x59, 0xae, 0x17, 0x1a, - 0x79, 0xdc, 0x04, 0x50, 0x8b, 0x7d, 0x16, 0xd3, 0x52, 0xc4, 0x86, 0x48, 0x55, 0xeb, 0xfb, 0xf0, - 0xf7, 0xb3, 0x80, 0x7f, 0xf0, 0xb3, 0x99, 0x99, 0xfe, 0x6b, 0x29, 0x9a, 0x39, 0x5b, 0x79, 0x7f, - 0xf9, 0x67, 0x33, 0x93, 0xea, 0x7f, 0xd4, 0x69, 0x7d, 0x8d, 0x64, 0xfa, 0xdd, 0x73, 0x9b, 0x37, - 0x36, 0xa4, 0x5b, 0x5a, 0xeb, 0xf7, 0x0d, 0x06, 0x44, 0x81, 0x23, 0x2f, 0x42, 0xa9, 0x69, 0xd1, - 0xae, 0xeb, 0xd0, 0x66, 0x75, 0x3c, 0x72, 0xce, 0x2d, 0x4a, 0x18, 0x6a, 0x2c, 0xe9, 0xc0, 0x88, - 0xcd, 0x8f, 0xfa, 0xd5, 0x53, 0x7c, 0xf6, 0xe4, 0x60, 0x5f, 0x08, 0xd3, 0x41, 0x24, 0x72, 0x89, - 0xdf, 0x28, 0x65, 0x10, 0x0f, 0x46, 0xdd, 0x5e, 0xc8, 0xc5, 0x4d, 0x70, 0x71, 0x39, 0x38, 0xbd, - 0xd7, 0x05, 0x43, 0x91, 0x67, 0x2e, 0xff, 0xa0, 0x12, 0xc3, 0x7a, 0xa2, 0xd1, 0xb6, 0x3b, 0x4d, - 0x9f, 0x3a, 0xd5, 0x49, 0xee, 0xd3, 0xe0, 0x3d, 0xb1, 0x20, 0x61, 0xa8, 0xb1, 0xe4, 0x4f, 0xc2, - 0xb8, 0xdb, 0x0b, 0xf9, 0x22, 0x67, 0xe3, 0x1f, 0x54, 0xa7, 0x38, 0xf9, 0x14, 0xcf, 0x31, 0x89, - 0x23, 0x30, 0x49, 0xc7, 0x94, 0x6d, 0xdb, 0x0d, 0x42, 0xf6, 0x87, 0x2b, 0xdb, 0x73, 0x49, 0x65, - 0x7b, 0x3d, 0x86, 0xc3, 0x04, 0x25, 0xf9, 0xc4, 0x80, 0xa9, 0x6e, 0xfa, 0x88, 0x5e, 0x3d, 0xcf, - 0x7b, 0xa6, 0x9e, 0xc7, 0x51, 0x2e, 0xc5, 0x5a, 0x04, 0x42, 0xfb, 0xc0, 0xd8, 0x5f, 0x09, 0x9e, - 0xbf, 0x1a, 0xec, 0x3b, 0x8d, 0xb6, 0xef, 0x3a, 0xc9, 0xea, 0x3d, 0xcd, 0xab, 0xf7, 0x76, 0x4e, - 0xab, 0x2c, 0x4b, 0x44, 0xed, 0xe9, 0xc3, 0x83, 0x99, 0xb3, 0x99, 0x28, 0xcc, 0xae, 0xd4, 0xf4, - 0x22, 0x9c, 0xcb, 0x5e, 0xa9, 0x0f, 0x3b, 0x53, 0x0e, 0xc5, 0xcf, 0x94, 0x4b, 0xf0, 0xf4, 0xc0, - 0x4a, 0x31, 0x9d, 0xaf, 0x0e, 0x20, 0x46, 0x52, 0xe7, 0xf7, 0x1d, 0x18, 0x4e, 0xc1, 0x58, 0xfc, - 0x32, 0x11, 0x0f, 0x5d, 0xc4, 0xf2, 0xa4, 0xc9, 0x3d, 0x28, 0xbb, 0xf5, 0xdc, 0x43, 0x17, 0xeb, - 0xf5, 0xbe, 0xd0, 0x85, 0x06, 0x61, 0x24, 0xf0, 0x61, 0xa1, 0x8b, 0xaf, 0x0e, 0x41, 0x54, 0x8e, - 0xbc, 0x04, 0x25, 0xea, 0x34, 0x3d, 0xd7, 0x76, 0xc2, 0x74, 0x04, 0xe8, 0x9a, 0x84, 0xa3, 0xa6, - 0x88, 0x05, 0x3a, 0x0a, 0x0f, 0x0c, 0x74, 0x34, 0x61, 0xc2, 0xe2, 0x69, 0x14, 0x91, 0x9b, 0x7a, - 0xe8, 0xd8, 0x7e, 0xb9, 0xf9, 0x24, 0x07, 0x4c, 0xb3, 0x64, 0x52, 0x82, 0xa8, 0x28, 0x97, 0x32, - 0x7c, 0x6c, 0x29, 0xf5, 0x24, 0x07, 0x4c, 0xb3, 0x24, 0xef, 0x40, 0xb5, 0xc1, 0x13, 0xd7, 0x44, - 0x1b, 0x6f, 0x6c, 0xaf, 0xb9, 0xe1, 0x86, 0x4f, 0x03, 0xea, 0x88, 0x30, 0x42, 0xa9, 0x76, 0x49, - 0xf6, 0x42, 0x75, 0x61, 0x00, 0x1d, 0x0e, 0xe4, 0x60, 0xfe, 0xdb, 0x02, 0x28, 0xa5, 0xf6, 0x9b, - 0xed, 0x8c, 0x21, 0x26, 0x8c, 0xf8, 0x34, 0x50, 0x09, 0xe7, 0x65, 0xb1, 0xbf, 0x20, 0x87, 0xa0, - 0xc4, 0x30, 0x6d, 0x4f, 0xef, 0xda, 0xe1, 0x82, 0xdb, 0x54, 0x27, 0x65, 0xae, 0xed, 0xaf, 0x49, - 0x18, 0x6a, 0xac, 0xf9, 0x17, 0x0d, 0x18, 0x67, 0xad, 0xec, 0x74, 0x68, 0xa7, 0x1e, 0x52, 0x2f, - 0x20, 0x01, 0x14, 0x03, 0xf6, 0x23, 0x3f, 0xcb, 0x26, 0xca, 0x8c, 0xa1, 0x5e, 0xcc, 0x87, 0xc3, - 0x84, 0xa0, 0x90, 0x65, 0xfe, 0xf7, 0x02, 0x94, 0x75, 0x67, 0x1f, 0xc1, 0x31, 0x74, 0x25, 0x4a, - 0xbb, 0x17, 0x2b, 0xac, 0x1a, 0x4b, 0xb9, 0x67, 0xc7, 0xdb, 0x79, 0x67, 0x5f, 0x24, 0x52, 0xeb, - 0xfc, 0x7b, 0xf2, 0x52, 0xd2, 0xd1, 0x78, 0x2e, 0xee, 0xbd, 0x8a, 0xd1, 0x4b, 0x8f, 0xe3, 0x5d, - 0x28, 0xf3, 0x1f, 0x4b, 0xea, 0x22, 0x5c, 0x2e, 0x73, 0xec, 0x8e, 0x62, 0x29, 0x42, 0x0a, 0xfa, - 0x2f, 0x46, 0xc2, 0x52, 0x17, 0xd8, 0x8a, 0x47, 0xba, 0xc0, 0x76, 0x19, 0x86, 0xa9, 0xd3, 0xeb, - 0xf2, 0xb4, 0x8c, 0x32, 0xdf, 0xde, 0x86, 0xaf, 0x39, 0xbd, 0x6e, 0xb2, 0x65, 0x9c, 0xc4, 0xfc, - 0xa7, 0x06, 0xb0, 0x43, 0xd2, 0xf2, 0x02, 0xf9, 0x33, 0x50, 0x0a, 0xa4, 0x6a, 0x96, 0x5d, 0xfd, - 0x5b, 0x3a, 0xaa, 0x2d, 0xe1, 0xf7, 0x0f, 0x66, 0xc6, 0x39, 0xb1, 0x02, 0xa0, 0x2e, 0x42, 0x3a, - 0x30, 0xce, 0xdd, 0x1f, 0x4a, 0x4f, 0x48, 0x87, 0xd5, 0xd5, 0x23, 0x26, 0x37, 0xc6, 0x8b, 0x8a, - 0xd3, 0x45, 0x02, 0x84, 0x49, 0xe6, 0xe6, 0x3f, 0x1b, 0x86, 0x98, 0x97, 0xe0, 0x08, 0x53, 0xe4, - 0xfd, 0x94, 0x4f, 0x68, 0x35, 0x17, 0x9f, 0x90, 0x72, 0xb4, 0x88, 0x65, 0x97, 0x74, 0x03, 0xb1, - 0x4a, 0xb5, 0x69, 0xc7, 0x93, 0x13, 0x4c, 0x57, 0xea, 0x3a, 0xed, 0x78, 0xc8, 0x31, 0x3a, 0x2d, - 0x64, 0x78, 0x60, 0x5a, 0x48, 0x1b, 0x8a, 0x2d, 0xab, 0xd7, 0xa2, 0x32, 0xa4, 0x91, 0x83, 0xfb, - 0x8f, 0x07, 0xb3, 0x85, 0xfb, 0x8f, 0xff, 0x44, 0x21, 0x80, 0xcd, 0xf0, 0xb6, 0xf2, 0xc2, 0x4b, - 0xfb, 0x36, 0x87, 0x19, 0xae, 0x1d, 0xfb, 0x62, 0x86, 0xeb, 0xbf, 0x18, 0x09, 0x63, 0xc7, 0xdf, - 0x86, 0xc8, 0x89, 0x96, 0x51, 0xd9, 0x1b, 0x79, 0xe4, 0xbd, 0x70, 0x86, 0xe2, 0xf8, 0x2b, 0xff, - 0xa0, 0x12, 0x63, 0xce, 0x41, 0x25, 0x76, 0x15, 0x8c, 0x0d, 0x83, 0x4e, 0xc7, 0x8d, 0x0d, 0xc3, - 0xa2, 0x15, 0x5a, 0xc8, 0x31, 0xe6, 0xdf, 0x1c, 0x02, 0x6d, 0x86, 0xc4, 0x33, 0x5a, 0xac, 0x46, - 0xec, 0x06, 0x48, 0x22, 0x5d, 0xcf, 0x75, 0x50, 0x62, 0x99, 0xe5, 0xde, 0xa5, 0x7e, 0x4b, 0x1f, - 0x7c, 0xa4, 0x8e, 0xd2, 0x96, 0xfb, 0x6a, 0x1c, 0x89, 0x49, 0x5a, 0x76, 0xd2, 0xe8, 0x5a, 0x8e, - 0xbd, 0x4d, 0x83, 0x30, 0x1d, 0x51, 0x5c, 0x95, 0x70, 0xd4, 0x14, 0x64, 0x19, 0xa6, 0x02, 0x1a, - 0xae, 0xef, 0x39, 0xd4, 0xd7, 0x69, 0x84, 0x32, 0xaf, 0xf4, 0x69, 0x65, 0x9b, 0xd5, 0xd3, 0x04, - 0xd8, 0x5f, 0x86, 0x2c, 0xc2, 0xa4, 0x4c, 0xe9, 0xd4, 0x19, 0x79, 0x52, 0xf7, 0xe8, 0xcb, 0xb7, - 0xf5, 0x14, 0x1e, 0xfb, 0x4a, 0x30, 0x2e, 0xdb, 0x96, 0xdd, 0xe9, 0xf9, 0x34, 0xe2, 0x32, 0x92, - 0xe4, 0xb2, 0x94, 0xc2, 0x63, 0x5f, 0x09, 0x9e, 0xa8, 0xd0, 0xb1, 0x5a, 0x41, 0x75, 0x34, 0x96, - 0xa8, 0xc0, 0x00, 0x28, 0xe0, 0xe6, 0x3f, 0x34, 0x60, 0x1c, 0x69, 0xe8, 0xef, 0xcf, 0x6f, 0x33, - 0x2b, 0x3d, 0xdc, 0x27, 0xdf, 0x36, 0x60, 0xd2, 0x71, 0x9b, 0x74, 0xde, 0x09, 0x6d, 0x05, 0xcc, - 0xef, 0x8a, 0x19, 0x97, 0xb5, 0x96, 0x62, 0x2f, 0xb2, 0x43, 0xd3, 0x50, 0xec, 0xab, 0x86, 0x79, - 0x1e, 0xce, 0x66, 0x32, 0x30, 0xbf, 0x3b, 0x24, 0x9b, 0xa1, 0x07, 0xff, 0x0d, 0x28, 0x76, 0x78, - 0xa6, 0xac, 0xf1, 0x88, 0xd7, 0x86, 0x78, 0x5f, 0x89, 0x54, 0x5a, 0xc1, 0x89, 0x2c, 0x42, 0xc5, - 0x67, 0x32, 0x64, 0x1e, 0xb3, 0x98, 0x8a, 0x66, 0x74, 0x11, 0x58, 0xa3, 0xee, 0x27, 0xff, 0x62, - 0xbc, 0x18, 0xf9, 0x10, 0x46, 0xb7, 0xc4, 0x4d, 0x28, 0x79, 0x42, 0xcd, 0x61, 0xc9, 0xca, 0xab, - 0x55, 0x7c, 0x27, 0x56, 0xf7, 0xac, 0xee, 0x47, 0x3f, 0x51, 0x49, 0x24, 0xfb, 0x50, 0xb2, 0xd4, - 0x98, 0x0e, 0xe7, 0x95, 0x1a, 0x90, 0x98, 0x3f, 0xe2, 0x7c, 0xa4, 0xc7, 0x50, 0x8b, 0x33, 0xbf, - 0x67, 0x00, 0x44, 0x97, 0x8f, 0xc9, 0x5d, 0x28, 0x05, 0x57, 0x13, 0x06, 0x4b, 0x1e, 0x49, 0x85, - 0x92, 0x63, 0x2c, 0xa9, 0x4c, 0x42, 0x50, 0x4b, 0x7b, 0x98, 0xb5, 0xf2, 0xcd, 0x22, 0xe8, 0x52, - 0x27, 0x64, 0xac, 0xbc, 0xc0, 0x0e, 0x9e, 0xad, 0xe8, 0xe2, 0x99, 0xa6, 0x43, 0x0e, 0x45, 0x89, - 0x65, 0x87, 0x4f, 0x95, 0xd1, 0x22, 0x35, 0x11, 0xef, 0x5c, 0x95, 0xfc, 0x82, 0x1a, 0x9b, 0x65, - 0xfe, 0x14, 0x9f, 0x88, 0xf9, 0x33, 0x92, 0xbf, 0xf9, 0x73, 0x19, 0x46, 0x7d, 0xb7, 0x43, 0xe7, - 0x71, 0x4d, 0xba, 0x5c, 0xb5, 0x59, 0x8c, 0x02, 0x8c, 0x0a, 0x4f, 0x5e, 0x85, 0x4a, 0x2f, 0xa0, - 0xf5, 0xc5, 0x95, 0x05, 0x9f, 0x36, 0x03, 0x99, 0x24, 0xa4, 0x5d, 0xdf, 0xb7, 0x23, 0x14, 0xc6, - 0xe9, 0xc8, 0x0f, 0x8c, 0x07, 0x58, 0x58, 0xe5, 0xbc, 0x54, 0x5d, 0xe6, 0xe5, 0xa3, 0xda, 0x85, - 0x47, 0x34, 0xdb, 0x3e, 0x36, 0xe0, 0x54, 0xbd, 0xe1, 0xdb, 0x5e, 0xa8, 0x37, 0xd1, 0x35, 0x7e, - 0x09, 0x31, 0xb4, 0x98, 0x2e, 0x93, 0x6b, 0xe8, 0xd9, 0x01, 0x79, 0x1b, 0x82, 0x28, 0x71, 0x55, - 0x59, 0x80, 0x30, 0x62, 0xc1, 0xa6, 0xa5, 0xd8, 0xa6, 0xd3, 0xd3, 0xb7, 0xce, 0xa1, 0x28, 0xb1, - 0xe6, 0x7b, 0x30, 0x59, 0xa7, 0x5d, 0xcb, 0x6b, 0xf3, 0x1c, 0x2b, 0x11, 0x4c, 0x99, 0x83, 0x72, - 0xa0, 0x60, 0xe9, 0x7b, 0xd1, 0x9a, 0x18, 0x23, 0x1a, 0xf2, 0xbc, 0x08, 0xfc, 0xa8, 0x04, 0x8c, - 0xb2, 0x38, 0x6e, 0x88, 0x68, 0x51, 0x80, 0x0a, 0x67, 0xee, 0xc1, 0x58, 0x54, 0x9c, 0x6e, 0x93, - 0x16, 0x4c, 0x34, 0x62, 0x69, 0x28, 0xd1, 0xf5, 0xe7, 0xa3, 0x67, 0xac, 0xf0, 0x59, 0xb8, 0x90, - 0x64, 0x82, 0x69, 0xae, 0xe6, 0xd7, 0x0b, 0x30, 0xa1, 0x25, 0x4b, 0x87, 0xcd, 0x47, 0xe9, 0x60, - 0x15, 0xe6, 0x91, 0x07, 0x9d, 0xec, 0xc9, 0x07, 0x04, 0xac, 0x3e, 0x4a, 0x07, 0xac, 0x4e, 0x54, - 0x7c, 0x9f, 0x0f, 0xea, 0x7b, 0x05, 0x28, 0xe9, 0xac, 0xec, 0x37, 0xa0, 0xc8, 0x4f, 0x84, 0x8f, - 0xb7, 0xbd, 0xf2, 0xd3, 0x25, 0x0a, 0x4e, 0x8c, 0x25, 0x8f, 0x43, 0x3c, 0xf2, 0x45, 0xdf, 0xb2, - 0x30, 0x86, 0x2d, 0x3f, 0x44, 0xc1, 0x89, 0xac, 0xc0, 0x10, 0x75, 0x9a, 0x72, 0x9f, 0x3d, 0x3e, - 0x43, 0xfe, 0x26, 0xc0, 0x35, 0xa7, 0x89, 0x8c, 0x0b, 0xbf, 0xa7, 0xe8, 0xfa, 0x5d, 0x2b, 0x94, - 0x36, 0x47, 0x74, 0x4f, 0x91, 0x43, 0x51, 0x62, 0xcd, 0xaf, 0x0e, 0xc1, 0x48, 0xbd, 0xb7, 0xc5, - 0x4e, 0x0c, 0x7f, 0xc7, 0x80, 0xd3, 0x7b, 0xa9, 0x4b, 0xa0, 0xd1, 0x94, 0xbd, 0x9d, 0xff, 0x0d, - 0x5b, 0xa4, 0xdb, 0xb5, 0x67, 0x64, 0xbd, 0x4e, 0x67, 0x20, 0x31, 0xab, 0x3a, 0x89, 0x2b, 0x8c, - 0x43, 0x27, 0x74, 0xb5, 0x38, 0x76, 0x51, 0xa4, 0x90, 0xff, 0x45, 0x91, 0xf1, 0x41, 0x97, 0x44, - 0xcc, 0x7f, 0x31, 0x0c, 0x20, 0x46, 0x63, 0xdd, 0x0b, 0x8f, 0x62, 0xed, 0xbe, 0x06, 0x63, 0xea, - 0x75, 0xab, 0xb5, 0x28, 0xf0, 0xaa, 0x9d, 0xef, 0xcb, 0x31, 0x1c, 0x26, 0x28, 0xc9, 0x15, 0x00, - 0xea, 0x84, 0xfe, 0xbe, 0x38, 0x2e, 0x0c, 0x27, 0xdd, 0x0d, 0xd7, 0x34, 0x06, 0x63, 0x54, 0x64, - 0x36, 0xe1, 0x81, 0x13, 0xd7, 0x47, 0x4e, 0x3d, 0xc0, 0x61, 0xf6, 0x3a, 0x8c, 0xeb, 0x7f, 0x4b, - 0x76, 0x47, 0x25, 0xce, 0x69, 0x83, 0x68, 0x23, 0x8e, 0xc4, 0x24, 0x2d, 0xf9, 0x5d, 0x38, 0x95, - 0x4c, 0xd5, 0x96, 0x1b, 0xec, 0x39, 0x59, 0xfa, 0x54, 0x32, 0xc3, 0x1b, 0x53, 0xd4, 0x6c, 0x05, - 0x34, 0xfd, 0x7d, 0xec, 0x39, 0x72, 0xa7, 0xd5, 0x2b, 0x60, 0x91, 0x43, 0x51, 0x62, 0x59, 0x17, - 0xb2, 0x92, 0xd4, 0x17, 0x70, 0xbe, 0xa5, 0x96, 0xa2, 0x2e, 0xac, 0xc7, 0x70, 0x98, 0xa0, 0x64, - 0x12, 0xa4, 0xab, 0x01, 0x92, 0x6b, 0x2c, 0xe5, 0x1f, 0xf0, 0xe0, 0x94, 0x9b, 0xb4, 0xd4, 0x44, - 0xa8, 0xf2, 0x95, 0x23, 0xce, 0xdb, 0x44, 0x59, 0x91, 0x0b, 0x9d, 0x32, 0xec, 0x52, 0xfc, 0xcd, - 0xd3, 0x30, 0x55, 0xef, 0x79, 0x5e, 0xc7, 0xa6, 0x4d, 0xed, 0x6b, 0x32, 0x7f, 0x0f, 0x26, 0xe4, - 0x55, 0x43, 0xbd, 0x29, 0x1f, 0xeb, 0x75, 0x03, 0xf3, 0x57, 0x06, 0x4c, 0xa4, 0x82, 0x03, 0xe4, - 0xc3, 0xf4, 0x56, 0x9a, 0x8b, 0xeb, 0x30, 0xbe, 0x8b, 0x8a, 0xe5, 0x92, 0xb9, 0x2d, 0xb7, 0x55, - 0xb2, 0x47, 0x6e, 0x39, 0x53, 0x3c, 0x25, 0x42, 0xe8, 0xe6, 0x78, 0xc6, 0x88, 0xf9, 0x47, 0x05, - 0xc8, 0x8e, 0xc8, 0x90, 0x2f, 0xf5, 0x77, 0xc0, 0x1b, 0x39, 0x76, 0x80, 0x0c, 0x09, 0x0d, 0xee, - 0x03, 0x27, 0xd9, 0x07, 0xab, 0x39, 0xf5, 0x81, 0x94, 0xdb, 0xdf, 0x13, 0xff, 0xcb, 0x80, 0xca, - 0xe6, 0xe6, 0x2d, 0x6d, 0xba, 0x22, 0x9c, 0x0b, 0xc4, 0x05, 0xd3, 0xf9, 0xed, 0x90, 0xfa, 0x0b, - 0x6e, 0xd7, 0xeb, 0x50, 0x3d, 0xa1, 0xe4, 0xad, 0xcf, 0x7a, 0x26, 0x05, 0x0e, 0x28, 0x49, 0x6e, - 0xc0, 0xe9, 0x38, 0x46, 0x3a, 0x20, 0x78, 0x0b, 0x8b, 0x32, 0x47, 0xbf, 0x1f, 0x8d, 0x59, 0x65, - 0xd2, 0xac, 0xa4, 0x17, 0x42, 0x3e, 0x80, 0xd6, 0xc7, 0x4a, 0xa2, 0x31, 0xab, 0x8c, 0xb9, 0x0e, - 0x95, 0xd8, 0x73, 0x7c, 0xe4, 0xf3, 0x30, 0xd9, 0x70, 0xbb, 0x9e, 0x4f, 0x83, 0xc0, 0x76, 0x9d, - 0x5b, 0x74, 0x97, 0x76, 0x64, 0x93, 0xb9, 0x83, 0x60, 0x21, 0x85, 0xc3, 0x3e, 0x6a, 0xf3, 0xff, - 0x4e, 0x83, 0xbe, 0xa7, 0x78, 0x04, 0x5d, 0xef, 0xe9, 0x58, 0x75, 0x31, 0xe7, 0x58, 0xb5, 0x56, - 0x5c, 0xa9, 0x78, 0x75, 0x18, 0xc5, 0xab, 0x47, 0xf2, 0x8e, 0x57, 0xeb, 0xa3, 0x5b, 0x5f, 0xcc, - 0xfa, 0x5b, 0x06, 0x8c, 0x39, 0x6e, 0x93, 0x6a, 0x07, 0xf3, 0x28, 0x3f, 0x3f, 0xbe, 0x93, 0x5f, - 0x12, 0x8e, 0x88, 0xbd, 0x4a, 0xf6, 0x22, 0xa3, 0x41, 0xeb, 0xfb, 0x38, 0x0a, 0x13, 0xf5, 0x20, - 0x4b, 0x31, 0x7f, 0x84, 0xb8, 0x5a, 0x78, 0x21, 0xeb, 0x1c, 0xff, 0x30, 0xe7, 0x02, 0xb9, 0x1b, - 0x3b, 0xc1, 0x94, 0xf3, 0xf2, 0x26, 0xa8, 0xc4, 0xc5, 0x98, 0xdb, 0x50, 0x5d, 0x5c, 0x8e, 0x4e, - 0x36, 0x26, 0x8c, 0x88, 0xd4, 0x07, 0xf9, 0x30, 0x1c, 0xf7, 0x66, 0x8b, 0xb4, 0x08, 0x94, 0x18, - 0x12, 0xaa, 0x40, 0x50, 0x85, 0x77, 0xfb, 0x7a, 0x3e, 0x11, 0x36, 0x1d, 0x68, 0xca, 0x8e, 0x04, - 0x91, 0x9b, 0x71, 0xf3, 0x70, 0xec, 0x28, 0xe6, 0xe1, 0xf8, 0x40, 0xd3, 0x30, 0x84, 0x91, 0x80, - 0x1b, 0x9f, 0x3c, 0xf9, 0xa3, 0x72, 0x65, 0x23, 0x07, 0x7d, 0x9c, 0x30, 0x66, 0x45, 0xbf, 0x09, - 0x18, 0x4a, 0x59, 0xe4, 0x1e, 0x94, 0x54, 0xba, 0x8a, 0x4c, 0x26, 0xc1, 0x3c, 0xbc, 0x55, 0x49, - 0x5f, 0xb4, 0xba, 0x65, 0x26, 0xa0, 0xa8, 0x25, 0x92, 0x36, 0x0c, 0x35, 0xad, 0x96, 0x4c, 0x2b, - 0x59, 0xcd, 0xe7, 0x2e, 0xa5, 0x92, 0xc9, 0x2d, 0x8b, 0xc5, 0xf9, 0x65, 0x64, 0x22, 0xc8, 0xdd, - 0xe8, 0x21, 0x83, 0xc9, 0xdc, 0xb6, 0xbb, 0xe4, 0xb9, 0x44, 0x98, 0xd7, 0x7d, 0xef, 0x22, 0x5c, - 0x83, 0xd1, 0x5d, 0xb7, 0xd3, 0xeb, 0xca, 0xe4, 0x94, 0xca, 0x95, 0xe9, 0xac, 0x19, 0x72, 0x87, - 0x93, 0x44, 0xfa, 0x45, 0xfc, 0x0f, 0x50, 0x95, 0x25, 0x5f, 0x37, 0xe0, 0x14, 0x5b, 0x88, 0x7a, - 0xee, 0x04, 0x55, 0x92, 0xd7, 0x54, 0xbf, 0x1d, 0xb0, 0x8d, 0x4c, 0x4d, 0x51, 0x7d, 0x54, 0xbd, - 0x91, 0x10, 0x87, 0x29, 0xf1, 0xe4, 0x23, 0x28, 0x05, 0x76, 0x93, 0x36, 0x2c, 0x3f, 0xa8, 0x9e, - 0x3e, 0x99, 0xaa, 0x44, 0x3e, 0x46, 0x29, 0x08, 0xb5, 0x48, 0xf2, 0xd7, 0xf9, 0x03, 0x63, 0xf2, - 0x11, 0x47, 0xf9, 0xa8, 0xe7, 0x99, 0x13, 0x7b, 0xd4, 0x53, 0x78, 0xef, 0x92, 0xe2, 0x30, 0x2d, - 0x9f, 0xfc, 0x79, 0x03, 0xce, 0x8a, 0x57, 0x10, 0xd2, 0x4f, 0x60, 0x9c, 0x7d, 0x44, 0xfb, 0x98, - 0x67, 0xd5, 0xcc, 0x67, 0xb1, 0xc4, 0x6c, 0x49, 0xe4, 0x63, 0x03, 0xc6, 0xfd, 0xb8, 0x9f, 0x9e, - 0xe7, 0x36, 0xe5, 0xe7, 0x85, 0xd6, 0x6f, 0x84, 0xf2, 0x30, 0x68, 0x02, 0x84, 0x49, 0xc1, 0xe4, - 0x65, 0xa8, 0x78, 0x52, 0x8b, 0xda, 0x41, 0x97, 0xe7, 0x48, 0x0d, 0x89, 0x3c, 0xd2, 0x8d, 0x08, - 0x8c, 0x71, 0x1a, 0x72, 0x1b, 0x2a, 0xa1, 0xdb, 0xa1, 0xbe, 0x4c, 0xd8, 0xaf, 0xf2, 0x79, 0x75, - 0x31, 0x6b, 0xc5, 0x6c, 0x6a, 0xb2, 0xc8, 0x1d, 0x19, 0xc1, 0x02, 0x8c, 0xf3, 0x61, 0x36, 0x9d, - 0x7a, 0x31, 0xc5, 0xe7, 0x26, 0xe7, 0xd3, 0x49, 0x9b, 0xae, 0x1e, 0x47, 0x62, 0x92, 0x96, 0x2c, - 0xc3, 0x94, 0xe7, 0xdb, 0xae, 0x6f, 0x87, 0xfb, 0x0b, 0x1d, 0x2b, 0x08, 0x38, 0x03, 0x91, 0xfb, - 0xa8, 0xc3, 0x56, 0x1b, 0x69, 0x02, 0xec, 0x2f, 0x43, 0x5e, 0x84, 0x92, 0x02, 0x56, 0x9f, 0xe1, - 0x87, 0xae, 0x31, 0x91, 0x37, 0x29, 0x60, 0xa8, 0xb1, 0x03, 0xee, 0x60, 0x5f, 0x78, 0x94, 0x3b, - 0xd8, 0xa4, 0x09, 0x17, 0xac, 0x5e, 0xe8, 0xf2, 0x0b, 0x44, 0xc9, 0x22, 0x9b, 0xee, 0x0e, 0x75, - 0xaa, 0x97, 0x44, 0xbe, 0xcb, 0xe1, 0xc1, 0xcc, 0x85, 0xf9, 0x07, 0xd0, 0xe1, 0x03, 0xb9, 0x90, - 0x0f, 0xa0, 0x44, 0xe5, 0x3d, 0xf2, 0xea, 0x6f, 0xe5, 0xb5, 0x81, 0x25, 0x6f, 0xa6, 0xab, 0xbc, - 0x10, 0x01, 0x43, 0x2d, 0x8f, 0x6c, 0x42, 0xa5, 0xed, 0x06, 0xe1, 0x7c, 0xc7, 0xb6, 0x02, 0x1a, - 0x54, 0x9f, 0xe5, 0x93, 0x26, 0x73, 0x23, 0xbe, 0xae, 0xc8, 0xa2, 0x39, 0x73, 0x3d, 0x2a, 0x89, - 0x71, 0x36, 0x84, 0x72, 0x57, 0x7c, 0x8f, 0x0f, 0xa1, 0xeb, 0x84, 0xf4, 0x6e, 0x58, 0xbd, 0xc8, - 0x1b, 0xf6, 0x42, 0x16, 0xe7, 0x0d, 0xb7, 0x59, 0x4f, 0x52, 0x6b, 0x5f, 0x7c, 0x1c, 0x88, 0x69, - 0x9e, 0xcc, 0x92, 0xf7, 0xdc, 0x66, 0xdd, 0xa3, 0x8d, 0x0d, 0x2b, 0x6c, 0xb4, 0xab, 0x33, 0x49, - 0x67, 0xc8, 0x46, 0x0c, 0x87, 0x09, 0x4a, 0xe2, 0xc1, 0x68, 0x57, 0xdc, 0x7c, 0xa8, 0x3e, 0x97, - 0xd7, 0x41, 0x57, 0x5e, 0xa5, 0x10, 0x7b, 0x99, 0xfc, 0x83, 0x4a, 0x0c, 0xf9, 0xdb, 0x06, 0x4c, - 0xa4, 0x72, 0xf9, 0xaa, 0xbf, 0x9d, 0xdb, 0x76, 0x9a, 0x64, 0x5c, 0x7b, 0x81, 0x77, 0x5f, 0x12, - 0x78, 0xbf, 0x1f, 0x84, 0xe9, 0x1a, 0x89, 0x7e, 0xe1, 0xd7, 0x97, 0xaa, 0xcf, 0xe7, 0xd7, 0x2f, - 0x9c, 0xa1, 0xea, 0x17, 0xfe, 0x07, 0x95, 0x18, 0x72, 0x19, 0x46, 0x43, 0xbb, 0x4b, 0xdd, 0x5e, - 0x58, 0x7d, 0x21, 0x19, 0x4f, 0xd9, 0x14, 0x60, 0x54, 0xf8, 0xe9, 0xdf, 0x83, 0xa9, 0xbe, 0x73, - 0xfc, 0xb1, 0xee, 0xd0, 0xfc, 0x0d, 0x66, 0xca, 0xc6, 0x3c, 0x8b, 0x79, 0x3f, 0x38, 0xf3, 0x1a, - 0x8c, 0x35, 0xc4, 0xdb, 0x7a, 0x22, 0x91, 0x7f, 0x38, 0xe9, 0x59, 0x5a, 0x88, 0xe1, 0x30, 0x41, - 0x69, 0xfe, 0x3d, 0x03, 0xc6, 0x13, 0xfb, 0x77, 0xee, 0xe1, 0x93, 0x25, 0x20, 0x5d, 0xdb, 0xf7, - 0x5d, 0x5f, 0x1c, 0x8f, 0x56, 0x99, 0xfa, 0x09, 0xe4, 0x4b, 0x06, 0xfc, 0x96, 0xec, 0x6a, 0x1f, - 0x16, 0x33, 0x4a, 0x98, 0xdf, 0x18, 0x82, 0x28, 0x9d, 0x49, 0x5f, 0x14, 0x37, 0x06, 0x5e, 0x14, - 0x7f, 0x09, 0x4a, 0xef, 0x05, 0xae, 0xb3, 0x11, 0x5d, 0x27, 0xd7, 0x3d, 0x78, 0xb3, 0xbe, 0xbe, - 0xc6, 0x29, 0x35, 0x05, 0xa7, 0x7e, 0x7f, 0xc9, 0xee, 0x84, 0xfd, 0xd7, 0xac, 0x6f, 0xbe, 0x21, - 0xe0, 0xa8, 0x29, 0xf8, 0x03, 0x7e, 0xbb, 0x54, 0x3b, 0x0a, 0xa3, 0x07, 0xfc, 0x18, 0x10, 0x05, - 0x8e, 0xcc, 0x41, 0x59, 0xfb, 0x19, 0xa5, 0xdb, 0x53, 0xf7, 0x94, 0xf6, 0x47, 0x62, 0x44, 0xc3, - 0x0f, 0x67, 0xd2, 0x97, 0x26, 0xad, 0xe0, 0x7a, 0x1e, 0x07, 0xde, 0x94, 0x77, 0x4e, 0x68, 0x64, - 0x05, 0x46, 0x2d, 0x32, 0x9e, 0xf2, 0x56, 0x3c, 0x62, 0xca, 0x9b, 0xf9, 0x97, 0x86, 0x60, 0xf4, - 0x0e, 0xf5, 0xf9, 0xf3, 0x10, 0x97, 0x61, 0x74, 0x57, 0xfc, 0x4c, 0xe7, 0xed, 0x4a, 0x0a, 0x54, - 0x78, 0xd6, 0x35, 0x5b, 0x3d, 0xbb, 0xd3, 0x5c, 0x8c, 0xa6, 0xb7, 0xee, 0x9a, 0x9a, 0x42, 0x60, - 0x44, 0xc3, 0x0a, 0xb4, 0xd8, 0x41, 0xb6, 0xdb, 0xb5, 0xc3, 0xf4, 0x7d, 0xc8, 0x65, 0x85, 0xc0, - 0x88, 0x86, 0xbc, 0x00, 0x23, 0x2d, 0x3b, 0xdc, 0xb4, 0x5a, 0xe9, 0xa8, 0xc4, 0x32, 0x87, 0xa2, - 0xc4, 0x72, 0xb7, 0xb6, 0x1d, 0x6e, 0xfa, 0x94, 0xfb, 0xbf, 0xfa, 0x2e, 0xf0, 0x2c, 0xc7, 0x70, - 0x98, 0xa0, 0xe4, 0x55, 0x72, 0x65, 0xcb, 0xa4, 0xbb, 0x39, 0xaa, 0x92, 0x42, 0x60, 0x44, 0xc3, - 0xa6, 0x58, 0xc3, 0xed, 0x7a, 0x76, 0x47, 0x66, 0x25, 0xc5, 0xa6, 0xd8, 0x82, 0x84, 0xa3, 0xa6, - 0x60, 0xd4, 0x6c, 0x6d, 0x6f, 0xbb, 0x7e, 0x37, 0xfd, 0x1e, 0xd9, 0x86, 0x84, 0xa3, 0xa6, 0x30, - 0xef, 0xc0, 0xb8, 0x58, 0x2c, 0x0b, 0x1d, 0xcb, 0xee, 0x2e, 0x2f, 0x90, 0x6b, 0x7d, 0xa9, 0x77, - 0x97, 0x33, 0x52, 0xef, 0xce, 0x26, 0x0a, 0xf5, 0xa7, 0xe0, 0x99, 0x9f, 0x16, 0xa0, 0xf4, 0x04, - 0x9f, 0x74, 0xf4, 0x12, 0x4f, 0x3a, 0xe6, 0xfd, 0xb0, 0x5f, 0xd6, 0x73, 0x8e, 0x77, 0x53, 0xcf, - 0x39, 0x6e, 0xe4, 0x99, 0x8d, 0xfa, 0xc0, 0xa7, 0x1c, 0x7f, 0x69, 0xc0, 0x19, 0x45, 0xca, 0xf5, - 0x46, 0xcd, 0x76, 0x78, 0x3c, 0xf3, 0xe4, 0xbb, 0xf9, 0x5e, 0xa2, 0x9b, 0xdf, 0xca, 0xaf, 0xc9, - 0xf1, 0x76, 0x0c, 0x7c, 0xd5, 0xf6, 0x17, 0x06, 0x54, 0xb3, 0x0a, 0x3c, 0x81, 0xb7, 0x2c, 0x3f, - 0x4c, 0xbe, 0x65, 0x79, 0xe7, 0x64, 0x5a, 0x3e, 0xe0, 0x4d, 0xcb, 0x5f, 0x0e, 0x68, 0x37, 0x7f, - 0x40, 0xb2, 0xa3, 0x76, 0x14, 0x23, 0xaf, 0x00, 0x83, 0x10, 0x91, 0xbd, 0x35, 0x75, 0x60, 0x24, - 0xe0, 0xc1, 0x3f, 0x39, 0x05, 0xae, 0xe7, 0xb1, 0xcf, 0x30, 0x7e, 0xd2, 0x5f, 0xc5, 0x7f, 0xa3, - 0x94, 0x61, 0xfe, 0x07, 0x03, 0xc6, 0x9e, 0xe0, 0x83, 0xa5, 0x6e, 0x72, 0x90, 0x6f, 0xe6, 0x37, - 0xc8, 0x03, 0x06, 0xf6, 0xdf, 0x5d, 0x80, 0xc4, 0xdb, 0xa0, 0xe4, 0x43, 0x28, 0xab, 0xa3, 0x99, - 0xca, 0x72, 0xbf, 0x99, 0x9f, 0x4f, 0x39, 0xda, 0x66, 0x14, 0x24, 0xc0, 0x48, 0x5e, 0x2a, 0xdc, - 0x5a, 0x38, 0x52, 0xb8, 0xf5, 0xb3, 0x7d, 0xb0, 0x30, 0xdb, 0x70, 0x1e, 0x3e, 0x11, 0xc3, 0xf9, - 0x42, 0xee, 0x86, 0xf3, 0xb3, 0x4f, 0xd8, 0x70, 0x8e, 0xf9, 0x26, 0x8b, 0x8f, 0xe1, 0x9b, 0xfc, - 0x10, 0xce, 0xec, 0x46, 0x9b, 0xbf, 0x9e, 0x49, 0xf2, 0xdd, 0xc5, 0xcb, 0x99, 0xe6, 0x32, 0x3b, - 0xc8, 0x04, 0x21, 0x75, 0xc2, 0xd8, 0xb1, 0x41, 0x5f, 0x25, 0x3d, 0x73, 0x27, 0x83, 0x1d, 0x66, - 0x0a, 0x49, 0x3b, 0x99, 0x46, 0x8f, 0xe0, 0x64, 0xfa, 0xfb, 0x03, 0xbf, 0xf3, 0x50, 0x3a, 0xd9, - 0xef, 0x3c, 0x3c, 0x7d, 0xec, 0x6f, 0x3c, 0x3c, 0x1f, 0xf9, 0xad, 0x45, 0x88, 0x3f, 0xdb, 0xc9, - 0xfc, 0x9d, 0x74, 0xf4, 0x09, 0x78, 0xd7, 0x7f, 0x31, 0xdf, 0x53, 0x4f, 0x0e, 0x11, 0xa8, 0xca, - 0x63, 0x44, 0xa0, 0x52, 0xbe, 0xc1, 0xb1, 0x9c, 0x7c, 0x83, 0x0e, 0x4c, 0xda, 0x5d, 0xab, 0x45, - 0x37, 0x7a, 0x9d, 0x8e, 0xc8, 0x8f, 0x0c, 0xaa, 0xe3, 0x9c, 0x77, 0x66, 0xc2, 0xdb, 0x2d, 0xb7, - 0x61, 0x75, 0xd2, 0x6f, 0xe1, 0xea, 0x84, 0xf1, 0x1b, 0x29, 0x4e, 0xd8, 0xc7, 0x9b, 0x4d, 0x58, - 0x7e, 0xa1, 0x94, 0x86, 0xac, 0xb7, 0x79, 0xd4, 0x45, 0x7e, 0xa0, 0xe8, 0x7a, 0x04, 0xc6, 0x38, - 0x0d, 0x59, 0x81, 0x72, 0xd3, 0x09, 0x64, 0x52, 0xf4, 0x04, 0x57, 0x66, 0x9f, 0x63, 0x2a, 0x70, - 0x71, 0xad, 0xae, 0xd3, 0xa1, 0x2f, 0x64, 0xdc, 0x55, 0xd6, 0x78, 0x8c, 0xca, 0x93, 0x55, 0xce, - 0x4c, 0x3e, 0x5e, 0x26, 0x82, 0x21, 0x97, 0x06, 0x78, 0xb4, 0x16, 0xd7, 0xd4, 0x63, 0x6b, 0xe3, - 0x52, 0x9c, 0x7c, 0x85, 0x2c, 0xe2, 0x10, 0x7b, 0x9c, 0x73, 0xea, 0x81, 0x8f, 0x73, 0xf2, 0x47, - 0x0a, 0xc2, 0x8e, 0xf6, 0x4a, 0x5f, 0xcc, 0xed, 0x91, 0x82, 0x28, 0xae, 0x2f, 0x1f, 0x29, 0x88, - 0x00, 0x18, 0x17, 0x49, 0xd6, 0x07, 0x79, 0xe7, 0x4f, 0x73, 0xa5, 0x71, 0x7c, 0x5f, 0x7b, 0xdc, - 0xa1, 0x7b, 0xe6, 0x81, 0x0e, 0xdd, 0x3e, 0x07, 0xf4, 0xd9, 0x63, 0x38, 0xa0, 0xdb, 0xfc, 0xfa, - 0xf8, 0xf2, 0x82, 0xf4, 0xe4, 0xe7, 0x70, 0xa0, 0xe3, 0xd7, 0xa4, 0x44, 0x9e, 0x04, 0xff, 0x89, - 0x42, 0x00, 0xd9, 0x80, 0x33, 0x9e, 0xdb, 0xec, 0x73, 0x66, 0x73, 0xd7, 0x7d, 0x74, 0xd3, 0xff, - 0xcc, 0x46, 0x06, 0x0d, 0x66, 0x96, 0xe4, 0xea, 0x39, 0x82, 0xf3, 0x77, 0x08, 0x8a, 0x52, 0x3d, - 0x47, 0x60, 0x8c, 0xd3, 0xa4, 0xdd, 0xb9, 0x4f, 0x9f, 0x98, 0x3b, 0x77, 0xfa, 0x09, 0xb8, 0x73, - 0x9f, 0x39, 0xb2, 0x3b, 0xf7, 0x23, 0x38, 0xed, 0xb9, 0xcd, 0x45, 0x3b, 0xf0, 0x7b, 0x3c, 0x91, - 0xb9, 0xd6, 0x6b, 0xb6, 0x68, 0xc8, 0xfd, 0xc1, 0x95, 0x2b, 0x57, 0xe2, 0x95, 0x14, 0x5f, 0xbf, - 0x9c, 0x95, 0x5f, 0xbf, 0xe4, 0x0b, 0x35, 0x55, 0x8a, 0x1b, 0x4c, 0x3c, 0x51, 0x24, 0x03, 0x89, - 0x59, 0x72, 0xe2, 0xde, 0xe4, 0x4b, 0x4f, 0xc6, 0x9b, 0xfc, 0x79, 0x28, 0x05, 0xed, 0x5e, 0xd8, - 0x74, 0xf7, 0x1c, 0x1e, 0x32, 0x28, 0xeb, 0xe7, 0xf2, 0x4b, 0x75, 0x09, 0xbf, 0x7f, 0x30, 0x33, - 0xa9, 0x7e, 0xc7, 0x5c, 0x0a, 0x12, 0x42, 0xbe, 0x3b, 0x20, 0xf9, 0xd3, 0x3c, 0xc9, 0xe4, 0xcf, - 0xf3, 0xc7, 0x4a, 0xfc, 0xcc, 0x72, 0x99, 0x3f, 0xf7, 0x6b, 0xe7, 0x32, 0xff, 0xb6, 0x01, 0xe3, - 0xbb, 0x71, 0xff, 0x8d, 0x74, 0xeb, 0xe7, 0x10, 0x34, 0x4c, 0xb8, 0x85, 0x6a, 0x26, 0x53, 0x76, - 0x09, 0xd0, 0xfd, 0x34, 0x00, 0x93, 0x35, 0xc9, 0x08, 0x68, 0x3e, 0xff, 0x59, 0x05, 0x34, 0x3f, - 0xe2, 0xca, 0x4c, 0xa5, 0xa8, 0x70, 0x5f, 0x7f, 0xbe, 0x69, 0x30, 0x4a, 0x31, 0xea, 0x2c, 0x98, - 0xb8, 0xbc, 0xc7, 0x8f, 0x1d, 0xfc, 0x94, 0xc0, 0xa9, 0xd4, 0xd3, 0xff, 0xaf, 0xa8, 0xb7, 0x77, - 0x84, 0x67, 0xef, 0x62, 0xfa, 0xed, 0x9d, 0x71, 0x45, 0x9f, 0x78, 0x7f, 0x27, 0xf1, 0x40, 0x4e, - 0xe1, 0x44, 0x1f, 0xc8, 0x19, 0x7a, 0x32, 0x0f, 0xe4, 0x4c, 0x9e, 0xc4, 0x03, 0x39, 0x53, 0xc7, - 0x7a, 0x20, 0x27, 0xf6, 0x40, 0xd1, 0xf0, 0x43, 0x1e, 0x28, 0x9a, 0x87, 0x09, 0x95, 0x98, 0x47, - 0xe5, 0xcb, 0x27, 0xc2, 0xdb, 0xac, 0xbf, 0x84, 0xb6, 0x90, 0x44, 0x63, 0x9a, 0x9e, 0x7c, 0xc5, - 0x80, 0xa2, 0xc3, 0x4b, 0x8e, 0xe4, 0xf5, 0x2a, 0x5e, 0x72, 0x6a, 0x71, 0x6b, 0x41, 0xbe, 0x45, - 0xa7, 0x72, 0x4a, 0x8a, 0x1c, 0x76, 0x5f, 0xfd, 0x40, 0x51, 0x03, 0xf2, 0x0e, 0x54, 0xdd, 0xed, - 0xed, 0x8e, 0x6b, 0x35, 0xa3, 0x57, 0x7c, 0x94, 0x3b, 0x5c, 0x64, 0x29, 0xeb, 0xe7, 0x18, 0xd6, - 0x07, 0xd0, 0xe1, 0x40, 0x0e, 0xcc, 0xdc, 0x9b, 0x08, 0x42, 0xd7, 0xa7, 0xcd, 0xc8, 0x34, 0x2d, - 0xf3, 0x36, 0xd3, 0xdc, 0xdb, 0x5c, 0x4f, 0xca, 0x11, 0xad, 0xd7, 0x83, 0x92, 0xc2, 0x62, 0xba, - 0x5a, 0xc4, 0x87, 0x73, 0x5e, 0x96, 0x65, 0x1c, 0xc8, 0x74, 0xc2, 0x07, 0xd9, 0xe7, 0x6a, 0xe9, - 0x9e, 0xcb, 0xb4, 0xad, 0x03, 0x1c, 0xc0, 0x39, 0xfe, 0xbe, 0x4f, 0xe9, 0xc9, 0xbc, 0xef, 0x93, - 0xfc, 0x60, 0xc7, 0xf8, 0x13, 0xff, 0x60, 0x07, 0xf9, 0x3f, 0x99, 0x4f, 0x51, 0x09, 0x83, 0xb2, - 0x95, 0xfb, 0x9c, 0xf8, 0xb5, 0x7b, 0x8e, 0xea, 0xef, 0x1a, 0x30, 0x2d, 0x66, 0x5e, 0xd6, 0xe7, - 0xe3, 0x64, 0x1e, 0x60, 0xde, 0x11, 0x13, 0x1e, 0x9f, 0xad, 0x27, 0xa4, 0x72, 0x47, 0xfe, 0x03, - 0x6a, 0x42, 0xbe, 0x95, 0x71, 0x78, 0x9a, 0xc8, 0xcb, 0x45, 0x93, 0xfd, 0x8c, 0xd1, 0xe9, 0xc3, - 0xa3, 0x9c, 0x97, 0xfe, 0xd1, 0x40, 0x0f, 0x12, 0xe1, 0xd5, 0xfb, 0xb3, 0x27, 0xe4, 0x41, 0x8a, - 0xbf, 0xb5, 0x74, 0x1c, 0x3f, 0xd2, 0xf4, 0x1f, 0x1a, 0xe2, 0x39, 0xc4, 0x81, 0x8f, 0x76, 0x6e, - 0xc5, 0x0f, 0x0d, 0xb9, 0x3c, 0x9b, 0x19, 0x29, 0xe2, 0xf8, 0xeb, 0xa1, 0x7f, 0xd5, 0x80, 0x33, - 0x59, 0x4a, 0x32, 0xa3, 0x4a, 0x5f, 0x4c, 0x56, 0x29, 0x47, 0xb7, 0x77, 0xbc, 0x42, 0xf9, 0xbc, - 0x42, 0xf5, 0x6f, 0x46, 0x62, 0x7e, 0xfb, 0x90, 0x7a, 0xff, 0xff, 0x3b, 0x40, 0x79, 0xbf, 0x30, - 0x99, 0xf8, 0xa2, 0x4f, 0xf1, 0xb3, 0xfa, 0xa2, 0xcf, 0xc8, 0xa3, 0x7c, 0xd1, 0x67, 0xf4, 0x33, - 0xfb, 0xa2, 0x4f, 0xe9, 0x88, 0x5f, 0xf4, 0x29, 0xff, 0x7a, 0x7e, 0xd1, 0xc7, 0xfc, 0x9f, 0x06, - 0x4c, 0xfe, 0x46, 0x7d, 0xa6, 0xf5, 0x7f, 0xc4, 0x22, 0xf9, 0x4f, 0xf0, 0xfb, 0xac, 0x7b, 0xc9, - 0x38, 0x27, 0xe6, 0xdf, 0xe2, 0x01, 0xf1, 0xce, 0xf7, 0x21, 0xcb, 0x95, 0x72, 0xb4, 0x3b, 0xa4, - 0x89, 0x34, 0xb5, 0xc2, 0x91, 0xd3, 0xd4, 0xbe, 0x56, 0xe8, 0xef, 0x62, 0x7e, 0xda, 0xf8, 0xf8, - 0xc9, 0x7c, 0x13, 0xf2, 0x4c, 0xd6, 0x37, 0x21, 0x53, 0xdf, 0x80, 0x4c, 0x7f, 0x13, 0xb0, 0x70, - 0x82, 0xdf, 0x04, 0x1c, 0x87, 0xca, 0x5b, 0xb6, 0xa7, 0xbd, 0x20, 0xb3, 0x3f, 0xfa, 0xf9, 0xc5, - 0xa7, 0x7e, 0xfc, 0xf3, 0x8b, 0x4f, 0x7d, 0xfa, 0xf3, 0x8b, 0x4f, 0x7d, 0xf9, 0xf0, 0xa2, 0xf1, - 0xa3, 0xc3, 0x8b, 0xc6, 0x8f, 0x0f, 0x2f, 0x1a, 0x9f, 0x1e, 0x5e, 0x34, 0xfe, 0xe3, 0xe1, 0x45, - 0xe3, 0xaf, 0xfd, 0xa7, 0x8b, 0x4f, 0xbd, 0x55, 0x52, 0x6d, 0xfb, 0x7f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x58, 0x02, 0x70, 0xa9, 0x7e, 0x88, 0x00, 0x00, + // 7731 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5b, 0x70, 0x24, 0x59, + 0x76, 0xd0, 0x64, 0x49, 0x25, 0x55, 0x9d, 0x92, 0x5a, 0xea, 0xdb, 0xaf, 0x1a, 0x4d, 0x4f, 0x6b, + 0x9c, 0xe3, 0x19, 0xa6, 0x61, 0x56, 0xf2, 0x74, 0xef, 0xc0, 0xc0, 0x06, 0xf6, 0xaa, 0xa4, 0x96, + 0xba, 0xa7, 0x5b, 0x8f, 0x39, 0xa5, 0xee, 0x89, 0x9d, 0x1d, 0x96, 0x4d, 0x55, 0x5d, 0x55, 0xe5, + 0xa8, 0x2a, 0x33, 0x27, 0x33, 0x4b, 0x6a, 0xed, 0xcc, 0xac, 0x17, 0x03, 0xf6, 0x2e, 0xc6, 0x18, + 0xcc, 0x86, 0xbd, 0x36, 0x3f, 0x1b, 0xc0, 0x02, 0x01, 0x0e, 0x02, 0x13, 0x7c, 0x99, 0x5f, 0x88, + 0x58, 0x82, 0x0f, 0x1c, 0x61, 0x08, 0x6f, 0x04, 0x20, 0xb3, 0x32, 0xaf, 0x1f, 0xf8, 0xf3, 0xe2, + 0x68, 0xf8, 0x20, 0xee, 0x33, 0x6f, 0x66, 0x65, 0x75, 0x4b, 0xd3, 0xa9, 0xde, 0x8d, 0x58, 0xff, + 0x55, 0x9d, 0x73, 0xee, 0x39, 0xf7, 0x79, 0xee, 0xb9, 0xe7, 0x9c, 0x7b, 0x13, 0xb6, 0x3a, 0x6e, + 0xdc, 0x1d, 0xec, 0x2c, 0xb4, 0xfc, 0xfe, 0xa2, 0x13, 0x76, 0xfc, 0x20, 0xf4, 0x3f, 0xe0, 0x3f, + 0x3e, 0x73, 0xe0, 0x87, 0x7b, 0xbb, 0x3d, 0xff, 0x20, 0x5a, 0xdc, 0xbf, 0xb9, 0x18, 0xec, 0x75, + 0x16, 0x9d, 0xc0, 0x8d, 0x16, 0x15, 0x74, 0x71, 0xff, 0x0d, 0xa7, 0x17, 0x74, 0x9d, 0x37, 0x16, + 0x3b, 0xd4, 0xa3, 0xa1, 0x13, 0xd3, 0xf6, 0x42, 0x10, 0xfa, 0xb1, 0x4f, 0x3e, 0x9f, 0x70, 0x5c, + 0x50, 0x1c, 0xf9, 0x8f, 0xbf, 0xa8, 0x39, 0x2e, 0xec, 0xdf, 0x5c, 0x08, 0xf6, 0x3a, 0x0b, 0x8c, + 0xe3, 0x82, 0x82, 0x2e, 0x28, 0x8e, 0x73, 0x9f, 0x31, 0xea, 0xd4, 0xf1, 0x3b, 0xfe, 0x22, 0x67, + 0xbc, 0x33, 0xd8, 0xe5, 0xff, 0xf8, 0x1f, 0xfe, 0x4b, 0x08, 0x9c, 0xb3, 0xf7, 0xde, 0x8a, 0x16, + 0x5c, 0x9f, 0xd5, 0x6f, 0xb1, 0xe5, 0x87, 0x74, 0x71, 0x7f, 0xa8, 0x52, 0x73, 0xd7, 0x0d, 0x9a, + 0xc0, 0xef, 0xb9, 0xad, 0xc3, 0xc5, 0xfd, 0x37, 0x76, 0x68, 0x3c, 0x5c, 0xff, 0xb9, 0xcf, 0x26, + 0xa4, 0x7d, 0xa7, 0xd5, 0x75, 0x3d, 0x1a, 0x1e, 0x26, 0xed, 0xef, 0xd3, 0xd8, 0xc9, 0x13, 0xb0, + 0x38, 0xaa, 0x54, 0x38, 0xf0, 0x62, 0xb7, 0x4f, 0x87, 0x0a, 0xfc, 0xe9, 0x27, 0x15, 0x88, 0x5a, + 0x5d, 0xda, 0x77, 0x86, 0xca, 0xdd, 0x1c, 0x55, 0x6e, 0x10, 0xbb, 0xbd, 0x45, 0xd7, 0x8b, 0xa3, + 0x38, 0xcc, 0x16, 0xb2, 0x6f, 0xc1, 0xc4, 0x52, 0xdf, 0x1f, 0x78, 0x31, 0xf9, 0x1c, 0x94, 0xf7, + 0x9d, 0xde, 0x80, 0xd6, 0xad, 0x97, 0xac, 0xd7, 0xaa, 0x8d, 0x57, 0xbe, 0x7b, 0x34, 0xff, 0xdc, + 0xf1, 0xd1, 0x7c, 0xf9, 0x01, 0x03, 0x3e, 0x3a, 0x9a, 0xbf, 0x48, 0xbd, 0x96, 0xdf, 0x76, 0xbd, + 0xce, 0xe2, 0x07, 0x91, 0xef, 0x2d, 0x6c, 0x0c, 0xfa, 0x3b, 0x34, 0x44, 0x51, 0xc6, 0xfe, 0xdd, + 0x12, 0xcc, 0x2c, 0x85, 0xad, 0xae, 0xbb, 0x4f, 0x9b, 0x31, 0xe3, 0xdf, 0x39, 0x24, 0x5d, 0x18, + 0x8b, 0x9d, 0x90, 0xb3, 0xab, 0xdd, 0x58, 0x5f, 0x78, 0xda, 0xc1, 0x5f, 0xd8, 0x76, 0x42, 0xc5, + 0xbb, 0x31, 0x79, 0x7c, 0x34, 0x3f, 0xb6, 0xed, 0x84, 0xc8, 0x44, 0x90, 0x1e, 0x8c, 0x7b, 0xbe, + 0x47, 0xeb, 0x25, 0x2e, 0x6a, 0xe3, 0xe9, 0x45, 0x6d, 0xf8, 0x9e, 0x6e, 0x47, 0xa3, 0x72, 0x7c, + 0x34, 0x3f, 0xce, 0x20, 0xc8, 0xa5, 0xb0, 0x76, 0x7d, 0xc5, 0x0d, 0xea, 0x63, 0x45, 0xb5, 0xeb, + 0x3d, 0x37, 0x48, 0xb7, 0xeb, 0x3d, 0x37, 0x40, 0x26, 0xc2, 0xfe, 0x46, 0x09, 0xaa, 0x4b, 0x61, + 0x67, 0xd0, 0xa7, 0x5e, 0x1c, 0x91, 0x9f, 0x05, 0x08, 0x9c, 0xd0, 0xe9, 0xd3, 0x98, 0x86, 0x51, + 0xdd, 0x7a, 0x69, 0xec, 0xb5, 0xda, 0x8d, 0xbb, 0x4f, 0x2f, 0x7e, 0x4b, 0xf1, 0x6c, 0x10, 0x39, + 0xe4, 0xa0, 0x41, 0x11, 0x1a, 0x22, 0xc9, 0x47, 0x50, 0x75, 0xc2, 0xd8, 0xdd, 0x75, 0x5a, 0x71, + 0x54, 0x2f, 0x71, 0xf9, 0x6f, 0x3f, 0xbd, 0xfc, 0x25, 0xc9, 0xb2, 0x71, 0x5e, 0x8a, 0xaf, 0x2a, + 0x48, 0x84, 0x89, 0x3c, 0xfb, 0x7f, 0x8c, 0x43, 0x45, 0x21, 0xc8, 0x4b, 0x30, 0xee, 0x39, 0x7d, + 0x35, 0x55, 0xa7, 0x64, 0xc1, 0xf1, 0x0d, 0xa7, 0xcf, 0x06, 0xc9, 0xe9, 0x53, 0x46, 0x11, 0x38, + 0x71, 0x97, 0x4f, 0x09, 0x83, 0x62, 0xcb, 0x89, 0xbb, 0xc8, 0x31, 0xe4, 0x2a, 0x8c, 0xf7, 0xfd, + 0x36, 0xe5, 0xe3, 0x58, 0x16, 0x83, 0xbc, 0xee, 0xb7, 0x29, 0x72, 0x28, 0x2b, 0xbf, 0x1b, 0xfa, + 0xfd, 0xfa, 0x78, 0xba, 0xfc, 0x6a, 0xe8, 0xf7, 0x91, 0x63, 0xc8, 0xb7, 0x2c, 0x98, 0x55, 0xd5, + 0xbb, 0xe7, 0xb7, 0x9c, 0xd8, 0xf5, 0xbd, 0x7a, 0x99, 0x4f, 0x0a, 0x2c, 0xae, 0x57, 0x14, 0xe7, + 0x46, 0x5d, 0x56, 0x61, 0x36, 0x8b, 0xc1, 0xa1, 0x5a, 0x90, 0x1b, 0x00, 0x9d, 0x9e, 0xbf, 0xe3, + 0xf4, 0x58, 0x87, 0xd4, 0x27, 0x78, 0x13, 0xf4, 0xe0, 0xae, 0x69, 0x0c, 0x1a, 0x54, 0xe4, 0x21, + 0x4c, 0x3a, 0x62, 0x01, 0xd7, 0x27, 0x79, 0x23, 0xde, 0x29, 0xa2, 0x11, 0x29, 0x8d, 0xd0, 0xa8, + 0x1d, 0x1f, 0xcd, 0x4f, 0x4a, 0x20, 0x2a, 0x71, 0xe4, 0x75, 0xa8, 0xf8, 0x01, 0xab, 0xb7, 0xd3, + 0xab, 0x57, 0x5e, 0xb2, 0x5e, 0xab, 0x34, 0x66, 0x65, 0x5d, 0x2b, 0x9b, 0x12, 0x8e, 0x9a, 0x82, + 0x5c, 0x87, 0xc9, 0x68, 0xb0, 0xc3, 0xc6, 0xb1, 0x5e, 0xe5, 0x0d, 0x9b, 0x91, 0xc4, 0x93, 0x4d, + 0x01, 0x46, 0x85, 0x27, 0x6f, 0x42, 0x2d, 0xa4, 0xad, 0x41, 0x18, 0x51, 0x36, 0xb0, 0x75, 0xe0, + 0xbc, 0x2f, 0x48, 0xf2, 0x1a, 0x26, 0x28, 0x34, 0xe9, 0xec, 0xdf, 0x9e, 0x84, 0xa1, 0x4e, 0x26, + 0x6f, 0x40, 0x4d, 0xd6, 0xf7, 0x9e, 0xdf, 0x89, 0xf8, 0xc4, 0xab, 0x34, 0x66, 0x18, 0x9f, 0xa5, + 0x04, 0x8c, 0x26, 0x0d, 0x69, 0x43, 0x29, 0xba, 0x29, 0x75, 0xd2, 0xbd, 0xa7, 0xef, 0xcc, 0xe6, + 0x4d, 0xbd, 0x52, 0x26, 0x8e, 0x8f, 0xe6, 0x4b, 0xcd, 0x9b, 0x58, 0x8a, 0x6e, 0x32, 0x6d, 0xd4, + 0x71, 0xe3, 0xe2, 0xb4, 0xd1, 0x9a, 0x1b, 0x6b, 0x39, 0x5c, 0x1b, 0xad, 0xb9, 0x31, 0x32, 0x11, + 0x4c, 0xcb, 0x76, 0xe3, 0x38, 0xe0, 0x4b, 0xa2, 0x10, 0x2d, 0x7b, 0x7b, 0x7b, 0x7b, 0x4b, 0xcb, + 0xe2, 0x0b, 0x90, 0x41, 0x90, 0x4b, 0x21, 0x5f, 0xb7, 0x58, 0x8f, 0x0b, 0xa4, 0x1f, 0x1e, 0xca, + 0x95, 0x75, 0xbf, 0xb8, 0x95, 0xe5, 0x87, 0x87, 0x5a, 0xb8, 0x1c, 0x48, 0x8d, 0x40, 0x53, 0x34, + 0x6f, 0x78, 0x7b, 0x37, 0xe2, 0x0b, 0xa9, 0x98, 0x86, 0xaf, 0xac, 0x36, 0x33, 0x0d, 0x5f, 0x59, + 0x6d, 0x22, 0x97, 0xc2, 0x06, 0x34, 0x74, 0x0e, 0xe4, 0x22, 0x2c, 0x60, 0x40, 0xd1, 0x39, 0x48, + 0x0f, 0x28, 0x3a, 0x07, 0xc8, 0x44, 0x30, 0x49, 0x7e, 0x14, 0xf1, 0x35, 0x57, 0x88, 0xa4, 0xcd, + 0x66, 0x33, 0x2d, 0x69, 0xb3, 0xd9, 0x44, 0x26, 0x82, 0x4f, 0xd2, 0x56, 0xc4, 0x17, 0x6c, 0x31, + 0x93, 0x74, 0x39, 0x23, 0x69, 0x6d, 0xb9, 0x89, 0x4c, 0x84, 0xfd, 0x0d, 0x0b, 0xa6, 0x15, 0x8a, + 0x29, 0x81, 0x88, 0x3c, 0x84, 0x8a, 0x1a, 0x4c, 0x69, 0x8b, 0x14, 0xb9, 0x69, 0x69, 0x55, 0xa5, + 0x20, 0xa8, 0xa5, 0xd9, 0x1f, 0xc2, 0x25, 0x0d, 0xa5, 0x81, 0x1f, 0xb9, 0x7c, 0x6a, 0xd1, 0x5d, + 0xb2, 0x08, 0xd5, 0x96, 0xef, 0xed, 0xba, 0x9d, 0x75, 0x27, 0x90, 0x7b, 0x98, 0xde, 0xfc, 0x96, + 0x15, 0x02, 0x13, 0x1a, 0xf2, 0x22, 0x8c, 0xed, 0xd1, 0x43, 0xb9, 0x99, 0xd5, 0x24, 0xe9, 0xd8, + 0x5d, 0x7a, 0x88, 0x0c, 0xfe, 0xe7, 0x2a, 0xdf, 0xfa, 0xf6, 0xfc, 0x73, 0x5f, 0xfb, 0x4f, 0x2f, + 0x3d, 0x67, 0xff, 0xf3, 0x12, 0xbc, 0x90, 0x2b, 0xb3, 0x19, 0x3b, 0xf1, 0x20, 0x22, 0xbf, 0x69, + 0xc1, 0x25, 0x27, 0x0f, 0x2f, 0xbb, 0xe6, 0xdd, 0xe2, 0xba, 0x26, 0xc5, 0xbe, 0xf1, 0xa2, 0xac, + 0x74, 0x7e, 0x8f, 0x60, 0x7e, 0xa5, 0x58, 0x47, 0xb1, 0xdd, 0x3c, 0x0a, 0x9c, 0x16, 0x95, 0xad, + 0xd7, 0x1d, 0xb5, 0xa1, 0x10, 0x98, 0xd0, 0xb0, 0xdd, 0xa1, 0x4d, 0x77, 0x9d, 0x41, 0x4f, 0x68, + 0xc4, 0x4a, 0xb2, 0x3b, 0xac, 0x08, 0x30, 0x2a, 0xbc, 0xd1, 0x69, 0xff, 0xd6, 0x82, 0x0b, 0x39, + 0x5a, 0x81, 0xf5, 0xfa, 0x20, 0xec, 0xc9, 0x01, 0xd2, 0xbd, 0x7e, 0x1f, 0xef, 0x21, 0x83, 0x93, + 0x6f, 0x5a, 0x30, 0x63, 0xa8, 0x89, 0xa5, 0x81, 0x34, 0x37, 0x0a, 0xda, 0x3a, 0x53, 0x8c, 0x1b, + 0x57, 0xa4, 0xf8, 0x99, 0x0c, 0x02, 0xb3, 0x55, 0xb0, 0x7f, 0xcf, 0x82, 0x2c, 0x11, 0x71, 0xe0, + 0xdc, 0x20, 0xa2, 0x21, 0xeb, 0xa7, 0x26, 0x6d, 0x85, 0x54, 0xad, 0x84, 0x57, 0x16, 0xc4, 0x99, + 0x81, 0xd5, 0x62, 0x81, 0x9d, 0x90, 0x16, 0xf6, 0xdf, 0x58, 0x10, 0x14, 0x77, 0xe9, 0x61, 0x93, + 0xf6, 0x28, 0xe3, 0xd1, 0x20, 0xc7, 0x47, 0xf3, 0xe7, 0xee, 0xa7, 0x18, 0x60, 0x86, 0x21, 0x13, + 0x11, 0x38, 0x51, 0x74, 0xe0, 0x87, 0x6d, 0x29, 0xa2, 0x74, 0x6a, 0x11, 0x5b, 0x29, 0x06, 0x98, + 0x61, 0x68, 0xff, 0x2b, 0x0b, 0x26, 0x1b, 0x4e, 0x6b, 0xcf, 0xdf, 0xdd, 0x65, 0x46, 0x43, 0x7b, + 0x10, 0x0a, 0xa3, 0x4b, 0x0c, 0x90, 0x5e, 0x89, 0x2b, 0x12, 0x8e, 0x9a, 0x82, 0x6c, 0xc3, 0x84, + 0xe8, 0x0e, 0x59, 0xa9, 0x9f, 0x32, 0x2a, 0xa5, 0xcf, 0x4a, 0x7c, 0x38, 0xd8, 0x59, 0x69, 0x41, + 0x9c, 0x95, 0x16, 0xee, 0x78, 0xf1, 0x26, 0x3b, 0x72, 0xb8, 0x5e, 0xa7, 0x01, 0xc7, 0x47, 0xf3, + 0x13, 0xab, 0x9c, 0x07, 0x4a, 0x5e, 0xcc, 0xbe, 0xe8, 0x3b, 0x0f, 0x95, 0x38, 0x3e, 0xe1, 0xaa, + 0x89, 0x7d, 0xb1, 0x9e, 0xa0, 0xd0, 0xa4, 0xb3, 0xbf, 0x04, 0xe5, 0x65, 0xa7, 0xd5, 0xa5, 0xe4, + 0x7e, 0x56, 0x0d, 0xd4, 0x6e, 0xbc, 0x96, 0xd7, 0x5b, 0x5a, 0x25, 0x98, 0x1d, 0x36, 0x3d, 0x4a, + 0x59, 0xd8, 0x7f, 0x68, 0xc1, 0x95, 0xe5, 0xde, 0x20, 0x8a, 0x69, 0xf8, 0xae, 0x9c, 0x57, 0xdb, + 0xb4, 0x1f, 0xf4, 0x9c, 0x98, 0x92, 0x2f, 0x43, 0x85, 0x9d, 0x53, 0xdb, 0x4e, 0xec, 0x48, 0x89, + 0xa3, 0xbb, 0x82, 0xcf, 0x4c, 0x46, 0xcd, 0xea, 0xb0, 0xb9, 0xf3, 0x01, 0x6d, 0xc5, 0xeb, 0x34, + 0x76, 0x12, 0x4b, 0x32, 0x81, 0xa1, 0xe6, 0x4a, 0x1e, 0xc2, 0x78, 0x14, 0xd0, 0x96, 0xec, 0xe8, + 0x07, 0x4f, 0xbf, 0x12, 0xb2, 0x6d, 0x68, 0x06, 0xb4, 0x95, 0x18, 0xe4, 0xec, 0x1f, 0x72, 0x89, + 0xf6, 0xff, 0xb5, 0xe0, 0x85, 0x11, 0xed, 0xbe, 0xe7, 0x46, 0x31, 0x79, 0x7f, 0xa8, 0xed, 0x0b, + 0x27, 0x6b, 0x3b, 0x2b, 0xcd, 0x5b, 0xae, 0xa7, 0x98, 0x82, 0x18, 0xed, 0xfe, 0x2a, 0x94, 0xdd, + 0x98, 0xf6, 0xd5, 0xc1, 0xe8, 0x0b, 0x4f, 0xdf, 0xf0, 0x11, 0x6d, 0x69, 0x4c, 0xab, 0x93, 0xf9, + 0x1d, 0x26, 0x0f, 0x85, 0x58, 0xfb, 0xdf, 0x58, 0xc0, 0xa6, 0x43, 0xdb, 0x95, 0xe6, 0xea, 0x78, + 0x7c, 0x18, 0xa8, 0x03, 0x92, 0x52, 0xbe, 0xe3, 0xdb, 0x87, 0x01, 0x3b, 0xca, 0x4f, 0x6b, 0x42, + 0x06, 0x40, 0x4e, 0x4a, 0xbe, 0x04, 0x13, 0x11, 0xdf, 0x24, 0xa4, 0xa2, 0x5d, 0x95, 0x85, 0x26, + 0xc4, 0xd6, 0xf1, 0xe8, 0x68, 0xfe, 0x44, 0xfe, 0x8f, 0x05, 0xcd, 0x5b, 0x94, 0x43, 0xc9, 0x95, + 0xa9, 0xe6, 0x3e, 0x8d, 0x22, 0xa7, 0x43, 0xe5, 0x4a, 0xd1, 0xaa, 0x79, 0x5d, 0x80, 0x51, 0xe1, + 0xed, 0x2f, 0x00, 0x2c, 0xfb, 0x5e, 0xec, 0x7a, 0x03, 0xba, 0xe9, 0x91, 0x97, 0xa1, 0x4c, 0xc3, + 0xd0, 0x0f, 0xa5, 0xd1, 0xad, 0x9b, 0x7f, 0x8b, 0x01, 0x51, 0xe0, 0xc8, 0xab, 0x6c, 0x85, 0xbb, + 0x3d, 0xda, 0xe6, 0xb5, 0xaf, 0x34, 0xce, 0xa9, 0xda, 0xaf, 0x72, 0x28, 0x4a, 0xac, 0xbd, 0x00, + 0x93, 0xcb, 0xfe, 0xc0, 0x8b, 0x69, 0xc8, 0xf8, 0x9a, 0x0e, 0x8f, 0xe9, 0x94, 0xc3, 0x43, 0x39, + 0x36, 0xb6, 0xe1, 0xd2, 0x72, 0x48, 0xd9, 0xb4, 0xbb, 0xd9, 0x18, 0xb4, 0xf6, 0x68, 0x2c, 0x8e, + 0x24, 0x11, 0xf9, 0x1c, 0x4c, 0xfb, 0x7c, 0xfe, 0xdf, 0xf3, 0x5b, 0x7b, 0xae, 0xd7, 0x91, 0xfb, + 0xcd, 0x25, 0xc9, 0x65, 0x7a, 0xd3, 0x44, 0x62, 0x9a, 0xd6, 0xfe, 0xaf, 0x25, 0x98, 0x5a, 0x0e, + 0x7d, 0x4f, 0x8d, 0xed, 0x33, 0x58, 0x97, 0x71, 0x6a, 0x5d, 0x16, 0x70, 0x42, 0x35, 0xeb, 0x3f, + 0x6a, 0x4d, 0x92, 0x8f, 0xf5, 0xa4, 0x12, 0x07, 0x94, 0xed, 0x82, 0xe5, 0x72, 0xde, 0xc9, 0x60, + 0xa7, 0xa7, 0x9c, 0xfd, 0xdf, 0x2c, 0x98, 0x35, 0xc9, 0x9f, 0x81, 0x1a, 0x88, 0xd2, 0x6a, 0x60, + 0xa3, 0xd8, 0xf6, 0x8e, 0x58, 0xfb, 0xdf, 0x98, 0x48, 0xb7, 0x93, 0x0d, 0x00, 0xf9, 0x96, 0x05, + 0x53, 0x07, 0x06, 0x40, 0x36, 0x76, 0xa3, 0x38, 0x8d, 0xcc, 0x47, 0xfd, 0x27, 0x65, 0x8d, 0xa6, + 0x4c, 0xe8, 0xa3, 0xcc, 0x7f, 0x4c, 0xd5, 0x84, 0x6d, 0xde, 0x51, 0xab, 0x4b, 0xdb, 0x83, 0x9e, + 0xb2, 0xea, 0x74, 0x97, 0x36, 0x25, 0x1c, 0x35, 0x05, 0x79, 0x1f, 0xce, 0xb7, 0x7c, 0xaf, 0x35, + 0x08, 0x43, 0xea, 0xb5, 0x0e, 0xb7, 0xb8, 0x8f, 0x56, 0xaa, 0x90, 0x05, 0x59, 0xec, 0xfc, 0x72, + 0x96, 0xe0, 0x51, 0x1e, 0x10, 0x87, 0x19, 0x09, 0x7f, 0x42, 0x14, 0x50, 0xaf, 0xcd, 0x0f, 0xb6, + 0x15, 0xd3, 0x9f, 0xc0, 0xc1, 0xa8, 0xf0, 0xe4, 0x3e, 0x5c, 0x89, 0x62, 0x66, 0x6e, 0x79, 0x9d, + 0x15, 0xea, 0xb4, 0x7b, 0xae, 0xc7, 0x8c, 0x1f, 0xdf, 0x6b, 0x47, 0xfc, 0x74, 0x3a, 0xd6, 0x78, + 0xe1, 0xf8, 0x68, 0xfe, 0x4a, 0x33, 0x9f, 0x04, 0x47, 0x95, 0x25, 0x5f, 0x82, 0xb9, 0x68, 0xd0, + 0x6a, 0xd1, 0x28, 0xda, 0x1d, 0xf4, 0xde, 0xf6, 0x77, 0xa2, 0xdb, 0x6e, 0xc4, 0x2c, 0xb7, 0x7b, + 0x6e, 0xdf, 0x8d, 0xf9, 0xa1, 0xb3, 0xdc, 0xb8, 0x76, 0x7c, 0x34, 0x3f, 0xd7, 0x1c, 0x49, 0x85, + 0x8f, 0xe1, 0x40, 0x10, 0x2e, 0x0b, 0xe5, 0x37, 0xc4, 0x7b, 0x92, 0xf3, 0x9e, 0x3b, 0x3e, 0x9a, + 0xbf, 0xbc, 0x9a, 0x4b, 0x81, 0x23, 0x4a, 0xb2, 0x11, 0x8c, 0xdd, 0x3e, 0xfd, 0x8a, 0xef, 0x51, + 0x7e, 0x7e, 0x34, 0x46, 0x70, 0x5b, 0xc2, 0x51, 0x53, 0x90, 0x0f, 0x92, 0x99, 0xc8, 0x96, 0x8b, + 0x3c, 0x07, 0x9e, 0x5e, 0xc3, 0x5d, 0x3c, 0x3e, 0x9a, 0x9f, 0x7d, 0xd7, 0xe0, 0xc4, 0x96, 0x1c, + 0xa6, 0x78, 0xdb, 0xbf, 0x5b, 0x02, 0x32, 0xac, 0x22, 0xc8, 0x5d, 0x98, 0x70, 0x5a, 0xb1, 0xbb, + 0x4f, 0xa5, 0xe3, 0xf4, 0xe5, 0x3c, 0x43, 0x4b, 0x88, 0x42, 0xba, 0x4b, 0xd9, 0x0c, 0xa1, 0x89, + 0x5e, 0x59, 0xe2, 0x45, 0x51, 0xb2, 0x20, 0x3e, 0x9c, 0xef, 0x39, 0x51, 0xac, 0xe6, 0x6a, 0x9b, + 0x35, 0x59, 0x2a, 0xd6, 0x3f, 0x79, 0xb2, 0x46, 0xb1, 0x12, 0x8d, 0x4b, 0x6c, 0xe6, 0xde, 0xcb, + 0x32, 0xc2, 0x61, 0xde, 0xe4, 0x67, 0x01, 0x5a, 0x6a, 0x5b, 0x65, 0xaa, 0xb4, 0x20, 0xd7, 0xaf, + 0xde, 0xaa, 0x93, 0xbd, 0x43, 0x83, 0x22, 0x34, 0x44, 0xda, 0xff, 0x6c, 0x12, 0x26, 0x57, 0x96, + 0xd6, 0xb6, 0x9d, 0x68, 0xef, 0x04, 0xce, 0x57, 0x36, 0x3b, 0xa4, 0xb5, 0x92, 0x5d, 0xdf, 0xca, + 0x8a, 0x41, 0x4d, 0x41, 0x3e, 0x86, 0xaa, 0xa3, 0x9c, 0xdc, 0x72, 0x9b, 0xb8, 0x5b, 0xc4, 0x01, + 0x4a, 0xb2, 0x34, 0xfd, 0xca, 0x12, 0x84, 0x89, 0x40, 0xf2, 0x35, 0x0b, 0x6a, 0xaa, 0x2a, 0xec, + 0x1c, 0x3c, 0x5e, 0x58, 0xb8, 0x22, 0x61, 0x2a, 0xfc, 0x4b, 0x06, 0x00, 0x4d, 0x91, 0xe4, 0xb3, + 0x30, 0xd5, 0xa6, 0x4c, 0xc3, 0x50, 0xaf, 0xe5, 0x52, 0xa6, 0x4c, 0xc6, 0x58, 0x97, 0x31, 0xa5, + 0xba, 0x62, 0xc0, 0x31, 0x45, 0x45, 0x0e, 0xa0, 0x7a, 0xe0, 0xc6, 0x5d, 0xbe, 0x11, 0xd4, 0x27, + 0xf8, 0x94, 0x58, 0x7d, 0xfa, 0x5a, 0x33, 0x76, 0x49, 0x8f, 0xbd, 0xab, 0x04, 0x60, 0x22, 0x8b, + 0x1d, 0xca, 0xd9, 0x1f, 0x1e, 0x24, 0xe0, 0x2a, 0xa4, 0x9a, 0x2e, 0xc0, 0x11, 0x98, 0xd0, 0xb0, + 0x2e, 0x9e, 0x62, 0xff, 0x9a, 0xf4, 0xc3, 0x01, 0x5b, 0x57, 0xd2, 0xe3, 0x54, 0x80, 0x1b, 0x46, + 0x71, 0x14, 0x9d, 0xf5, 0xae, 0x21, 0x03, 0x53, 0x12, 0xd9, 0x9c, 0x3d, 0xe8, 0x52, 0x4f, 0xba, + 0x8c, 0xf5, 0x9c, 0x7d, 0xb7, 0x4b, 0x3d, 0xe4, 0x18, 0xf2, 0x31, 0x5f, 0x62, 0xd2, 0xe6, 0xe4, + 0xbe, 0xe2, 0x42, 0xbc, 0xb6, 0x89, 0x1d, 0xdb, 0x38, 0x27, 0xd7, 0x97, 0xfc, 0x8f, 0x86, 0x3c, + 0x66, 0xbe, 0xfa, 0xde, 0xad, 0x87, 0x6e, 0x5c, 0xaf, 0xf1, 0x1a, 0x6a, 0xcd, 0xb3, 0xc9, 0xa1, + 0x28, 0xb1, 0xc2, 0xbf, 0xc1, 0x26, 0x41, 0x54, 0x9f, 0x4a, 0x1b, 0xd1, 0x62, 0xa6, 0x44, 0xa8, + 0xf0, 0xf6, 0xbf, 0xb3, 0xa0, 0xc6, 0x96, 0xac, 0x5a, 0x66, 0xaf, 0xc2, 0x44, 0xec, 0x84, 0x1d, + 0x79, 0xf6, 0x37, 0x44, 0x6c, 0x73, 0x28, 0x4a, 0x2c, 0xf1, 0xa0, 0x1c, 0x3b, 0xd1, 0x9e, 0xb2, + 0x60, 0xee, 0x3c, 0x7d, 0x1f, 0x48, 0xc5, 0x91, 0x18, 0x2f, 0xec, 0x5f, 0x84, 0x42, 0x0c, 0x79, + 0x0d, 0x2a, 0x6c, 0x93, 0x59, 0x75, 0x22, 0xe5, 0xb3, 0x99, 0x62, 0x8a, 0x62, 0x55, 0xc2, 0x50, + 0x63, 0xed, 0xbf, 0x5d, 0x82, 0xf1, 0x15, 0x61, 0xcb, 0x4e, 0x44, 0xfe, 0x20, 0x6c, 0x51, 0x69, + 0xd3, 0x14, 0x30, 0x4e, 0x8c, 0x6f, 0x93, 0xf3, 0x34, 0xac, 0x49, 0xfe, 0x1f, 0xa5, 0x2c, 0xf2, + 0x4d, 0x0b, 0xce, 0xc5, 0xa1, 0xe3, 0x45, 0xbb, 0x7e, 0xd8, 0x17, 0x47, 0x7e, 0xd1, 0x45, 0x05, + 0x18, 0xb5, 0xdb, 0x29, 0xbe, 0xcd, 0x98, 0x06, 0x8d, 0xcb, 0xb2, 0x1a, 0xe7, 0xd2, 0x38, 0xcc, + 0xd4, 0xc1, 0xfe, 0x35, 0x0b, 0x20, 0xa9, 0x3d, 0xf9, 0xba, 0x05, 0xd3, 0x8e, 0xe9, 0x00, 0x95, + 0x7d, 0xb4, 0x59, 0x9c, 0x4f, 0x8a, 0xb3, 0x6d, 0x9c, 0x67, 0xa7, 0x9c, 0x14, 0x08, 0xd3, 0x82, + 0xed, 0x37, 0xa1, 0x7c, 0x6b, 0x9f, 0x7a, 0xdc, 0x5a, 0x88, 0xa4, 0xdf, 0x22, 0xeb, 0xac, 0x51, + 0xfe, 0x0c, 0xd4, 0x14, 0xf6, 0xfb, 0x70, 0xee, 0xd6, 0x43, 0xda, 0x1a, 0xc4, 0x7e, 0x28, 0xfc, + 0x1b, 0xe4, 0x6d, 0x20, 0x11, 0x0d, 0xf7, 0xdd, 0x16, 0x5d, 0x6a, 0xb5, 0xd8, 0xe9, 0x6d, 0x23, + 0xd9, 0x7f, 0xe6, 0x24, 0x27, 0xd2, 0x1c, 0xa2, 0xc0, 0x9c, 0x52, 0xf6, 0x3f, 0xb6, 0xa0, 0x66, + 0xb8, 0x8f, 0xd9, 0xee, 0xd3, 0x59, 0x6e, 0x8a, 0xb3, 0x9d, 0xec, 0xaa, 0xbb, 0x85, 0x38, 0xa8, + 0x05, 0xcb, 0x44, 0x35, 0x6a, 0x10, 0x26, 0x02, 0x9f, 0xe0, 0xd8, 0xb5, 0x7f, 0xcb, 0x82, 0xa4, + 0x1c, 0x5b, 0xc1, 0x3b, 0x49, 0x3d, 0x8d, 0x15, 0x2c, 0xf9, 0x4a, 0x2c, 0xf9, 0x18, 0xae, 0xa4, + 0x1b, 0xce, 0xfd, 0x46, 0xa7, 0xf7, 0xc9, 0x09, 0x73, 0x36, 0x9f, 0x13, 0x8e, 0x12, 0x61, 0x3f, + 0x80, 0xf2, 0x9a, 0x33, 0xe8, 0xd0, 0x13, 0x9d, 0xaf, 0xd9, 0xea, 0x0f, 0xa9, 0xd3, 0x8b, 0x95, + 0x05, 0x25, 0x57, 0x3f, 0x4a, 0x18, 0x6a, 0xac, 0xfd, 0x9b, 0xe3, 0x50, 0x33, 0x82, 0x53, 0x4c, + 0xa5, 0x87, 0x34, 0xf0, 0xb3, 0x66, 0x08, 0xd2, 0xc0, 0x47, 0x8e, 0x61, 0xd3, 0x2e, 0xa4, 0xfb, + 0x6e, 0x24, 0x56, 0x6a, 0x6a, 0xda, 0xa1, 0x84, 0xa3, 0xa6, 0x20, 0xf3, 0x50, 0x6e, 0xd3, 0x20, + 0xee, 0x72, 0x25, 0x34, 0xde, 0xa8, 0xb2, 0xaa, 0xae, 0x30, 0x00, 0x0a, 0x38, 0x23, 0xd8, 0xa5, + 0x71, 0xab, 0x5b, 0x1f, 0xe7, 0xfb, 0x33, 0x27, 0x58, 0x65, 0x00, 0x14, 0xf0, 0x1c, 0x2f, 0x6b, + 0xf9, 0xec, 0xbd, 0xac, 0x13, 0x05, 0x7b, 0x59, 0x49, 0x00, 0x17, 0xa2, 0xa8, 0xbb, 0x15, 0xba, + 0xfb, 0x4e, 0x4c, 0x93, 0x99, 0x33, 0x79, 0x1a, 0x39, 0x57, 0x8e, 0x8f, 0xe6, 0x2f, 0x34, 0x9b, + 0xb7, 0xb3, 0x5c, 0x30, 0x8f, 0x35, 0x69, 0xc2, 0x25, 0xd7, 0x8b, 0x68, 0x6b, 0x10, 0xd2, 0x3b, + 0x1d, 0xcf, 0x0f, 0xe9, 0x6d, 0x3f, 0x62, 0xec, 0x64, 0x34, 0x58, 0x87, 0x0e, 0xee, 0xe4, 0x11, + 0x61, 0x7e, 0x59, 0xfb, 0x7b, 0x16, 0x4c, 0x99, 0x71, 0x36, 0x66, 0x85, 0x40, 0x77, 0x65, 0xb5, + 0x29, 0x74, 0x4a, 0x71, 0x3b, 0xc7, 0x6d, 0xcd, 0x33, 0xb1, 0xa2, 0x13, 0x18, 0x1a, 0x32, 0x4f, + 0x90, 0x94, 0xf0, 0x32, 0x94, 0x77, 0x7d, 0xb6, 0xb1, 0x8d, 0xa5, 0x7d, 0x5d, 0xab, 0x0c, 0x88, + 0x02, 0x67, 0xff, 0xc0, 0x02, 0x43, 0x02, 0xf9, 0xeb, 0x16, 0x4c, 0x33, 0x21, 0x77, 0xc3, 0x9d, + 0x54, 0xdb, 0x36, 0x8b, 0x69, 0x9b, 0x66, 0x9b, 0xf8, 0xb6, 0x52, 0x60, 0x4c, 0x0b, 0x27, 0x7f, + 0x0a, 0xaa, 0x4e, 0xbb, 0x1d, 0xd2, 0x28, 0xa2, 0xc2, 0x86, 0xa8, 0x0a, 0x5f, 0xf5, 0x92, 0x02, + 0x62, 0x82, 0x67, 0x4b, 0xb4, 0xdb, 0xde, 0x8d, 0xd8, 0xac, 0x97, 0x47, 0x7a, 0xbd, 0x44, 0x99, + 0x10, 0x06, 0x47, 0x4d, 0x61, 0xff, 0xd2, 0x38, 0xa4, 0x65, 0x93, 0x36, 0xcc, 0xec, 0x85, 0x3b, + 0xcb, 0xdc, 0x9f, 0xfe, 0x69, 0x22, 0x1b, 0x17, 0x8e, 0x8f, 0xe6, 0x67, 0xee, 0xa6, 0x39, 0x60, + 0x96, 0xa5, 0x94, 0x72, 0x97, 0x1e, 0xc6, 0xce, 0xce, 0xa7, 0x51, 0xa4, 0x4a, 0x8a, 0xc9, 0x01, + 0xb3, 0x2c, 0xc9, 0x9b, 0x50, 0xdb, 0x0b, 0x77, 0x94, 0x02, 0xc8, 0x86, 0x13, 0xee, 0x26, 0x28, + 0x34, 0xe9, 0x58, 0x17, 0xee, 0x85, 0x3b, 0x4c, 0x61, 0xaa, 0x6c, 0x15, 0xdd, 0x85, 0x77, 0x25, + 0x1c, 0x35, 0x05, 0x09, 0x80, 0xec, 0xa9, 0xde, 0xd3, 0xd1, 0x03, 0xa9, 0xa7, 0x4e, 0x1e, 0x7c, + 0xb8, 0xcc, 0x36, 0xdc, 0xbb, 0x43, 0x7c, 0x30, 0x87, 0x37, 0xf9, 0x02, 0x5c, 0xd9, 0x0b, 0x77, + 0xe4, 0x36, 0xb2, 0x15, 0xba, 0x5e, 0xcb, 0x0d, 0x52, 0x99, 0x29, 0xf3, 0xb2, 0xba, 0x57, 0xee, + 0xe6, 0x93, 0xe1, 0xa8, 0xf2, 0xf6, 0xdf, 0x65, 0x6b, 0xdc, 0x48, 0x22, 0x78, 0x52, 0xc4, 0x2e, + 0x82, 0xc9, 0x2e, 0x75, 0xda, 0x34, 0x54, 0xc6, 0xed, 0xed, 0x02, 0x96, 0x08, 0x67, 0x98, 0xd8, + 0xe1, 0xe2, 0x7f, 0x84, 0x4a, 0x92, 0xbd, 0x09, 0x13, 0x02, 0x76, 0x82, 0x83, 0xb3, 0xde, 0x32, + 0x4b, 0x8f, 0x71, 0x49, 0x7f, 0xc7, 0x82, 0x2a, 0x77, 0xc6, 0x74, 0xd8, 0xe1, 0x4a, 0x17, 0x19, + 0x7b, 0xcc, 0x2e, 0x1b, 0xc1, 0xa4, 0xb0, 0x0d, 0x22, 0xbe, 0x79, 0x15, 0xd2, 0x70, 0x91, 0x36, + 0x98, 0x34, 0x5c, 0x18, 0x21, 0x11, 0x2a, 0x49, 0xf6, 0xcf, 0x97, 0x60, 0xe2, 0x8e, 0x17, 0x0c, + 0x7e, 0xec, 0x53, 0xd7, 0xd6, 0x61, 0x9c, 0x9d, 0x9c, 0xd3, 0x19, 0x96, 0x53, 0x8d, 0x57, 0xcc, + 0xec, 0xca, 0x7a, 0x3a, 0xbb, 0x12, 0x9d, 0x03, 0x15, 0x15, 0x11, 0x65, 0x8c, 0x70, 0x75, 0x0f, + 0xc6, 0xef, 0xb9, 0xde, 0xde, 0xc9, 0xa6, 0x53, 0xd4, 0xf2, 0x83, 0xa1, 0xe9, 0xd4, 0x64, 0x40, + 0x14, 0x38, 0xb5, 0x66, 0xc6, 0xf2, 0xd7, 0x8c, 0xfd, 0x73, 0x16, 0x9c, 0x5f, 0xa7, 0x7d, 0xdf, + 0xfd, 0x8a, 0x93, 0x04, 0x75, 0x58, 0xa1, 0xae, 0x1b, 0xcb, 0x88, 0x8c, 0x2e, 0x74, 0xdb, 0x8d, + 0x91, 0xc1, 0x9f, 0x60, 0xd6, 0xf2, 0xfc, 0x07, 0xa6, 0x5e, 0x37, 0x12, 0x3d, 0x97, 0xe4, 0x3f, + 0x28, 0x04, 0x26, 0x34, 0xf6, 0x6f, 0x5b, 0x30, 0x29, 0x2a, 0x41, 0x15, 0x6f, 0x6b, 0x04, 0xef, + 0x2e, 0x94, 0x79, 0x39, 0xa9, 0xa1, 0xd7, 0x0a, 0x38, 0xc2, 0x33, 0x76, 0xc2, 0xdc, 0xe3, 0x3f, + 0x51, 0x08, 0x60, 0xe6, 0x78, 0xdf, 0x79, 0xb8, 0xa4, 0xe3, 0x59, 0xda, 0x1c, 0x5f, 0xe7, 0x50, + 0x94, 0x58, 0xfb, 0x37, 0xc6, 0xa0, 0xa2, 0x9c, 0x95, 0xe4, 0x57, 0x2c, 0xa8, 0x39, 0x9e, 0xe7, + 0xc7, 0x8e, 0xf0, 0xe5, 0x89, 0xb5, 0xf0, 0xc5, 0xa7, 0xaf, 0xa5, 0x92, 0xb0, 0xb0, 0x94, 0x70, + 0xbf, 0xe5, 0xc5, 0xe1, 0x61, 0xb2, 0x85, 0x18, 0x18, 0x34, 0x2b, 0x41, 0xbe, 0x0a, 0x13, 0x3d, + 0x67, 0x87, 0xf6, 0xd4, 0xd2, 0x78, 0x50, 0x60, 0x75, 0xee, 0x71, 0xc6, 0xa2, 0x26, 0xba, 0x87, + 0x04, 0x10, 0xa5, 0xd4, 0xb9, 0x9f, 0x86, 0xd9, 0x6c, 0xad, 0xc9, 0xac, 0x31, 0xcc, 0x62, 0x64, + 0x2f, 0xa6, 0x94, 0xa3, 0x5a, 0x17, 0xa5, 0xb7, 0xac, 0xb9, 0x3f, 0x0b, 0x35, 0x43, 0xcc, 0x69, + 0x8a, 0xda, 0xef, 0x40, 0x6d, 0x9d, 0xc6, 0xa1, 0xdb, 0xe2, 0x0c, 0x9e, 0x34, 0xb9, 0x4e, 0xa4, + 0x9f, 0x7f, 0x81, 0x4f, 0x56, 0xc6, 0x33, 0x22, 0x1f, 0x03, 0x04, 0xa1, 0xdf, 0xa7, 0x71, 0x97, + 0x0e, 0xd4, 0x60, 0x17, 0x60, 0x73, 0x6e, 0x69, 0x9e, 0xc2, 0xab, 0x94, 0xfc, 0x47, 0x43, 0x9e, + 0x7d, 0x1d, 0xca, 0xeb, 0x83, 0x98, 0x3e, 0x7c, 0xb2, 0xaa, 0xb0, 0xbf, 0x08, 0x53, 0x9c, 0xf4, + 0xb6, 0xdf, 0x63, 0x5a, 0x88, 0xb5, 0xb4, 0xcf, 0xfe, 0x67, 0x0f, 0x6f, 0x9c, 0x08, 0x05, 0x8e, + 0xad, 0x80, 0xae, 0xdf, 0x6b, 0xd3, 0x50, 0xf6, 0x87, 0x1e, 0xdf, 0xdb, 0x1c, 0x8a, 0x12, 0x6b, + 0xff, 0xe5, 0x12, 0xd4, 0x78, 0x41, 0xa9, 0x3d, 0x0e, 0x61, 0xb2, 0x2b, 0xe4, 0xc8, 0x2e, 0x29, + 0x20, 0x28, 0x65, 0xd6, 0xde, 0xd8, 0x8d, 0x05, 0x00, 0x95, 0x3c, 0x26, 0xfa, 0xc0, 0x71, 0x63, + 0x26, 0xba, 0x74, 0xb6, 0xa2, 0xdf, 0x15, 0x62, 0x50, 0xc9, 0xb3, 0xff, 0xfb, 0x0c, 0xc0, 0x86, + 0xdf, 0xa6, 0xb2, 0x13, 0xe6, 0xa0, 0xe4, 0xb6, 0x65, 0xf7, 0x82, 0x2c, 0x54, 0xba, 0xb3, 0x82, + 0x25, 0xb7, 0xad, 0xc7, 0xab, 0x34, 0x52, 0xb5, 0xbf, 0x09, 0xb5, 0xb6, 0x1b, 0x05, 0x3d, 0xe7, + 0x70, 0x23, 0xc7, 0x58, 0x5c, 0x49, 0x50, 0x68, 0xd2, 0x91, 0xd7, 0x65, 0x5e, 0x80, 0x30, 0x14, + 0xeb, 0x99, 0xbc, 0x80, 0x0a, 0xab, 0x9e, 0x91, 0x12, 0xf0, 0x16, 0x4c, 0x29, 0x3f, 0x35, 0x97, + 0x52, 0xe6, 0xa5, 0x2e, 0xaa, 0x88, 0xdf, 0xb6, 0x81, 0xc3, 0x14, 0xe5, 0x90, 0x57, 0x7d, 0xe2, + 0xd9, 0x7b, 0xd5, 0x3f, 0x07, 0xd3, 0xea, 0x2f, 0xdf, 0xef, 0xea, 0x17, 0x79, 0xed, 0xf5, 0x21, + 0x66, 0xdb, 0x44, 0x62, 0x9a, 0x96, 0xfc, 0x14, 0x94, 0x83, 0xae, 0x13, 0x51, 0xe9, 0xdf, 0x56, + 0x4e, 0xa6, 0xf2, 0x16, 0x03, 0x3e, 0x3a, 0x9a, 0xaf, 0xb2, 0x9e, 0xe2, 0x7f, 0x50, 0x10, 0x92, + 0x1b, 0x00, 0x3b, 0xfe, 0xc0, 0x6b, 0x3b, 0xe1, 0xe1, 0x9d, 0x15, 0x19, 0x13, 0xd3, 0x56, 0x49, + 0x43, 0x63, 0xd0, 0xa0, 0x32, 0x53, 0x22, 0xaa, 0x8f, 0x4f, 0x89, 0x20, 0x5f, 0x84, 0x2a, 0x8f, + 0x1f, 0xd2, 0xf6, 0x52, 0x2c, 0xbd, 0xd3, 0xa7, 0x09, 0x35, 0xe9, 0xed, 0xb5, 0xa9, 0x98, 0x60, + 0xc2, 0x8f, 0x7c, 0x09, 0x60, 0xd7, 0xf5, 0xdc, 0xa8, 0xcb, 0xb9, 0xd7, 0x4e, 0xcd, 0x5d, 0xb7, + 0x73, 0x55, 0x73, 0x41, 0x83, 0x23, 0x79, 0x1f, 0xce, 0xd3, 0x28, 0x76, 0xfb, 0x4e, 0x4c, 0xdb, + 0x3a, 0x5d, 0xaa, 0xce, 0x43, 0xa6, 0x3a, 0x82, 0x7b, 0x2b, 0x4b, 0xf0, 0x28, 0x0f, 0x88, 0xc3, + 0x8c, 0xc8, 0x5b, 0x50, 0x09, 0x42, 0xbf, 0xc3, 0x4e, 0x94, 0xf5, 0x39, 0xde, 0x8d, 0x57, 0xd5, + 0x01, 0x68, 0x4b, 0xc2, 0x1f, 0x19, 0xbf, 0x51, 0x53, 0x93, 0x3f, 0xb2, 0xe0, 0x7c, 0x48, 0x85, + 0x7b, 0x37, 0xd2, 0x15, 0xbb, 0xc4, 0xf5, 0x42, 0xab, 0x88, 0x5b, 0x24, 0x6a, 0xb1, 0x2f, 0x60, + 0x56, 0x8a, 0xd8, 0x10, 0xa9, 0x6a, 0xfd, 0x10, 0xfe, 0x51, 0x1e, 0xf0, 0xe7, 0x7e, 0x7f, 0x7e, + 0x7e, 0xf8, 0x4a, 0x93, 0x66, 0xce, 0x56, 0xde, 0x5f, 0xfb, 0xfd, 0xf9, 0x59, 0xf5, 0x3f, 0xe9, + 0xb4, 0xa1, 0x46, 0x32, 0xfd, 0x1e, 0xf8, 0xed, 0x3b, 0x5b, 0x32, 0x8c, 0xa0, 0xf5, 0xfb, 0x16, + 0x03, 0xa2, 0xc0, 0x91, 0xd7, 0xa0, 0xd2, 0x76, 0x68, 0xdf, 0xf7, 0x68, 0xbb, 0x3e, 0x9d, 0x38, + 0xe7, 0x56, 0x24, 0x0c, 0x35, 0x96, 0xf4, 0x60, 0xc2, 0xe5, 0xa6, 0x7e, 0xfd, 0x1c, 0x9f, 0x3d, + 0x05, 0x9c, 0x2f, 0xc4, 0xd1, 0x41, 0x24, 0xde, 0x89, 0xdf, 0x28, 0x65, 0x90, 0x00, 0x26, 0xfd, + 0x41, 0xcc, 0xc5, 0xcd, 0x70, 0x71, 0x05, 0x04, 0x29, 0x36, 0x05, 0x43, 0x71, 0x47, 0x41, 0xfe, + 0x41, 0x25, 0x86, 0xf5, 0x44, 0xab, 0xeb, 0xf6, 0xda, 0x21, 0xf5, 0xea, 0xb3, 0xdc, 0xa7, 0xc1, + 0x7b, 0x62, 0x59, 0xc2, 0x50, 0x63, 0xc9, 0x9f, 0x81, 0x69, 0x7f, 0x10, 0xf3, 0x45, 0xce, 0xc6, + 0x3f, 0xaa, 0x9f, 0xe7, 0xe4, 0xdc, 0x5b, 0xbe, 0x69, 0x22, 0x30, 0x4d, 0xc7, 0x94, 0x6d, 0xd7, + 0x8f, 0x62, 0xf6, 0x87, 0x2b, 0xdb, 0xcb, 0x69, 0x65, 0x7b, 0xdb, 0xc0, 0x61, 0x8a, 0x92, 0x7c, + 0xcb, 0x82, 0xf3, 0xfd, 0xac, 0x89, 0x5e, 0xbf, 0xc2, 0x7b, 0xa6, 0x59, 0x84, 0x29, 0x97, 0x61, + 0x2d, 0x02, 0xd7, 0x43, 0x60, 0x1c, 0xae, 0x04, 0xcf, 0x37, 0x8e, 0x0e, 0xbd, 0x56, 0x37, 0xf4, + 0xbd, 0x74, 0xf5, 0x9e, 0xe7, 0xd5, 0xfb, 0x62, 0x41, 0xab, 0x2c, 0x4f, 0x44, 0xe3, 0xf9, 0xe3, + 0xa3, 0xf9, 0x4b, 0xb9, 0x28, 0xcc, 0xaf, 0xd4, 0xdc, 0x0a, 0x5c, 0xce, 0x5f, 0xa9, 0x4f, 0xb2, + 0x29, 0xc7, 0x4c, 0x9b, 0x72, 0x15, 0x9e, 0x1f, 0x59, 0x29, 0xa6, 0xf3, 0x95, 0x01, 0x62, 0xa5, + 0x75, 0xfe, 0x90, 0xc1, 0x70, 0x0e, 0xa6, 0xcc, 0x8b, 0x68, 0x3c, 0x74, 0x61, 0xe4, 0xd8, 0x93, + 0x8f, 0xa1, 0xea, 0x37, 0x0b, 0x0f, 0x5d, 0x6c, 0x36, 0x87, 0x42, 0x17, 0x1a, 0x84, 0x89, 0xc0, + 0x27, 0x85, 0x2e, 0x7e, 0x71, 0x0c, 0x92, 0x72, 0xe4, 0x75, 0xa8, 0x50, 0xaf, 0x1d, 0xf8, 0xae, + 0x17, 0x67, 0x23, 0x40, 0xb7, 0x24, 0x1c, 0x35, 0x85, 0x11, 0xe8, 0x28, 0x3d, 0x36, 0xd0, 0xd1, + 0x86, 0x19, 0x87, 0xa7, 0xbd, 0x24, 0x6e, 0xea, 0xb1, 0x53, 0xfb, 0xe5, 0x96, 0xd2, 0x1c, 0x30, + 0xcb, 0x92, 0x49, 0x89, 0x92, 0xa2, 0x5c, 0xca, 0xf8, 0xa9, 0xa5, 0x34, 0xd3, 0x1c, 0x30, 0xcb, + 0x92, 0xbc, 0x0f, 0xf5, 0x16, 0x4f, 0x34, 0x14, 0x6d, 0xbc, 0xb3, 0xbb, 0xe1, 0xc7, 0x5b, 0x21, + 0x8d, 0xa8, 0x27, 0xc2, 0x08, 0x95, 0xc6, 0x4b, 0xb2, 0x17, 0xea, 0xcb, 0x23, 0xe8, 0x70, 0x24, + 0x07, 0xfb, 0x3f, 0x94, 0x40, 0x29, 0xb5, 0x1f, 0x6f, 0x67, 0x0c, 0xb1, 0x61, 0x22, 0xa4, 0x91, + 0xba, 0x20, 0x50, 0x15, 0xfb, 0x0b, 0x72, 0x08, 0x4a, 0x0c, 0xd3, 0xf6, 0xf4, 0xa1, 0x1b, 0x2f, + 0xfb, 0x6d, 0x65, 0x29, 0x73, 0x6d, 0x7f, 0x4b, 0xc2, 0x50, 0x63, 0xed, 0xbf, 0x62, 0xc1, 0x34, + 0x6b, 0x65, 0xaf, 0x47, 0x7b, 0xcd, 0x98, 0x06, 0x11, 0x89, 0xa0, 0x1c, 0xb1, 0x1f, 0xc5, 0x9d, + 0x6c, 0x92, 0x4c, 0x26, 0x1a, 0x18, 0x3e, 0x1c, 0x26, 0x04, 0x85, 0x2c, 0xfb, 0x7f, 0x96, 0xa0, + 0xaa, 0x3b, 0xfb, 0x04, 0x8e, 0xa1, 0x1b, 0xc9, 0x35, 0x09, 0xb1, 0xc2, 0xea, 0xc6, 0x15, 0x09, + 0x66, 0xde, 0x2e, 0x79, 0x87, 0x22, 0xf1, 0x5d, 0xdf, 0x97, 0x20, 0xaf, 0xa7, 0x1d, 0x8d, 0x97, + 0x4d, 0xef, 0x95, 0x41, 0x2f, 0x3d, 0x8e, 0x0f, 0xa1, 0xca, 0x7f, 0xac, 0xaa, 0x4b, 0x94, 0x85, + 0xcc, 0xb1, 0x07, 0x8a, 0xa5, 0x08, 0x29, 0xe8, 0xbf, 0x98, 0x08, 0xcb, 0x5c, 0x7e, 0x2c, 0x9f, + 0xe8, 0xf2, 0xe3, 0x75, 0x18, 0xa7, 0xde, 0xa0, 0xcf, 0xd3, 0x68, 0xaa, 0x7c, 0x7b, 0x1b, 0xbf, + 0xe5, 0x0d, 0xfa, 0xe9, 0x96, 0x71, 0x12, 0xfb, 0x5f, 0x58, 0xc0, 0x8c, 0xa4, 0xb5, 0x65, 0xf2, + 0xe7, 0xa1, 0x12, 0x49, 0xd5, 0x2c, 0xbb, 0xfa, 0x27, 0x74, 0x54, 0x5b, 0xc2, 0x1f, 0x1d, 0xcd, + 0x4f, 0x73, 0x62, 0x05, 0x40, 0x5d, 0x84, 0xf4, 0x60, 0x9a, 0xbb, 0x3f, 0x94, 0x9e, 0x90, 0x0e, + 0xab, 0x9b, 0x27, 0x4c, 0x46, 0x35, 0x8b, 0x0a, 0xeb, 0x22, 0x05, 0xc2, 0x34, 0x73, 0xfb, 0x5f, + 0x8e, 0x83, 0xe1, 0x25, 0x38, 0xc1, 0x14, 0xf9, 0x30, 0xe3, 0x13, 0x5a, 0x2f, 0xc4, 0x27, 0xa4, + 0x1c, 0x2d, 0x62, 0xd9, 0xa5, 0xdd, 0x40, 0xac, 0x52, 0x5d, 0xda, 0x0b, 0xe4, 0x04, 0xd3, 0x95, + 0xba, 0x4d, 0x7b, 0x01, 0x72, 0x8c, 0x4e, 0xe3, 0x19, 0x1f, 0x99, 0xc6, 0xd3, 0x85, 0x72, 0xc7, + 0x19, 0x74, 0xa8, 0x0c, 0x69, 0x14, 0xe0, 0xfe, 0xe3, 0xc1, 0x6c, 0xe1, 0xfe, 0xe3, 0x3f, 0x51, + 0x08, 0x60, 0x33, 0xbc, 0xab, 0xbc, 0xf0, 0xf2, 0x7c, 0x5b, 0xc0, 0x0c, 0xd7, 0x8e, 0x7d, 0x31, + 0xc3, 0xf5, 0x5f, 0x4c, 0x84, 0x31, 0xf3, 0xb7, 0x25, 0x72, 0xd8, 0x65, 0x54, 0xf6, 0x4e, 0x11, + 0x79, 0x4a, 0x9c, 0xa1, 0x30, 0x7f, 0xe5, 0x1f, 0x54, 0x62, 0xec, 0x45, 0xa8, 0x19, 0xd7, 0x08, + 0xd9, 0x30, 0xe8, 0xf4, 0x69, 0x63, 0x18, 0x56, 0x9c, 0xd8, 0x41, 0x8e, 0xb1, 0xff, 0xce, 0x18, + 0xe8, 0x63, 0x88, 0x99, 0x81, 0xe4, 0xb4, 0x8c, 0x1b, 0x3b, 0xa9, 0xf4, 0x4a, 0xdf, 0x43, 0x89, + 0x65, 0x27, 0xf7, 0x3e, 0x0d, 0x3b, 0xda, 0xf0, 0x91, 0x3a, 0x4a, 0x9f, 0xdc, 0xd7, 0x4d, 0x24, + 0xa6, 0x69, 0x99, 0xa5, 0xd1, 0x77, 0x3c, 0x77, 0x97, 0x46, 0x71, 0x36, 0xa2, 0xb8, 0x2e, 0xe1, + 0xa8, 0x29, 0xc8, 0x1a, 0x9c, 0x8f, 0x68, 0xbc, 0x79, 0xe0, 0xd1, 0x50, 0xa7, 0x7d, 0xca, 0x3c, + 0xe0, 0xe7, 0xd5, 0xd9, 0xac, 0x99, 0x25, 0xc0, 0xe1, 0x32, 0x64, 0x05, 0x66, 0x65, 0x0a, 0xae, + 0xce, 0xa0, 0x94, 0xba, 0x47, 0x5f, 0xdc, 0x6e, 0x66, 0xf0, 0x38, 0x54, 0x82, 0x71, 0xd9, 0x75, + 0xdc, 0xde, 0x20, 0xa4, 0x09, 0x97, 0x89, 0x34, 0x97, 0xd5, 0x0c, 0x1e, 0x87, 0x4a, 0xf0, 0x44, + 0x85, 0x9e, 0xd3, 0x89, 0xea, 0x93, 0x46, 0xa2, 0x02, 0x03, 0xa0, 0x80, 0xdb, 0xff, 0xc4, 0x82, + 0x69, 0xa4, 0x71, 0x78, 0xb8, 0xb4, 0xcb, 0x4e, 0xe9, 0xf1, 0x21, 0xf9, 0x75, 0x0b, 0x66, 0x3d, + 0xbf, 0x4d, 0x97, 0xbc, 0xd8, 0x55, 0xc0, 0xe2, 0xae, 0x04, 0x72, 0x59, 0x1b, 0x19, 0xf6, 0x22, + 0x9b, 0x37, 0x0b, 0xc5, 0xa1, 0x6a, 0xd8, 0x57, 0xe0, 0x52, 0x2e, 0x03, 0xfb, 0xdb, 0x63, 0xb2, + 0x19, 0x7a, 0xf0, 0xdf, 0x81, 0x72, 0x8f, 0x67, 0x36, 0x5b, 0x9f, 0xf2, 0x9a, 0x17, 0xef, 0x2b, + 0x91, 0xfa, 0x2c, 0x38, 0x91, 0x15, 0xa8, 0x85, 0x4c, 0x86, 0xcc, 0x3b, 0x17, 0x53, 0xd1, 0x4e, + 0x2e, 0x91, 0x6b, 0xd4, 0xa3, 0xf4, 0x5f, 0x34, 0x8b, 0x91, 0x8f, 0x60, 0x72, 0x47, 0xdc, 0x5c, + 0x93, 0x16, 0x6a, 0x01, 0x4b, 0x56, 0x5e, 0x85, 0xe3, 0x3b, 0xb1, 0xba, 0x17, 0xf7, 0x28, 0xf9, + 0x89, 0x4a, 0x22, 0x39, 0x84, 0x8a, 0xa3, 0xc6, 0x74, 0xbc, 0xa8, 0xd4, 0x80, 0xd4, 0xfc, 0x11, + 0xf6, 0x91, 0x1e, 0x43, 0x2d, 0xce, 0xfe, 0x8e, 0x05, 0x90, 0x5c, 0x5c, 0x27, 0x0f, 0xa1, 0x12, + 0xdd, 0x4c, 0x1d, 0x58, 0x8a, 0x48, 0x02, 0x95, 0x1c, 0x8d, 0xa4, 0x32, 0x09, 0x41, 0x2d, 0xed, + 0x49, 0xa7, 0x95, 0x6f, 0x96, 0x41, 0x97, 0x3a, 0xa3, 0xc3, 0xca, 0xab, 0xcc, 0xf0, 0xec, 0x24, + 0x17, 0x05, 0x35, 0x1d, 0x72, 0x28, 0x4a, 0x2c, 0x33, 0x3e, 0x55, 0x46, 0x8b, 0xd4, 0x44, 0xbc, + 0x73, 0x55, 0xf2, 0x0b, 0x6a, 0x6c, 0xde, 0xf1, 0xa7, 0xfc, 0x4c, 0x8e, 0x3f, 0x13, 0xc5, 0x1f, + 0x7f, 0xae, 0xc3, 0x64, 0xe8, 0xf7, 0xe8, 0x12, 0x6e, 0x48, 0x97, 0xab, 0x3e, 0x16, 0xa3, 0x00, + 0xa3, 0xc2, 0x93, 0x37, 0xa1, 0x36, 0x88, 0x68, 0x73, 0xe5, 0xee, 0x72, 0x48, 0xdb, 0x91, 0x4c, + 0x12, 0xd2, 0xae, 0xef, 0xfb, 0x09, 0x0a, 0x4d, 0x3a, 0xf2, 0x5b, 0xd6, 0x63, 0x4e, 0x58, 0xd5, + 0xa2, 0x54, 0x5d, 0xee, 0x65, 0xb1, 0xc6, 0xd5, 0x4f, 0x79, 0x6c, 0xfb, 0xba, 0x05, 0xe7, 0x9a, + 0xad, 0xd0, 0x0d, 0x62, 0xbd, 0x89, 0x6e, 0xf0, 0x4b, 0xa3, 0xb1, 0xc3, 0x74, 0x99, 0x5c, 0x43, + 0x2f, 0x8e, 0xc8, 0xdb, 0x10, 0x44, 0xa9, 0xab, 0xe5, 0x02, 0x84, 0x09, 0x0b, 0x36, 0x2d, 0x65, + 0x2e, 0x6d, 0x66, 0xfa, 0xa6, 0xb3, 0x5f, 0xed, 0x0f, 0x60, 0xb6, 0x49, 0xfb, 0x4e, 0xd0, 0xe5, + 0x39, 0x56, 0x22, 0x98, 0xb2, 0x08, 0xd5, 0x48, 0xc1, 0xb2, 0xf7, 0xd8, 0x35, 0x31, 0x26, 0x34, + 0xe4, 0x15, 0x11, 0xf8, 0x51, 0x09, 0x18, 0x55, 0x61, 0x6e, 0x88, 0x68, 0x51, 0x84, 0x0a, 0x67, + 0x1f, 0xc0, 0x54, 0x52, 0x9c, 0xee, 0x92, 0x0e, 0xcc, 0xb4, 0x8c, 0x34, 0x94, 0xe4, 0xba, 0xfa, + 0xc9, 0x33, 0x56, 0xf8, 0x2c, 0x5c, 0x4e, 0x33, 0xc1, 0x2c, 0x57, 0xfb, 0x97, 0x4b, 0x30, 0xa3, + 0x25, 0x4b, 0x87, 0xcd, 0x27, 0xd9, 0x60, 0x15, 0x16, 0x91, 0xb7, 0x9e, 0xee, 0xc9, 0xc7, 0x04, + 0xac, 0x3e, 0xc9, 0x06, 0xac, 0xce, 0x54, 0xfc, 0x90, 0x0f, 0xea, 0x3b, 0x25, 0xa8, 0xe8, 0x2c, + 0xfa, 0x77, 0xa0, 0xcc, 0x2d, 0xc2, 0xa7, 0xdb, 0x5e, 0xb9, 0x75, 0x89, 0x82, 0x13, 0x63, 0xc9, + 0xe3, 0x10, 0x9f, 0xfa, 0x62, 0x76, 0x55, 0x1c, 0x86, 0x9d, 0x30, 0x46, 0xc1, 0x89, 0xdc, 0x85, + 0x31, 0xea, 0xb5, 0xe5, 0x3e, 0x7b, 0x7a, 0x86, 0xfc, 0x3d, 0x89, 0x5b, 0x5e, 0x1b, 0x19, 0x17, + 0x7e, 0xaf, 0x94, 0xa7, 0x5a, 0xcb, 0x33, 0x47, 0x72, 0xaf, 0x94, 0x43, 0x51, 0x62, 0xed, 0x5f, + 0x1c, 0x83, 0x89, 0xe6, 0x60, 0x87, 0x59, 0x0c, 0x7f, 0xdf, 0x82, 0x0b, 0x07, 0x99, 0x4b, 0xbb, + 0xc9, 0x94, 0xbd, 0x5f, 0xfc, 0x8d, 0x68, 0xa4, 0xbb, 0x8d, 0x17, 0x64, 0xbd, 0x2e, 0xe4, 0x20, + 0x31, 0xaf, 0x3a, 0xa9, 0x2b, 0xa7, 0x63, 0x67, 0x74, 0x15, 0xdc, 0xb8, 0xd8, 0x53, 0x2a, 0xfe, + 0x62, 0xcf, 0xf4, 0xa8, 0x4b, 0x3d, 0xf6, 0xbf, 0x1e, 0x07, 0x10, 0xa3, 0xb1, 0x19, 0xc4, 0x27, + 0x39, 0xed, 0xbe, 0x05, 0x53, 0xea, 0x65, 0xb4, 0x8d, 0x24, 0xf0, 0xaa, 0x9d, 0xef, 0x6b, 0x06, + 0x0e, 0x53, 0x94, 0xe4, 0x06, 0x00, 0xf5, 0xe2, 0xf0, 0x50, 0x98, 0x0b, 0xe3, 0x69, 0x77, 0xc3, + 0x2d, 0x8d, 0x41, 0x83, 0x8a, 0x2c, 0xa4, 0x3c, 0x70, 0xe2, 0xba, 0xcf, 0xb9, 0xc7, 0x38, 0xcc, + 0x3e, 0x07, 0xd3, 0xfa, 0xdf, 0xaa, 0xdb, 0x53, 0x89, 0x73, 0xfa, 0x40, 0xb4, 0x65, 0x22, 0x31, + 0x4d, 0x4b, 0x7e, 0x1a, 0xce, 0xa5, 0x53, 0xb5, 0xe5, 0x06, 0xab, 0xef, 0x17, 0xa4, 0x33, 0xbc, + 0x31, 0x43, 0xcd, 0x56, 0x40, 0x3b, 0x3c, 0xc4, 0x81, 0x27, 0x77, 0x5a, 0xbd, 0x02, 0x56, 0x38, + 0x14, 0x25, 0x96, 0x75, 0x21, 0x2b, 0x49, 0x43, 0x01, 0xe7, 0x5b, 0x6a, 0x25, 0xe9, 0xc2, 0xa6, + 0x81, 0xc3, 0x14, 0x25, 0x93, 0x20, 0x5d, 0x0d, 0x90, 0x5e, 0x63, 0x19, 0xff, 0x40, 0x00, 0xe7, + 0xfc, 0xf4, 0x49, 0x4d, 0x84, 0x2a, 0x3f, 0x7b, 0xc2, 0x79, 0x9b, 0x2a, 0x2b, 0x72, 0xa1, 0x33, + 0x07, 0xbb, 0x0c, 0x7f, 0xfb, 0x02, 0x9c, 0x6f, 0x0e, 0x82, 0xa0, 0xe7, 0xd2, 0xb6, 0xf6, 0x35, + 0xd9, 0x3f, 0x03, 0x33, 0xf2, 0x6a, 0xa8, 0xde, 0x94, 0x4f, 0xf5, 0x1a, 0x85, 0xfd, 0x47, 0x16, + 0xcc, 0x64, 0x82, 0x03, 0xe4, 0xa3, 0xec, 0x56, 0x5a, 0x88, 0xeb, 0xd0, 0xdc, 0x45, 0xc5, 0x72, + 0xc9, 0xdd, 0x96, 0xbb, 0x2a, 0xd9, 0xa3, 0xb0, 0x9c, 0x29, 0x9e, 0x12, 0x21, 0x74, 0xb3, 0x99, + 0x31, 0x62, 0xff, 0x42, 0x09, 0xf2, 0x23, 0x32, 0xe4, 0xab, 0xc3, 0x1d, 0xf0, 0x4e, 0x81, 0x1d, + 0x20, 0x43, 0x42, 0xa3, 0xfb, 0xc0, 0x4b, 0xf7, 0xc1, 0x7a, 0x41, 0x7d, 0x20, 0xe5, 0x0e, 0xf7, + 0xc4, 0xff, 0xb1, 0xa0, 0xb6, 0xbd, 0x7d, 0x4f, 0x1f, 0x5d, 0x11, 0x2e, 0x47, 0xe2, 0x42, 0xf0, + 0xd2, 0x6e, 0x4c, 0xc3, 0x65, 0xbf, 0x1f, 0xf4, 0xa8, 0x9e, 0x50, 0xf2, 0x96, 0x6e, 0x33, 0x97, + 0x02, 0x47, 0x94, 0x24, 0x77, 0xe0, 0x82, 0x89, 0x91, 0x0e, 0x08, 0xde, 0xc2, 0xb2, 0xcc, 0xd1, + 0x1f, 0x46, 0x63, 0x5e, 0x99, 0x2c, 0x2b, 0xe9, 0x85, 0x90, 0x8f, 0xe7, 0x0d, 0xb1, 0x92, 0x68, + 0xcc, 0x2b, 0x63, 0x6f, 0x42, 0xcd, 0x78, 0xca, 0x91, 0x7c, 0x1e, 0x66, 0x5b, 0x7e, 0x3f, 0x08, + 0x69, 0x14, 0xb9, 0xbe, 0x77, 0x8f, 0xee, 0xd3, 0x9e, 0x6c, 0x32, 0x77, 0x10, 0x2c, 0x67, 0x70, + 0x38, 0x44, 0x6d, 0xff, 0xc1, 0x0b, 0xa0, 0xef, 0x95, 0x9e, 0x40, 0xd7, 0x07, 0x3a, 0x56, 0x5d, + 0x2e, 0x38, 0x56, 0xad, 0x15, 0x57, 0x26, 0x5e, 0x1d, 0x27, 0xf1, 0xea, 0x89, 0xa2, 0xe3, 0xd5, + 0xda, 0x74, 0x1b, 0x8a, 0x59, 0xff, 0xaa, 0x05, 0x53, 0x9e, 0xdf, 0xa6, 0xda, 0xc1, 0x3c, 0xc9, + 0xed, 0xc7, 0xf7, 0x8b, 0x4b, 0xc2, 0x11, 0xb1, 0x57, 0xc9, 0x5e, 0x64, 0x34, 0x68, 0x7d, 0x6f, + 0xa2, 0x30, 0x55, 0x0f, 0xb2, 0x6a, 0xf8, 0x23, 0xc4, 0x55, 0xd0, 0xab, 0x79, 0x76, 0xfc, 0x93, + 0x9c, 0x0b, 0xe4, 0xa1, 0x61, 0xc1, 0x54, 0x8b, 0xf2, 0x26, 0xa8, 0xc4, 0x45, 0xc3, 0x6d, 0xa8, + 0x2e, 0x9a, 0x27, 0x96, 0x8d, 0x0d, 0x13, 0x22, 0xf5, 0x41, 0x3e, 0x2a, 0xc8, 0xbd, 0xd9, 0x22, + 0x2d, 0x02, 0x25, 0x86, 0xc4, 0x2a, 0x10, 0x54, 0xe3, 0xdd, 0xbe, 0x59, 0x4c, 0x84, 0x4d, 0x07, + 0x9a, 0xf2, 0x23, 0x41, 0xe4, 0x6d, 0xf3, 0x78, 0x38, 0x75, 0x92, 0xe3, 0xe1, 0xf4, 0xc8, 0xa3, + 0x61, 0x0c, 0x13, 0x11, 0x3f, 0x7c, 0xf2, 0xe4, 0x8f, 0xda, 0x8d, 0xad, 0x02, 0xf4, 0x71, 0xea, + 0x30, 0x2b, 0xfa, 0x4d, 0xc0, 0x50, 0xca, 0x22, 0x1f, 0x43, 0x45, 0xa5, 0xab, 0xc8, 0x64, 0x12, + 0x2c, 0xc2, 0x5b, 0x95, 0xf6, 0x45, 0xab, 0x5b, 0x66, 0x02, 0x8a, 0x5a, 0x22, 0xe9, 0xc2, 0x58, + 0xdb, 0xe9, 0xc8, 0xb4, 0x92, 0xf5, 0x62, 0xee, 0xbe, 0x2a, 0x99, 0xfc, 0x64, 0xb1, 0xb2, 0xb4, + 0x86, 0x4c, 0x04, 0x79, 0x98, 0x3c, 0x3c, 0x31, 0x5b, 0xd8, 0x76, 0x97, 0xb6, 0x4b, 0xc4, 0xf1, + 0x7a, 0xe8, 0x1d, 0x8b, 0xb6, 0x74, 0xdf, 0xff, 0x09, 0x2e, 0x76, 0xb5, 0x98, 0xcb, 0xb3, 0xe2, + 0x1d, 0xc3, 0x24, 0x04, 0x40, 0x6e, 0xc1, 0xe4, 0xbe, 0xdf, 0x1b, 0xf4, 0x65, 0x0a, 0x4c, 0xed, + 0xc6, 0x5c, 0xde, 0x3c, 0x7c, 0xc0, 0x49, 0x12, 0x2d, 0x26, 0xfe, 0x47, 0xa8, 0xca, 0x92, 0x5f, + 0xb6, 0xe0, 0x1c, 0x5b, 0xee, 0x7a, 0x86, 0x46, 0x75, 0x52, 0xd4, 0x82, 0xba, 0x1f, 0xb1, 0xed, + 0x52, 0x2d, 0x04, 0x6d, 0x10, 0xdf, 0x49, 0x89, 0xc3, 0x8c, 0x78, 0xf2, 0x09, 0x54, 0x22, 0xb7, + 0x4d, 0x5b, 0x4e, 0x18, 0xd5, 0x2f, 0x9c, 0x4d, 0x55, 0x12, 0x4f, 0xa6, 0x14, 0x84, 0x5a, 0x24, + 0xf9, 0x5b, 0xfc, 0xd9, 0x39, 0xf9, 0xcc, 0xa8, 0x7c, 0x76, 0xf6, 0xe2, 0x99, 0x3d, 0x3b, 0x2b, + 0x7c, 0x84, 0x69, 0x71, 0x98, 0x95, 0x4f, 0xfe, 0x92, 0x05, 0x97, 0xc4, 0xdb, 0x18, 0xd9, 0x87, + 0x51, 0x2e, 0x7d, 0xca, 0x53, 0x38, 0xcf, 0xdd, 0x59, 0xca, 0x63, 0x89, 0xf9, 0x92, 0xf8, 0xc5, + 0xe7, 0xd0, 0x8c, 0x06, 0xf0, 0x0c, 0xaa, 0xe2, 0x7c, 0xdd, 0xfa, 0x15, 0x5b, 0x1e, 0x6c, 0x4d, + 0x81, 0x30, 0x2d, 0x98, 0xbc, 0x01, 0xb5, 0x40, 0xea, 0x6a, 0x37, 0xea, 0xf3, 0x4c, 0xac, 0x31, + 0x91, 0xad, 0xba, 0x95, 0x80, 0xd1, 0xa4, 0x21, 0xf7, 0xa1, 0x16, 0xfb, 0x3d, 0x1a, 0xca, 0x6b, + 0x01, 0x75, 0x3e, 0xaf, 0xae, 0xe5, 0xad, 0x98, 0x6d, 0x4d, 0x96, 0x38, 0x3d, 0x13, 0x58, 0x84, + 0x26, 0x1f, 0x76, 0x72, 0x54, 0xef, 0xe8, 0x84, 0xfc, 0x60, 0xfb, 0x7c, 0xfa, 0xe4, 0xd8, 0x34, + 0x91, 0x98, 0xa6, 0x25, 0x6b, 0x70, 0x3e, 0x08, 0x5d, 0x3f, 0x74, 0xe3, 0xc3, 0xe5, 0x9e, 0x13, + 0x45, 0x9c, 0x81, 0xc8, 0xb0, 0xd4, 0xc1, 0xb1, 0xad, 0x2c, 0x01, 0x0e, 0x97, 0x21, 0xaf, 0x41, + 0x45, 0x01, 0xeb, 0x2f, 0x70, 0xd3, 0x6e, 0x4a, 0x64, 0x67, 0x0a, 0x18, 0x6a, 0xec, 0x88, 0x9b, + 0xde, 0x57, 0x3f, 0xcd, 0x4d, 0x6f, 0xd2, 0x86, 0xab, 0xce, 0x20, 0xf6, 0xf9, 0x35, 0xa5, 0x74, + 0x91, 0x6d, 0x7f, 0x8f, 0x7a, 0xf5, 0x97, 0x44, 0x56, 0xcd, 0xf1, 0xd1, 0xfc, 0xd5, 0xa5, 0xc7, + 0xd0, 0xe1, 0x63, 0xb9, 0x90, 0xaf, 0x40, 0x85, 0xca, 0xdb, 0xea, 0xf5, 0x9f, 0x28, 0x6a, 0x9b, + 0x4c, 0xdf, 0x7f, 0x57, 0xd9, 0x27, 0x02, 0x86, 0x5a, 0x1e, 0xd9, 0x86, 0x5a, 0xd7, 0x8f, 0xe2, + 0xa5, 0x9e, 0xeb, 0x44, 0x34, 0xaa, 0xbf, 0xc8, 0x27, 0x4d, 0xee, 0x76, 0x7f, 0x5b, 0x91, 0x25, + 0x73, 0xe6, 0x76, 0x52, 0x12, 0x4d, 0x36, 0x84, 0x72, 0x87, 0xff, 0x80, 0x0f, 0xa1, 0xef, 0xc5, + 0xf4, 0x61, 0x5c, 0xbf, 0xc6, 0x1b, 0xf6, 0x6a, 0x1e, 0xe7, 0x2d, 0xbf, 0xdd, 0x4c, 0x53, 0x6b, + 0x8f, 0xbf, 0x09, 0xc4, 0x2c, 0x4f, 0xf2, 0x16, 0x4c, 0x05, 0x7e, 0xbb, 0x19, 0xd0, 0xd6, 0x96, + 0x13, 0xb7, 0xba, 0xf5, 0xf9, 0xb4, 0xcb, 0x65, 0xcb, 0xc0, 0x61, 0x8a, 0x92, 0x04, 0x30, 0xd9, + 0x17, 0xf7, 0x2b, 0xea, 0x2f, 0x17, 0x65, 0x4e, 0xcb, 0x0b, 0x1b, 0x62, 0xc7, 0x94, 0x7f, 0x50, + 0x89, 0x21, 0x7f, 0xcf, 0x82, 0x99, 0x4c, 0xc6, 0x60, 0xfd, 0x27, 0x0b, 0xdb, 0xb4, 0xd3, 0x8c, + 0x1b, 0xaf, 0xf2, 0xee, 0x4b, 0x03, 0x1f, 0x0d, 0x83, 0x30, 0x5b, 0x23, 0xd1, 0x2f, 0xfc, 0x92, + 0x54, 0xfd, 0x95, 0xe2, 0xfa, 0x85, 0x33, 0x54, 0xfd, 0xc2, 0xff, 0xa0, 0x12, 0x43, 0xae, 0xc3, + 0x64, 0xec, 0xf6, 0xa9, 0x3f, 0x88, 0xeb, 0xaf, 0xa6, 0xa3, 0x36, 0xdb, 0x02, 0x8c, 0x0a, 0x3f, + 0xf7, 0x33, 0x70, 0x7e, 0xe8, 0xb4, 0x70, 0xaa, 0x9b, 0x3a, 0xbf, 0xc6, 0x0e, 0xcc, 0x86, 0xff, + 0xb2, 0xe8, 0x67, 0x88, 0xde, 0x82, 0xa9, 0x96, 0x78, 0x71, 0x51, 0x5c, 0x17, 0x18, 0x4f, 0xfb, + 0xaf, 0x96, 0x0d, 0x1c, 0xa6, 0x28, 0xed, 0xdb, 0x40, 0x86, 0xdf, 0xef, 0xe0, 0x8e, 0xc1, 0x87, + 0xea, 0xa0, 0x2a, 0x6b, 0x99, 0x38, 0x06, 0x35, 0x06, 0x0d, 0x2a, 0xfb, 0x1f, 0x5a, 0x30, 0x9d, + 0xb2, 0x04, 0x0a, 0x0f, 0xf7, 0xac, 0x02, 0xe9, 0xbb, 0x61, 0xe8, 0x87, 0xc2, 0xd0, 0x5a, 0x67, + 0x8a, 0x2c, 0x92, 0x2f, 0x2f, 0xf0, 0x5b, 0xbd, 0xeb, 0x43, 0x58, 0xcc, 0x29, 0x61, 0xff, 0xca, + 0x18, 0x24, 0xe9, 0x57, 0xfa, 0x62, 0xbb, 0x35, 0xf2, 0x62, 0xfb, 0xeb, 0x50, 0xf9, 0x20, 0xf2, + 0xbd, 0xad, 0xe4, 0xfa, 0xbb, 0x1e, 0x8b, 0xb7, 0x9b, 0x9b, 0x1b, 0x9c, 0x52, 0x53, 0x70, 0xea, + 0x0f, 0x57, 0xdd, 0x5e, 0x3c, 0x7c, 0x2d, 0xfc, 0xed, 0x77, 0x04, 0x1c, 0x35, 0x05, 0x7f, 0x20, + 0x72, 0x9f, 0x6a, 0xc7, 0x66, 0xf2, 0x40, 0x24, 0x03, 0xa2, 0xc0, 0x91, 0x45, 0xa8, 0x6a, 0xbf, + 0xa8, 0x74, 0xd3, 0xea, 0x9e, 0xd2, 0xfe, 0x53, 0x4c, 0x68, 0xb8, 0x99, 0x27, 0x7d, 0x7f, 0xf2, + 0xd4, 0xde, 0x2c, 0xc2, 0x40, 0xcf, 0x78, 0x13, 0x85, 0x6e, 0x57, 0x60, 0xd4, 0x22, 0xcd, 0x14, + 0xbd, 0xf2, 0x09, 0x53, 0xf4, 0xec, 0xbf, 0x3a, 0x06, 0x93, 0x0f, 0x68, 0xc8, 0x9f, 0xb3, 0xb8, + 0x0e, 0x93, 0xfb, 0xe2, 0x67, 0x36, 0xcf, 0x58, 0x52, 0xa0, 0xc2, 0xb3, 0xae, 0xd9, 0x19, 0xb8, + 0xbd, 0xf6, 0x4a, 0xb2, 0x50, 0x74, 0xd7, 0x34, 0x14, 0x02, 0x13, 0x1a, 0x56, 0xa0, 0xc3, 0x4c, + 0xe2, 0x7e, 0xdf, 0x8d, 0xb3, 0xf7, 0x37, 0xd7, 0x14, 0x02, 0x13, 0x1a, 0xf2, 0x2a, 0x4c, 0x74, + 0xdc, 0x78, 0xdb, 0xe9, 0x64, 0xa3, 0x28, 0x6b, 0x1c, 0x8a, 0x12, 0xcb, 0xdd, 0xf0, 0x6e, 0xbc, + 0x1d, 0x52, 0xee, 0xaf, 0x1b, 0xba, 0x70, 0xb4, 0x66, 0xe0, 0x30, 0x45, 0xc9, 0xab, 0xe4, 0xcb, + 0x96, 0x49, 0xf7, 0x78, 0x52, 0x25, 0x85, 0xc0, 0x84, 0x86, 0x4d, 0xb1, 0x96, 0xdf, 0x0f, 0xdc, + 0x9e, 0xcc, 0xa2, 0x32, 0xa6, 0xd8, 0xb2, 0x84, 0xa3, 0xa6, 0x60, 0xd4, 0x4c, 0x4b, 0xb0, 0x15, + 0x9e, 0x7d, 0xef, 0x6e, 0x4b, 0xc2, 0x51, 0x53, 0xd8, 0x0f, 0x60, 0x5a, 0x2c, 0x96, 0xe5, 0x9e, + 0xe3, 0xf6, 0xd7, 0x96, 0xc9, 0xad, 0xa1, 0x54, 0xc1, 0xeb, 0x39, 0xa9, 0x82, 0x97, 0x52, 0x85, + 0x86, 0x53, 0x06, 0xed, 0xef, 0x95, 0xa0, 0xf2, 0x0c, 0x9f, 0x0c, 0x0d, 0x52, 0x4f, 0x86, 0x16, + 0xfd, 0x70, 0x64, 0xde, 0x73, 0xa1, 0x0f, 0x33, 0xcf, 0x85, 0x6e, 0x15, 0x99, 0x3d, 0xfb, 0xd8, + 0xa7, 0x42, 0x7f, 0x60, 0xc1, 0x45, 0x45, 0xca, 0xf5, 0x46, 0xc3, 0xf5, 0x78, 0xfc, 0xf5, 0xec, + 0xbb, 0xf9, 0xe3, 0x54, 0x37, 0xbf, 0x57, 0x5c, 0x93, 0xcd, 0x76, 0x8c, 0x7c, 0x35, 0xf9, 0x0f, + 0x2d, 0xa8, 0xe7, 0x15, 0x78, 0x06, 0x6f, 0xa5, 0x7e, 0x94, 0x7e, 0x2b, 0xf5, 0xc1, 0xd9, 0xb4, + 0x7c, 0xc4, 0x9b, 0xa9, 0x3f, 0x18, 0xd1, 0x6e, 0xfe, 0x40, 0x69, 0x4f, 0xed, 0x28, 0x56, 0x51, + 0x01, 0x11, 0x21, 0x22, 0x7f, 0x6b, 0xea, 0xc1, 0x44, 0xc4, 0x83, 0x95, 0x72, 0x0a, 0xdc, 0x2e, + 0x62, 0x9f, 0x61, 0xfc, 0xa4, 0x7f, 0x8d, 0xff, 0x46, 0x29, 0xc3, 0xfe, 0xcf, 0x16, 0x4c, 0x3d, + 0xc3, 0x07, 0x71, 0xfd, 0xf4, 0x20, 0xbf, 0x5d, 0xdc, 0x20, 0x8f, 0x18, 0xd8, 0xff, 0x78, 0x15, + 0x52, 0x6f, 0xcf, 0x92, 0x8f, 0xa0, 0xaa, 0x8c, 0x3c, 0x95, 0x95, 0xff, 0x76, 0x71, 0x3e, 0xf0, + 0x64, 0x9b, 0x51, 0x90, 0x08, 0x13, 0x79, 0x99, 0xf0, 0x70, 0xe9, 0x44, 0xe1, 0xe1, 0x1f, 0xee, + 0x83, 0x98, 0xf9, 0x47, 0xf0, 0xf1, 0x33, 0x39, 0x82, 0x5f, 0x2d, 0xfc, 0x08, 0xfe, 0xe2, 0x33, + 0x3e, 0x82, 0x1b, 0x5e, 0xce, 0xf2, 0x53, 0x78, 0x39, 0x3f, 0x82, 0x8b, 0xfb, 0xc9, 0xe6, 0xaf, + 0x67, 0x92, 0x7c, 0xd7, 0xf3, 0x7a, 0xee, 0xc1, 0x9b, 0x19, 0x32, 0x51, 0x4c, 0xbd, 0xd8, 0x30, + 0x1b, 0xf4, 0xd5, 0xd7, 0x8b, 0x0f, 0x72, 0xd8, 0x61, 0xae, 0x90, 0xac, 0xbb, 0x6a, 0xf2, 0x04, + 0xee, 0xaa, 0x7f, 0x34, 0xf2, 0x3b, 0x22, 0x95, 0xb3, 0xfd, 0x8e, 0xc8, 0xf3, 0xa7, 0xfe, 0x86, + 0xc8, 0x2b, 0x89, 0x9f, 0x5d, 0xa4, 0x24, 0xe4, 0x3b, 0xc5, 0x7f, 0x23, 0x1b, 0x2d, 0x03, 0xde, + 0xf5, 0x5f, 0x2e, 0xd6, 0xea, 0x29, 0x20, 0x62, 0x56, 0x7b, 0x8a, 0x88, 0x59, 0xc6, 0xcb, 0x38, + 0x55, 0x90, 0x97, 0xd1, 0x83, 0x59, 0xb7, 0xef, 0x74, 0xe8, 0xd6, 0xa0, 0xd7, 0x13, 0xf9, 0x9c, + 0x51, 0x7d, 0x9a, 0xf3, 0xce, 0x4d, 0xd0, 0xbb, 0xe7, 0xb7, 0x9c, 0x5e, 0xf6, 0xad, 0x65, 0x9d, + 0xe0, 0x7e, 0x27, 0xc3, 0x09, 0x87, 0x78, 0xb3, 0x09, 0xcb, 0x2f, 0xc0, 0xd2, 0x98, 0xf5, 0x36, + 0x8f, 0x12, 0xc9, 0x8f, 0x71, 0xdd, 0x4e, 0xc0, 0x68, 0xd2, 0x90, 0xbb, 0x50, 0x6d, 0x7b, 0x91, + 0x4c, 0xe2, 0x9e, 0xe1, 0xca, 0xec, 0x33, 0x4c, 0x05, 0xae, 0x6c, 0x34, 0x75, 0xfa, 0xf6, 0xd5, + 0x9c, 0xbb, 0xd5, 0x1a, 0x8f, 0x49, 0x79, 0xb2, 0xce, 0x99, 0xc9, 0xc7, 0xd6, 0x44, 0xf0, 0xe6, + 0xa5, 0x11, 0xbe, 0xb1, 0x95, 0x0d, 0xf5, 0x38, 0xdc, 0xb4, 0x14, 0x27, 0x5f, 0x4d, 0x4b, 0x38, + 0x18, 0x8f, 0xbf, 0x9e, 0x7f, 0xec, 0xe3, 0xaf, 0xfc, 0x51, 0x85, 0xb8, 0xa7, 0xfd, 0xdb, 0xd7, + 0x0a, 0x7b, 0x54, 0x21, 0xc9, 0x43, 0x90, 0x8f, 0x2a, 0x24, 0x00, 0x34, 0x45, 0x92, 0xcd, 0x51, + 0x7e, 0xfe, 0x0b, 0x5c, 0x69, 0x9c, 0xde, 0x6b, 0x6f, 0xba, 0x86, 0x2f, 0x3e, 0xd6, 0x35, 0x3c, + 0xe4, 0xca, 0xbe, 0x74, 0x0a, 0x57, 0x76, 0x97, 0x5f, 0x77, 0x5f, 0x5b, 0x96, 0x31, 0x81, 0x02, + 0x0c, 0x3a, 0x7e, 0xad, 0x4b, 0xe4, 0x75, 0xf0, 0x9f, 0x28, 0x04, 0x90, 0x2d, 0xb8, 0x18, 0xf8, + 0xed, 0x21, 0xb7, 0x38, 0x0f, 0x02, 0x24, 0x2f, 0x13, 0x5c, 0xdc, 0xca, 0xa1, 0xc1, 0xdc, 0x92, + 0x5c, 0x3d, 0x27, 0x70, 0xfe, 0x6e, 0x42, 0x59, 0xaa, 0xe7, 0x04, 0x8c, 0x26, 0x4d, 0xd6, 0x31, + 0xfc, 0xfc, 0x99, 0x39, 0x86, 0xe7, 0x9e, 0x81, 0x63, 0xf8, 0x85, 0x13, 0x3b, 0x86, 0x3f, 0x81, + 0x0b, 0x81, 0xdf, 0x5e, 0x71, 0xa3, 0x70, 0xc0, 0x13, 0xaf, 0x1b, 0x83, 0x76, 0x87, 0xc6, 0xdc, + 0xb3, 0x5c, 0xbb, 0x71, 0xc3, 0xac, 0xa4, 0xf8, 0xd2, 0xeb, 0x82, 0xfc, 0xd2, 0x2b, 0x5f, 0xa8, + 0x99, 0x52, 0xfc, 0xc0, 0xc4, 0x13, 0x5b, 0x72, 0x90, 0x98, 0x27, 0xc7, 0xf4, 0x4b, 0xbf, 0xf4, + 0x6c, 0xfc, 0xd2, 0x9f, 0x87, 0x4a, 0xd4, 0x1d, 0xc4, 0x6d, 0xff, 0xc0, 0xe3, 0xc1, 0x87, 0xaa, + 0xfe, 0x1c, 0x43, 0xa5, 0x29, 0xe1, 0x8f, 0x8e, 0xe6, 0x67, 0xd5, 0x6f, 0xc3, 0xa5, 0x20, 0x21, + 0xe4, 0xdb, 0x23, 0x92, 0x55, 0xed, 0xb3, 0x4c, 0x56, 0xbd, 0x72, 0xaa, 0x44, 0xd5, 0x3c, 0xe7, + 0xfb, 0xcb, 0x3f, 0x72, 0xce, 0xf7, 0x5f, 0xb7, 0x60, 0x7a, 0xdf, 0xf4, 0xdf, 0xc8, 0x00, 0x41, + 0x01, 0xe1, 0xc7, 0x94, 0x5b, 0xa8, 0x61, 0x33, 0x65, 0x97, 0x02, 0x3d, 0xca, 0x02, 0x30, 0x5d, + 0x93, 0x9c, 0xd0, 0xe8, 0x2b, 0x3f, 0xac, 0xd0, 0xe8, 0x27, 0x5c, 0x99, 0xa9, 0x94, 0x1a, 0x1e, + 0x35, 0x28, 0x36, 0x6d, 0x47, 0x29, 0x46, 0x9d, 0xb5, 0x63, 0xca, 0x7b, 0xfa, 0x28, 0xc4, 0xef, + 0x11, 0x38, 0x97, 0xf9, 0xb4, 0xc4, 0x67, 0xd5, 0x5b, 0x41, 0xc2, 0xb3, 0x77, 0x2d, 0xfb, 0x56, + 0xd0, 0xb4, 0xa2, 0x4f, 0xbd, 0x17, 0x94, 0x7a, 0xd0, 0xa7, 0x74, 0xa6, 0x0f, 0xfa, 0x8c, 0x3d, + 0x9b, 0x07, 0x7d, 0x66, 0xcf, 0xe2, 0x41, 0x9f, 0xf3, 0xa7, 0x7a, 0xd0, 0xc7, 0x78, 0x50, 0x69, + 0xfc, 0x09, 0x0f, 0x2a, 0x2d, 0xc1, 0x8c, 0x4a, 0x24, 0xa4, 0xf2, 0xa5, 0x16, 0xe1, 0x6d, 0xd6, + 0x5f, 0xda, 0x5b, 0x4e, 0xa3, 0x31, 0x4b, 0x4f, 0xbe, 0x61, 0x41, 0xd9, 0xe3, 0x25, 0x27, 0x8a, + 0x7a, 0xc5, 0x2f, 0x3d, 0xb5, 0xf8, 0x69, 0x41, 0xbe, 0x9d, 0xa7, 0xb2, 0x53, 0xca, 0x1c, 0xf6, + 0x48, 0xfd, 0x40, 0x51, 0x03, 0xf2, 0x3e, 0xd4, 0xfd, 0xdd, 0xdd, 0x9e, 0xef, 0xb4, 0x93, 0x57, + 0x87, 0x94, 0x3b, 0x5c, 0x64, 0x55, 0xeb, 0xe7, 0x23, 0x36, 0x47, 0xd0, 0xe1, 0x48, 0x0e, 0xec, + 0xb8, 0x37, 0x13, 0xc5, 0x7e, 0x48, 0xdb, 0xc9, 0xd1, 0xb4, 0xca, 0xdb, 0x4c, 0x0b, 0x6f, 0x73, + 0x33, 0x2d, 0x47, 0xb4, 0x5e, 0x0f, 0x4a, 0x06, 0x8b, 0xd9, 0x6a, 0x91, 0x10, 0x2e, 0x07, 0x79, + 0x27, 0xe3, 0x48, 0xa6, 0x3f, 0x3e, 0xee, 0x7c, 0xae, 0x96, 0xee, 0xe5, 0xdc, 0xb3, 0x75, 0x84, + 0x23, 0x38, 0x9b, 0xef, 0x11, 0x55, 0x9e, 0xcd, 0x7b, 0x44, 0xe9, 0x0f, 0xc2, 0x4c, 0x3f, 0xf3, + 0x0f, 0xc2, 0x90, 0xff, 0x97, 0xfb, 0x74, 0x96, 0x38, 0x50, 0x76, 0x0a, 0x9f, 0x13, 0x3f, 0x72, + 0xcf, 0x67, 0xfd, 0x03, 0x0b, 0xe6, 0xc4, 0xcc, 0xcb, 0xfb, 0x3c, 0xa1, 0xcc, 0x5b, 0x2c, 0x3a, + 0x62, 0xc2, 0xe3, 0xb3, 0xcd, 0x94, 0x54, 0xee, 0xc8, 0x7f, 0x4c, 0x4d, 0xc8, 0xaf, 0xe6, 0x18, + 0x4f, 0x33, 0x45, 0xb9, 0x68, 0xf2, 0x9f, 0x5d, 0xba, 0x70, 0x7c, 0x12, 0x7b, 0xe9, 0x9f, 0x8e, + 0xf4, 0x20, 0x11, 0x5e, 0xbd, 0xbf, 0x70, 0x46, 0x1e, 0x24, 0xf3, 0x6d, 0xa8, 0xd3, 0xf8, 0x91, + 0xe6, 0x7e, 0xde, 0x12, 0xcf, 0x37, 0x8e, 0x7c, 0x64, 0x74, 0xc7, 0x34, 0x1a, 0x0a, 0x79, 0xe6, + 0x33, 0x51, 0xc4, 0xe6, 0x6b, 0xa7, 0x7f, 0xc3, 0x82, 0x8b, 0x79, 0x4a, 0x32, 0xa7, 0x4a, 0x5f, + 0x4e, 0x57, 0xa9, 0x40, 0xb7, 0xb7, 0x59, 0xa1, 0x62, 0x5e, 0xcd, 0xfa, 0xf7, 0x13, 0x86, 0xdf, + 0x3e, 0xa6, 0xc1, 0x1f, 0x7f, 0x67, 0xaa, 0xe8, 0x17, 0x31, 0x53, 0x5f, 0x8c, 0x2a, 0xff, 0xb0, + 0xbe, 0x18, 0x35, 0xf1, 0x69, 0xbe, 0x18, 0x35, 0xf9, 0x43, 0xfb, 0x62, 0x54, 0xe5, 0x84, 0x5f, + 0x8c, 0xaa, 0xfe, 0x68, 0x7e, 0x31, 0xca, 0xfe, 0xdf, 0x16, 0xcc, 0xfe, 0x58, 0x7d, 0x06, 0xf8, + 0x7f, 0x19, 0x91, 0xfc, 0x67, 0xf8, 0xfd, 0xdf, 0x83, 0x74, 0x9c, 0x13, 0x8b, 0x6f, 0xf1, 0x88, + 0x78, 0xe7, 0x87, 0x90, 0xe7, 0x4a, 0x39, 0xd9, 0x9d, 0xd7, 0x54, 0xc2, 0x5b, 0xe9, 0xc4, 0x09, + 0x6f, 0xbf, 0x54, 0x1a, 0xee, 0x62, 0x6e, 0x6d, 0x7c, 0xfd, 0xd9, 0x7c, 0x73, 0xf4, 0x62, 0xde, + 0x37, 0x47, 0x33, 0xdf, 0x18, 0xcd, 0x7e, 0x73, 0xb2, 0x74, 0x86, 0xdf, 0x9c, 0x9c, 0x86, 0xda, + 0x7b, 0x6e, 0xa0, 0xbd, 0x20, 0x0b, 0xdf, 0xfd, 0xfe, 0xb5, 0xe7, 0x7e, 0xe7, 0xfb, 0xd7, 0x9e, + 0xfb, 0xde, 0xf7, 0xaf, 0x3d, 0xf7, 0xb5, 0xe3, 0x6b, 0xd6, 0x77, 0x8f, 0xaf, 0x59, 0xbf, 0x73, + 0x7c, 0xcd, 0xfa, 0xde, 0xf1, 0x35, 0xeb, 0xbf, 0x1c, 0x5f, 0xb3, 0xfe, 0xe6, 0x1f, 0x5c, 0x7b, + 0xee, 0xbd, 0x8a, 0x6a, 0xdb, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x3a, 0x5e, 0xa2, 0xc8, 0x6a, + 0x8b, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -3642,6 +3768,39 @@ func (m *ArtifactLocation) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ArtifactPaths) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ArtifactPaths) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ArtifactPaths) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Artifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ArtifactRepositoryRef) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4532,6 +4691,88 @@ func (m *DAGTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Data) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Data) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Data) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Transformation) > 0 { + for iNdEx := len(m.Transformation) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Transformation[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *DataSource) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DataSource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DataSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ArtifactPaths != nil { + { + size, err := m.ArtifactPaths.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Event) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -7174,6 +7415,20 @@ func (m *Template) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Data != nil { + { + size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xba + } i -= len(m.Timeout) copy(dAtA[i:], m.Timeout) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Timeout))) @@ -7628,6 +7883,34 @@ func (m *TemplateRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *TransformationStep) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TransformationStep) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TransformationStep) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *UserContainer) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -9182,6 +9465,17 @@ func (m *ArtifactLocation) Size() (n int) { return n } +func (m *ArtifactPaths) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Artifact.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ArtifactRepositoryRef) Size() (n int) { if m == nil { return 0 @@ -9501,6 +9795,36 @@ func (m *DAGTemplate) Size() (n int) { return n } +func (m *Data) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Source.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Transformation) > 0 { + for _, e := range m.Transformation { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *DataSource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ArtifactPaths != nil { + l = m.ArtifactPaths.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *Event) Size() (n int) { if m == nil { return 0 @@ -10629,6 +10953,10 @@ func (m *Template) Size() (n int) { } l = len(m.Timeout) n += 2 + l + sovGenerated(uint64(l)) + if m.Data != nil { + l = m.Data.Size() + n += 2 + l + sovGenerated(uint64(l)) + } return n } @@ -10646,6 +10974,17 @@ func (m *TemplateRef) Size() (n int) { return n } +func (m *TransformationStep) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *UserContainer) Size() (n int) { if m == nil { return 0 @@ -11219,6 +11558,16 @@ func (this *ArtifactLocation) String() string { }, "") return s } +func (this *ArtifactPaths) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ArtifactPaths{`, + `Artifact:` + strings.Replace(strings.Replace(this.Artifact.String(), "Artifact", "Artifact", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} func (this *ArtifactoryArtifact) String() string { if this == nil { return "nil" @@ -11444,6 +11793,32 @@ func (this *DAGTemplate) String() string { }, "") return s } +func (this *Data) String() string { + if this == nil { + return "nil" + } + repeatedStringForTransformation := "[]TransformationStep{" + for _, f := range this.Transformation { + repeatedStringForTransformation += strings.Replace(strings.Replace(f.String(), "TransformationStep", "TransformationStep", 1), `&`, ``, 1) + "," + } + repeatedStringForTransformation += "}" + s := strings.Join([]string{`&Data{`, + `Source:` + strings.Replace(strings.Replace(this.Source.String(), "DataSource", "DataSource", 1), `&`, ``, 1) + `,`, + `Transformation:` + repeatedStringForTransformation + `,`, + `}`, + }, "") + return s +} +func (this *DataSource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DataSource{`, + `ArtifactPaths:` + strings.Replace(this.ArtifactPaths.String(), "ArtifactPaths", "ArtifactPaths", 1) + `,`, + `}`, + }, "") + return s +} func (this *Event) String() string { if this == nil { return "nil" @@ -12250,6 +12625,7 @@ func (this *Template) String() string { `Synchronization:` + strings.Replace(this.Synchronization.String(), "Synchronization", "Synchronization", 1) + `,`, `Memoize:` + strings.Replace(this.Memoize.String(), "Memoize", "Memoize", 1) + `,`, `Timeout:` + fmt.Sprintf("%v", this.Timeout) + `,`, + `Data:` + strings.Replace(this.Data.String(), "Data", "Data", 1) + `,`, `}`, }, "") return s @@ -12266,6 +12642,16 @@ func (this *TemplateRef) String() string { }, "") return s } +func (this *TransformationStep) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TransformationStep{`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} func (this *UserContainer) String() string { if this == nil { return "nil" @@ -13699,6 +14085,92 @@ func (m *ArtifactLocation) Unmarshal(dAtA []byte) error { } return nil } +func (m *ArtifactPaths) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ArtifactPaths: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ArtifactPaths: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Artifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Artifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ArtifactRepositoryRef) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -16171,7 +16643,124 @@ func (m *DAGTask) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 11: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OnExit", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OnExit", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OnExit = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Depends", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Depends = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DAGTemplate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DAGTemplate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DAGTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -16199,13 +16788,13 @@ func (m *DAGTask) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.OnExit = string(dAtA[iNdEx:postIndex]) + m.Target = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 12: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Depends", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Tasks", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -16215,24 +16804,47 @@ func (m *DAGTask) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Depends = string(dAtA[iNdEx:postIndex]) + m.Tasks = append(m.Tasks, DAGTask{}) + if err := m.Tasks[len(m.Tasks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FailFast", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.FailFast = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -16257,7 +16869,7 @@ func (m *DAGTask) Unmarshal(dAtA []byte) error { } return nil } -func (m *DAGTemplate) Unmarshal(dAtA []byte) error { +func (m *Data) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -16280,17 +16892,17 @@ func (m *DAGTemplate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DAGTemplate: wiretype end group for non-group") + return fmt.Errorf("proto: Data: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DAGTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Data: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -16300,27 +16912,28 @@ func (m *DAGTemplate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Target = string(dAtA[iNdEx:postIndex]) + if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tasks", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Transformation", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -16347,16 +16960,69 @@ func (m *DAGTemplate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Tasks = append(m.Tasks, DAGTask{}) - if err := m.Tasks[len(m.Tasks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Transformation = append(m.Transformation, TransformationStep{}) + if err := m.Transformation[len(m.Transformation)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field FailFast", wireType) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err } - var v int + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DataSource) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DataSource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DataSource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ArtifactPaths", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -16366,13 +17032,28 @@ func (m *DAGTemplate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - b := bool(v != 0) - m.FailFast = &b + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ArtifactPaths == nil { + m.ArtifactPaths = &ArtifactPaths{} + } + if err := m.ArtifactPaths.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -25982,6 +26663,42 @@ func (m *Template) Unmarshal(dAtA []byte) error { } m.Timeout = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 39: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Data == nil { + m.Data = &Data{} + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -26143,6 +26860,91 @@ func (m *TemplateRef) Unmarshal(dAtA []byte) error { } return nil } +func (m *TransformationStep) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TransformationStep: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TransformationStep: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *UserContainer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto index 478c44e3d88e..1f1a7968a526 100644 --- a/pkg/apis/workflow/v1alpha1/generated.proto +++ b/pkg/apis/workflow/v1alpha1/generated.proto @@ -111,6 +111,12 @@ message ArtifactLocation { optional GCSArtifact gcs = 9; } +// ArtifactPaths expands a step from a collection of artifacts +message ArtifactPaths { + // Artifact is the artifact location from which to source the artifacts, it can be a directory + optional Artifact artifact = 1; +} + // +protobuf.options.(gogoproto.goproto_stringer)=false message ArtifactRepositoryRef { // The name of the config map. Defaults to "artifact-repositories". @@ -345,6 +351,21 @@ message DAGTemplate { optional bool failFast = 3; } +// Data is a data template +message Data { + // Source sources external data into a data template + optional DataSource source = 1; + + // Transformation applies a set of transformations + repeated TransformationStep transformation = 2; +} + +// DataSource sources external data into a data template +message DataSource { + // ArtifactPaths is a data transformation that collects a list of artifact paths + optional ArtifactPaths artifactPaths = 1; +} + message Event { // Selector (https://github.com/antonmedv/expr) that we must must match the event. E.g. `payload.message == "test"` optional string selector = 1; @@ -1090,6 +1111,9 @@ message Template { // Suspend template subtype which can suspend a workflow when reaching the step optional SuspendTemplate suspend = 16; + // Data is a data template + optional Data data = 39; + // Volumes is a list of volumes that can be mounted by containers in a template. // +patchStrategy=merge // +patchMergeKey=name @@ -1192,6 +1216,11 @@ message TemplateRef { optional bool clusterScope = 4; } +message TransformationStep { + // Expression defines an expr expression to apply + optional string expression = 1; +} + // UserContainer is a container specified by a user. message UserContainer { optional k8s.io.api.core.v1.Container container = 1; diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index 177435b4faa4..2c5e9ad6a2b5 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -18,6 +18,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Arguments": schema_pkg_apis_workflow_v1alpha1_Arguments(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Artifact": schema_pkg_apis_workflow_v1alpha1_Artifact(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactLocation": schema_pkg_apis_workflow_v1alpha1_ArtifactLocation(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactPaths": schema_pkg_apis_workflow_v1alpha1_ArtifactPaths(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactRepositoryRef": schema_pkg_apis_workflow_v1alpha1_ArtifactRepositoryRef(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactRepositoryRefStatus": schema_pkg_apis_workflow_v1alpha1_ArtifactRepositoryRefStatus(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact": schema_pkg_apis_workflow_v1alpha1_ArtifactoryArtifact(ref), @@ -36,6 +37,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.CronWorkflowStatus": schema_pkg_apis_workflow_v1alpha1_CronWorkflowStatus(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DAGTask": schema_pkg_apis_workflow_v1alpha1_DAGTask(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DAGTemplate": schema_pkg_apis_workflow_v1alpha1_DAGTemplate(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Data": schema_pkg_apis_workflow_v1alpha1_Data(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DataSource": schema_pkg_apis_workflow_v1alpha1_DataSource(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Event": schema_pkg_apis_workflow_v1alpha1_Event(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ExecutorConfig": schema_pkg_apis_workflow_v1alpha1_ExecutorConfig(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact": schema_pkg_apis_workflow_v1alpha1_GCSArtifact(ref), @@ -91,6 +94,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.TarStrategy": schema_pkg_apis_workflow_v1alpha1_TarStrategy(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Template": schema_pkg_apis_workflow_v1alpha1_Template(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.TemplateRef": schema_pkg_apis_workflow_v1alpha1_TemplateRef(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.TransformationStep": schema_pkg_apis_workflow_v1alpha1_TransformationStep(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.UserContainer": schema_pkg_apis_workflow_v1alpha1_UserContainer(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ValueFrom": schema_pkg_apis_workflow_v1alpha1_ValueFrom(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Version": schema_pkg_apis_workflow_v1alpha1_Version(ref), @@ -412,6 +416,140 @@ func schema_pkg_apis_workflow_v1alpha1_ArtifactLocation(ref common.ReferenceCall } } +func schema_pkg_apis_workflow_v1alpha1_ArtifactPaths(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ArtifactPaths expands a step from a collection of artifacts", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "name of the artifact. must be unique within a template's inputs/outputs.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "Path is the container path to the artifact", + Type: []string{"string"}, + Format: "", + }, + }, + "mode": { + SchemaProps: spec.SchemaProps{ + Description: "mode bits to use on this file, must be a value between 0 and 0777 set when loading input artifacts.", + Type: []string{"integer"}, + Format: "int32", + }, + }, + "from": { + SchemaProps: spec.SchemaProps{ + Description: "From allows an artifact to reference an artifact from a previous step", + Type: []string{"string"}, + Format: "", + }, + }, + "archiveLogs": { + SchemaProps: spec.SchemaProps{ + Description: "ArchiveLogs indicates if the container logs should be archived", + Type: []string{"boolean"}, + Format: "", + }, + }, + "s3": { + SchemaProps: spec.SchemaProps{ + Description: "S3 contains S3 artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"), + }, + }, + "git": { + SchemaProps: spec.SchemaProps{ + Description: "Git contains git artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact"), + }, + }, + "http": { + SchemaProps: spec.SchemaProps{ + Description: "HTTP contains HTTP artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact"), + }, + }, + "artifactory": { + SchemaProps: spec.SchemaProps{ + Description: "Artifactory contains artifactory artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact"), + }, + }, + "hdfs": { + SchemaProps: spec.SchemaProps{ + Description: "HDFS contains HDFS artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact"), + }, + }, + "raw": { + SchemaProps: spec.SchemaProps{ + Description: "Raw contains raw artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact"), + }, + }, + "oss": { + SchemaProps: spec.SchemaProps{ + Description: "OSS contains OSS artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact"), + }, + }, + "gcs": { + SchemaProps: spec.SchemaProps{ + Description: "GCS contains GCS artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact"), + }, + }, + "globalName": { + SchemaProps: spec.SchemaProps{ + Description: "GlobalName exports an output artifact to the global scope, making it available as '{{workflow.outputs.artifacts.XXXX}} and in workflow.status.outputs.artifacts", + Type: []string{"string"}, + Format: "", + }, + }, + "archive": { + SchemaProps: spec.SchemaProps{ + Description: "Archive controls how the artifact will be saved to the artifact repository.", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArchiveStrategy"), + }, + }, + "optional": { + SchemaProps: spec.SchemaProps{ + Description: "Make Artifacts optional, if Artifacts doesn't generate or exist", + Type: []string{"boolean"}, + Format: "", + }, + }, + "subPath": { + SchemaProps: spec.SchemaProps{ + Description: "SubPath allows an artifact to be sourced from a subpath within the specified source", + Type: []string{"string"}, + Format: "", + }, + }, + "recurseMode": { + SchemaProps: spec.SchemaProps{ + Description: "If mode is set, apply the permission recursively into the artifact if it is a folder", + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArchiveStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, + } +} + func schema_pkg_apis_workflow_v1alpha1_ArtifactRepositoryRef(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1178,6 +1316,64 @@ func schema_pkg_apis_workflow_v1alpha1_DAGTemplate(ref common.ReferenceCallback) } } +func schema_pkg_apis_workflow_v1alpha1_Data(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Data is a data template", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "source": { + SchemaProps: spec.SchemaProps{ + Description: "Source sources external data into a data template", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DataSource"), + }, + }, + "transformation": { + SchemaProps: spec.SchemaProps{ + Description: "Transformation applies a set of transformations", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.TransformationStep"), + }, + }, + }, + }, + }, + }, + Required: []string{"source", "transformation"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DataSource", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.TransformationStep"}, + } +} + +func schema_pkg_apis_workflow_v1alpha1_DataSource(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DataSource sources external data into a data template", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "artifactPaths": { + SchemaProps: spec.SchemaProps{ + Description: "ArtifactPaths is a data transformation that collects a list of artifact paths", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactPaths"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactPaths"}, + } +} + func schema_pkg_apis_workflow_v1alpha1_Event(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2928,13 +3124,11 @@ func schema_pkg_apis_workflow_v1alpha1_S3Artifact(ref common.ReferenceCallback) "key": { SchemaProps: spec.SchemaProps{ Description: "Key is the key in the bucket where the artifact resides", - Default: "", Type: []string{"string"}, Format: "", }, }, }, - Required: []string{"key"}, }, }, Dependencies: []string{ @@ -3788,6 +3982,12 @@ func schema_pkg_apis_workflow_v1alpha1_Template(ref common.ReferenceCallback) co Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SuspendTemplate"), }, }, + "data": { + SchemaProps: spec.SchemaProps{ + Description: "Data is a data template", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Data"), + }, + }, "volumes": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -3997,7 +4197,7 @@ func schema_pkg_apis_workflow_v1alpha1_Template(ref common.ReferenceCallback) co }, }, Dependencies: []string{ - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactLocation", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DAGTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ExecutorConfig", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Inputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Memoize", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metadata", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metrics", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Outputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ParallelSteps", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ResourceTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RetryStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ScriptTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SuspendTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Synchronization", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.UserContainer", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.HostAlias", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/util/intstr.IntOrString"}, + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactLocation", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.DAGTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Data", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ExecutorConfig", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Inputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Memoize", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metadata", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Metrics", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Outputs", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ParallelSteps", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ResourceTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RetryStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ScriptTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SuspendTemplate", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Synchronization", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.UserContainer", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.HostAlias", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/util/intstr.IntOrString"}, } } @@ -4035,6 +4235,27 @@ func schema_pkg_apis_workflow_v1alpha1_TemplateRef(ref common.ReferenceCallback) } } +func schema_pkg_apis_workflow_v1alpha1_TransformationStep(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "expression": { + SchemaProps: spec.SchemaProps{ + Description: "Expression defines an expr expression to apply", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"expression"}, + }, + }, + } +} + func schema_pkg_apis_workflow_v1alpha1_UserContainer(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apis/workflow/v1alpha1/workflow_types.go b/pkg/apis/workflow/v1alpha1/workflow_types.go index feae6bf7ec45..678fb02d69c2 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types.go @@ -32,6 +32,7 @@ const ( TemplateTypeResource TemplateType = "Resource" TemplateTypeDAG TemplateType = "DAG" TemplateTypeSuspend TemplateType = "Suspend" + TemplateTypeData TemplateType = "Data" TemplateTypeUnknown TemplateType = "Unknown" ) @@ -521,6 +522,9 @@ type Template struct { // Suspend template subtype which can suspend a workflow when reaching the step Suspend *SuspendTemplate `json:"suspend,omitempty" protobuf:"bytes,16,opt,name=suspend"` + // Data is a data template + Data *Data `json:"data,omitempty" protobuf:"bytes,39,opt,name=data"` + // Volumes is a list of volumes that can be mounted by containers in a template. // +patchStrategy=merge // +patchMergeKey=name @@ -1782,7 +1786,7 @@ type S3Artifact struct { S3Bucket `json:",inline" protobuf:"bytes,1,opt,name=s3Bucket"` // Key is the key in the bucket where the artifact resides - Key string `json:"key" protobuf:"bytes,2,opt,name=key"` + Key string `json:"key,omitempty" protobuf:"bytes,2,opt,name=key"` } func (s *S3Artifact) GetKey() (string, error) { @@ -2009,7 +2013,6 @@ func (h *HTTPArtifact) HasLocation() bool { // GCSBucket contains the access information for interfacring with a GCS bucket type GCSBucket struct { - // Bucket is the name of the bucket Bucket string `json:"bucket,omitempty" protobuf:"bytes,1,opt,name=bucket"` @@ -2140,6 +2143,9 @@ func (tmpl *Template) GetType() TemplateType { if tmpl.Resource != nil { return TemplateTypeResource } + if tmpl.Data != nil { + return TemplateTypeData + } if tmpl.Suspend != nil { return TemplateTypeSuspend } @@ -2149,7 +2155,7 @@ func (tmpl *Template) GetType() TemplateType { // IsPodType returns whether or not the template is a pod type func (tmpl *Template) IsPodType() bool { switch tmpl.GetType() { - case TemplateTypeContainer, TemplateTypeScript, TemplateTypeResource: + case TemplateTypeContainer, TemplateTypeScript, TemplateTypeResource, TemplateTypeData: return true } return false @@ -2158,7 +2164,7 @@ func (tmpl *Template) IsPodType() bool { // IsLeaf returns whether or not the template is a leaf func (tmpl *Template) IsLeaf() bool { switch tmpl.GetType() { - case TemplateTypeContainer, TemplateTypeScript, TemplateTypeResource: + case TemplateTypeContainer, TemplateTypeScript, TemplateTypeResource, TemplateTypeData: return true } return false diff --git a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go index faed9ce51798..2dc26a9615ac 100644 --- a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go @@ -177,6 +177,23 @@ func (in *ArtifactLocation) DeepCopy() *ArtifactLocation { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArtifactPaths) DeepCopyInto(out *ArtifactPaths) { + *out = *in + in.Artifact.DeepCopyInto(&out.Artifact) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArtifactPaths. +func (in *ArtifactPaths) DeepCopy() *ArtifactPaths { + if in == nil { + return nil + } + out := new(ArtifactPaths) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ArtifactRepositoryRef) DeepCopyInto(out *ArtifactRepositoryRef) { *out = *in @@ -683,6 +700,49 @@ func (in *DAGTemplate) DeepCopy() *DAGTemplate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Data) DeepCopyInto(out *Data) { + *out = *in + in.Source.DeepCopyInto(&out.Source) + if in.Transformation != nil { + in, out := &in.Transformation, &out.Transformation + *out = make(Transformation, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Data. +func (in *Data) DeepCopy() *Data { + if in == nil { + return nil + } + out := new(Data) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DataSource) DeepCopyInto(out *DataSource) { + *out = *in + if in.ArtifactPaths != nil { + in, out := &in.ArtifactPaths, &out.ArtifactPaths + *out = new(ArtifactPaths) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataSource. +func (in *DataSource) DeepCopy() *DataSource { + if in == nil { + return nil + } + out := new(DataSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Event) DeepCopyInto(out *Event) { *out = *in @@ -2031,6 +2091,11 @@ func (in *Template) DeepCopyInto(out *Template) { *out = new(SuspendTemplate) **out = **in } + if in.Data != nil { + in, out := &in.Data, &out.Data + *out = new(Data) + (*in).DeepCopyInto(*out) + } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]v1.Volume, len(*in)) @@ -2150,6 +2215,42 @@ func (in *TemplateRef) DeepCopy() *TemplateRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Transformation) DeepCopyInto(out *Transformation) { + { + in := &in + *out = make(Transformation, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Transformation. +func (in Transformation) DeepCopy() Transformation { + if in == nil { + return nil + } + out := new(Transformation) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TransformationStep) DeepCopyInto(out *TransformationStep) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransformationStep. +func (in *TransformationStep) DeepCopy() *TransformationStep { + if in == nil { + return nil + } + out := new(TransformationStep) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UserContainer) DeepCopyInto(out *UserContainer) { *out = *in diff --git a/server/artifacts/artifact_server_test.go b/server/artifacts/artifact_server_test.go index dd2f79a07821..4b8c75654e95 100644 --- a/server/artifacts/artifact_server_test.go +++ b/server/artifacts/artifact_server_test.go @@ -22,7 +22,7 @@ import ( authmocks "github.com/argoproj/argo-workflows/v3/server/auth/mocks" "github.com/argoproj/argo-workflows/v3/util/instanceid" armocks "github.com/argoproj/argo-workflows/v3/workflow/artifactrepositories/mocks" - artifact "github.com/argoproj/argo-workflows/v3/workflow/artifacts" + artifactscommon "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/resource" "github.com/argoproj/argo-workflows/v3/workflow/common" hydratorfake "github.com/argoproj/argo-workflows/v3/workflow/hydrator/fake" @@ -37,7 +37,7 @@ func mustParse(text string) *url.URL { } type fakeArtifactDriver struct { - artifact.ArtifactDriver + artifactscommon.ArtifactDriver data []byte } @@ -109,7 +109,7 @@ func newServer() *ArtifactServer { a := &sqldbmocks.WorkflowArchive{} a.On("GetWorkflow", "my-uuid").Return(wf, nil) - fakeArtifactDriverFactory := func(_ context.Context, _ *wfv1.Artifact, _ resource.Interface) (artifact.ArtifactDriver, error) { + fakeArtifactDriverFactory := func(_ context.Context, _ *wfv1.Artifact, _ resource.Interface) (artifactscommon.ArtifactDriver, error) { return &fakeArtifactDriver{data: []byte("my-data")}, nil } diff --git a/test/e2e/functional_test.go b/test/e2e/functional_test.go index 454b5ad7bfef..a7d9746f8888 100644 --- a/test/e2e/functional_test.go +++ b/test/e2e/functional_test.go @@ -823,6 +823,42 @@ spec: }) } +func (s *FunctionalSuite) TestDataTransformation() { + s.Given(). + Workflow("@testdata/data-transformation.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(1 * time.Minute). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + paths := status.Nodes.FindByDisplayName("get-artifact-path") + if assert.NotNil(t, paths) { + assert.Equal(t, `["foo/script.py","script.py"]`, *paths.Outputs.Result) + } + assert.NotNil(t, status.Nodes.FindByDisplayName("process-artifact(0:foo/script.py)")) + assert.NotNil(t, status.Nodes.FindByDisplayName("process-artifact(1:script.py)")) + }) +} + +func (s *FunctionalSuite) TestDataTransformationArtifactRepositoryRef() { + s.Given(). + Workflow("@testdata/data-transformation-artifact-repository-ref.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(1 * time.Minute). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + paths := status.Nodes.FindByDisplayName("get-artifact-path") + if assert.NotNil(t, paths) { + assert.Equal(t, `["foo/script.py","script.py"]`, *paths.Outputs.Result) + } + assert.NotNil(t, status.Nodes.FindByDisplayName("process-artifact(0:foo/script.py)")) + assert.NotNil(t, status.Nodes.FindByDisplayName("process-artifact(1:script.py)")) + }) +} + func TestFunctionalSuite(t *testing.T) { suite.Run(t, new(FunctionalSuite)) } diff --git a/test/e2e/testdata/data-transformation-artifact-repository-ref.yaml b/test/e2e/testdata/data-transformation-artifact-repository-ref.yaml new file mode 100644 index 000000000000..8116a9993d49 --- /dev/null +++ b/test/e2e/testdata/data-transformation-artifact-repository-ref.yaml @@ -0,0 +1,64 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: data-transformation + labels: + argo-e2e: "true" +spec: + entrypoint: artifact-example + artifactRepositoryRef: + key: my-key + templates: + - name: artifact-example + steps: + - - name: generate-artifact + template: generate-artifacts + withItems: ['script.py', 'doc.pdf', 'foo/script.py', 'foo/doc.pdf'] + arguments: + parameters: + - name: file-name + value: "{{item}}" + - - name: get-artifact-path + template: get-artifact-paths + - - name: process-artifact + template: process-message + withParam: "{{steps.get-artifact-path.outputs.result}}" + arguments: + parameters: + - name: file-name + value: "{{item}}" + + - name: generate-artifacts + inputs: + parameters: + - name: file-name + container: + image: argoproj/argosay:v2 + args: + - echo + - hello + - "/mnt/{{inputs.parameters.file-name}}" + outputs: + artifacts: + - name: file + path: "/mnt/{{inputs.parameters.file-name}}" + s3: + key: "{{inputs.parameters.file-name}}" + + - name: get-artifact-paths + data: + source: + artifactPaths: + s3: + bucket: my-bucket + transformation: + - expression: "filter(data, {# endsWith \".py\"})" + + - name: process-message + inputs: + parameters: + - name: file-name + container: + image: argoproj/argosay:v1 + command: [sh, -c] + args: ["echo \"{{inputs.parameters.file-name}}.processed\""] diff --git a/test/e2e/testdata/data-transformation.yaml b/test/e2e/testdata/data-transformation.yaml new file mode 100644 index 000000000000..3ca46af9bb4a --- /dev/null +++ b/test/e2e/testdata/data-transformation.yaml @@ -0,0 +1,100 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: data-transformation + labels: + argo-e2e: "true" +spec: + entrypoint: artifact-example + templates: + - name: artifact-example + steps: + - - name: generate-artifact + template: generate-artifacts + withItems: ['script.py', 'doc.pdf', 'foo/script.py', 'foo/doc.pdf'] + arguments: + parameters: + - name: file-name + value: "{{item}}" + - - name: get-artifact-path + template: get-artifact-paths + - - name: process-artifact + template: process-message + withParam: "{{steps.get-artifact-path.outputs.result}}" + arguments: + artifacts: + - name: file + s3: + bucket: my-bucket + key: "{{item}}" + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + parameters: + - name: file-name + value: "{{item}}" + + - name: generate-artifacts + inputs: + parameters: + - name: file-name + container: + image: argoproj/argosay:v2 + args: + - echo + - hello + - "/mnt/{{inputs.parameters.file-name}}" + outputs: + artifacts: + - name: file + path: "/mnt/{{inputs.parameters.file-name}}" + s3: + bucket: my-bucket + key: "{{inputs.parameters.file-name}}" + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + + - name: get-artifact-paths + data: + source: + artifactPaths: + s3: + bucket: my-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + transformation: + - expression: "filter(data, {# endsWith \".py\"})" + + - name: process-message + inputs: + parameters: + - name: file-name + artifacts: + - name: file + path: /file + container: + image: argoproj/argosay:v1 + command: [sh, -c] + args: ["cat /file && echo \"{{inputs.parameters.file-name}}.processed\" | tee /tmp/f.txt"] + outputs: + parameters: + - name: processed + valueFrom: + path: /tmp/f.txt diff --git a/workflow/artifacts/artifactory/artifactory.go b/workflow/artifacts/artifactory/artifactory.go index 8f1b0aaf2ba8..c6ef78e5a30d 100644 --- a/workflow/artifacts/artifactory/artifactory.go +++ b/workflow/artifacts/artifactory/artifactory.go @@ -1,21 +1,25 @@ package artifactory import ( + "fmt" "io" "net/http" "os" "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" ) -type ArtifactoryArtifactDriver struct { +type ArtifactDriver struct { Username string Password string } +var _ common.ArtifactDriver = &ArtifactDriver{} + // Download artifact from an artifactory URL -func (a *ArtifactoryArtifactDriver) Load(artifact *wfv1.Artifact, path string) error { +func (a *ArtifactDriver) Load(artifact *wfv1.Artifact, path string) error { lf, err := os.Create(path) if err != nil { return err @@ -49,7 +53,7 @@ func (a *ArtifactoryArtifactDriver) Load(artifact *wfv1.Artifact, path string) e } // UpLoad artifact to an artifactory URL -func (a *ArtifactoryArtifactDriver) Save(path string, artifact *wfv1.Artifact) error { +func (a *ArtifactDriver) Save(path string, artifact *wfv1.Artifact) error { f, err := os.Open(path) if err != nil { return err @@ -71,3 +75,7 @@ func (a *ArtifactoryArtifactDriver) Save(path string, artifact *wfv1.Artifact) e } return nil } + +func (a *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/artifactory/artifactory_test.go b/workflow/artifacts/artifactory/artifactory_test.go index 5fbfad1f6c7e..f19d0f516380 100644 --- a/workflow/artifacts/artifactory/artifactory_test.go +++ b/workflow/artifacts/artifactory/artifactory_test.go @@ -11,7 +11,7 @@ import ( ) func TestArtifactoryArtifactDriver_Load(t *testing.T) { - driver := &ArtifactoryArtifactDriver{} + driver := &ArtifactDriver{} t.Run("NotFound", func(t *testing.T) { err := driver.Load(&wfv1.Artifact{ ArtifactLocation: wfv1.ArtifactLocation{ diff --git a/workflow/artifacts/artifacts.go b/workflow/artifacts/artifacts.go index 07f7b12e0dd3..363978dc2812 100644 --- a/workflow/artifacts/artifacts.go +++ b/workflow/artifacts/artifacts.go @@ -6,6 +6,7 @@ import ( wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/artifactory" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/gcs" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/git" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/hdfs" @@ -16,21 +17,12 @@ import ( "github.com/argoproj/argo-workflows/v3/workflow/artifacts/s3" ) -// ArtifactDriver is the interface for loading and saving of artifacts -type ArtifactDriver interface { - // Load accepts an artifact source URL and places it at specified path - Load(inputArtifact *wfv1.Artifact, path string) error - - // Save uploads the path to artifact destination - Save(path string, outputArtifact *wfv1.Artifact) error -} - var ErrUnsupportedDriver = fmt.Errorf("unsupported artifact driver") -type NewDriverFunc func(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) (ArtifactDriver, error) +type NewDriverFunc func(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) (common.ArtifactDriver, error) // NewDriver initializes an instance of an artifact driver -func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) (ArtifactDriver, error) { +func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) (common.ArtifactDriver, error) { if art.S3 != nil { var accessKey string var secretKey string @@ -48,7 +40,7 @@ func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( secretKey = secretKeyBytes } - driver := s3.S3ArtifactDriver{ + driver := s3.ArtifactDriver{ Endpoint: art.S3.Endpoint, AccessKey: accessKey, SecretKey: secretKey, @@ -60,10 +52,10 @@ func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( return &driver, nil } if art.HTTP != nil { - return &http.HTTPArtifactDriver{}, nil + return &http.ArtifactDriver{}, nil } if art.Git != nil { - gitDriver := git.GitArtifactDriver{ + gitDriver := git.ArtifactDriver{ InsecureIgnoreHostKey: art.Git.InsecureIgnoreHostKey, } if art.Git.UsernameSecret != nil { @@ -99,7 +91,7 @@ func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( if err != nil { return nil, err } - driver := artifactory.ArtifactoryArtifactDriver{ + driver := artifactory.ArtifactDriver{ Username: usernameBytes, Password: passwordBytes, } @@ -110,7 +102,7 @@ func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( return hdfs.CreateDriver(ctx, ri, art.HDFS) } if art.Raw != nil { - return &raw.RawArtifactDriver{}, nil + return &raw.ArtifactDriver{}, nil } if art.OSS != nil { @@ -130,7 +122,7 @@ func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( secretKey = string(secretKeyBytes) } - driver := oss.OSSArtifactDriver{ + driver := oss.ArtifactDriver{ Endpoint: art.OSS.Endpoint, AccessKey: accessKey, SecretKey: secretKey, diff --git a/workflow/artifacts/common/common.go b/workflow/artifacts/common/common.go new file mode 100644 index 000000000000..ea2c928916b7 --- /dev/null +++ b/workflow/artifacts/common/common.go @@ -0,0 +1,14 @@ +package common + +import "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + +// ArtifactDriver is the interface for loading and saving of artifacts +type ArtifactDriver interface { + // Load accepts an artifact source URL and places it at specified path + Load(inputArtifact *v1alpha1.Artifact, path string) error + + // Save uploads the path to artifact destination + Save(path string, outputArtifact *v1alpha1.Artifact) error + + ListObjects(artifact *v1alpha1.Artifact) ([]string, error) +} diff --git a/workflow/artifacts/gcs/gcs.go b/workflow/artifacts/gcs/gcs.go index 0b32ed0cf4dd..be98f296a049 100644 --- a/workflow/artifacts/gcs/gcs.go +++ b/workflow/artifacts/gcs/gcs.go @@ -20,6 +20,7 @@ import ( "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" ) // ArtifactDriver is a driver for GCS @@ -27,6 +28,8 @@ type ArtifactDriver struct { ServiceAccountKey string } +var _ common.ArtifactDriver = &ArtifactDriver{} + func (g *ArtifactDriver) newGCSClient() (*storage.Client, error) { if g.ServiceAccountKey != "" { return newGCSClientWithCredential(g.ServiceAccountKey) @@ -248,3 +251,7 @@ func uploadObject(client *storage.Client, bucket, key, localPath string) error { } return nil } + +func (g *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/git/git.go b/workflow/artifacts/git/git.go index 12dc7425c38b..c976cd386a3d 100644 --- a/workflow/artifacts/git/git.go +++ b/workflow/artifacts/git/git.go @@ -2,6 +2,7 @@ package git import ( "errors" + "fmt" "io/ioutil" "os" "os/exec" @@ -17,17 +18,20 @@ import ( ssh2 "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" ) -// GitArtifactDriver is the artifact driver for a git repo -type GitArtifactDriver struct { +// ArtifactDriver is the artifact driver for a git repo +type ArtifactDriver struct { Username string Password string SSHPrivateKey string InsecureIgnoreHostKey bool } -func (g *GitArtifactDriver) auth() (func(), transport.AuthMethod, []string, error) { +var _ common.ArtifactDriver = &ArtifactDriver{} + +func (g *ArtifactDriver) auth() (func(), transport.AuthMethod, []string, error) { if g.SSHPrivateKey != "" { signer, err := ssh.ParsePrivateKey([]byte(g.SSHPrivateKey)) if err != nil { @@ -91,11 +95,11 @@ esac } // Save is unsupported for git output artifacts -func (g *GitArtifactDriver) Save(string, *wfv1.Artifact) error { +func (g *ArtifactDriver) Save(string, *wfv1.Artifact) error { return errors.New("git output artifacts unsupported") } -func (g *GitArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { +func (g *ArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { closer, auth, env, err := g.auth() if err != nil { return err @@ -157,10 +161,14 @@ func isAlreadyUpToDateErr(err error) bool { return err != nil && err.Error() != "already up-to-date" } -func (g *GitArtifactDriver) error(err error, cmd *exec.Cmd) error { +func (g *ArtifactDriver) error(err error, cmd *exec.Cmd) error { if exErr, ok := err.(*exec.ExitError); ok { log.Errorf("`%s` stderr:\n%s", cmd.Args, string(exErr.Stderr)) return errors.New(strings.Split(string(exErr.Stderr), "\n")[0]) } return err } + +func (g *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/git/git_test.go b/workflow/artifacts/git/git_test.go index b245db1ec7dd..9b4b6f0bc563 100644 --- a/workflow/artifacts/git/git_test.go +++ b/workflow/artifacts/git/git_test.go @@ -14,7 +14,7 @@ var d = uint64(1) func TestGitArtifactDriver_Load(t *testing.T) { _ = os.Remove("git-ask-pass.sh") - driver := &GitArtifactDriver{} + driver := &ArtifactDriver{} path := "/tmp/git-found" assert.NoError(t, os.RemoveAll(path)) assert.NoError(t, os.MkdirAll(path, 0777)) @@ -35,7 +35,7 @@ func TestGitArtifactDriver_Load(t *testing.T) { } func TestGitArtifactDriver_Save(t *testing.T) { - driver := &GitArtifactDriver{} + driver := &ArtifactDriver{} err := driver.Save("", nil) assert.Error(t, err) } @@ -47,7 +47,7 @@ func TestGitArtifactDriverLoad_HTTPS(t *testing.T) { _ = os.Remove("git-ask-pass.sh") tmp, err := ioutil.TempDir("", "") assert.NoError(t, err) - driver := &GitArtifactDriver{Username: os.Getenv("GITHUB_TOKEN")} + driver := &ArtifactDriver{Username: os.Getenv("GITHUB_TOKEN")} assert.NotEmpty(t, driver.Username) err = driver.Load(&wfv1.Artifact{ ArtifactLocation: wfv1.ArtifactLocation{ @@ -82,7 +82,7 @@ func TestGitArtifactDriverLoad_SSL(t *testing.T) { tmp, err := ioutil.TempDir("", "") assert.NoError(t, err) println(tmp) - driver := &GitArtifactDriver{SSHPrivateKey: string(data)} + driver := &ArtifactDriver{SSHPrivateKey: string(data)} err = driver.Load(&wfv1.Artifact{ ArtifactLocation: wfv1.ArtifactLocation{ Git: &wfv1.GitArtifact{ diff --git a/workflow/artifacts/hdfs/hdfs.go b/workflow/artifacts/hdfs/hdfs.go index b02f5e7943ac..39f76412a7cf 100644 --- a/workflow/artifacts/hdfs/hdfs.go +++ b/workflow/artifacts/hdfs/hdfs.go @@ -13,6 +13,7 @@ import ( "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/resource" ) @@ -25,6 +26,8 @@ type ArtifactDriver struct { KrbOptions *KrbOptions } +var _ common.ArtifactDriver = &ArtifactDriver{} + // KrbOptions is options for Kerberos type KrbOptions struct { CCacheOptions *CCacheOptions @@ -221,3 +224,7 @@ func (driver *ArtifactDriver) Save(path string, outputArtifact *wfv1.Artifact) e return hdfscli.CopyToRemote(path, driver.Path) } + +func (driver *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/http/http.go b/workflow/artifacts/http/http.go index 0f8bdaf960b8..afb47289fa1a 100644 --- a/workflow/artifacts/http/http.go +++ b/workflow/artifacts/http/http.go @@ -9,13 +9,16 @@ import ( "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" ) -// HTTPArtifactDriver is the artifact driver for a HTTP URL -type HTTPArtifactDriver struct{} +// ArtifactDriver is the artifact driver for a HTTP URL +type ArtifactDriver struct{} + +var _ common.ArtifactDriver = &ArtifactDriver{} // Load download artifacts from an HTTP URL -func (h *HTTPArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { +func (h *ArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { // Download the file to a local file path args := []string{"-fsS", "-L", "-o", path, inputArtifact.HTTP.URL} headers := inputArtifact.HTTP.Headers @@ -41,6 +44,10 @@ func (h *HTTPArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) err return nil } -func (h *HTTPArtifactDriver) Save(string, *wfv1.Artifact) error { +func (h *ArtifactDriver) Save(string, *wfv1.Artifact) error { return errors.Errorf(errors.CodeBadRequest, "HTTP output artifacts unsupported") } + +func (h *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/http/http_test.go b/workflow/artifacts/http/http_test.go index 6ee24648fe54..ed3b0eb37365 100644 --- a/workflow/artifacts/http/http_test.go +++ b/workflow/artifacts/http/http_test.go @@ -22,7 +22,7 @@ func captureOutput(f func()) string { } func TestHTTPArtifactDriver_Load(t *testing.T) { - driver := &HTTPArtifactDriver{} + driver := &ArtifactDriver{} a := &wfv1.HTTPArtifact{ URL: "https://github.com/argoproj/argo-workflows", } @@ -67,6 +67,6 @@ func TestHTTPArtifactDriver_Load(t *testing.T) { } func TestHTTPArtifactDriver_Save(t *testing.T) { - driver := &HTTPArtifactDriver{} + driver := &ArtifactDriver{} assert.Error(t, driver.Save("", nil)) } diff --git a/workflow/artifacts/oss/oss.go b/workflow/artifacts/oss/oss.go index cd78dee5c7f4..15925f53ecb2 100644 --- a/workflow/artifacts/oss/oss.go +++ b/workflow/artifacts/oss/oss.go @@ -9,16 +9,19 @@ import ( "k8s.io/apimachinery/pkg/util/wait" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" ) -// OSSArtifactDriver is a driver for OSS -type OSSArtifactDriver struct { +// ArtifactDriver is a driver for OSS +type ArtifactDriver struct { Endpoint string AccessKey string SecretKey string } -func (ossDriver *OSSArtifactDriver) newOSSClient() (*oss.Client, error) { +var _ common.ArtifactDriver = &ArtifactDriver{} + +func (ossDriver *ArtifactDriver) newOSSClient() (*oss.Client, error) { client, err := oss.New(ossDriver.Endpoint, ossDriver.AccessKey, ossDriver.SecretKey) if err != nil { log.Warnf("Failed to create new OSS client: %v", err) @@ -28,7 +31,7 @@ func (ossDriver *OSSArtifactDriver) newOSSClient() (*oss.Client, error) { } // Downloads artifacts from OSS compliant storage, e.g., downloading an artifact into local path -func (ossDriver *OSSArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { +func (ossDriver *ArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { err := wait.ExponentialBackoff(wait.Backoff{Duration: time.Second * 2, Factor: 2.0, Steps: 5, Jitter: 0.1}, func() (bool, error) { log.Infof("OSS Load path: %s, key: %s", path, inputArtifact.OSS.Key) @@ -52,7 +55,7 @@ func (ossDriver *OSSArtifactDriver) Load(inputArtifact *wfv1.Artifact, path stri } // Saves an artifact to OSS compliant storage, e.g., uploading a local file to OSS bucket -func (ossDriver *OSSArtifactDriver) Save(path string, outputArtifact *wfv1.Artifact) error { +func (ossDriver *ArtifactDriver) Save(path string, outputArtifact *wfv1.Artifact) error { err := wait.ExponentialBackoff(wait.Backoff{Duration: time.Second * 2, Factor: 2.0, Steps: 5, Jitter: 0.1}, func() (bool, error) { log.Infof("OSS Save path: %s, key: %s", path, outputArtifact.OSS.Key) @@ -87,3 +90,7 @@ func (ossDriver *OSSArtifactDriver) Save(path string, outputArtifact *wfv1.Artif }) return err } + +func (ossDriver *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/raw/raw.go b/workflow/artifacts/raw/raw.go index 714aed3b58f6..af66bbac0e53 100644 --- a/workflow/artifacts/raw/raw.go +++ b/workflow/artifacts/raw/raw.go @@ -1,16 +1,20 @@ package raw import ( + "fmt" "os" "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" ) -type RawArtifactDriver struct{} +type ArtifactDriver struct{} + +var _ common.ArtifactDriver = &ArtifactDriver{} // Store raw content as artifact -func (a *RawArtifactDriver) Load(artifact *wfv1.Artifact, path string) error { +func (a *ArtifactDriver) Load(artifact *wfv1.Artifact, path string) error { lf, err := os.Create(path) if err != nil { return err @@ -24,6 +28,10 @@ func (a *RawArtifactDriver) Load(artifact *wfv1.Artifact, path string) error { } // Save is unsupported for raw output artifacts -func (g *RawArtifactDriver) Save(string, *wfv1.Artifact) error { +func (g *ArtifactDriver) Save(string, *wfv1.Artifact) error { return errors.Errorf(errors.CodeBadRequest, "Raw output artifacts unsupported") } + +func (a *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + return nil, fmt.Errorf("ListObjects is currently not supported for this artifact type, but it will be in a future version") +} diff --git a/workflow/artifacts/raw/raw_test.go b/workflow/artifacts/raw/raw_test.go index 822e08a3072a..85ec6232bbdb 100644 --- a/workflow/artifacts/raw/raw_test.go +++ b/workflow/artifacts/raw/raw_test.go @@ -27,7 +27,7 @@ func TestLoad(t *testing.T) { art.Raw = &wfv1.RawArtifact{ Data: content, } - driver := &raw.RawArtifactDriver{} + driver := &raw.ArtifactDriver{} err = driver.Load(art, lf.Name()) assert.NoError(t, err) diff --git a/workflow/artifacts/s3/s3.go b/workflow/artifacts/s3/s3.go index c97e3b728e51..16e169c867b0 100644 --- a/workflow/artifacts/s3/s3.go +++ b/workflow/artifacts/s3/s3.go @@ -13,11 +13,12 @@ import ( "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + artifactscommon "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/common" ) -// S3ArtifactDriver is a driver for AWS S3 -type S3ArtifactDriver struct { +// ArtifactDriver is a driver for AWS S3 +type ArtifactDriver struct { Endpoint string Region string Secure bool @@ -28,8 +29,10 @@ type S3ArtifactDriver struct { Context context.Context } +var _ artifactscommon.ArtifactDriver = &ArtifactDriver{} + // newMinioClient instantiates a new minio client object. -func (s3Driver *S3ArtifactDriver) newS3Client(ctx context.Context) (argos3.S3Client, error) { +func (s3Driver *ArtifactDriver) newS3Client(ctx context.Context) (argos3.S3Client, error) { opts := argos3.S3ClientOpts{ Endpoint: s3Driver.Endpoint, Region: s3Driver.Region, @@ -44,7 +47,7 @@ func (s3Driver *S3ArtifactDriver) newS3Client(ctx context.Context) (argos3.S3Cli } // Load downloads artifacts from S3 compliant storage -func (s3Driver *S3ArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { +func (s3Driver *ArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string) error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -86,7 +89,7 @@ func (s3Driver *S3ArtifactDriver) Load(inputArtifact *wfv1.Artifact, path string } // Save saves an artifact to S3 compliant storage -func (s3Driver *S3ArtifactDriver) Save(path string, outputArtifact *wfv1.Artifact) error { +func (s3Driver *ArtifactDriver) Save(path string, outputArtifact *wfv1.Artifact) error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -131,3 +134,24 @@ func (s3Driver *S3ArtifactDriver) Save(path string, outputArtifact *wfv1.Artifac }) return err } + +func (s3Driver *ArtifactDriver) ListObjects(artifact *wfv1.Artifact) ([]string, error) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var files []string + err := wait.ExponentialBackoff(wait.Backoff{Duration: time.Second * 2, Factor: 2.0, Steps: 5, Jitter: 0.1}, + func() (bool, error) { + s3cli, err := s3Driver.newS3Client(ctx) + if err != nil { + return false, err + } + files, err = s3cli.ListDirectory(artifact.S3.Bucket, artifact.S3.Key) + if err != nil { + return false, err + } + return true, nil + }) + + return files, err +} diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go index 41df05bf2808..98377773ad7d 100644 --- a/workflow/controller/operator.go +++ b/workflow/controller/operator.go @@ -1181,7 +1181,7 @@ func (woc *wfOperationCtx) assessNodeStatus(pod *apiv1.Pod, node *wfv1.NodeStatu outputStr, ok := pod.Annotations[common.AnnotationKeyOutputs] if ok && node.Outputs == nil { updated = true - woc.log.Infof("Setting node %v outputs", node.ID) + woc.log.Infof("Setting node %v outputs: %s", node.ID, outputStr) var outputs wfv1.Outputs err := json.Unmarshal([]byte(outputStr), &outputs) if err != nil { @@ -1724,6 +1724,8 @@ func (woc *wfOperationCtx) executeTemplate(ctx context.Context, nodeName string, node, err = woc.executeDAG(ctx, nodeName, newTmplCtx, templateScope, processedTmpl, orgTmpl, opts) case wfv1.TemplateTypeSuspend: node, err = woc.executeSuspend(nodeName, templateScope, processedTmpl, orgTmpl, opts) + case wfv1.TemplateTypeData: + node, err = woc.executeData(ctx, nodeName, templateScope, processedTmpl, orgTmpl, opts) default: err = errors.Errorf(errors.CodeBadRequest, "Template '%s' missing specification", processedTmpl.Name) return woc.initializeNode(nodeName, wfv1.NodeTypeSkipped, templateScope, orgTmpl, opts.boundaryID, wfv1.NodeError, err.Error()), err @@ -2630,6 +2632,29 @@ func (woc *wfOperationCtx) executeResource(ctx context.Context, nodeName string, return node, err } +func (woc *wfOperationCtx) executeData(ctx context.Context, nodeName string, templateScope string, tmpl *wfv1.Template, orgTmpl wfv1.TemplateReferenceHolder, opts *executeTemplateOpts) (*wfv1.NodeStatus, error) { + node := woc.wf.GetNodeByName(nodeName) + if node == nil { + node = woc.initializeExecutableNode(nodeName, wfv1.NodeTypePod, templateScope, tmpl, orgTmpl, opts.boundaryID, wfv1.NodePending) + } else if !node.Pending() { + return node, nil + } + + dataTemplate, err := json.Marshal(tmpl.Data) + if err != nil { + return node, fmt.Errorf("could not marshal data in transformation: %w", err) + } + + mainCtr := woc.newExecContainer(common.MainContainerName, tmpl) + mainCtr.Command = []string{"argoexec", "data", string(dataTemplate)} + _, err = woc.createWorkflowPod(ctx, nodeName, *mainCtr, tmpl, &createWorkflowPodOpts{onExitPod: opts.onExitTemplate, executionDeadline: opts.executionDeadline, includeScriptOutput: true}) + if err != nil { + return woc.requeueIfTransientErr(err, node.Name) + } + + return node, nil +} + func (woc *wfOperationCtx) executeSuspend(nodeName string, templateScope string, tmpl *wfv1.Template, orgTmpl wfv1.TemplateReferenceHolder, opts *executeTemplateOpts) (*wfv1.NodeStatus, error) { node := woc.wf.GetNodeByName(nodeName) if node == nil { diff --git a/workflow/controller/operator_data_test.go b/workflow/controller/operator_data_test.go new file mode 100644 index 000000000000..8d4445658558 --- /dev/null +++ b/workflow/controller/operator_data_test.go @@ -0,0 +1,242 @@ +package controller + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" +) + +var inMemoryDataNode = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: artifact-passing-z9j6n +spec: + activeDeadlineSeconds: 300 + entrypoint: artifact-example + templates: + - inputs: {} + name: artifact-example + steps: + - - arguments: {} + name: generate-artifact + template: generate-artifacts + - - arguments: + artifacts: + - name: file + s3: + accessKeySecret: + key: accesskey + name: my-minio-cred + bucket: test + endpoint: minio:9000 + insecure: true + key: '{{item}}' + secretKeySecret: + key: secretkey + name: my-minio-cred + parameters: + - name: file-name + value: '{{item}}' + name: process-artifact + template: process-message + withParam: '{{steps.generate-artifact.outputs.result}}' + - - arguments: + parameters: + - name: processed + value: '{{steps.process-artifact.outputs.parameters.processed}}' + name: collect-artifact + template: collect-artifacts + - - arguments: + parameters: + - name: file + value: '{{steps.collect-artifact.outputs.result}}' + name: print-artifact + template: print-message + - data: + source: + artifactPaths: + name: "" + s3: + accessKeySecret: + key: accesskey + name: my-minio-cred + bucket: test + endpoint: minio:9000 + insecure: true + key: "" + secretKeySecret: + key: secretkey + name: my-minio-cred + transformation: + - expression: filter(data, {# endsWith ".py"}) + name: generate-artifacts + - data: + source: + %s + transformation: + - expression: map(data, {# + ".collected"}) + inputs: + parameters: + - name: processed + name: collect-artifacts + - container: + args: + - cat /file && echo "{{inputs.parameters.file-name}}.processed" | tee /tmp/f.txt + command: + - sh + - -c + image: alpine:latest + name: "" + inputs: + artifacts: + - name: file + path: /file + parameters: + - name: file-name + name: process-message + outputs: + parameters: + - name: processed + valueFrom: + path: /tmp/f.txt + - container: + args: + - echo {{inputs.parameters.file}} + command: + - sh + - -c + image: alpine:latest + inputs: + parameters: + - name: file + name: print-message + ttlStrategy: + secondsAfterCompletion: 600 +status: + nodes: + artifact-passing-z9j6n: + children: + - artifact-passing-z9j6n-3901459921 + displayName: artifact-passing-z9j6n + finishedAt: "2021-02-22T18:01:14Z" + id: artifact-passing-z9j6n + name: artifact-passing-z9j6n + outboundNodes: + - artifact-passing-z9j6n-1913061144 + phase: Running + startedAt: "2021-02-22T18:01:00Z" + templateName: artifact-example + templateScope: local/artifact-passing-z9j6n + type: Steps + artifact-passing-z9j6n-612855575: + boundaryID: artifact-passing-z9j6n + displayName: '[2]' + finishedAt: "2021-02-22T18:01:09Z" + id: artifact-passing-z9j6n-612855575 + name: artifact-passing-z9j6n[2] + phase: Running + startedAt: "2021-02-22T18:01:09Z" + templateScope: local/artifact-passing-z9j6n + type: StepGroup + artifact-passing-z9j6n-613296860: + boundaryID: artifact-passing-z9j6n + children: + - artifact-passing-z9j6n-4238057504 + - artifact-passing-z9j6n-762040888 + displayName: '[1]' + finishedAt: "2021-02-22T18:01:09Z" + id: artifact-passing-z9j6n-613296860 + name: artifact-passing-z9j6n[1] + phase: Succeeded + startedAt: "2021-02-22T18:01:02Z" + templateScope: local/artifact-passing-z9j6n + type: StepGroup + artifact-passing-z9j6n-762040888: + boundaryID: artifact-passing-z9j6n + children: + - artifact-passing-z9j6n-612855575 + displayName: process-artifact(1:script.py) + finishedAt: "2021-02-22T18:01:08Z" + hostNodeName: k3d-k3s-default-server-0 + id: artifact-passing-z9j6n-762040888 + name: artifact-passing-z9j6n[1].process-artifact(1:script.py) + phase: Succeeded + startedAt: "2021-02-22T18:01:02Z" + templateName: process-message + templateScope: local/artifact-passing-z9j6n + type: Pod + artifact-passing-z9j6n-2656044291: + boundaryID: artifact-passing-z9j6n + children: + - artifact-passing-z9j6n-613296860 + displayName: generate-artifact + finishedAt: "2021-02-22T18:01:01Z" + id: artifact-passing-z9j6n-2656044291 + name: artifact-passing-z9j6n[0].generate-artifact + outputs: + result: '["foo/script.py","script.py"]' + phase: Succeeded + startedAt: "2021-02-22T18:01:00Z" + templateName: generate-artifacts + templateScope: local/artifact-passing-z9j6n + type: Pod + artifact-passing-z9j6n-3901312826: + boundaryID: artifact-passing-z9j6n + children: + - artifact-passing-z9j6n-1913061144 + displayName: '[3]' + finishedAt: "2021-02-22T18:01:14Z" + id: artifact-passing-z9j6n-3901312826 + name: artifact-passing-z9j6n[3] + phase: Succeeded + startedAt: "2021-02-22T18:01:09Z" + templateScope: local/artifact-passing-z9j6n + type: StepGroup + artifact-passing-z9j6n-3901459921: + boundaryID: artifact-passing-z9j6n + children: + - artifact-passing-z9j6n-2656044291 + displayName: '[0]' + finishedAt: "2021-02-22T18:01:02Z" + id: artifact-passing-z9j6n-3901459921 + name: artifact-passing-z9j6n[0] + phase: Succeeded + startedAt: "2021-02-22T18:01:00Z" + templateScope: local/artifact-passing-z9j6n + type: StepGroup + artifact-passing-z9j6n-4238057504: + boundaryID: artifact-passing-z9j6n + displayName: process-artifact(0:foo/script.py) + finishedAt: "2021-02-22T18:01:08Z" + hostNodeName: k3d-k3s-default-server-0 + id: artifact-passing-z9j6n-4238057504 + name: artifact-passing-z9j6n[1].process-artifact(0:foo/script.py) + phase: Succeeded + startedAt: "2021-02-22T18:01:02Z" + templateName: process-message + templateScope: local/artifact-passing-z9j6n + type: Pod + phase: Running + startedAt: "2021-02-22T18:01:00Z" +` + +// Test that a pod is created when necessary +func TestDataTemplateCreatesPod(t *testing.T) { + wf := unmarshalWF(fmt.Sprintf(inMemoryDataNode, `artifactPaths: {s3: {bucket: "test"}}`)) + cancel, controller := newController(wf) + defer cancel() + + ctx := context.Background() + woc := newWorkflowOperationCtx(wf, controller) + woc.operate(ctx) + + node := woc.wf.Status.Nodes.FindByDisplayName("collect-artifact") + if assert.NotNil(t, node) { + assert.Equal(t, wfv1.NodePending, node.Phase) + } +} diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 7f4c85d5b4dd..0bcd8290d705 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -248,7 +248,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin return nil, err } - if tmpl.GetType() != wfv1.TemplateTypeResource { + if tmpl.GetType() != wfv1.TemplateTypeResource && tmpl.GetType() != wfv1.TemplateTypeData { // we do not need the wait container for resource templates because // argoexec runs as the main container and will perform the job of // annotating the outputs or errors, making the wait container redundant. @@ -752,7 +752,7 @@ func addSchedulingConstraints(pod *apiv1.Pod, wfSpec *wfv1.WorkflowSpec, tmpl *w // These are either specified in the workflow.spec.volumes or the workflow.spec.volumeClaimTemplate section func addVolumeReferences(pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Template, pvcs []apiv1.Volume) error { switch tmpl.GetType() { - case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript: + case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript, wfv1.TemplateTypeData: default: return nil } @@ -845,6 +845,14 @@ func addVolumeReferences(pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Templat break } } + if tmpl.Data != nil { + for idx, container := range pod.Spec.Containers { + if container.Name == common.MainContainerName { + pod.Spec.Containers[idx].VolumeMounts = append(pod.Spec.Containers[idx].VolumeMounts, volumeMounts...) + break + } + } + } return nil } @@ -911,7 +919,7 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.T } } if mainCtrIndex == -1 { - panic("Could not find main or wait container in pod spec") + panic("Could not find main container in pod spec") } mainCtr := &pod.Spec.Containers[mainCtrIndex] @@ -953,7 +961,7 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.T // them to the wait sidecar. In order for this to work, we mirror all volume mounts in the main // container under a well-known path. func addOutputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.Template) { - if tmpl.GetType() == wfv1.TemplateTypeResource { + if tmpl.GetType() == wfv1.TemplateTypeResource || tmpl.GetType() == wfv1.TemplateTypeData { return } mainCtrIndex := -1 @@ -1160,6 +1168,12 @@ func createSecretVolumes(tmpl *wfv1.Template) ([]apiv1.Volume, []apiv1.VolumeMou createSecretVolume(allVolumesMap, art, uniqueKeyMap) } + if tmpl.Data != nil { + if art, needed := tmpl.Data.Source.GetArtifactIfNeeded(); needed { + createSecretVolume(allVolumesMap, *art, uniqueKeyMap) + } + } + for volMountName, val := range allVolumesMap { secretVolumes = append(secretVolumes, val) secretVolMounts = append(secretVolMounts, apiv1.VolumeMount{ diff --git a/workflow/data/data.go b/workflow/data/data.go new file mode 100644 index 000000000000..9ffd7add77df --- /dev/null +++ b/workflow/data/data.go @@ -0,0 +1,60 @@ +package data + +import ( + "fmt" + + "github.com/antonmedv/expr" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" +) + +func ProcessData(data *wfv1.Data, processor wfv1.DataSourceProcessor) (interface{}, error) { + sourcedData, err := processSource(data.Source, processor) + if err != nil { + return nil, fmt.Errorf("unable to process data source: %w", err) + } + transformedData, err := processTransformation(sourcedData, &data.Transformation) + if err != nil { + return nil, fmt.Errorf("unable to process data transformation: %w", err) + } + return transformedData, nil +} + +func processSource(source wfv1.DataSource, processor wfv1.DataSourceProcessor) (interface{}, error) { + var data interface{} + var err error + switch { + case source.ArtifactPaths != nil: + data, err = processor.ProcessArtifactPaths(source.ArtifactPaths) + if err != nil { + return nil, fmt.Errorf("unable to source artifact paths: %w", err) + } + default: + return nil, fmt.Errorf("no valid source is used for data template") + } + + return data, nil +} + +func processTransformation(data interface{}, transformation *wfv1.Transformation) (interface{}, error) { + if transformation == nil { + return data, nil + } + + var err error + for i, step := range *transformation { + switch { + case step.Expression != "": + data, err = processExpression(step.Expression, data) + } + if err != nil { + return nil, fmt.Errorf("error processing data step %d: %w", i, err) + } + } + + return data, nil +} + +func processExpression(expression string, data interface{}) (interface{}, error) { + return expr.Eval(expression, map[string]interface{}{"data": data}) +} diff --git a/workflow/data/data_test.go b/workflow/data/data_test.go new file mode 100644 index 000000000000..63b56977e909 --- /dev/null +++ b/workflow/data/data_test.go @@ -0,0 +1,103 @@ +package data + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" +) + +type testDataSourceProcessor struct{} + +var _ v1alpha1.DataSourceProcessor = &testDataSourceProcessor{} + +func (t testDataSourceProcessor) ProcessArtifactPaths(*v1alpha1.ArtifactPaths) (interface{}, error) { + return []interface{}{"foo.py", "bar.pdf", "goo/foo.py", "moo/bar.pdf"}, nil +} + +type nullTestDataSourceProcessor struct{} + +var _ v1alpha1.DataSourceProcessor = &nullTestDataSourceProcessor{} + +func (t nullTestDataSourceProcessor) ProcessArtifactPaths(*v1alpha1.ArtifactPaths) (interface{}, error) { + return nil, fmt.Errorf("cannot get artifacts") +} + +func TestProcessSource(t *testing.T) { + artifactPathsSource := v1alpha1.DataSource{ArtifactPaths: &v1alpha1.ArtifactPaths{}} + data, err := processSource(artifactPathsSource, &testDataSourceProcessor{}) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"foo.py", "bar.pdf", "goo/foo.py", "moo/bar.pdf"}, data) + } + + _, err = processSource(artifactPathsSource, &nullTestDataSourceProcessor{}) + assert.Error(t, err) + + _, err = processSource(v1alpha1.DataSource{}, &nullTestDataSourceProcessor{}) + assert.Error(t, err) +} + +func TestProcessTransformation(t *testing.T) { + files := []interface{}{"foo.py", "bar.pdf", "goo/foo.py", "moo/bar.pdf"} + + filterFiles := &v1alpha1.Transformation{{Expression: `filter(data, {# endsWith '.py'})`}} + filtered, err := processTransformation(files, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"foo.py", "goo/foo.py"}, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `filter(data, {# contains '/'})`}} + filtered, err = processTransformation(files, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"goo/foo.py", "moo/bar.pdf"}, filtered) + } + filterFiles = &v1alpha1.Transformation{{Expression: `filter(data, {# contains 'foo'})`}} + filtered, err = processTransformation(filtered, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"goo/foo.py"}, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `filter(data, {# contains '/'})`}, {Expression: `filter(data, {# contains 'foo'})`}} + filtered, err = processTransformation(files, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"goo/foo.py"}, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `filter(data, {not(# contains '/')})`}} + filtered, err = processTransformation(files, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"foo.py", "bar.pdf"}, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `map(data, {# + '.processed'})`}} + filtered, err = processTransformation(files, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"foo.py.processed", "bar.pdf.processed", "goo/foo.py.processed", "moo/bar.pdf.processed"}, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `filter(data, {not(# contains '/')})`}, {Expression: `map(data, {# + '.processed'})`}} + filtered, err = processTransformation(files, filterFiles) + if assert.NoError(t, err) { + assert.Equal(t, []interface{}{"foo.py.processed", "bar.pdf.processed"}, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `filter(data, {not(# contains '/')})`}, {Expression: `map(data, {# + '.processed'})`}, {}} + _, err = processTransformation(files, filterFiles) + assert.NoError(t, err) + + filtered, err = processTransformation(files, nil) + if assert.NoError(t, err) { + assert.Equal(t, files, filtered) + } + + filtered, err = processTransformation(files, &v1alpha1.Transformation{}) + if assert.NoError(t, err) { + assert.Equal(t, files, filtered) + } + + filterFiles = &v1alpha1.Transformation{{Expression: `map(data, {# + '.processed'}`}} + _, err = processTransformation(files, filterFiles) + assert.Error(t, err) +} diff --git a/workflow/executor/data.go b/workflow/executor/data.go new file mode 100644 index 000000000000..5da38a719259 --- /dev/null +++ b/workflow/executor/data.go @@ -0,0 +1,35 @@ +package executor + +import ( + "context" + "encoding/json" + "fmt" + + "k8s.io/utils/pointer" + + "github.com/argoproj/argo-workflows/v3/workflow/data" +) + +func (we *WorkflowExecutor) Data(ctx context.Context) error { + dataTemplate := we.Template.Data + if dataTemplate == nil { + return fmt.Errorf("no data template found") + } + + transformedData, err := data.ProcessData(dataTemplate, newExecutorDataSourceProcessor(ctx, we)) + if err != nil { + return fmt.Errorf("unable to process data template: %w", err) + } + + out, err := json.Marshal(transformedData) + if err != nil { + return err + } + we.Template.Outputs.Result = pointer.StringPtr(string(out)) + err = we.AnnotateOutputs(ctx, nil) + if err != nil { + return err + } + + return nil +} diff --git a/workflow/executor/executor.go b/workflow/executor/executor.go index 50288a6ff9b2..c5d1b488f890 100644 --- a/workflow/executor/executor.go +++ b/workflow/executor/executor.go @@ -34,6 +34,7 @@ import ( "github.com/argoproj/argo-workflows/v3/util/retry" waitutil "github.com/argoproj/argo-workflows/v3/util/wait" artifact "github.com/argoproj/argo-workflows/v3/workflow/artifacts" + artifactcommon "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/common" os_specific "github.com/argoproj/argo-workflows/v3/workflow/executor/os-specific" ) @@ -580,7 +581,7 @@ func (we *WorkflowExecutor) newDriverArt(art *wfv1.Artifact) (*wfv1.Artifact, er } // InitDriver initializes an instance of an artifact driver -func (we *WorkflowExecutor) InitDriver(ctx context.Context, art *wfv1.Artifact) (artifact.ArtifactDriver, error) { +func (we *WorkflowExecutor) InitDriver(ctx context.Context, art *wfv1.Artifact) (artifactcommon.ArtifactDriver, error) { driver, err := artifact.NewDriver(ctx, art, we) if err == artifact.ErrUnsupportedDriver { return nil, errors.Errorf(errors.CodeBadRequest, "Unsupported artifact driver for %s", art.Name) diff --git a/workflow/executor/executor_data_source_processor.go b/workflow/executor/executor_data_source_processor.go new file mode 100644 index 000000000000..3e3da7bb20da --- /dev/null +++ b/workflow/executor/executor_data_source_processor.go @@ -0,0 +1,38 @@ +package executor + +import ( + "context" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" +) + +type executorDataSourceProcessor struct { + ctx context.Context + we *WorkflowExecutor +} + +func newExecutorDataSourceProcessor(ctx context.Context, we *WorkflowExecutor) *executorDataSourceProcessor { + return &executorDataSourceProcessor{ + ctx: ctx, + we: we, + } +} + +func (ep *executorDataSourceProcessor) ProcessArtifactPaths(artifacts *wfv1.ArtifactPaths) (interface{}, error) { + driverArt, err := ep.we.newDriverArt(&artifacts.Artifact) + if err != nil { + return nil, err + } + artDriver, err := ep.we.InitDriver(ep.ctx, driverArt) + if err != nil { + return nil, err + } + + var files []string + files, err = artDriver.ListObjects(&artifacts.Artifact) + if err != nil { + return nil, err + } + + return files, nil +} diff --git a/workflow/util/util.go b/workflow/util/util.go index e37913fee96f..89b28e98e4e8 100644 --- a/workflow/util/util.go +++ b/workflow/util/util.go @@ -1029,7 +1029,7 @@ func GetNodeType(tmpl *wfv1.Template) wfv1.NodeType { return wfv1.NodeTypeRetry } switch tmpl.GetType() { - case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript, wfv1.TemplateTypeResource: + case wfv1.TemplateTypeContainer, wfv1.TemplateTypeScript, wfv1.TemplateTypeResource, wfv1.TemplateTypeData: return wfv1.NodeTypePod case wfv1.TemplateTypeDAG: return wfv1.NodeTypeDAG diff --git a/workflow/validate/validate.go b/workflow/validate/validate.go index 2cd3e217a938..c118ea63d8e5 100644 --- a/workflow/validate/validate.go +++ b/workflow/validate/validate.go @@ -435,7 +435,7 @@ func (ctx *templateValidationCtx) validateTemplateHolder(tmplHolder wfv1.Templat // validateTemplateType validates that only one template type is defined func validateTemplateType(tmpl *wfv1.Template) error { numTypes := 0 - for _, tmplType := range []interface{}{tmpl.Container, tmpl.Steps, tmpl.Script, tmpl.Resource, tmpl.DAG, tmpl.Suspend} { + for _, tmplType := range []interface{}{tmpl.Container, tmpl.Steps, tmpl.Script, tmpl.Resource, tmpl.DAG, tmpl.Suspend, tmpl.Data} { if !reflect.ValueOf(tmplType).IsNil() { numTypes++ } @@ -806,7 +806,7 @@ func (ctx *templateValidationCtx) addOutputsToScope(tmpl *wfv1.Template, prefix if tmpl.Daemon != nil && *tmpl.Daemon { scope[fmt.Sprintf("%s.ip", prefix)] = true } - if tmpl.Script != nil || tmpl.Container != nil { + if tmpl.Script != nil || tmpl.Container != nil || tmpl.Data != nil { scope[fmt.Sprintf("%s.outputs.result", prefix)] = true scope[fmt.Sprintf("%s.exitCode", prefix)] = true }