diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f073bfb4df1fe..a36d736e83588 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,5 +29,29 @@ "remoteEnv": { "PATH": "${containerEnv:PATH}:/home/vscode/go/bin", "GOPATH": "/home/vscode/go" + }, + "customizations": { + "vscode": { + "settings": { + "launch": { + "configurations": [ + { + "name": "Attach to argo server", + "type": "go", + "request": "attach", + "mode": "local", + "processId": "argo" + }, + { + "name": "Attach to workflow controller", + "type": "go", + "request": "attach", + "mode": "local", + "processId": "workflow-controller" + } + ] + } + } + } } } diff --git a/.gitignore b/.gitignore index c24fdb1b5f252..e4048074607dd 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ git-ask-pass.sh sdks/python/client/dist/* /v3/ /cmd/argoexec/commands/test.txt +/db-dumps/ # Do not commit rendered installation manifests since they are misleading to users. manifests/install.yaml diff --git a/.spelling b/.spelling index 8a3401f1ca5bb..6bfe6bd93bde2 100644 --- a/.spelling +++ b/.spelling @@ -23,6 +23,7 @@ 5xx 8Ki 90m +ARGO_TEMPLATE Alexandre Alibaba Ang @@ -102,6 +103,7 @@ PVCs Peixuan Ploomber Postgres +PriorityClass RCs Roadmap RoleBinding @@ -164,6 +166,7 @@ govaluate gzipped i.e. idempotence +inputs.parameters instantiator instantiators jenkins diff --git a/Makefile b/Makefile index f3acdfd3c5500..110407fb3aee0 100644 --- a/Makefile +++ b/Makefile @@ -50,12 +50,16 @@ endif PROFILE ?= minimal KUBE_NAMESPACE ?= argo # namespace where Kubernetes resources/RBAC will be installed PLUGINS ?= $(shell [ $PROFILE = plugins ] && echo false || echo true) -UI ?= false # start the UI +UI ?= false # start the UI with HTTP +UI_SECURE ?= false # start the UI with HTTPS API ?= $(UI) # start the Argo Server TASKS := controller ifeq ($(API),true) TASKS := controller server endif +ifeq ($(UI_SECURE),true) +TASKS := controller server ui +endif ifeq ($(UI),true) TASKS := controller server ui endif @@ -486,6 +490,9 @@ ifeq ($(RUN_MODE),kubernetes) kubectl -n $(KUBE_NAMESPACE) scale deploy/workflow-controller --replicas 1 kubectl -n $(KUBE_NAMESPACE) scale deploy/argo-server --replicas 1 endif +ifeq ($(UI_SECURE)$(PROFILE),truesso) + KUBE_NAMESPACE=$(KUBE_NAMESPACE) ./hack/update-sso-redirect-url.sh +endif .PHONY: argosay argosay: @@ -563,7 +570,7 @@ endif grep '127.0.0.1.*postgres' /etc/hosts grep '127.0.0.1.*mysql' /etc/hosts ifeq ($(RUN_MODE),local) - env DEFAULT_REQUEUE_TIME=$(DEFAULT_REQUEUE_TIME) ARGO_SECURE=$(SECURE) ALWAYS_OFFLOAD_NODE_STATUS=$(ALWAYS_OFFLOAD_NODE_STATUS) ARGO_LOGLEVEL=$(LOG_LEVEL) UPPERIO_DB_DEBUG=$(UPPERIO_DB_DEBUG) ARGO_AUTH_MODE=$(AUTH_MODE) ARGO_NAMESPACED=$(NAMESPACED) ARGO_NAMESPACE=$(KUBE_NAMESPACE) ARGO_MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) ARGO_EXECUTOR_PLUGINS=$(PLUGINS) ARGO_POD_STATUS_CAPTURE_FINALIZER=$(POD_STATUS_CAPTURE_FINALIZER) PROFILE=$(PROFILE) kit $(TASKS) + env DEFAULT_REQUEUE_TIME=$(DEFAULT_REQUEUE_TIME) ARGO_SECURE=$(SECURE) ALWAYS_OFFLOAD_NODE_STATUS=$(ALWAYS_OFFLOAD_NODE_STATUS) ARGO_LOGLEVEL=$(LOG_LEVEL) UPPERIO_DB_DEBUG=$(UPPERIO_DB_DEBUG) ARGO_AUTH_MODE=$(AUTH_MODE) ARGO_NAMESPACED=$(NAMESPACED) ARGO_NAMESPACE=$(KUBE_NAMESPACE) ARGO_MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) ARGO_EXECUTOR_PLUGINS=$(PLUGINS) ARGO_POD_STATUS_CAPTURE_FINALIZER=$(POD_STATUS_CAPTURE_FINALIZER) ARGO_UI_SECURE=$(UI_SECURE) PROFILE=$(PROFILE) kit $(TASKS) endif .PHONY: wait @@ -581,11 +588,22 @@ endif .PHONY: postgres-cli postgres-cli: - kubectl exec -ti `kubectl get pod -l app=postgres -o name|cut -c 5-` -- psql -U postgres + kubectl exec -ti svc/postgres -- psql -U postgres + +.PHONY: postgres-dump +postgres-dump: + @mkdir -p db-dumps + kubectl exec svc/postgres -- pg_dump --clean -U postgres > "db-dumps/postgres-$(BUILD_DATE).sql" .PHONY: mysql-cli mysql-cli: - kubectl exec -ti `kubectl get pod -l app=mysql -o name|cut -c 5-` -- mysql -u mysql -ppassword argo + kubectl exec -ti svc/mysql -- mysql -u mysql -ppassword argo + +.PHONY: mysql-dump +mysql-dump: + @mkdir -p db-dumps + kubectl exec svc/mysql -- mysqldump --no-tablespaces -u mysql -ppassword argo > "db-dumps/mysql-$(BUILD_DATE).sql" + test-cli: ./dist/argo diff --git a/USERS.md b/USERS.md index 344b8fd3ea97b..7ebc6b5ad0998 100644 --- a/USERS.md +++ b/USERS.md @@ -158,6 +158,7 @@ Currently, the following organizations are **officially** using Argo Workflows: 1. [Procore](https://www.procore.com) 1. [Promaton](https://www.promaton.com/) 1. [Prudential](https://www.prudential.com.sg/) +1. [Pvotal Technologies](https://pvotal.tech/) 1. [Quantibio](http://quantibio.com/us/en/) 1. [QuantumBlack](https://quantumblack.com/) 1. [Raccoon Digital Marketing](https://raccoon.ag/) diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json index c454d10098e8d..8e5601aaac0be 100644 --- a/api/jsonschema/schema.json +++ b/api/jsonschema/schema.json @@ -6843,15 +6843,15 @@ "type": "object" }, "io.argoproj.workflow.v1alpha1.StopStrategy": { - "description": "v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition", + "description": "StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after", "properties": { - "condition": { - "description": "v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.", + "expression": { + "description": "v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.", "type": "string" } }, "required": [ - "condition" + "expression" ], "type": "object" }, diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 222e843ad7cc8..b2577b4b353cc 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -2961,6 +2961,12 @@ "description": "Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\".", "name": "fields", "in": "query" + }, + { + "type": "string", + "description": "Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact.", + "name": "nameFilter", + "in": "query" } ], "responses": { @@ -10861,14 +10867,14 @@ } }, "io.argoproj.workflow.v1alpha1.StopStrategy": { - "description": "v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition", + "description": "StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after", "type": "object", "required": [ - "condition" + "expression" ], "properties": { - "condition": { - "description": "v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.", + "expression": { + "description": "v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.", "type": "string" } } diff --git a/cmd/argo/commands/archive/get.go b/cmd/argo/commands/archive/get.go index cf91949eb6617..07dcbd860ef4c 100644 --- a/cmd/argo/commands/archive/get.go +++ b/cmd/argo/commands/archive/get.go @@ -10,12 +10,16 @@ import ( "sigs.k8s.io/yaml" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowarchivepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowarchive" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.EnumFlagValue{ + AllowedValues: []string{"json", "yaml", "wide"}, + Value: "wide", + } command := &cobra.Command{ Use: "get UID", Short: "get a workflow in the archive", @@ -41,11 +45,11 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printWorkflow(wf, output) + printWorkflow(wf, output.String()) return nil }, } - command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/archive/list.go b/cmd/argo/commands/archive/list.go index 8972fab18f9cc..1ea5946537b68 100644 --- a/cmd/argo/commands/archive/list.go +++ b/cmd/argo/commands/archive/list.go @@ -10,6 +10,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowarchivepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowarchive" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/printer" @@ -18,7 +19,7 @@ import ( func NewListCommand() *cobra.Command { var ( selector string - output string + output = common.NewPrintWorkflowOutputValue("wide") chunkSize int64 ) command := &cobra.Command{ @@ -50,10 +51,10 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - return printer.PrintWorkflows(workflows, os.Stdout, printer.PrintOpts{Output: output, Namespace: true, UID: true}) + return printer.PrintWorkflows(workflows, os.Stdout, printer.PrintOpts{Output: output.String(), Namespace: true, UID: true}) }, } - command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) command.Flags().StringVarP(&selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") command.Flags().Int64VarP(&chunkSize, "chunk-size", "", 0, "Return large lists in chunks rather than all at once. Pass 0 to disable.") return command diff --git a/cmd/argo/commands/archive/resubmit.go b/cmd/argo/commands/archive/resubmit.go index 1143c42bffc60..fb26dde5172e6 100644 --- a/cmd/argo/commands/archive/resubmit.go +++ b/cmd/argo/commands/archive/resubmit.go @@ -33,7 +33,7 @@ func (o *resubmitOps) hasSelector() bool { func NewResubmitCommand() *cobra.Command { var ( resubmitOpts resubmitOps - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() ) command := &cobra.Command{ Use: "resubmit [WORKFLOW...]", @@ -87,7 +87,7 @@ func NewResubmitCommand() *cobra.Command { command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") command.Flags().Int32Var(&resubmitOpts.priority, "priority", 0, "workflow priority") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") @@ -140,7 +140,7 @@ func resubmitArchivedWorkflows(ctx context.Context, archiveServiceClient workflo if err != nil { return err } - printWorkflow(lastResubmitted, cliSubmitOpts.Output) + printWorkflow(lastResubmitted, cliSubmitOpts.Output.String()) } if len(resubmittedUids) == 1 { diff --git a/cmd/argo/commands/archive/retry.go b/cmd/argo/commands/archive/retry.go index de3eead996d98..585ee5b196061 100644 --- a/cmd/argo/commands/archive/retry.go +++ b/cmd/argo/commands/archive/retry.go @@ -35,7 +35,7 @@ func (o *retryOps) hasSelector() bool { func NewRetryCommand() *cobra.Command { var ( - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() retryOpts retryOps ) command := &cobra.Command{ @@ -92,7 +92,7 @@ func NewRetryCommand() *cobra.Command { } command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") @@ -146,7 +146,7 @@ func retryArchivedWorkflows(ctx context.Context, archiveServiceClient workflowar if err != nil { return err } - printWorkflow(lastRetried, cliSubmitOpts.Output) + printWorkflow(lastRetried, cliSubmitOpts.Output.String()) } if len(retriedUids) == 1 { // watch or wait when there is only one workflow retried diff --git a/cmd/argo/commands/clustertemplate/create.go b/cmd/argo/commands/clustertemplate/create.go index 94457fa5f494a..6bbfe0b4bb494 100644 --- a/cmd/argo/commands/clustertemplate/create.go +++ b/cmd/argo/commands/clustertemplate/create.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" ) type cliCreateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewCreateCommand() *cobra.Command { - var cliCreateOpts cliCreateOpts + var cliCreateOpts = cliCreateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "create FILE1 FILE2...", Short: "create a cluster workflow template", @@ -35,7 +36,7 @@ func NewCreateCommand() *cobra.Command { return createClusterWorkflowTemplates(cmd.Context(), args, &cliCreateOpts) }, } - command.Flags().StringVarP(&cliCreateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliCreateOpts.output, "output", "o", "Output format. "+cliCreateOpts.output.Usage()) command.Flags().BoolVar(&cliCreateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -62,7 +63,7 @@ func createClusterWorkflowTemplates(ctx context.Context, filePaths []string, cli if err != nil { return fmt.Errorf("Failed to create cluster workflow template: %s, %v", wftmpl.Name, err) } - printClusterWorkflowTemplate(created, cliOpts.output) + printClusterWorkflowTemplate(created, cliOpts.output.String()) } return nil } diff --git a/cmd/argo/commands/clustertemplate/get.go b/cmd/argo/commands/clustertemplate/get.go index ff704bf45a876..e12331af5896d 100644 --- a/cmd/argo/commands/clustertemplate/get.go +++ b/cmd/argo/commands/clustertemplate/get.go @@ -4,11 +4,12 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" clusterworkflowtmplpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.NewPrintWorkflowOutputValue("") command := &cobra.Command{ Use: "get CLUSTER WORKFLOW_TEMPLATE...", @@ -29,12 +30,12 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printClusterWorkflowTemplate(wftmpl, output) + printClusterWorkflowTemplate(wftmpl, output.String()) } return nil }, } - command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/clustertemplate/lint.go b/cmd/argo/commands/clustertemplate/lint.go index 141346189e60c..e2addeb27a841 100644 --- a/cmd/argo/commands/clustertemplate/lint.go +++ b/cmd/argo/commands/clustertemplate/lint.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/cmd/argo/lint" wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" ) @@ -13,7 +14,10 @@ import ( func NewLintCommand() *cobra.Command { var ( strict bool - output string + output = common.EnumFlagValue{ + AllowedValues: []string{"pretty", "simple"}, + Value: "pretty", + } ) command := &cobra.Command{ @@ -32,11 +36,11 @@ func NewLintCommand() *cobra.Command { Printer: os.Stdout, } - return lint.RunLint(ctx, apiClient, []string{wf.ClusterWorkflowTemplatePlural}, output, false, opts) + return lint.RunLint(ctx, apiClient, []string{wf.ClusterWorkflowTemplatePlural}, output.String(), false, opts) }, } - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "perform strict workflow validation") return command } diff --git a/cmd/argo/commands/clustertemplate/list.go b/cmd/argo/commands/clustertemplate/list.go index 71d7148936818..9bd2cee483628 100644 --- a/cmd/argo/commands/clustertemplate/list.go +++ b/cmd/argo/commands/clustertemplate/list.go @@ -8,16 +8,15 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) -type listFlags struct { - output string // --output -} - func NewListCommand() *cobra.Command { - var listArgs listFlags + var output = common.EnumFlagValue{ + AllowedValues: []string{"wide", "name"}, + } command := &cobra.Command{ Use: "list", Short: "list cluster workflow templates", @@ -44,7 +43,7 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - switch listArgs.output { + switch output.String() { case "", "wide": printTable(cwftmplList.Items) case "name": @@ -52,12 +51,12 @@ func NewListCommand() *cobra.Command { fmt.Println(cwftmp.ObjectMeta.Name) } default: - return fmt.Errorf("Unknown output mode: %s", listArgs.output) + return fmt.Errorf("Unknown output mode: %s", output.String()) } return nil }, } - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: wide|name") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/clustertemplate/update.go b/cmd/argo/commands/clustertemplate/update.go index 2ef63615180e1..78cad58774082 100644 --- a/cmd/argo/commands/clustertemplate/update.go +++ b/cmd/argo/commands/clustertemplate/update.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" ) type cliUpdateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewUpdateCommand() *cobra.Command { - var cliUpdateOpts cliUpdateOpts + var cliUpdateOpts = cliUpdateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "update FILE1 FILE2...", Short: "update a cluster workflow template", @@ -34,7 +35,7 @@ func NewUpdateCommand() *cobra.Command { return updateClusterWorkflowTemplates(cmd.Context(), args, &cliUpdateOpts) }, } - command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliUpdateOpts.output, "output", "o", "Output format. "+cliUpdateOpts.output.Usage()) command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -68,7 +69,7 @@ func updateClusterWorkflowTemplates(ctx context.Context, filePaths []string, cli if err != nil { return fmt.Errorf("Failed to update cluster workflow template: %s, %v", wftmpl.Name, err) } - printClusterWorkflowTemplate(updated, cliOpts.output) + printClusterWorkflowTemplate(updated, cliOpts.output.String()) } return nil } diff --git a/cmd/argo/commands/common/flags.go b/cmd/argo/commands/common/flags.go new file mode 100644 index 0000000000000..085905bb8a55c --- /dev/null +++ b/cmd/argo/commands/common/flags.go @@ -0,0 +1,48 @@ +package common + +import ( + "errors" + "fmt" + "slices" + "strings" + + "github.com/spf13/pflag" +) + +// EnumFlagValue represents a CLI flag that can take one of a fixed set of values, and validates +// that the provided value is one of the allowed values. +// There's several libraries for this (e.g. https://github.com/thediveo/enumflag), but they're overkill. +type EnumFlagValue struct { + AllowedValues []string + Value string +} + +func (e *EnumFlagValue) Usage() string { + return fmt.Sprintf("One of: %s", strings.Join(e.AllowedValues, "|")) +} + +func (e *EnumFlagValue) String() string { + return e.Value +} + +func (e *EnumFlagValue) Set(v string) error { + if slices.Contains(e.AllowedValues, v) { + e.Value = v + return nil + } else { + return errors.New(e.Usage()) + } +} + +func (e *EnumFlagValue) Type() string { + return "string" +} + +var _ pflag.Value = &EnumFlagValue{} + +func NewPrintWorkflowOutputValue(value string) EnumFlagValue { + return EnumFlagValue{ + AllowedValues: []string{"name", "json", "yaml", "wide"}, + Value: value, + } +} diff --git a/cmd/argo/commands/common/flags_test.go b/cmd/argo/commands/common/flags_test.go new file mode 100644 index 0000000000000..efadec0b38a59 --- /dev/null +++ b/cmd/argo/commands/common/flags_test.go @@ -0,0 +1,35 @@ +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEnumFlagValue(t *testing.T) { + e := EnumFlagValue{ + AllowedValues: []string{"name", "json", "yaml", "wide"}, + Value: "json", + } + t.Run("Usage", func(t *testing.T) { + assert.Equal(t, "One of: name|json|yaml|wide", e.Usage()) + }) + + t.Run("String", func(t *testing.T) { + assert.Equal(t, "json", e.String()) + }) + + t.Run("Type", func(t *testing.T) { + assert.Equal(t, "string", e.Type()) + }) + + t.Run("Set", func(t *testing.T) { + err := e.Set("name") + require.NoError(t, err) + assert.Equal(t, "name", e.Value) + + err = e.Set("invalid") + require.Error(t, err, "One of: name|json|yaml|wide") + }) +} diff --git a/cmd/argo/commands/common/get.go b/cmd/argo/commands/common/get.go index 0740978b03074..4e2422ad86de0 100644 --- a/cmd/argo/commands/common/get.go +++ b/cmd/argo/commands/common/get.go @@ -20,7 +20,7 @@ import ( const onExitSuffix = "onExit" type GetFlags struct { - Output string + Output EnumFlagValue NodeFieldSelectorString string // Only used for backwards compatibility @@ -147,9 +147,9 @@ func PrintWorkflowHelper(wf *wfv1.Workflow, getArgs GetFlags) string { w := tabwriter.NewWriter(writerBuffer, 0, 0, 2, ' ', 0) out += "\n" // apply a dummy FgDefault format to align tab writer with the rest of the columns - if getArgs.Output == "wide" { + if getArgs.Output.String() == "wide" { _, _ = fmt.Fprintf(w, "%s\tTEMPLATE\tPODNAME\tDURATION\tARTIFACTS\tMESSAGE\tRESOURCESDURATION\tNODENAME\n", ansiFormat("STEP", FgDefault)) - } else if getArgs.Output == "short" { + } else if getArgs.Output.String() == "short" { _, _ = fmt.Fprintf(w, "%s\tTEMPLATE\tPODNAME\tDURATION\tMESSAGE\tNODENAME\n", ansiFormat("STEP", FgDefault)) } else { _, _ = fmt.Fprintf(w, "%s\tTEMPLATE\tPODNAME\tDURATION\tMESSAGE\n", ansiFormat("STEP", FgDefault)) @@ -171,7 +171,7 @@ func PrintWorkflowHelper(wf *wfv1.Workflow, getArgs GetFlags) string { onExitRoot.renderNodes(w, wf, 0, " ", " ", getArgs) } _ = w.Flush() - if getArgs.Output == "short" { + if getArgs.Output.String() == "short" { out = writerBuffer.String() } else { out += writerBuffer.String() @@ -498,7 +498,7 @@ func printNode(w *tabwriter.Writer, node wfv1.NodeStatus, wfName, nodePrefix str } else { args = []interface{}{nodePrefix, fmtNodeName, fmtTemplateName, "", "", node.Message, ""} } - if getArgs.Output == "wide" { + if getArgs.Output.String() == "wide" { msg := args[len(args)-2] args[len(args)-2] = getArtifactsString(node) args[len(args)-1] = msg @@ -507,7 +507,7 @@ func printNode(w *tabwriter.Writer, node wfv1.NodeStatus, wfName, nodePrefix str args[len(args)-1] = node.HostNodeName } _, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", args...) - } else if getArgs.Output == "short" { + } else if getArgs.Output.String() == "short" { if node.Type == wfv1.NodeTypePod { args[len(args)-1] = node.HostNodeName } diff --git a/cmd/argo/commands/common/get_test.go b/cmd/argo/commands/common/get_test.go index 7b98d4fadfca1..f042bc66c7a2d 100644 --- a/cmd/argo/commands/common/get_test.go +++ b/cmd/argo/commands/common/get_test.go @@ -54,9 +54,7 @@ func TestPrintNode(t *testing.T) { nodeTemplateRefName := "testTemplateRef" nodeID := "testID" nodeMessage := "test" - getArgs := GetFlags{ - Output: "", - } + getArgs := GetFlags{} timestamp := metav1.Time{ Time: time.Now(), } @@ -105,7 +103,7 @@ func TestPrintNode(t *testing.T) { testPrintNodeImpl(t, "", node, getArgs) getArgs = GetFlags{ - Output: "", + Output: EnumFlagValue{AllowedValues: []string{"short", "wide"}}, } node.TemplateName = nodeTemplateName @@ -124,13 +122,13 @@ func TestPrintNode(t *testing.T) { expectedPodName = util.GeneratePodName(workflowName, nodeName, templateName, nodeID, util.GetPodNameVersion()) testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\n", NodeTypeIconMap[wfv1.NodeTypeSuspend], nodeName, nodeTemplateRefName, nodeTemplateRefName, "", "", nodeMessage, ""), node, getArgs) - getArgs.Output = "wide" + require.NoError(t, getArgs.Output.Set("wide")) testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\t%s\t\n", NodeTypeIconMap[wfv1.NodeTypeSuspend], nodeName, nodeTemplateRefName, nodeTemplateRefName, "", "", getArtifactsString(node), nodeMessage, ""), node, getArgs) node.Type = wfv1.NodeTypePod testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\t%s\t%s\n", JobStatusIconMap[wfv1.NodeRunning], nodeName, nodeTemplateRefName, nodeTemplateRefName, expectedPodName, "0s", getArtifactsString(node), nodeMessage, "", kubernetesNodeName), node, getArgs) - getArgs.Output = "short" + require.NoError(t, getArgs.Output.Set("short")) testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\n", JobStatusIconMap[wfv1.NodeRunning], nodeName, nodeTemplateRefName, nodeTemplateRefName, expectedPodName, "0s", nodeMessage, kubernetesNodeName), node, getArgs) getArgs.Status = "foobar" diff --git a/cmd/argo/commands/common/submit.go b/cmd/argo/commands/common/submit.go index 905e55ea4c08a..0867c980dfda2 100644 --- a/cmd/argo/commands/common/submit.go +++ b/cmd/argo/commands/common/submit.go @@ -11,17 +11,23 @@ import ( // CliSubmitOpts holds submission options specific to CLI submission (e.g. controlling output) type CliSubmitOpts struct { - Output string // --output - Wait bool // --wait - Watch bool // --watch - Log bool // --log - Strict bool // --strict - Priority *int32 // --priority + Output EnumFlagValue // --output + Wait bool // --wait + Watch bool // --watch + Log bool // --log + Strict bool // --strict + Priority *int32 // --priority GetArgs GetFlags ScheduledTime string // --scheduled-time Parameters []string // --parameter } +func NewCliSubmitOpts() CliSubmitOpts { + return CliSubmitOpts{ + Output: NewPrintWorkflowOutputValue(""), + } +} + func WaitWatchOrLog(ctx context.Context, serviceClient workflowpkg.WorkflowServiceClient, namespace string, workflowNames []string, cliSubmitOpts CliSubmitOpts) error { if cliSubmitOpts.Log { for _, workflow := range workflowNames { @@ -35,7 +41,7 @@ func WaitWatchOrLog(ctx context.Context, serviceClient workflowpkg.WorkflowServi } } if cliSubmitOpts.Wait { - WaitWorkflows(ctx, serviceClient, namespace, workflowNames, false, !(cliSubmitOpts.Output == "" || cliSubmitOpts.Output == "wide")) + WaitWorkflows(ctx, serviceClient, namespace, workflowNames, false, !(cliSubmitOpts.Output.String() == "" || cliSubmitOpts.Output.String() == "wide")) } else if cliSubmitOpts.Watch { for _, workflow := range workflowNames { if err := WatchWorkflow(ctx, serviceClient, namespace, workflow, cliSubmitOpts.GetArgs); err != nil { diff --git a/cmd/argo/commands/cron/create.go b/cmd/argo/commands/cron/create.go index fd97f535c58e3..592289d0beb81 100644 --- a/cmd/argo/commands/cron/create.go +++ b/cmd/argo/commands/cron/create.go @@ -7,20 +7,21 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/workflow/util" ) type cliCreateOpts struct { - output string // --output - schedule string // --schedule - strict bool // --strict + output common.EnumFlagValue // --output + schedule string // --schedule + strict bool // --strict } func NewCreateCommand() *cobra.Command { var ( - cliCreateOpts cliCreateOpts + cliCreateOpts = cliCreateOpts{output: common.NewPrintWorkflowOutputValue("")} submitOpts wfv1.SubmitOpts parametersFile string ) @@ -40,7 +41,7 @@ func NewCreateCommand() *cobra.Command { } util.PopulateSubmitOpts(command, &submitOpts, ¶metersFile, false) - command.Flags().StringVarP(&cliCreateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliCreateOpts.output, "output", "o", "Output format. "+cliCreateOpts.output.Usage()) command.Flags().BoolVar(&cliCreateOpts.strict, "strict", true, "perform strict workflow validation") command.Flags().StringVar(&cliCreateOpts.schedule, "schedule", "", "override cron workflow schedule") return command @@ -90,7 +91,7 @@ func CreateCronWorkflows(ctx context.Context, filePaths []string, cliOpts *cliCr if err != nil { return fmt.Errorf("Failed to create cron workflow: %v", err) } - fmt.Print(getCronWorkflowGet(created)) + fmt.Print(getCronWorkflowGet(ctx, created)) } return nil } diff --git a/cmd/argo/commands/cron/get.go b/cmd/argo/commands/cron/get.go index 75e5e242e150b..fbbdd7ba561ce 100644 --- a/cmd/argo/commands/cron/get.go +++ b/cmd/argo/commands/cron/get.go @@ -4,11 +4,12 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.NewPrintWorkflowOutputValue("") command := &cobra.Command{ Use: "get CRON_WORKFLOW...", @@ -33,12 +34,12 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printCronWorkflow(cronWf, output) + printCronWorkflow(ctx, cronWf, output.String()) } return nil }, } - command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/cron/lint.go b/cmd/argo/commands/cron/lint.go index 5c7f3a8638859..5ba988a2991b4 100644 --- a/cmd/argo/commands/cron/lint.go +++ b/cmd/argo/commands/cron/lint.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/cmd/argo/lint" wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" ) @@ -13,7 +14,7 @@ import ( func NewLintCommand() *cobra.Command { var ( strict bool - output string + output = common.EnumFlagValue{AllowedValues: []string{"pretty", "simple"}, Value: "pretty"} ) command := &cobra.Command{ @@ -31,11 +32,11 @@ func NewLintCommand() *cobra.Command { DefaultNamespace: client.Namespace(), Printer: os.Stdout, } - return lint.RunLint(ctx, apiClient, []string{wf.CronWorkflowPlural}, output, false, opts) + return lint.RunLint(ctx, apiClient, []string{wf.CronWorkflowPlural}, output.String(), false, opts) }, } - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "perform strict validation") return command } diff --git a/cmd/argo/commands/cron/list.go b/cmd/argo/commands/cron/list.go index d4ccfc4b118ba..f1c2c272293a8 100644 --- a/cmd/argo/commands/cron/list.go +++ b/cmd/argo/commands/cron/list.go @@ -1,6 +1,7 @@ package cron import ( + "context" "fmt" "os" "text/tabwriter" @@ -11,18 +12,21 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) type listFlags struct { - allNamespaces bool // --all-namespaces - output string // --output - labelSelector string // --selector + allNamespaces bool // --all-namespaces + output common.EnumFlagValue // --output + labelSelector string // --selector } func NewListCommand() *cobra.Command { - var listArgs listFlags + var listArgs = listFlags{ + output: common.EnumFlagValue{AllowedValues: []string{"wide", "name"}}, + } command := &cobra.Command{ Use: "list", Short: "list cron workflows", @@ -48,26 +52,26 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - switch listArgs.output { + switch listArgs.output.String() { case "", "wide": - printTable(cronWfList.Items, &listArgs) + printTable(ctx, cronWfList.Items, &listArgs) case "name": for _, cronWf := range cronWfList.Items { fmt.Println(cronWf.ObjectMeta.Name) } default: - return fmt.Errorf("Unknown output mode: %s", listArgs.output) + return fmt.Errorf("Unknown output mode: %s", listArgs.output.String()) } return nil }, } command.Flags().BoolVarP(&listArgs.allNamespaces, "all-namespaces", "A", false, "Show workflows from all namespaces") - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: wide|name") + command.Flags().VarP(&listArgs.output, "output", "o", "Output format. "+listArgs.output.Usage()) command.Flags().StringVarP(&listArgs.labelSelector, "selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.") return command } -func printTable(wfList []wfv1.CronWorkflow, listArgs *listFlags) { +func printTable(ctx context.Context, wfList []wfv1.CronWorkflow, listArgs *listFlags) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) if listArgs.allNamespaces { _, _ = fmt.Fprint(w, "NAMESPACE\t") @@ -85,7 +89,7 @@ func printTable(wfList []wfv1.CronWorkflow, listArgs *listFlags) { cleanLastScheduledTime = "N/A" } var cleanNextScheduledTime string - if next, err := GetNextRuntime(&cwf); err == nil { + if next, err := GetNextRuntime(ctx, &cwf); err == nil { cleanNextScheduledTime = humanize.RelativeDurationShort(next, time.Now()) } else { cleanNextScheduledTime = "N/A" diff --git a/cmd/argo/commands/cron/update.go b/cmd/argo/commands/cron/update.go index e1340267fe95b..807a8c4e0b2dc 100644 --- a/cmd/argo/commands/cron/update.go +++ b/cmd/argo/commands/cron/update.go @@ -7,19 +7,20 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/workflow/util" ) type cliUpdateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewUpdateCommand() *cobra.Command { var ( - cliUpdateOpts cliUpdateOpts + cliUpdateOpts = cliUpdateOpts{output: common.NewPrintWorkflowOutputValue("")} submitOpts wfv1.SubmitOpts parametersFile string ) @@ -48,7 +49,7 @@ func NewUpdateCommand() *cobra.Command { } util.PopulateSubmitOpts(command, &submitOpts, ¶metersFile, false) - command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliUpdateOpts.output, "output", "o", "Output format. "+cliUpdateOpts.output.Usage()) command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -89,7 +90,7 @@ func updateCronWorkflows(ctx context.Context, filePaths []string, cliOpts *cliUp if err != nil { return fmt.Errorf("Failed to update workflow template: %v", err) } - fmt.Print(getCronWorkflowGet(updated)) + fmt.Print(getCronWorkflowGet(ctx, updated)) } return nil } diff --git a/cmd/argo/commands/cron/util.go b/cmd/argo/commands/cron/util.go index eefbd754c0c17..82db7983dcded 100644 --- a/cmd/argo/commands/cron/util.go +++ b/cmd/argo/commands/cron/util.go @@ -1,6 +1,7 @@ package cron import ( + "context" "encoding/json" "fmt" "log" @@ -22,10 +23,10 @@ import ( // GetNextRuntime returns the next time the workflow should run in local time. It assumes the workflow-controller is in // UTC, but nevertheless returns the time in the local timezone. -func GetNextRuntime(cwf *v1alpha1.CronWorkflow) (time.Time, error) { +func GetNextRuntime(ctx context.Context, cwf *v1alpha1.CronWorkflow) (time.Time, error) { var nextRunTime time.Time now := time.Now().UTC() - for _, schedule := range cwf.Spec.GetSchedulesWithTimezone() { + for _, schedule := range cwf.Spec.GetSchedulesWithTimezone(ctx) { cronSchedule, err := cron.ParseStandard(schedule) if err != nil { return time.Time{}, err @@ -77,7 +78,7 @@ func unmarshalCronWorkflows(wfBytes []byte, strict bool) []wfv1.CronWorkflow { return nil } -func printCronWorkflow(wf *wfv1.CronWorkflow, outFmt string) { +func printCronWorkflow(ctx context.Context, wf *wfv1.CronWorkflow, outFmt string) { switch outFmt { case "name": fmt.Println(wf.ObjectMeta.Name) @@ -88,13 +89,13 @@ func printCronWorkflow(wf *wfv1.CronWorkflow, outFmt string) { outBytes, _ := yaml.Marshal(wf) fmt.Print(string(outBytes)) case "wide", "": - fmt.Print(getCronWorkflowGet(wf)) + fmt.Print(getCronWorkflowGet(ctx, wf)) default: log.Fatalf("Unknown output format: %s", outFmt) } } -func getCronWorkflowGet(cwf *wfv1.CronWorkflow) string { +func getCronWorkflowGet(ctx context.Context, cwf *wfv1.CronWorkflow) string { const fmtStr = "%-30s %v\n" out := "" @@ -116,7 +117,7 @@ func getCronWorkflowGet(cwf *wfv1.CronWorkflow) string { out += fmt.Sprintf(fmtStr, "LastScheduledTime:", humanize.Timestamp(cwf.Status.LastScheduledTime.Time)) } - next, err := GetNextRuntime(cwf) + next, err := GetNextRuntime(ctx, cwf) if err == nil { out += fmt.Sprintf(fmtStr, "NextScheduledTime:", humanize.Timestamp(next)+" (assumes workflow-controller is in UTC)") } diff --git a/cmd/argo/commands/cron/util_test.go b/cmd/argo/commands/cron/util_test.go index 0eb696d14ab9e..e1e0ab9e623cb 100644 --- a/cmd/argo/commands/cron/util_test.go +++ b/cmd/argo/commands/cron/util_test.go @@ -1,6 +1,7 @@ package cron import ( + "context" "testing" "time" @@ -56,13 +57,13 @@ Conditions: func TestPrintCronWorkflow(t *testing.T) { var cronWf = v1alpha1.MustUnmarshalCronWorkflow(invalidCwf) - out := getCronWorkflowGet(cronWf) + out := getCronWorkflowGet(context.Background(), cronWf) assert.Contains(t, out, expectedOut) } func TestNextRuntime(t *testing.T) { var cronWf = v1alpha1.MustUnmarshalCronWorkflow(invalidCwf) - next, err := GetNextRuntime(cronWf) + next, err := GetNextRuntime(context.Background(), cronWf) require.NoError(t, err) assert.LessOrEqual(t, next.Unix(), time.Now().Add(1*time.Minute).Unix()) assert.Greater(t, next.Unix(), time.Now().Unix()) @@ -94,7 +95,7 @@ spec: func TestNextRuntimeWithMultipleSchedules(t *testing.T) { var cronWf = v1alpha1.MustUnmarshalCronWorkflow(cronMultipleSchedules) - next, err := GetNextRuntime(cronWf) + next, err := GetNextRuntime(context.Background(), cronWf) require.NoError(t, err) assert.LessOrEqual(t, next.Unix(), time.Now().Add(1*time.Minute).Unix()) assert.Greater(t, next.Unix(), time.Now().Unix()) diff --git a/cmd/argo/commands/get.go b/cmd/argo/commands/get.go index c1b50cded1446..e5c34ddb995b7 100644 --- a/cmd/argo/commands/get.go +++ b/cmd/argo/commands/get.go @@ -14,7 +14,11 @@ import ( ) func NewGetCommand() *cobra.Command { - var getArgs common.GetFlags + var getArgs = common.GetFlags{ + Output: common.EnumFlagValue{ + AllowedValues: []string{"name", "json", "yaml", "short", "wide"}, + }, + } command := &cobra.Command{ Use: "get WORKFLOW...", @@ -50,7 +54,7 @@ func NewGetCommand() *cobra.Command { }, } - command.Flags().StringVarP(&getArgs.Output, "output", "o", "", "Output format. One of: json|yaml|short|wide") + command.Flags().VarP(&getArgs.Output, "output", "o", "Output format. "+getArgs.Output.Usage()) command.Flags().BoolVar(&common.NoColor, "no-color", false, "Disable colorized output") command.Flags().BoolVar(&common.NoUtf8, "no-utf8", false, "Use plain 7-bits ascii characters") command.Flags().StringVar(&getArgs.Status, "status", "", "Filter by status (Pending, Running, Succeeded, Skipped, Failed, Error)") @@ -59,7 +63,7 @@ func NewGetCommand() *cobra.Command { } func printWorkflow(wf *wfv1.Workflow, getArgs common.GetFlags) error { - switch getArgs.Output { + switch getArgs.Output.String() { case "name": fmt.Println(wf.ObjectMeta.Name) case "json": diff --git a/cmd/argo/commands/lint.go b/cmd/argo/commands/lint.go index 9dcc173293036..643c4a39f6e92 100644 --- a/cmd/argo/commands/lint.go +++ b/cmd/argo/commands/lint.go @@ -20,8 +20,11 @@ func NewLintCommand() *cobra.Command { var ( strict bool lintKinds []string - output string - offline bool + output = common.EnumFlagValue{ + AllowedValues: []string{"pretty", "simple"}, + Value: "pretty", + } + offline bool ) command := &cobra.Command{ @@ -37,12 +40,12 @@ func NewLintCommand() *cobra.Command { cat manifests.yaml | argo lint --kinds=workflows,cronworkflows -`, Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return runLint(cmd.Context(), args, offline, lintKinds, output, strict) + return runLint(cmd.Context(), args, offline, lintKinds, output.String(), strict) }, } command.Flags().StringSliceVar(&lintKinds, "kinds", []string{"all"}, fmt.Sprintf("Which kinds will be linted. Can be: %s", strings.Join(allKinds, "|"))) - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "Perform strict workflow validation") command.Flags().BoolVar(&offline, "offline", false, "perform offline linting. For resources referencing other resources, the references will be resolved from the provided args") command.Flags().BoolVar(&common.NoColor, "no-color", false, "Disable colorized output") diff --git a/cmd/argo/commands/lint_test.go b/cmd/argo/commands/lint_test.go index 92aa37dde1271..da109835d6484 100644 --- a/cmd/argo/commands/lint_test.go +++ b/cmd/argo/commands/lint_test.go @@ -221,4 +221,65 @@ spec: require.NoError(t, err) assert.False(t, fatal, "should not have exited") }) + + workflowMultiDocsPath := filepath.Join(subdir, "workflowMultiDocs.yaml") + err = os.WriteFile(workflowMultiDocsPath, []byte(` +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: hello-world-template-local-arg-1 +spec: + templates: + - name: hello-world + inputs: + parameters: + - name: msg + value: 'hello world' + container: + image: busybox + command: [echo] + args: ['{{inputs.parameters.msg}}'] +--- +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: hello-world-template-local-arg-2 +spec: + templates: + - name: hello-world + inputs: + parameters: + - name: msg + value: 'hello world' + container: + image: busybox + command: [echo] + args: ['{{inputs.parameters.msg}}'] +--- +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: hello-world-local-arg- +spec: + entrypoint: whalesay + templates: + - name: whalesay + steps: + - - name: hello-world + templateRef: + name: hello-world-template-local-arg-2 + template: hello-world +`), 0644) + require.NoError(t, err) + + t.Run("linting a workflow in multi-documents yaml", func(t *testing.T) { + defer func() { logrus.StandardLogger().ExitFunc = nil }() + var fatal bool + logrus.StandardLogger().ExitFunc = func(int) { fatal = true } + err = runLint(context.Background(), []string{workflowMultiDocsPath}, true, nil, "pretty", false) + + require.NoError(t, err) + assert.False(t, fatal, "should not have exited") + }) + } diff --git a/cmd/argo/commands/list.go b/cmd/argo/commands/list.go index e5258175df2fa..db0a311c6a2d9 100644 --- a/cmd/argo/commands/list.go +++ b/cmd/argo/commands/list.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/selection" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + cmdcommon "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/printer" @@ -28,7 +29,7 @@ type listFlags struct { running bool resubmitted bool prefix string - output string + output cmdcommon.EnumFlagValue createdSince string finishedBefore string chunkSize int64 @@ -44,7 +45,7 @@ var ( ) func (f listFlags) displayFields() string { - switch f.output { + switch f.output.String() { case "name": return nameFields case "json", "yaml": @@ -58,7 +59,7 @@ func (f listFlags) displayFields() string { func NewListCommand() *cobra.Command { var ( - listArgs listFlags + listArgs = listFlags{output: cmdcommon.NewPrintWorkflowOutputValue("")} allNamespaces bool ) command := &cobra.Command{ @@ -108,7 +109,7 @@ func NewListCommand() *cobra.Command { return printer.PrintWorkflows(workflows, os.Stdout, printer.PrintOpts{ NoHeaders: listArgs.noHeaders, Namespace: allNamespaces, - Output: listArgs.output, + Output: listArgs.output.String(), }) }, } @@ -119,7 +120,7 @@ func NewListCommand() *cobra.Command { command.Flags().BoolVar(&listArgs.completed, "completed", false, "Show completed workflows. Mutually exclusive with --running.") command.Flags().BoolVar(&listArgs.running, "running", false, "Show running workflows. Mutually exclusive with --completed.") command.Flags().BoolVar(&listArgs.resubmitted, "resubmitted", false, "Show resubmitted workflows") - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: name|wide|yaml|json") + command.Flags().VarP(&listArgs.output, "output", "o", "Output format. "+listArgs.output.Usage()) command.Flags().StringVar(&listArgs.createdSince, "since", "", "Show only workflows created after than a relative duration") command.Flags().Int64VarP(&listArgs.chunkSize, "chunk-size", "", 0, "Return large lists in chunks rather than all at once. Pass 0 to disable.") command.Flags().BoolVar(&listArgs.noHeaders, "no-headers", false, "Don't print headers (default print headers).") diff --git a/cmd/argo/commands/resubmit.go b/cmd/argo/commands/resubmit.go index 049dafeb6101d..7e59c36f51c3c 100644 --- a/cmd/argo/commands/resubmit.go +++ b/cmd/argo/commands/resubmit.go @@ -31,7 +31,7 @@ func (o *resubmitOps) hasSelector() bool { func NewResubmitCommand() *cobra.Command { var ( resubmitOpts resubmitOps - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() ) command := &cobra.Command{ Use: "resubmit [WORKFLOW...]", @@ -86,7 +86,7 @@ func NewResubmitCommand() *cobra.Command { command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") command.Flags().Int32Var(&resubmitOpts.priority, "priority", 0, "workflow priority") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") diff --git a/cmd/argo/commands/retry.go b/cmd/argo/commands/retry.go index e202e2fe23c36..76ef55393a746 100644 --- a/cmd/argo/commands/retry.go +++ b/cmd/argo/commands/retry.go @@ -33,7 +33,7 @@ func (o *retryOps) hasSelector() bool { func NewRetryCommand() *cobra.Command { var ( - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() retryOpts retryOps ) command := &cobra.Command{ @@ -93,7 +93,7 @@ func NewRetryCommand() *cobra.Command { }, } command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") diff --git a/cmd/argo/commands/submit.go b/cmd/argo/commands/submit.go index 0aa1f9f7d5ff6..73c2d31c4902a 100644 --- a/cmd/argo/commands/submit.go +++ b/cmd/argo/commands/submit.go @@ -24,7 +24,7 @@ func NewSubmitCommand() *cobra.Command { var ( submitOpts wfv1.SubmitOpts parametersFile string - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() priority int32 from string ) @@ -90,7 +90,7 @@ func NewSubmitCommand() *cobra.Command { }, } util.PopulateSubmitOpts(command, &submitOpts, ¶metersFile, true) - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") @@ -150,7 +150,7 @@ func validateOptions(workflows []wfv1.Workflow, submitOpts *wfv1.SubmitOpts, cli } if submitOpts.DryRun { - if cliOpts.Output == "" { + if cliOpts.Output.String() == "" { return errors.New("--dry-run should have an output option") } if submitOpts.ServerDryRun { @@ -159,7 +159,7 @@ func validateOptions(workflows []wfv1.Workflow, submitOpts *wfv1.SubmitOpts, cli } if submitOpts.ServerDryRun { - if cliOpts.Output == "" { + if cliOpts.Output.String() == "" { return errors.New("--server-dry-run should have an output option") } } diff --git a/cmd/argo/commands/template/create.go b/cmd/argo/commands/template/create.go index 6003407ebd740..cd36e87fb344d 100644 --- a/cmd/argo/commands/template/create.go +++ b/cmd/argo/commands/template/create.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" ) type cliCreateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewCreateCommand() *cobra.Command { - var cliCreateOpts cliCreateOpts + var cliCreateOpts = cliCreateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "create FILE1 FILE2...", Short: "create a workflow template", @@ -25,7 +26,7 @@ func NewCreateCommand() *cobra.Command { return CreateWorkflowTemplates(cmd.Context(), args, &cliCreateOpts) }, } - command.Flags().StringVarP(&cliCreateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliCreateOpts.output, "output", "o", "Output format. "+cliCreateOpts.output.Usage()) command.Flags().BoolVar(&cliCreateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -56,7 +57,7 @@ func CreateWorkflowTemplates(ctx context.Context, filePaths []string, cliOpts *c if err != nil { return fmt.Errorf("Failed to create workflow template: %v", err) } - printWorkflowTemplate(created, cliOpts.output) + printWorkflowTemplate(created, cliOpts.output.String()) } return nil } diff --git a/cmd/argo/commands/template/get.go b/cmd/argo/commands/template/get.go index 2ed16f93c1ed0..0e7bc96f8172b 100644 --- a/cmd/argo/commands/template/get.go +++ b/cmd/argo/commands/template/get.go @@ -4,11 +4,12 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.NewPrintWorkflowOutputValue("") command := &cobra.Command{ Use: "get WORKFLOW_TEMPLATE...", @@ -31,12 +32,12 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printWorkflowTemplate(wftmpl, output) + printWorkflowTemplate(wftmpl, output.String()) } return nil }, } - command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/template/lint.go b/cmd/argo/commands/template/lint.go index 29c7f849766c7..c516ba8e24997 100644 --- a/cmd/argo/commands/template/lint.go +++ b/cmd/argo/commands/template/lint.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/cmd/argo/lint" wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" ) @@ -13,7 +14,10 @@ import ( func NewLintCommand() *cobra.Command { var ( strict bool - output string + output = common.EnumFlagValue{ + AllowedValues: []string{"pretty", "simple"}, + Value: "pretty", + } ) command := &cobra.Command{ @@ -31,11 +35,11 @@ func NewLintCommand() *cobra.Command { DefaultNamespace: client.Namespace(), Printer: os.Stdout, } - return lint.RunLint(ctx, apiClient, []string{wf.WorkflowTemplatePlural}, output, false, opts) + return lint.RunLint(ctx, apiClient, []string{wf.WorkflowTemplatePlural}, output.String(), false, opts) }, } - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "perform strict workflow validation") return command } diff --git a/cmd/argo/commands/template/list.go b/cmd/argo/commands/template/list.go index 42b4b21aa59cb..3dad60149e133 100644 --- a/cmd/argo/commands/template/list.go +++ b/cmd/argo/commands/template/list.go @@ -11,18 +11,19 @@ import ( "k8s.io/apimachinery/pkg/labels" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) type listFlags struct { - allNamespaces bool // --all-namespaces - output string // --output - labels string // --selector + allNamespaces bool // --all-namespaces + output common.EnumFlagValue // --output + labels string // --selector } func NewListCommand() *cobra.Command { - var listArgs listFlags + var listArgs = listFlags{output: common.EnumFlagValue{AllowedValues: []string{"wide", "name"}}} command := &cobra.Command{ Use: "list", Short: "list workflow templates", @@ -53,7 +54,7 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - switch listArgs.output { + switch listArgs.output.String() { case "", "wide": printTable(wftmplList.Items, &listArgs) case "name": @@ -67,7 +68,7 @@ func NewListCommand() *cobra.Command { }, } command.Flags().BoolVarP(&listArgs.allNamespaces, "all-namespaces", "A", false, "Show workflows from all namespaces") - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: wide|name") + command.Flags().VarP(&listArgs.output, "output", "o", "Output format. "+listArgs.output.Usage()) command.Flags().StringVarP(&listArgs.labels, "selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") return command } diff --git a/cmd/argo/commands/template/update.go b/cmd/argo/commands/template/update.go index 95e5c76177863..4849a47839852 100644 --- a/cmd/argo/commands/template/update.go +++ b/cmd/argo/commands/template/update.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" ) type cliUpdateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewUpdateCommand() *cobra.Command { - var cliUpdateOpts cliUpdateOpts + var cliUpdateOpts = cliUpdateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "update FILE1 FILE2...", Short: "update a workflow template", @@ -34,7 +35,7 @@ func NewUpdateCommand() *cobra.Command { return updateWorkflowTemplates(cmd.Context(), args, &cliUpdateOpts) }, } - command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliUpdateOpts.output, "output", "o", "Output format. "+cliUpdateOpts.output.Usage()) command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -73,7 +74,7 @@ func updateWorkflowTemplates(ctx context.Context, filePaths []string, cliOpts *c if err != nil { return fmt.Errorf("Failed to update workflow template: %v", err) } - printWorkflowTemplate(updated, cliOpts.output) + printWorkflowTemplate(updated, cliOpts.output.String()) } return nil } diff --git a/cmd/workflow-controller/main.go b/cmd/workflow-controller/main.go index 7bf2d0984fc7b..9b2247c62fd45 100644 --- a/cmd/workflow-controller/main.go +++ b/cmd/workflow-controller/main.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "strings" + "sync" "time" "github.com/argoproj/pkg/cli" @@ -134,9 +135,15 @@ func NewRootCommand() *cobra.Command { } // for controlling the dummy metrics server + var wg sync.WaitGroup dummyCtx, dummyCancel := context.WithCancel(context.Background()) defer dummyCancel() - go wfController.RunPrometheusServer(dummyCtx, true) + + wg.Add(1) + go func() { + wfController.RunPrometheusServer(dummyCtx, true) + wg.Done() + }() go leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{ Lock: &resourcelock.LeaseLock{ @@ -150,12 +157,18 @@ func NewRootCommand() *cobra.Command { Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(ctx context.Context) { dummyCancel() + wg.Wait() go wfController.Run(ctx, workflowWorkers, workflowTTLWorkers, podCleanupWorkers, cronWorkflowWorkers, workflowArchiveWorkers) - go wfController.RunPrometheusServer(ctx, false) + wg.Add(1) + go func() { + wfController.RunPrometheusServer(ctx, false) + wg.Done() + }() }, OnStoppedLeading: func() { log.WithField("id", nodeID).Info("stopped leading") cancel() + wg.Wait() go wfController.RunPrometheusServer(dummyCtx, true) }, OnNewLeader: func(identity string) { diff --git a/config/config.go b/config/config.go index edccd9fa1ba3b..8462838b4ca5c 100644 --- a/config/config.go +++ b/config/config.go @@ -6,6 +6,8 @@ import ( "net/url" "time" + metricsdk "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -24,6 +26,9 @@ type Config struct { // NodeEvents configures how node events are emitted NodeEvents NodeEvents `json:"nodeEvents,omitempty"` + // WorkflowEvents configures how workflow events are emitted + WorkflowEvents WorkflowEvents `json:"workflowEvents,omitempty"` + // Executor holds container customizations for the executor to use when running pods Executor *apiv1.Container `json:"executor,omitempty"` @@ -288,13 +293,28 @@ type MetricsConfig struct { Temporality MetricsTemporality `json:"temporality,omitempty"` } -func (mc MetricsConfig) GetSecure(defaultValue bool) bool { +func (mc *MetricsConfig) GetSecure(defaultValue bool) bool { if mc.Secure != nil { return *mc.Secure } return defaultValue } +func (mc *MetricsConfig) GetTemporality() metricsdk.TemporalitySelector { + switch mc.Temporality { + case MetricsTemporalityCumulative: + return func(metricsdk.InstrumentKind) metricdata.Temporality { + return metricdata.CumulativeTemporality + } + case MetricsTemporalityDelta: + return func(metricsdk.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + } + default: + return metricsdk.DefaultTemporalitySelector + } +} + type WorkflowRestrictions struct { TemplateReferencing TemplateReferencing `json:"templateReferencing,omitempty"` } diff --git a/config/workflow_events.go b/config/workflow_events.go new file mode 100644 index 0000000000000..45dfa250f7194 --- /dev/null +++ b/config/workflow_events.go @@ -0,0 +1,9 @@ +package config + +type WorkflowEvents struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func (e WorkflowEvents) IsEnabled() bool { + return e.Enabled == nil || *e.Enabled +} diff --git a/config/workflow_events_test.go b/config/workflow_events_test.go new file mode 100644 index 0000000000000..235400ae67bcb --- /dev/null +++ b/config/workflow_events_test.go @@ -0,0 +1,14 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/utils/ptr" +) + +func TestWorkflowEvents_IsEnabled(t *testing.T) { + assert.True(t, WorkflowEvents{}.IsEnabled()) + assert.False(t, WorkflowEvents{Enabled: ptr.To(false)}.IsEnabled()) + assert.True(t, WorkflowEvents{Enabled: ptr.To(true)}.IsEnabled()) +} diff --git a/dev/nix/conf.nix b/dev/nix/conf.nix index 68ca78dff0aa3..1850eb2d0f229 100644 --- a/dev/nix/conf.nix +++ b/dev/nix/conf.nix @@ -24,6 +24,7 @@ rec { LOGS = "true"; # same as CTRL - not acted upon UI = "true"; # same as CTRL API = "true"; # same as CTRL + UI_SECURE = "false"; PLUGINS = "false"; }; controller = { @@ -50,7 +51,10 @@ rec { args = "--loglevel ${env.LOG_LEVEL} server --namespaced=${env.NAMESPACED} --auth-mode ${env.AUTH_MODE} --secure=${env.SECURE} --x-frame-options=SAMEORIGIN"; }; ui = { - env = { }; + env = { + ARGO_UI_SECURE = "${env.UI_SECURE}"; + ARGO_SECURE = "${env.SECURE}"; + }; args = "--cwd ui start"; }; } diff --git a/docs/cli/argo_archive_list.md b/docs/cli/argo_archive_list.md index c27daefa86c87..72f710582d726 100644 --- a/docs/cli/argo_archive_list.md +++ b/docs/cli/argo_archive_list.md @@ -28,7 +28,7 @@ argo archive list [flags] ``` --chunk-size int Return large lists in chunks rather than all at once. Pass 0 to disable. -h, --help help for list - -o, --output string Output format. One of: json|yaml|wide (default "wide") + -o, --output string Output format. One of: name|json|yaml|wide (default "wide") -l, --selector string Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2) ``` diff --git a/docs/cli/argo_cluster-template_get.md b/docs/cli/argo_cluster-template_get.md index 883efc666340f..93168ddc1ac2f 100644 --- a/docs/cli/argo_cluster-template_get.md +++ b/docs/cli/argo_cluster-template_get.md @@ -10,7 +10,7 @@ argo cluster-template get CLUSTER WORKFLOW_TEMPLATE... [flags] ``` -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide + -o, --output string Output format. One of: name|json|yaml|wide ``` ### Options inherited from parent commands diff --git a/docs/cli/argo_cron_get.md b/docs/cli/argo_cron_get.md index ce50ab0aca4be..e611410406121 100644 --- a/docs/cli/argo_cron_get.md +++ b/docs/cli/argo_cron_get.md @@ -10,7 +10,7 @@ argo cron get CRON_WORKFLOW... [flags] ``` -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide + -o, --output string Output format. One of: name|json|yaml|wide ``` ### Options inherited from parent commands diff --git a/docs/cli/argo_get.md b/docs/cli/argo_get.md index 3f3ffdcfede4a..f72d8db767d87 100644 --- a/docs/cli/argo_get.md +++ b/docs/cli/argo_get.md @@ -25,7 +25,7 @@ argo get WORKFLOW... [flags] --no-color Disable colorized output --no-utf8 Use plain 7-bits ascii characters --node-field-selector string selector of node to display, eg: --node-field-selector phase=abc - -o, --output string Output format. One of: json|yaml|short|wide + -o, --output string Output format. One of: name|json|yaml|short|wide --status string Filter by status (Pending, Running, Succeeded, Skipped, Failed, Error) ``` diff --git a/docs/cli/argo_list.md b/docs/cli/argo_list.md index 05ae34c77c5a4..55b47de123ea8 100644 --- a/docs/cli/argo_list.md +++ b/docs/cli/argo_list.md @@ -48,7 +48,7 @@ argo list [flags] -h, --help help for list --no-headers Don't print headers (default print headers). --older string List completed workflows finished before the specified duration (e.g. 10m, 3h, 1d) - -o, --output string Output format. One of: name|wide|yaml|json + -o, --output string Output format. One of: name|json|yaml|wide --prefix string Filter workflows by prefix --resubmitted Show resubmitted workflows --running Show running workflows. Mutually exclusive with --completed. diff --git a/docs/cli/argo_template_get.md b/docs/cli/argo_template_get.md index 054abb1cba3d1..2d539988ec052 100644 --- a/docs/cli/argo_template_get.md +++ b/docs/cli/argo_template_get.md @@ -10,7 +10,7 @@ argo template get WORKFLOW_TEMPLATE... [flags] ``` -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide + -o, --output string Output format. One of: name|json|yaml|wide ``` ### Options inherited from parent commands diff --git a/docs/client-libraries.md b/docs/client-libraries.md index 451c381495cf1..c8fb03cbdc5ab 100644 --- a/docs/client-libraries.md +++ b/docs/client-libraries.md @@ -12,11 +12,11 @@ Client libraries often handle common tasks such as authentication for you. The following client libraries are auto-generated using [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator-cli). Please expect very minimal support from the Argo team. -| Language | Client Library | Examples/Docs | -|----------|-----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------| -| Golang | [`apiclient.go`](https://github.com/argoproj/argo-workflows/blob/main/pkg/apiclient/apiclient.go) | [Example](https://github.com/argoproj/argo-workflows/blob/main/cmd/argo/commands/submit.go) | -| Java | [Java](https://github.com/argoproj/argo-workflows/blob/main/sdks/java) | | -| Python | [Python](https://github.com/argoproj/argo-workflows/blob/main/sdks/python) | | +| Language | Client Library | Examples/Docs | +|----------|---------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| Golang | [`apiclient.go`](https://github.com/argoproj/argo-workflows/blob/main/pkg/apiclient/apiclient.go) | [Example](https://github.com/argoproj/argo-workflows/blob/main/cmd/argo/commands/submit.go) | +| Java | [Java](https://github.com/argoproj/argo-workflows/blob/main/sdks/java) | | +| Python | ⚠️ deprecated [Python](https://github.com/argoproj/argo-workflows/blob/main/sdks/python) | Use one of the [community-maintained](#community-maintained-client-libraries) instead. Will be removed in version 3.7 | ## Community-maintained client libraries @@ -24,5 +24,5 @@ The following client libraries are provided and maintained by their authors, not | Language | Client Library | Examples/Docs | |----------|---------------------------------------------------------|--------------------------------------------------------------------------| -| Python | [Couler](https://github.com/couler-proj/couler) | Multi-workflow engine support Python SDK | | Python | [Hera](https://github.com/argoproj-labs/hera-workflows) | Easy and accessible Argo workflows construction and submission in Python | +| Python | [Couler](https://github.com/couler-proj/couler) | Multi-workflow engine support Python SDK. May be unmaintained. | diff --git a/docs/cron-workflows.md b/docs/cron-workflows.md index 281366a5feef5..cdc7b440420c7 100644 --- a/docs/cron-workflows.md +++ b/docs/cron-workflows.md @@ -44,14 +44,15 @@ You can use `CronWorkflow.spec.workflowMetadata` to add `labels` and `annotation | Option Name | Default Value | Description | |:----------------------------:|:----------------------:|-------------| | `schedule` | None | [Cron schedule](#cron-schedule-syntax) to run `Workflows`. Example: `5 4 * * *`. Deprecated, use `schedules`. | -| `schedules` | None | v3.6 and after: List of [Cron schedules](#cron-schedule-syntax) to run `Workflows`. Example: `5 4 * * *`, `0 1 * * *`. Either `schedule` or `schedules` must be provided. | +| `schedules` | None | v3.6 and after: List of [Cron schedules](#cron-schedule-syntax) to run `Workflows`. Example: `5 4 * * *`, `0 1 * * *`. Either `schedule` or `schedules` must be provided. | | `timezone` | Machine timezone | [IANA Timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to run `Workflows`. Example: `America/Los_Angeles` | | `suspend` | `false` | If `true` Workflow scheduling will not occur. Can be set from the CLI, GitOps, or directly | | `concurrencyPolicy` | `Allow` | What to do if multiple `Workflows` are scheduled at the same time. `Allow`: allow all, `Replace`: remove all old before scheduling new, `Forbid`: do not allow any new while there are old | | `startingDeadlineSeconds` | `0` | Seconds after [the last scheduled time](#crash-recovery) during which a missed `Workflow` will still be run. | | `successfulJobsHistoryLimit` | `3` | Number of successful `Workflows` to persist | | `failedJobsHistoryLimit` | `1` | Number of failed `Workflows` to persist | -| `stopStrategy` | `nil` | v3.6 and after: defines if the CronWorkflow should stop scheduling based on a condition | +| `stopStrategy.expression` | `nil` | v3.6 and after: defines if the CronWorkflow should stop scheduling based on an expression, which if present must evaluate to false for the workflow to be created | +| `when` | None | v3.6 and after: An optional [expression](walk-through/conditionals.md) which will be evaluated on each cron schedule hit and the workflow will only run if it evaluates to `true` | ### Cron Schedule Syntax @@ -109,35 +110,70 @@ For example, with `timezone: America/Los_Angeles`: | | 2 | 2020-11-02 02:01:00 -0800 PST | | | 3 | 2020-11-03 02:01:00 -0800 PST | +#### Skip forward (missing schedule) + +You can use `when` to schedule once per day, even if the time you want is in a daylight saving skip forward period where it would otherwise be scheduled twice. + +An example 02:30:00 schedule + +```yaml +schedules: + - 30 2 * * * + - 0 3 * * * +when: "{{= cronworkflow.lastScheduledTime == nil || (now() - cronworkflow.lastScheduledTime).Seconds() > 3600 }}" +``` + +The 3:00 run of the schedule will not be scheduled every day of the year except on the day when the clock leaps forward over 2:30. +The `when` expression prevents this workflow from running more than once an hour. +In that case the 3:00 run will run, as 2:30 was skipped over. + +!!! Warning "Can run at 3:00" + If you create this CronWorkflow between the desired time and 3:00 it will run at 3:00 as it has never run before. + +#### Skip backwards (duplication) + +You can use `when` to schedule once per day, even if the time you want is in a daylight saving skip backwards period where it would otherwise not be scheduled. + +An example 01:30:00 schedule + +```yaml +schedules: + - 30 1 * * * +when: "{{= cronworkflow.lastScheduledTime == nil || (now() - cronworkflow.lastScheduledTime).Seconds() > 7200 }}" +``` + +This will schedule at the first 01:30 on a skip backwards change. +The second will not run because of the `when` expression, which prevents this workflow running more often than once every 2 hours.. + ### Automatically Stopping a `CronWorkflow` > v3.6 and after You can configure a `CronWorkflow` to automatically stop based on an [expression](variables.md#expression) with `stopStrategy.condition`. -You can use the [variables](variables.md#stopstrategy) `failed` and `succeeded`. +You can use the [variables](variables.md#cronworkflows) `cronworkflow.failed` and `cronworkflow.succeede2d`. For example, if you want to stop scheduling new workflows after one success: ```yaml stopStrategy: - condition: "succeeded >= 1" + expression: "cronworkflow.succeeded >= 1" ``` You can also stop scheduling new workflows after three failures with: ```yaml stopStrategy: - condition: "failed >= 3" + expression: "cronworkflow.failed >= 3" ``` !!! Warning "Scheduling vs. Completions" Depending on the time it takes to schedule and run a workflow, the number of completions can exceed the configured maximum. - For example, if you configure the `CronWorkflow` to schedule every minute (`* * * * *`) and stop after one success (`succeeded >= 1`). + For example, if you configure the `CronWorkflow` to schedule every minute (`* * * * *`) and stop after one success (`cronworkflow.succeeded >= 1`). If the `Workflow` takes 90 seconds to run, the `CronWorkflow` will actually stop after two completions. This is because when the stopping condition is achieved, there is _already_ another `Workflow` running. - For that reason, prefer conditions like `succeeded >= 1` over `succeeded == 1`. + For that reason, prefer conditions like `cronworkflow.succeeded >= 1` over `cronworkflow.succeeded == 1`. ## Managing `CronWorkflow` diff --git a/docs/deprecations.md b/docs/deprecations.md new file mode 100644 index 0000000000000..b830701e67945 --- /dev/null +++ b/docs/deprecations.md @@ -0,0 +1,75 @@ +# Deprecations + +Sometimes a feature of Argo Workflows is deprecated. +You should stop using a deprecated feature as it may be removed in a future minor or major release of Argo Workflows. + +To determine if you are using a deprecated feature the [`deprecated_feature`](metrics.md#deprecated_feature) metric can help. +This metric will go up for each use of a deprecated feature by the workflow controller. +This means it may go up once or many times for a single event. +If the number is going up the feature is still in use by your system. +If the metric is not present or no longer increasing are no longer using the monitored deprecated features. + +## `cronworkflow schedule` + +The spec field `schedule` which takes a single value is replaced by `schedules` which takes a list. +To update this replace the `schedule` with `schedules` as in the following example + +```yaml +spec: + schedule: "30 1 * * *" +``` + +is replaced with + +```yaml +spec: + schedules: + - "30 1 * * *" +``` + +## `synchronization mutex` + +The synchronization field `mutex` which takes a single value is replaced by `mutexes` which takes a list. +To update this replace `mutex` with `mutexes` as in the following example + +```yaml +synchronization: + mutex: + name: foobar +``` + +is replaced with + +```yaml +synchronization: + mutexes: + - name: foobar +``` + +## `synchronization semaphore` + +The synchronization field `semaphore` which takes a single value is replaced by `semaphores` which takes a list. +To update this replace `semaphore` with `semaphores` as in the following example + +```yaml +synchronization: + semaphore: + configMapKeyRef: + name: my-config + key: workflow +``` + +is replaced with + +```yaml +synchronization: + semaphores: + - configMapKeyRef: + name: my-config + key: workflow +``` + +## `workflow podpriority` + +The Workflow spec field `podPriority` which takes a numeric value is deprecated and `podPriorityClassName` should be used instead. +To update this you will need a [PriorityClass](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass) in your cluster and refer to that using `podPriorityClassName`. diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 66f0145724e51..45ee275208e77 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -23,6 +23,7 @@ This document outlines environment variables that can be used to customize behav | `ARGO_AGENT_CPU_LIMIT` | `resource.Quantity` | `100m` | CPU resource limit for the agent. | | `ARGO_AGENT_MEMORY_LIMIT` | `resource.Quantity` | `256m` | Memory resource limit for the agent. | | `ARGO_POD_STATUS_CAPTURE_FINALIZER` | `bool` | `false` | The finalizer blocks the deletion of pods until the controller captures their status. +| `ARGO_TEMPLATE_WITH_INPUTS_PARAMETERS` | `bool` | `true` | Whether to keep inputs.parameters inside the ARGO_TEMPLATE environment variable of pods. | `BUBBLE_ENTRY_TEMPLATE_ERR` | `bool` | `true` | Whether to bubble up template errors to workflow. | | `CACHE_GC_PERIOD` | `time.Duration` | `0s` | How often to perform memoization cache GC, which is disabled by default and can be enabled by providing a non-zero duration. | | `CACHE_GC_AFTER_NOT_HIT_DURATION` | `time.Duration` | `30s` | When a memoization cache has not been hit after this duration, it will be deleted. | @@ -55,6 +56,7 @@ This document outlines environment variables that can be used to customize behav | `WORKFLOW_GC_PERIOD` | `time.Duration` | `5m` | The periodicity for GC of workflows. | | `SEMAPHORE_NOTIFY_DELAY` | `time.Duration` | `1s` | Tuning Delay when notifying semaphore waiters about availability in the semaphore | | `WATCH_CONTROLLER_SEMAPHORE_CONFIGMAPS` | `bool` | `true` | Whether to watch the Controller's ConfigMap and semaphore ConfigMaps for run-time changes. When disabled, the Controller will only read these ConfigMaps once and will have to be manually restarted to pick up new changes. | +| `SKIP_WORKFLOW_DURATION_ESTIMATION` | `bool` | `false` | Whether to lookup resource usage from prior workflows to estimate usage for new workflows. | CLI parameters of the Controller can be specified as environment variables with the `ARGO_` prefix. For example: diff --git a/docs/fields.md b/docs/fields.md index a34f743aace10..5cc3c86970164 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -1994,12 +1994,12 @@ SynchronizationStatus stores the status of semaphore and mutex. ## StopStrategy -v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after ### Fields | Field Name | Field Type | Description | |:----------:|:----------:|---------------| -|`condition`|`string`|v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.| +|`expression`|`string`|v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.| ## Artifact @@ -2399,7 +2399,11 @@ Mutex holds Mutex configuration - [`synchronization-mutex-tmpl-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level-legacy.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-mutex-wf-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level-legacy.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml) ### Fields @@ -3291,7 +3295,11 @@ MutexStatus contains which objects hold mutex locks, and which objects this work - [`synchronization-mutex-tmpl-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level-legacy.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-mutex-wf-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level-legacy.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml) ### Fields diff --git a/docs/metrics.md b/docs/metrics.md index d9bae309d34ed..a1cd4adb586f4 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -265,6 +265,23 @@ Suppressed runs due to `concurrencyPolicy: Forbid` will not be counted. | `name` | ⚠️ The name of the CronWorkflow | | `namespace` | The namespace of the CronWorkflow | +#### `deprecated_feature` + +A counter which goes up when a feature which is [deprecated](deprecations.md) is used. +🚨 This counter may go up much more than once for a single use of the feature. + +| attribute | explanation | +|-------------|---------------------------------------------| +| `feature` | The name of the feature used | +| `namespace` | The namespace of the item using the feature | + +`feature` will be one of: + +- [`cronworkflow schedule`](deprecations.md#cronworkflow_schedule) +- [`synchronization mutex`](deprecations.md#synchronization_mutex) +- [`synchronization semaphore`](deprecations.md#synchronization_semaphore) +- [`workflow podpriority`](deprecations.md#workflow_podpriority) + #### `gauge` A gauge of the number of workflows currently in the cluster in each phase. The `Running` count does not mean that a workflows pods are running, just that the controller has scheduled them. A workflow can be stuck in `Running` with pending pods for a long time. diff --git a/docs/running-locally.md b/docs/running-locally.md index 8e5c53ced90d6..85f67f0ac5ac6 100644 --- a/docs/running-locally.md +++ b/docs/running-locally.md @@ -148,12 +148,41 @@ You'll have, either: * Postgres on , run `make postgres-cli` to access. * MySQL on , run `make mysql-cli` to access. +To back up the database, use `make postgres-dump` or `make mysql-dump`, which will generate a SQL dump in the `db-dumps/` directory. + +```console +make postgres-dump +``` + +To restore the backup, use `make postgres-cli` or `make mysql-cli`, piping in the file from the `db-dumps/` directory. + +Note that this is destructive and will delete any data you have stored. + +```console +make postgres-cli < db-dumps/2024-10-16T17:11:58Z.sql +``` + To test SSO integration, use `PROFILE=sso`: ```bash make start UI=true PROFILE=sso ``` +## TLS + +By default, `make start` will start Argo in [plain text mode](tls.md#plain-text). +To simulate a TLS proxy in front of Argo, use `UI_SECURE=true` (which implies `UI=true`): + +```bash +make start UI_SECURE=true +``` + +To start Argo in [encrypted mode](tls.md#encrypted), use `SECURE=true`, which can be optionally combined with `UI_SECURE=true`: + +```bash +make start SECURE=true UI_SECURE=true +``` + ### Running E2E tests locally Start up Argo Workflows using the following: @@ -206,6 +235,12 @@ Tests often fail: that's good. To diagnose failure: If tests run slowly or time out, factory reset your Kubernetes cluster. +### Debugging using Visual Studio Code + +When using the Dev Container with VSCode, use the `Attach to argo server` and/or `Attach to workflow controller` launch configurations to attach to the `argo` or `workflow-controller` processes, respectively. + +This will allow you to start a debug session, where you can inspect variables and set breakpoints. + ## Committing Before you commit code and raise a PR, always run: diff --git a/docs/synchronization.md b/docs/synchronization.md index 8c5ef695ce909..d18de01fcc8d4 100644 --- a/docs/synchronization.md +++ b/docs/synchronization.md @@ -24,10 +24,6 @@ data: template: "2" # Two instances of template can run at a given time in particular namespace ``` -!!! Warning - Each synchronization block may only refer to either a semaphore or a mutex. - If you specify both only the semaphore will be locked. - ## Workflow-level Synchronization You can limit parallel execution of workflows by using the same synchronization reference. @@ -36,44 +32,14 @@ In this example the synchronization key `workflow` is configured as limit `"1"`, Using a semaphore configured by a `ConfigMap`: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-wf-level- -spec: - entrypoint: hello-world - synchronization: - semaphores: - - configMapKeyRef: - name: my-config - key: workflow - templates: - - name: hello-world - container: - image: busybox - command: [echo] - args: ["hello world"] +```yaml title="examples/synchronization-wf-level.yaml" +--8<-- "examples/synchronization-wf-level.yaml:12" ``` Using a mutex is equivalent to a limit `"1"` semaphore: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-wf-level- -spec: - entrypoint: hello-world - synchronization: - mutexes: - - name: workflow - templates: - - name: hello-world - container: - image: busybox - command: [echo] - args: ["hello world"] +```yaml title="examples/synchronization-mutex-wf-level.yaml" +--8<-- "examples/synchronization-mutex-wf-level.yaml:3" ``` ## Template-level Synchronization @@ -85,77 +51,16 @@ This applies even when multiple steps or tasks within a workflow or different wo Using a semaphore configured by a `ConfigMap`: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-tmpl-level- -spec: - entrypoint: synchronization-tmpl-level-example - templates: - - name: synchronization-tmpl-level-example - steps: - - - name: synchronization-acquire-lock - template: acquire-lock - arguments: - parameters: - - name: seconds - value: "{{item}}" - withParam: '["1","2","3","4","5"]' - - - name: acquire-lock - synchronization: - semaphores: - - configMapKeyRef: - name: my-config - key: template - container: - image: alpine:latest - command: [sh, -c] - args: ["sleep 10; echo acquired lock"] +```yaml title="examples/synchronization-tmpl-level.yaml" +--8<-- "examples/synchronization-tmpl-level.yaml:11" ``` Using a mutex will limit to a single concurrent execution of the template: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-tmpl-level- -spec: - entrypoint: synchronization-tmpl-level-example - templates: - - name: synchronization-tmpl-level-example - steps: - - - name: synchronization-acquire-lock - template: acquire-lock - arguments: - parameters: - - name: seconds - value: "{{item}}" - withParam: '["1","2","3","4","5"]' - - - name: acquire-lock - synchronization: - mutexes: - - name: template - container: - image: alpine:latest - command: [sh, -c] - args: ["sleep 10; echo acquired lock"] +```yaml title="examples/synchronization-mutex-tmpl-level.yaml" +--8<-- "examples/synchronization-mutex-tmpl-level.yaml:3" ``` -Examples: - -1. [Workflow level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-wf-level.yaml) -1. [Workflow level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml) -1. [Step level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-tmpl-level.yaml) -1. [Step level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml) -1. [Legacy workflow level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-wf-level-legacy.yaml) -1. [Legacy workflow level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level-legacy.yaml) -1. [Legacy step level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-tmpl-level-legacy.yaml) -1. [Legacy step level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level-legacy.yaml) - ## Queuing When a workflow cannot acquire a lock it will be placed into a ordered queue. @@ -204,30 +109,6 @@ Examples: !!! Warning If a Workflow is at the front of the queue and it needs to acquire multiple locks, all other Workflows that also need those same locks will wait. This applies even if the other Workflows only wish to acquire a subset of those locks. -## Legacy - -In workflows prior to 3.6 you can only specify one lock in any one workflow or template using either a mutex: - -```yaml - synchronization: - mutex: - ... -``` - -or a semaphore: - -```yaml - synchronizaion: - semamphore: - ... -``` - -Specifying both would not work in <3.6, only the semaphore would be used. - -The single `mutex` and `semaphore` syntax still works in version 3.6 but is considered deprecated. -Both the `mutex` and the `semaphore` will be taken in version 3.6 with this syntax. -This syntax can be mixed with `mutexes` and `semaphores`, all locks will be required. - ## Other Parallelism support You can also [restrict parallelism at the Controller-level](parallelism.md). diff --git a/docs/upgrading.md b/docs/upgrading.md index d17f155899a84..74ec313eb94f7 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -5,6 +5,15 @@ the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summar ## Upgrading to v3.6 +### Deprecations + +The following features are deprecated and will be removed in a future verison of Argo Workflows: + +* The Python SDK is deprecated, we recommend migrating to [Hera](https://github.com/argoproj-labs/hera) +* `schedule` in CronWorkflows, `podPriority`, `mutex` and `semaphore` in Workflows and WorkflowTemplates. + +For more information on how to migrate these see [deprecations](deprecations.md) + ### Fixed Server `--basehref` inconsistency For consistency, the Server now uses `--base-href` and `ARGO_BASE_HREF`. @@ -31,6 +40,7 @@ The following are new metrics: * `cronworkflows_concurrencypolicy_triggered` * `cronworkflows_triggered_total` +* `deprecated_feature` * `is_leader` * `k8s_request_duration` * `pod_pending_count` @@ -78,6 +88,11 @@ Custom metrics, as defined by a workflow, could be defined as one type (say coun The Prometheus `/metrics` endpoint now has TLS enabled by default. To disable this set `metricsConfig.secure` to `false`. +### JSON templating fix + +When returning a map or array in an expression, you would get a Golang representation. +This now returns plain JSON. + ## Upgrading to v3.5 There are no known breaking changes in this release. diff --git a/docs/variables.md b/docs/variables.md index 5274e1f812b11..330d71572c49d 100644 --- a/docs/variables.md +++ b/docs/variables.md @@ -197,6 +197,8 @@ Only available for `successCondition` | `cronworkflow.annotations.` | CronWorkflow annotations (`string`) | | `cronworkflow.annotations.json` | CronWorkflow annotations as a JSON string (`string`) | | `cronworkflow.lastScheduledTime` | The time since this workflow was last scheduled, value is nil on first run (`*time.Time`) | +| `cronworkflow.failed` | Counts how many times child workflows failed | +| `cronworkflow.succeeded` | Counts how many times child workflows succeeded | ### `RetryStrategy` @@ -290,17 +292,6 @@ For `Template`-level metrics: | `workflow.status` | Workflow status. One of: `Succeeded`, `Failed`, `Error` | | `workflow.failures` | A list of JSON objects containing information about nodes that failed or errored during execution. Available fields: `displayName`, `message`, `templateName`, `phase`, `podName`, and `finishedAt`. | -### `stopStrategy` - -> v3.6 and after - -When using the `condition` field within the [`stopStrategy` of a `CronWorkflow`](cron-workflows.md#automatically-stopping-a-cronworkflow), special variables are available. - -| Variable | Description| -|----------|------------| -| `failed` | Counts how many times child workflows failed | -| `succeeded` | Counts how many times child workflows succeeded | - ### Knowing where you are The idea with creating a `WorkflowTemplate` is that they are reusable bits of code you will use in many actual Workflows. Sometimes it is useful to know which workflow you are part of. diff --git a/docs/workflow-controller-configmap.yaml b/docs/workflow-controller-configmap.yaml index efb6cdabe113d..b91e457d9f1d5 100644 --- a/docs/workflow-controller-configmap.yaml +++ b/docs/workflow-controller-configmap.yaml @@ -41,6 +41,13 @@ data: nodeEvents: | enabled: true + # Whether or not to emit events on workflow status changes. These can take a up a lot of space in + # k8s (typically etcd), see nodeEvents above. + # This config item allows you to disable this. + # (since v3.6) + workflowEvents: | + enabled: true + # uncomment following lines if workflow controller runs in a different k8s cluster with the # workflow workloads, or needs to communicate with the k8s apiserver using an out-of-cluster # kubeconfig secret diff --git a/docs/workflow-templates.md b/docs/workflow-templates.md index bb52956fab808..63b66dc292295 100644 --- a/docs/workflow-templates.md +++ b/docs/workflow-templates.md @@ -249,37 +249,6 @@ spec: value: "hello world" ``` -You should **never** reference another template directly on a `template` object (outside of a `steps` or `dag` template). -This includes both using `template` and `templateRef`. -This behavior is deprecated, no longer supported, and will be removed in a future version. - -Here is an example of a **deprecated** reference that **should not be used**: - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: workflow-template-hello-world- -spec: - entrypoint: hello-world - templates: - - name: hello-world - template: # You should NEVER use "template" here. Use it under a "steps" or "dag" template (see above). - templateRef: # You should NEVER use "templateRef" here. Use it under a "steps" or "dag" template (see above). - name: workflow-template-1 - template: print-message - arguments: # Arguments here are ignored. Use them under a "steps" or "dag" template (see above). - parameters: - - name: message - value: "hello world" -``` - -The reasoning for deprecating this behavior is that a `template` is a "definition": it defines inputs and things to be -done once instantiated. With this deprecated behavior, the same template object is allowed to be an "instantiator": -to pass in "live" arguments and reference other templates (those other templates may be "definitions" or "instantiators"). - -This behavior has been problematic and dangerous. It causes confusion and has design inconsistencies. - ### Create `Workflow` from `WorkflowTemplate` Spec > v2.9 and after diff --git a/examples/http-hello-world.yaml b/examples/http-hello-world.yaml index 1c58b604b5078..429120d4582ee 100644 --- a/examples/http-hello-world.yaml +++ b/examples/http-hello-world.yaml @@ -22,8 +22,8 @@ spec: continueOn: failed: true arguments: - parameters: [{name: url, value: "http://openlibrary.org/people/george08/nofound.json"}] - + parameters: [{name: url, value: "https://raw.githubusercontent.com/argoproj/argo-workflows/thisisnotahash/pkg/apis/workflow/v1alpha1/generated.swagger.json"}] + - name: http inputs: parameters: @@ -31,4 +31,3 @@ spec: http: # url: http://dummy.restapiexample.com/api/v1/employees url: "{{inputs.parameters.url}}" - diff --git a/examples/synchronization-mutex-tmpl-level-legacy.yaml b/examples/synchronization-mutex-tmpl-level-legacy.yaml index 9652e48a7d0ab..3ad2648c0b9c8 100644 --- a/examples/synchronization-mutex-tmpl-level-legacy.yaml +++ b/examples/synchronization-mutex-tmpl-level-legacy.yaml @@ -1,6 +1,5 @@ # This example demonstrates the use of a Synchronization Mutex lock on template execution. Mutex lock limits # only one of the template execution across the workflows in the namespace which has same Mutex lock. - apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: @@ -28,8 +27,10 @@ spec: - name: acquire-lock synchronization: - mutex: + mutex: # deprecated: v3.5 and before name: welcome + # mutexes: # v3.6 and after + # - name: welcome container: image: alpine:latest command: [sh, -c] @@ -37,9 +38,11 @@ spec: - name: acquire-lock-1 synchronization: - mutex: + mutex: # deprecated: v3.5 and before name: test + # mutexes: # v3.6 and after + # - name: test container: image: alpine:latest command: [sh, -c] - args: ["sleep 50; echo acquired lock"] \ No newline at end of file + args: ["sleep 50; echo acquired lock"] diff --git a/examples/synchronization-mutex-tmpl-level.yaml b/examples/synchronization-mutex-tmpl-level.yaml index c2368cca835db..948634e92e0fa 100644 --- a/examples/synchronization-mutex-tmpl-level.yaml +++ b/examples/synchronization-mutex-tmpl-level.yaml @@ -1,6 +1,5 @@ # This example demonstrates the use of a Synchronization Mutex lock on template execution. Mutex lock limits # only one of the template execution across the workflows in the namespace which has same Mutex lock. - apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: @@ -28,8 +27,10 @@ spec: - name: acquire-lock synchronization: - mutexes: + mutexes: # v3.6 and after - name: welcome + # mutex: # deprecated: v3.5 and before + # name: welcome container: image: alpine:latest command: [sh, -c] @@ -37,8 +38,10 @@ spec: - name: acquire-lock-1 synchronization: - mutexes: + mutexes: # v3.6 and after - name: test + # mutex: # deprecated: v3.5 and before + # name: test container: image: alpine:latest command: [sh, -c] diff --git a/examples/synchronization-mutex-wf-level-legacy.yaml b/examples/synchronization-mutex-wf-level-legacy.yaml index f13b199c6aaad..cc4689bbd2348 100644 --- a/examples/synchronization-mutex-wf-level-legacy.yaml +++ b/examples/synchronization-mutex-wf-level-legacy.yaml @@ -7,8 +7,10 @@ metadata: spec: entrypoint: hello-world synchronization: - mutex: - name: test + mutex: # deprecated: v3.5 and before + name: test + # mutexes: # v3.6 and after + # - name: test templates: - name: hello-world container: diff --git a/examples/synchronization-mutex-wf-level.yaml b/examples/synchronization-mutex-wf-level.yaml index 00494c3a8cd07..8d3f45af4811a 100644 --- a/examples/synchronization-mutex-wf-level.yaml +++ b/examples/synchronization-mutex-wf-level.yaml @@ -7,8 +7,10 @@ metadata: spec: entrypoint: hello-world synchronization: - mutexes: + mutexes: # v3.6 and after - name: test + # mutex: # deprecated: v3.5 and before + # name: test templates: - name: hello-world container: diff --git a/examples/synchronization-tmpl-level-legacy.yaml b/examples/synchronization-tmpl-level-legacy.yaml index b8c0f79c6c6f6..1bc96e22f04fa 100644 --- a/examples/synchronization-tmpl-level-legacy.yaml +++ b/examples/synchronization-tmpl-level-legacy.yaml @@ -27,10 +27,14 @@ spec: - name: acquire-lock synchronization: - semaphore: + semaphore: # deprecated: v3.5 and before configMapKeyRef: name: my-config key: template + # semaphores: # v3.6 and after + # - configMapKeyRef: + # name: my-config + # key: template container: image: alpine:latest command: [sh, -c] diff --git a/examples/synchronization-tmpl-level.yaml b/examples/synchronization-tmpl-level.yaml index d9eafd230ca1a..47232505ee32d 100644 --- a/examples/synchronization-tmpl-level.yaml +++ b/examples/synchronization-tmpl-level.yaml @@ -27,10 +27,14 @@ spec: - name: acquire-lock synchronization: - semaphores: + semaphores: # v3.6 and after - configMapKeyRef: name: my-config key: template + # semaphore: # deprecated: v3.5 and before + # configMapKeyRef: + # name: my-config + # key: template container: image: alpine:latest command: [sh, -c] diff --git a/examples/synchronization-wf-level-legacy.yaml b/examples/synchronization-wf-level-legacy.yaml index b7ed90a092ca1..fa89a65c200d8 100644 --- a/examples/synchronization-wf-level-legacy.yaml +++ b/examples/synchronization-wf-level-legacy.yaml @@ -16,10 +16,14 @@ metadata: spec: entrypoint: hello-world synchronization: - semaphore: + semaphore: # deprecated: v3.5 and before configMapKeyRef: name: my-config key: workflow + # semaphores: # v3.6 and after + # - configMapKeyRef: + # name: my-config + # key: workflow templates: - name: hello-world container: diff --git a/examples/synchronization-wf-level.yaml b/examples/synchronization-wf-level.yaml index 33a8e11f7eb2a..060c09cf17116 100644 --- a/examples/synchronization-wf-level.yaml +++ b/examples/synchronization-wf-level.yaml @@ -16,10 +16,14 @@ metadata: spec: entrypoint: hello-world synchronization: - semaphores: + semaphores: # v3.6 and after - configMapKeyRef: name: my-config key: workflow + # semaphore: # deprecated: v3.5 and before + # configMapKeyRef: + # name: my-config + # key: workflow templates: - name: hello-world container: diff --git a/hack/git/hooks/commit-msg b/hack/git/hooks/commit-msg index bae720f594fc1..73600e06f0511 100755 --- a/hack/git/hooks/commit-msg +++ b/hack/git/hooks/commit-msg @@ -6,7 +6,7 @@ grep -q 'Signed-off-by: ' "$1" || { exit 1 } -grep -qE '^(?:build|feat|fix|docs|style|refactor|perf|test|ci|chore|revert)\(?(?:\w+|\s|\-|_)?\)?!?:\s\w+' "$1" || grep -q 'Merge' "$1" || { +grep -qE '^(build|feat|fix|docs|style|refactor|perf|test|ci|chore|revert)\(?(\w+|\s|\-|_)?\)?!?:\s\w+' "$1" || grep -q 'Merge' "$1" || { echo >&2 '❌ Commit message must be semantic: https://github.com/zeke/semantic-pull-requests' >&2 exit 1 } diff --git a/hack/manifests/crdgen.sh b/hack/manifests/crdgen.sh index e75feab2af322..2b503ee91ca47 100755 --- a/hack/manifests/crdgen.sh +++ b/hack/manifests/crdgen.sh @@ -18,5 +18,5 @@ find manifests/base/crds/full -name 'argoproj.io*.yaml' | while read -r file; do minimal="manifests/base/crds/minimal/$(basename "$file")" echo "Creating minimal CRD file: ${minimal}" cp "$file" "$minimal" - go run ./hack/manifests removecrdvalidation "$minimal" + go run ./hack/manifests minimizecrd "$minimal" done diff --git a/hack/manifests/crds.go b/hack/manifests/crds.go index b34096161bc53..5162500a920ba 100644 --- a/hack/manifests/crds.go +++ b/hack/manifests/crds.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" "path/filepath" @@ -46,25 +47,42 @@ func cleanCRD(filename string) { } } -func removeCRDValidation(filename string) { +// minimizeCRD is a workaround for two separate issues: +// 1. "Request entity too large: limit is 3145728" errors due to https://github.com/kubernetes/kubernetes/issues/82292 +// 2. "spec.validation.openAPIV3Schema.properties[spec].properties[tasks].additionalProperties.properties[steps].items.items: Required value: must be specified" due to kubebuilder issues (https://github.com/argoproj/argo-workflows/pull/3809#discussion_r472383090) +func minimizeCRD(filename string) { data, err := os.ReadFile(filepath.Clean(filename)) if err != nil { panic(err) } + + shouldMinimize := false + if len(data) > 1024*1024 { + fmt.Printf("Minimizing %s due to CRD size (%d) exceeding 1MB\n", filename, len(data)) + shouldMinimize = true + } + crd := make(obj) err = yaml.Unmarshal(data, &crd) if err != nil { panic(err) } - spec := crd["spec"].(obj) - versions := spec["versions"].([]interface{}) - version := versions[0].(obj) - properties := version["schema"].(obj)["openAPIV3Schema"].(obj)["properties"].(obj) - for k := range properties { - if k == "spec" || k == "status" { - properties[k] = obj{"type": "object", "x-kubernetes-preserve-unknown-fields": true, "x-kubernetes-map-type": "atomic"} + + if !shouldMinimize { + name := crd["metadata"].(obj)["name"].(string) + switch name { + case "cronworkflows.argoproj.io", "clusterworkflowtemplates.argoproj.io", "workflows.argoproj.io", "workflowtemplates.argoproj.io", "workflowtasksets.argoproj.io": + fmt.Printf("Minimizing %s due to kubebuilder issues\n", filename) + shouldMinimize = true } } + + if !shouldMinimize { + return + } + + crd = stripSpecAndStatusFields(crd) + data, err = yaml.Marshal(crd) if err != nil { panic(err) @@ -74,3 +92,17 @@ func removeCRDValidation(filename string) { panic(err) } } + +// stripSpecAndStatusFields strips the "spec" and "status" fields from the CRD, as those are usually the largest. +func stripSpecAndStatusFields(crd obj) obj { + spec := crd["spec"].(obj) + versions := spec["versions"].([]interface{}) + version := versions[0].(obj) + properties := version["schema"].(obj)["openAPIV3Schema"].(obj)["properties"].(obj) + for k := range properties { + if k == "spec" || k == "status" { + properties[k] = obj{"type": "object", "x-kubernetes-preserve-unknown-fields": true, "x-kubernetes-map-type": "atomic"} + } + } + return crd +} diff --git a/hack/manifests/main.go b/hack/manifests/main.go index 5a5292f99326d..0b3284b5dc9b8 100644 --- a/hack/manifests/main.go +++ b/hack/manifests/main.go @@ -8,8 +8,8 @@ func main() { switch os.Args[1] { case "cleancrd": cleanCRD(os.Args[2]) - case "removecrdvalidation": - removeCRDValidation(os.Args[2]) + case "minimizecrd": + minimizeCRD(os.Args[2]) default: panic(os.Args[1]) } diff --git a/hack/update-sso-redirect-url.sh b/hack/update-sso-redirect-url.sh new file mode 100755 index 0000000000000..dece268307d53 --- /dev/null +++ b/hack/update-sso-redirect-url.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +# Rewrite the SSO redirect URL to use HTTPS to support "make start PROFILE=sso UI_SECURE=true". +# Can't use "kubectl patch" because the SSO config is a YAML string. +kubectl -n "${KUBE_NAMESPACE}" get configmap workflow-controller-configmap -o yaml | \ + sed 's@redirectUrl: http://localhost:8080/oauth2/callback@redirectUrl: https://localhost:8080/oauth2/callback@' | \ + kubectl apply -n "${KUBE_NAMESPACE}" -f - \ No newline at end of file diff --git a/manifests/base/crds/full/README.md b/manifests/base/crds/full/README.md index bca5186fefe56..e81aba5a49ea0 100644 --- a/manifests/base/crds/full/README.md +++ b/manifests/base/crds/full/README.md @@ -1,3 +1,4 @@ # Full CRDs -These CRDs have full schema validation. As a result, they are large and probably not suitable to be used in your cluster. +These CRDs have the full schema. +As a result, they are large and probably not suitable to be used in your cluster due to [kubernetes/kubernetes#82292](https://github.com/kubernetes/kubernetes/issues/82292). \ No newline at end of file diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml index 8864d46131397..4d46ecb5a95c0 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -43,10 +43,10 @@ spec: type: integer stopStrategy: properties: - condition: + expression: type: string required: - - condition + - expression type: object successfulJobsHistoryLimit: format: int32 diff --git a/manifests/base/crds/minimal/README.md b/manifests/base/crds/minimal/README.md index 55f48f08081fd..b7d131b4691e3 100644 --- a/manifests/base/crds/minimal/README.md +++ b/manifests/base/crds/minimal/README.md @@ -1,3 +1,3 @@ # Minimal CRDs -These CRDs omit schema validation. +These CRDs omit large fields as a workaround for [kubernetes/kubernetes#82292](https://github.com/kubernetes/kubernetes/issues/82292). diff --git a/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml b/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml index 35b1e2eab5487..d5f34672e00f8 100644 --- a/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml @@ -1,3 +1,4 @@ +# This is an auto-generated file. DO NOT EDIT apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -24,13 +25,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml b/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml index 22e2ecf0f6b41..0477a09076927 100644 --- a/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml @@ -1,3 +1,4 @@ +# This is an auto-generated file. DO NOT EDIT apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -24,9 +25,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml b/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml index 5f8d1f4e863fe..bccbf467f6b4c 100644 --- a/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml @@ -1,3 +1,4 @@ +# This is an auto-generated file. DO NOT EDIT apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/manifests/quick-start-minimal.yaml b/manifests/quick-start-minimal.yaml index 2bb819f867c93..b6b42725cfc6e 100644 --- a/manifests/quick-start-minimal.yaml +++ b/manifests/quick-start-minimal.yaml @@ -103,13 +103,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec @@ -145,9 +1237,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/quick-start-mysql.yaml b/manifests/quick-start-mysql.yaml index a1b95019f15fa..4d59148b61694 100644 --- a/manifests/quick-start-mysql.yaml +++ b/manifests/quick-start-mysql.yaml @@ -103,13 +103,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec @@ -145,9 +1237,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/quick-start-postgres.yaml b/manifests/quick-start-postgres.yaml index 743bcd43cf68c..80a8ce0aa6df5 100644 --- a/manifests/quick-start-postgres.yaml +++ b/manifests/quick-start-postgres.yaml @@ -103,13 +103,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec @@ -145,9 +1237,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + 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: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/quick-start/sso/dex/dex-cm.yaml b/manifests/quick-start/sso/dex/dex-cm.yaml index a99d186a28c28..689db0affb909 100644 --- a/manifests/quick-start/sso/dex/dex-cm.yaml +++ b/manifests/quick-start/sso/dex/dex-cm.yaml @@ -20,6 +20,7 @@ data: redirectURIs: - http://localhost:2746/oauth2/callback - http://localhost:8080/oauth2/callback + - https://localhost:8080/oauth2/callback name: Argo Server secret: ZXhhbXBsZS1hcHAtc2VjcmV0 connectors: diff --git a/mkdocs.yml b/mkdocs.yml index 52e1dbb74f3b7..70dc812ae8bfc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -32,6 +32,7 @@ markdown_extensions: - admonition - md_in_html - pymdownx.details + - pymdownx.snippets - pymdownx.superfences: custom_fences: # support mermaid diagrams per https://squidfunk.github.io/mkdocs-material/reference/diagrams/#configuration @@ -248,6 +249,7 @@ nav: - offloading-large-workflows.md - workflow-archive.md - metrics.md + - deprecations.md - workflow-executors.md - workflow-restrictions.md - sidecar-injection.md diff --git a/persist/sqldb/selector.go b/persist/sqldb/selector.go index 5e2b9cbb53ca1..93a0b580ad7b9 100644 --- a/persist/sqldb/selector.go +++ b/persist/sqldb/selector.go @@ -39,7 +39,19 @@ func BuildWorkflowSelector(in string, inArgs []any, tableName, labelTableName st clauses = append(clauses, db.Raw("namespace = ?", options.Namespace)) } if options.Name != "" { - clauses = append(clauses, db.Raw("name = ?", options.Name)) + nameFilter := options.NameFilter + if nameFilter == "" { + nameFilter = "Exact" + } + if nameFilter == "Exact" { + clauses = append(clauses, db.Raw("name = ?", options.Name)) + } + if nameFilter == "Contains" { + clauses = append(clauses, db.Raw("name like ?", "%"+options.Name+"%")) + } + if nameFilter == "Prefix" { + clauses = append(clauses, db.Raw("name like ?", options.Name+"%")) + } } if options.NamePrefix != "" { clauses = append(clauses, db.Raw("name like ?", options.NamePrefix+"%")) diff --git a/pkg/apiclient/offline-client.go b/pkg/apiclient/offline-client.go index 9446a71240b03..c6048d1dffe88 100644 --- a/pkg/apiclient/offline-client.go +++ b/pkg/apiclient/offline-client.go @@ -12,9 +12,8 @@ import ( "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/file" + "github.com/argoproj/argo-workflows/v3/workflow/common" "github.com/argoproj/argo-workflows/v3/workflow/templateresolution" - - "sigs.k8s.io/yaml" ) type offlineWorkflowTemplateGetterMap map[string]templateresolution.WorkflowTemplateNamespacedGetter @@ -50,42 +49,43 @@ func newOfflineClient(paths []string) (context.Context, Client, error) { for _, basePath := range paths { err := file.WalkManifests(basePath, func(path string, bytes []byte) error { - var generic map[string]interface{} - if err := yaml.Unmarshal(bytes, &generic); err != nil { - return fmt.Errorf("failed to parse YAML from file %s: %w", path, err) - } - switch generic["kind"] { - case "ClusterWorkflowTemplate": - cwftmpl := new(wfv1.ClusterWorkflowTemplate) - if err := yaml.Unmarshal(bytes, &cwftmpl); err != nil { - return fmt.Errorf("failed to unmarshal file %s as a ClusterWorkflowTemplate: %w", path, err) + for _, pr := range common.ParseObjects(bytes, false) { + obj, err := pr.Object, pr.Err + if err != nil { + return fmt.Errorf("failed to parse YAML from file %s: %w", path, err) } - if _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[cwftmpl.Name]; ok { - return fmt.Errorf("duplicate ClusterWorkflowTemplate found: %q", cwftmpl.Name) + if obj == nil { + continue // could not parse to kubernetes object } - clusterWorkflowTemplateGetter.clusterWorkflowTemplates[cwftmpl.Name] = cwftmpl - case "WorkflowTemplate": - wftmpl := new(wfv1.WorkflowTemplate) - if err := yaml.Unmarshal(bytes, &wftmpl); err != nil { - return fmt.Errorf("failed to unmarshal file %s as a WorkflowTemplate: %w", path, err) - } - getter, ok := workflowTemplateGetters[wftmpl.Namespace] - if !ok { - getter = &offlineWorkflowTemplateNamespacedGetter{ - namespace: wftmpl.Namespace, - workflowTemplates: map[string]*wfv1.WorkflowTemplate{}, + objName := obj.GetName() + namespace := obj.GetNamespace() + + switch v := obj.(type) { + case *wfv1.ClusterWorkflowTemplate: + if _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName]; ok { + return fmt.Errorf("duplicate ClusterWorkflowTemplate found: %q", objName) + } + clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName] = v + + case *wfv1.WorkflowTemplate: + getter, ok := workflowTemplateGetters[namespace] + if !ok { + getter = &offlineWorkflowTemplateNamespacedGetter{ + namespace: namespace, + workflowTemplates: map[string]*wfv1.WorkflowTemplate{}, + } + workflowTemplateGetters[namespace] = getter } - workflowTemplateGetters[wftmpl.Namespace] = getter - } - if _, ok := getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[wftmpl.Name]; ok { - return fmt.Errorf("duplicate WorkflowTemplate found: %q", wftmpl.Name) + if _, ok := getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName]; ok { + return fmt.Errorf("duplicate WorkflowTemplate found: %q", objName) + } + getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName] = v } - getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[wftmpl.Name] = wftmpl - } + } return nil }) diff --git a/pkg/apiclient/offline-cron-workflow-service-client.go b/pkg/apiclient/offline-cron-workflow-service-client.go index 6104a207c89bb..6dbd1a7bd407e 100644 --- a/pkg/apiclient/offline-cron-workflow-service-client.go +++ b/pkg/apiclient/offline-cron-workflow-service-client.go @@ -19,7 +19,7 @@ type OfflineCronWorkflowServiceClient struct { var _ cronworkflow.CronWorkflowServiceClient = &OfflineCronWorkflowServiceClient{} func (o OfflineCronWorkflowServiceClient) LintCronWorkflow(ctx context.Context, req *cronworkflow.LintCronWorkflowRequest, _ ...grpc.CallOption) (*v1alpha1.CronWorkflow, error) { - err := validate.ValidateCronWorkflow(o.namespacedWorkflowTemplateGetterMap.GetNamespaceGetter(req.Namespace), o.clusterWorkflowTemplateGetter, req.CronWorkflow) + err := validate.ValidateCronWorkflow(ctx, o.namespacedWorkflowTemplateGetterMap.GetNamespaceGetter(req.Namespace), o.clusterWorkflowTemplateGetter, req.CronWorkflow) if err != nil { return nil, err } diff --git a/pkg/apiclient/workflow/workflow.pb.go b/pkg/apiclient/workflow/workflow.pb.go index 0733f16480d2d..9f2f76be21f70 100644 --- a/pkg/apiclient/workflow/workflow.pb.go +++ b/pkg/apiclient/workflow/workflow.pb.go @@ -191,7 +191,9 @@ type WorkflowListRequest struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` ListOptions *v1.ListOptions `protobuf:"bytes,2,opt,name=listOptions,proto3" json:"listOptions,omitempty"` // Fields to be included or excluded in the response. e.g. "items.spec,items.status.phase", "-items.status.nodes" - Fields string `protobuf:"bytes,3,opt,name=fields,proto3" json:"fields,omitempty"` + Fields string `protobuf:"bytes,3,opt,name=fields,proto3" json:"fields,omitempty"` + // Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact + NameFilter string `protobuf:"bytes,4,opt,name=nameFilter,proto3" json:"nameFilter,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -251,6 +253,13 @@ func (m *WorkflowListRequest) GetFields() string { return "" } +func (m *WorkflowListRequest) GetNameFilter() string { + if m != nil { + return m.NameFilter + } + return "" +} + type WorkflowResubmitRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` @@ -1312,98 +1321,98 @@ func init() { } var fileDescriptor_1f6bb75f9e833cb6 = []byte{ - // 1442 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x98, 0xcd, 0x6f, 0x1c, 0xb5, - 0x1b, 0xc7, 0xe5, 0xa4, 0x4d, 0x13, 0xe7, 0xa5, 0xad, 0x7f, 0x6d, 0x7f, 0xcb, 0xa8, 0x4d, 0x53, - 0x97, 0x42, 0x9a, 0x36, 0x33, 0x79, 0x29, 0xd0, 0x22, 0x81, 0x44, 0x9b, 0x12, 0x51, 0x96, 0x52, - 0xcd, 0x22, 0x21, 0xb8, 0xa0, 0xc9, 0xec, 0x93, 0xc9, 0x34, 0x3b, 0xe3, 0xc1, 0xf6, 0x6e, 0x15, - 0x4a, 0x91, 0xe0, 0x02, 0x07, 0x24, 0x0e, 0x1c, 0xb9, 0x20, 0x24, 0x04, 0x07, 0x04, 0x08, 0x09, - 0x09, 0x81, 0x84, 0x38, 0x70, 0xe0, 0x58, 0xa9, 0x57, 0x0e, 0xa8, 0xe2, 0x1f, 0xe0, 0x3f, 0x40, - 0xf6, 0xbc, 0x67, 0xb7, 0xdb, 0x21, 0xd9, 0x42, 0x6f, 0x63, 0xcf, 0xd8, 0xcf, 0xc7, 0xdf, 0xc7, - 0x7e, 0x9e, 0xc7, 0x83, 0x4f, 0x45, 0x9b, 0x9e, 0xe5, 0x44, 0xbe, 0xdb, 0xf2, 0x21, 0x94, 0xd6, - 0x0d, 0xc6, 0x37, 0xd7, 0x5b, 0xec, 0x46, 0xf6, 0x60, 0x46, 0x9c, 0x49, 0x46, 0x46, 0xd3, 0xb6, - 0x71, 0xd4, 0x63, 0xcc, 0x6b, 0x81, 0x1a, 0x63, 0x39, 0x61, 0xc8, 0xa4, 0x23, 0x7d, 0x16, 0x8a, - 0xf8, 0x3b, 0xe3, 0xdc, 0xe6, 0x79, 0x61, 0xfa, 0x4c, 0xbd, 0x0d, 0x1c, 0x77, 0xc3, 0x0f, 0x81, - 0x6f, 0x59, 0x89, 0x09, 0x61, 0x05, 0x20, 0x1d, 0xab, 0xb3, 0x68, 0x79, 0x10, 0x02, 0x77, 0x24, - 0x34, 0x93, 0x51, 0x2f, 0x79, 0xbe, 0xdc, 0x68, 0xaf, 0x99, 0x2e, 0x0b, 0x2c, 0x87, 0x7b, 0x2c, - 0xe2, 0xec, 0xba, 0x7e, 0x98, 0x4f, 0xcd, 0x8a, 0x7c, 0x92, 0x0c, 0xb1, 0xb3, 0xe8, 0xb4, 0xa2, - 0x0d, 0xa7, 0x7b, 0x3a, 0x9a, 0x43, 0x58, 0x2e, 0xe3, 0xd0, 0xc3, 0x24, 0xfd, 0x65, 0x08, 0x1f, - 0x7e, 0x35, 0x99, 0xe9, 0x12, 0x07, 0x47, 0x82, 0x0d, 0x6f, 0xb6, 0x41, 0x48, 0x72, 0x14, 0x8f, - 0x85, 0x4e, 0x00, 0x22, 0x72, 0x5c, 0xa8, 0xa1, 0x19, 0x34, 0x3b, 0x66, 0xe7, 0x1d, 0x64, 0x1d, - 0x67, 0x52, 0xd4, 0x86, 0x66, 0xd0, 0xec, 0xf8, 0xd2, 0x15, 0x33, 0xa7, 0x37, 0x53, 0x7a, 0xfd, - 0xf0, 0x46, 0x46, 0x6f, 0x76, 0x96, 0xcd, 0x68, 0xd3, 0x33, 0xd5, 0x02, 0xcc, 0x4c, 0xda, 0x74, - 0x01, 0x66, 0x0a, 0x62, 0x67, 0x73, 0x13, 0x8a, 0xb1, 0x1f, 0x0a, 0xe9, 0x84, 0x2e, 0xbc, 0xb0, - 0x52, 0x1b, 0x56, 0x18, 0x17, 0x87, 0x6a, 0xc8, 0x2e, 0xf4, 0x12, 0x8a, 0x27, 0x04, 0xf0, 0x0e, - 0xf0, 0x15, 0xbe, 0x65, 0xb7, 0xc3, 0xda, 0x9e, 0x19, 0x34, 0x3b, 0x6a, 0x97, 0xfa, 0xc8, 0x6b, - 0x78, 0xd2, 0xd5, 0xcb, 0x7b, 0x39, 0xd2, 0x7e, 0xaa, 0xed, 0xd5, 0xd0, 0xcb, 0x66, 0xac, 0x91, - 0x59, 0x74, 0x54, 0x8e, 0xa8, 0x1c, 0x65, 0x76, 0x16, 0xcd, 0x4b, 0xc5, 0xa1, 0x76, 0x79, 0x26, - 0xfa, 0x2d, 0xc2, 0x24, 0x25, 0x5f, 0x05, 0x99, 0xea, 0x47, 0xf0, 0x1e, 0x25, 0x57, 0x22, 0x9d, - 0x7e, 0x2e, 0x6b, 0x3a, 0xb4, 0x5d, 0xd3, 0x6b, 0x18, 0x7b, 0x20, 0x53, 0xc0, 0x61, 0x0d, 0xb8, - 0x50, 0x0d, 0x70, 0x35, 0x1b, 0x67, 0x17, 0xe6, 0x20, 0x47, 0xf0, 0xc8, 0xba, 0x0f, 0xad, 0xa6, - 0xd0, 0x9a, 0x8c, 0xd9, 0x49, 0x8b, 0x7e, 0x8a, 0xf0, 0xff, 0x52, 0xe4, 0xba, 0x2f, 0x64, 0x35, - 0x9f, 0x37, 0xf0, 0x78, 0xcb, 0x17, 0x19, 0x60, 0xec, 0xf6, 0xc5, 0x6a, 0x80, 0xf5, 0x7c, 0xa0, - 0x5d, 0x9c, 0xa5, 0x80, 0x38, 0x5c, 0x42, 0x7c, 0x1f, 0xe1, 0xff, 0x67, 0xfb, 0x01, 0x44, 0x7b, - 0x2d, 0xf0, 0x77, 0x21, 0xad, 0x81, 0x47, 0x03, 0x08, 0x98, 0xff, 0x16, 0x34, 0xb5, 0x9d, 0x51, - 0x3b, 0x6b, 0x93, 0x69, 0x8c, 0x23, 0x87, 0x3b, 0x01, 0x48, 0xe0, 0x6a, 0x5f, 0x0c, 0xcf, 0x8e, - 0xd9, 0x85, 0x1e, 0xfa, 0x2b, 0xc2, 0x87, 0x72, 0x12, 0xc9, 0xb7, 0x76, 0x8e, 0x71, 0x16, 0x1f, - 0xe4, 0x20, 0xa4, 0xc3, 0x65, 0xa3, 0xed, 0xba, 0x20, 0xc4, 0x7a, 0xbb, 0x95, 0xf0, 0x74, 0xbf, - 0x50, 0x5f, 0x87, 0xac, 0x09, 0xcf, 0x2b, 0x41, 0x1a, 0xd0, 0x02, 0x57, 0x32, 0x9e, 0x38, 0xb2, - 0xfb, 0xc5, 0x7d, 0x97, 0x71, 0x23, 0x3f, 0xe8, 0x4a, 0xcf, 0x00, 0x76, 0xb5, 0x8c, 0x6e, 0xb0, - 0xe1, 0x7b, 0x80, 0xd1, 0x3a, 0xae, 0xa5, 0x86, 0x5f, 0x01, 0x1e, 0xf8, 0x61, 0x21, 0xc8, 0xfc, - 0x63, 0xdb, 0xf4, 0xa3, 0xc2, 0xd6, 0x6d, 0x48, 0x16, 0xfd, 0x4b, 0xab, 0x20, 0x35, 0xbc, 0x2f, - 0x00, 0x21, 0x1c, 0x0f, 0x12, 0x17, 0xa4, 0x4d, 0x7a, 0xbb, 0x70, 0xfe, 0x1b, 0xbb, 0x39, 0xff, - 0x03, 0x02, 0x22, 0x87, 0xf0, 0xde, 0x68, 0xc3, 0x11, 0xa0, 0x63, 0xdc, 0x98, 0x1d, 0x37, 0xc8, - 0x1c, 0x3e, 0xc0, 0xda, 0x32, 0x6a, 0xcb, 0x6b, 0xf9, 0x2e, 0x19, 0xd1, 0x1f, 0x74, 0xf5, 0xd3, - 0x2b, 0xf8, 0x48, 0xb6, 0xa2, 0xb6, 0x88, 0x20, 0x6c, 0xee, 0xdc, 0x61, 0x77, 0x0a, 0xf2, 0xd4, - 0x99, 0xb7, 0x73, 0x79, 0x6a, 0x78, 0x5f, 0xc4, 0x9a, 0x57, 0xd5, 0xa0, 0x58, 0x94, 0xb4, 0x49, - 0x9e, 0xc3, 0xb8, 0xc5, 0xbc, 0x34, 0x2e, 0xed, 0xd1, 0x71, 0xe9, 0x44, 0x21, 0x2e, 0x99, 0x2a, - 0xfb, 0xa9, 0x28, 0x74, 0x8d, 0x35, 0xeb, 0xd9, 0x87, 0x76, 0x61, 0x90, 0xc2, 0xf1, 0x38, 0x44, - 0x89, 0x64, 0xfa, 0x59, 0x05, 0x0d, 0x91, 0xba, 0x21, 0x56, 0x2a, 0x6b, 0xd3, 0x1f, 0x51, 0x7e, - 0x9c, 0x56, 0xa0, 0x05, 0xbb, 0xd8, 0xd2, 0x2a, 0x37, 0x35, 0xf5, 0x14, 0xe5, 0xd0, 0x5f, 0x31, - 0x37, 0xad, 0x14, 0x87, 0xda, 0xe5, 0x99, 0xd4, 0x56, 0x58, 0x67, 0xdc, 0x85, 0x24, 0x27, 0xc6, - 0x0d, 0x5a, 0xcb, 0xdd, 0x9b, 0xb2, 0x8b, 0x88, 0x85, 0x02, 0xe8, 0x67, 0x6a, 0x59, 0x8e, 0x74, - 0x37, 0xd2, 0xf7, 0xe2, 0x21, 0x4c, 0x0d, 0x1f, 0x16, 0x76, 0x94, 0x86, 0xbd, 0xdc, 0x81, 0x50, - 0x0b, 0x2f, 0xb7, 0xa2, 0x4c, 0x78, 0xf5, 0x4c, 0xd6, 0xf0, 0x08, 0x5b, 0xbb, 0x0e, 0xae, 0x7c, - 0x00, 0x45, 0x4a, 0x32, 0xb3, 0xca, 0x54, 0x24, 0xc7, 0xf8, 0x0f, 0x05, 0xa3, 0xcf, 0xe2, 0xd1, - 0x3a, 0xf3, 0x2e, 0x87, 0x92, 0x6f, 0xa9, 0xd3, 0xe2, 0xb2, 0x50, 0x42, 0x28, 0x13, 0xe3, 0x69, - 0xb3, 0x78, 0x8e, 0x86, 0x4a, 0xe7, 0x88, 0x7e, 0x52, 0x2a, 0x0b, 0x42, 0xf9, 0x50, 0x95, 0x82, - 0xf4, 0xaf, 0xc2, 0x91, 0x6b, 0x94, 0xea, 0x81, 0xfe, 0x7c, 0x14, 0x4f, 0x70, 0x10, 0xac, 0xcd, - 0x5d, 0x78, 0xd1, 0x0f, 0x9b, 0xc9, 0xa2, 0x4b, 0x7d, 0xc5, 0x6f, 0x0a, 0x01, 0xa6, 0xd4, 0x47, - 0x38, 0x9e, 0x8c, 0xcb, 0x90, 0x72, 0xa0, 0xa9, 0xef, 0x7e, 0xb1, 0x8d, 0x74, 0x5a, 0x61, 0x97, - 0x4d, 0x2c, 0xfd, 0x7e, 0x18, 0xef, 0xcf, 0x73, 0x0b, 0xef, 0xf8, 0x2e, 0x90, 0x2f, 0x10, 0x9e, - 0x8a, 0x0b, 0xd2, 0xf4, 0x0d, 0x39, 0x9e, 0x4f, 0xda, 0xb3, 0x98, 0x37, 0x06, 0xe8, 0x11, 0x3a, - 0xfb, 0xde, 0x9d, 0x3f, 0x3f, 0x1e, 0xa2, 0xf4, 0x98, 0xbe, 0x58, 0x74, 0x16, 0xad, 0xfc, 0x72, - 0x72, 0x33, 0x53, 0xfd, 0xd6, 0xd3, 0x68, 0x8e, 0x7c, 0x8e, 0xf0, 0xf8, 0x2a, 0xc8, 0x0c, 0xf3, - 0x68, 0x37, 0x66, 0x5e, 0x30, 0x0f, 0x94, 0xf1, 0xac, 0x66, 0x7c, 0x8c, 0x3c, 0xda, 0x97, 0x31, - 0x7e, 0xbe, 0xa5, 0x38, 0x27, 0xd5, 0xa1, 0xca, 0x82, 0x1e, 0x39, 0xd6, 0x4d, 0x5a, 0xa8, 0x93, - 0x8d, 0xab, 0x83, 0x43, 0x55, 0xd3, 0xd2, 0x53, 0x1a, 0xf7, 0x38, 0xe9, 0x2f, 0x29, 0x79, 0x07, - 0x4f, 0x95, 0x83, 0x73, 0xc9, 0xf1, 0xbd, 0xc2, 0xb6, 0xd1, 0x43, 0xf2, 0x3c, 0x56, 0xd1, 0x33, - 0xda, 0xee, 0x29, 0x72, 0x72, 0xbb, 0xdd, 0x79, 0xd0, 0xb1, 0xac, 0x68, 0x7d, 0x01, 0x11, 0x81, - 0xc7, 0x0b, 0x81, 0xae, 0xe4, 0xce, 0xae, 0xf8, 0x67, 0x3c, 0xd2, 0x2b, 0x01, 0xc7, 0x66, 0x4f, - 0x6b, 0xb3, 0x27, 0xc9, 0x89, 0xd4, 0xac, 0x90, 0x1c, 0x9c, 0xc0, 0xea, 0x69, 0xf4, 0x5d, 0x84, - 0xa7, 0xe2, 0x2c, 0xd5, 0x6f, 0xbb, 0x97, 0x72, 0xb0, 0x31, 0x73, 0xef, 0x0f, 0x92, 0x44, 0x97, - 0x6c, 0x90, 0xb9, 0x6a, 0x1b, 0xe4, 0x3b, 0x84, 0x27, 0x75, 0xe9, 0x9f, 0x21, 0x4c, 0x77, 0x5b, - 0x28, 0xde, 0x0d, 0x06, 0xba, 0x99, 0x9f, 0xd0, 0xac, 0x96, 0x31, 0x57, 0x85, 0xd5, 0xe2, 0x0a, - 0x43, 0x9d, 0xbe, 0x9f, 0x10, 0x3e, 0x90, 0xde, 0x9c, 0x32, 0xee, 0x13, 0xbd, 0xb8, 0x4b, 0xb7, - 0xab, 0x81, 0xa2, 0x9f, 0xd7, 0xe8, 0x4b, 0xc6, 0x7c, 0x45, 0xf4, 0x98, 0x44, 0xd1, 0x7f, 0x8f, - 0xf0, 0x54, 0x7c, 0x4f, 0xe9, 0xe7, 0xf6, 0xd2, 0x4d, 0x66, 0xa0, 0xe4, 0x4f, 0x6a, 0xf2, 0x05, - 0xe3, 0x4c, 0x65, 0xf2, 0x00, 0x14, 0xf7, 0x0f, 0x08, 0xef, 0x4f, 0x6a, 0xe6, 0x0c, 0xbc, 0xc7, - 0x76, 0x2c, 0x97, 0xd5, 0x03, 0x25, 0x7f, 0x4a, 0x93, 0x2f, 0x1a, 0x67, 0x2b, 0x91, 0x8b, 0x18, - 0x44, 0xa1, 0xff, 0x8c, 0xf0, 0xc1, 0xec, 0x86, 0x96, 0xc1, 0xd3, 0x6e, 0xf8, 0xed, 0xd7, 0xb8, - 0x81, 0xe2, 0x5f, 0xd0, 0xf8, 0xcb, 0x86, 0x59, 0x09, 0x5f, 0xa6, 0x28, 0x6a, 0x01, 0xdf, 0x20, - 0x3c, 0xa1, 0xee, 0x84, 0x19, 0x7b, 0x8f, 0x30, 0x5e, 0xb8, 0x33, 0x0e, 0x14, 0xfb, 0x9c, 0xc6, - 0x36, 0x8d, 0xd3, 0xd5, 0x54, 0x97, 0x2c, 0x52, 0xc4, 0x5f, 0x21, 0x3c, 0xde, 0xe8, 0x9f, 0x21, - 0x1b, 0x0f, 0x26, 0x43, 0x2e, 0x6b, 0xde, 0x79, 0x63, 0xb6, 0x1a, 0x2f, 0xe8, 0x43, 0xf9, 0x25, - 0xc2, 0x13, 0xaa, 0x30, 0xec, 0x27, 0x70, 0xa1, 0x70, 0x1c, 0x28, 0xf0, 0xbc, 0x06, 0x7e, 0x9c, - 0xd2, 0xfe, 0xc0, 0x2d, 0x3f, 0xd4, 0xa8, 0x6f, 0xe3, 0x7d, 0xf1, 0x6d, 0x4f, 0xf4, 0x12, 0x35, - 0xbf, 0x88, 0x1a, 0x24, 0x7f, 0x9b, 0x16, 0xcf, 0xf4, 0x19, 0x6d, 0xeb, 0x1c, 0x59, 0xaa, 0x24, - 0xce, 0xcd, 0xa4, 0x7e, 0xbe, 0x65, 0xb5, 0x98, 0xf7, 0xc1, 0x10, 0x5a, 0x40, 0x44, 0xe2, 0x89, - 0x82, 0xa9, 0x9d, 0x20, 0x2c, 0x68, 0x84, 0x39, 0x52, 0xcd, 0x3f, 0x2d, 0xe6, 0x2d, 0x20, 0xf2, - 0x35, 0xc2, 0x53, 0x8d, 0x72, 0xbc, 0x3f, 0xde, 0x2b, 0xf4, 0x3c, 0xa8, 0x68, 0x6f, 0x69, 0xe6, - 0xd3, 0xf4, 0x3e, 0x49, 0x35, 0x0b, 0xf2, 0x17, 0x57, 0x7f, 0xbb, 0x3b, 0x8d, 0x6e, 0xdf, 0x9d, - 0x46, 0x7f, 0xdc, 0x9d, 0x46, 0xaf, 0x5f, 0xa8, 0xfe, 0xfb, 0x7b, 0xdb, 0x6f, 0xfa, 0xb5, 0x11, - 0xfd, 0x37, 0x7b, 0xf9, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6d, 0x5c, 0x66, 0x41, 0xc7, 0x17, - 0x00, 0x00, + // 1451 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x98, 0xcf, 0x6f, 0x1c, 0x35, + 0x14, 0xc7, 0xe5, 0x4d, 0x9b, 0x26, 0xce, 0x8f, 0xb6, 0xa6, 0x2d, 0xcb, 0xa8, 0x4d, 0x53, 0x97, + 0x42, 0x9a, 0x36, 0x33, 0xf9, 0x51, 0xa0, 0x45, 0x02, 0x89, 0x36, 0x6d, 0x44, 0x59, 0x4a, 0x35, + 0x8b, 0x84, 0xe0, 0x82, 0x26, 0xb3, 0xce, 0x64, 0x9a, 0x99, 0xf1, 0x60, 0x7b, 0xb7, 0x0a, 0xa5, + 0x48, 0x70, 0x81, 0x03, 0x12, 0x07, 0x8e, 0xdc, 0x90, 0x10, 0x1c, 0x10, 0x20, 0x24, 0x24, 0x04, + 0x12, 0xea, 0x81, 0x03, 0xc7, 0x4a, 0xbd, 0x72, 0x40, 0x15, 0xff, 0x00, 0xff, 0x01, 0xb2, 0xe7, + 0x97, 0x27, 0xbb, 0xdd, 0x0e, 0xc9, 0x06, 0x7a, 0x1b, 0x7b, 0xc6, 0x7e, 0x1f, 0x7f, 0x9f, 0xfd, + 0xde, 0xf3, 0xc0, 0x53, 0xf1, 0x86, 0x67, 0x39, 0xb1, 0xef, 0x06, 0x3e, 0x89, 0x84, 0x75, 0x93, + 0xb2, 0x8d, 0xb5, 0x80, 0xde, 0xcc, 0x1f, 0xcc, 0x98, 0x51, 0x41, 0xd1, 0x48, 0xd6, 0x36, 0x8e, + 0x7a, 0x94, 0x7a, 0x01, 0x91, 0x63, 0x2c, 0x27, 0x8a, 0xa8, 0x70, 0x84, 0x4f, 0x23, 0x9e, 0x7c, + 0x67, 0x9c, 0xdb, 0x38, 0xcf, 0x4d, 0x9f, 0xca, 0xb7, 0xa1, 0xe3, 0xae, 0xfb, 0x11, 0x61, 0x9b, + 0x56, 0x6a, 0x82, 0x5b, 0x21, 0x11, 0x8e, 0xd5, 0x59, 0xb0, 0x3c, 0x12, 0x11, 0xe6, 0x08, 0xd2, + 0x4a, 0x47, 0xbd, 0xea, 0xf9, 0x62, 0xbd, 0xbd, 0x6a, 0xba, 0x34, 0xb4, 0x1c, 0xe6, 0xd1, 0x98, + 0xd1, 0x1b, 0xea, 0x61, 0x2e, 0x33, 0xcb, 0x8b, 0x49, 0x72, 0xc4, 0xce, 0x82, 0x13, 0xc4, 0xeb, + 0x4e, 0xf7, 0x74, 0xb8, 0x80, 0xb0, 0x5c, 0xca, 0x48, 0x0f, 0x93, 0xf8, 0x4e, 0x0d, 0x1e, 0x7e, + 0x23, 0x9d, 0xe9, 0x12, 0x23, 0x8e, 0x20, 0x36, 0x79, 0xa7, 0x4d, 0xb8, 0x40, 0x47, 0xe1, 0x68, + 0xe4, 0x84, 0x84, 0xc7, 0x8e, 0x4b, 0xea, 0x60, 0x1a, 0xcc, 0x8c, 0xda, 0x45, 0x07, 0x5a, 0x83, + 0xb9, 0x14, 0xf5, 0xda, 0x34, 0x98, 0x19, 0x5b, 0xbc, 0x6a, 0x16, 0xf4, 0x66, 0x46, 0xaf, 0x1e, + 0xde, 0xce, 0xe9, 0xcd, 0xce, 0x92, 0x19, 0x6f, 0x78, 0xa6, 0x5c, 0x80, 0x99, 0x4b, 0x9b, 0x2d, + 0xc0, 0xcc, 0x40, 0xec, 0x7c, 0x6e, 0x84, 0x21, 0xf4, 0x23, 0x2e, 0x9c, 0xc8, 0x25, 0x2f, 0x2f, + 0xd7, 0x87, 0x24, 0xc6, 0xc5, 0x5a, 0x1d, 0xd8, 0x5a, 0x2f, 0xc2, 0x70, 0x9c, 0x13, 0xd6, 0x21, + 0x6c, 0x99, 0x6d, 0xda, 0xed, 0xa8, 0xbe, 0x67, 0x1a, 0xcc, 0x8c, 0xd8, 0xa5, 0x3e, 0xf4, 0x26, + 0x9c, 0x70, 0xd5, 0xf2, 0x5e, 0x8b, 0x95, 0x9f, 0xea, 0x7b, 0x15, 0xf4, 0x92, 0x99, 0x68, 0x64, + 0xea, 0x8e, 0x2a, 0x10, 0xa5, 0xa3, 0xcc, 0xce, 0x82, 0x79, 0x49, 0x1f, 0x6a, 0x97, 0x67, 0xc2, + 0xdf, 0x03, 0x88, 0x32, 0xf2, 0x15, 0x22, 0x32, 0xfd, 0x10, 0xdc, 0x23, 0xe5, 0x4a, 0xa5, 0x53, + 0xcf, 0x65, 0x4d, 0x6b, 0x5b, 0x35, 0xbd, 0x0e, 0xa1, 0x47, 0x44, 0x06, 0x38, 0xa4, 0x00, 0xe7, + 0xab, 0x01, 0xae, 0xe4, 0xe3, 0x6c, 0x6d, 0x0e, 0x74, 0x04, 0x0e, 0xaf, 0xf9, 0x24, 0x68, 0x71, + 0xa5, 0xc9, 0xa8, 0x9d, 0xb6, 0xf0, 0x1d, 0x00, 0x1f, 0xcb, 0x90, 0x1b, 0x3e, 0x17, 0xd5, 0x7c, + 0xde, 0x84, 0x63, 0x81, 0xcf, 0x73, 0xc0, 0xc4, 0xed, 0x0b, 0xd5, 0x00, 0x1b, 0xc5, 0x40, 0x5b, + 0x9f, 0x45, 0x43, 0x1c, 0xd2, 0x11, 0xd1, 0x14, 0x84, 0xd2, 0xf2, 0x15, 0x3f, 0x10, 0x84, 0xa5, + 0xf8, 0x5a, 0x0f, 0xfe, 0x08, 0xc0, 0xc7, 0xf3, 0xfd, 0x42, 0x78, 0x7b, 0x35, 0xf4, 0x77, 0x20, + 0xbd, 0x01, 0x47, 0x42, 0x12, 0x52, 0xff, 0x5d, 0xd2, 0x52, 0x1c, 0x23, 0x76, 0xde, 0x96, 0x24, + 0xb1, 0xc3, 0x9c, 0x90, 0x08, 0xc2, 0xe4, 0xbe, 0x19, 0x92, 0x24, 0x45, 0x0f, 0xfe, 0x0d, 0xc0, + 0x43, 0x05, 0x89, 0x60, 0x9b, 0xdb, 0xc7, 0x38, 0x0b, 0x0f, 0x32, 0xc2, 0x85, 0xc3, 0x44, 0xb3, + 0xed, 0xba, 0x84, 0xf3, 0xb5, 0x76, 0x90, 0xf2, 0x74, 0xbf, 0x90, 0x5f, 0x47, 0xb4, 0x45, 0xae, + 0x48, 0xc1, 0x9a, 0x24, 0x20, 0xae, 0xa0, 0x99, 0x52, 0xdd, 0x2f, 0x1e, 0xba, 0x8c, 0x9b, 0x45, + 0x20, 0x90, 0x7a, 0x86, 0x64, 0x47, 0xcb, 0xe8, 0x06, 0x1b, 0x7a, 0x00, 0x18, 0x6e, 0xc0, 0x7a, + 0x66, 0xf8, 0x75, 0xc2, 0x42, 0x3f, 0xd2, 0x82, 0xd0, 0xbf, 0xb6, 0x8d, 0x3f, 0xd5, 0xb6, 0x76, + 0x53, 0xd0, 0xf8, 0x3f, 0x5a, 0x05, 0xaa, 0xc3, 0x7d, 0x21, 0xe1, 0xdc, 0xf1, 0x48, 0xea, 0x82, + 0xac, 0x89, 0xef, 0x6a, 0xf1, 0xa1, 0xb9, 0x93, 0xf8, 0x30, 0x20, 0x20, 0x74, 0x08, 0xee, 0x8d, + 0xd7, 0x1d, 0x4e, 0x54, 0x0c, 0x1c, 0xb5, 0x93, 0x06, 0x9a, 0x85, 0x07, 0x68, 0x5b, 0xc4, 0x6d, + 0x71, 0xbd, 0xd8, 0x25, 0xc3, 0xea, 0x83, 0xae, 0x7e, 0x7c, 0x15, 0x1e, 0xc9, 0x57, 0xd4, 0xe6, + 0x31, 0x89, 0x5a, 0xdb, 0x77, 0xd8, 0x3d, 0x4d, 0x9e, 0x06, 0xf5, 0xb6, 0x2f, 0x4f, 0x1d, 0xee, + 0x8b, 0x69, 0xeb, 0x9a, 0x1c, 0x94, 0x88, 0x92, 0x35, 0xd1, 0x4b, 0x10, 0x06, 0xd4, 0xcb, 0xe2, + 0xd6, 0x1e, 0x15, 0xb7, 0x4e, 0x68, 0x71, 0xcb, 0x94, 0xd9, 0x51, 0x46, 0xa9, 0xeb, 0xb4, 0xd5, + 0xc8, 0x3f, 0xb4, 0xb5, 0x41, 0x12, 0xc7, 0x63, 0x24, 0x4e, 0x25, 0x53, 0xcf, 0x32, 0x68, 0xf0, + 0xcc, 0x0d, 0x89, 0x52, 0x79, 0x1b, 0xff, 0x0c, 0x8a, 0xe3, 0xb4, 0x4c, 0x02, 0xb2, 0x83, 0x2d, + 0x2d, 0x73, 0x57, 0x4b, 0x4d, 0x51, 0x4e, 0x0d, 0x15, 0x73, 0xd7, 0xb2, 0x3e, 0xd4, 0x2e, 0xcf, + 0x24, 0xb7, 0xc2, 0x1a, 0x65, 0x2e, 0x49, 0x73, 0x66, 0xd2, 0xc0, 0xf5, 0xc2, 0xbd, 0x19, 0x3b, + 0x8f, 0x69, 0xc4, 0x09, 0xfe, 0x42, 0x2e, 0xcb, 0x11, 0xee, 0x7a, 0xf6, 0x9e, 0x3f, 0x7a, 0xa9, + 0x03, 0x7f, 0xa2, 0xed, 0x28, 0x05, 0x7b, 0xb9, 0x43, 0x22, 0x25, 0xbc, 0xd8, 0x8c, 0x73, 0xe1, + 0xe5, 0x33, 0x5a, 0x85, 0xc3, 0x74, 0xf5, 0x06, 0x71, 0xc5, 0x2e, 0x14, 0x31, 0xe9, 0xcc, 0x32, + 0x53, 0xa1, 0x02, 0xe3, 0x7f, 0x14, 0x0c, 0xbf, 0x08, 0x47, 0x1a, 0xd4, 0xbb, 0x1c, 0x09, 0xb6, + 0x29, 0x4f, 0x8b, 0x4b, 0x23, 0x41, 0x22, 0x91, 0x1a, 0xcf, 0x9a, 0xfa, 0x39, 0xaa, 0x95, 0xce, + 0x11, 0xfe, 0xbc, 0x54, 0x36, 0x44, 0xe2, 0x91, 0x2a, 0x15, 0xf1, 0xdf, 0xda, 0x91, 0x6b, 0x96, + 0xea, 0x81, 0xfe, 0x7c, 0x18, 0x8e, 0x33, 0xc2, 0x69, 0x9b, 0xb9, 0xe4, 0x15, 0x3f, 0x6a, 0xa5, + 0x8b, 0x2e, 0xf5, 0xe9, 0xdf, 0x68, 0x01, 0xa6, 0xd4, 0x87, 0x18, 0x9c, 0x48, 0xca, 0x90, 0x72, + 0xa0, 0x69, 0xec, 0x7c, 0xb1, 0xcd, 0x6c, 0x5a, 0x6e, 0x97, 0x4d, 0x2c, 0xfe, 0x71, 0x18, 0xee, + 0x2f, 0x72, 0x0b, 0xeb, 0xf8, 0x2e, 0x41, 0x5f, 0x01, 0x38, 0x99, 0x14, 0xac, 0xd9, 0x1b, 0x74, + 0xbc, 0x98, 0xb4, 0x67, 0xb1, 0x6f, 0x0c, 0xd0, 0x23, 0x78, 0xe6, 0xc3, 0x7b, 0x7f, 0x7d, 0x56, + 0xc3, 0xf8, 0x98, 0xba, 0x78, 0x74, 0x16, 0xac, 0xe2, 0xf2, 0x72, 0x2b, 0x57, 0xfd, 0xf6, 0xf3, + 0x60, 0x16, 0x7d, 0x09, 0xe0, 0xd8, 0x0a, 0x11, 0x39, 0xe6, 0xd1, 0x6e, 0xcc, 0xa2, 0xa0, 0x1e, + 0x28, 0xe3, 0x59, 0xc5, 0xf8, 0x14, 0x7a, 0xb2, 0x2f, 0x63, 0xf2, 0x7c, 0x5b, 0x72, 0x4e, 0xc8, + 0x43, 0x95, 0x07, 0x3d, 0x74, 0xac, 0x9b, 0x54, 0xab, 0xa3, 0x8d, 0x6b, 0x83, 0x43, 0x95, 0xd3, + 0xe2, 0x53, 0x0a, 0xf7, 0x38, 0xea, 0x2f, 0x29, 0x7a, 0x1f, 0x4e, 0x96, 0x83, 0x73, 0xc9, 0xf1, + 0xbd, 0xc2, 0xb6, 0xd1, 0x43, 0xf2, 0x22, 0x56, 0xe1, 0x33, 0xca, 0xee, 0x29, 0x74, 0x72, 0xab, + 0xdd, 0x39, 0xa2, 0x62, 0x99, 0x6e, 0x7d, 0x1e, 0x20, 0x0e, 0xc7, 0xb4, 0x40, 0x57, 0x72, 0x67, + 0x57, 0xfc, 0x33, 0x9e, 0xe8, 0x95, 0x80, 0x13, 0xb3, 0xa7, 0x95, 0xd9, 0x93, 0xe8, 0x44, 0x66, + 0x96, 0x0b, 0x46, 0x9c, 0xd0, 0xea, 0x69, 0xf4, 0x03, 0x00, 0x27, 0x93, 0x2c, 0xd5, 0x6f, 0xbb, + 0x97, 0x72, 0xb0, 0x31, 0xfd, 0xe0, 0x0f, 0xd2, 0x44, 0x97, 0x6e, 0x90, 0xd9, 0x6a, 0x1b, 0xe4, + 0x07, 0x00, 0x27, 0x54, 0xe9, 0x9f, 0x23, 0x4c, 0x75, 0x5b, 0xd0, 0xef, 0x06, 0x03, 0xdd, 0xcc, + 0xcf, 0x28, 0x56, 0xcb, 0x98, 0xad, 0xc2, 0x6a, 0x31, 0x89, 0x21, 0x4f, 0xdf, 0x2f, 0x00, 0x1e, + 0xc8, 0x6e, 0x4e, 0x39, 0xf7, 0x89, 0x5e, 0xdc, 0xa5, 0xdb, 0xd5, 0x40, 0xd1, 0xcf, 0x2b, 0xf4, + 0x45, 0x63, 0xae, 0x22, 0x7a, 0x42, 0x22, 0xe9, 0x7f, 0x04, 0x70, 0x32, 0xb9, 0xa7, 0xf4, 0x73, + 0x7b, 0xe9, 0x26, 0x33, 0x50, 0xf2, 0x67, 0x15, 0xf9, 0xbc, 0x71, 0xa6, 0x32, 0x79, 0x48, 0x24, + 0xf7, 0x4f, 0x00, 0xee, 0x4f, 0x6b, 0xe6, 0x1c, 0xbc, 0xc7, 0x76, 0x2c, 0x97, 0xd5, 0x03, 0x25, + 0x7f, 0x4e, 0x91, 0x2f, 0x18, 0x67, 0x2b, 0x91, 0xf3, 0x04, 0x44, 0xa2, 0xff, 0x0a, 0xe0, 0xc1, + 0xfc, 0x86, 0x96, 0xc3, 0xe3, 0x6e, 0xf8, 0xad, 0xd7, 0xb8, 0x81, 0xe2, 0x5f, 0x50, 0xf8, 0x4b, + 0x86, 0x59, 0x09, 0x5f, 0x64, 0x28, 0x72, 0x01, 0xdf, 0x01, 0x38, 0x2e, 0xef, 0x84, 0x39, 0x7b, + 0x8f, 0x30, 0xae, 0xdd, 0x19, 0x07, 0x8a, 0x7d, 0x4e, 0x61, 0x9b, 0xc6, 0xe9, 0x6a, 0xaa, 0x0b, + 0x1a, 0x4b, 0xe2, 0x6f, 0x00, 0x1c, 0x6b, 0xf6, 0xcf, 0x90, 0xcd, 0xdd, 0xc9, 0x90, 0x4b, 0x8a, + 0x77, 0xce, 0x98, 0xa9, 0xc6, 0x4b, 0xd4, 0xa1, 0xfc, 0x1a, 0xc0, 0x71, 0x59, 0x18, 0xf6, 0x13, + 0x58, 0x2b, 0x1c, 0x07, 0x0a, 0x3c, 0xa7, 0x80, 0x9f, 0xc6, 0xb8, 0x3f, 0x70, 0xe0, 0x47, 0x0a, + 0xf5, 0x3d, 0xb8, 0x2f, 0xb9, 0xed, 0xf1, 0x5e, 0xa2, 0x16, 0x17, 0x51, 0x03, 0x15, 0x6f, 0xb3, + 0xe2, 0x19, 0xbf, 0xa0, 0x6c, 0x9d, 0x43, 0x8b, 0x95, 0xc4, 0xb9, 0x95, 0xd6, 0xcf, 0xb7, 0xad, + 0x80, 0x7a, 0x1f, 0xd7, 0xc0, 0x3c, 0x40, 0x02, 0x8e, 0x6b, 0xa6, 0xb6, 0x83, 0x30, 0xaf, 0x10, + 0x66, 0x51, 0x35, 0xff, 0x04, 0xd4, 0x9b, 0x07, 0xe8, 0x5b, 0x00, 0x27, 0x9b, 0xe5, 0x78, 0x7f, + 0xbc, 0x57, 0xe8, 0xd9, 0xad, 0x68, 0x6f, 0x29, 0xe6, 0xd3, 0xf8, 0x21, 0x49, 0x35, 0x0f, 0xf2, + 0x17, 0x57, 0x7e, 0xbf, 0x3f, 0x05, 0xee, 0xde, 0x9f, 0x02, 0x7f, 0xde, 0x9f, 0x02, 0x6f, 0x5d, + 0xa8, 0xfe, 0x7b, 0x7c, 0xcb, 0x6f, 0xfc, 0xd5, 0x61, 0xf5, 0xb7, 0x7b, 0xe9, 0x9f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x07, 0xe3, 0x32, 0x3c, 0xe7, 0x17, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2333,6 +2342,13 @@ func (m *WorkflowListRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.NameFilter) > 0 { + i -= len(m.NameFilter) + copy(dAtA[i:], m.NameFilter) + i = encodeVarintWorkflow(dAtA, i, uint64(len(m.NameFilter))) + i-- + dAtA[i] = 0x22 + } if len(m.Fields) > 0 { i -= len(m.Fields) copy(dAtA[i:], m.Fields) @@ -3287,6 +3303,10 @@ func (m *WorkflowListRequest) Size() (n int) { if l > 0 { n += 1 + l + sovWorkflow(uint64(l)) } + l = len(m.NameFilter) + if l > 0 { + n += 1 + l + sovWorkflow(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -4215,6 +4235,38 @@ func (m *WorkflowListRequest) Unmarshal(dAtA []byte) error { } m.Fields = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NameFilter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorkflow + } + 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 ErrInvalidLengthWorkflow + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWorkflow + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NameFilter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipWorkflow(dAtA[iNdEx:]) diff --git a/pkg/apiclient/workflow/workflow.proto b/pkg/apiclient/workflow/workflow.proto index edfeaf171280b..17b234c06bfda 100644 --- a/pkg/apiclient/workflow/workflow.proto +++ b/pkg/apiclient/workflow/workflow.proto @@ -33,6 +33,8 @@ message WorkflowListRequest { k8s.io.apimachinery.pkg.apis.meta.v1.ListOptions listOptions = 2; // Fields to be included or excluded in the response. e.g. "items.spec,items.status.phase", "-items.status.nodes" string fields = 3; + // Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact + string nameFilter = 4; } message WorkflowResubmitRequest { diff --git a/pkg/apis/workflow/v1alpha1/cron_workflow_types.go b/pkg/apis/workflow/v1alpha1/cron_workflow_types.go index d6c2d69aaf29b..65cb6884eb184 100644 --- a/pkg/apis/workflow/v1alpha1/cron_workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/cron_workflow_types.go @@ -1,6 +1,7 @@ package v1alpha1 import ( + "context" "strings" v1 "k8s.io/api/core/v1" @@ -8,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" + "github.com/argoproj/argo-workflows/v3/util/deprecation" ) // CronWorkflow is the definition of a scheduled workflow resource @@ -69,11 +71,11 @@ type CronWorkflowSpec struct { When string `json:"when,omitempty" protobuf:"bytes,12,opt,name=when"` } -// v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +// StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after type StopStrategy struct { - // v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the - // variables `failed` or `succeeded` to access the number of failed or successful child workflows. - Condition string `json:"condition" protobuf:"bytes,1,opt,name=condition"` + // v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables + // `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. + Expression string `json:"expression" protobuf:"bytes,1,opt,name=expression"` } // CronWorkflowStatus is the status of a CronWorkflow @@ -169,17 +171,17 @@ func (c *CronWorkflowSpec) getScheduleString(withTimezone bool) string { // GetSchedulesWithTimezone returns all schedules configured for the CronWorkflow with a timezone. It handles // both Spec.Schedules and Spec.Schedule for backwards compatibility -func (c *CronWorkflowSpec) GetSchedulesWithTimezone() []string { - return c.getSchedules(true) +func (c *CronWorkflowSpec) GetSchedulesWithTimezone(ctx context.Context) []string { + return c.getSchedules(ctx, true) } // GetSchedules returns all schedules configured for the CronWorkflow. It handles both Spec.Schedules // and Spec.Schedule for backwards compatibility -func (c *CronWorkflowSpec) GetSchedules() []string { - return c.getSchedules(false) +func (c *CronWorkflowSpec) GetSchedules(ctx context.Context) []string { + return c.getSchedules(ctx, false) } -func (c *CronWorkflowSpec) getSchedules(withTimezone bool) []string { +func (c *CronWorkflowSpec) getSchedules(ctx context.Context, withTimezone bool) []string { var schedules []string if c.Schedule != "" { schedule := c.Schedule @@ -187,6 +189,7 @@ func (c *CronWorkflowSpec) getSchedules(withTimezone bool) []string { schedule = c.withTimezone(c.Schedule) } schedules = append(schedules, schedule) + deprecation.Record(ctx, deprecation.Schedule) } else { schedules = make([]string, len(c.Schedules)) for i, schedule := range c.Schedules { diff --git a/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go b/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go index 1822eec4f9411..021b60f6e9dee 100644 --- a/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go +++ b/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go @@ -1,6 +1,7 @@ package v1alpha1 import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -21,14 +22,14 @@ func TestCronWorkflowSpec_GetScheduleStrings(t *testing.T) { Timezone: "", Schedule: "* * * * *", } - - assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules()) - assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedulesWithTimezone()) + ctx := context.Background() + assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules(ctx)) + assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedulesWithTimezone(ctx)) assert.Equal(t, "* * * * *", cwfSpec.GetScheduleString()) cwfSpec.Timezone = "America/Los_Angeles" - assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules()) - assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *"}, cwfSpec.GetSchedulesWithTimezone()) + assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules(ctx)) + assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *"}, cwfSpec.GetSchedulesWithTimezone(ctx)) assert.Equal(t, "* * * * *", cwfSpec.GetScheduleString()) assert.Equal(t, "CRON_TZ=America/Los_Angeles * * * * *", cwfSpec.GetScheduleWithTimezoneString()) @@ -39,8 +40,8 @@ func TestCronWorkflowSpec_GetScheduleStrings(t *testing.T) { assert.Equal(t, "* * * * *,0 * * * *", cwfSpec.GetScheduleString()) cwfSpec.Timezone = "America/Los_Angeles" - assert.Equal(t, []string{"* * * * *", "0 * * * *"}, cwfSpec.GetSchedules()) - assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *", "CRON_TZ=America/Los_Angeles 0 * * * *"}, cwfSpec.GetSchedulesWithTimezone()) + assert.Equal(t, []string{"* * * * *", "0 * * * *"}, cwfSpec.GetSchedules(ctx)) + assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *", "CRON_TZ=America/Los_Angeles 0 * * * *"}, cwfSpec.GetSchedulesWithTimezone(ctx)) assert.Equal(t, "* * * * *,0 * * * *", cwfSpec.GetScheduleString()) assert.Equal(t, "CRON_TZ=America/Los_Angeles * * * * *,CRON_TZ=America/Los_Angeles 0 * * * *", cwfSpec.GetScheduleWithTimezoneString()) } diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index a75856f9a30a3..673ebb999d7df 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -4448,704 +4448,704 @@ func init() { } var fileDescriptor_724696e352c3df5f = []byte{ - // 11152 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0xbd, 0x7b, 0x70, 0x24, 0xc7, - 0x79, 0x18, 0xce, 0x59, 0x60, 0xf1, 0xf8, 0x16, 0xc0, 0xe1, 0xfa, 0x5e, 0x4b, 0x1c, 0x79, 0xa0, - 0x87, 0x22, 0x7f, 0xa4, 0x4d, 0xe1, 0xcc, 0xa3, 0xf4, 0x0b, 0x23, 0x25, 0x92, 0xf0, 0x38, 0xe0, - 0x8e, 0x00, 0x0e, 0x60, 0x2f, 0xee, 0xce, 0xa4, 0x68, 0x49, 0x83, 0xdd, 0xc6, 0xee, 0x10, 0xbb, - 0x33, 0xcb, 0x99, 0x59, 0xdc, 0x81, 0x0f, 0x49, 0xa1, 0xde, 0xb1, 0x6c, 0xc5, 0xb2, 0x24, 0x4b, - 0x4a, 0x52, 0xa5, 0x28, 0x52, 0xc2, 0x92, 0x5d, 0x49, 0xd9, 0x7f, 0xa5, 0xec, 0xff, 0x52, 0x29, - 0x97, 0x52, 0x4e, 0x25, 0x72, 0x45, 0x29, 0xe9, 0x0f, 0x1b, 0x8c, 0x2e, 0x89, 0x2a, 0x95, 0x44, - 0x55, 0xb1, 0x2a, 0x4e, 0xe2, 0xcb, 0xa3, 0x52, 0xfd, 0x9c, 0xee, 0xd9, 0x59, 0xdc, 0xe2, 0xae, - 0x81, 0x53, 0xd9, 0x7f, 0x01, 0xfb, 0x75, 0xf7, 0xf7, 0x75, 0xf7, 0x74, 0x7f, 0xfd, 0xbd, 0xfa, - 0x6b, 0x58, 0xaf, 0xfb, 0x49, 0xa3, 0xb3, 0x39, 0x53, 0x0d, 0x5b, 0xe7, 0xbd, 0xa8, 0x1e, 0xb6, - 0xa3, 0xf0, 0x65, 0xf6, 0xcf, 0x3b, 0x6f, 0x84, 0xd1, 0xf6, 0x56, 0x33, 0xbc, 0x11, 0x9f, 0xdf, - 0x79, 0xe6, 0x7c, 0x7b, 0xbb, 0x7e, 0xde, 0x6b, 0xfb, 0xf1, 0x79, 0x09, 0x3d, 0xbf, 0xf3, 0xb4, - 0xd7, 0x6c, 0x37, 0xbc, 0xa7, 0xcf, 0xd7, 0x49, 0x40, 0x22, 0x2f, 0x21, 0xb5, 0x99, 0x76, 0x14, - 0x26, 0x21, 0xfa, 0x40, 0x8a, 0x71, 0x46, 0x62, 0x64, 0xff, 0x7c, 0x58, 0x61, 0x9c, 0xd9, 0x79, - 0x66, 0xa6, 0xbd, 0x5d, 0x9f, 0xa1, 0x18, 0x67, 0x24, 0x74, 0x46, 0x62, 0x9c, 0x7a, 0xa7, 0xd6, - 0xa7, 0x7a, 0x58, 0x0f, 0xcf, 0x33, 0xc4, 0x9b, 0x9d, 0x2d, 0xf6, 0x8b, 0xfd, 0x60, 0xff, 0x71, - 0x82, 0x53, 0xee, 0xf6, 0xb3, 0xf1, 0x8c, 0x1f, 0xd2, 0xfe, 0x9d, 0xaf, 0x86, 0x11, 0x39, 0xbf, - 0xd3, 0xd5, 0xa9, 0xa9, 0x77, 0x68, 0x75, 0xda, 0x61, 0xd3, 0xaf, 0xee, 0xe6, 0xd5, 0x7a, 0x57, - 0x5a, 0xab, 0xe5, 0x55, 0x1b, 0x7e, 0x40, 0xa2, 0xdd, 0x74, 0xe8, 0x2d, 0x92, 0x78, 0x79, 0xad, - 0xce, 0xf7, 0x6a, 0x15, 0x75, 0x82, 0xc4, 0x6f, 0x91, 0xae, 0x06, 0xff, 0xff, 0x9d, 0x1a, 0xc4, - 0xd5, 0x06, 0x69, 0x79, 0x5d, 0xed, 0x9e, 0xe9, 0xd5, 0xae, 0x93, 0xf8, 0xcd, 0xf3, 0x7e, 0x90, - 0xc4, 0x49, 0x94, 0x6d, 0xe4, 0x5e, 0x84, 0xa1, 0xd9, 0x56, 0xd8, 0x09, 0x12, 0xf4, 0x5e, 0x28, - 0xee, 0x78, 0xcd, 0x0e, 0x29, 0x3b, 0x8f, 0x38, 0x4f, 0x8c, 0xce, 0x3d, 0xf6, 0xdd, 0xbd, 0xe9, - 0x07, 0x6e, 0xed, 0x4d, 0x17, 0xaf, 0x51, 0xe0, 0xed, 0xbd, 0xe9, 0x93, 0x24, 0xa8, 0x86, 0x35, - 0x3f, 0xa8, 0x9f, 0x7f, 0x39, 0x0e, 0x83, 0x99, 0x2b, 0x9d, 0xd6, 0x26, 0x89, 0x30, 0x6f, 0xe3, - 0xfe, 0xeb, 0x02, 0x1c, 0x9b, 0x8d, 0xaa, 0x0d, 0x7f, 0x87, 0x54, 0x12, 0x8a, 0xbf, 0xbe, 0x8b, - 0x1a, 0x30, 0x90, 0x78, 0x11, 0x43, 0x57, 0xba, 0xb0, 0x3a, 0x73, 0xaf, 0xdf, 0x7d, 0x66, 0xc3, - 0x8b, 0x24, 0xee, 0xb9, 0xe1, 0x5b, 0x7b, 0xd3, 0x03, 0x1b, 0x5e, 0x84, 0x29, 0x09, 0xd4, 0x84, - 0xc1, 0x20, 0x0c, 0x48, 0xb9, 0xc0, 0x48, 0x5d, 0xb9, 0x77, 0x52, 0x57, 0xc2, 0x40, 0x8d, 0x63, - 0x6e, 0xe4, 0xd6, 0xde, 0xf4, 0x20, 0x85, 0x60, 0x46, 0x85, 0x8e, 0xeb, 0x55, 0xbf, 0x5d, 0x1e, - 0xb0, 0x35, 0xae, 0x17, 0xfd, 0xb6, 0x39, 0xae, 0x17, 0xfd, 0x36, 0xa6, 0x24, 0xdc, 0xcf, 0x15, - 0x60, 0x74, 0x36, 0xaa, 0x77, 0x5a, 0x24, 0x48, 0x62, 0xf4, 0x31, 0x80, 0xb6, 0x17, 0x79, 0x2d, - 0x92, 0x90, 0x28, 0x2e, 0x3b, 0x8f, 0x0c, 0x3c, 0x51, 0xba, 0xb0, 0x7c, 0xef, 0xe4, 0xd7, 0x25, - 0xce, 0x39, 0x24, 0x3e, 0x39, 0x28, 0x50, 0x8c, 0x35, 0x92, 0xe8, 0x35, 0x18, 0xf5, 0xa2, 0xc4, - 0xdf, 0xf2, 0xaa, 0x49, 0x5c, 0x2e, 0x30, 0xfa, 0xcf, 0xdd, 0x3b, 0xfd, 0x59, 0x81, 0x72, 0xee, - 0xb8, 0x20, 0x3f, 0x2a, 0x21, 0x31, 0x4e, 0xe9, 0xb9, 0xbf, 0x37, 0x08, 0xa5, 0xd9, 0x28, 0x59, - 0x9a, 0xaf, 0x24, 0x5e, 0xd2, 0x89, 0xd1, 0x1f, 0x3a, 0x70, 0x22, 0xe6, 0xd3, 0xe6, 0x93, 0x78, - 0x3d, 0x0a, 0xab, 0x24, 0x8e, 0x49, 0x4d, 0xcc, 0xcb, 0x96, 0x95, 0x7e, 0x49, 0x62, 0x33, 0x95, - 0x6e, 0x42, 0x17, 0x83, 0x24, 0xda, 0x9d, 0x7b, 0x5a, 0xf4, 0xf9, 0x44, 0x4e, 0x8d, 0x37, 0xdf, - 0x9e, 0x46, 0x72, 0x28, 0x14, 0x13, 0xff, 0xc4, 0x38, 0xaf, 0xd7, 0xe8, 0x6b, 0x0e, 0x8c, 0xb5, - 0xc3, 0x5a, 0x8c, 0x49, 0x35, 0xec, 0xb4, 0x49, 0x4d, 0x4c, 0xef, 0x87, 0xed, 0x0e, 0x63, 0x5d, - 0xa3, 0xc0, 0xfb, 0x7f, 0x52, 0xf4, 0x7f, 0x4c, 0x2f, 0xc2, 0x46, 0x57, 0xd0, 0xb3, 0x30, 0x16, - 0x84, 0x49, 0xa5, 0x4d, 0xaa, 0xfe, 0x96, 0x4f, 0x6a, 0x6c, 0xe1, 0x8f, 0xa4, 0x2d, 0xaf, 0x68, - 0x65, 0xd8, 0xa8, 0x39, 0xb5, 0x08, 0xe5, 0x5e, 0x33, 0x87, 0x26, 0x61, 0x60, 0x9b, 0xec, 0x72, - 0x66, 0x83, 0xe9, 0xbf, 0xe8, 0xa4, 0x64, 0x40, 0x74, 0x1b, 0x8f, 0x08, 0xce, 0xf2, 0x9e, 0xc2, - 0xb3, 0xce, 0xd4, 0xfb, 0xe1, 0x78, 0x57, 0xd7, 0x0f, 0x82, 0xc0, 0xfd, 0xde, 0x10, 0x8c, 0xc8, - 0x4f, 0x81, 0x1e, 0x81, 0xc1, 0xc0, 0x6b, 0x49, 0x3e, 0x37, 0x26, 0xc6, 0x31, 0x78, 0xc5, 0x6b, - 0xd1, 0x1d, 0xee, 0xb5, 0x08, 0xad, 0xd1, 0xf6, 0x92, 0x06, 0xc3, 0xa3, 0xd5, 0x58, 0xf7, 0x92, - 0x06, 0x66, 0x25, 0xe8, 0x21, 0x18, 0x6c, 0x85, 0x35, 0xc2, 0xe6, 0xa2, 0xc8, 0x39, 0xc4, 0x6a, - 0x58, 0x23, 0x98, 0x41, 0x69, 0xfb, 0xad, 0x28, 0x6c, 0x95, 0x07, 0xcd, 0xf6, 0x8b, 0x51, 0xd8, - 0xc2, 0xac, 0x04, 0x7d, 0xd5, 0x81, 0x49, 0xb9, 0xb6, 0x57, 0xc2, 0xaa, 0x97, 0xf8, 0x61, 0x50, - 0x2e, 0x32, 0x8e, 0x82, 0xed, 0x6d, 0x29, 0x89, 0x79, 0xae, 0x2c, 0xba, 0x30, 0x99, 0x2d, 0xc1, - 0x5d, 0xbd, 0x40, 0x17, 0x00, 0xea, 0xcd, 0x70, 0xd3, 0x6b, 0xd2, 0x09, 0x29, 0x0f, 0xb1, 0x21, - 0x28, 0xce, 0xb0, 0xa4, 0x4a, 0xb0, 0x56, 0x0b, 0xdd, 0x84, 0x61, 0x8f, 0x73, 0xff, 0xf2, 0x30, - 0x1b, 0xc4, 0xf3, 0x36, 0x06, 0x61, 0x1c, 0x27, 0x73, 0xa5, 0x5b, 0x7b, 0xd3, 0xc3, 0x02, 0x88, - 0x25, 0x39, 0xf4, 0x14, 0x8c, 0x84, 0x6d, 0xda, 0x6f, 0xaf, 0x59, 0x1e, 0x61, 0x0b, 0x73, 0x52, - 0xf4, 0x75, 0x64, 0x4d, 0xc0, 0xb1, 0xaa, 0x81, 0x9e, 0x84, 0xe1, 0xb8, 0xb3, 0x49, 0xbf, 0x63, - 0x79, 0x94, 0x0d, 0xec, 0x98, 0xa8, 0x3c, 0x5c, 0xe1, 0x60, 0x2c, 0xcb, 0xd1, 0xbb, 0xa1, 0x14, - 0x91, 0x6a, 0x27, 0x8a, 0x09, 0xfd, 0xb0, 0x65, 0x60, 0xb8, 0x4f, 0x88, 0xea, 0x25, 0x9c, 0x16, - 0x61, 0xbd, 0x1e, 0x7a, 0x1f, 0x4c, 0xd0, 0x0f, 0x7c, 0xf1, 0x66, 0x3b, 0x22, 0x71, 0x4c, 0xbf, - 0x6a, 0x89, 0x11, 0x3a, 0x2d, 0x5a, 0x4e, 0x2c, 0x1a, 0xa5, 0x38, 0x53, 0x1b, 0xbd, 0x0e, 0xe0, - 0x29, 0x9e, 0x51, 0x1e, 0x63, 0x93, 0xb9, 0x62, 0x6f, 0x45, 0x2c, 0xcd, 0xcf, 0x4d, 0xd0, 0xef, - 0x98, 0xfe, 0xc6, 0x1a, 0x3d, 0x3a, 0x3f, 0x35, 0xd2, 0x24, 0x09, 0xa9, 0x95, 0xc7, 0xd9, 0x80, - 0xd5, 0xfc, 0x2c, 0x70, 0x30, 0x96, 0xe5, 0xee, 0xdf, 0x2e, 0x80, 0x86, 0x05, 0xcd, 0xc1, 0x88, - 0xe0, 0x6b, 0x62, 0x4b, 0xce, 0x3d, 0x2e, 0xbf, 0x83, 0xfc, 0x82, 0xb7, 0xf7, 0x72, 0xf9, 0xa1, - 0x6a, 0x87, 0xde, 0x80, 0x52, 0x3b, 0xac, 0xad, 0x92, 0xc4, 0xab, 0x79, 0x89, 0x27, 0x4e, 0x73, - 0x0b, 0x27, 0x8c, 0xc4, 0x38, 0x77, 0x8c, 0x7e, 0xba, 0xf5, 0x94, 0x04, 0xd6, 0xe9, 0xa1, 0xe7, - 0x00, 0xc5, 0x24, 0xda, 0xf1, 0xab, 0x64, 0xb6, 0x5a, 0xa5, 0x22, 0x11, 0xdb, 0x00, 0x03, 0x6c, - 0x30, 0x53, 0x62, 0x30, 0xa8, 0xd2, 0x55, 0x03, 0xe7, 0xb4, 0x72, 0xbf, 0x5f, 0x80, 0x09, 0x6d, - 0xac, 0x6d, 0x52, 0x45, 0x6f, 0x39, 0x70, 0x4c, 0x1d, 0x67, 0x73, 0xbb, 0x57, 0xe8, 0xaa, 0xe2, - 0x87, 0x15, 0xb1, 0xf9, 0x7d, 0x29, 0x2d, 0xf5, 0x53, 0xd0, 0xe1, 0xbc, 0xfe, 0x8c, 0x18, 0xc3, - 0xb1, 0x4c, 0x29, 0xce, 0x76, 0x6b, 0xea, 0x2b, 0x0e, 0x9c, 0xcc, 0x43, 0x91, 0xc3, 0x73, 0x1b, - 0x3a, 0xcf, 0xb5, 0xca, 0xbc, 0x28, 0x55, 0x3a, 0x18, 0x9d, 0x8f, 0xff, 0xdf, 0x02, 0x4c, 0xea, - 0x4b, 0x88, 0x49, 0x02, 0xff, 0xd4, 0x81, 0x53, 0x72, 0x04, 0x98, 0xc4, 0x9d, 0x66, 0x66, 0x7a, - 0x5b, 0x56, 0xa7, 0x97, 0x9f, 0xa4, 0xb3, 0x79, 0xf4, 0xf8, 0x34, 0x3f, 0x2c, 0xa6, 0xf9, 0x54, - 0x6e, 0x1d, 0x9c, 0xdf, 0xd5, 0xa9, 0x6f, 0x39, 0x30, 0xd5, 0x1b, 0x69, 0xce, 0xc4, 0xb7, 0xcd, - 0x89, 0x7f, 0xd1, 0xde, 0x20, 0x39, 0x79, 0x36, 0xfd, 0x6c, 0xb0, 0xfa, 0x07, 0xf8, 0xed, 0x11, - 0xe8, 0x3a, 0x43, 0xd0, 0xd3, 0x50, 0x12, 0xec, 0x78, 0x25, 0xac, 0xc7, 0xac, 0x93, 0x23, 0x7c, - 0xaf, 0xcd, 0xa6, 0x60, 0xac, 0xd7, 0x41, 0x35, 0x28, 0xc4, 0xcf, 0x88, 0xae, 0x5b, 0x60, 0x6f, - 0x95, 0x67, 0x94, 0x14, 0x39, 0x74, 0x6b, 0x6f, 0xba, 0x50, 0x79, 0x06, 0x17, 0xe2, 0x67, 0xa8, - 0xa4, 0x5e, 0xf7, 0x13, 0x7b, 0x92, 0xfa, 0x92, 0x9f, 0x28, 0x3a, 0x4c, 0x52, 0x5f, 0xf2, 0x13, - 0x4c, 0x49, 0x50, 0x0d, 0xa4, 0x91, 0x24, 0x6d, 0x76, 0xe2, 0x5b, 0xd1, 0x40, 0x2e, 0x6d, 0x6c, - 0xac, 0x2b, 0x5a, 0x4c, 0xbe, 0xa0, 0x10, 0xcc, 0xa8, 0xa0, 0xcf, 0x3a, 0x74, 0xc6, 0x79, 0x61, - 0x18, 0xed, 0x0a, 0xc1, 0xe1, 0xaa, 0xbd, 0x25, 0x10, 0x46, 0xbb, 0x8a, 0xb8, 0xf8, 0x90, 0xaa, - 0x00, 0xeb, 0xa4, 0xd9, 0xc0, 0x6b, 0x5b, 0x31, 0x93, 0x13, 0xec, 0x0c, 0x7c, 0x61, 0xb1, 0x92, - 0x19, 0xf8, 0xc2, 0x62, 0x05, 0x33, 0x2a, 0xf4, 0x83, 0x46, 0xde, 0x0d, 0x21, 0x63, 0x58, 0xf8, - 0xa0, 0xd8, 0xbb, 0x61, 0x7e, 0x50, 0xec, 0xdd, 0xc0, 0x94, 0x04, 0xa5, 0x14, 0xc6, 0x31, 0x13, - 0x29, 0xac, 0x50, 0x5a, 0xab, 0x54, 0x4c, 0x4a, 0x6b, 0x95, 0x0a, 0xa6, 0x24, 0xd8, 0x22, 0xad, - 0xc6, 0x4c, 0x1e, 0xb1, 0xb3, 0x48, 0xe7, 0x33, 0x94, 0x96, 0xe6, 0x2b, 0x98, 0x92, 0xa0, 0x2c, - 0xc3, 0x7b, 0xb5, 0x13, 0x71, 0x61, 0xa6, 0x74, 0x61, 0xcd, 0xc2, 0x7a, 0xa1, 0xe8, 0x14, 0xb5, - 0xd1, 0x5b, 0x7b, 0xd3, 0x45, 0x06, 0xc2, 0x9c, 0x90, 0xfb, 0x07, 0x03, 0x29, 0xbb, 0x90, 0xfc, - 0x1c, 0xfd, 0x3a, 0x3b, 0x08, 0x05, 0x2f, 0x10, 0xa2, 0xaf, 0x73, 0x68, 0xa2, 0xef, 0x09, 0x7e, - 0xe2, 0x19, 0xe4, 0x70, 0x96, 0x3e, 0xfa, 0xa2, 0xd3, 0xad, 0xdb, 0x7a, 0xf6, 0xcf, 0xb2, 0xf4, - 0x60, 0xe6, 0x67, 0xc5, 0xbe, 0x2a, 0xef, 0xd4, 0x67, 0x9d, 0x54, 0x88, 0x88, 0x7b, 0x9d, 0x03, - 0x1f, 0x31, 0xcf, 0x01, 0x8b, 0x0a, 0xb9, 0xce, 0xf7, 0x3f, 0xe7, 0xc0, 0xb8, 0x84, 0x53, 0xf1, - 0x38, 0x46, 0x37, 0x61, 0x44, 0xf6, 0x54, 0x7c, 0x3d, 0x9b, 0xb6, 0x00, 0x25, 0xc4, 0xab, 0xce, - 0x28, 0x6a, 0xee, 0x5b, 0x43, 0x80, 0xd2, 0xb3, 0xaa, 0x1d, 0xc6, 0x3e, 0xe3, 0x44, 0x77, 0x71, - 0x0a, 0x05, 0xda, 0x29, 0x74, 0xcd, 0xe6, 0x29, 0x94, 0x76, 0xcb, 0x38, 0x8f, 0xbe, 0x98, 0xe1, - 0xdb, 0xfc, 0x60, 0xfa, 0xf0, 0xa1, 0xf0, 0x6d, 0xad, 0x0b, 0xfb, 0x73, 0xf0, 0x1d, 0xc1, 0xc1, - 0xf9, 0xd1, 0xf5, 0x4b, 0x76, 0x39, 0xb8, 0xd6, 0x8b, 0x2c, 0x2f, 0x8f, 0x38, 0x87, 0xe5, 0x67, - 0xd7, 0x75, 0xab, 0x1c, 0x56, 0xa3, 0x6a, 0xf2, 0xda, 0x88, 0xf3, 0xda, 0x21, 0x5b, 0x34, 0x35, - 0x5e, 0x9b, 0xa5, 0xa9, 0xb8, 0xee, 0xab, 0x92, 0xeb, 0xf2, 0x53, 0xeb, 0x05, 0xcb, 0x5c, 0x57, - 0xa3, 0xdb, 0xcd, 0x7f, 0x5f, 0x81, 0x53, 0xdd, 0xf5, 0x30, 0xd9, 0x42, 0xe7, 0x61, 0xb4, 0x1a, - 0x06, 0x5b, 0x7e, 0x7d, 0xd5, 0x6b, 0x0b, 0x7d, 0x4d, 0xf1, 0xa2, 0x79, 0x59, 0x80, 0xd3, 0x3a, - 0xe8, 0x61, 0xce, 0x78, 0xb8, 0x45, 0xa4, 0x24, 0xaa, 0x0e, 0x2c, 0x93, 0x5d, 0xc6, 0x85, 0xde, - 0x33, 0xf2, 0xd5, 0x6f, 0x4c, 0x3f, 0xf0, 0xf1, 0x3f, 0x7e, 0xe4, 0x01, 0xf7, 0x8f, 0x06, 0xe0, - 0x6c, 0x2e, 0x4d, 0x21, 0xad, 0xff, 0xb6, 0x21, 0xad, 0x6b, 0xe5, 0x82, 0x8b, 0x5c, 0xb7, 0x29, - 0xc8, 0x6a, 0xe8, 0xf3, 0xe4, 0x72, 0xad, 0x18, 0xe7, 0x77, 0x8a, 0x4e, 0x54, 0xe0, 0xb5, 0x48, - 0xdc, 0xf6, 0xaa, 0x44, 0x8c, 0x5e, 0x4d, 0xd4, 0x15, 0x59, 0x80, 0xd3, 0x3a, 0x5c, 0x85, 0xde, - 0xf2, 0x3a, 0xcd, 0x44, 0x18, 0xca, 0x34, 0x15, 0x9a, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xc7, 0x01, - 0xd4, 0x4d, 0x55, 0x6c, 0xc4, 0x8d, 0xc3, 0x98, 0x87, 0xb9, 0xd3, 0xb7, 0x34, 0x25, 0x5c, 0x1b, - 0x69, 0x4e, 0x3f, 0xb4, 0x6f, 0xfa, 0xd1, 0xf4, 0x1c, 0xe2, 0xca, 0x41, 0x1f, 0x36, 0x34, 0x66, - 0x6a, 0xa9, 0x56, 0x49, 0x1c, 0x73, 0x73, 0x9c, 0x6e, 0x6a, 0x61, 0x60, 0x2c, 0xcb, 0xd1, 0x34, - 0x14, 0x49, 0x14, 0x85, 0x91, 0xd0, 0xb5, 0xd9, 0x32, 0xbe, 0x48, 0x01, 0x98, 0xc3, 0xdd, 0x1f, - 0x17, 0xa0, 0xdc, 0x4b, 0x3b, 0x41, 0xbf, 0xab, 0xe9, 0xd5, 0x42, 0x73, 0x12, 0x8a, 0x5f, 0x78, - 0x78, 0x3a, 0x51, 0x56, 0x01, 0xec, 0xa1, 0x61, 0x8b, 0x52, 0x9c, 0xed, 0xe0, 0xd4, 0x97, 0x34, - 0x0d, 0x5b, 0x47, 0x91, 0x73, 0xc0, 0x6f, 0x99, 0x07, 0xfc, 0xba, 0xed, 0x41, 0xe9, 0xc7, 0xfc, - 0x9f, 0x14, 0xe1, 0x84, 0x2c, 0xad, 0x10, 0x7a, 0x54, 0x3e, 0xdf, 0x21, 0xd1, 0x2e, 0xfa, 0x81, - 0x03, 0x27, 0xbd, 0xac, 0xe9, 0xc6, 0x27, 0x87, 0x30, 0xd1, 0x1a, 0xd5, 0x99, 0xd9, 0x1c, 0x8a, - 0x7c, 0xa2, 0x2f, 0x88, 0x89, 0x3e, 0x99, 0x57, 0xa5, 0x87, 0xdd, 0x3d, 0x77, 0x00, 0xe8, 0x59, - 0x18, 0x93, 0x70, 0x66, 0xee, 0xe1, 0x5b, 0x5c, 0x19, 0xb7, 0x67, 0xb5, 0x32, 0x6c, 0xd4, 0xa4, - 0x2d, 0x13, 0xd2, 0x6a, 0x37, 0xbd, 0x84, 0x68, 0x86, 0x22, 0xd5, 0x72, 0x43, 0x2b, 0xc3, 0x46, - 0x4d, 0xf4, 0x38, 0x0c, 0x05, 0x61, 0x8d, 0x5c, 0xae, 0x09, 0x03, 0xf1, 0x84, 0x68, 0x33, 0x74, - 0x85, 0x41, 0xb1, 0x28, 0x45, 0x8f, 0xa5, 0xd6, 0xb8, 0x22, 0xdb, 0x42, 0xa5, 0x3c, 0x4b, 0x1c, - 0xfa, 0x7b, 0x0e, 0x8c, 0xd2, 0x16, 0x1b, 0xbb, 0x6d, 0x42, 0xcf, 0x36, 0xfa, 0x45, 0x6a, 0x87, - 0xf3, 0x45, 0xae, 0x48, 0x32, 0xa6, 0xa9, 0x63, 0x54, 0xc1, 0xdf, 0x7c, 0x7b, 0x7a, 0x44, 0xfe, - 0xc0, 0x69, 0xaf, 0xa6, 0x96, 0xe0, 0xc1, 0x9e, 0x5f, 0xf3, 0x40, 0xae, 0x80, 0xbf, 0x06, 0x13, - 0x66, 0x27, 0x0e, 0xe4, 0x07, 0xf8, 0x27, 0xda, 0xb6, 0xe3, 0xe3, 0x12, 0xfc, 0xec, 0xbe, 0x49, - 0xb3, 0x6a, 0x31, 0x2c, 0x88, 0xa5, 0x67, 0x2e, 0x86, 0x05, 0xb1, 0x18, 0x16, 0xdc, 0x3f, 0x74, - 0xd2, 0xad, 0xa9, 0x89, 0x79, 0xf4, 0x60, 0xee, 0x44, 0x4d, 0xc1, 0x88, 0xd5, 0xc1, 0x7c, 0x15, - 0xaf, 0x60, 0x0a, 0x47, 0x5f, 0xd2, 0xb8, 0x23, 0x6d, 0xd6, 0x11, 0x6e, 0x0d, 0x4b, 0x26, 0x7a, - 0x03, 0x71, 0x37, 0xff, 0x13, 0x05, 0x38, 0xdb, 0x05, 0xf7, 0x8b, 0x05, 0x78, 0x78, 0x5f, 0xa1, - 0x35, 0xb7, 0xe3, 0xce, 0x7d, 0xef, 0x38, 0x3d, 0xd6, 0x22, 0xd2, 0x0e, 0xaf, 0xe2, 0x15, 0xf1, - 0xbd, 0xd4, 0xb1, 0x86, 0x39, 0x18, 0xcb, 0x72, 0x2a, 0x3a, 0x6c, 0x93, 0xdd, 0xc5, 0x30, 0x6a, - 0x79, 0x89, 0xe0, 0x0e, 0x4a, 0x74, 0x58, 0x96, 0x05, 0x38, 0xad, 0xe3, 0xfe, 0xc0, 0x81, 0x6c, - 0x07, 0x90, 0x07, 0x13, 0x9d, 0x98, 0x44, 0xf4, 0x48, 0xad, 0x90, 0x6a, 0x44, 0xe4, 0xf2, 0x7c, - 0x6c, 0x86, 0x7b, 0xfb, 0xe9, 0x08, 0x67, 0xaa, 0x61, 0x44, 0x66, 0x76, 0x9e, 0x9e, 0xe1, 0x35, - 0x96, 0xc9, 0x6e, 0x85, 0x34, 0x09, 0xc5, 0x31, 0x87, 0x6e, 0xed, 0x4d, 0x4f, 0x5c, 0x35, 0x10, - 0xe0, 0x0c, 0x42, 0x4a, 0xa2, 0xed, 0xc5, 0xf1, 0x8d, 0x30, 0xaa, 0x09, 0x12, 0x85, 0x03, 0x93, - 0x58, 0x37, 0x10, 0xe0, 0x0c, 0x42, 0xf7, 0xfb, 0x54, 0x7d, 0xd4, 0xa5, 0x56, 0xf4, 0x0d, 0x2a, - 0xfb, 0x50, 0xc8, 0x5c, 0x33, 0xdc, 0x9c, 0x0f, 0x83, 0xc4, 0xf3, 0x03, 0x22, 0x83, 0x05, 0x36, - 0x2c, 0xc9, 0xc8, 0x06, 0xee, 0xd4, 0x86, 0xdf, 0x5d, 0x86, 0x73, 0xfa, 0x42, 0x65, 0x9c, 0xcd, - 0x66, 0xb8, 0x99, 0xf5, 0x02, 0xd2, 0x4a, 0x98, 0x95, 0xb8, 0x3f, 0x75, 0xe0, 0x4c, 0x0f, 0x61, - 0x1c, 0x7d, 0xc5, 0x81, 0xf1, 0xcd, 0x9f, 0x89, 0xb1, 0x99, 0xdd, 0x40, 0xef, 0x83, 0x09, 0x0a, - 0xa0, 0x27, 0x91, 0x58, 0x9b, 0x05, 0xd3, 0x43, 0x35, 0x67, 0x94, 0xe2, 0x4c, 0x6d, 0xf7, 0x37, - 0x0a, 0x90, 0x43, 0x05, 0x3d, 0x05, 0x23, 0x24, 0xa8, 0xb5, 0x43, 0x3f, 0x48, 0x04, 0x33, 0x52, - 0x5c, 0xef, 0xa2, 0x80, 0x63, 0x55, 0x43, 0xe8, 0x1f, 0x62, 0x62, 0x0a, 0x5d, 0xfa, 0x87, 0xe8, - 0x79, 0x5a, 0x07, 0xd5, 0x61, 0xd2, 0xe3, 0xfe, 0x15, 0xb6, 0xf6, 0xd8, 0x32, 0x1d, 0x38, 0xc8, - 0x32, 0x3d, 0xc9, 0xdc, 0x9f, 0x19, 0x14, 0xb8, 0x0b, 0x29, 0x7a, 0x37, 0x94, 0x3a, 0x31, 0xa9, - 0x2c, 0x2c, 0xcf, 0x47, 0xa4, 0xc6, 0xb5, 0x62, 0xcd, 0xef, 0x77, 0x35, 0x2d, 0xc2, 0x7a, 0x3d, - 0xf7, 0x9f, 0x39, 0x30, 0x3c, 0xe7, 0x55, 0xb7, 0xc3, 0xad, 0x2d, 0x3a, 0x15, 0xb5, 0x4e, 0x94, - 0x1a, 0xb6, 0xb4, 0xa9, 0x58, 0x10, 0x70, 0xac, 0x6a, 0xa0, 0x0d, 0x18, 0xe2, 0x1b, 0x5e, 0x6c, - 0xbb, 0x5f, 0xd4, 0xc6, 0xa3, 0xe2, 0x78, 0xd8, 0x72, 0xe8, 0x24, 0x7e, 0x73, 0x86, 0xc7, 0xf1, - 0xcc, 0x5c, 0x0e, 0x92, 0xb5, 0xa8, 0x92, 0x44, 0x7e, 0x50, 0x9f, 0x03, 0x7a, 0x5c, 0x2c, 0x32, - 0x1c, 0x58, 0xe0, 0xa2, 0xc3, 0x68, 0x79, 0x37, 0x25, 0x39, 0xc1, 0x7e, 0xd4, 0x30, 0x56, 0xd3, - 0x22, 0xac, 0xd7, 0x73, 0xff, 0xc8, 0x81, 0xd1, 0x39, 0x2f, 0xf6, 0xab, 0x7f, 0x81, 0x98, 0xcf, - 0x87, 0xa0, 0x38, 0xef, 0x55, 0x1b, 0x04, 0x5d, 0xcd, 0x2a, 0xbd, 0xa5, 0x0b, 0x4f, 0xe4, 0x91, - 0x51, 0x0a, 0xb0, 0x4e, 0x69, 0xbc, 0x97, 0x6a, 0xec, 0xbe, 0xed, 0xc0, 0xc4, 0x7c, 0xd3, 0x27, - 0x41, 0x32, 0x4f, 0xa2, 0x84, 0x4d, 0x5c, 0x1d, 0x26, 0xab, 0x0a, 0x72, 0x37, 0x53, 0xc7, 0x56, - 0xeb, 0x7c, 0x06, 0x05, 0xee, 0x42, 0x8a, 0x6a, 0x70, 0x8c, 0xc3, 0xd2, 0x5d, 0x71, 0xa0, 0xf9, - 0x63, 0xd6, 0xd1, 0x79, 0x13, 0x03, 0xce, 0xa2, 0x74, 0x7f, 0xe2, 0xc0, 0x99, 0xf9, 0x66, 0x27, - 0x4e, 0x48, 0x74, 0x5d, 0x70, 0x23, 0x29, 0xde, 0xa2, 0x8f, 0xc0, 0x48, 0x4b, 0x7a, 0x6c, 0x9d, - 0x3b, 0x2c, 0x60, 0xc6, 0xcf, 0x68, 0x6d, 0xda, 0x99, 0xb5, 0xcd, 0x97, 0x49, 0x35, 0x59, 0x25, - 0x89, 0x97, 0x86, 0x17, 0xa4, 0x30, 0xac, 0xb0, 0xa2, 0x36, 0x0c, 0xc6, 0x6d, 0x52, 0xb5, 0x17, - 0xdd, 0x25, 0xc7, 0x50, 0x69, 0x93, 0x6a, 0xca, 0xd7, 0x99, 0xaf, 0x91, 0x51, 0x72, 0xff, 0x97, - 0x03, 0x67, 0x7b, 0x8c, 0x77, 0xc5, 0x8f, 0x13, 0xf4, 0x52, 0xd7, 0x98, 0x67, 0xfa, 0x1b, 0x33, - 0x6d, 0xcd, 0x46, 0xac, 0x18, 0x82, 0x84, 0x68, 0xe3, 0xfd, 0x28, 0x14, 0xfd, 0x84, 0xb4, 0xa4, - 0x19, 0xda, 0x82, 0xc1, 0xa8, 0xc7, 0x58, 0xe6, 0xc6, 0x65, 0x8c, 0xdf, 0x65, 0x4a, 0x0f, 0x73, - 0xb2, 0xee, 0x36, 0x0c, 0xcd, 0x87, 0xcd, 0x4e, 0x2b, 0xe8, 0x2f, 0x52, 0x26, 0xd9, 0x6d, 0x93, - 0xec, 0x19, 0xc9, 0xc4, 0x7f, 0x56, 0x22, 0x0d, 0x47, 0x03, 0xf9, 0x86, 0x23, 0xf7, 0x9f, 0x3b, - 0x40, 0x77, 0x55, 0xcd, 0x17, 0x9e, 0x44, 0x8e, 0x8e, 0x13, 0x7c, 0x58, 0x47, 0x77, 0x7b, 0x6f, - 0x7a, 0x5c, 0x55, 0xd4, 0xf0, 0x7f, 0x08, 0x86, 0x62, 0xa6, 0x92, 0x8b, 0x3e, 0x2c, 0x4a, 0xf9, - 0x99, 0x2b, 0xea, 0xb7, 0xf7, 0xa6, 0xfb, 0x0a, 0xdb, 0x9c, 0x51, 0xb8, 0x85, 0xd3, 0x53, 0x60, - 0xa5, 0x02, 0x5f, 0x8b, 0xc4, 0xb1, 0x57, 0x97, 0x1a, 0x9e, 0x12, 0xf8, 0x56, 0x39, 0x18, 0xcb, - 0x72, 0xf7, 0xcb, 0x0e, 0x8c, 0xab, 0xc3, 0x8b, 0x8a, 0xef, 0xe8, 0x8a, 0x7e, 0xcc, 0xf1, 0x95, - 0xf2, 0x70, 0x0f, 0x8e, 0x23, 0x0e, 0xf2, 0xfd, 0x4f, 0xc1, 0x77, 0xc1, 0x58, 0x8d, 0xb4, 0x49, - 0x50, 0x23, 0x41, 0x95, 0xaa, 0xdf, 0x74, 0x85, 0x8c, 0xce, 0x4d, 0x52, 0x7d, 0x73, 0x41, 0x83, - 0x63, 0xa3, 0x96, 0xfb, 0x4d, 0x07, 0x1e, 0x54, 0xe8, 0x2a, 0x24, 0xc1, 0x24, 0x89, 0x76, 0x55, - 0x98, 0xe6, 0xc1, 0x4e, 0xab, 0xeb, 0x54, 0xfe, 0x4d, 0x22, 0x4e, 0xfc, 0xee, 0x8e, 0xab, 0x12, - 0x97, 0x96, 0x19, 0x12, 0x2c, 0xb1, 0xb9, 0xbf, 0x36, 0x00, 0x27, 0xf5, 0x4e, 0x2a, 0x06, 0xf3, - 0x09, 0x07, 0x40, 0xcd, 0x00, 0x3d, 0x90, 0x07, 0xec, 0xf8, 0xae, 0x8c, 0x2f, 0x95, 0xb2, 0x20, - 0x05, 0x8e, 0xb1, 0x46, 0x16, 0xbd, 0x00, 0x63, 0x3b, 0x74, 0x53, 0x90, 0x55, 0x2a, 0x2e, 0xc4, - 0xe5, 0x01, 0xd6, 0x8d, 0xe9, 0xbc, 0x8f, 0x79, 0x2d, 0xad, 0x97, 0x9a, 0x03, 0x34, 0x60, 0x8c, - 0x0d, 0x54, 0x54, 0xd3, 0x19, 0x8f, 0xf4, 0x4f, 0x22, 0x6c, 0xe2, 0x1f, 0xb4, 0x38, 0xc6, 0xec, - 0x57, 0x9f, 0x3b, 0x7e, 0x6b, 0x6f, 0x7a, 0xdc, 0x00, 0x61, 0xb3, 0x13, 0xee, 0x0b, 0xc0, 0xe6, - 0xc2, 0x0f, 0x3a, 0x64, 0x2d, 0x40, 0x8f, 0x4a, 0x1b, 0x1d, 0xf7, 0xab, 0x28, 0xce, 0xa1, 0xdb, - 0xe9, 0xa8, 0x2e, 0xbb, 0xe5, 0xf9, 0x4d, 0x16, 0xbe, 0x48, 0x6b, 0x29, 0x5d, 0x76, 0x91, 0x41, - 0xb1, 0x28, 0x75, 0x67, 0x60, 0x78, 0x9e, 0x8e, 0x9d, 0x44, 0x14, 0xaf, 0x1e, 0x75, 0x3c, 0x6e, - 0x44, 0x1d, 0xcb, 0xe8, 0xe2, 0x0d, 0x38, 0x35, 0x1f, 0x11, 0x2f, 0x21, 0x95, 0x67, 0xe6, 0x3a, - 0xd5, 0x6d, 0x92, 0xf0, 0xd0, 0xae, 0x18, 0xbd, 0x17, 0xc6, 0x43, 0x76, 0x64, 0xac, 0x84, 0xd5, - 0x6d, 0x3f, 0xa8, 0x0b, 0x93, 0xeb, 0x29, 0x81, 0x65, 0x7c, 0x4d, 0x2f, 0xc4, 0x66, 0x5d, 0xf7, - 0xdf, 0x17, 0x60, 0x6c, 0x3e, 0x0a, 0x03, 0xc9, 0x16, 0x8f, 0xe0, 0x28, 0x4b, 0x8c, 0xa3, 0xcc, - 0x82, 0xbb, 0x53, 0xef, 0x7f, 0xaf, 0xe3, 0x0c, 0xbd, 0xae, 0x58, 0xe4, 0x80, 0x2d, 0x15, 0xc4, - 0xa0, 0xcb, 0x70, 0xa7, 0x1f, 0xdb, 0x64, 0xa0, 0xee, 0x7f, 0x70, 0x60, 0x52, 0xaf, 0x7e, 0x04, - 0x27, 0x68, 0x6c, 0x9e, 0xa0, 0x57, 0xec, 0x8e, 0xb7, 0xc7, 0xb1, 0xf9, 0xf6, 0xb0, 0x39, 0x4e, - 0xe6, 0xeb, 0xfe, 0xaa, 0x03, 0x63, 0x37, 0x34, 0x80, 0x18, 0xac, 0x6d, 0x21, 0xe6, 0x1d, 0x92, - 0xcd, 0xe8, 0xd0, 0xdb, 0x99, 0xdf, 0xd8, 0xe8, 0x09, 0xe5, 0xfb, 0x71, 0xb5, 0x41, 0x6a, 0x9d, - 0xa6, 0x3c, 0xbe, 0xd5, 0x94, 0x56, 0x04, 0x1c, 0xab, 0x1a, 0xe8, 0x25, 0x38, 0x5e, 0x0d, 0x83, - 0x6a, 0x27, 0x8a, 0x48, 0x50, 0xdd, 0x5d, 0x67, 0x77, 0x24, 0xc4, 0x81, 0x38, 0x23, 0x9a, 0x1d, - 0x9f, 0xcf, 0x56, 0xb8, 0x9d, 0x07, 0xc4, 0xdd, 0x88, 0xb8, 0xb3, 0x20, 0xa6, 0x47, 0x96, 0x50, - 0xb8, 0x34, 0x67, 0x01, 0x03, 0x63, 0x59, 0x8e, 0xae, 0xc2, 0x99, 0x38, 0xf1, 0xa2, 0xc4, 0x0f, - 0xea, 0x0b, 0xc4, 0xab, 0x35, 0xfd, 0x80, 0xaa, 0x12, 0x61, 0x50, 0xe3, 0xae, 0xc4, 0x81, 0xb9, - 0xb3, 0xb7, 0xf6, 0xa6, 0xcf, 0x54, 0xf2, 0xab, 0xe0, 0x5e, 0x6d, 0xd1, 0x87, 0x60, 0x4a, 0xb8, - 0x23, 0xb6, 0x3a, 0xcd, 0xe7, 0xc2, 0xcd, 0xf8, 0x92, 0x1f, 0x53, 0x3d, 0x7e, 0xc5, 0x6f, 0xf9, - 0x09, 0x73, 0x18, 0x16, 0xe7, 0xce, 0xdd, 0xda, 0x9b, 0x9e, 0xaa, 0xf4, 0xac, 0x85, 0xf7, 0xc1, - 0x80, 0x30, 0x9c, 0xe6, 0xcc, 0xaf, 0x0b, 0xf7, 0x30, 0xc3, 0x3d, 0x75, 0x6b, 0x6f, 0xfa, 0xf4, - 0x62, 0x6e, 0x0d, 0xdc, 0xa3, 0x25, 0xfd, 0x82, 0x89, 0xdf, 0x22, 0xaf, 0x86, 0x01, 0x61, 0x81, - 0x2a, 0xda, 0x17, 0xdc, 0x10, 0x70, 0xac, 0x6a, 0xa0, 0x97, 0xd3, 0x95, 0x48, 0xb7, 0x8b, 0x08, - 0x38, 0x39, 0x38, 0x87, 0x63, 0xaa, 0xc9, 0x75, 0x0d, 0x13, 0x8b, 0xa4, 0x34, 0x70, 0xa3, 0x4f, - 0x3a, 0x30, 0x16, 0x27, 0xa1, 0xba, 0xd7, 0x20, 0x22, 0x4e, 0x2c, 0x2c, 0xfb, 0x8a, 0x86, 0x95, - 0x0b, 0x3e, 0x3a, 0x04, 0x1b, 0x54, 0xd1, 0x2f, 0xc0, 0xa8, 0x5c, 0xc0, 0x71, 0xb9, 0xc4, 0x64, - 0x25, 0xa6, 0xc6, 0xc9, 0xf5, 0x1d, 0xe3, 0xb4, 0x9c, 0x8a, 0xb2, 0x37, 0x1a, 0x24, 0x60, 0x31, - 0xb7, 0x9a, 0x28, 0x7b, 0xbd, 0x41, 0x02, 0xcc, 0x4a, 0xdc, 0x1f, 0x0f, 0x00, 0xea, 0x66, 0x7c, - 0x68, 0x19, 0x86, 0xbc, 0x6a, 0xe2, 0xef, 0xc8, 0x78, 0xc3, 0x47, 0xf3, 0x84, 0x02, 0x3e, 0x81, - 0x98, 0x6c, 0x11, 0xba, 0xee, 0x49, 0xca, 0x2d, 0x67, 0x59, 0x53, 0x2c, 0x50, 0xa0, 0x10, 0x8e, - 0x37, 0xbd, 0x38, 0x91, 0x3d, 0xac, 0xd1, 0x0f, 0x29, 0x8e, 0x8b, 0x9f, 0xef, 0xef, 0x53, 0xd1, - 0x16, 0x73, 0xa7, 0xe8, 0x7e, 0x5c, 0xc9, 0x22, 0xc2, 0xdd, 0xb8, 0xd1, 0xc7, 0x98, 0x74, 0xc5, - 0x45, 0x5f, 0x29, 0xd6, 0x2c, 0x5b, 0x91, 0x3c, 0x38, 0x4e, 0x43, 0xb2, 0x12, 0x64, 0xb0, 0x46, - 0x12, 0x9d, 0x87, 0x51, 0xb6, 0x6f, 0x48, 0x8d, 0xf0, 0xdd, 0x3f, 0x90, 0x0a, 0xc1, 0x15, 0x59, - 0x80, 0xd3, 0x3a, 0x9a, 0x94, 0xc1, 0x37, 0x7c, 0x0f, 0x29, 0x03, 0x3d, 0x0b, 0xc5, 0x76, 0xc3, - 0x8b, 0x65, 0x0c, 0xbb, 0x2b, 0xb9, 0xf6, 0x3a, 0x05, 0x32, 0xd6, 0xa4, 0x7d, 0x4b, 0x06, 0xc4, - 0xbc, 0x81, 0xfb, 0x2f, 0x00, 0x86, 0x17, 0x66, 0x97, 0x36, 0xbc, 0x78, 0xbb, 0x0f, 0x1d, 0x88, - 0x6e, 0x43, 0x21, 0xac, 0x66, 0x19, 0xa9, 0x14, 0x62, 0xb1, 0xaa, 0x81, 0x02, 0x18, 0xf2, 0x03, - 0xca, 0x79, 0xca, 0x13, 0xb6, 0xfc, 0x0c, 0x4a, 0x9f, 0x63, 0x86, 0xa0, 0xcb, 0x0c, 0x3b, 0x16, - 0x54, 0xd0, 0xeb, 0x30, 0xea, 0xc9, 0x2b, 0x44, 0xe2, 0xfc, 0x5f, 0xb6, 0x61, 0x40, 0x17, 0x28, - 0xf5, 0x10, 0x26, 0x01, 0xc2, 0x29, 0x41, 0xf4, 0x71, 0x07, 0x4a, 0x72, 0xe8, 0x98, 0x6c, 0x09, - 0xdf, 0xf6, 0xaa, 0xbd, 0x31, 0x63, 0xb2, 0xc5, 0xe3, 0x5b, 0x34, 0x00, 0xd6, 0x49, 0x76, 0xe9, - 0x4c, 0xc5, 0x7e, 0x74, 0x26, 0x74, 0x03, 0x46, 0x6f, 0xf8, 0x49, 0x83, 0x9d, 0xf0, 0xc2, 0xa7, - 0xb6, 0x78, 0xef, 0xbd, 0xa6, 0xe8, 0xd2, 0x19, 0xbb, 0x2e, 0x09, 0xe0, 0x94, 0x16, 0xdd, 0x0e, - 0xf4, 0x07, 0xbb, 0x82, 0xc5, 0xce, 0x86, 0x51, 0xb3, 0x01, 0x2b, 0xc0, 0x69, 0x1d, 0x3a, 0xc5, - 0x63, 0xf4, 0x57, 0x85, 0xbc, 0xd2, 0xa1, 0xac, 0x45, 0xc4, 0x2c, 0x5a, 0x58, 0x57, 0x12, 0x23, - 0x9f, 0xac, 0xeb, 0x1a, 0x0d, 0x6c, 0x50, 0x54, 0xac, 0x73, 0xb4, 0x17, 0xeb, 0x44, 0xaf, 0x73, - 0x1d, 0x8e, 0x2b, 0x13, 0xe2, 0x34, 0x58, 0xb1, 0xa3, 0xdf, 0x70, 0x9c, 0xfc, 0x5a, 0x43, 0xfa, - 0x1b, 0x6b, 0xf4, 0x28, 0xc7, 0x08, 0x83, 0x8b, 0x37, 0xfd, 0x44, 0x5c, 0xc6, 0x50, 0x1c, 0x63, - 0x8d, 0x41, 0xb1, 0x28, 0xe5, 0xb1, 0x1b, 0x74, 0x11, 0xc4, 0xe2, 0x14, 0xd0, 0x62, 0x37, 0x18, - 0x18, 0xcb, 0x72, 0xf4, 0x77, 0x1d, 0x28, 0x36, 0xc2, 0x70, 0x3b, 0x2e, 0x8f, 0xb3, 0xc5, 0x61, - 0x41, 0xa6, 0x16, 0x1c, 0x67, 0xe6, 0x12, 0x45, 0x6b, 0x5e, 0x2f, 0x2b, 0x32, 0xd8, 0xed, 0xbd, - 0xe9, 0x89, 0x15, 0x7f, 0x8b, 0x54, 0x77, 0xab, 0x4d, 0xc2, 0x20, 0x6f, 0xbe, 0xad, 0x41, 0x2e, - 0xee, 0x90, 0x20, 0xc1, 0xbc, 0x57, 0x53, 0x9f, 0x73, 0x00, 0x52, 0x44, 0x39, 0x4e, 0x52, 0x62, - 0x86, 0x15, 0x58, 0x50, 0xa8, 0x8d, 0xae, 0xe9, 0x5e, 0xd7, 0x7f, 0xe5, 0x40, 0x89, 0x0e, 0x4e, - 0xb2, 0xc0, 0xc7, 0x61, 0x28, 0xf1, 0xa2, 0x3a, 0x91, 0x8e, 0x02, 0xf5, 0x39, 0x36, 0x18, 0x14, - 0x8b, 0x52, 0x14, 0x40, 0x31, 0xf1, 0xe2, 0x6d, 0x29, 0xc6, 0x5f, 0xb6, 0x36, 0xc5, 0xa9, 0x04, - 0x4f, 0x7f, 0xc5, 0x98, 0x93, 0x41, 0x4f, 0xc0, 0x08, 0x3d, 0x3a, 0x16, 0xbd, 0x58, 0xc6, 0xee, - 0x8c, 0x51, 0x26, 0xbe, 0x28, 0x60, 0x58, 0x95, 0xba, 0xbf, 0x51, 0x80, 0xc1, 0x05, 0xae, 0xd0, - 0x0d, 0xc5, 0x61, 0x27, 0xaa, 0x12, 0x21, 0xd8, 0x5b, 0x58, 0xd3, 0x14, 0x6f, 0x85, 0xe1, 0xd4, - 0x54, 0x2a, 0xf6, 0x1b, 0x0b, 0x5a, 0xe8, 0x4b, 0x0e, 0x4c, 0x24, 0x91, 0x17, 0xc4, 0x5b, 0xcc, - 0x25, 0xe3, 0x87, 0x81, 0x98, 0x22, 0x0b, 0xab, 0x70, 0xc3, 0xc0, 0x5b, 0x49, 0x48, 0x3b, 0xf5, - 0x0c, 0x99, 0x65, 0x38, 0xd3, 0x07, 0xf7, 0x37, 0x1d, 0x80, 0xb4, 0xf7, 0xe8, 0xb3, 0x0e, 0x8c, - 0x7b, 0x7a, 0xcc, 0xa8, 0x98, 0xa3, 0x35, 0x7b, 0xfe, 0x5b, 0x86, 0x96, 0xdb, 0x32, 0x0c, 0x10, - 0x36, 0x09, 0xbb, 0xef, 0x86, 0x22, 0xdb, 0x1d, 0x4c, 0xe9, 0x11, 0xb6, 0xef, 0xac, 0xb1, 0x4b, - 0xda, 0xc4, 0xb1, 0xaa, 0xe1, 0xbe, 0x04, 0x13, 0x17, 0x6f, 0x92, 0x6a, 0x27, 0x09, 0x23, 0x6e, - 0xf9, 0xef, 0x71, 0x47, 0xc8, 0xb9, 0xab, 0x3b, 0x42, 0xdf, 0x71, 0xa0, 0xa4, 0x05, 0x10, 0xd2, - 0x93, 0xba, 0x3e, 0x5f, 0xe1, 0x06, 0x0e, 0x31, 0x55, 0xcb, 0x56, 0x42, 0x14, 0x39, 0xca, 0xf4, - 0x18, 0x51, 0x20, 0x9c, 0x12, 0xbc, 0x43, 0x80, 0x9f, 0xfb, 0x07, 0x0e, 0x9c, 0xca, 0x8d, 0x76, - 0xbc, 0xcf, 0xdd, 0x36, 0x9c, 0xec, 0x85, 0x3e, 0x9c, 0xec, 0xbf, 0xe3, 0x40, 0x8a, 0x89, 0xb2, - 0xa2, 0xcd, 0xb4, 0xe7, 0x1a, 0x2b, 0x12, 0x94, 0x44, 0x29, 0x7a, 0x1d, 0xce, 0x98, 0x5f, 0xf0, - 0x2e, 0xfd, 0x2d, 0x5c, 0x39, 0xcd, 0xc7, 0x84, 0x7b, 0x91, 0x70, 0xbf, 0xe6, 0x40, 0x71, 0xc9, - 0xeb, 0xd4, 0x49, 0x5f, 0xe6, 0x32, 0xca, 0xc7, 0x22, 0xe2, 0x35, 0x13, 0xa9, 0x3a, 0x08, 0x3e, - 0x86, 0x05, 0x0c, 0xab, 0x52, 0x34, 0x0b, 0xa3, 0x61, 0x9b, 0x18, 0x3e, 0xc2, 0x47, 0xe5, 0xec, - 0xad, 0xc9, 0x02, 0x7a, 0xec, 0x30, 0xea, 0x0a, 0x82, 0xd3, 0x56, 0xee, 0x0f, 0x8a, 0x50, 0xd2, - 0xee, 0xc5, 0x50, 0x59, 0x20, 0x22, 0xed, 0x30, 0x2b, 0x2f, 0xd3, 0x05, 0x83, 0x59, 0x09, 0xdd, - 0x83, 0x11, 0xd9, 0xf1, 0x63, 0xce, 0xb6, 0x8c, 0x3d, 0x88, 0x05, 0x1c, 0xab, 0x1a, 0x68, 0x1a, - 0x8a, 0x35, 0xd2, 0x4e, 0x1a, 0xac, 0x7b, 0x83, 0x3c, 0x38, 0x70, 0x81, 0x02, 0x30, 0x87, 0xd3, - 0x0a, 0x5b, 0x24, 0xa9, 0x36, 0x98, 0x65, 0x58, 0x44, 0x0f, 0x2e, 0x52, 0x00, 0xe6, 0xf0, 0x1c, - 0x2f, 0x66, 0xf1, 0xf0, 0xbd, 0x98, 0x43, 0x96, 0xbd, 0x98, 0xa8, 0x0d, 0x27, 0xe2, 0xb8, 0xb1, - 0x1e, 0xf9, 0x3b, 0x5e, 0x42, 0xd2, 0xd5, 0x37, 0x7c, 0x10, 0x3a, 0x67, 0xd8, 0x4d, 0xf5, 0xca, - 0xa5, 0x2c, 0x16, 0x9c, 0x87, 0x1a, 0x55, 0xe0, 0x94, 0x1f, 0xc4, 0xa4, 0xda, 0x89, 0xc8, 0xe5, - 0x7a, 0x10, 0x46, 0xe4, 0x52, 0x18, 0x53, 0x74, 0xe2, 0x9e, 0xad, 0x8a, 0xa7, 0xbd, 0x9c, 0x57, - 0x09, 0xe7, 0xb7, 0x45, 0x4b, 0x70, 0xbc, 0xe6, 0xc7, 0xde, 0x66, 0x93, 0x54, 0x3a, 0x9b, 0xad, - 0x90, 0xab, 0xe6, 0xa3, 0x0c, 0xe1, 0x83, 0xd2, 0x8e, 0xb4, 0x90, 0xad, 0x80, 0xbb, 0xdb, 0xa0, - 0x67, 0x61, 0x2c, 0xf6, 0x83, 0x7a, 0x93, 0xcc, 0x45, 0x5e, 0x50, 0x6d, 0x88, 0x0b, 0xba, 0xca, - 0xde, 0x5e, 0xd1, 0xca, 0xb0, 0x51, 0x93, 0xed, 0x79, 0xde, 0x26, 0x23, 0x0d, 0x8a, 0xda, 0xa2, - 0xd4, 0xfd, 0xa1, 0x03, 0x63, 0x7a, 0x2c, 0x3b, 0x95, 0xb4, 0xa1, 0xb1, 0xb0, 0x58, 0xe1, 0x67, - 0x81, 0xbd, 0x13, 0xff, 0x92, 0xc2, 0x99, 0x2a, 0xcb, 0x29, 0x0c, 0x6b, 0x34, 0xfb, 0xb8, 0x99, - 0xfe, 0x28, 0x14, 0xb7, 0x42, 0x2a, 0x90, 0x0c, 0x98, 0x86, 0xfa, 0x45, 0x0a, 0xc4, 0xbc, 0xcc, - 0xfd, 0x6f, 0x0e, 0x9c, 0xce, 0x0f, 0xd3, 0xff, 0x59, 0x18, 0xe4, 0x05, 0x00, 0x3a, 0x14, 0x83, - 0xa9, 0x6b, 0xb9, 0x29, 0x64, 0x09, 0xd6, 0x6a, 0xf5, 0x37, 0xec, 0x7f, 0x59, 0x00, 0x8d, 0x26, - 0xfa, 0xbc, 0x03, 0xe3, 0x94, 0xec, 0x72, 0xb4, 0x69, 0x8c, 0x76, 0xcd, 0xce, 0x68, 0x15, 0xda, - 0xd4, 0x1f, 0x61, 0x80, 0xb1, 0x49, 0x1c, 0xfd, 0x02, 0x8c, 0x7a, 0xb5, 0x5a, 0x44, 0xe2, 0x58, - 0x79, 0xf6, 0x98, 0xb5, 0x6a, 0x56, 0x02, 0x71, 0x5a, 0x4e, 0x99, 0x68, 0xa3, 0xb6, 0x15, 0x53, - 0xbe, 0x24, 0x18, 0xb7, 0x62, 0xa2, 0x94, 0x08, 0x85, 0x63, 0x55, 0x03, 0x5d, 0x83, 0xd3, 0x35, - 0x2f, 0xf1, 0xb8, 0xfc, 0x46, 0xa2, 0xf5, 0x28, 0x4c, 0x48, 0x95, 0x31, 0x7d, 0x1e, 0x81, 0x7a, - 0x4e, 0xb4, 0x3d, 0xbd, 0x90, 0x5b, 0x0b, 0xf7, 0x68, 0xed, 0xfe, 0xea, 0x20, 0x98, 0x63, 0x42, - 0x35, 0x38, 0xb6, 0x1d, 0x6d, 0xce, 0xb3, 0x80, 0x8b, 0xbb, 0x09, 0x7c, 0x60, 0x01, 0x09, 0xcb, - 0x26, 0x06, 0x9c, 0x45, 0x29, 0xa8, 0x2c, 0x93, 0xdd, 0xc4, 0xdb, 0xbc, 0xeb, 0xb0, 0x87, 0x65, - 0x13, 0x03, 0xce, 0xa2, 0x44, 0xef, 0x86, 0xd2, 0x76, 0xb4, 0x29, 0x59, 0x7f, 0x36, 0x86, 0x66, - 0x39, 0x2d, 0xc2, 0x7a, 0x3d, 0xfa, 0x69, 0xb6, 0xa3, 0x4d, 0x7a, 0xda, 0xca, 0x0c, 0x10, 0xea, - 0xd3, 0x2c, 0x0b, 0x38, 0x56, 0x35, 0x50, 0x1b, 0xd0, 0xb6, 0x9c, 0x3d, 0x15, 0x5e, 0x22, 0x4e, - 0xa8, 0xfe, 0xa3, 0x53, 0x58, 0x5c, 0xff, 0x72, 0x17, 0x1e, 0x9c, 0x83, 0x1b, 0xbd, 0x00, 0x67, - 0xb6, 0xa3, 0x4d, 0x21, 0x84, 0xac, 0x47, 0x7e, 0x50, 0xf5, 0xdb, 0x46, 0xb6, 0x87, 0x69, 0xd1, - 0xdd, 0x33, 0xcb, 0xf9, 0xd5, 0x70, 0xaf, 0xf6, 0xee, 0xef, 0x0e, 0x02, 0xbb, 0xa7, 0x4a, 0x79, - 0x6c, 0x8b, 0x24, 0x8d, 0xb0, 0x96, 0x95, 0xab, 0x56, 0x19, 0x14, 0x8b, 0x52, 0x19, 0xbd, 0x5a, - 0xe8, 0x11, 0xbd, 0x7a, 0x03, 0x86, 0x1b, 0xc4, 0xab, 0x91, 0x48, 0x5a, 0x26, 0x57, 0xec, 0xdc, - 0xac, 0xbd, 0xc4, 0x90, 0xa6, 0xea, 0x3d, 0xff, 0x1d, 0x63, 0x49, 0x0d, 0xbd, 0x07, 0x26, 0xa8, - 0x80, 0x14, 0x76, 0x12, 0xe9, 0x5c, 0xe0, 0x96, 0x49, 0x76, 0x52, 0x6f, 0x18, 0x25, 0x38, 0x53, - 0x13, 0x2d, 0xc0, 0xa4, 0x70, 0x04, 0x28, 0x8b, 0xa7, 0x98, 0x58, 0x95, 0x86, 0xa3, 0x92, 0x29, - 0xc7, 0x5d, 0x2d, 0x58, 0xf4, 0x61, 0x58, 0xe3, 0xbe, 0x60, 0x3d, 0xfa, 0x30, 0xac, 0xed, 0x62, - 0x56, 0x82, 0x5e, 0x85, 0x11, 0xfa, 0x77, 0x31, 0x0a, 0x5b, 0xc2, 0xe6, 0xb3, 0x6e, 0x67, 0x76, - 0x28, 0x0d, 0xa1, 0x81, 0x32, 0xc1, 0x71, 0x4e, 0x50, 0xc1, 0x8a, 0x1e, 0xd5, 0x83, 0xe4, 0xf9, - 0x5e, 0xd9, 0xf6, 0xdb, 0xd7, 0x48, 0xe4, 0x6f, 0xed, 0x32, 0x61, 0x64, 0x24, 0xd5, 0x83, 0x2e, - 0x77, 0xd5, 0xc0, 0x39, 0xad, 0xdc, 0xcf, 0x17, 0x60, 0x4c, 0xbf, 0xee, 0x7c, 0xa7, 0x90, 0xe6, - 0x38, 0x5d, 0x14, 0x5c, 0xeb, 0xbd, 0x64, 0x61, 0xd8, 0x77, 0x5a, 0x10, 0x0d, 0x18, 0xf4, 0x3a, - 0x42, 0x0a, 0xb5, 0x62, 0x5c, 0x63, 0x23, 0xee, 0x24, 0x0d, 0x7e, 0x2f, 0x8e, 0x05, 0x1b, 0x33, - 0x0a, 0xee, 0xa7, 0x06, 0x60, 0x44, 0x16, 0xa2, 0x4f, 0x3a, 0x00, 0x69, 0xd0, 0x97, 0x60, 0xa5, - 0xeb, 0x36, 0x22, 0x82, 0xf4, 0x78, 0x35, 0xcd, 0x46, 0xaf, 0xe0, 0x58, 0xa3, 0x8b, 0x12, 0x18, - 0x0a, 0x69, 0xe7, 0x2e, 0xd8, 0xbb, 0xb2, 0xbf, 0x46, 0x09, 0x5f, 0x60, 0xd4, 0x53, 0x73, 0x1c, - 0x83, 0x61, 0x41, 0x8b, 0x6a, 0x96, 0x9b, 0x32, 0x16, 0xd1, 0x9e, 0xe9, 0x5a, 0x85, 0x37, 0xa6, - 0x8a, 0xa2, 0x02, 0xe1, 0x94, 0xa0, 0xfb, 0x34, 0x4c, 0x98, 0x9b, 0x81, 0x6a, 0x1a, 0x9b, 0xbb, - 0x09, 0xe1, 0x76, 0x8c, 0x31, 0xae, 0x69, 0xcc, 0x51, 0x00, 0xe6, 0x70, 0xf7, 0xfb, 0x0e, 0x40, - 0xca, 0x5e, 0xfa, 0x70, 0x1d, 0x3c, 0xaa, 0x1b, 0xe1, 0x7a, 0xa9, 0x73, 0x1f, 0x83, 0x51, 0xf6, - 0x0f, 0xdb, 0xe8, 0x03, 0xb6, 0x22, 0x07, 0xd2, 0x7e, 0x8a, 0xad, 0xce, 0x64, 0x8d, 0x6b, 0x92, - 0x10, 0x4e, 0x69, 0xba, 0x21, 0x4c, 0x66, 0x6b, 0xa3, 0x0f, 0xc2, 0x58, 0x2c, 0x8f, 0xd5, 0xf4, - 0xf2, 0x5e, 0x9f, 0xc7, 0x2f, 0xf7, 0xdb, 0x69, 0xcd, 0xb1, 0x81, 0xcc, 0x5d, 0x83, 0x21, 0xab, - 0x53, 0xe8, 0x7e, 0xdb, 0x81, 0x51, 0xe6, 0x3a, 0xad, 0x47, 0x5e, 0x2b, 0x6d, 0x32, 0xb0, 0xcf, - 0xac, 0xc7, 0x30, 0xcc, 0x75, 0x7f, 0x19, 0x72, 0x64, 0x81, 0xcb, 0xf0, 0x4c, 0x7b, 0x29, 0x97, - 0xe1, 0x46, 0x86, 0x18, 0x4b, 0x4a, 0xee, 0xa7, 0x0b, 0x30, 0x74, 0x39, 0x68, 0x77, 0xfe, 0xd2, - 0x67, 0x7b, 0x5b, 0x85, 0xc1, 0xcb, 0x09, 0x69, 0x99, 0x49, 0x09, 0xc7, 0xe6, 0x1e, 0xd3, 0x13, - 0x12, 0x96, 0xcd, 0x84, 0x84, 0xd8, 0xbb, 0x21, 0x23, 0xf2, 0x84, 0xed, 0x39, 0xbd, 0xc0, 0xf8, - 0x14, 0x8c, 0xae, 0x78, 0x9b, 0xa4, 0xb9, 0x4c, 0x76, 0xd9, 0x75, 0x43, 0x1e, 0x1d, 0xe2, 0xa4, - 0x06, 0x03, 0x23, 0x92, 0x63, 0x01, 0x26, 0x58, 0x6d, 0xb5, 0x19, 0xa8, 0x46, 0x42, 0xd2, 0x8c, - 0x4e, 0x8e, 0xa9, 0x91, 0x68, 0xd9, 0x9c, 0xb4, 0x5a, 0xee, 0x0c, 0x94, 0x52, 0x2c, 0x7d, 0x50, - 0xfd, 0x69, 0x01, 0xc6, 0x0d, 0x13, 0xba, 0xe1, 0x58, 0x74, 0xee, 0xe8, 0x58, 0x34, 0x1c, 0x7d, - 0x85, 0xfb, 0xed, 0xe8, 0x1b, 0x38, 0x7a, 0x47, 0x9f, 0xf9, 0x91, 0x06, 0xfb, 0xfa, 0x48, 0x4d, - 0x18, 0x5c, 0xf1, 0x83, 0xed, 0xfe, 0xf8, 0x4c, 0x5c, 0x0d, 0xdb, 0x5d, 0x7c, 0xa6, 0x42, 0x81, - 0x98, 0x97, 0x49, 0xc9, 0x65, 0x20, 0x5f, 0x72, 0x71, 0x3f, 0xe9, 0xc0, 0xd8, 0xaa, 0x17, 0xf8, - 0x5b, 0x24, 0x4e, 0xd8, 0xba, 0x4a, 0x0e, 0xf5, 0xda, 0xd9, 0x58, 0x8f, 0x04, 0x0a, 0x6f, 0x3a, - 0x70, 0x7c, 0x95, 0xb4, 0x42, 0xff, 0x55, 0x2f, 0x0d, 0x78, 0xa5, 0x7d, 0x6f, 0xf8, 0x89, 0x88, - 0xef, 0x53, 0x7d, 0xbf, 0xe4, 0x27, 0x98, 0xc2, 0xef, 0x60, 0x1f, 0x66, 0x17, 0x3a, 0xa8, 0x82, - 0xa6, 0x5d, 0x85, 0x4c, 0x43, 0x59, 0x65, 0x01, 0x4e, 0xeb, 0xb8, 0xbf, 0xe7, 0xc0, 0x30, 0xef, - 0x84, 0x8a, 0x11, 0x76, 0x7a, 0xe0, 0x6e, 0x40, 0x91, 0xb5, 0x13, 0xab, 0x7a, 0xc9, 0x82, 0xf8, - 0x43, 0xd1, 0xf1, 0x3d, 0xc8, 0xfe, 0xc5, 0x9c, 0x00, 0x53, 0x5b, 0xbc, 0x9b, 0xb3, 0x2a, 0xd6, - 0x37, 0x55, 0x5b, 0x18, 0x14, 0x8b, 0x52, 0xf7, 0xeb, 0x03, 0x30, 0xa2, 0xf2, 0x86, 0xb1, 0xac, - 0x0e, 0x41, 0x10, 0x26, 0x1e, 0x8f, 0xa1, 0xe0, 0xbc, 0xfa, 0x83, 0xf6, 0xf2, 0x96, 0xcd, 0xcc, - 0xa6, 0xd8, 0xb9, 0x5f, 0x50, 0x29, 0xa1, 0x5a, 0x09, 0xd6, 0x3b, 0x81, 0x3e, 0x0a, 0x43, 0x4d, - 0xca, 0x7d, 0x24, 0xeb, 0xbe, 0x66, 0xb1, 0x3b, 0x8c, 0xad, 0x89, 0x9e, 0xa8, 0x19, 0xe2, 0x40, - 0x2c, 0xa8, 0x4e, 0xbd, 0x0f, 0x26, 0xb3, 0xbd, 0xbe, 0xd3, 0x4d, 0xcd, 0x51, 0xfd, 0x9e, 0xe7, - 0x5f, 0x15, 0xdc, 0xf3, 0xe0, 0x4d, 0xdd, 0xe7, 0xa1, 0xb4, 0x4a, 0x92, 0xc8, 0xaf, 0x32, 0x04, - 0x77, 0x5a, 0x5c, 0x7d, 0xc9, 0x0f, 0x9f, 0x61, 0x8b, 0x95, 0xe2, 0x8c, 0xd1, 0xeb, 0x00, 0xed, - 0x28, 0xa4, 0xfa, 0x2b, 0xe9, 0xc8, 0x8f, 0x6d, 0x41, 0x1e, 0x5e, 0x57, 0x38, 0xb9, 0x2b, 0x3b, - 0xfd, 0x8d, 0x35, 0x7a, 0xee, 0x8b, 0x50, 0x5c, 0xed, 0x24, 0xe4, 0x66, 0x1f, 0x1c, 0xeb, 0xa0, - 0xa9, 0x0b, 0xdc, 0x0f, 0xc2, 0x18, 0xc3, 0x7d, 0x29, 0x6c, 0xd2, 0x63, 0x95, 0x4e, 0x4d, 0x8b, - 0xfe, 0xce, 0x3a, 0x1b, 0x58, 0x25, 0xcc, 0xcb, 0xe8, 0x96, 0x69, 0x84, 0xcd, 0x9a, 0xba, 0xc6, - 0xa5, 0x16, 0xc4, 0x25, 0x06, 0xc5, 0xa2, 0xd4, 0xfd, 0x44, 0x01, 0x4a, 0xac, 0xa1, 0x60, 0x37, - 0xbb, 0x30, 0xdc, 0xe0, 0x74, 0xc4, 0x1c, 0x5a, 0x08, 0x0e, 0xd3, 0x7b, 0xaf, 0xe9, 0x72, 0x1c, - 0x80, 0x25, 0x3d, 0x4a, 0xfa, 0x86, 0xe7, 0x27, 0x94, 0x74, 0xe1, 0x70, 0x49, 0x5f, 0xe7, 0x64, - 0xb0, 0xa4, 0xe7, 0xfe, 0x32, 0xb0, 0xeb, 0xd1, 0x8b, 0x4d, 0xaf, 0xce, 0x67, 0x2e, 0xdc, 0x26, - 0x35, 0xc1, 0x73, 0xb5, 0x99, 0xa3, 0x50, 0x2c, 0x4a, 0xf9, 0x95, 0xd3, 0x24, 0xf2, 0x55, 0x58, - 0xb5, 0x76, 0xe5, 0x94, 0x81, 0x65, 0x10, 0x7d, 0xcd, 0xfd, 0x72, 0x01, 0x80, 0x65, 0x99, 0xe3, - 0xb7, 0x9a, 0x7f, 0x51, 0x46, 0x40, 0x99, 0x0e, 0x4a, 0x15, 0x01, 0xc5, 0xee, 0x6d, 0xeb, 0x91, - 0x4f, 0xfa, 0x6d, 0x87, 0xc2, 0xfe, 0xb7, 0x1d, 0x50, 0x1b, 0x86, 0xc3, 0x4e, 0x42, 0x65, 0x55, - 0x71, 0xd8, 0x5b, 0xf0, 0xcf, 0xaf, 0x71, 0x84, 0xfc, 0x8a, 0x80, 0xf8, 0x81, 0x25, 0x19, 0xf4, - 0x2c, 0x8c, 0xb4, 0xa3, 0xb0, 0x4e, 0xcf, 0x6e, 0x71, 0xbc, 0x3f, 0x24, 0xe5, 0xa1, 0x75, 0x01, - 0xbf, 0xad, 0xfd, 0x8f, 0x55, 0x6d, 0xf7, 0x8f, 0x27, 0xf9, 0xbc, 0x88, 0xb5, 0x37, 0x05, 0x05, - 0x5f, 0x5a, 0xa6, 0x40, 0xa0, 0x28, 0x5c, 0x5e, 0xc0, 0x05, 0xbf, 0xa6, 0xf6, 0x55, 0xa1, 0xe7, - 0xbe, 0x7a, 0x37, 0x94, 0x6a, 0x7e, 0xdc, 0x6e, 0x7a, 0xbb, 0x57, 0x72, 0xcc, 0x82, 0x0b, 0x69, - 0x11, 0xd6, 0xeb, 0xa1, 0xa7, 0xc4, 0xdd, 0x96, 0x41, 0xc3, 0x14, 0x24, 0xef, 0xb6, 0xa4, 0xb7, - 0xe6, 0xf9, 0xb5, 0x96, 0x6c, 0x76, 0x81, 0x62, 0xdf, 0xd9, 0x05, 0xb2, 0x92, 0xd8, 0xd0, 0xd1, - 0x4b, 0x62, 0xef, 0x85, 0x71, 0xf9, 0x93, 0x89, 0x47, 0xe5, 0x93, 0xac, 0xf7, 0xca, 0x0c, 0xbe, - 0xa1, 0x17, 0x62, 0xb3, 0x6e, 0xba, 0x68, 0x87, 0xfb, 0x5d, 0xb4, 0x17, 0x00, 0x36, 0xc3, 0x4e, - 0x50, 0xf3, 0xa2, 0xdd, 0xcb, 0x0b, 0x22, 0x12, 0x56, 0x09, 0x7e, 0x73, 0xaa, 0x04, 0x6b, 0xb5, - 0xf4, 0x85, 0x3e, 0x7a, 0x87, 0x85, 0xfe, 0x41, 0x18, 0x65, 0x51, 0xc3, 0xa4, 0x36, 0x9b, 0x88, - 0xd0, 0xa5, 0x83, 0x84, 0x62, 0xa6, 0xc1, 0x8c, 0x12, 0x09, 0x4e, 0xf1, 0xa1, 0x0f, 0x01, 0x6c, - 0xf9, 0x81, 0x1f, 0x37, 0x18, 0xf6, 0xd2, 0x81, 0xb1, 0xab, 0x71, 0x2e, 0x2a, 0x2c, 0x58, 0xc3, - 0x88, 0x5e, 0x82, 0xe3, 0x24, 0x4e, 0xfc, 0x96, 0x97, 0x90, 0x9a, 0xba, 0x0d, 0x5a, 0x66, 0xb6, - 0x4c, 0x15, 0xb7, 0x7d, 0x31, 0x5b, 0xe1, 0x76, 0x1e, 0x10, 0x77, 0x23, 0x32, 0x76, 0xe4, 0xd4, - 0x41, 0x76, 0x24, 0xfa, 0x9f, 0x0e, 0x1c, 0x8f, 0x08, 0x8f, 0x67, 0x89, 0x55, 0xc7, 0x4e, 0x31, - 0x76, 0x5c, 0xb5, 0x91, 0xc0, 0x5d, 0x65, 0x6a, 0xc1, 0x59, 0x2a, 0x5c, 0x70, 0x21, 0x72, 0xf4, - 0x5d, 0xe5, 0xb7, 0xf3, 0x80, 0x6f, 0xbe, 0x3d, 0x3d, 0xdd, 0xfd, 0x90, 0x80, 0x42, 0x4e, 0x77, - 0xde, 0xdf, 0x7c, 0x7b, 0x7a, 0x52, 0xfe, 0x4e, 0x27, 0xad, 0x6b, 0x90, 0xf4, 0x58, 0x6d, 0x87, - 0xb5, 0xcb, 0xeb, 0x22, 0xc6, 0x4c, 0x1d, 0xab, 0xeb, 0x14, 0x88, 0x79, 0x19, 0x7a, 0x02, 0x46, - 0x6a, 0x1e, 0x69, 0x85, 0x81, 0x4a, 0xc5, 0xcb, 0xa4, 0xf9, 0x05, 0x01, 0xc3, 0xaa, 0x94, 0xea, - 0x10, 0x81, 0x38, 0x52, 0xca, 0x67, 0x6d, 0xe9, 0x10, 0xf2, 0x90, 0xe2, 0x54, 0xe5, 0x2f, 0xac, - 0x28, 0xa1, 0x26, 0x0c, 0xf9, 0xcc, 0x50, 0x21, 0xc2, 0x58, 0x2d, 0x58, 0x47, 0xb8, 0xe1, 0x43, - 0x06, 0xb1, 0x32, 0xd6, 0x2f, 0x68, 0xe8, 0x67, 0xcd, 0xb1, 0xa3, 0x39, 0x6b, 0x9e, 0x80, 0x91, - 0x6a, 0xc3, 0x6f, 0xd6, 0x22, 0x12, 0x94, 0x27, 0x99, 0xc6, 0xce, 0x66, 0x62, 0x5e, 0xc0, 0xb0, - 0x2a, 0x45, 0x7f, 0x05, 0xc6, 0xc3, 0x4e, 0xc2, 0x58, 0x0b, 0x9d, 0xa7, 0xb8, 0x7c, 0x9c, 0x55, - 0x67, 0x41, 0x49, 0x6b, 0x7a, 0x01, 0x36, 0xeb, 0x51, 0x16, 0xdf, 0x08, 0x63, 0x96, 0x54, 0x88, - 0xb1, 0xf8, 0xd3, 0x26, 0x8b, 0xbf, 0xa4, 0x95, 0x61, 0xa3, 0x26, 0xfa, 0xaa, 0x03, 0xc7, 0x5b, - 0x59, 0x05, 0xae, 0x7c, 0x86, 0xcd, 0x4c, 0xc5, 0x86, 0xa0, 0x9f, 0x41, 0xcd, 0xc3, 0xc9, 0xbb, - 0xc0, 0xb8, 0xbb, 0x13, 0x2c, 0xbd, 0x57, 0xbc, 0x1b, 0x54, 0x1b, 0x51, 0x18, 0x98, 0xdd, 0x7b, - 0xd0, 0xd6, 0xa5, 0x36, 0xb6, 0xb7, 0xf3, 0x48, 0xcc, 0x3d, 0x78, 0x6b, 0x6f, 0xfa, 0x54, 0x6e, - 0x11, 0xce, 0xef, 0xd4, 0xd4, 0x02, 0x9c, 0xce, 0xe7, 0x0f, 0x77, 0xd2, 0x38, 0x06, 0x74, 0x8d, - 0x63, 0x11, 0x1e, 0xec, 0xd9, 0x29, 0x7a, 0xd2, 0x48, 0x69, 0xd3, 0x31, 0x4f, 0x9a, 0x2e, 0xe9, - 0x70, 0x02, 0xc6, 0xf4, 0x97, 0x27, 0xdc, 0xff, 0x33, 0x00, 0x90, 0xda, 0xc9, 0x91, 0x07, 0x13, - 0xdc, 0x26, 0x7f, 0x79, 0xe1, 0xae, 0xaf, 0xe3, 0xcf, 0x1b, 0x08, 0x70, 0x06, 0x21, 0x6a, 0x01, - 0xe2, 0x10, 0xfe, 0xfb, 0x6e, 0x7c, 0xab, 0xcc, 0x15, 0x39, 0xdf, 0x85, 0x04, 0xe7, 0x20, 0xa6, - 0x23, 0x4a, 0xc2, 0x6d, 0x12, 0x5c, 0xc5, 0x2b, 0x77, 0x93, 0xd3, 0x81, 0x7b, 0xe3, 0x0c, 0x04, - 0x38, 0x83, 0x10, 0xb9, 0x30, 0xc4, 0x6c, 0x33, 0x32, 0xf0, 0x9b, 0xb1, 0x17, 0x26, 0x69, 0xc4, - 0x58, 0x94, 0xa0, 0x2f, 0x3b, 0x30, 0x21, 0x53, 0x53, 0x30, 0x6b, 0xa8, 0x0c, 0xf9, 0xbe, 0x6a, - 0xcb, 0xcf, 0x71, 0x51, 0xc7, 0x9e, 0x06, 0x54, 0x1a, 0xe0, 0x18, 0x67, 0x3a, 0xe1, 0xbe, 0x00, - 0x27, 0x72, 0x9a, 0x5b, 0xd1, 0x68, 0xbf, 0xe3, 0x40, 0x49, 0xcb, 0x98, 0x88, 0x5e, 0x87, 0xd1, - 0xb0, 0x62, 0x3d, 0x8a, 0x6f, 0xad, 0xd2, 0x15, 0xc5, 0xa7, 0x40, 0x38, 0x25, 0xd8, 0x4f, 0xf0, - 0x61, 0x6e, 0x7a, 0xc7, 0xfb, 0xdc, 0xed, 0x03, 0x07, 0x1f, 0xfe, 0x6a, 0x11, 0x52, 0x4c, 0x07, - 0x4c, 0x99, 0x92, 0x86, 0x2a, 0x16, 0xf6, 0x0d, 0x55, 0xac, 0xc1, 0x31, 0x8f, 0xf9, 0x92, 0xef, - 0x32, 0x51, 0x0a, 0x4f, 0x98, 0x6b, 0x62, 0xc0, 0x59, 0x94, 0x94, 0x4a, 0x9c, 0x36, 0x65, 0x54, - 0x06, 0x0f, 0x4c, 0xa5, 0x62, 0x62, 0xc0, 0x59, 0x94, 0xe8, 0x25, 0x28, 0x57, 0xd9, 0xc5, 0x5f, - 0x3e, 0xc6, 0xcb, 0x5b, 0x57, 0xc2, 0x64, 0x3d, 0x22, 0x31, 0x09, 0x12, 0x91, 0x12, 0xed, 0x11, - 0x31, 0x0b, 0xe5, 0xf9, 0x1e, 0xf5, 0x70, 0x4f, 0x0c, 0x54, 0x4d, 0x61, 0xce, 0x68, 0x3f, 0xd9, - 0x65, 0x4c, 0x44, 0x78, 0xe9, 0x95, 0x9a, 0x52, 0xd1, 0x0b, 0xb1, 0x59, 0x17, 0xfd, 0x8a, 0x03, - 0xe3, 0x4d, 0x69, 0xae, 0xc7, 0x9d, 0xa6, 0xcc, 0xef, 0x89, 0xad, 0x2c, 0xbf, 0x15, 0x1d, 0x33, - 0x97, 0x25, 0x0c, 0x10, 0x36, 0x69, 0x67, 0xb3, 0xd6, 0x8c, 0xf4, 0x99, 0xb5, 0xe6, 0xfb, 0x0e, - 0x4c, 0x66, 0xa9, 0xa1, 0x6d, 0x78, 0xb8, 0xe5, 0x45, 0xdb, 0x97, 0x83, 0xad, 0x88, 0x5d, 0xf0, - 0x48, 0xf8, 0x62, 0x98, 0xdd, 0x4a, 0x48, 0xb4, 0xe0, 0xed, 0x72, 0xf7, 0x67, 0x51, 0x3d, 0x10, - 0xf5, 0xf0, 0xea, 0x7e, 0x95, 0xf1, 0xfe, 0xb8, 0x50, 0x05, 0x4e, 0xd1, 0x0a, 0x2c, 0xa9, 0x9d, - 0x1f, 0x06, 0x29, 0x91, 0x02, 0x23, 0xa2, 0x82, 0x0c, 0x57, 0xf3, 0x2a, 0xe1, 0xfc, 0xb6, 0xee, - 0x45, 0x18, 0xe2, 0xf7, 0xed, 0xee, 0xc9, 0x7f, 0xe4, 0xfe, 0x9b, 0x02, 0x48, 0xc1, 0xf0, 0x2f, - 0xb7, 0x3b, 0x8e, 0x1e, 0xa2, 0x11, 0x33, 0x29, 0x09, 0x6b, 0x07, 0x3b, 0x44, 0x45, 0xfa, 0x48, - 0x51, 0x42, 0x25, 0x66, 0x72, 0xd3, 0x4f, 0xe6, 0xc3, 0x9a, 0xb4, 0x71, 0x30, 0x89, 0xf9, 0xa2, - 0x80, 0x61, 0x55, 0xea, 0x7e, 0xd2, 0x81, 0x71, 0x3a, 0xca, 0x66, 0x93, 0x34, 0x2b, 0x09, 0x69, - 0xc7, 0x28, 0x86, 0x62, 0x4c, 0xff, 0xb1, 0x67, 0x0a, 0x4c, 0xef, 0x68, 0x92, 0xb6, 0xe6, 0xac, - 0xa1, 0x44, 0x30, 0xa7, 0xe5, 0xbe, 0x35, 0x00, 0xa3, 0x6a, 0xb2, 0xfb, 0xb0, 0xa7, 0x5e, 0x48, - 0x33, 0xbb, 0x72, 0x0e, 0x5c, 0xd6, 0xb2, 0xba, 0xde, 0xa6, 0x53, 0x17, 0xec, 0xf2, 0x14, 0x17, - 0x69, 0x8a, 0xd7, 0xa7, 0x4c, 0x57, 0xf3, 0x69, 0x7d, 0xfd, 0x69, 0xf5, 0x85, 0xcf, 0xf9, 0xa6, - 0xee, 0xe9, 0x1f, 0xb4, 0x75, 0x9a, 0x29, 0x37, 0x66, 0x6f, 0x17, 0x7f, 0xe6, 0xd1, 0x9f, 0x62, - 0x5f, 0x8f, 0xfe, 0x3c, 0x09, 0x83, 0x24, 0xe8, 0xb4, 0x98, 0xa8, 0x34, 0xca, 0x54, 0x84, 0xc1, - 0x8b, 0x41, 0xa7, 0x65, 0x8e, 0x8c, 0x55, 0x41, 0xef, 0x83, 0x52, 0x8d, 0xc4, 0xd5, 0xc8, 0x67, - 0x79, 0x1b, 0x84, 0x65, 0xe7, 0x21, 0x66, 0x2e, 0x4b, 0xc1, 0x66, 0x43, 0xbd, 0x81, 0xfb, 0x2a, - 0x0c, 0xad, 0x37, 0x3b, 0x75, 0x3f, 0x40, 0x6d, 0x18, 0xe2, 0x59, 0x1c, 0xc4, 0x69, 0x6f, 0x41, - 0xef, 0xe4, 0xac, 0x42, 0x8b, 0x42, 0xe1, 0x57, 0x75, 0x05, 0x1d, 0xf7, 0x13, 0x05, 0xa0, 0xaa, - 0xf9, 0xd2, 0x3c, 0xfa, 0xeb, 0x5d, 0x6f, 0xdc, 0xfc, 0x5c, 0xce, 0x1b, 0x37, 0xe3, 0xac, 0x72, - 0xce, 0xf3, 0x36, 0x4d, 0x18, 0x67, 0xce, 0x11, 0x79, 0x06, 0x0a, 0xb1, 0xfa, 0x99, 0x3e, 0x13, - 0x1f, 0xe8, 0x4d, 0xc5, 0x89, 0xa0, 0x83, 0xb0, 0x89, 0x1c, 0xad, 0xc2, 0x09, 0x9e, 0x20, 0x74, - 0x81, 0x34, 0xbd, 0xdd, 0x4c, 0x22, 0xb0, 0xb3, 0xf2, 0xd9, 0xb2, 0x85, 0xee, 0x2a, 0x38, 0xaf, - 0x9d, 0xfb, 0xfb, 0x83, 0xa0, 0xb9, 0x24, 0xfa, 0xd8, 0x2d, 0xaf, 0x64, 0x1c, 0x50, 0xab, 0x56, - 0x1c, 0x50, 0xd2, 0xab, 0xc3, 0x39, 0x90, 0xe9, 0x73, 0xa2, 0x9d, 0x6a, 0x90, 0x66, 0x5b, 0x8c, - 0x51, 0x75, 0xea, 0x12, 0x69, 0xb6, 0x31, 0x2b, 0x51, 0x17, 0x15, 0x07, 0x7b, 0x5e, 0x54, 0x6c, - 0x40, 0xb1, 0xee, 0x75, 0xea, 0x44, 0x44, 0x60, 0x5a, 0xf0, 0x35, 0xb2, 0xab, 0x13, 0xdc, 0xd7, - 0xc8, 0xfe, 0xc5, 0x9c, 0x00, 0xdd, 0xec, 0x0d, 0x19, 0x92, 0x22, 0x8c, 0xb4, 0x16, 0x36, 0xbb, - 0x8a, 0x72, 0xe1, 0x9b, 0x5d, 0xfd, 0xc4, 0x29, 0x31, 0xd4, 0x86, 0xe1, 0x2a, 0x4f, 0xbf, 0x22, - 0x64, 0x96, 0xcb, 0x36, 0x6e, 0x62, 0x32, 0x84, 0xdc, 0x9a, 0x22, 0x7e, 0x60, 0x49, 0xc6, 0x3d, - 0x0f, 0x25, 0xed, 0xa9, 0x0d, 0xfa, 0x19, 0x54, 0xe6, 0x0f, 0xed, 0x33, 0x2c, 0x78, 0x89, 0x87, - 0x59, 0x89, 0xfb, 0xcd, 0x41, 0x50, 0xb6, 0x34, 0xfd, 0xde, 0xa0, 0x57, 0xd5, 0xf2, 0x14, 0x19, - 0x77, 0xe8, 0xc3, 0x00, 0x8b, 0x52, 0x2a, 0xd7, 0xb5, 0x48, 0x54, 0x57, 0x7a, 0xb4, 0x60, 0xd7, - 0x4a, 0xae, 0x5b, 0xd5, 0x0b, 0xb1, 0x59, 0x97, 0x0a, 0xe5, 0x2d, 0xe1, 0xa2, 0xcf, 0x06, 0x56, - 0x4b, 0xd7, 0x3d, 0x56, 0x35, 0x58, 0xa2, 0x83, 0x96, 0xe6, 0xd1, 0x17, 0x81, 0x98, 0x36, 0x1c, - 0x4a, 0x1a, 0x56, 0x1e, 0x30, 0xa5, 0x43, 0xb0, 0x41, 0x15, 0x2d, 0xc1, 0xf1, 0x98, 0x24, 0x6b, - 0x37, 0x02, 0x12, 0xa9, 0x14, 0x03, 0x22, 0x93, 0x86, 0xba, 0x55, 0x51, 0xc9, 0x56, 0xc0, 0xdd, - 0x6d, 0x72, 0x63, 0x57, 0x8b, 0x07, 0x8e, 0x5d, 0x5d, 0x80, 0xc9, 0x2d, 0xcf, 0x6f, 0x76, 0x22, - 0xd2, 0x33, 0x02, 0x76, 0x31, 0x53, 0x8e, 0xbb, 0x5a, 0xb0, 0x8b, 0x3d, 0x4d, 0xaf, 0x1e, 0x97, - 0x87, 0xb5, 0x8b, 0x3d, 0x14, 0x80, 0x39, 0xdc, 0xfd, 0x2d, 0x07, 0x78, 0x0a, 0xa3, 0xd9, 0xad, - 0x2d, 0x3f, 0xf0, 0x93, 0x5d, 0xf4, 0x35, 0x07, 0x26, 0x83, 0xb0, 0x46, 0x66, 0x83, 0xc4, 0x97, - 0x40, 0x7b, 0x79, 0xe5, 0x19, 0xad, 0x2b, 0x19, 0xf4, 0x3c, 0x1f, 0x46, 0x16, 0x8a, 0xbb, 0xba, - 0xe1, 0x9e, 0x81, 0x53, 0xb9, 0x08, 0xdc, 0xef, 0x0f, 0x80, 0x99, 0x89, 0x09, 0x3d, 0x0f, 0xc5, - 0x26, 0xcb, 0x0d, 0xe2, 0xdc, 0x65, 0x8a, 0x2d, 0x36, 0x57, 0x3c, 0x79, 0x08, 0xc7, 0x84, 0x16, - 0xa0, 0xc4, 0xd2, 0x3b, 0x89, 0xcc, 0x2d, 0x05, 0x23, 0x25, 0x42, 0x09, 0xa7, 0x45, 0xb7, 0xcd, - 0x9f, 0x58, 0x6f, 0x86, 0x5e, 0x83, 0xe1, 0x4d, 0x9e, 0xe4, 0xd2, 0x9e, 0xcf, 0x4f, 0x64, 0xcd, - 0x64, 0xb2, 0x91, 0x4c, 0xa1, 0x79, 0x3b, 0xfd, 0x17, 0x4b, 0x8a, 0x68, 0x17, 0x46, 0x3c, 0xf9, - 0x4d, 0x07, 0x6d, 0x5d, 0xd4, 0x30, 0xd6, 0x8f, 0x88, 0x98, 0x91, 0xdf, 0x50, 0x91, 0xcb, 0x84, - 0x16, 0x15, 0xfb, 0x0a, 0x2d, 0xfa, 0xb6, 0x03, 0x90, 0xbe, 0x08, 0x82, 0x6e, 0xc2, 0x48, 0xfc, - 0x8c, 0x61, 0xa8, 0xb0, 0x71, 0x43, 0x5f, 0x60, 0xd4, 0x6e, 0xb1, 0x0a, 0x08, 0x56, 0xd4, 0xee, - 0x64, 0x5c, 0xf9, 0xa9, 0x03, 0x27, 0xf3, 0x5e, 0x2e, 0xb9, 0x8f, 0x3d, 0x3e, 0xa8, 0x5d, 0x45, - 0x34, 0x58, 0x8f, 0xc8, 0x96, 0x7f, 0x33, 0x27, 0xd5, 0x32, 0x2f, 0xc0, 0x69, 0x1d, 0xf7, 0x4f, - 0x87, 0x41, 0x11, 0x3e, 0x24, 0x3b, 0xcc, 0xe3, 0x54, 0x67, 0xaa, 0xa7, 0x32, 0x97, 0xaa, 0x87, - 0x19, 0x14, 0x8b, 0x52, 0xaa, 0x37, 0xc9, 0xa0, 0x78, 0xc1, 0xb2, 0xd9, 0x2a, 0x94, 0xc1, 0xf3, - 0x58, 0x95, 0xe6, 0x59, 0x76, 0x8a, 0x47, 0x62, 0xd9, 0x19, 0xb2, 0x6f, 0xd9, 0x69, 0x01, 0x8a, - 0xf9, 0x46, 0x61, 0xe6, 0x14, 0x41, 0x68, 0xec, 0xc0, 0x86, 0xe6, 0x4a, 0x17, 0x12, 0x9c, 0x83, - 0x98, 0xc5, 0x50, 0x84, 0x4d, 0x32, 0x8b, 0xaf, 0x08, 0xe5, 0x23, 0x8d, 0xa1, 0xe0, 0x60, 0x2c, - 0xcb, 0xef, 0xd2, 0x94, 0x82, 0x7e, 0xc7, 0xd9, 0xc7, 0x56, 0x35, 0x6a, 0xeb, 0x08, 0xca, 0x4d, - 0x83, 0xc7, 0x34, 0xa9, 0xbb, 0x31, 0x80, 0x7d, 0xdd, 0x81, 0xe3, 0x24, 0xa8, 0x46, 0xbb, 0x0c, - 0x8f, 0xc0, 0x26, 0x5c, 0xdc, 0x57, 0x6d, 0xec, 0xf5, 0x8b, 0x59, 0xe4, 0xdc, 0x93, 0xd4, 0x05, - 0xc6, 0xdd, 0xdd, 0x40, 0x6b, 0x30, 0x52, 0xf5, 0xc4, 0xba, 0x28, 0x1d, 0x64, 0x5d, 0x70, 0x47, - 0xdd, 0xac, 0x58, 0x0d, 0x0a, 0x89, 0xfb, 0xe3, 0x02, 0x9c, 0xc8, 0xe9, 0x12, 0xbb, 0xaf, 0xd5, - 0xa2, 0x1b, 0xe0, 0x72, 0x2d, 0xbb, 0xfd, 0x97, 0x05, 0x1c, 0xab, 0x1a, 0x68, 0x1d, 0x4e, 0x6e, - 0xb7, 0xe2, 0x14, 0xcb, 0x7c, 0x18, 0x24, 0xe4, 0xa6, 0x64, 0x06, 0xd2, 0xfd, 0x7d, 0x72, 0x39, - 0xa7, 0x0e, 0xce, 0x6d, 0x49, 0xa5, 0x25, 0x12, 0x78, 0x9b, 0x4d, 0x92, 0x16, 0x89, 0x5b, 0x8c, - 0x4a, 0x5a, 0xba, 0x98, 0x29, 0xc7, 0x5d, 0x2d, 0xd0, 0x67, 0x1d, 0x38, 0x1b, 0x93, 0x68, 0x87, - 0x44, 0x15, 0xbf, 0x46, 0xe6, 0x3b, 0x71, 0x12, 0xb6, 0x48, 0x74, 0x97, 0xd6, 0xd9, 0xe9, 0x5b, - 0x7b, 0xd3, 0x67, 0x2b, 0xbd, 0xb1, 0xe1, 0xfd, 0x48, 0xb9, 0x9f, 0x75, 0x60, 0xa2, 0xc2, 0x74, - 0x77, 0x25, 0xba, 0xdb, 0x4e, 0x84, 0xfa, 0xb8, 0xca, 0xbb, 0x91, 0x61, 0xc2, 0x66, 0xa6, 0x0c, - 0xf7, 0x65, 0x98, 0xac, 0x90, 0x96, 0xd7, 0x6e, 0xb0, 0x2b, 0xc8, 0x3c, 0xfc, 0xeb, 0x3c, 0x8c, - 0xc6, 0x12, 0x96, 0x7d, 0xfb, 0x48, 0x55, 0xc6, 0x69, 0x1d, 0xf4, 0x18, 0x0f, 0x55, 0x93, 0x17, - 0x8e, 0x46, 0xb9, 0x92, 0xc3, 0xe3, 0xdb, 0x62, 0x2c, 0xcb, 0xdc, 0xb7, 0x1c, 0x18, 0x4b, 0xdb, - 0x93, 0x2d, 0x54, 0x87, 0x63, 0x55, 0xed, 0xb2, 0x5e, 0x7a, 0x4d, 0xa2, 0xff, 0x7b, 0x7d, 0x3c, - 0x3f, 0xb3, 0x89, 0x04, 0x67, 0xb1, 0x1e, 0x3c, 0xd2, 0xef, 0x0b, 0x05, 0x38, 0xa6, 0xba, 0x2a, - 0xfc, 0x94, 0x6f, 0x64, 0x03, 0xf2, 0xb0, 0x8d, 0x0c, 0x42, 0xe6, 0xdc, 0xef, 0x13, 0x94, 0xf7, - 0x46, 0x36, 0x28, 0xef, 0x50, 0xc9, 0x77, 0xb9, 0x5e, 0xbf, 0x5d, 0x80, 0x11, 0x95, 0xcf, 0xe8, - 0x79, 0x28, 0x32, 0xcd, 0xf5, 0xde, 0xe4, 0x6f, 0xa6, 0x05, 0x63, 0x8e, 0x89, 0xa2, 0x64, 0x41, - 0x3f, 0x77, 0x9d, 0x35, 0x77, 0x94, 0xdb, 0x2f, 0xbd, 0x28, 0xc1, 0x1c, 0x13, 0x5a, 0x86, 0x01, - 0x12, 0xd4, 0x84, 0x20, 0x7e, 0x70, 0x84, 0xec, 0x95, 0xb2, 0x8b, 0x41, 0x0d, 0x53, 0x2c, 0x2c, - 0xa9, 0x1a, 0x97, 0xb7, 0x32, 0x6f, 0xd2, 0x08, 0x61, 0x4b, 0x94, 0xba, 0xef, 0x07, 0x23, 0xe1, - 0x9e, 0x48, 0xe4, 0x2f, 0x74, 0xbc, 0xee, 0x87, 0xc4, 0x84, 0x72, 0x97, 0xd6, 0x71, 0x7f, 0x65, - 0x00, 0x86, 0x2a, 0x9d, 0x4d, 0xaa, 0x93, 0x7c, 0xcb, 0x81, 0x13, 0x37, 0x32, 0x39, 0xa9, 0xd3, - 0x4d, 0x72, 0xd5, 0x9e, 0x11, 0x58, 0x8f, 0x5c, 0x53, 0xa6, 0xaf, 0x9c, 0x42, 0x9c, 0xd7, 0x1d, - 0x23, 0x2d, 0xec, 0xc0, 0xa1, 0xa4, 0x85, 0xbd, 0x79, 0xc8, 0x57, 0x37, 0xc6, 0x7b, 0x5d, 0xdb, - 0x70, 0x7f, 0xbf, 0x08, 0xc0, 0xbf, 0xc6, 0x5a, 0x3b, 0xe9, 0xc7, 0xac, 0xf7, 0x2c, 0x8c, 0xd5, - 0x49, 0x40, 0x22, 0x19, 0x97, 0x98, 0x79, 0x2f, 0x69, 0x49, 0x2b, 0xc3, 0x46, 0x4d, 0xa6, 0x43, - 0x05, 0x49, 0xb4, 0xcb, 0xe5, 0xec, 0xec, 0xf5, 0x0c, 0x55, 0x82, 0xb5, 0x5a, 0x68, 0xc6, 0xf0, - 0xba, 0x70, 0x07, 0xfe, 0xc4, 0x3e, 0x4e, 0x92, 0xf7, 0xc1, 0x84, 0x99, 0x43, 0x45, 0x48, 0x7b, - 0xca, 0xe1, 0x6e, 0xa6, 0x5e, 0xc1, 0x99, 0xda, 0x74, 0x17, 0xd4, 0xa2, 0x5d, 0xdc, 0x09, 0x84, - 0xd8, 0xa7, 0x76, 0xc1, 0x02, 0x83, 0x62, 0x51, 0xca, 0x92, 0x4f, 0xb0, 0x03, 0x90, 0xc3, 0x45, - 0x02, 0x8b, 0x34, 0xf9, 0x84, 0x56, 0x86, 0x8d, 0x9a, 0x94, 0x82, 0x30, 0x8b, 0x82, 0xb9, 0xcf, - 0x32, 0xb6, 0xcc, 0x36, 0x4c, 0x84, 0xa6, 0x39, 0x87, 0xcb, 0x40, 0xef, 0xea, 0x73, 0xe9, 0x19, - 0x6d, 0x79, 0xa0, 0x44, 0xc6, 0xfa, 0x93, 0xc1, 0x4f, 0xe5, 0x5e, 0xfd, 0x16, 0xc3, 0x98, 0x19, - 0xd6, 0xda, 0xf3, 0xa2, 0xc1, 0x3a, 0x9c, 0x6c, 0x87, 0xb5, 0xf5, 0xc8, 0x0f, 0x23, 0x3f, 0xd9, - 0x9d, 0x6f, 0x7a, 0x71, 0xcc, 0x16, 0xc6, 0xb8, 0x29, 0x0f, 0xad, 0xe7, 0xd4, 0xc1, 0xb9, 0x2d, - 0xa9, 0x42, 0xd4, 0x16, 0x40, 0x16, 0x5c, 0x56, 0xe4, 0x12, 0x9d, 0xac, 0x88, 0x55, 0xa9, 0x7b, - 0x02, 0x8e, 0x57, 0x3a, 0xed, 0x76, 0xd3, 0x27, 0x35, 0xe5, 0xd5, 0x70, 0xdf, 0x0f, 0xc7, 0x44, - 0xd2, 0x58, 0x25, 0x7d, 0x1c, 0x28, 0xc5, 0xb9, 0xfb, 0x1f, 0x07, 0xe0, 0x58, 0x26, 0x94, 0x07, - 0xbd, 0x96, 0x95, 0x19, 0xec, 0x24, 0x33, 0xd5, 0xa4, 0x05, 0x91, 0x99, 0x34, 0x4f, 0xfe, 0x68, - 0xc8, 0x38, 0x7c, 0x6b, 0xf7, 0x5f, 0x58, 0xb4, 0x3a, 0x3f, 0x52, 0x8c, 0x60, 0xfe, 0x8f, 0x02, - 0x28, 0xb2, 0xf2, 0xca, 0xbd, 0xed, 0x71, 0xb2, 0xfd, 0xab, 0x20, 0x31, 0xd6, 0x28, 0xa2, 0x00, - 0x86, 0x59, 0x47, 0x88, 0xbc, 0x74, 0x69, 0x6d, 0xac, 0x4c, 0x64, 0x5b, 0xe5, 0xb8, 0xb1, 0x24, - 0xe2, 0x7e, 0xa6, 0x00, 0xf9, 0xf1, 0x62, 0xe8, 0xa3, 0xdd, 0x1f, 0xfc, 0x79, 0x8b, 0x13, 0x21, - 0x02, 0xd6, 0x7a, 0x7f, 0xf3, 0xc0, 0xfc, 0xe6, 0xab, 0x96, 0xe6, 0x41, 0xd0, 0xed, 0xfa, 0xf2, - 0xee, 0xff, 0x70, 0xa0, 0xb4, 0xb1, 0xb1, 0xa2, 0xce, 0x75, 0x0c, 0xa7, 0x63, 0x9e, 0xcf, 0x80, - 0xb9, 0xd5, 0xe7, 0xc3, 0x56, 0x9b, 0x7b, 0xd9, 0x85, 0xf7, 0x9f, 0xe5, 0x2b, 0xae, 0xe4, 0xd6, - 0xc0, 0x3d, 0x5a, 0xa2, 0xcb, 0x70, 0x42, 0x2f, 0xa9, 0x68, 0xcf, 0x43, 0x16, 0x45, 0x6e, 0xa2, - 0xee, 0x62, 0x9c, 0xd7, 0x26, 0x8b, 0x4a, 0x58, 0x93, 0xd9, 0xf1, 0x9c, 0x83, 0x4a, 0x14, 0xe3, - 0xbc, 0x36, 0xee, 0x1a, 0x94, 0x36, 0xbc, 0x48, 0x0d, 0xfc, 0x03, 0x30, 0x59, 0x0d, 0x5b, 0xd2, - 0x8a, 0xb7, 0x42, 0x76, 0x48, 0x53, 0x0c, 0x99, 0xbf, 0xc9, 0x92, 0x29, 0xc3, 0x5d, 0xb5, 0xdd, - 0xff, 0x7a, 0x0e, 0xd4, 0xfd, 0xcc, 0x3e, 0x4e, 0xd4, 0xb6, 0x8a, 0xa4, 0x2d, 0x5a, 0x8e, 0xa4, - 0x55, 0x67, 0x4b, 0x26, 0x9a, 0x36, 0x49, 0xa3, 0x69, 0x87, 0x6c, 0x47, 0xd3, 0x2a, 0x09, 0xbb, - 0x2b, 0xa2, 0xf6, 0x2b, 0x0e, 0x8c, 0x05, 0x61, 0x8d, 0x28, 0xf7, 0xe7, 0x30, 0xdb, 0xe1, 0x2f, - 0xd9, 0xbb, 0x98, 0xc0, 0x23, 0x43, 0x05, 0x7a, 0x1e, 0xe5, 0xad, 0x8e, 0x64, 0xbd, 0x08, 0x1b, - 0xfd, 0x40, 0x8b, 0x9a, 0x5d, 0x99, 0xbb, 0x6f, 0x1e, 0xca, 0xd3, 0xcf, 0xee, 0x68, 0x24, 0xbe, - 0xa9, 0xc9, 0x89, 0xa3, 0xb6, 0xec, 0xa5, 0xf2, 0xd2, 0x9d, 0xe6, 0x85, 0x92, 0x29, 0xb7, 0x53, - 0xf9, 0xd1, 0x85, 0x21, 0x1e, 0x0e, 0x2e, 0xb2, 0x60, 0x31, 0xe7, 0x28, 0x0f, 0x15, 0xc7, 0xa2, - 0x04, 0x25, 0x32, 0xc4, 0xa2, 0x64, 0xeb, 0x01, 0x0d, 0x23, 0x84, 0x23, 0x3f, 0xc6, 0x02, 0x3d, - 0xa7, 0xeb, 0xfd, 0x63, 0xfd, 0xe8, 0xfd, 0xe3, 0x3d, 0x75, 0xfe, 0xcf, 0x3b, 0x30, 0x56, 0xd5, - 0x1e, 0xb4, 0x28, 0x3f, 0x61, 0xeb, 0xe1, 0xee, 0xbc, 0x77, 0x47, 0xb8, 0xcf, 0xcd, 0x78, 0x40, - 0xc3, 0xa0, 0xce, 0x52, 0x7f, 0x32, 0x23, 0x07, 0x13, 0x75, 0xac, 0x64, 0xe5, 0x30, 0x8d, 0x26, - 0x32, 0x54, 0x95, 0xc2, 0xb0, 0xa0, 0x85, 0x5e, 0x87, 0x11, 0x79, 0xa3, 0x40, 0x44, 0xde, 0x63, - 0x1b, 0x4e, 0x10, 0xd3, 0xd3, 0x2a, 0xf3, 0x05, 0x72, 0x28, 0x56, 0x14, 0x51, 0x03, 0x06, 0x6a, - 0x5e, 0x5d, 0xc4, 0xe0, 0xaf, 0xda, 0xc9, 0xc7, 0x2a, 0x69, 0x32, 0x7d, 0x74, 0x61, 0x76, 0x09, - 0x53, 0x12, 0xe8, 0x66, 0xfa, 0x22, 0xc0, 0xa4, 0xb5, 0xd3, 0xd7, 0x14, 0x0b, 0xb9, 0x4c, 0xd0, - 0xf5, 0xc0, 0x40, 0x4d, 0x38, 0xa7, 0xff, 0x3f, 0x46, 0x76, 0xd1, 0x4e, 0x42, 0x57, 0x9e, 0xe5, - 0x25, 0x75, 0x70, 0x53, 0x2a, 0x8d, 0x24, 0x69, 0x97, 0x7f, 0xde, 0x16, 0x15, 0x96, 0xab, 0x84, - 0xbf, 0xb1, 0xbe, 0xb1, 0xb1, 0x8e, 0x19, 0x76, 0xd4, 0x84, 0xa1, 0x36, 0x8b, 0x9b, 0x29, 0xff, - 0x82, 0xad, 0xb3, 0x85, 0xc7, 0xe1, 0xf0, 0xb5, 0xc9, 0xff, 0xc7, 0x82, 0x06, 0xba, 0x08, 0xc3, - 0xfc, 0x61, 0x1b, 0x7e, 0x07, 0xa2, 0x74, 0x61, 0xaa, 0xf7, 0xf3, 0x38, 0xe9, 0x41, 0xc1, 0x7f, - 0xc7, 0x58, 0xb6, 0x45, 0x5f, 0x70, 0x60, 0x82, 0x72, 0xd4, 0xf4, 0x25, 0x9e, 0x32, 0xb2, 0xc5, - 0xb3, 0xae, 0xc6, 0x54, 0x22, 0x91, 0xbc, 0x46, 0xa9, 0x85, 0x97, 0x0d, 0x72, 0x38, 0x43, 0x1e, - 0xbd, 0x01, 0x23, 0xb1, 0x5f, 0x23, 0x55, 0x2f, 0x8a, 0xcb, 0x27, 0x0e, 0xa7, 0x2b, 0xa9, 0x3b, - 0x4c, 0x10, 0xc2, 0x8a, 0x24, 0xfa, 0x75, 0xf6, 0x14, 0x6a, 0xb5, 0xe1, 0xef, 0x90, 0x95, 0xb0, - 0xca, 0xd5, 0x98, 0x93, 0xb6, 0xf6, 0xbe, 0x74, 0xfc, 0x49, 0xcc, 0xc2, 0x4b, 0x64, 0x92, 0xc3, - 0x59, 0xfa, 0xe8, 0x6f, 0x38, 0x70, 0x8a, 0x3f, 0x59, 0x90, 0x7d, 0x85, 0xe3, 0xd4, 0x5d, 0xda, - 0xa3, 0xd8, 0xe5, 0x8d, 0xd9, 0x3c, 0x94, 0x38, 0x9f, 0x12, 0x4b, 0x30, 0x6c, 0x3e, 0x9c, 0x74, - 0xda, 0xaa, 0x5b, 0xb8, 0xff, 0xc7, 0x92, 0xd0, 0xd3, 0x50, 0x6a, 0x8b, 0xe3, 0xd0, 0x8f, 0x5b, - 0xec, 0x2a, 0xce, 0x00, 0xbf, 0x24, 0xb9, 0x9e, 0x82, 0xb1, 0x5e, 0xc7, 0xc8, 0x36, 0xfd, 0xe4, - 0x7e, 0xd9, 0xa6, 0xd1, 0x55, 0x28, 0x25, 0x61, 0x53, 0x24, 0x5c, 0x8d, 0xcb, 0x65, 0xb6, 0x02, - 0xcf, 0xe5, 0xed, 0xad, 0x0d, 0x55, 0x2d, 0xd5, 0xdc, 0x53, 0x58, 0x8c, 0x75, 0x3c, 0x2c, 0xfc, - 0x59, 0x3c, 0x05, 0x11, 0x31, 0x95, 0xfd, 0xc1, 0x4c, 0xf8, 0xb3, 0x5e, 0x88, 0xcd, 0xba, 0x68, - 0x09, 0x8e, 0xb7, 0xbb, 0x74, 0x7e, 0x7e, 0x05, 0x50, 0x45, 0x9c, 0x74, 0x2b, 0xfc, 0xdd, 0x6d, - 0x0c, 0x6d, 0xff, 0xec, 0x7e, 0xda, 0x7e, 0x8f, 0xdc, 0xcb, 0x0f, 0xdd, 0x4d, 0xee, 0x65, 0x54, - 0x83, 0x87, 0xbc, 0x4e, 0x12, 0xb2, 0x7c, 0x3c, 0x66, 0x13, 0x1e, 0x09, 0xfe, 0x08, 0x0f, 0x2e, - 0xbf, 0xb5, 0x37, 0xfd, 0xd0, 0xec, 0x3e, 0xf5, 0xf0, 0xbe, 0x58, 0xd0, 0xab, 0x30, 0x42, 0x44, - 0xfe, 0xe8, 0xf2, 0xcf, 0xd9, 0x12, 0x12, 0xcc, 0x8c, 0xd4, 0x32, 0xc8, 0x96, 0xc3, 0xb0, 0xa2, - 0x87, 0x36, 0xa0, 0xd4, 0x08, 0xe3, 0x64, 0xb6, 0xe9, 0x7b, 0x31, 0x89, 0xcb, 0x0f, 0xb3, 0x45, - 0x93, 0x2b, 0x7b, 0x5d, 0x92, 0xd5, 0xd2, 0x35, 0x73, 0x29, 0x6d, 0x89, 0x75, 0x34, 0x88, 0x30, - 0xe7, 0x30, 0x0b, 0x83, 0x97, 0x8e, 0xaf, 0x73, 0x6c, 0x60, 0x8f, 0xe7, 0x61, 0x5e, 0x0f, 0x6b, - 0x15, 0xb3, 0xb6, 0xf2, 0x0e, 0xeb, 0x40, 0x9c, 0xc5, 0x89, 0x9e, 0x85, 0xb1, 0x76, 0x58, 0xab, - 0xb4, 0x49, 0x75, 0xdd, 0x4b, 0xaa, 0x8d, 0xf2, 0xb4, 0x69, 0x65, 0x5c, 0xd7, 0xca, 0xb0, 0x51, - 0x13, 0xb5, 0x61, 0xb8, 0xc5, 0x13, 0x35, 0x94, 0x1f, 0xb5, 0xa5, 0xdb, 0x88, 0xcc, 0x0f, 0xc2, - 0x86, 0xc0, 0x7f, 0x60, 0x49, 0x06, 0xfd, 0x7d, 0x07, 0x8e, 0x65, 0x2e, 0x97, 0x95, 0xdf, 0x61, - 0x4d, 0x64, 0x31, 0x11, 0xcf, 0x3d, 0xce, 0xa6, 0xcf, 0x04, 0xde, 0xee, 0x06, 0xe1, 0x6c, 0x8f, - 0xf8, 0xbc, 0xb0, 0x6c, 0x2b, 0xe5, 0xc7, 0xec, 0xcd, 0x0b, 0x43, 0x28, 0xe7, 0x85, 0xfd, 0xc0, - 0x92, 0x0c, 0x7a, 0x12, 0x86, 0x45, 0x62, 0xc4, 0xf2, 0xe3, 0xa6, 0xcb, 0x5d, 0xe4, 0x4f, 0xc4, - 0xb2, 0x7c, 0xea, 0xfd, 0x70, 0xbc, 0x4b, 0x75, 0x3b, 0x50, 0xca, 0x8f, 0xdf, 0x74, 0x40, 0xbf, - 0x8d, 0x6e, 0xfd, 0xd1, 0x96, 0x67, 0x61, 0xac, 0xca, 0xdf, 0xd0, 0xe4, 0xf7, 0xd9, 0x07, 0x4d, - 0x7b, 0xef, 0xbc, 0x56, 0x86, 0x8d, 0x9a, 0xee, 0x25, 0x40, 0xdd, 0x19, 0xf5, 0xef, 0x2a, 0x9f, - 0xd4, 0x3f, 0x74, 0x60, 0xdc, 0x90, 0x19, 0xac, 0x3b, 0x55, 0x17, 0x01, 0xb5, 0xfc, 0x28, 0x0a, - 0x23, 0xfd, 0xb1, 0x42, 0x91, 0x73, 0x82, 0x05, 0x5b, 0xac, 0x76, 0x95, 0xe2, 0x9c, 0x16, 0xee, - 0x3f, 0x1e, 0x84, 0x34, 0xca, 0x5c, 0xa5, 0x2c, 0x76, 0x7a, 0xa6, 0x2c, 0x7e, 0x0a, 0x46, 0x5e, - 0x8e, 0xc3, 0x60, 0x3d, 0x4d, 0x6c, 0xac, 0xbe, 0xc5, 0x73, 0x95, 0xb5, 0x2b, 0xac, 0xa6, 0xaa, - 0xc1, 0x6a, 0xbf, 0xb2, 0xe8, 0x37, 0x93, 0xee, 0xcc, 0xb7, 0xcf, 0x3d, 0xcf, 0xe1, 0x58, 0xd5, - 0x60, 0xef, 0x16, 0xee, 0x10, 0xe5, 0x08, 0x48, 0xdf, 0x2d, 0xe4, 0x8f, 0x65, 0xb0, 0x32, 0x74, - 0x1e, 0x46, 0x95, 0x13, 0x41, 0x78, 0x26, 0xd4, 0x4c, 0x29, 0x4f, 0x03, 0x4e, 0xeb, 0x30, 0x81, - 0x50, 0x18, 0x9e, 0x85, 0x09, 0xa5, 0x62, 0x43, 0x3d, 0xc9, 0x98, 0xb2, 0x39, 0x6f, 0x97, 0x60, - 0xac, 0x48, 0xe6, 0x39, 0x96, 0x47, 0x0f, 0xc5, 0xb1, 0xac, 0x5d, 0x79, 0x28, 0xf6, 0x7b, 0xe5, - 0xc1, 0x5c, 0xdb, 0x23, 0x7d, 0xad, 0xed, 0x4f, 0x0d, 0xc0, 0xf0, 0x35, 0x12, 0xb1, 0x84, 0xef, - 0x4f, 0xc2, 0xf0, 0x0e, 0xff, 0x37, 0x7b, 0x5f, 0x56, 0xd4, 0xc0, 0xb2, 0x9c, 0x7e, 0xb7, 0xcd, - 0x8e, 0xdf, 0xac, 0x2d, 0xa4, 0xbb, 0x38, 0xcd, 0xe9, 0x28, 0x0b, 0x70, 0x5a, 0x87, 0x36, 0xa8, - 0x53, 0xc9, 0xbe, 0xd5, 0xf2, 0xbb, 0x9e, 0xe4, 0x5f, 0x92, 0x05, 0x38, 0xad, 0x83, 0x1e, 0x87, - 0xa1, 0xba, 0x9f, 0x6c, 0x78, 0xf5, 0xac, 0x5b, 0x74, 0x89, 0x41, 0xb1, 0x28, 0x65, 0x6e, 0x31, - 0x3f, 0xd9, 0x88, 0x08, 0xb3, 0xec, 0x76, 0xa5, 0xeb, 0x58, 0xd2, 0xca, 0xb0, 0x51, 0x93, 0x75, - 0x29, 0x14, 0x23, 0x13, 0x41, 0xb2, 0x69, 0x97, 0x64, 0x01, 0x4e, 0xeb, 0xd0, 0xf5, 0x5f, 0x0d, - 0x5b, 0x6d, 0xbf, 0x29, 0xc2, 0xb7, 0xb5, 0xf5, 0x3f, 0x2f, 0xe0, 0x58, 0xd5, 0xa0, 0xb5, 0x29, - 0x0b, 0xa3, 0xec, 0x27, 0xfb, 0x46, 0xdc, 0xba, 0x80, 0x63, 0x55, 0xc3, 0xbd, 0x06, 0xe3, 0x7c, - 0x27, 0xcf, 0x37, 0x3d, 0xbf, 0xb5, 0x34, 0x8f, 0x2e, 0x76, 0x5d, 0x79, 0x78, 0x32, 0xe7, 0xca, - 0xc3, 0x29, 0xa3, 0x51, 0xf7, 0xd5, 0x07, 0xf7, 0x87, 0x05, 0x18, 0x39, 0xc2, 0x67, 0x36, 0x8f, - 0xfc, 0xc5, 0x68, 0x74, 0x33, 0xf3, 0xc4, 0xe6, 0xba, 0xcd, 0x1b, 0x4c, 0xfb, 0x3e, 0xaf, 0xf9, - 0x9f, 0x0a, 0x70, 0x5a, 0x56, 0x95, 0xba, 0xdc, 0xd2, 0x3c, 0x7b, 0xba, 0xec, 0xf0, 0x27, 0x3a, - 0x32, 0x26, 0x7a, 0xdd, 0x9e, 0x36, 0xba, 0x34, 0xdf, 0x73, 0xaa, 0x5f, 0xcd, 0x4c, 0x35, 0xb6, - 0x4a, 0x75, 0xff, 0xc9, 0xfe, 0x73, 0x07, 0xa6, 0xf2, 0x27, 0xfb, 0x08, 0x5e, 0x35, 0x7d, 0xc3, - 0x7c, 0xd5, 0xf4, 0x97, 0xec, 0x2d, 0x31, 0x73, 0x28, 0x3d, 0xde, 0x37, 0xfd, 0xef, 0x0e, 0x9c, - 0x94, 0x0d, 0xd8, 0xe9, 0x39, 0xe7, 0x07, 0x2c, 0x72, 0xe7, 0xf0, 0x97, 0xd9, 0xeb, 0xc6, 0x32, - 0x7b, 0xd1, 0xde, 0xc0, 0xf5, 0x71, 0xf4, 0x7c, 0x0d, 0xfe, 0xcf, 0x1c, 0x28, 0xe7, 0x35, 0x38, - 0x82, 0x4f, 0xfe, 0x9a, 0xf9, 0xc9, 0xaf, 0x1d, 0xce, 0xc8, 0x7b, 0x7f, 0xf0, 0x72, 0xaf, 0x89, - 0x42, 0x4d, 0x29, 0x57, 0x39, 0xb6, 0x7c, 0xd2, 0x9c, 0x44, 0xbe, 0x80, 0xd6, 0x84, 0xa1, 0x98, - 0x45, 0xa9, 0x88, 0x25, 0x70, 0xc9, 0x86, 0xb4, 0x45, 0xf1, 0x09, 0x1b, 0x3b, 0xfb, 0x1f, 0x0b, - 0x1a, 0xee, 0x6f, 0x15, 0xe0, 0x8c, 0x7a, 0xad, 0x98, 0xec, 0x90, 0x66, 0xba, 0x3f, 0xd8, 0xf3, - 0x18, 0x9e, 0xfa, 0x69, 0xef, 0x79, 0x8c, 0x94, 0x44, 0xba, 0x17, 0x52, 0x18, 0xd6, 0x68, 0xa2, - 0x0a, 0x9c, 0x62, 0xcf, 0x59, 0x2c, 0xfa, 0x81, 0xd7, 0xf4, 0x5f, 0x25, 0x11, 0x26, 0xad, 0x70, - 0xc7, 0x6b, 0x0a, 0x49, 0x5d, 0x5d, 0x99, 0x5e, 0xcc, 0xab, 0x84, 0xf3, 0xdb, 0x76, 0x69, 0xdc, - 0x03, 0xfd, 0x6a, 0xdc, 0xee, 0x9f, 0x38, 0x30, 0x76, 0x84, 0x6f, 0x3b, 0x87, 0xe6, 0x96, 0x78, - 0xce, 0xde, 0x96, 0xe8, 0xb1, 0x0d, 0xf6, 0x8a, 0xd0, 0xf5, 0xdc, 0x2d, 0xfa, 0xb4, 0xa3, 0xe2, - 0x78, 0x78, 0xb0, 0xe4, 0x87, 0xec, 0xf5, 0xe3, 0x20, 0x79, 0x36, 0xd1, 0xd7, 0x33, 0xc9, 0x47, - 0x0b, 0xb6, 0x32, 0x68, 0x75, 0xf5, 0xe6, 0x2e, 0x92, 0x90, 0x7e, 0xc5, 0x01, 0xe0, 0xfd, 0x14, - 0xb9, 0xcb, 0x69, 0xdf, 0x36, 0x0f, 0x6d, 0xa6, 0x28, 0x11, 0xde, 0x35, 0xb5, 0x85, 0xd2, 0x02, - 0xac, 0xf5, 0xe4, 0x1e, 0xb2, 0x8b, 0xde, 0x73, 0x62, 0xd3, 0x2f, 0x38, 0x70, 0x2c, 0xd3, 0xdd, - 0x9c, 0xf6, 0x5b, 0xe6, 0xeb, 0x8c, 0x16, 0x24, 0x2b, 0x33, 0xa3, 0xb5, 0x6e, 0x3c, 0xf9, 0x2f, - 0x2e, 0x18, 0xef, 0x84, 0xa3, 0xd7, 0x60, 0x54, 0x5a, 0x3e, 0xe4, 0xf2, 0xb6, 0xf9, 0x4a, 0xad, - 0x52, 0x6f, 0x24, 0x24, 0xc6, 0x29, 0xbd, 0x4c, 0x98, 0x60, 0xa1, 0xaf, 0x30, 0xc1, 0xfb, 0xfb, - 0xc6, 0x6d, 0xbe, 0x5d, 0x7a, 0xf0, 0x50, 0xec, 0xd2, 0x0f, 0x59, 0xb7, 0x4b, 0x3f, 0x7c, 0xc4, - 0x76, 0x69, 0xcd, 0x49, 0x58, 0xbc, 0x07, 0x27, 0xe1, 0x6b, 0x70, 0x72, 0x27, 0x55, 0x3a, 0xd5, - 0x4a, 0x12, 0x79, 0x9b, 0x9e, 0xcc, 0xb5, 0x46, 0x53, 0x05, 0x3a, 0x4e, 0x48, 0x90, 0x68, 0xea, - 0x6a, 0x1a, 0xa1, 0x78, 0x2d, 0x07, 0x1d, 0xce, 0x25, 0x92, 0xf5, 0xf6, 0x0c, 0xf7, 0xe1, 0xed, - 0x79, 0xcb, 0x81, 0x53, 0x5e, 0xd7, 0x1d, 0x3b, 0x4c, 0xb6, 0x44, 0xc8, 0xc9, 0x75, 0x7b, 0x22, - 0x84, 0x81, 0x5e, 0xb8, 0xd5, 0xf2, 0x8a, 0x70, 0x7e, 0x87, 0xd0, 0x63, 0xa9, 0xeb, 0x9d, 0xc7, - 0xb5, 0xe6, 0xfb, 0xc9, 0xbf, 0x9e, 0x8d, 0xe7, 0x01, 0x36, 0xf5, 0x1f, 0xb1, 0xab, 0x6d, 0x5b, - 0x88, 0xe9, 0x29, 0xdd, 0x43, 0x4c, 0x4f, 0xc6, 0xf5, 0x36, 0x66, 0xc9, 0xf5, 0x16, 0xc0, 0xa4, - 0xdf, 0xf2, 0xea, 0x64, 0xbd, 0xd3, 0x6c, 0xf2, 0x4b, 0x33, 0xf2, 0x1d, 0xe1, 0x5c, 0x0b, 0xde, - 0x4a, 0x58, 0xf5, 0x9a, 0xd9, 0x17, 0xe4, 0xd5, 0xe5, 0xa0, 0xcb, 0x19, 0x4c, 0xb8, 0x0b, 0x37, - 0x5d, 0xb0, 0x2c, 0x81, 0x20, 0x49, 0xe8, 0x6c, 0xb3, 0xc0, 0x91, 0x11, 0xbe, 0x60, 0x2f, 0xa5, - 0x60, 0xac, 0xd7, 0x41, 0xcb, 0x30, 0x5a, 0x0b, 0x62, 0x71, 0x5d, 0xf8, 0x18, 0x63, 0x66, 0xef, - 0xa4, 0x2c, 0x70, 0xe1, 0x4a, 0x45, 0x5d, 0x14, 0x7e, 0x28, 0x27, 0x23, 0xa6, 0x2a, 0xc7, 0x69, - 0x7b, 0xb4, 0xca, 0x90, 0x89, 0x47, 0xd6, 0x78, 0x3c, 0xc7, 0x23, 0x3d, 0x1c, 0x46, 0x0b, 0x57, - 0xe4, 0x33, 0x71, 0xe3, 0x82, 0x9c, 0x78, 0x2d, 0x2d, 0xc5, 0xa0, 0xbd, 0xe7, 0x7c, 0x7c, 0xdf, - 0xf7, 0x9c, 0x59, 0x2a, 0xdc, 0xa4, 0xa9, 0xdc, 0xc3, 0xe7, 0xac, 0xa5, 0xc2, 0x4d, 0x23, 0x25, - 0x45, 0x2a, 0xdc, 0x14, 0x80, 0x75, 0x92, 0x68, 0xad, 0x97, 0x9b, 0xfc, 0x04, 0x63, 0x1a, 0x07, - 0x77, 0x7a, 0xeb, 0xfe, 0xd2, 0x93, 0xfb, 0xfa, 0x4b, 0xbb, 0xfc, 0xbb, 0xa7, 0x0e, 0xe0, 0xdf, - 0x6d, 0xb0, 0x24, 0xa5, 0x4b, 0xf3, 0xc2, 0xa5, 0x6e, 0x41, 0xbf, 0x63, 0x69, 0x51, 0x78, 0xe4, - 0x29, 0xfb, 0x17, 0x73, 0x02, 0x3d, 0x03, 0xc8, 0xcf, 0xdc, 0x75, 0x00, 0x39, 0x65, 0xcf, 0x29, - 0x9c, 0x65, 0xbb, 0x2d, 0x0a, 0xf6, 0x9c, 0x82, 0xb1, 0x5e, 0x27, 0xeb, 0x2d, 0x7d, 0xf0, 0xd0, - 0xbc, 0xa5, 0x53, 0x47, 0xe0, 0x2d, 0x3d, 0xdb, 0xb7, 0xb7, 0xf4, 0x26, 0x9c, 0x68, 0x87, 0xb5, - 0x05, 0x3f, 0x8e, 0x3a, 0xec, 0x16, 0xe1, 0x5c, 0xa7, 0x56, 0x27, 0x09, 0x73, 0xb7, 0x96, 0x2e, - 0xbc, 0x53, 0xef, 0x64, 0x9b, 0x6d, 0x64, 0xb9, 0x47, 0x33, 0x0d, 0x98, 0xe9, 0x84, 0x45, 0xdd, - 0xe6, 0x14, 0xe2, 0x3c, 0x12, 0xba, 0x9f, 0xf6, 0x91, 0xa3, 0xf1, 0xd3, 0x7e, 0x00, 0x46, 0xe2, - 0x46, 0x27, 0xa9, 0x85, 0x37, 0x02, 0xe6, 0x8c, 0x1f, 0x9d, 0x7b, 0x87, 0x32, 0x65, 0x0b, 0xf8, - 0xed, 0xbd, 0xe9, 0x49, 0xf9, 0xbf, 0x66, 0xc5, 0x16, 0x10, 0xf4, 0x8d, 0x1e, 0xf7, 0x95, 0xdc, - 0xc3, 0xbc, 0xaf, 0x74, 0xe6, 0x40, 0x77, 0x95, 0xf2, 0x9c, 0xd1, 0x8f, 0xfe, 0xcc, 0x39, 0xa3, - 0xbf, 0xe6, 0xc0, 0xf8, 0x8e, 0xee, 0x32, 0x10, 0x0e, 0x73, 0x0b, 0x81, 0x3b, 0x86, 0x27, 0x62, - 0xce, 0xa5, 0x7c, 0xce, 0x00, 0xdd, 0xce, 0x02, 0xb0, 0xd9, 0x93, 0x9c, 0xa0, 0xa2, 0xc7, 0xee, - 0x57, 0x50, 0xd1, 0x1b, 0x8c, 0x8f, 0x49, 0x25, 0x97, 0x79, 0xd1, 0xed, 0xc6, 0x14, 0x4b, 0x9e, - 0xa8, 0x42, 0x8a, 0x75, 0x7a, 0xe8, 0xf3, 0x0e, 0x4c, 0x4a, 0xbd, 0x4c, 0xb8, 0xfc, 0x62, 0x11, - 0x15, 0x69, 0x53, 0x1d, 0x64, 0x61, 0xf5, 0x1b, 0x19, 0x3a, 0xb8, 0x8b, 0x32, 0xe5, 0xea, 0x2a, - 0x08, 0xad, 0x1e, 0xb3, 0xe0, 0x5f, 0x21, 0xc3, 0xcc, 0xa6, 0x60, 0xac, 0xd7, 0x41, 0xdf, 0x74, - 0xa0, 0xd8, 0x08, 0xc3, 0xed, 0xb8, 0xfc, 0x24, 0x63, 0xe8, 0x2f, 0x58, 0x96, 0x4d, 0x2f, 0x51, - 0xdc, 0x5c, 0x28, 0x7d, 0x5a, 0xda, 0x8e, 0x18, 0xec, 0xf6, 0xde, 0xf4, 0x84, 0xf1, 0x96, 0x53, - 0xfc, 0xe6, 0xdb, 0x1a, 0x44, 0xd8, 0x36, 0x59, 0xd7, 0xd0, 0x97, 0x1c, 0x98, 0xbc, 0x91, 0x31, - 0x68, 0x88, 0xb0, 0x50, 0x6c, 0xdf, 0x54, 0xc2, 0xa7, 0x3b, 0x0b, 0xc5, 0x5d, 0x3d, 0x40, 0x9f, - 0x33, 0x0d, 0x9d, 0x3c, 0x7e, 0xd4, 0xe2, 0x04, 0x66, 0x0c, 0xab, 0xfc, 0x5a, 0x50, 0xbe, 0xc5, - 0xf3, 0x9e, 0xe3, 0x43, 0xa6, 0xe8, 0x60, 0xd2, 0x8f, 0x95, 0xd3, 0x94, 0x98, 0xf6, 0x16, 0x0b, - 0x9b, 0xdd, 0xf8, 0xfc, 0xba, 0xb9, 0xe5, 0x4b, 0xa7, 0x61, 0xc2, 0xf4, 0xed, 0xa1, 0x77, 0x99, - 0xef, 0x74, 0x9c, 0xcb, 0x3e, 0x79, 0x30, 0x2e, 0xeb, 0x1b, 0xcf, 0x1e, 0x18, 0xef, 0x12, 0x14, - 0x0e, 0xf5, 0x5d, 0x82, 0x81, 0xa3, 0x79, 0x97, 0x60, 0xf2, 0x30, 0xde, 0x25, 0x38, 0x7e, 0xa0, - 0x77, 0x09, 0xb4, 0x77, 0x21, 0x06, 0xef, 0xf0, 0x2e, 0xc4, 0x2c, 0x1c, 0x93, 0x77, 0x7f, 0x88, - 0x48, 0xfd, 0xce, 0xdd, 0xfe, 0x67, 0x44, 0x93, 0x63, 0xf3, 0x66, 0x31, 0xce, 0xd6, 0xa7, 0x9b, - 0xac, 0x18, 0xb0, 0x96, 0x43, 0xb6, 0x1e, 0x8d, 0x32, 0x97, 0x16, 0x53, 0x9f, 0x05, 0x8b, 0x92, - 0xd1, 0xce, 0x45, 0x06, 0xbb, 0x2d, 0xff, 0xc1, 0xbc, 0x07, 0xe8, 0x25, 0x28, 0x87, 0x5b, 0x5b, - 0xcd, 0xd0, 0xab, 0xa5, 0x8f, 0x27, 0xc8, 0xb8, 0x04, 0x7e, 0x57, 0x55, 0xe5, 0xda, 0x5d, 0xeb, - 0x51, 0x0f, 0xf7, 0xc4, 0x80, 0xde, 0xa2, 0x82, 0x49, 0x12, 0x46, 0xa4, 0x96, 0xda, 0x6a, 0x46, - 0xd9, 0x98, 0x89, 0xf5, 0x31, 0x57, 0x4c, 0x3a, 0x7c, 0xf4, 0xea, 0xa3, 0x64, 0x4a, 0x71, 0xb6, - 0x5b, 0x28, 0x82, 0xd3, 0xed, 0x3c, 0x53, 0x51, 0x2c, 0x6e, 0x2c, 0xed, 0x67, 0xb0, 0x52, 0x0f, - 0x69, 0xe7, 0x1a, 0x9b, 0x62, 0xdc, 0x03, 0xb3, 0xfe, 0xc0, 0xc1, 0xc8, 0xd1, 0x3c, 0x70, 0xf0, - 0x31, 0x00, 0x75, 0x29, 0x5f, 0x1a, 0x1f, 0x96, 0xad, 0x5c, 0xa5, 0xe1, 0x38, 0xb5, 0x37, 0x65, - 0x15, 0x19, 0xac, 0x91, 0x44, 0xff, 0x3b, 0xf7, 0x05, 0x10, 0x6e, 0x61, 0xa9, 0x5b, 0x5f, 0x13, - 0x3f, 0x73, 0xaf, 0x80, 0xfc, 0x03, 0x07, 0xa6, 0xf8, 0xca, 0xcb, 0x0a, 0xf7, 0x54, 0xb4, 0x10, - 0x77, 0x7b, 0x6c, 0x87, 0xae, 0xf0, 0x94, 0x49, 0x06, 0x55, 0xe6, 0xe8, 0xde, 0xa7, 0x27, 0xe8, - 0x2b, 0x39, 0x2a, 0xc5, 0x31, 0x5b, 0x36, 0xcb, 0xfc, 0x77, 0x1c, 0x4e, 0xdc, 0xea, 0x47, 0x8b, - 0xf8, 0x47, 0x3d, 0x4d, 0xaa, 0x88, 0x75, 0xef, 0x97, 0x0f, 0xc9, 0xa4, 0xaa, 0x3f, 0x36, 0x71, - 0x20, 0xc3, 0xea, 0x17, 0x1c, 0x98, 0xf4, 0x32, 0xa1, 0x26, 0xcc, 0x0e, 0x64, 0xc5, 0x26, 0x35, - 0x1b, 0xa5, 0xf1, 0x2b, 0x4c, 0xc8, 0xcb, 0x46, 0xb5, 0xe0, 0x2e, 0xe2, 0xe8, 0x87, 0x0e, 0x9c, - 0x4d, 0xbc, 0x78, 0x9b, 0xa7, 0x72, 0x8e, 0xd3, 0xbb, 0xba, 0xa2, 0x73, 0x27, 0xd9, 0x6e, 0x7c, - 0xc5, 0xfa, 0x6e, 0xdc, 0xe8, 0x4d, 0x93, 0xef, 0xcb, 0x47, 0xc5, 0xbe, 0x3c, 0xbb, 0x4f, 0x4d, - 0xbc, 0x5f, 0xd7, 0xa7, 0x3e, 0xed, 0xf0, 0x27, 0xbf, 0x7a, 0x8a, 0x7c, 0x9b, 0xa6, 0xc8, 0xb7, - 0x62, 0xf3, 0xd1, 0x21, 0x5d, 0xf6, 0xfc, 0x35, 0x07, 0x4e, 0xe6, 0x9d, 0x48, 0x39, 0x5d, 0xfa, - 0x88, 0xd9, 0x25, 0x8b, 0x5a, 0x96, 0xde, 0x21, 0x2b, 0x6f, 0x9e, 0x4c, 0x5d, 0x81, 0x47, 0xee, - 0xf4, 0x15, 0xef, 0x84, 0x6f, 0x44, 0x17, 0x8b, 0xff, 0x6c, 0x54, 0xf3, 0x42, 0x26, 0xa4, 0x6d, - 0x3d, 0x86, 0x3b, 0x80, 0x21, 0x3f, 0x68, 0xfa, 0x01, 0x11, 0xf7, 0x35, 0x6d, 0xea, 0xb0, 0xe2, - 0xcd, 0x22, 0x8a, 0x1d, 0x0b, 0x2a, 0xf7, 0xd9, 0x29, 0x99, 0x7d, 0x05, 0x6e, 0xf0, 0xe8, 0x5f, - 0x81, 0xbb, 0x01, 0xa3, 0x37, 0xfc, 0xa4, 0xc1, 0x82, 0x29, 0x84, 0xaf, 0xcf, 0xc2, 0x3d, 0x47, - 0x8a, 0x2e, 0x1d, 0xfb, 0x75, 0x49, 0x00, 0xa7, 0xb4, 0xd0, 0x79, 0x4e, 0x98, 0x45, 0x6e, 0x67, - 0x43, 0x6a, 0xaf, 0xcb, 0x02, 0x9c, 0xd6, 0xa1, 0x93, 0x35, 0x46, 0x7f, 0xc9, 0x04, 0x50, 0x22, - 0x2d, 0xb2, 0x8d, 0x74, 0x97, 0x02, 0x23, 0xbf, 0x4d, 0x7c, 0x5d, 0xa3, 0x81, 0x0d, 0x8a, 0x2a, - 0x33, 0xf5, 0x48, 0xcf, 0xcc, 0xd4, 0xaf, 0x33, 0x81, 0x2d, 0xf1, 0x83, 0x0e, 0x59, 0x0b, 0x44, - 0xbc, 0xf7, 0x8a, 0x9d, 0xbb, 0xcf, 0x1c, 0x27, 0x57, 0xc1, 0xd3, 0xdf, 0x58, 0xa3, 0xa7, 0xb9, - 0x5c, 0x4a, 0xfb, 0xba, 0x5c, 0x52, 0x93, 0xcb, 0x98, 0x75, 0x93, 0x4b, 0x42, 0xda, 0x56, 0x4c, - 0x2e, 0x3f, 0x53, 0xe6, 0x80, 0x3f, 0x77, 0x00, 0x29, 0xb9, 0x4b, 0x31, 0xd4, 0x23, 0x08, 0xaa, - 0xfc, 0xb8, 0x03, 0x10, 0xa8, 0xb7, 0x42, 0xed, 0x9e, 0x82, 0x1c, 0x67, 0xda, 0x81, 0x14, 0x86, - 0x35, 0x9a, 0xee, 0x9f, 0x3a, 0x69, 0xec, 0x72, 0x3a, 0xf6, 0x23, 0x08, 0x22, 0xdb, 0x35, 0x83, - 0xc8, 0x36, 0x2c, 0x9a, 0xee, 0xd5, 0x30, 0x7a, 0x84, 0x93, 0xfd, 0xa4, 0x00, 0xc7, 0xf4, 0xca, - 0x15, 0x72, 0x14, 0x1f, 0xfb, 0x86, 0x11, 0x41, 0x7b, 0xd5, 0xee, 0x78, 0x2b, 0xc2, 0x03, 0x94, - 0x17, 0xad, 0xfd, 0xb1, 0x4c, 0xb4, 0xf6, 0x75, 0xfb, 0xa4, 0xf7, 0x0f, 0xd9, 0xfe, 0xcf, 0x0e, - 0x9c, 0xc8, 0xb4, 0x38, 0x82, 0x05, 0xb6, 0x63, 0x2e, 0xb0, 0xe7, 0xad, 0x8f, 0xba, 0xc7, 0xea, - 0xfa, 0x56, 0xa1, 0x6b, 0xb4, 0x4c, 0x89, 0xfb, 0x94, 0x03, 0x45, 0x2a, 0x2d, 0xcb, 0x78, 0xae, - 0x8f, 0x1c, 0xca, 0x0a, 0x60, 0x72, 0xbd, 0xe0, 0xce, 0xaa, 0x7f, 0x0c, 0x86, 0x39, 0xf5, 0xa9, - 0x4f, 0x3a, 0x00, 0x69, 0xa5, 0xfb, 0x25, 0x02, 0xbb, 0xdf, 0x29, 0xc0, 0xa9, 0xdc, 0x65, 0x84, - 0x3e, 0xa3, 0x2c, 0x72, 0x8e, 0xed, 0x68, 0x45, 0x83, 0x90, 0x6e, 0x98, 0x1b, 0x37, 0x0c, 0x73, - 0xc2, 0x1e, 0x77, 0xbf, 0x14, 0x18, 0xc1, 0xa6, 0xb5, 0xc9, 0xfa, 0xb1, 0x93, 0x06, 0xc0, 0xaa, - 0xbc, 0x46, 0x7f, 0x01, 0x2f, 0xf1, 0xb8, 0x3f, 0xd1, 0x6e, 0x38, 0xc8, 0x81, 0x1e, 0x01, 0xaf, - 0xb8, 0x61, 0xf2, 0x0a, 0x6c, 0xdf, 0x8f, 0xdc, 0x83, 0x59, 0xbc, 0x02, 0x79, 0x8e, 0xe5, 0xfe, - 0x92, 0x40, 0x1a, 0xd7, 0x61, 0x0b, 0x7d, 0x5f, 0x87, 0x1d, 0x87, 0xd2, 0x8b, 0xbe, 0xca, 0x1e, - 0x3a, 0x37, 0xf3, 0xdd, 0x1f, 0x9d, 0x7b, 0xe0, 0x7b, 0x3f, 0x3a, 0xf7, 0xc0, 0x0f, 0x7f, 0x74, - 0xee, 0x81, 0x8f, 0xdf, 0x3a, 0xe7, 0x7c, 0xf7, 0xd6, 0x39, 0xe7, 0x7b, 0xb7, 0xce, 0x39, 0x3f, - 0xbc, 0x75, 0xce, 0xf9, 0xb7, 0xb7, 0xce, 0x39, 0x7f, 0xeb, 0xdf, 0x9d, 0x7b, 0xe0, 0xc5, 0x11, - 0x39, 0xb0, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x78, 0xa3, 0xd3, 0x3a, 0x8f, 0xd8, 0x00, 0x00, + // 11144 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0xbd, 0x7d, 0x70, 0x24, 0xc7, + 0x75, 0x18, 0xce, 0x59, 0x60, 0xf1, 0xf1, 0x16, 0xc0, 0xe1, 0xfa, 0xbe, 0x96, 0x20, 0x79, 0xa0, + 0x87, 0x22, 0x7f, 0xa4, 0x4d, 0xe1, 0xcc, 0xa3, 0xf4, 0x0b, 0x23, 0x25, 0x92, 0xf0, 0x71, 0xc0, + 0x1d, 0x01, 0x1c, 0xc0, 0x5e, 0x1c, 0xcf, 0xa4, 0x68, 0x49, 0x83, 0xdd, 0xc6, 0xee, 0x10, 0xbb, + 0x33, 0xcb, 0x99, 0x59, 0xdc, 0x81, 0x1f, 0x92, 0x42, 0x7d, 0xc7, 0xb2, 0x15, 0xcb, 0x92, 0x2c, + 0x29, 0x49, 0x95, 0xa2, 0x48, 0x09, 0x4b, 0x76, 0x25, 0x65, 0xff, 0x95, 0xb2, 0xff, 0x4b, 0xa5, + 0x5c, 0x4a, 0x39, 0x95, 0xc8, 0x15, 0xa5, 0xa4, 0x3f, 0x6c, 0x30, 0xba, 0x24, 0xaa, 0x54, 0x12, + 0x55, 0xc5, 0xaa, 0x38, 0x89, 0x2f, 0x1f, 0x95, 0xea, 0xcf, 0xe9, 0x9e, 0x9d, 0xc5, 0x2d, 0x70, + 0x0d, 0x9c, 0xca, 0xfe, 0x0b, 0xd8, 0xd7, 0xaf, 0xdf, 0xeb, 0xee, 0xe9, 0x7e, 0xfd, 0xfa, 0xbd, + 0xd7, 0xaf, 0x61, 0xbd, 0xee, 0x27, 0x8d, 0xce, 0xe6, 0x4c, 0x35, 0x6c, 0x5d, 0xf0, 0xa2, 0x7a, + 0xd8, 0x8e, 0xc2, 0x97, 0xd9, 0x3f, 0xef, 0xbc, 0x11, 0x46, 0xdb, 0x5b, 0xcd, 0xf0, 0x46, 0x7c, + 0x61, 0xe7, 0xe9, 0x0b, 0xed, 0xed, 0xfa, 0x05, 0xaf, 0xed, 0xc7, 0x17, 0x24, 0xf4, 0xc2, 0xce, + 0x53, 0x5e, 0xb3, 0xdd, 0xf0, 0x9e, 0xba, 0x50, 0x27, 0x01, 0x89, 0xbc, 0x84, 0xd4, 0x66, 0xda, + 0x51, 0x98, 0x84, 0xe8, 0x03, 0x29, 0xc5, 0x19, 0x49, 0x91, 0xfd, 0xf3, 0x61, 0x45, 0x71, 0x66, + 0xe7, 0xe9, 0x99, 0xf6, 0x76, 0x7d, 0x86, 0x52, 0x9c, 0x91, 0xd0, 0x19, 0x49, 0x71, 0xea, 0x9d, + 0x5a, 0x9b, 0xea, 0x61, 0x3d, 0xbc, 0xc0, 0x08, 0x6f, 0x76, 0xb6, 0xd8, 0x2f, 0xf6, 0x83, 0xfd, + 0xc7, 0x19, 0x4e, 0xb9, 0xdb, 0xcf, 0xc4, 0x33, 0x7e, 0x48, 0xdb, 0x77, 0xa1, 0x1a, 0x46, 0xe4, + 0xc2, 0x4e, 0x57, 0xa3, 0xa6, 0xde, 0xa1, 0xe1, 0xb4, 0xc3, 0xa6, 0x5f, 0xdd, 0xcd, 0xc3, 0x7a, + 0x57, 0x8a, 0xd5, 0xf2, 0xaa, 0x0d, 0x3f, 0x20, 0xd1, 0x6e, 0xda, 0xf5, 0x16, 0x49, 0xbc, 0xbc, + 0x5a, 0x17, 0x7a, 0xd5, 0x8a, 0x3a, 0x41, 0xe2, 0xb7, 0x48, 0x57, 0x85, 0xff, 0xff, 0x4e, 0x15, + 0xe2, 0x6a, 0x83, 0xb4, 0xbc, 0xae, 0x7a, 0x4f, 0xf7, 0xaa, 0xd7, 0x49, 0xfc, 0xe6, 0x05, 0x3f, + 0x48, 0xe2, 0x24, 0xca, 0x56, 0x72, 0x2f, 0xc1, 0xd0, 0x6c, 0x2b, 0xec, 0x04, 0x09, 0x7a, 0x2f, + 0x14, 0x77, 0xbc, 0x66, 0x87, 0x94, 0x9d, 0x87, 0x9d, 0xc7, 0x47, 0xe7, 0x1e, 0xfd, 0xee, 0xde, + 0xf4, 0x7d, 0xb7, 0xf6, 0xa6, 0x8b, 0xcf, 0x53, 0xe0, 0xed, 0xbd, 0xe9, 0xd3, 0x24, 0xa8, 0x86, + 0x35, 0x3f, 0xa8, 0x5f, 0x78, 0x39, 0x0e, 0x83, 0x99, 0xab, 0x9d, 0xd6, 0x26, 0x89, 0x30, 0xaf, + 0xe3, 0xfe, 0xeb, 0x02, 0x9c, 0x98, 0x8d, 0xaa, 0x0d, 0x7f, 0x87, 0x54, 0x12, 0x4a, 0xbf, 0xbe, + 0x8b, 0x1a, 0x30, 0x90, 0x78, 0x11, 0x23, 0x57, 0xba, 0xb8, 0x3a, 0x73, 0xb7, 0xdf, 0x7d, 0x66, + 0xc3, 0x8b, 0x24, 0xed, 0xb9, 0xe1, 0x5b, 0x7b, 0xd3, 0x03, 0x1b, 0x5e, 0x84, 0x29, 0x0b, 0xd4, + 0x84, 0xc1, 0x20, 0x0c, 0x48, 0xb9, 0xc0, 0x58, 0x5d, 0xbd, 0x7b, 0x56, 0x57, 0xc3, 0x40, 0xf5, + 0x63, 0x6e, 0xe4, 0xd6, 0xde, 0xf4, 0x20, 0x85, 0x60, 0xc6, 0x85, 0xf6, 0xeb, 0x55, 0xbf, 0x5d, + 0x1e, 0xb0, 0xd5, 0xaf, 0x17, 0xfd, 0xb6, 0xd9, 0xaf, 0x17, 0xfd, 0x36, 0xa6, 0x2c, 0xdc, 0xcf, + 0x15, 0x60, 0x74, 0x36, 0xaa, 0x77, 0x5a, 0x24, 0x48, 0x62, 0xf4, 0x31, 0x80, 0xb6, 0x17, 0x79, + 0x2d, 0x92, 0x90, 0x28, 0x2e, 0x3b, 0x0f, 0x0f, 0x3c, 0x5e, 0xba, 0xb8, 0x7c, 0xf7, 0xec, 0xd7, + 0x25, 0xcd, 0x39, 0x24, 0x3e, 0x39, 0x28, 0x50, 0x8c, 0x35, 0x96, 0xe8, 0x35, 0x18, 0xf5, 0xa2, + 0xc4, 0xdf, 0xf2, 0xaa, 0x49, 0x5c, 0x2e, 0x30, 0xfe, 0xcf, 0xde, 0x3d, 0xff, 0x59, 0x41, 0x72, + 0xee, 0xa4, 0x60, 0x3f, 0x2a, 0x21, 0x31, 0x4e, 0xf9, 0xb9, 0xbf, 0x37, 0x08, 0xa5, 0xd9, 0x28, + 0x59, 0x9a, 0xaf, 0x24, 0x5e, 0xd2, 0x89, 0xd1, 0x1f, 0x3a, 0x70, 0x2a, 0xe6, 0xc3, 0xe6, 0x93, + 0x78, 0x3d, 0x0a, 0xab, 0x24, 0x8e, 0x49, 0x4d, 0x8c, 0xcb, 0x96, 0x95, 0x76, 0x49, 0x66, 0x33, + 0x95, 0x6e, 0x46, 0x97, 0x82, 0x24, 0xda, 0x9d, 0x7b, 0x4a, 0xb4, 0xf9, 0x54, 0x0e, 0xc6, 0x9b, + 0x6f, 0x4f, 0x23, 0xd9, 0x15, 0x4a, 0x89, 0x7f, 0x62, 0x9c, 0xd7, 0x6a, 0xf4, 0x35, 0x07, 0xc6, + 0xda, 0x61, 0x2d, 0xc6, 0xa4, 0x1a, 0x76, 0xda, 0xa4, 0x26, 0x86, 0xf7, 0xc3, 0x76, 0xbb, 0xb1, + 0xae, 0x71, 0xe0, 0xed, 0x3f, 0x2d, 0xda, 0x3f, 0xa6, 0x17, 0x61, 0xa3, 0x29, 0xe8, 0x19, 0x18, + 0x0b, 0xc2, 0xa4, 0xd2, 0x26, 0x55, 0x7f, 0xcb, 0x27, 0x35, 0x36, 0xf1, 0x47, 0xd2, 0x9a, 0x57, + 0xb5, 0x32, 0x6c, 0x60, 0x4e, 0x2d, 0x42, 0xb9, 0xd7, 0xc8, 0xa1, 0x49, 0x18, 0xd8, 0x26, 0xbb, + 0x5c, 0xd8, 0x60, 0xfa, 0x2f, 0x3a, 0x2d, 0x05, 0x10, 0x5d, 0xc6, 0x23, 0x42, 0xb2, 0xbc, 0xa7, + 0xf0, 0x8c, 0x33, 0xf5, 0x7e, 0x38, 0xd9, 0xd5, 0xf4, 0x83, 0x10, 0x70, 0xbf, 0x37, 0x04, 0x23, + 0xf2, 0x53, 0xa0, 0x87, 0x61, 0x30, 0xf0, 0x5a, 0x52, 0xce, 0x8d, 0x89, 0x7e, 0x0c, 0x5e, 0xf5, + 0x5a, 0x74, 0x85, 0x7b, 0x2d, 0x42, 0x31, 0xda, 0x5e, 0xd2, 0x60, 0x74, 0x34, 0x8c, 0x75, 0x2f, + 0x69, 0x60, 0x56, 0x82, 0x1e, 0x84, 0xc1, 0x56, 0x58, 0x23, 0x6c, 0x2c, 0x8a, 0x5c, 0x42, 0xac, + 0x86, 0x35, 0x82, 0x19, 0x94, 0xd6, 0xdf, 0x8a, 0xc2, 0x56, 0x79, 0xd0, 0xac, 0xbf, 0x18, 0x85, + 0x2d, 0xcc, 0x4a, 0xd0, 0x57, 0x1d, 0x98, 0x94, 0x73, 0x7b, 0x25, 0xac, 0x7a, 0x89, 0x1f, 0x06, + 0xe5, 0x22, 0x93, 0x28, 0xd8, 0xde, 0x92, 0x92, 0x94, 0xe7, 0xca, 0xa2, 0x09, 0x93, 0xd9, 0x12, + 0xdc, 0xd5, 0x0a, 0x74, 0x11, 0xa0, 0xde, 0x0c, 0x37, 0xbd, 0x26, 0x1d, 0x90, 0xf2, 0x10, 0xeb, + 0x82, 0x92, 0x0c, 0x4b, 0xaa, 0x04, 0x6b, 0x58, 0xe8, 0x26, 0x0c, 0x7b, 0x5c, 0xfa, 0x97, 0x87, + 0x59, 0x27, 0x9e, 0xb3, 0xd1, 0x09, 0x63, 0x3b, 0x99, 0x2b, 0xdd, 0xda, 0x9b, 0x1e, 0x16, 0x40, + 0x2c, 0xd9, 0xa1, 0x27, 0x61, 0x24, 0x6c, 0xd3, 0x76, 0x7b, 0xcd, 0xf2, 0x08, 0x9b, 0x98, 0x93, + 0xa2, 0xad, 0x23, 0x6b, 0x02, 0x8e, 0x15, 0x06, 0x7a, 0x02, 0x86, 0xe3, 0xce, 0x26, 0xfd, 0x8e, + 0xe5, 0x51, 0xd6, 0xb1, 0x13, 0x02, 0x79, 0xb8, 0xc2, 0xc1, 0x58, 0x96, 0xa3, 0x77, 0x43, 0x29, + 0x22, 0xd5, 0x4e, 0x14, 0x13, 0xfa, 0x61, 0xcb, 0xc0, 0x68, 0x9f, 0x12, 0xe8, 0x25, 0x9c, 0x16, + 0x61, 0x1d, 0x0f, 0xbd, 0x0f, 0x26, 0xe8, 0x07, 0xbe, 0x74, 0xb3, 0x1d, 0x91, 0x38, 0xa6, 0x5f, + 0xb5, 0xc4, 0x18, 0x9d, 0x15, 0x35, 0x27, 0x16, 0x8d, 0x52, 0x9c, 0xc1, 0x46, 0xaf, 0x03, 0x78, + 0x4a, 0x66, 0x94, 0xc7, 0xd8, 0x60, 0xae, 0xd8, 0x9b, 0x11, 0x4b, 0xf3, 0x73, 0x13, 0xf4, 0x3b, + 0xa6, 0xbf, 0xb1, 0xc6, 0x8f, 0x8e, 0x4f, 0x8d, 0x34, 0x49, 0x42, 0x6a, 0xe5, 0x71, 0xd6, 0x61, + 0x35, 0x3e, 0x0b, 0x1c, 0x8c, 0x65, 0xb9, 0xfb, 0xb7, 0x0b, 0xa0, 0x51, 0x41, 0x73, 0x30, 0x22, + 0xe4, 0x9a, 0x58, 0x92, 0x73, 0x8f, 0xc9, 0xef, 0x20, 0xbf, 0xe0, 0xed, 0xbd, 0x5c, 0x79, 0xa8, + 0xea, 0xa1, 0x37, 0xa0, 0xd4, 0x0e, 0x6b, 0xab, 0x24, 0xf1, 0x6a, 0x5e, 0xe2, 0x89, 0xdd, 0xdc, + 0xc2, 0x0e, 0x23, 0x29, 0xce, 0x9d, 0xa0, 0x9f, 0x6e, 0x3d, 0x65, 0x81, 0x75, 0x7e, 0xe8, 0x59, + 0x40, 0x31, 0x89, 0x76, 0xfc, 0x2a, 0x99, 0xad, 0x56, 0xa9, 0x4a, 0xc4, 0x16, 0xc0, 0x00, 0xeb, + 0xcc, 0x94, 0xe8, 0x0c, 0xaa, 0x74, 0x61, 0xe0, 0x9c, 0x5a, 0xee, 0xf7, 0x0b, 0x30, 0xa1, 0xf5, + 0xb5, 0x4d, 0xaa, 0xe8, 0x2d, 0x07, 0x4e, 0xa8, 0xed, 0x6c, 0x6e, 0xf7, 0x2a, 0x9d, 0x55, 0x7c, + 0xb3, 0x22, 0x36, 0xbf, 0x2f, 0xe5, 0xa5, 0x7e, 0x0a, 0x3e, 0x5c, 0xd6, 0x9f, 0x13, 0x7d, 0x38, + 0x91, 0x29, 0xc5, 0xd9, 0x66, 0x4d, 0x7d, 0xc5, 0x81, 0xd3, 0x79, 0x24, 0x72, 0x64, 0x6e, 0x43, + 0x97, 0xb9, 0x56, 0x85, 0x17, 0xe5, 0x4a, 0x3b, 0xa3, 0xcb, 0xf1, 0xff, 0x5b, 0x80, 0x49, 0x7d, + 0x0a, 0x31, 0x4d, 0xe0, 0x9f, 0x3a, 0x70, 0x46, 0xf6, 0x00, 0x93, 0xb8, 0xd3, 0xcc, 0x0c, 0x6f, + 0xcb, 0xea, 0xf0, 0xf2, 0x9d, 0x74, 0x36, 0x8f, 0x1f, 0x1f, 0xe6, 0x87, 0xc4, 0x30, 0x9f, 0xc9, + 0xc5, 0xc1, 0xf9, 0x4d, 0x9d, 0xfa, 0x96, 0x03, 0x53, 0xbd, 0x89, 0xe6, 0x0c, 0x7c, 0xdb, 0x1c, + 0xf8, 0x17, 0xed, 0x75, 0x92, 0xb3, 0x67, 0xc3, 0xcf, 0x3a, 0xab, 0x7f, 0x80, 0xdf, 0x1e, 0x81, + 0xae, 0x3d, 0x04, 0x3d, 0x05, 0x25, 0x21, 0x8e, 0x57, 0xc2, 0x7a, 0xcc, 0x1a, 0x39, 0xc2, 0xd7, + 0xda, 0x6c, 0x0a, 0xc6, 0x3a, 0x0e, 0xaa, 0x41, 0x21, 0x7e, 0x5a, 0x34, 0xdd, 0x82, 0x78, 0xab, + 0x3c, 0xad, 0xb4, 0xc8, 0xa1, 0x5b, 0x7b, 0xd3, 0x85, 0xca, 0xd3, 0xb8, 0x10, 0x3f, 0x4d, 0x35, + 0xf5, 0xba, 0x9f, 0xd8, 0xd3, 0xd4, 0x97, 0xfc, 0x44, 0xf1, 0x61, 0x9a, 0xfa, 0x92, 0x9f, 0x60, + 0xca, 0x82, 0x9e, 0x40, 0x1a, 0x49, 0xd2, 0x66, 0x3b, 0xbe, 0x95, 0x13, 0xc8, 0xe5, 0x8d, 0x8d, + 0x75, 0xc5, 0x8b, 0xe9, 0x17, 0x14, 0x82, 0x19, 0x17, 0xf4, 0x59, 0x87, 0x8e, 0x38, 0x2f, 0x0c, + 0xa3, 0x5d, 0xa1, 0x38, 0x5c, 0xb3, 0x37, 0x05, 0xc2, 0x68, 0x57, 0x31, 0x17, 0x1f, 0x52, 0x15, + 0x60, 0x9d, 0x35, 0xeb, 0x78, 0x6d, 0x2b, 0x66, 0x7a, 0x82, 0x9d, 0x8e, 0x2f, 0x2c, 0x56, 0x32, + 0x1d, 0x5f, 0x58, 0xac, 0x60, 0xc6, 0x85, 0x7e, 0xd0, 0xc8, 0xbb, 0x21, 0x74, 0x0c, 0x0b, 0x1f, + 0x14, 0x7b, 0x37, 0xcc, 0x0f, 0x8a, 0xbd, 0x1b, 0x98, 0xb2, 0xa0, 0x9c, 0xc2, 0x38, 0x66, 0x2a, + 0x85, 0x15, 0x4e, 0x6b, 0x95, 0x8a, 0xc9, 0x69, 0xad, 0x52, 0xc1, 0x94, 0x05, 0x9b, 0xa4, 0xd5, + 0x98, 0xe9, 0x23, 0x76, 0x26, 0xe9, 0x7c, 0x86, 0xd3, 0xd2, 0x7c, 0x05, 0x53, 0x16, 0x54, 0x64, + 0x78, 0xaf, 0x76, 0x22, 0xae, 0xcc, 0x94, 0x2e, 0xae, 0x59, 0x98, 0x2f, 0x94, 0x9c, 0xe2, 0x36, + 0x7a, 0x6b, 0x6f, 0xba, 0xc8, 0x40, 0x98, 0x33, 0x72, 0xff, 0x60, 0x20, 0x15, 0x17, 0x52, 0x9e, + 0xa3, 0x5f, 0x67, 0x1b, 0xa1, 0x90, 0x05, 0x42, 0xf5, 0x75, 0x8e, 0x4c, 0xf5, 0x3d, 0xc5, 0x77, + 0x3c, 0x83, 0x1d, 0xce, 0xf2, 0x47, 0x5f, 0x74, 0xba, 0xcf, 0xb6, 0x9e, 0xfd, 0xbd, 0x2c, 0xdd, + 0x98, 0xf9, 0x5e, 0xb1, 0xef, 0x91, 0x77, 0xea, 0xb3, 0x4e, 0xaa, 0x44, 0xc4, 0xbd, 0xf6, 0x81, + 0x8f, 0x98, 0xfb, 0x80, 0xc5, 0x03, 0xb9, 0x2e, 0xf7, 0x3f, 0xe7, 0xc0, 0xb8, 0x84, 0x53, 0xf5, + 0x38, 0x46, 0x37, 0x61, 0x44, 0xb6, 0x54, 0x7c, 0x3d, 0x9b, 0xb6, 0x00, 0xa5, 0xc4, 0xab, 0xc6, + 0x28, 0x6e, 0xee, 0x5b, 0x43, 0x80, 0xd2, 0xbd, 0xaa, 0x1d, 0xc6, 0x3e, 0x93, 0x44, 0x87, 0xd8, + 0x85, 0x02, 0x6d, 0x17, 0x7a, 0xde, 0xe6, 0x2e, 0x94, 0x36, 0xcb, 0xd8, 0x8f, 0xbe, 0x98, 0x91, + 0xdb, 0x7c, 0x63, 0xfa, 0xf0, 0x91, 0xc8, 0x6d, 0xad, 0x09, 0xfb, 0x4b, 0xf0, 0x1d, 0x21, 0xc1, + 0xf9, 0xd6, 0xf5, 0x4b, 0x76, 0x25, 0xb8, 0xd6, 0x8a, 0xac, 0x2c, 0x8f, 0xb8, 0x84, 0xe5, 0x7b, + 0xd7, 0x75, 0xab, 0x12, 0x56, 0xe3, 0x6a, 0xca, 0xda, 0x88, 0xcb, 0xda, 0x21, 0x5b, 0x3c, 0x35, + 0x59, 0x9b, 0xe5, 0xa9, 0xa4, 0xee, 0xab, 0x52, 0xea, 0xf2, 0x5d, 0xeb, 0x05, 0xcb, 0x52, 0x57, + 0xe3, 0xdb, 0x2d, 0x7f, 0x5f, 0x81, 0x33, 0xdd, 0x78, 0x98, 0x6c, 0xa1, 0x0b, 0x30, 0x5a, 0x0d, + 0x83, 0x2d, 0xbf, 0xbe, 0xea, 0xb5, 0xc5, 0x79, 0x4d, 0xc9, 0xa2, 0x79, 0x59, 0x80, 0x53, 0x1c, + 0xf4, 0x10, 0x17, 0x3c, 0xdc, 0x22, 0x52, 0x12, 0xa8, 0x03, 0xcb, 0x64, 0x97, 0x49, 0xa1, 0xf7, + 0x8c, 0x7c, 0xf5, 0x1b, 0xd3, 0xf7, 0x7d, 0xfc, 0x8f, 0x1f, 0xbe, 0xcf, 0xfd, 0xa3, 0x01, 0x78, + 0x20, 0x97, 0xa7, 0xd0, 0xd6, 0x7f, 0xdb, 0xd0, 0xd6, 0xb5, 0x72, 0x21, 0x45, 0xae, 0xdb, 0x54, + 0x64, 0x35, 0xf2, 0x79, 0x7a, 0xb9, 0x56, 0x8c, 0xf3, 0x1b, 0x45, 0x07, 0x2a, 0xf0, 0x5a, 0x24, + 0x6e, 0x7b, 0x55, 0x22, 0x7a, 0xaf, 0x06, 0xea, 0xaa, 0x2c, 0xc0, 0x29, 0x0e, 0x3f, 0x42, 0x6f, + 0x79, 0x9d, 0x66, 0x22, 0x0c, 0x65, 0xda, 0x11, 0x9a, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xc7, 0x01, + 0xd4, 0xcd, 0x55, 0x2c, 0xc4, 0x8d, 0xa3, 0x18, 0x87, 0xb9, 0xb3, 0xb7, 0xb4, 0x43, 0xb8, 0xd6, + 0xd3, 0x9c, 0x76, 0x68, 0xdf, 0xf4, 0xa3, 0xe9, 0x3e, 0xc4, 0x0f, 0x07, 0x7d, 0xd8, 0xd0, 0x98, + 0xa9, 0xa5, 0x5a, 0x25, 0x71, 0xcc, 0xcd, 0x71, 0xba, 0xa9, 0x85, 0x81, 0xb1, 0x2c, 0x47, 0xd3, + 0x50, 0x24, 0x51, 0x14, 0x46, 0xe2, 0xac, 0xcd, 0xa6, 0xf1, 0x25, 0x0a, 0xc0, 0x1c, 0xee, 0xfe, + 0xb8, 0x00, 0xe5, 0x5e, 0xa7, 0x13, 0xf4, 0xbb, 0xda, 0xb9, 0x5a, 0x9c, 0x9c, 0xc4, 0xc1, 0x2f, + 0x3c, 0xba, 0x33, 0x51, 0xf6, 0x00, 0xd8, 0xe3, 0x84, 0x2d, 0x4a, 0x71, 0xb6, 0x81, 0x53, 0x5f, + 0xd2, 0x4e, 0xd8, 0x3a, 0x89, 0x9c, 0x0d, 0x7e, 0xcb, 0xdc, 0xe0, 0xd7, 0x6d, 0x77, 0x4a, 0xdf, + 0xe6, 0xff, 0xa4, 0x08, 0xa7, 0x64, 0x69, 0x85, 0xd0, 0xad, 0xf2, 0xb9, 0x0e, 0x89, 0x76, 0xd1, + 0x0f, 0x1c, 0x38, 0xed, 0x65, 0x4d, 0x37, 0x3e, 0x39, 0x82, 0x81, 0xd6, 0xb8, 0xce, 0xcc, 0xe6, + 0x70, 0xe4, 0x03, 0x7d, 0x51, 0x0c, 0xf4, 0xe9, 0x3c, 0x94, 0x1e, 0x76, 0xf7, 0xdc, 0x0e, 0xa0, + 0x67, 0x60, 0x4c, 0xc2, 0x99, 0xb9, 0x87, 0x2f, 0x71, 0x65, 0xdc, 0x9e, 0xd5, 0xca, 0xb0, 0x81, + 0x49, 0x6b, 0x26, 0xa4, 0xd5, 0x6e, 0x7a, 0x09, 0xd1, 0x0c, 0x45, 0xaa, 0xe6, 0x86, 0x56, 0x86, + 0x0d, 0x4c, 0xf4, 0x18, 0x0c, 0x05, 0x61, 0x8d, 0x5c, 0xa9, 0x09, 0x03, 0xf1, 0x84, 0xa8, 0x33, + 0x74, 0x95, 0x41, 0xb1, 0x28, 0x45, 0x8f, 0xa6, 0xd6, 0xb8, 0x22, 0x5b, 0x42, 0xa5, 0x3c, 0x4b, + 0x1c, 0xfa, 0x7b, 0x0e, 0x8c, 0xd2, 0x1a, 0x1b, 0xbb, 0x6d, 0x42, 0xf7, 0x36, 0xfa, 0x45, 0x6a, + 0x47, 0xf3, 0x45, 0xae, 0x4a, 0x36, 0xa6, 0xa9, 0x63, 0x54, 0xc1, 0xdf, 0x7c, 0x7b, 0x7a, 0x44, + 0xfe, 0xc0, 0x69, 0xab, 0xa6, 0x96, 0xe0, 0xfe, 0x9e, 0x5f, 0xf3, 0x40, 0xae, 0x80, 0xbf, 0x06, + 0x13, 0x66, 0x23, 0x0e, 0xe4, 0x07, 0xf8, 0x27, 0xda, 0xb2, 0xe3, 0xfd, 0x12, 0xf2, 0xec, 0x9e, + 0x69, 0xb3, 0x6a, 0x32, 0x2c, 0x88, 0xa9, 0x67, 0x4e, 0x86, 0x05, 0x31, 0x19, 0x16, 0xdc, 0x3f, + 0x74, 0xd2, 0xa5, 0xa9, 0xa9, 0x79, 0x74, 0x63, 0xee, 0x44, 0x4d, 0x21, 0x88, 0xd5, 0xc6, 0x7c, + 0x0d, 0xaf, 0x60, 0x0a, 0x47, 0x5f, 0xd2, 0xa4, 0x23, 0xad, 0xd6, 0x11, 0x6e, 0x0d, 0x4b, 0x26, + 0x7a, 0x83, 0x70, 0xb7, 0xfc, 0x13, 0x05, 0x38, 0xdb, 0x04, 0xf7, 0x8b, 0x05, 0x78, 0x68, 0x5f, + 0xa5, 0x35, 0xb7, 0xe1, 0xce, 0x3d, 0x6f, 0x38, 0xdd, 0xd6, 0x22, 0xd2, 0x0e, 0xaf, 0xe1, 0x15, + 0xf1, 0xbd, 0xd4, 0xb6, 0x86, 0x39, 0x18, 0xcb, 0x72, 0xaa, 0x3a, 0x6c, 0x93, 0xdd, 0xc5, 0x30, + 0x6a, 0x79, 0x89, 0x90, 0x0e, 0x4a, 0x75, 0x58, 0x96, 0x05, 0x38, 0xc5, 0x71, 0x7f, 0xe0, 0x40, + 0xb6, 0x01, 0xc8, 0x83, 0x89, 0x4e, 0x4c, 0x22, 0xba, 0xa5, 0x56, 0x48, 0x35, 0x22, 0x72, 0x7a, + 0x3e, 0x3a, 0xc3, 0xbd, 0xfd, 0xb4, 0x87, 0x33, 0xd5, 0x30, 0x22, 0x33, 0x3b, 0x4f, 0xcd, 0x70, + 0x8c, 0x65, 0xb2, 0x5b, 0x21, 0x4d, 0x42, 0x69, 0xcc, 0xa1, 0x5b, 0x7b, 0xd3, 0x13, 0xd7, 0x0c, + 0x02, 0x38, 0x43, 0x90, 0xb2, 0x68, 0x7b, 0x71, 0x7c, 0x23, 0x8c, 0x6a, 0x82, 0x45, 0xe1, 0xc0, + 0x2c, 0xd6, 0x0d, 0x02, 0x38, 0x43, 0xd0, 0xfd, 0x3e, 0x3d, 0x3e, 0xea, 0x5a, 0x2b, 0xfa, 0x06, + 0xd5, 0x7d, 0x28, 0x64, 0xae, 0x19, 0x6e, 0xce, 0x87, 0x41, 0xe2, 0xf9, 0x01, 0x91, 0xc1, 0x02, + 0x1b, 0x96, 0x74, 0x64, 0x83, 0x76, 0x6a, 0xc3, 0xef, 0x2e, 0xc3, 0x39, 0x6d, 0xa1, 0x3a, 0xce, + 0x66, 0x33, 0xdc, 0xcc, 0x7a, 0x01, 0x29, 0x12, 0x66, 0x25, 0xee, 0x4f, 0x1d, 0x38, 0xd7, 0x43, + 0x19, 0x47, 0x5f, 0x71, 0x60, 0x7c, 0xf3, 0x67, 0xa2, 0x6f, 0x66, 0x33, 0xd0, 0xfb, 0x60, 0x82, + 0x02, 0xe8, 0x4e, 0x24, 0xe6, 0x66, 0xc1, 0xf4, 0x50, 0xcd, 0x19, 0xa5, 0x38, 0x83, 0xed, 0xfe, + 0x46, 0x01, 0x72, 0xb8, 0xa0, 0x27, 0x61, 0x84, 0x04, 0xb5, 0x76, 0xe8, 0x07, 0x89, 0x10, 0x46, + 0x4a, 0xea, 0x5d, 0x12, 0x70, 0xac, 0x30, 0xc4, 0xf9, 0x43, 0x0c, 0x4c, 0xa1, 0xeb, 0xfc, 0x21, + 0x5a, 0x9e, 0xe2, 0xa0, 0x3a, 0x4c, 0x7a, 0xdc, 0xbf, 0xc2, 0xe6, 0x1e, 0x9b, 0xa6, 0x03, 0x07, + 0x99, 0xa6, 0xa7, 0x99, 0xfb, 0x33, 0x43, 0x02, 0x77, 0x11, 0x45, 0xef, 0x86, 0x52, 0x27, 0x26, + 0x95, 0x85, 0xe5, 0xf9, 0x88, 0xd4, 0xf8, 0xa9, 0x58, 0xf3, 0xfb, 0x5d, 0x4b, 0x8b, 0xb0, 0x8e, + 0xe7, 0xfe, 0x33, 0x07, 0x86, 0xe7, 0xbc, 0xea, 0x76, 0xb8, 0xb5, 0x45, 0x87, 0xa2, 0xd6, 0x89, + 0x52, 0xc3, 0x96, 0x36, 0x14, 0x0b, 0x02, 0x8e, 0x15, 0x06, 0xda, 0x80, 0x21, 0xbe, 0xe0, 0xc5, + 0xb2, 0xfb, 0x45, 0xad, 0x3f, 0x2a, 0x8e, 0x87, 0x4d, 0x87, 0x4e, 0xe2, 0x37, 0x67, 0x78, 0x1c, + 0xcf, 0xcc, 0x95, 0x20, 0x59, 0x8b, 0x2a, 0x49, 0xe4, 0x07, 0xf5, 0x39, 0xa0, 0xdb, 0xc5, 0x22, + 0xa3, 0x81, 0x05, 0x2d, 0xda, 0x8d, 0x96, 0x77, 0x53, 0xb2, 0x13, 0xe2, 0x47, 0x75, 0x63, 0x35, + 0x2d, 0xc2, 0x3a, 0x9e, 0xfb, 0x47, 0x0e, 0x8c, 0xce, 0x79, 0xb1, 0x5f, 0xfd, 0x0b, 0x24, 0x7c, + 0x3e, 0x04, 0xc5, 0x79, 0xaf, 0xda, 0x20, 0xe8, 0x5a, 0xf6, 0xd0, 0x5b, 0xba, 0xf8, 0x78, 0x1e, + 0x1b, 0x75, 0x00, 0xd6, 0x39, 0x8d, 0xf7, 0x3a, 0x1a, 0xbb, 0x6f, 0x3b, 0x30, 0x31, 0xdf, 0xf4, + 0x49, 0x90, 0xcc, 0x93, 0x28, 0x61, 0x03, 0x57, 0x87, 0xc9, 0xaa, 0x82, 0x1c, 0x66, 0xe8, 0xd8, + 0x6c, 0x9d, 0xcf, 0x90, 0xc0, 0x5d, 0x44, 0x51, 0x0d, 0x4e, 0x70, 0x58, 0xba, 0x2a, 0x0e, 0x34, + 0x7e, 0xcc, 0x3a, 0x3a, 0x6f, 0x52, 0xc0, 0x59, 0x92, 0xee, 0x4f, 0x1c, 0x38, 0x37, 0xdf, 0xec, + 0xc4, 0x09, 0x89, 0xae, 0x0b, 0x69, 0x24, 0xd5, 0x5b, 0xf4, 0x11, 0x18, 0x69, 0x49, 0x8f, 0xad, + 0x73, 0x87, 0x09, 0xcc, 0xe4, 0x19, 0xc5, 0xa6, 0x8d, 0x59, 0xdb, 0x7c, 0x99, 0x54, 0x93, 0x55, + 0x92, 0x78, 0x69, 0x78, 0x41, 0x0a, 0xc3, 0x8a, 0x2a, 0x6a, 0xc3, 0x60, 0xdc, 0x26, 0x55, 0x7b, + 0xd1, 0x5d, 0xb2, 0x0f, 0x95, 0x36, 0xa9, 0xa6, 0x72, 0x9d, 0xf9, 0x1a, 0x19, 0x27, 0xf7, 0x7f, + 0x39, 0xf0, 0x40, 0x8f, 0xfe, 0xae, 0xf8, 0x71, 0x82, 0x5e, 0xea, 0xea, 0xf3, 0x4c, 0x7f, 0x7d, + 0xa6, 0xb5, 0x59, 0x8f, 0x95, 0x40, 0x90, 0x10, 0xad, 0xbf, 0x1f, 0x85, 0xa2, 0x9f, 0x90, 0x96, + 0x34, 0x43, 0x5b, 0x30, 0x18, 0xf5, 0xe8, 0xcb, 0xdc, 0xb8, 0x8c, 0xf1, 0xbb, 0x42, 0xf9, 0x61, + 0xce, 0xd6, 0xdd, 0x86, 0xa1, 0xf9, 0xb0, 0xd9, 0x69, 0x05, 0xfd, 0x45, 0xca, 0x24, 0xbb, 0x6d, + 0x92, 0xdd, 0x23, 0x99, 0xfa, 0xcf, 0x4a, 0xa4, 0xe1, 0x68, 0x20, 0xdf, 0x70, 0xe4, 0xfe, 0x73, + 0x07, 0xe8, 0xaa, 0xaa, 0xf9, 0xc2, 0x93, 0xc8, 0xc9, 0x71, 0x86, 0x0f, 0xe9, 0xe4, 0x6e, 0xef, + 0x4d, 0x8f, 0x2b, 0x44, 0x8d, 0xfe, 0x87, 0x60, 0x28, 0x66, 0x47, 0x72, 0xd1, 0x86, 0x45, 0xa9, + 0x3f, 0xf3, 0x83, 0xfa, 0xed, 0xbd, 0xe9, 0xbe, 0xc2, 0x36, 0x67, 0x14, 0x6d, 0xe1, 0xf4, 0x14, + 0x54, 0xa9, 0xc2, 0xd7, 0x22, 0x71, 0xec, 0xd5, 0xe5, 0x09, 0x4f, 0x29, 0x7c, 0xab, 0x1c, 0x8c, + 0x65, 0xb9, 0xfb, 0x65, 0x07, 0xc6, 0xd5, 0xe6, 0x45, 0xd5, 0x77, 0x74, 0x55, 0xdf, 0xe6, 0xf8, + 0x4c, 0x79, 0xa8, 0x87, 0xc4, 0x11, 0x1b, 0xf9, 0xfe, 0xbb, 0xe0, 0xbb, 0x60, 0xac, 0x46, 0xda, + 0x24, 0xa8, 0x91, 0xa0, 0x4a, 0x8f, 0xdf, 0x74, 0x86, 0x8c, 0xce, 0x4d, 0xd2, 0xf3, 0xe6, 0x82, + 0x06, 0xc7, 0x06, 0x96, 0xfb, 0x4d, 0x07, 0xee, 0x57, 0xe4, 0x2a, 0x24, 0xc1, 0x24, 0x89, 0x76, + 0x55, 0x98, 0xe6, 0xc1, 0x76, 0xab, 0xeb, 0x54, 0xff, 0x4d, 0x22, 0xce, 0xfc, 0x70, 0xdb, 0x55, + 0x89, 0x6b, 0xcb, 0x8c, 0x08, 0x96, 0xd4, 0xdc, 0x5f, 0x1b, 0x80, 0xd3, 0x7a, 0x23, 0x95, 0x80, + 0xf9, 0x84, 0x03, 0xa0, 0x46, 0x80, 0x6e, 0xc8, 0x03, 0x76, 0x7c, 0x57, 0xc6, 0x97, 0x4a, 0x45, + 0x90, 0x02, 0xc7, 0x58, 0x63, 0x8b, 0x5e, 0x80, 0xb1, 0x1d, 0xba, 0x28, 0xc8, 0x2a, 0x55, 0x17, + 0xe2, 0xf2, 0x00, 0x6b, 0xc6, 0x74, 0xde, 0xc7, 0x7c, 0x3e, 0xc5, 0x4b, 0xcd, 0x01, 0x1a, 0x30, + 0xc6, 0x06, 0x29, 0x7a, 0xd2, 0x19, 0x8f, 0xf4, 0x4f, 0x22, 0x6c, 0xe2, 0x1f, 0xb4, 0xd8, 0xc7, + 0xec, 0x57, 0x9f, 0x3b, 0x79, 0x6b, 0x6f, 0x7a, 0xdc, 0x00, 0x61, 0xb3, 0x11, 0xee, 0x0b, 0xc0, + 0xc6, 0xc2, 0x0f, 0x3a, 0x64, 0x2d, 0x40, 0x8f, 0x48, 0x1b, 0x1d, 0xf7, 0xab, 0x28, 0xc9, 0xa1, + 0xdb, 0xe9, 0xe8, 0x59, 0x76, 0xcb, 0xf3, 0x9b, 0x2c, 0x7c, 0x91, 0x62, 0xa9, 0xb3, 0xec, 0x22, + 0x83, 0x62, 0x51, 0xea, 0xce, 0xc0, 0xf0, 0x3c, 0xed, 0x3b, 0x89, 0x28, 0x5d, 0x3d, 0xea, 0x78, + 0xdc, 0x88, 0x3a, 0x96, 0xd1, 0xc5, 0x1b, 0x70, 0x66, 0x3e, 0x22, 0x5e, 0x42, 0x2a, 0x4f, 0xcf, + 0x75, 0xaa, 0xdb, 0x24, 0xe1, 0xa1, 0x5d, 0x31, 0x7a, 0x2f, 0x8c, 0x87, 0x6c, 0xcb, 0x58, 0x09, + 0xab, 0xdb, 0x7e, 0x50, 0x17, 0x26, 0xd7, 0x33, 0x82, 0xca, 0xf8, 0x9a, 0x5e, 0x88, 0x4d, 0x5c, + 0xf7, 0xdf, 0x17, 0x60, 0x6c, 0x3e, 0x0a, 0x03, 0x29, 0x16, 0x8f, 0x61, 0x2b, 0x4b, 0x8c, 0xad, + 0xcc, 0x82, 0xbb, 0x53, 0x6f, 0x7f, 0xaf, 0xed, 0x0c, 0xbd, 0xae, 0x44, 0xe4, 0x80, 0xad, 0x23, + 0x88, 0xc1, 0x97, 0xd1, 0x4e, 0x3f, 0xb6, 0x29, 0x40, 0xdd, 0xff, 0xe0, 0xc0, 0xa4, 0x8e, 0x7e, + 0x0c, 0x3b, 0x68, 0x6c, 0xee, 0xa0, 0x57, 0xed, 0xf6, 0xb7, 0xc7, 0xb6, 0xf9, 0xf6, 0xb0, 0xd9, + 0x4f, 0xe6, 0xeb, 0xfe, 0xaa, 0x03, 0x63, 0x37, 0x34, 0x80, 0xe8, 0xac, 0x6d, 0x25, 0xe6, 0x1d, + 0x52, 0xcc, 0xe8, 0xd0, 0xdb, 0x99, 0xdf, 0xd8, 0x68, 0x09, 0x95, 0xfb, 0x71, 0xb5, 0x41, 0x6a, + 0x9d, 0xa6, 0xdc, 0xbe, 0xd5, 0x90, 0x56, 0x04, 0x1c, 0x2b, 0x0c, 0xf4, 0x12, 0x9c, 0xac, 0x86, + 0x41, 0xb5, 0x13, 0x45, 0x24, 0xa8, 0xee, 0xae, 0xb3, 0x3b, 0x12, 0x62, 0x43, 0x9c, 0x11, 0xd5, + 0x4e, 0xce, 0x67, 0x11, 0x6e, 0xe7, 0x01, 0x71, 0x37, 0x21, 0xee, 0x2c, 0x88, 0xe9, 0x96, 0x25, + 0x0e, 0x5c, 0x9a, 0xb3, 0x80, 0x81, 0xb1, 0x2c, 0x47, 0xd7, 0xe0, 0x5c, 0x9c, 0x78, 0x51, 0xe2, + 0x07, 0xf5, 0x05, 0xe2, 0xd5, 0x9a, 0x7e, 0x40, 0x8f, 0x12, 0x61, 0x50, 0xe3, 0xae, 0xc4, 0x81, + 0xb9, 0x07, 0x6e, 0xed, 0x4d, 0x9f, 0xab, 0xe4, 0xa3, 0xe0, 0x5e, 0x75, 0xd1, 0x87, 0x60, 0x4a, + 0xb8, 0x23, 0xb6, 0x3a, 0xcd, 0x67, 0xc3, 0xcd, 0xf8, 0xb2, 0x1f, 0xd3, 0x73, 0xfc, 0x8a, 0xdf, + 0xf2, 0x13, 0xe6, 0x30, 0x2c, 0xce, 0x9d, 0xbf, 0xb5, 0x37, 0x3d, 0x55, 0xe9, 0x89, 0x85, 0xf7, + 0xa1, 0x80, 0x30, 0x9c, 0xe5, 0xc2, 0xaf, 0x8b, 0xf6, 0x30, 0xa3, 0x3d, 0x75, 0x6b, 0x6f, 0xfa, + 0xec, 0x62, 0x2e, 0x06, 0xee, 0x51, 0x93, 0x7e, 0xc1, 0xc4, 0x6f, 0x91, 0x57, 0xc3, 0x80, 0xb0, + 0x40, 0x15, 0xed, 0x0b, 0x6e, 0x08, 0x38, 0x56, 0x18, 0xe8, 0xe5, 0x74, 0x26, 0xd2, 0xe5, 0x22, + 0x02, 0x4e, 0x0e, 0x2e, 0xe1, 0xd8, 0xd1, 0xe4, 0xba, 0x46, 0x89, 0x45, 0x52, 0x1a, 0xb4, 0xd1, + 0x27, 0x1d, 0x18, 0x8b, 0x93, 0x50, 0xdd, 0x6b, 0x10, 0x11, 0x27, 0x16, 0xa6, 0x7d, 0x45, 0xa3, + 0xca, 0x15, 0x1f, 0x1d, 0x82, 0x0d, 0xae, 0xe8, 0x17, 0x60, 0x54, 0x4e, 0xe0, 0xb8, 0x5c, 0x62, + 0xba, 0x12, 0x3b, 0xc6, 0xc9, 0xf9, 0x1d, 0xe3, 0xb4, 0x9c, 0xaa, 0xb2, 0x37, 0x1a, 0x24, 0x60, + 0x31, 0xb7, 0x9a, 0x2a, 0x7b, 0xbd, 0x41, 0x02, 0xcc, 0x4a, 0xdc, 0x1f, 0x0f, 0x00, 0xea, 0x16, + 0x7c, 0x68, 0x19, 0x86, 0xbc, 0x6a, 0xe2, 0xef, 0xc8, 0x78, 0xc3, 0x47, 0xf2, 0x94, 0x02, 0x3e, + 0x80, 0x98, 0x6c, 0x11, 0x3a, 0xef, 0x49, 0x2a, 0x2d, 0x67, 0x59, 0x55, 0x2c, 0x48, 0xa0, 0x10, + 0x4e, 0x36, 0xbd, 0x38, 0x91, 0x2d, 0xac, 0xd1, 0x0f, 0x29, 0xb6, 0x8b, 0x9f, 0xef, 0xef, 0x53, + 0xd1, 0x1a, 0x73, 0x67, 0xe8, 0x7a, 0x5c, 0xc9, 0x12, 0xc2, 0xdd, 0xb4, 0xd1, 0xc7, 0x98, 0x76, + 0xc5, 0x55, 0x5f, 0xa9, 0xd6, 0x2c, 0x5b, 0xd1, 0x3c, 0x38, 0x4d, 0x43, 0xb3, 0x12, 0x6c, 0xb0, + 0xc6, 0x12, 0x5d, 0x80, 0x51, 0xb6, 0x6e, 0x48, 0x8d, 0xf0, 0xd5, 0x3f, 0x90, 0x2a, 0xc1, 0x15, + 0x59, 0x80, 0x53, 0x1c, 0x4d, 0xcb, 0xe0, 0x0b, 0xbe, 0x87, 0x96, 0x81, 0x9e, 0x81, 0x62, 0xbb, + 0xe1, 0xc5, 0x32, 0x86, 0xdd, 0x95, 0x52, 0x7b, 0x9d, 0x02, 0x99, 0x68, 0xd2, 0xbe, 0x25, 0x03, + 0x62, 0x5e, 0xc1, 0xfd, 0x17, 0x00, 0xc3, 0x0b, 0xb3, 0x4b, 0x1b, 0x5e, 0xbc, 0xdd, 0xc7, 0x19, + 0x88, 0x2e, 0x43, 0xa1, 0xac, 0x66, 0x05, 0xa9, 0x54, 0x62, 0xb1, 0xc2, 0x40, 0x01, 0x0c, 0xf9, + 0x01, 0x95, 0x3c, 0xe5, 0x09, 0x5b, 0x7e, 0x06, 0x75, 0x9e, 0x63, 0x86, 0xa0, 0x2b, 0x8c, 0x3a, + 0x16, 0x5c, 0xd0, 0xeb, 0x30, 0xea, 0xc9, 0x2b, 0x44, 0x62, 0xff, 0x5f, 0xb6, 0x61, 0x40, 0x17, + 0x24, 0xf5, 0x10, 0x26, 0x01, 0xc2, 0x29, 0x43, 0xf4, 0x71, 0x07, 0x4a, 0xb2, 0xeb, 0x98, 0x6c, + 0x09, 0xdf, 0xf6, 0xaa, 0xbd, 0x3e, 0x63, 0xb2, 0xc5, 0xe3, 0x5b, 0x34, 0x00, 0xd6, 0x59, 0x76, + 0x9d, 0x99, 0x8a, 0xfd, 0x9c, 0x99, 0xd0, 0x0d, 0x18, 0xbd, 0xe1, 0x27, 0x0d, 0xb6, 0xc3, 0x0b, + 0x9f, 0xda, 0xe2, 0xdd, 0xb7, 0x9a, 0x92, 0x4b, 0x47, 0xec, 0xba, 0x64, 0x80, 0x53, 0x5e, 0x74, + 0x39, 0xd0, 0x1f, 0xec, 0x0a, 0x16, 0xdb, 0x1b, 0x46, 0xcd, 0x0a, 0xac, 0x00, 0xa7, 0x38, 0x74, + 0x88, 0xc7, 0xe8, 0xaf, 0x0a, 0x79, 0xa5, 0x43, 0x45, 0x8b, 0x88, 0x59, 0xb4, 0x30, 0xaf, 0x24, + 0x45, 0x3e, 0x58, 0xd7, 0x35, 0x1e, 0xd8, 0xe0, 0xa8, 0x44, 0xe7, 0x68, 0x2f, 0xd1, 0x89, 0x5e, + 0xe7, 0x67, 0x38, 0x7e, 0x98, 0x10, 0xbb, 0xc1, 0x8a, 0x9d, 0xf3, 0x0d, 0xa7, 0xc9, 0xaf, 0x35, + 0xa4, 0xbf, 0xb1, 0xc6, 0x8f, 0x4a, 0x8c, 0x30, 0xb8, 0x74, 0xd3, 0x4f, 0xc4, 0x65, 0x0c, 0x25, + 0x31, 0xd6, 0x18, 0x14, 0x8b, 0x52, 0x1e, 0xbb, 0x41, 0x27, 0x41, 0x2c, 0x76, 0x01, 0x2d, 0x76, + 0x83, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xd7, 0x81, 0x62, 0x23, 0x0c, 0xb7, 0xe3, 0xf2, 0x38, 0x9b, + 0x1c, 0x16, 0x74, 0x6a, 0x21, 0x71, 0x66, 0x2e, 0x53, 0xb2, 0xe6, 0xf5, 0xb2, 0x22, 0x83, 0xdd, + 0xde, 0x9b, 0x9e, 0x58, 0xf1, 0xb7, 0x48, 0x75, 0xb7, 0xda, 0x24, 0x0c, 0xf2, 0xe6, 0xdb, 0x1a, + 0xe4, 0xd2, 0x0e, 0x09, 0x12, 0xcc, 0x5b, 0x35, 0xf5, 0x39, 0x07, 0x20, 0x25, 0x94, 0xe3, 0x24, + 0x25, 0x66, 0x58, 0x81, 0x85, 0x03, 0xb5, 0xd1, 0x34, 0xdd, 0xeb, 0xfa, 0xaf, 0x1c, 0x28, 0xd1, + 0xce, 0x49, 0x11, 0xf8, 0x18, 0x0c, 0x25, 0x5e, 0x54, 0x27, 0xd2, 0x51, 0xa0, 0x3e, 0xc7, 0x06, + 0x83, 0x62, 0x51, 0x8a, 0x02, 0x28, 0x26, 0x5e, 0xbc, 0x2d, 0xd5, 0xf8, 0x2b, 0xd6, 0x86, 0x38, + 0xd5, 0xe0, 0xe9, 0xaf, 0x18, 0x73, 0x36, 0xe8, 0x71, 0x18, 0xa1, 0x5b, 0xc7, 0xa2, 0x17, 0xcb, + 0xd8, 0x9d, 0x31, 0x2a, 0xc4, 0x17, 0x05, 0x0c, 0xab, 0x52, 0xf7, 0x37, 0x0a, 0x30, 0xb8, 0xc0, + 0x0f, 0x74, 0x43, 0x71, 0xd8, 0x89, 0xaa, 0x44, 0x28, 0xf6, 0x16, 0xe6, 0x34, 0xa5, 0x5b, 0x61, + 0x34, 0xb5, 0x23, 0x15, 0xfb, 0x8d, 0x05, 0x2f, 0xf4, 0x25, 0x07, 0x26, 0x92, 0xc8, 0x0b, 0xe2, + 0x2d, 0xe6, 0x92, 0xf1, 0xc3, 0x40, 0x0c, 0x91, 0x85, 0x59, 0xb8, 0x61, 0xd0, 0xad, 0x24, 0xa4, + 0x9d, 0x7a, 0x86, 0xcc, 0x32, 0x9c, 0x69, 0x83, 0xfb, 0x9b, 0x0e, 0x40, 0xda, 0x7a, 0xf4, 0x59, + 0x07, 0xc6, 0x3d, 0x3d, 0x66, 0x54, 0x8c, 0xd1, 0x9a, 0x3d, 0xff, 0x2d, 0x23, 0xcb, 0x6d, 0x19, + 0x06, 0x08, 0x9b, 0x8c, 0xdd, 0x77, 0x43, 0x91, 0xad, 0x0e, 0x76, 0xe8, 0x11, 0xb6, 0xef, 0xac, + 0xb1, 0x4b, 0xda, 0xc4, 0xb1, 0xc2, 0x70, 0x5f, 0x82, 0x89, 0x4b, 0x37, 0x49, 0xb5, 0x93, 0x84, + 0x11, 0xb7, 0xfc, 0xf7, 0xb8, 0x23, 0xe4, 0x1c, 0xea, 0x8e, 0xd0, 0x77, 0x1c, 0x28, 0x69, 0x01, + 0x84, 0x74, 0xa7, 0xae, 0xcf, 0x57, 0xb8, 0x81, 0x43, 0x0c, 0xd5, 0xb2, 0x95, 0x10, 0x45, 0x4e, + 0x32, 0xdd, 0x46, 0x14, 0x08, 0xa7, 0x0c, 0xef, 0x10, 0xe0, 0xe7, 0xfe, 0x81, 0x03, 0x67, 0x72, + 0xa3, 0x1d, 0xef, 0x71, 0xb3, 0x0d, 0x27, 0x7b, 0xa1, 0x0f, 0x27, 0xfb, 0xef, 0x38, 0x90, 0x52, + 0xa2, 0xa2, 0x68, 0x33, 0x6d, 0xb9, 0x26, 0x8a, 0x04, 0x27, 0x51, 0x8a, 0x5e, 0x87, 0x73, 0xe6, + 0x17, 0x3c, 0xa4, 0xbf, 0x85, 0x1f, 0x4e, 0xf3, 0x29, 0xe1, 0x5e, 0x2c, 0xdc, 0xaf, 0x39, 0x50, + 0x5c, 0xf2, 0x3a, 0x75, 0xd2, 0x97, 0xb9, 0x8c, 0xca, 0xb1, 0x88, 0x78, 0xcd, 0x44, 0x1e, 0x1d, + 0x84, 0x1c, 0xc3, 0x02, 0x86, 0x55, 0x29, 0x9a, 0x85, 0xd1, 0xb0, 0x4d, 0x0c, 0x1f, 0xe1, 0x23, + 0x72, 0xf4, 0xd6, 0x64, 0x01, 0xdd, 0x76, 0x18, 0x77, 0x05, 0xc1, 0x69, 0x2d, 0xf7, 0x07, 0x45, + 0x28, 0x69, 0xf7, 0x62, 0xa8, 0x2e, 0x10, 0x91, 0x76, 0x98, 0xd5, 0x97, 0xe9, 0x84, 0xc1, 0xac, + 0x84, 0xae, 0xc1, 0x88, 0xec, 0xf8, 0x31, 0x17, 0x5b, 0xc6, 0x1a, 0xc4, 0x02, 0x8e, 0x15, 0x06, + 0x9a, 0x86, 0x62, 0x8d, 0xb4, 0x93, 0x06, 0x6b, 0xde, 0x20, 0x0f, 0x0e, 0x5c, 0xa0, 0x00, 0xcc, + 0xe1, 0x14, 0x61, 0x8b, 0x24, 0xd5, 0x06, 0xb3, 0x0c, 0x8b, 0xe8, 0xc1, 0x45, 0x0a, 0xc0, 0x1c, + 0x9e, 0xe3, 0xc5, 0x2c, 0x1e, 0xbd, 0x17, 0x73, 0xc8, 0xb2, 0x17, 0x13, 0xb5, 0xe1, 0x54, 0x1c, + 0x37, 0xd6, 0x23, 0x7f, 0xc7, 0x4b, 0x48, 0x3a, 0xfb, 0x86, 0x0f, 0xc2, 0xe7, 0x1c, 0xbb, 0xa9, + 0x5e, 0xb9, 0x9c, 0xa5, 0x82, 0xf3, 0x48, 0xa3, 0x0a, 0x9c, 0xf1, 0x83, 0x98, 0x54, 0x3b, 0x11, + 0xb9, 0x52, 0x0f, 0xc2, 0x88, 0x5c, 0x0e, 0x63, 0x4a, 0x4e, 0xdc, 0xb3, 0x55, 0xf1, 0xb4, 0x57, + 0xf2, 0x90, 0x70, 0x7e, 0x5d, 0xb4, 0x04, 0x27, 0x6b, 0x7e, 0xec, 0x6d, 0x36, 0x49, 0xa5, 0xb3, + 0xd9, 0x0a, 0xf9, 0xd1, 0x7c, 0x94, 0x11, 0xbc, 0x5f, 0xda, 0x91, 0x16, 0xb2, 0x08, 0xb8, 0xbb, + 0x0e, 0x7a, 0x06, 0xc6, 0x62, 0x3f, 0xa8, 0x37, 0xc9, 0x5c, 0xe4, 0x05, 0xd5, 0x86, 0xb8, 0xa0, + 0xab, 0xec, 0xed, 0x15, 0xad, 0x0c, 0x1b, 0x98, 0x6c, 0xcd, 0xf3, 0x3a, 0x19, 0x6d, 0x50, 0x60, + 0x8b, 0x52, 0xf7, 0x87, 0x0e, 0x8c, 0xe9, 0xb1, 0xec, 0x54, 0xd3, 0x86, 0xc6, 0xc2, 0x62, 0x85, + 0xef, 0x05, 0xf6, 0x76, 0xfc, 0xcb, 0x8a, 0x66, 0x7a, 0x58, 0x4e, 0x61, 0x58, 0xe3, 0xd9, 0xc7, + 0xcd, 0xf4, 0x47, 0xa0, 0xb8, 0x15, 0x52, 0x85, 0x64, 0xc0, 0x34, 0xd4, 0x2f, 0x52, 0x20, 0xe6, + 0x65, 0xee, 0x7f, 0x73, 0xe0, 0x6c, 0x7e, 0x98, 0xfe, 0xcf, 0x42, 0x27, 0x2f, 0x02, 0xd0, 0xae, + 0x18, 0x42, 0x5d, 0xcb, 0x4d, 0x21, 0x4b, 0xb0, 0x86, 0xd5, 0x5f, 0xb7, 0xff, 0x65, 0x01, 0x34, + 0x9e, 0xe8, 0xf3, 0x0e, 0x8c, 0x53, 0xb6, 0xcb, 0xd1, 0xa6, 0xd1, 0xdb, 0x35, 0x3b, 0xbd, 0x55, + 0x64, 0x53, 0x7f, 0x84, 0x01, 0xc6, 0x26, 0x73, 0xf4, 0x0b, 0x30, 0xea, 0xd5, 0x6a, 0x11, 0x89, + 0x63, 0xe5, 0xd9, 0x63, 0xd6, 0xaa, 0x59, 0x09, 0xc4, 0x69, 0x39, 0x15, 0xa2, 0x8d, 0xda, 0x56, + 0x4c, 0xe5, 0x92, 0x10, 0xdc, 0x4a, 0x88, 0x52, 0x26, 0x14, 0x8e, 0x15, 0x06, 0x7a, 0x1e, 0xce, + 0xd6, 0xbc, 0xc4, 0xe3, 0xfa, 0x1b, 0x89, 0xd6, 0xa3, 0x30, 0x21, 0x55, 0x26, 0xf4, 0x79, 0x04, + 0xea, 0x79, 0x51, 0xf7, 0xec, 0x42, 0x2e, 0x16, 0xee, 0x51, 0xdb, 0xfd, 0xd5, 0x41, 0x30, 0xfb, + 0x84, 0x6a, 0x70, 0x62, 0x3b, 0xda, 0x9c, 0x67, 0x01, 0x17, 0x87, 0x09, 0x7c, 0x60, 0x01, 0x09, + 0xcb, 0x26, 0x05, 0x9c, 0x25, 0x29, 0xb8, 0x2c, 0x93, 0xdd, 0xc4, 0xdb, 0x3c, 0x74, 0xd8, 0xc3, + 0xb2, 0x49, 0x01, 0x67, 0x49, 0xa2, 0x77, 0x43, 0x69, 0x3b, 0xda, 0x94, 0xa2, 0x3f, 0x1b, 0x43, + 0xb3, 0x9c, 0x16, 0x61, 0x1d, 0x8f, 0x7e, 0x9a, 0xed, 0x68, 0x93, 0xee, 0xb6, 0x32, 0x03, 0x84, + 0xfa, 0x34, 0xcb, 0x02, 0x8e, 0x15, 0x06, 0x6a, 0x03, 0xda, 0x96, 0xa3, 0xa7, 0xc2, 0x4b, 0xc4, + 0x0e, 0xd5, 0x7f, 0x74, 0x0a, 0x8b, 0xeb, 0x5f, 0xee, 0xa2, 0x83, 0x73, 0x68, 0xa3, 0x17, 0xe0, + 0xdc, 0x76, 0xb4, 0x29, 0x94, 0x90, 0xf5, 0xc8, 0x0f, 0xaa, 0x7e, 0xdb, 0xc8, 0xf6, 0x30, 0x2d, + 0x9a, 0x7b, 0x6e, 0x39, 0x1f, 0x0d, 0xf7, 0xaa, 0xef, 0xfe, 0xee, 0x20, 0xb0, 0x7b, 0xaa, 0x54, + 0xc6, 0xb6, 0x48, 0xd2, 0x08, 0x6b, 0x59, 0xbd, 0x6a, 0x95, 0x41, 0xb1, 0x28, 0x95, 0xd1, 0xab, + 0x85, 0x1e, 0xd1, 0xab, 0x37, 0x60, 0xb8, 0x41, 0xbc, 0x1a, 0x89, 0xa4, 0x65, 0x72, 0xc5, 0xce, + 0xcd, 0xda, 0xcb, 0x8c, 0x68, 0x7a, 0xbc, 0xe7, 0xbf, 0x63, 0x2c, 0xb9, 0xa1, 0xf7, 0xc0, 0x04, + 0x55, 0x90, 0xc2, 0x4e, 0x22, 0x9d, 0x0b, 0xdc, 0x32, 0xc9, 0x76, 0xea, 0x0d, 0xa3, 0x04, 0x67, + 0x30, 0xd1, 0x02, 0x4c, 0x0a, 0x47, 0x80, 0xb2, 0x78, 0x8a, 0x81, 0x55, 0x69, 0x38, 0x2a, 0x99, + 0x72, 0xdc, 0x55, 0x83, 0x45, 0x1f, 0x86, 0x35, 0xee, 0x0b, 0xd6, 0xa3, 0x0f, 0xc3, 0xda, 0x2e, + 0x66, 0x25, 0xe8, 0x55, 0x18, 0xa1, 0x7f, 0x17, 0xa3, 0xb0, 0x25, 0x6c, 0x3e, 0xeb, 0x76, 0x46, + 0x87, 0xf2, 0x10, 0x27, 0x50, 0xa6, 0x38, 0xce, 0x09, 0x2e, 0x58, 0xf1, 0xa3, 0xe7, 0x20, 0xb9, + 0xbf, 0x57, 0xb6, 0xfd, 0xf6, 0xf3, 0x24, 0xf2, 0xb7, 0x76, 0x99, 0x32, 0x32, 0x92, 0x9e, 0x83, + 0xae, 0x74, 0x61, 0xe0, 0x9c, 0x5a, 0xee, 0xe7, 0x0b, 0x30, 0xa6, 0x5f, 0x77, 0xbe, 0x53, 0x48, + 0x73, 0x9c, 0x4e, 0x0a, 0x7e, 0xea, 0xbd, 0x6c, 0xa1, 0xdb, 0x77, 0x9a, 0x10, 0x0d, 0x18, 0xf4, + 0x3a, 0x42, 0x0b, 0xb5, 0x62, 0x5c, 0x63, 0x3d, 0xee, 0x24, 0x0d, 0x7e, 0x2f, 0x8e, 0x05, 0x1b, + 0x33, 0x0e, 0xee, 0xa7, 0x06, 0x60, 0x44, 0x16, 0xa2, 0x4f, 0x3a, 0x00, 0x69, 0xd0, 0x97, 0x10, + 0xa5, 0xeb, 0x36, 0x22, 0x82, 0xf4, 0x78, 0x35, 0xcd, 0x46, 0xaf, 0xe0, 0x58, 0xe3, 0x8b, 0x12, + 0x18, 0x0a, 0x69, 0xe3, 0x2e, 0xda, 0xbb, 0xb2, 0xbf, 0x46, 0x19, 0x5f, 0x64, 0xdc, 0x53, 0x73, + 0x1c, 0x83, 0x61, 0xc1, 0x8b, 0x9e, 0x2c, 0x37, 0x65, 0x2c, 0xa2, 0x3d, 0xd3, 0xb5, 0x0a, 0x6f, + 0x4c, 0x0f, 0x8a, 0x0a, 0x84, 0x53, 0x86, 0xee, 0x53, 0x30, 0x61, 0x2e, 0x06, 0x7a, 0xd2, 0xd8, + 0xdc, 0x4d, 0x08, 0xb7, 0x63, 0x8c, 0xf1, 0x93, 0xc6, 0x1c, 0x05, 0x60, 0x0e, 0x77, 0xbf, 0xef, + 0x00, 0xa4, 0xe2, 0xa5, 0x0f, 0xd7, 0xc1, 0x23, 0xba, 0x11, 0xae, 0xd7, 0x71, 0xee, 0x63, 0x30, + 0xca, 0xfe, 0x61, 0x0b, 0x7d, 0xc0, 0x56, 0xe4, 0x40, 0xda, 0x4e, 0xb1, 0xd4, 0x99, 0xae, 0xf1, + 0xbc, 0x64, 0x84, 0x53, 0x9e, 0x6e, 0x08, 0x93, 0x59, 0x6c, 0xf4, 0x41, 0x18, 0x8b, 0xe5, 0xb6, + 0x9a, 0x5e, 0xde, 0xeb, 0x73, 0xfb, 0xe5, 0x7e, 0x3b, 0xad, 0x3a, 0x36, 0x88, 0xb9, 0x6b, 0x30, + 0x64, 0x75, 0x08, 0xdd, 0x6f, 0x3b, 0x30, 0xca, 0x5c, 0xa7, 0xf5, 0xc8, 0x6b, 0xa5, 0x55, 0x06, + 0xf6, 0x19, 0xf5, 0x18, 0x86, 0xf9, 0xd9, 0x5f, 0x86, 0x1c, 0x59, 0x90, 0x32, 0x3c, 0xd3, 0x5e, + 0x2a, 0x65, 0xb8, 0x91, 0x21, 0xc6, 0x92, 0x93, 0xfb, 0xe9, 0x02, 0x0c, 0x5d, 0x09, 0xda, 0x9d, + 0xbf, 0xf4, 0xd9, 0xde, 0x56, 0x61, 0xf0, 0x4a, 0x42, 0x5a, 0x66, 0x52, 0xc2, 0xb1, 0xb9, 0x47, + 0xf5, 0x84, 0x84, 0x65, 0x33, 0x21, 0x21, 0xf6, 0x6e, 0xc8, 0x88, 0x3c, 0x61, 0x7b, 0x4e, 0x2f, + 0x30, 0x3e, 0x09, 0xa3, 0x2b, 0xde, 0x26, 0x69, 0x2e, 0x93, 0x5d, 0x76, 0xdd, 0x90, 0x47, 0x87, + 0x38, 0xa9, 0xc1, 0xc0, 0x88, 0xe4, 0x58, 0x80, 0x09, 0x86, 0xad, 0x16, 0x03, 0x3d, 0x91, 0x90, + 0x34, 0xa3, 0x93, 0x63, 0x9e, 0x48, 0xb4, 0x6c, 0x4e, 0x1a, 0x96, 0x3b, 0x03, 0xa5, 0x94, 0x4a, + 0x1f, 0x5c, 0x7f, 0x5a, 0x80, 0x71, 0xc3, 0x84, 0x6e, 0x38, 0x16, 0x9d, 0x3b, 0x3a, 0x16, 0x0d, + 0x47, 0x5f, 0xe1, 0x5e, 0x3b, 0xfa, 0x06, 0x8e, 0xdf, 0xd1, 0x67, 0x7e, 0xa4, 0xc1, 0xbe, 0x3e, + 0x52, 0x13, 0x06, 0x57, 0xfc, 0x60, 0xbb, 0x3f, 0x39, 0x13, 0x57, 0xc3, 0x76, 0x97, 0x9c, 0xa9, + 0x50, 0x20, 0xe6, 0x65, 0x52, 0x73, 0x19, 0xc8, 0xd7, 0x5c, 0xdc, 0x4f, 0x3a, 0x30, 0xb6, 0xea, + 0x05, 0xfe, 0x16, 0x89, 0x13, 0x36, 0xaf, 0x92, 0x23, 0xbd, 0x76, 0x36, 0xd6, 0x23, 0x81, 0xc2, + 0x9b, 0x0e, 0x9c, 0x5c, 0x25, 0xad, 0xd0, 0x7f, 0xd5, 0x4b, 0x03, 0x5e, 0x69, 0xdb, 0x1b, 0x7e, + 0x22, 0xe2, 0xfb, 0x54, 0xdb, 0x2f, 0xfb, 0x09, 0xa6, 0xf0, 0x3b, 0xd8, 0x87, 0xd9, 0x85, 0x0e, + 0x7a, 0x40, 0xd3, 0xae, 0x42, 0xa6, 0xa1, 0xac, 0xb2, 0x00, 0xa7, 0x38, 0xee, 0xef, 0x39, 0x30, + 0xcc, 0x1b, 0xa1, 0x62, 0x84, 0x9d, 0x1e, 0xb4, 0x1b, 0x50, 0x64, 0xf5, 0xc4, 0xac, 0x5e, 0xb2, + 0xa0, 0xfe, 0x50, 0x72, 0x7c, 0x0d, 0xb2, 0x7f, 0x31, 0x67, 0xc0, 0x8e, 0x2d, 0xde, 0xcd, 0x59, + 0x15, 0xeb, 0x9b, 0x1e, 0x5b, 0x18, 0x14, 0x8b, 0x52, 0xf7, 0xeb, 0x03, 0x30, 0xa2, 0xf2, 0x86, + 0xb1, 0xac, 0x0e, 0x41, 0x10, 0x26, 0x1e, 0x8f, 0xa1, 0xe0, 0xb2, 0xfa, 0x83, 0xf6, 0xf2, 0x96, + 0xcd, 0xcc, 0xa6, 0xd4, 0xb9, 0x5f, 0x50, 0x1d, 0x42, 0xb5, 0x12, 0xac, 0x37, 0x02, 0x7d, 0x14, + 0x86, 0x9a, 0x54, 0xfa, 0x48, 0xd1, 0xfd, 0xbc, 0xc5, 0xe6, 0x30, 0xb1, 0x26, 0x5a, 0xa2, 0x46, + 0x88, 0x03, 0xb1, 0xe0, 0x3a, 0xf5, 0x3e, 0x98, 0xcc, 0xb6, 0xfa, 0x4e, 0x37, 0x35, 0x47, 0xf5, + 0x7b, 0x9e, 0x7f, 0x55, 0x48, 0xcf, 0x83, 0x57, 0x75, 0x9f, 0x83, 0xd2, 0x2a, 0x49, 0x22, 0xbf, + 0xca, 0x08, 0xdc, 0x69, 0x72, 0xf5, 0xa5, 0x3f, 0x7c, 0x86, 0x4d, 0x56, 0x4a, 0x33, 0x46, 0xaf, + 0x03, 0xb4, 0xa3, 0x90, 0x9e, 0x5f, 0x49, 0x47, 0x7e, 0x6c, 0x0b, 0xfa, 0xf0, 0xba, 0xa2, 0xc9, + 0x5d, 0xd9, 0xe9, 0x6f, 0xac, 0xf1, 0x73, 0x5f, 0x84, 0xe2, 0x6a, 0x27, 0x21, 0x37, 0xfb, 0x90, + 0x58, 0x07, 0x4d, 0x5d, 0xe0, 0x7e, 0x10, 0xc6, 0x18, 0xed, 0xcb, 0x61, 0x93, 0x6e, 0xab, 0x74, + 0x68, 0x5a, 0xf4, 0x77, 0xd6, 0xd9, 0xc0, 0x90, 0x30, 0x2f, 0xa3, 0x4b, 0xa6, 0x11, 0x36, 0x6b, + 0xea, 0x1a, 0x97, 0x9a, 0x10, 0x97, 0x19, 0x14, 0x8b, 0x52, 0xf7, 0x13, 0x05, 0x28, 0xb1, 0x8a, + 0x42, 0xdc, 0xec, 0xc2, 0x70, 0x83, 0xf3, 0x11, 0x63, 0x68, 0x21, 0x38, 0x4c, 0x6f, 0xbd, 0x76, + 0x96, 0xe3, 0x00, 0x2c, 0xf9, 0x51, 0xd6, 0x37, 0x3c, 0x3f, 0xa1, 0xac, 0x0b, 0x47, 0xcb, 0xfa, + 0x3a, 0x67, 0x83, 0x25, 0x3f, 0xf7, 0x97, 0x81, 0x5d, 0x8f, 0x5e, 0x6c, 0x7a, 0x75, 0x3e, 0x72, + 0xe1, 0x36, 0xa9, 0x09, 0x99, 0xab, 0x8d, 0x1c, 0x85, 0x62, 0x51, 0xca, 0xaf, 0x9c, 0x26, 0x91, + 0xaf, 0xc2, 0xaa, 0xb5, 0x2b, 0xa7, 0x0c, 0x2c, 0x83, 0xe8, 0x6b, 0xee, 0x97, 0x0b, 0x00, 0x2c, + 0xcb, 0x1c, 0xbf, 0xd5, 0xfc, 0x8b, 0x32, 0x02, 0xca, 0x74, 0x50, 0xaa, 0x08, 0x28, 0x76, 0x6f, + 0x5b, 0x8f, 0x7c, 0xd2, 0x6f, 0x3b, 0x14, 0xf6, 0xbf, 0xed, 0x80, 0xda, 0x30, 0x1c, 0x76, 0x12, + 0xaa, 0xab, 0x8a, 0xcd, 0xde, 0x82, 0x7f, 0x7e, 0x8d, 0x13, 0xe4, 0x57, 0x04, 0xc4, 0x0f, 0x2c, + 0xd9, 0xa0, 0x67, 0x60, 0xa4, 0x1d, 0x85, 0x75, 0xba, 0x77, 0x8b, 0xed, 0xfd, 0x41, 0xa9, 0x0f, + 0xad, 0x0b, 0xf8, 0x6d, 0xed, 0x7f, 0xac, 0xb0, 0xdd, 0x3f, 0x9e, 0xe4, 0xe3, 0x22, 0xe6, 0xde, + 0x14, 0x14, 0x7c, 0x69, 0x99, 0x02, 0x41, 0xa2, 0x70, 0x65, 0x01, 0x17, 0xfc, 0x9a, 0x5a, 0x57, + 0x85, 0x9e, 0xeb, 0xea, 0xdd, 0x50, 0xaa, 0xf9, 0x71, 0xbb, 0xe9, 0xed, 0x5e, 0xcd, 0x31, 0x0b, + 0x2e, 0xa4, 0x45, 0x58, 0xc7, 0x43, 0x4f, 0x8a, 0xbb, 0x2d, 0x83, 0x86, 0x29, 0x48, 0xde, 0x6d, + 0x49, 0x6f, 0xcd, 0xf3, 0x6b, 0x2d, 0xd9, 0xec, 0x02, 0xc5, 0xbe, 0xb3, 0x0b, 0x64, 0x35, 0xb1, + 0xa1, 0xe3, 0xd7, 0xc4, 0xde, 0x0b, 0xe3, 0xf2, 0x27, 0x53, 0x8f, 0xca, 0xa7, 0x59, 0xeb, 0x95, + 0x19, 0x7c, 0x43, 0x2f, 0xc4, 0x26, 0x6e, 0x3a, 0x69, 0x87, 0xfb, 0x9d, 0xb4, 0x17, 0x01, 0x36, + 0xc3, 0x4e, 0x50, 0xf3, 0xa2, 0xdd, 0x2b, 0x0b, 0x22, 0x12, 0x56, 0x29, 0x7e, 0x73, 0xaa, 0x04, + 0x6b, 0x58, 0xfa, 0x44, 0x1f, 0xbd, 0xc3, 0x44, 0xff, 0x20, 0x8c, 0xb2, 0xa8, 0x61, 0x52, 0x9b, + 0x4d, 0x44, 0xe8, 0xd2, 0x41, 0x42, 0x31, 0xd3, 0x60, 0x46, 0x49, 0x04, 0xa7, 0xf4, 0xd0, 0x87, + 0x00, 0xb6, 0xfc, 0xc0, 0x8f, 0x1b, 0x8c, 0x7a, 0xe9, 0xc0, 0xd4, 0x55, 0x3f, 0x17, 0x15, 0x15, + 0xac, 0x51, 0x44, 0x2f, 0xc1, 0x49, 0x12, 0x27, 0x7e, 0xcb, 0x4b, 0x48, 0x4d, 0xdd, 0x06, 0x2d, + 0x33, 0x5b, 0xa6, 0x8a, 0xdb, 0xbe, 0x94, 0x45, 0xb8, 0x9d, 0x07, 0xc4, 0xdd, 0x84, 0x8c, 0x15, + 0x39, 0x75, 0x90, 0x15, 0x89, 0xfe, 0xa7, 0x03, 0x27, 0x23, 0xc2, 0xe3, 0x59, 0x62, 0xd5, 0xb0, + 0x33, 0x4c, 0x1c, 0x57, 0x6d, 0x24, 0x70, 0x57, 0x99, 0x5a, 0x70, 0x96, 0x0b, 0x57, 0x5c, 0x88, + 0xec, 0x7d, 0x57, 0xf9, 0xed, 0x3c, 0xe0, 0x9b, 0x6f, 0x4f, 0x4f, 0x77, 0x3f, 0x24, 0xa0, 0x88, + 0xd3, 0x95, 0xf7, 0x37, 0xdf, 0x9e, 0x9e, 0x94, 0xbf, 0xd3, 0x41, 0xeb, 0xea, 0x24, 0xdd, 0x56, + 0xdb, 0x61, 0xed, 0xca, 0xba, 0x88, 0x31, 0x53, 0xdb, 0xea, 0x3a, 0x05, 0x62, 0x5e, 0x86, 0x1e, + 0x87, 0x91, 0x9a, 0x47, 0x5a, 0x61, 0xa0, 0x52, 0xf1, 0x32, 0x6d, 0x7e, 0x41, 0xc0, 0xb0, 0x2a, + 0xa5, 0x67, 0x88, 0x40, 0x6c, 0x29, 0xe5, 0x07, 0x6c, 0x9d, 0x21, 0xe4, 0x26, 0xc5, 0xb9, 0xca, + 0x5f, 0x58, 0x71, 0x42, 0x4d, 0x18, 0xf2, 0x99, 0xa1, 0x42, 0x84, 0xb1, 0x5a, 0xb0, 0x8e, 0x70, + 0xc3, 0x87, 0x0c, 0x62, 0x65, 0xa2, 0x5f, 0xf0, 0xd0, 0xf7, 0x9a, 0x13, 0xc7, 0xb3, 0xd7, 0x3c, + 0x0e, 0x23, 0xd5, 0x86, 0xdf, 0xac, 0x45, 0x24, 0x28, 0x4f, 0xb2, 0x13, 0x3b, 0x1b, 0x89, 0x79, + 0x01, 0xc3, 0xaa, 0x14, 0xfd, 0x15, 0x18, 0x0f, 0x3b, 0x09, 0x13, 0x2d, 0x74, 0x9c, 0xe2, 0xf2, + 0x49, 0x86, 0xce, 0x82, 0x92, 0xd6, 0xf4, 0x02, 0x6c, 0xe2, 0x51, 0x11, 0xdf, 0x08, 0x63, 0x96, + 0x54, 0x88, 0x89, 0xf8, 0xb3, 0xa6, 0x88, 0xbf, 0xac, 0x95, 0x61, 0x03, 0x13, 0x7d, 0xd5, 0x81, + 0x93, 0xad, 0xec, 0x01, 0xae, 0x7c, 0x8e, 0x8d, 0x4c, 0xc5, 0x86, 0xa2, 0x9f, 0x21, 0xcd, 0xc3, + 0xc9, 0xbb, 0xc0, 0xb8, 0xbb, 0x11, 0x2c, 0xbd, 0x57, 0xbc, 0x1b, 0x54, 0x1b, 0x51, 0x18, 0x98, + 0xcd, 0xbb, 0xdf, 0xd6, 0xa5, 0x36, 0xb6, 0xb6, 0xf3, 0x58, 0xcc, 0xdd, 0x7f, 0x6b, 0x6f, 0xfa, + 0x4c, 0x6e, 0x11, 0xce, 0x6f, 0xd4, 0xd4, 0x02, 0x9c, 0xcd, 0x97, 0x0f, 0x77, 0x3a, 0x71, 0x0c, + 0xe8, 0x27, 0x8e, 0x45, 0xb8, 0xbf, 0x67, 0xa3, 0xe8, 0x4e, 0x23, 0xb5, 0x4d, 0xc7, 0xdc, 0x69, + 0xba, 0xb4, 0xc3, 0x09, 0x18, 0xd3, 0x5f, 0x9e, 0x70, 0xff, 0xcf, 0x00, 0x40, 0x6a, 0x27, 0x47, + 0x1e, 0x4c, 0x70, 0x9b, 0xfc, 0x95, 0x85, 0x43, 0x5f, 0xc7, 0x9f, 0x37, 0x08, 0xe0, 0x0c, 0x41, + 0xd4, 0x02, 0xc4, 0x21, 0xfc, 0xf7, 0x61, 0x7c, 0xab, 0xcc, 0x15, 0x39, 0xdf, 0x45, 0x04, 0xe7, + 0x10, 0xa6, 0x3d, 0x4a, 0xc2, 0x6d, 0x12, 0x5c, 0xc3, 0x2b, 0x87, 0xc9, 0xe9, 0xc0, 0xbd, 0x71, + 0x06, 0x01, 0x9c, 0x21, 0x88, 0x5c, 0x18, 0x62, 0xb6, 0x19, 0x19, 0xf8, 0xcd, 0xc4, 0x0b, 0xd3, + 0x34, 0x62, 0x2c, 0x4a, 0xd0, 0x97, 0x1d, 0x98, 0x90, 0xa9, 0x29, 0x98, 0x35, 0x54, 0x86, 0x7c, + 0x5f, 0xb3, 0xe5, 0xe7, 0xb8, 0xa4, 0x53, 0x4f, 0x03, 0x2a, 0x0d, 0x70, 0x8c, 0x33, 0x8d, 0x70, + 0x5f, 0x80, 0x53, 0x39, 0xd5, 0xad, 0x9c, 0x68, 0xbf, 0xe3, 0x40, 0x49, 0xcb, 0x98, 0x88, 0x5e, + 0x87, 0xd1, 0xb0, 0x62, 0x3d, 0x8a, 0x6f, 0xad, 0xd2, 0x15, 0xc5, 0xa7, 0x40, 0x38, 0x65, 0xd8, + 0x4f, 0xf0, 0x61, 0x6e, 0x7a, 0xc7, 0x7b, 0xdc, 0xec, 0x03, 0x07, 0x1f, 0xfe, 0x6a, 0x11, 0x52, + 0x4a, 0x07, 0x4c, 0x99, 0x92, 0x86, 0x2a, 0x16, 0xf6, 0x0d, 0x55, 0xac, 0xc1, 0x09, 0x8f, 0xf9, + 0x92, 0x0f, 0x99, 0x28, 0x85, 0x27, 0xcc, 0x35, 0x29, 0xe0, 0x2c, 0x49, 0xca, 0x25, 0x4e, 0xab, + 0x32, 0x2e, 0x83, 0x07, 0xe6, 0x52, 0x31, 0x29, 0xe0, 0x2c, 0x49, 0xf4, 0x12, 0x94, 0xab, 0xec, + 0xe2, 0x2f, 0xef, 0xe3, 0x95, 0xad, 0xab, 0x61, 0xb2, 0x1e, 0x91, 0x98, 0x04, 0x89, 0x48, 0x89, + 0xf6, 0xb0, 0x18, 0x85, 0xf2, 0x7c, 0x0f, 0x3c, 0xdc, 0x93, 0x02, 0x3d, 0xa6, 0x30, 0x67, 0xb4, + 0x9f, 0xec, 0x32, 0x21, 0x22, 0xbc, 0xf4, 0xea, 0x98, 0x52, 0xd1, 0x0b, 0xb1, 0x89, 0x8b, 0x7e, + 0xc5, 0x81, 0xf1, 0xa6, 0x34, 0xd7, 0xe3, 0x4e, 0x53, 0xe6, 0xf7, 0xc4, 0x56, 0xa6, 0xdf, 0x8a, + 0x4e, 0x99, 0xeb, 0x12, 0x06, 0x08, 0x9b, 0xbc, 0xb3, 0x59, 0x6b, 0x46, 0xfa, 0xcc, 0x5a, 0xf3, + 0x7d, 0x07, 0x26, 0xb3, 0xdc, 0xd0, 0x36, 0x3c, 0xd4, 0xf2, 0xa2, 0xed, 0x2b, 0xc1, 0x56, 0xc4, + 0x2e, 0x78, 0x24, 0x7c, 0x32, 0xcc, 0x6e, 0x25, 0x24, 0x5a, 0xf0, 0x76, 0xb9, 0xfb, 0xb3, 0xa8, + 0x1e, 0x88, 0x7a, 0x68, 0x75, 0x3f, 0x64, 0xbc, 0x3f, 0x2d, 0x54, 0x81, 0x33, 0x14, 0x81, 0x25, + 0xb5, 0xf3, 0xc3, 0x20, 0x65, 0x52, 0x60, 0x4c, 0x54, 0x90, 0xe1, 0x6a, 0x1e, 0x12, 0xce, 0xaf, + 0xeb, 0x5e, 0x82, 0x21, 0x7e, 0xdf, 0xee, 0xae, 0xfc, 0x47, 0xee, 0xbf, 0x29, 0x80, 0x54, 0x0c, + 0xff, 0x72, 0xbb, 0xe3, 0xe8, 0x26, 0x1a, 0x31, 0x93, 0x92, 0xb0, 0x76, 0xb0, 0x4d, 0x54, 0xa4, + 0x8f, 0x14, 0x25, 0x54, 0x63, 0x26, 0x37, 0xfd, 0x64, 0x3e, 0xac, 0x49, 0x1b, 0x07, 0xd3, 0x98, + 0x2f, 0x09, 0x18, 0x56, 0xa5, 0xee, 0x27, 0x1d, 0x18, 0xa7, 0xbd, 0x6c, 0x36, 0x49, 0xb3, 0x92, + 0x90, 0x76, 0x8c, 0x62, 0x28, 0xc6, 0xf4, 0x1f, 0x7b, 0xa6, 0xc0, 0xf4, 0x8e, 0x26, 0x69, 0x6b, + 0xce, 0x1a, 0xca, 0x04, 0x73, 0x5e, 0xee, 0x5b, 0x03, 0x30, 0xaa, 0x06, 0xbb, 0x0f, 0x7b, 0xea, + 0xc5, 0x34, 0xb3, 0x2b, 0x97, 0xc0, 0x65, 0x2d, 0xab, 0xeb, 0x6d, 0x3a, 0x74, 0xc1, 0x2e, 0x4f, + 0x71, 0x91, 0xa6, 0x78, 0x7d, 0xd2, 0x74, 0x35, 0x9f, 0xd5, 0xe7, 0x9f, 0x86, 0x2f, 0x7c, 0xce, + 0x37, 0x75, 0x4f, 0xff, 0xa0, 0xad, 0xdd, 0x4c, 0xb9, 0x31, 0x7b, 0xbb, 0xf8, 0x33, 0x8f, 0xfe, + 0x14, 0xfb, 0x7a, 0xf4, 0xe7, 0x09, 0x18, 0x24, 0x41, 0xa7, 0xc5, 0x54, 0xa5, 0x51, 0x76, 0x44, + 0x18, 0xbc, 0x14, 0x74, 0x5a, 0x66, 0xcf, 0x18, 0x0a, 0x7a, 0x1f, 0x94, 0x6a, 0x24, 0xae, 0x46, + 0x3e, 0xcb, 0xdb, 0x20, 0x2c, 0x3b, 0x0f, 0x32, 0x73, 0x59, 0x0a, 0x36, 0x2b, 0xea, 0x15, 0xdc, + 0x57, 0x61, 0x68, 0xbd, 0xd9, 0xa9, 0xfb, 0x01, 0x6a, 0xc3, 0x10, 0xcf, 0xe2, 0x20, 0x76, 0x7b, + 0x0b, 0xe7, 0x4e, 0x2e, 0x2a, 0xb4, 0x28, 0x14, 0x7e, 0x55, 0x57, 0xf0, 0x71, 0x3f, 0x51, 0x00, + 0x7a, 0x34, 0x5f, 0x9a, 0x47, 0x7f, 0xbd, 0xeb, 0x8d, 0x9b, 0x9f, 0xcb, 0x79, 0xe3, 0x66, 0x9c, + 0x21, 0xe7, 0x3c, 0x6f, 0xd3, 0x84, 0x71, 0xe6, 0x1c, 0x91, 0x7b, 0xa0, 0x50, 0xab, 0x9f, 0xee, + 0x33, 0xf1, 0x81, 0x5e, 0x55, 0xec, 0x08, 0x3a, 0x08, 0x9b, 0xc4, 0xd1, 0x2a, 0x9c, 0xe2, 0x09, + 0x42, 0x17, 0x48, 0xd3, 0xdb, 0xcd, 0x24, 0x02, 0x7b, 0x40, 0x3e, 0x5b, 0xb6, 0xd0, 0x8d, 0x82, + 0xf3, 0xea, 0xb9, 0xbf, 0x3f, 0x08, 0x9a, 0x4b, 0xa2, 0x8f, 0xd5, 0xf2, 0x4a, 0xc6, 0x01, 0xb5, + 0x6a, 0xc5, 0x01, 0x25, 0xbd, 0x3a, 0x5c, 0x02, 0x99, 0x3e, 0x27, 0xda, 0xa8, 0x06, 0x69, 0xb6, + 0x45, 0x1f, 0x55, 0xa3, 0x2e, 0x93, 0x66, 0x1b, 0xb3, 0x12, 0x75, 0x51, 0x71, 0xb0, 0xe7, 0x45, + 0xc5, 0x06, 0x14, 0xeb, 0x5e, 0xa7, 0x4e, 0x44, 0x04, 0xa6, 0x05, 0x5f, 0x23, 0xbb, 0x3a, 0xc1, + 0x7d, 0x8d, 0xec, 0x5f, 0xcc, 0x19, 0xd0, 0xc5, 0xde, 0x90, 0x21, 0x29, 0xc2, 0x48, 0x6b, 0x61, + 0xb1, 0xab, 0x28, 0x17, 0xbe, 0xd8, 0xd5, 0x4f, 0x9c, 0x32, 0x43, 0x6d, 0x18, 0xae, 0xf2, 0xf4, + 0x2b, 0x42, 0x67, 0xb9, 0x62, 0xe3, 0x26, 0x26, 0x23, 0xc8, 0xad, 0x29, 0xe2, 0x07, 0x96, 0x6c, + 0xdc, 0x0b, 0x50, 0xd2, 0x9e, 0xda, 0xa0, 0x9f, 0x41, 0x65, 0xfe, 0xd0, 0x3e, 0xc3, 0x82, 0x97, + 0x78, 0x98, 0x95, 0xb8, 0xdf, 0x1c, 0x04, 0x65, 0x4b, 0xd3, 0xef, 0x0d, 0x7a, 0x55, 0x2d, 0x4f, + 0x91, 0x71, 0x87, 0x3e, 0x0c, 0xb0, 0x28, 0xa5, 0x7a, 0x5d, 0x8b, 0x44, 0x75, 0x75, 0x8e, 0x16, + 0xe2, 0x5a, 0xe9, 0x75, 0xab, 0x7a, 0x21, 0x36, 0x71, 0xa9, 0x52, 0xde, 0x12, 0x2e, 0xfa, 0x6c, + 0x60, 0xb5, 0x74, 0xdd, 0x63, 0x85, 0xc1, 0x12, 0x1d, 0xb4, 0x34, 0x8f, 0xbe, 0x08, 0xc4, 0xb4, + 0xe1, 0x50, 0xd2, 0xa8, 0xf2, 0x80, 0x29, 0x1d, 0x82, 0x0d, 0xae, 0x68, 0x09, 0x4e, 0xc6, 0x24, + 0x59, 0xbb, 0x11, 0x90, 0x48, 0xa5, 0x18, 0x10, 0x99, 0x34, 0xd4, 0xad, 0x8a, 0x4a, 0x16, 0x01, + 0x77, 0xd7, 0xc9, 0x8d, 0x5d, 0x2d, 0x1e, 0x38, 0x76, 0x75, 0x01, 0x26, 0xb7, 0x3c, 0xbf, 0xd9, + 0x89, 0x48, 0xcf, 0x08, 0xd8, 0xc5, 0x4c, 0x39, 0xee, 0xaa, 0xc1, 0x2e, 0xf6, 0x34, 0xbd, 0x7a, + 0x5c, 0x1e, 0xd6, 0x2e, 0xf6, 0x50, 0x00, 0xe6, 0x70, 0xf7, 0xb7, 0x1c, 0xe0, 0x29, 0x8c, 0x66, + 0xb7, 0xb6, 0xfc, 0xc0, 0x4f, 0x76, 0xd1, 0xd7, 0x1c, 0x98, 0x0c, 0xc2, 0x1a, 0x99, 0x0d, 0x12, + 0x5f, 0x02, 0xed, 0xe5, 0x95, 0x67, 0xbc, 0xae, 0x66, 0xc8, 0xf3, 0x7c, 0x18, 0x59, 0x28, 0xee, + 0x6a, 0x86, 0x7b, 0x0e, 0xce, 0xe4, 0x12, 0x70, 0xbf, 0x3f, 0x00, 0x66, 0x26, 0x26, 0xf4, 0x1c, + 0x14, 0x9b, 0x2c, 0x37, 0x88, 0x73, 0xc8, 0x14, 0x5b, 0x6c, 0xac, 0x78, 0xf2, 0x10, 0x4e, 0x09, + 0x2d, 0x40, 0x89, 0xa5, 0x77, 0x12, 0x99, 0x5b, 0x0a, 0x46, 0x4a, 0x84, 0x12, 0x4e, 0x8b, 0x6e, + 0x9b, 0x3f, 0xb1, 0x5e, 0x0d, 0xbd, 0x06, 0xc3, 0x9b, 0x3c, 0xc9, 0xa5, 0x3d, 0x9f, 0x9f, 0xc8, + 0x9a, 0xc9, 0x74, 0x23, 0x99, 0x42, 0xf3, 0x76, 0xfa, 0x2f, 0x96, 0x1c, 0xd1, 0x2e, 0x8c, 0x78, + 0xf2, 0x9b, 0x0e, 0xda, 0xba, 0xa8, 0x61, 0xcc, 0x1f, 0x11, 0x31, 0x23, 0xbf, 0xa1, 0x62, 0x97, + 0x09, 0x2d, 0x2a, 0xf6, 0x15, 0x5a, 0xf4, 0x6d, 0x07, 0x20, 0x7d, 0x11, 0x04, 0xdd, 0x84, 0x91, + 0xf8, 0x69, 0xc3, 0x50, 0x61, 0xe3, 0x86, 0xbe, 0xa0, 0xa8, 0xdd, 0x62, 0x15, 0x10, 0xac, 0xb8, + 0xdd, 0xc9, 0xb8, 0xf2, 0x53, 0x07, 0x4e, 0xe7, 0xbd, 0x5c, 0x72, 0x0f, 0x5b, 0x7c, 0x50, 0xbb, + 0x8a, 0xa8, 0xb0, 0x1e, 0x91, 0x2d, 0xff, 0x66, 0x4e, 0xaa, 0x65, 0x5e, 0x80, 0x53, 0x1c, 0xf7, + 0x4f, 0x87, 0x41, 0x31, 0x3e, 0x22, 0x3b, 0xcc, 0x63, 0xf4, 0xcc, 0x54, 0x4f, 0x75, 0x2e, 0x85, + 0x87, 0x19, 0x14, 0x8b, 0x52, 0x7a, 0x6e, 0x92, 0x41, 0xf1, 0x42, 0x64, 0xb3, 0x59, 0x28, 0x83, + 0xe7, 0xb1, 0x2a, 0xcd, 0xb3, 0xec, 0x14, 0x8f, 0xc5, 0xb2, 0x33, 0x64, 0xdf, 0xb2, 0xd3, 0x02, + 0x14, 0xf3, 0x85, 0xc2, 0xcc, 0x29, 0x82, 0xd1, 0xd8, 0x81, 0x0d, 0xcd, 0x95, 0x2e, 0x22, 0x38, + 0x87, 0x30, 0x8b, 0xa1, 0x08, 0x9b, 0x64, 0x16, 0x5f, 0x15, 0x87, 0x8f, 0x34, 0x86, 0x82, 0x83, + 0xb1, 0x2c, 0x3f, 0xa4, 0x29, 0x05, 0xfd, 0x8e, 0xb3, 0x8f, 0xad, 0x6a, 0xd4, 0xd6, 0x16, 0x94, + 0x9b, 0x06, 0x8f, 0x9d, 0xa4, 0x0e, 0x63, 0x00, 0xfb, 0xba, 0x03, 0x27, 0x49, 0x50, 0x8d, 0x76, + 0x19, 0x1d, 0x41, 0x4d, 0xb8, 0xb8, 0xaf, 0xd9, 0x58, 0xeb, 0x97, 0xb2, 0xc4, 0xb9, 0x27, 0xa9, + 0x0b, 0x8c, 0xbb, 0x9b, 0x81, 0xd6, 0x60, 0xa4, 0xea, 0x89, 0x79, 0x51, 0x3a, 0xc8, 0xbc, 0xe0, + 0x8e, 0xba, 0x59, 0x31, 0x1b, 0x14, 0x11, 0xf7, 0xc7, 0x05, 0x38, 0x95, 0xd3, 0x24, 0x76, 0x5f, + 0xab, 0x45, 0x17, 0xc0, 0x95, 0x5a, 0x76, 0xf9, 0x2f, 0x0b, 0x38, 0x56, 0x18, 0x68, 0x1d, 0x4e, + 0x6f, 0xb7, 0xe2, 0x94, 0xca, 0x7c, 0x18, 0x24, 0xe4, 0xa6, 0x14, 0x06, 0xd2, 0xfd, 0x7d, 0x7a, + 0x39, 0x07, 0x07, 0xe7, 0xd6, 0xa4, 0xda, 0x12, 0x09, 0xbc, 0xcd, 0x26, 0x49, 0x8b, 0xc4, 0x2d, + 0x46, 0xa5, 0x2d, 0x5d, 0xca, 0x94, 0xe3, 0xae, 0x1a, 0xe8, 0xb3, 0x0e, 0x3c, 0x10, 0x93, 0x68, + 0x87, 0x44, 0x15, 0xbf, 0x46, 0xe6, 0x3b, 0x71, 0x12, 0xb6, 0x48, 0x74, 0x48, 0xeb, 0xec, 0xf4, + 0xad, 0xbd, 0xe9, 0x07, 0x2a, 0xbd, 0xa9, 0xe1, 0xfd, 0x58, 0xb9, 0x9f, 0x75, 0x60, 0xa2, 0xc2, + 0xce, 0xee, 0x4a, 0x75, 0xb7, 0x9d, 0x08, 0xf5, 0x31, 0x95, 0x77, 0x23, 0x23, 0x84, 0xcd, 0x4c, + 0x19, 0xee, 0xcb, 0x30, 0x59, 0x21, 0x2d, 0xaf, 0xdd, 0x60, 0x57, 0x90, 0x79, 0xf8, 0xd7, 0x05, + 0x18, 0x8d, 0x25, 0x2c, 0xfb, 0xf6, 0x91, 0x42, 0xc6, 0x29, 0x0e, 0x7a, 0x94, 0x87, 0xaa, 0xc9, + 0x0b, 0x47, 0xa3, 0xfc, 0x90, 0xc3, 0xe3, 0xdb, 0x62, 0x2c, 0xcb, 0xdc, 0xb7, 0x1c, 0x18, 0x4b, + 0xeb, 0x93, 0x2d, 0x54, 0x87, 0x13, 0x55, 0xed, 0xb2, 0x5e, 0x7a, 0x4d, 0xa2, 0xff, 0x7b, 0x7d, + 0x3c, 0x3f, 0xb3, 0x49, 0x04, 0x67, 0xa9, 0x1e, 0x3c, 0xd2, 0xef, 0x0b, 0x05, 0x38, 0xa1, 0x9a, + 0x2a, 0xfc, 0x94, 0x6f, 0x64, 0x03, 0xf2, 0xb0, 0x8d, 0x0c, 0x42, 0xe6, 0xd8, 0xef, 0x13, 0x94, + 0xf7, 0x46, 0x36, 0x28, 0xef, 0x48, 0xd9, 0x77, 0xb9, 0x5e, 0xbf, 0x5d, 0x80, 0x11, 0x95, 0xcf, + 0xe8, 0x39, 0x28, 0xb2, 0x93, 0xeb, 0xdd, 0xe9, 0xdf, 0xec, 0x14, 0x8c, 0x39, 0x25, 0x4a, 0x92, + 0x05, 0xfd, 0x1c, 0x3a, 0x6b, 0xee, 0x28, 0xb7, 0x5f, 0x7a, 0x51, 0x82, 0x39, 0x25, 0xb4, 0x0c, + 0x03, 0x24, 0xa8, 0x09, 0x45, 0xfc, 0xe0, 0x04, 0xd9, 0x2b, 0x65, 0x97, 0x82, 0x1a, 0xa6, 0x54, + 0x58, 0x52, 0x35, 0xae, 0x6f, 0x65, 0xde, 0xa4, 0x11, 0xca, 0x96, 0x28, 0x75, 0xe7, 0xc0, 0x48, + 0xb8, 0x77, 0xa8, 0x9b, 0x11, 0xbf, 0x32, 0x00, 0x43, 0x95, 0xce, 0x26, 0x3d, 0x96, 0x7c, 0xcb, + 0x81, 0x53, 0x37, 0x32, 0x69, 0xa9, 0xd3, 0x75, 0x72, 0xcd, 0x9e, 0x1d, 0x58, 0x0f, 0x5e, 0x53, + 0xd6, 0xaf, 0x9c, 0x42, 0x9c, 0xd7, 0x1c, 0x23, 0x33, 0xec, 0xc0, 0x91, 0x64, 0x86, 0xbd, 0x79, + 0xc4, 0xb7, 0x37, 0xc6, 0x7b, 0xdd, 0xdc, 0x70, 0x7f, 0xbf, 0x08, 0xc0, 0xbf, 0xc6, 0x5a, 0x3b, + 0xe9, 0xc7, 0xb2, 0xf7, 0x0c, 0x8c, 0xd5, 0x49, 0x40, 0x22, 0x19, 0x9a, 0x98, 0x79, 0x32, 0x69, + 0x49, 0x2b, 0xc3, 0x06, 0x26, 0x9b, 0x2c, 0x41, 0x12, 0xed, 0x72, 0x55, 0x3b, 0x7b, 0x43, 0x43, + 0x95, 0x60, 0x0d, 0x0b, 0xcd, 0x18, 0x8e, 0x17, 0xee, 0xc3, 0x9f, 0xd8, 0xc7, 0x4f, 0xf2, 0x3e, + 0x98, 0x30, 0xd3, 0xa8, 0x08, 0x85, 0x4f, 0xf9, 0xdc, 0xcd, 0xec, 0x2b, 0x38, 0x83, 0x4d, 0x17, + 0x42, 0x2d, 0xda, 0xc5, 0x9d, 0x40, 0x68, 0x7e, 0x6a, 0x21, 0x2c, 0x30, 0x28, 0x16, 0xa5, 0x2c, + 0xff, 0x04, 0xdb, 0x03, 0x39, 0x5c, 0xe4, 0xb0, 0x48, 0xf3, 0x4f, 0x68, 0x65, 0xd8, 0xc0, 0xa4, + 0x1c, 0x84, 0x65, 0x14, 0xcc, 0xa5, 0x96, 0x31, 0x67, 0xb6, 0x61, 0x22, 0x34, 0x2d, 0x3a, 0x5c, + 0x0d, 0x7a, 0x57, 0x9f, 0x53, 0xcf, 0xa8, 0xcb, 0x63, 0x25, 0x32, 0x06, 0xa0, 0x0c, 0x7d, 0xaa, + 0xfa, 0xea, 0x17, 0x19, 0xc6, 0xcc, 0xc8, 0xd6, 0x9e, 0x77, 0x0d, 0xd6, 0xe1, 0x74, 0x3b, 0xac, + 0xad, 0x47, 0x7e, 0x18, 0xf9, 0xc9, 0xee, 0x7c, 0xd3, 0x8b, 0x63, 0x36, 0x31, 0xc6, 0x4d, 0x95, + 0x68, 0x3d, 0x07, 0x07, 0xe7, 0xd6, 0xa4, 0x67, 0xa2, 0xb6, 0x00, 0xb2, 0xf8, 0xb2, 0x22, 0x57, + 0xea, 0x24, 0x22, 0x56, 0xa5, 0xee, 0x29, 0x38, 0x59, 0xe9, 0xb4, 0xdb, 0x4d, 0x9f, 0xd4, 0x94, + 0x63, 0xc3, 0x7d, 0x3f, 0x9c, 0x10, 0x79, 0x63, 0x95, 0x02, 0x72, 0xa0, 0x2c, 0xe7, 0xee, 0x7f, + 0x1c, 0x80, 0x13, 0x99, 0x68, 0x1e, 0xf4, 0x5a, 0x56, 0x6d, 0xb0, 0x93, 0xcf, 0x54, 0x53, 0x18, + 0x44, 0x72, 0xd2, 0x3c, 0x15, 0xa4, 0x21, 0x43, 0xf1, 0xad, 0x5d, 0x81, 0x61, 0x01, 0xeb, 0x7c, + 0x57, 0x31, 0xe2, 0xf9, 0x3f, 0x0a, 0xa0, 0xd8, 0xca, 0x5b, 0xf7, 0xb6, 0xfb, 0xc9, 0xd6, 0xaf, + 0x82, 0xc4, 0x58, 0xe3, 0x88, 0x02, 0x18, 0x66, 0x0d, 0x21, 0xf2, 0xde, 0xa5, 0xb5, 0xbe, 0x32, + 0xad, 0x6d, 0x95, 0xd3, 0xc6, 0x92, 0x89, 0xfb, 0x99, 0x02, 0xe4, 0x87, 0x8c, 0xa1, 0x8f, 0x76, + 0x7f, 0xf0, 0xe7, 0x2c, 0x0e, 0x84, 0x88, 0x59, 0xeb, 0xfd, 0xcd, 0x03, 0xf3, 0x9b, 0xaf, 0x5a, + 0x1a, 0x07, 0xc1, 0xb7, 0xeb, 0xcb, 0xbb, 0xff, 0xc3, 0x81, 0xd2, 0xc6, 0xc6, 0x8a, 0xda, 0xda, + 0x31, 0x9c, 0x8d, 0x79, 0x4a, 0x03, 0xe6, 0x59, 0x9f, 0x0f, 0x5b, 0x6d, 0xee, 0x68, 0x17, 0x01, + 0x00, 0x2c, 0x65, 0x71, 0x25, 0x17, 0x03, 0xf7, 0xa8, 0x89, 0xae, 0xc0, 0x29, 0xbd, 0xa4, 0xa2, + 0xbd, 0x10, 0x59, 0x14, 0xe9, 0x89, 0xba, 0x8b, 0x71, 0x5e, 0x9d, 0x2c, 0x29, 0x61, 0x50, 0x66, + 0xdb, 0x73, 0x0e, 0x29, 0x51, 0x8c, 0xf3, 0xea, 0xb8, 0x6b, 0x50, 0xda, 0xf0, 0x22, 0xd5, 0xf1, + 0x0f, 0xc0, 0x64, 0x35, 0x6c, 0x49, 0x75, 0x65, 0x85, 0xec, 0x90, 0xa6, 0xe8, 0x32, 0x7f, 0x96, + 0x25, 0x53, 0x86, 0xbb, 0xb0, 0xdd, 0xff, 0x7a, 0x1e, 0xd4, 0x15, 0xcd, 0x3e, 0x76, 0xd4, 0xb6, + 0x0a, 0xa6, 0x2d, 0x5a, 0x0e, 0xa6, 0x55, 0x7b, 0x4b, 0x26, 0xa0, 0x36, 0x49, 0x03, 0x6a, 0x87, + 0x6c, 0x07, 0xd4, 0x2a, 0x25, 0xbb, 0x2b, 0xa8, 0xf6, 0x2b, 0x0e, 0x8c, 0x05, 0x61, 0x8d, 0x28, + 0x0f, 0xe8, 0x30, 0x5b, 0xe1, 0x2f, 0xd9, 0xbb, 0x9b, 0xc0, 0x83, 0x43, 0x05, 0x79, 0x1e, 0xe8, + 0xad, 0xb6, 0x64, 0xbd, 0x08, 0x1b, 0xed, 0x40, 0x8b, 0x9a, 0x69, 0x99, 0x7b, 0x70, 0x1e, 0xcc, + 0x3b, 0xa2, 0xdd, 0xd1, 0x4e, 0x7c, 0x53, 0xd3, 0x13, 0x47, 0x6d, 0x99, 0x4c, 0xe5, 0xbd, 0x3b, + 0xcd, 0x11, 0x25, 0xb3, 0x6e, 0xa7, 0xfa, 0xa3, 0x0b, 0x43, 0x3c, 0x22, 0x5c, 0x24, 0xc2, 0x62, + 0xfe, 0x51, 0x1e, 0x2d, 0x8e, 0x45, 0x09, 0x4a, 0x64, 0x94, 0x45, 0xc9, 0xd6, 0x1b, 0x1a, 0x46, + 0x14, 0x47, 0x7e, 0x98, 0x05, 0x7a, 0x56, 0x3f, 0xfa, 0x8f, 0xf5, 0x73, 0xf4, 0x1f, 0xef, 0x79, + 0xec, 0xff, 0xbc, 0x03, 0x63, 0x55, 0xed, 0x4d, 0x8b, 0xf2, 0xe3, 0xb6, 0xde, 0xee, 0xce, 0x7b, + 0x7a, 0x84, 0xbb, 0xdd, 0x8c, 0x37, 0x34, 0x0c, 0xee, 0x2c, 0xfb, 0x27, 0xb3, 0x73, 0x30, 0x55, + 0xc7, 0x4a, 0x62, 0x0e, 0xd3, 0x6e, 0x22, 0xa3, 0x55, 0x29, 0x0c, 0x0b, 0x5e, 0xe8, 0x75, 0x18, + 0x91, 0x97, 0x0a, 0x44, 0xf0, 0x3d, 0xb6, 0xe1, 0x07, 0x31, 0x9d, 0xad, 0x32, 0x65, 0x20, 0x87, + 0x62, 0xc5, 0x11, 0x35, 0x60, 0xa0, 0xe6, 0xd5, 0x45, 0x18, 0xfe, 0xaa, 0x9d, 0x94, 0xac, 0x92, + 0x27, 0x3b, 0x92, 0x2e, 0xcc, 0x2e, 0x61, 0xca, 0x02, 0xdd, 0x4c, 0x1f, 0x05, 0x98, 0xb4, 0xb6, + 0xfb, 0x9a, 0x6a, 0x21, 0xd7, 0x09, 0xba, 0xde, 0x18, 0xa8, 0x09, 0xff, 0xf4, 0xff, 0xc7, 0xd8, + 0x2e, 0xda, 0xc9, 0xe9, 0xca, 0x13, 0xbd, 0xa4, 0x3e, 0x6e, 0xca, 0xa5, 0x91, 0x24, 0xed, 0xf2, + 0xcf, 0xdb, 0xe2, 0xc2, 0xd2, 0x95, 0xf0, 0x67, 0xd6, 0x37, 0x36, 0xd6, 0x31, 0xa3, 0x8e, 0x9a, + 0x30, 0xd4, 0x66, 0xa1, 0x33, 0xe5, 0x5f, 0xb0, 0xb5, 0xb7, 0xf0, 0x50, 0x1c, 0x3e, 0x37, 0xf9, + 0xff, 0x58, 0xf0, 0x40, 0x97, 0x60, 0x98, 0xbf, 0x6d, 0xc3, 0xaf, 0x41, 0x94, 0x2e, 0x4e, 0xf5, + 0x7e, 0x21, 0x27, 0xdd, 0x28, 0xf8, 0xef, 0x18, 0xcb, 0xba, 0xe8, 0x0b, 0x0e, 0x4c, 0x50, 0x89, + 0x9a, 0x3e, 0xc6, 0x53, 0x46, 0xb6, 0x64, 0xd6, 0xb5, 0x98, 0x6a, 0x24, 0x52, 0xd6, 0xa8, 0x63, + 0xe1, 0x15, 0x83, 0x1d, 0xce, 0xb0, 0x47, 0x6f, 0xc0, 0x48, 0xec, 0xd7, 0x48, 0xd5, 0x8b, 0xe2, + 0xf2, 0xa9, 0xa3, 0x69, 0x4a, 0xea, 0x11, 0x13, 0x8c, 0xb0, 0x62, 0x89, 0x7e, 0x9d, 0xbd, 0x86, + 0x5a, 0x6d, 0xf8, 0x3b, 0x64, 0x25, 0xac, 0xf2, 0x63, 0xcc, 0x69, 0x5b, 0x6b, 0x5f, 0xfa, 0xfe, + 0x24, 0x65, 0xe1, 0x28, 0x32, 0xd9, 0xe1, 0x2c, 0x7f, 0xf4, 0x37, 0x1c, 0x38, 0xc3, 0x5f, 0x2d, + 0xc8, 0x3e, 0xc4, 0x71, 0xe6, 0x90, 0x26, 0x29, 0x76, 0x7f, 0x63, 0x36, 0x8f, 0x24, 0xce, 0xe7, + 0xc4, 0x72, 0x0c, 0x9b, 0x6f, 0x27, 0x9d, 0xb5, 0xea, 0x19, 0xee, 0xff, 0xbd, 0x24, 0xf4, 0x14, + 0x94, 0xda, 0x62, 0x3b, 0xf4, 0xe3, 0x16, 0xbb, 0x8d, 0x33, 0xc0, 0xef, 0x49, 0xae, 0xa7, 0x60, + 0xac, 0xe3, 0x18, 0x09, 0xa7, 0x9f, 0xd8, 0x2f, 0xe1, 0x34, 0xba, 0x06, 0xa5, 0x24, 0x6c, 0x8a, + 0x9c, 0xab, 0x71, 0xb9, 0xcc, 0x66, 0xe0, 0xf9, 0xbc, 0xb5, 0xb5, 0xa1, 0xd0, 0xd2, 0x93, 0x7b, + 0x0a, 0x8b, 0xb1, 0x4e, 0x87, 0x45, 0x40, 0x8b, 0xd7, 0x20, 0x22, 0x76, 0x64, 0xbf, 0x3f, 0x13, + 0x01, 0xad, 0x17, 0x62, 0x13, 0x17, 0x2d, 0xc1, 0xc9, 0x76, 0xd7, 0x99, 0x9f, 0xdf, 0x02, 0x54, + 0x41, 0x27, 0xdd, 0x07, 0xfe, 0xee, 0x3a, 0xc6, 0x69, 0xff, 0x81, 0xfd, 0x4e, 0xfb, 0x3d, 0xd2, + 0x2f, 0x3f, 0x78, 0x98, 0xf4, 0xcb, 0xa8, 0x06, 0x0f, 0x7a, 0x9d, 0x24, 0x64, 0x29, 0x79, 0xcc, + 0x2a, 0x3c, 0x18, 0xfc, 0x61, 0x1e, 0x5f, 0x7e, 0x6b, 0x6f, 0xfa, 0xc1, 0xd9, 0x7d, 0xf0, 0xf0, + 0xbe, 0x54, 0xd0, 0xab, 0x30, 0x42, 0x44, 0x0a, 0xe9, 0xf2, 0xcf, 0xd9, 0x52, 0x12, 0xcc, 0xa4, + 0xd4, 0x32, 0xce, 0x96, 0xc3, 0xb0, 0xe2, 0x87, 0x36, 0xa0, 0xd4, 0x08, 0xe3, 0x64, 0xb6, 0xe9, + 0x7b, 0x31, 0x89, 0xcb, 0x0f, 0xb1, 0x49, 0x93, 0xab, 0x7b, 0x5d, 0x96, 0x68, 0xe9, 0x9c, 0xb9, + 0x9c, 0xd6, 0xc4, 0x3a, 0x19, 0x44, 0x98, 0x7f, 0x98, 0x45, 0xc2, 0x4b, 0xdf, 0xd7, 0x79, 0xd6, + 0xb1, 0xc7, 0xf2, 0x28, 0xaf, 0x87, 0xb5, 0x8a, 0x89, 0xad, 0x1c, 0xc4, 0x3a, 0x10, 0x67, 0x69, + 0xa2, 0x67, 0x60, 0xac, 0x1d, 0xd6, 0x2a, 0x6d, 0x52, 0x5d, 0xf7, 0x92, 0x6a, 0xa3, 0x3c, 0x6d, + 0x5a, 0x19, 0xd7, 0xb5, 0x32, 0x6c, 0x60, 0xa2, 0x36, 0x0c, 0xb7, 0x78, 0xae, 0x86, 0xf2, 0x23, + 0xb6, 0xce, 0x36, 0x22, 0xf9, 0x83, 0xb0, 0x21, 0xf0, 0x1f, 0x58, 0xb2, 0x41, 0x7f, 0xdf, 0x81, + 0x13, 0x99, 0xfb, 0x65, 0xe5, 0x77, 0x58, 0x53, 0x59, 0x4c, 0xc2, 0x73, 0x8f, 0xb1, 0xe1, 0x33, + 0x81, 0xb7, 0xbb, 0x41, 0x38, 0xdb, 0x22, 0x3e, 0x2e, 0x2c, 0xe1, 0x4a, 0xf9, 0x51, 0x7b, 0xe3, + 0xc2, 0x08, 0xca, 0x71, 0x61, 0x3f, 0xb0, 0x64, 0x83, 0x9e, 0x80, 0x61, 0x91, 0x1b, 0xb1, 0xfc, + 0x98, 0xe9, 0x75, 0x17, 0x29, 0x14, 0xb1, 0x2c, 0x9f, 0x7a, 0x3f, 0x9c, 0xec, 0x3a, 0xba, 0x1d, + 0x28, 0xeb, 0xc7, 0x6f, 0x3a, 0xa0, 0x5f, 0x48, 0xb7, 0xfe, 0x6e, 0xcb, 0x33, 0x30, 0x56, 0xe5, + 0xcf, 0x68, 0xf2, 0x2b, 0xed, 0x83, 0xa6, 0xbd, 0x77, 0x5e, 0x2b, 0xc3, 0x06, 0xa6, 0x7b, 0x19, + 0x50, 0x77, 0x52, 0xfd, 0x43, 0x39, 0x4e, 0xfe, 0xa1, 0x03, 0xe3, 0x86, 0xce, 0x60, 0xdd, 0xaf, + 0xba, 0x08, 0xa8, 0xe5, 0x47, 0x51, 0x18, 0xe9, 0xef, 0x15, 0x8a, 0xb4, 0x13, 0x2c, 0xde, 0x62, + 0xb5, 0xab, 0x14, 0xe7, 0xd4, 0x70, 0xff, 0xf1, 0x20, 0xa4, 0x81, 0xe6, 0x2a, 0x6b, 0xb1, 0xd3, + 0x33, 0x6b, 0xf1, 0x93, 0x30, 0xf2, 0x72, 0x1c, 0x06, 0xeb, 0x69, 0x6e, 0x63, 0xf5, 0x2d, 0x9e, + 0xad, 0xac, 0x5d, 0x65, 0x98, 0x0a, 0x83, 0x61, 0xbf, 0xb2, 0xe8, 0x37, 0x93, 0xee, 0xe4, 0xb7, + 0xcf, 0x3e, 0xc7, 0xe1, 0x58, 0x61, 0xb0, 0xa7, 0x0b, 0x77, 0x88, 0x72, 0x04, 0xa4, 0x4f, 0x17, + 0xf2, 0xf7, 0x32, 0x58, 0x19, 0xba, 0x00, 0xa3, 0xca, 0x89, 0x20, 0x3c, 0x13, 0x6a, 0xa4, 0x94, + 0xa7, 0x01, 0xa7, 0x38, 0x4c, 0x21, 0x14, 0x86, 0x67, 0x61, 0x42, 0xa9, 0xd8, 0x38, 0x9e, 0x64, + 0x4c, 0xd9, 0x5c, 0xb6, 0x4b, 0x30, 0x56, 0x2c, 0xf3, 0x7c, 0xcb, 0xa3, 0x47, 0xe2, 0x5b, 0xd6, + 0x6e, 0x3d, 0x14, 0xfb, 0xbd, 0xf5, 0x60, 0xce, 0xed, 0x91, 0xbe, 0xe6, 0xf6, 0xa7, 0x06, 0x60, + 0xf8, 0x79, 0x12, 0xb1, 0x9c, 0xef, 0x4f, 0xc0, 0xf0, 0x0e, 0xff, 0x37, 0x7b, 0x65, 0x56, 0x60, + 0x60, 0x59, 0x4e, 0xbf, 0xdb, 0x66, 0xc7, 0x6f, 0xd6, 0x16, 0xd2, 0x55, 0x9c, 0xa6, 0x75, 0x94, + 0x05, 0x38, 0xc5, 0xa1, 0x15, 0xea, 0x54, 0xb3, 0x6f, 0xb5, 0xfc, 0xae, 0x57, 0xf9, 0x97, 0x64, + 0x01, 0x4e, 0x71, 0xd0, 0x63, 0x30, 0x54, 0xf7, 0x93, 0x0d, 0xaf, 0x9e, 0xf5, 0x8c, 0x2e, 0x31, + 0x28, 0x16, 0xa5, 0xcc, 0x2d, 0xe6, 0x27, 0x1b, 0x11, 0x61, 0x96, 0xdd, 0xae, 0x8c, 0x1d, 0x4b, + 0x5a, 0x19, 0x36, 0x30, 0x59, 0x93, 0x42, 0xd1, 0x33, 0x11, 0x27, 0x9b, 0x36, 0x49, 0x16, 0xe0, + 0x14, 0x87, 0xce, 0xff, 0x6a, 0xd8, 0x6a, 0xfb, 0x4d, 0x11, 0xc1, 0xad, 0xcd, 0xff, 0x79, 0x01, + 0xc7, 0x0a, 0x83, 0x62, 0x53, 0x11, 0x46, 0xc5, 0x4f, 0xf6, 0x99, 0xb8, 0x75, 0x01, 0xc7, 0x0a, + 0xc3, 0x7d, 0x1e, 0xc6, 0xf9, 0x4a, 0x9e, 0x6f, 0x7a, 0x7e, 0x6b, 0x69, 0x1e, 0x5d, 0xea, 0xba, + 0xf5, 0xf0, 0x44, 0xce, 0xad, 0x87, 0x33, 0x46, 0xa5, 0xee, 0xdb, 0x0f, 0xee, 0x0f, 0x0b, 0x30, + 0x72, 0x8c, 0x2f, 0x6d, 0x1e, 0xfb, 0xa3, 0xd1, 0xe8, 0x66, 0xe6, 0x95, 0xcd, 0x75, 0x9b, 0x97, + 0x98, 0xf6, 0x7d, 0x61, 0xf3, 0x3f, 0x15, 0xe0, 0xac, 0x44, 0x95, 0x67, 0xb9, 0xa5, 0x79, 0xf6, + 0x7a, 0xd9, 0xd1, 0x0f, 0x74, 0x64, 0x0c, 0xf4, 0xba, 0xbd, 0xd3, 0xe8, 0xd2, 0x7c, 0xcf, 0xa1, + 0x7e, 0x35, 0x33, 0xd4, 0xd8, 0x2a, 0xd7, 0xfd, 0x07, 0xfb, 0xcf, 0x1d, 0x98, 0xca, 0x1f, 0xec, + 0x63, 0x78, 0xd8, 0xf4, 0x0d, 0xf3, 0x61, 0xd3, 0x5f, 0xb2, 0x37, 0xc5, 0xcc, 0xae, 0xf4, 0x78, + 0xe2, 0xf4, 0xbf, 0x3b, 0x70, 0x5a, 0x56, 0x60, 0xbb, 0xe7, 0x9c, 0x1f, 0xb0, 0xe0, 0x9d, 0xa3, + 0x9f, 0x66, 0xaf, 0x1b, 0xd3, 0xec, 0x45, 0x7b, 0x1d, 0xd7, 0xfb, 0xd1, 0xf3, 0x41, 0xf8, 0x3f, + 0x73, 0xa0, 0x9c, 0x57, 0xe1, 0x18, 0x3e, 0xf9, 0x6b, 0xe6, 0x27, 0x7f, 0xfe, 0x68, 0x7a, 0xde, + 0xfb, 0x83, 0x97, 0x7b, 0x0d, 0x14, 0x6a, 0x4a, 0xbd, 0xca, 0xb1, 0xe5, 0x93, 0xe6, 0x2c, 0xf2, + 0x15, 0xb4, 0x26, 0x0c, 0xc5, 0x2c, 0x4a, 0x45, 0x4c, 0x81, 0xcb, 0x36, 0xb4, 0x2d, 0x4a, 0x4f, + 0xd8, 0xd8, 0xd9, 0xff, 0x58, 0xf0, 0x70, 0x7f, 0xab, 0x00, 0xe7, 0xd4, 0x83, 0xc5, 0x64, 0x87, + 0x34, 0xd3, 0xf5, 0xc1, 0x5e, 0xc8, 0xf0, 0xd4, 0x4f, 0x7b, 0x2f, 0x64, 0xa4, 0x2c, 0xd2, 0xb5, + 0x90, 0xc2, 0xb0, 0xc6, 0x13, 0x55, 0xe0, 0x0c, 0x7b, 0xd1, 0x62, 0xd1, 0x0f, 0xbc, 0xa6, 0xff, + 0x2a, 0x89, 0x30, 0x69, 0x85, 0x3b, 0x5e, 0x53, 0x68, 0xea, 0xea, 0xd6, 0xf4, 0x62, 0x1e, 0x12, + 0xce, 0xaf, 0xdb, 0x75, 0xe2, 0x1e, 0xe8, 0xf7, 0xc4, 0xed, 0xfe, 0x89, 0x03, 0x63, 0xc7, 0xf8, + 0xbc, 0x73, 0x68, 0x2e, 0x89, 0x67, 0xed, 0x2d, 0x89, 0x1e, 0xcb, 0x60, 0xaf, 0x08, 0x5d, 0x2f, + 0xde, 0xa2, 0x4f, 0x3b, 0x2a, 0x8e, 0x87, 0xc7, 0x4b, 0x7e, 0xc8, 0x5e, 0x3b, 0x0e, 0x92, 0x6a, + 0x13, 0x7d, 0x3d, 0x93, 0x7f, 0xb4, 0x60, 0x2b, 0x89, 0x56, 0x57, 0x6b, 0x0e, 0x91, 0x87, 0xf4, + 0x2b, 0x0e, 0x00, 0x6f, 0xa7, 0x48, 0x5f, 0x4e, 0xdb, 0xb6, 0x79, 0x64, 0x23, 0x45, 0x99, 0xf0, + 0xa6, 0xa9, 0x25, 0x94, 0x16, 0x60, 0xad, 0x25, 0x77, 0x91, 0x60, 0xf4, 0xae, 0x73, 0x9b, 0x7e, + 0xc1, 0x81, 0x13, 0x99, 0xe6, 0xe6, 0xd4, 0xdf, 0x32, 0x1f, 0x68, 0xb4, 0xa0, 0x59, 0x99, 0x49, + 0xad, 0x75, 0xe3, 0xc9, 0x7f, 0x71, 0xc1, 0x78, 0x2a, 0x1c, 0xbd, 0x06, 0xa3, 0xd2, 0xf2, 0x21, + 0xa7, 0xb7, 0xcd, 0x87, 0x6a, 0xd5, 0xf1, 0x46, 0x42, 0x62, 0x9c, 0xf2, 0xcb, 0x84, 0x09, 0x16, + 0xfa, 0x0a, 0x13, 0xbc, 0xb7, 0xcf, 0xdc, 0xe6, 0xdb, 0xa5, 0x07, 0x8f, 0xc4, 0x2e, 0xfd, 0xa0, + 0x75, 0xbb, 0xf4, 0x43, 0xc7, 0x6c, 0x97, 0xd6, 0x9c, 0x84, 0xc5, 0xbb, 0x70, 0x12, 0xbe, 0x06, + 0xa7, 0x77, 0xd2, 0x43, 0xa7, 0x9a, 0x49, 0x22, 0x75, 0xd3, 0x13, 0xb9, 0xd6, 0x68, 0x7a, 0x80, + 0x8e, 0x13, 0x12, 0x24, 0xda, 0x71, 0x35, 0x8d, 0x50, 0x7c, 0x3e, 0x87, 0x1c, 0xce, 0x65, 0x92, + 0xf5, 0xf6, 0x0c, 0xf7, 0xe1, 0xed, 0x79, 0xcb, 0x81, 0x33, 0x5e, 0xd7, 0x35, 0x3b, 0x4c, 0xb6, + 0x44, 0xc8, 0xc9, 0x75, 0x7b, 0x2a, 0x84, 0x41, 0x5e, 0xb8, 0xd5, 0xf2, 0x8a, 0x70, 0x7e, 0x83, + 0xd0, 0xa3, 0xa9, 0xeb, 0x9d, 0xc7, 0xb5, 0xe6, 0xfb, 0xc9, 0xbf, 0x9e, 0x8d, 0xe7, 0x01, 0x36, + 0xf4, 0x1f, 0xb1, 0x7b, 0xda, 0xb6, 0x10, 0xd3, 0x53, 0xba, 0x8b, 0x98, 0x9e, 0x8c, 0xeb, 0x6d, + 0xcc, 0x92, 0xeb, 0x2d, 0x80, 0x49, 0xbf, 0xe5, 0xd5, 0xc9, 0x7a, 0xa7, 0xd9, 0xe4, 0xf7, 0x66, + 0xe4, 0x53, 0xc2, 0xb9, 0x16, 0xbc, 0x95, 0xb0, 0xea, 0x35, 0xb3, 0x8f, 0xc8, 0xab, 0xfb, 0x41, + 0x57, 0x32, 0x94, 0x70, 0x17, 0x6d, 0x3a, 0x61, 0x59, 0x0e, 0x41, 0x92, 0xd0, 0xd1, 0x66, 0x81, + 0x23, 0x23, 0x7c, 0xc2, 0x5e, 0x4e, 0xc1, 0x58, 0xc7, 0x41, 0xcb, 0x30, 0x5a, 0x0b, 0x62, 0x71, + 0x63, 0xf8, 0x04, 0x13, 0x66, 0xef, 0xa4, 0x22, 0x70, 0xe1, 0x6a, 0x45, 0xdd, 0x15, 0x7e, 0x30, + 0x27, 0x29, 0xa6, 0x2a, 0xc7, 0x69, 0x7d, 0xb4, 0xca, 0x88, 0x89, 0x77, 0xd6, 0x78, 0x3c, 0xc7, + 0xc3, 0x3d, 0x1c, 0x46, 0x0b, 0x57, 0xe5, 0x4b, 0x71, 0xe3, 0x82, 0x9d, 0x78, 0x30, 0x2d, 0xa5, + 0xa0, 0x3d, 0xe9, 0x7c, 0x72, 0xdf, 0x27, 0x9d, 0x59, 0x36, 0xdc, 0xa4, 0xa9, 0xdc, 0xc3, 0xe7, + 0xad, 0x65, 0xc3, 0x4d, 0x23, 0x25, 0x45, 0x36, 0xdc, 0x14, 0x80, 0x75, 0x96, 0x68, 0xad, 0x97, + 0x9b, 0xfc, 0x14, 0x13, 0x1a, 0x07, 0x77, 0x7a, 0xeb, 0xfe, 0xd2, 0xd3, 0xfb, 0xfa, 0x4b, 0xbb, + 0xfc, 0xbb, 0x67, 0x0e, 0xe0, 0xdf, 0x6d, 0xb0, 0x3c, 0xa5, 0x4b, 0xf3, 0xc2, 0xa5, 0x6e, 0xe1, + 0x7c, 0xc7, 0x32, 0xa3, 0xf0, 0xc8, 0x53, 0xf6, 0x2f, 0xe6, 0x0c, 0x7a, 0x06, 0x90, 0x9f, 0x3b, + 0x74, 0x00, 0x39, 0x15, 0xcf, 0x29, 0x9c, 0x25, 0xbc, 0x2d, 0x0a, 0xf1, 0x9c, 0x82, 0xb1, 0x8e, + 0x93, 0xf5, 0x96, 0xde, 0x7f, 0x64, 0xde, 0xd2, 0xa9, 0x63, 0xf0, 0x96, 0x3e, 0xd0, 0xb7, 0xb7, + 0xf4, 0x26, 0x9c, 0x6a, 0x87, 0xb5, 0x05, 0x3f, 0x8e, 0x3a, 0xec, 0x22, 0xe1, 0x5c, 0xa7, 0x56, + 0x27, 0x09, 0x73, 0xb7, 0x96, 0x2e, 0xbe, 0x53, 0x6f, 0x64, 0x9b, 0x2d, 0x64, 0xb9, 0x46, 0x33, + 0x15, 0x98, 0xe9, 0x84, 0x45, 0xdd, 0xe6, 0x14, 0xe2, 0x3c, 0x16, 0xba, 0x9f, 0xf6, 0xe1, 0xe3, + 0xf1, 0xd3, 0x7e, 0x00, 0x46, 0xe2, 0x46, 0x27, 0xa9, 0x85, 0x37, 0x02, 0xe6, 0x8c, 0x1f, 0x9d, + 0x7b, 0x87, 0x32, 0x65, 0x0b, 0xf8, 0xed, 0xbd, 0xe9, 0x49, 0xf9, 0xbf, 0x66, 0xc5, 0x16, 0x10, + 0xf4, 0x8d, 0x1e, 0xf7, 0x95, 0xdc, 0xa3, 0xbc, 0xaf, 0x74, 0xee, 0x40, 0x77, 0x95, 0xf2, 0x9c, + 0xd1, 0x8f, 0xfc, 0xcc, 0x39, 0xa3, 0xbf, 0xe6, 0xc0, 0xf8, 0x8e, 0xee, 0x32, 0x10, 0x0e, 0x73, + 0x0b, 0x81, 0x3b, 0x86, 0x27, 0x62, 0xce, 0xa5, 0x72, 0xce, 0x00, 0xdd, 0xce, 0x02, 0xb0, 0xd9, + 0x92, 0x9c, 0xa0, 0xa2, 0x47, 0xef, 0x55, 0x50, 0xd1, 0x1b, 0x4c, 0x8e, 0xc9, 0x43, 0x2e, 0xf3, + 0xa2, 0xdb, 0x8d, 0x29, 0x96, 0x32, 0x51, 0x85, 0x14, 0xeb, 0xfc, 0xd0, 0xe7, 0x1d, 0x98, 0x94, + 0xe7, 0x32, 0xe1, 0xf2, 0x8b, 0x45, 0x54, 0xa4, 0xcd, 0xe3, 0x20, 0x0b, 0xab, 0xdf, 0xc8, 0xf0, + 0xc1, 0x5d, 0x9c, 0xa9, 0x54, 0x57, 0x41, 0x68, 0xf5, 0x98, 0x05, 0xff, 0x0a, 0x1d, 0x66, 0x36, + 0x05, 0x63, 0x1d, 0x07, 0x7d, 0xd3, 0x81, 0x62, 0x23, 0x0c, 0xb7, 0xe3, 0xf2, 0x13, 0x4c, 0xa0, + 0xbf, 0x60, 0x59, 0x37, 0xbd, 0x4c, 0x69, 0x73, 0xa5, 0xf4, 0x29, 0x69, 0x3b, 0x62, 0xb0, 0xdb, + 0x7b, 0xd3, 0x13, 0xc6, 0x73, 0x4e, 0xf1, 0x9b, 0x6f, 0x6b, 0x10, 0x61, 0xdb, 0x64, 0x4d, 0x43, + 0x5f, 0x72, 0x60, 0xf2, 0x46, 0xc6, 0xa0, 0x21, 0xc2, 0x42, 0xb1, 0x7d, 0x53, 0x09, 0x1f, 0xee, + 0x2c, 0x14, 0x77, 0xb5, 0x00, 0x7d, 0xce, 0x34, 0x74, 0xf2, 0xf8, 0x51, 0x8b, 0x03, 0x98, 0x31, + 0xac, 0xf2, 0x6b, 0x41, 0xf9, 0x16, 0xcf, 0xbb, 0x8e, 0x0f, 0x99, 0xa2, 0x9d, 0x49, 0x3f, 0x56, + 0x4e, 0x55, 0x62, 0xda, 0x5b, 0x2c, 0x2c, 0x76, 0xe3, 0xf3, 0xeb, 0xe6, 0x96, 0x2f, 0x9d, 0x85, + 0x09, 0xd3, 0xb7, 0x87, 0xde, 0x65, 0x3e, 0xd5, 0x71, 0x3e, 0xfb, 0xea, 0xc1, 0xb8, 0xc4, 0x37, + 0x5e, 0x3e, 0x30, 0x9e, 0x26, 0x28, 0x1c, 0xe9, 0xd3, 0x04, 0x03, 0xc7, 0xf3, 0x34, 0xc1, 0xe4, + 0x51, 0x3c, 0x4d, 0x70, 0xf2, 0x40, 0x4f, 0x13, 0x68, 0x4f, 0x43, 0x0c, 0xde, 0xe1, 0x69, 0x88, + 0x59, 0x38, 0x21, 0xef, 0xfe, 0x10, 0x91, 0xfd, 0x9d, 0xbb, 0xfd, 0xcf, 0x89, 0x2a, 0x27, 0xe6, + 0xcd, 0x62, 0x9c, 0xc5, 0xa7, 0x8b, 0xac, 0x18, 0xb0, 0x9a, 0x43, 0xb6, 0xde, 0x8d, 0x32, 0xa7, + 0x16, 0x3b, 0x3e, 0x0b, 0x11, 0x25, 0xa3, 0x9d, 0x8b, 0x0c, 0x76, 0x5b, 0xfe, 0x83, 0x79, 0x0b, + 0xd0, 0x4b, 0x50, 0x0e, 0xb7, 0xb6, 0x9a, 0xa1, 0x57, 0x4b, 0xdf, 0x4f, 0x90, 0x71, 0x09, 0xfc, + 0xae, 0xaa, 0x4a, 0xb7, 0xbb, 0xd6, 0x03, 0x0f, 0xf7, 0xa4, 0x80, 0xde, 0xa2, 0x8a, 0x49, 0x12, + 0x46, 0xa4, 0x96, 0xda, 0x6a, 0x46, 0x59, 0x9f, 0x89, 0xf5, 0x3e, 0x57, 0x4c, 0x3e, 0xbc, 0xf7, + 0xea, 0xa3, 0x64, 0x4a, 0x71, 0xb6, 0x59, 0x28, 0x82, 0xb3, 0xed, 0x3c, 0x53, 0x51, 0x2c, 0x6e, + 0x2c, 0xed, 0x67, 0xb0, 0x52, 0x6f, 0x69, 0xe7, 0x1a, 0x9b, 0x62, 0xdc, 0x83, 0xb2, 0xfe, 0xc6, + 0xc1, 0xc8, 0xf1, 0xbc, 0x71, 0xf0, 0x31, 0x80, 0xaa, 0xcc, 0xb6, 0x26, 0x8d, 0x0f, 0xcb, 0x56, + 0xae, 0xd2, 0x70, 0x9a, 0xda, 0xb3, 0xb2, 0x8a, 0x0d, 0xd6, 0x58, 0xa2, 0xff, 0x9d, 0xfb, 0x08, + 0x08, 0xb7, 0xb0, 0xd4, 0xad, 0xcf, 0x89, 0x9f, 0xb9, 0x87, 0x40, 0xfe, 0x81, 0x03, 0x53, 0x7c, + 0xe6, 0x65, 0x95, 0x7b, 0xaa, 0x5a, 0x88, 0xbb, 0x3d, 0xb6, 0x43, 0x57, 0x78, 0xd6, 0x24, 0x83, + 0x2b, 0x73, 0x74, 0xef, 0xd3, 0x12, 0xf4, 0x95, 0x9c, 0x23, 0xc5, 0x09, 0x5b, 0x36, 0xcb, 0xfc, + 0xa7, 0x1c, 0x4e, 0xdd, 0xea, 0xe7, 0x14, 0xf1, 0x8f, 0x7a, 0x9a, 0x54, 0x11, 0x6b, 0xde, 0x2f, + 0x1f, 0x91, 0x49, 0x55, 0x7f, 0x6f, 0xe2, 0x40, 0x86, 0xd5, 0x2f, 0x38, 0x30, 0xe9, 0x65, 0x42, + 0x4d, 0x98, 0x1d, 0xc8, 0x8a, 0x4d, 0x6a, 0x36, 0x4a, 0xe3, 0x57, 0x98, 0x92, 0x97, 0x8d, 0x6a, + 0xc1, 0x5d, 0xcc, 0xd1, 0x0f, 0x1d, 0x78, 0x20, 0xf1, 0xe2, 0x6d, 0x9e, 0xcd, 0x39, 0x4e, 0xef, + 0xea, 0x8a, 0xc6, 0x9d, 0x66, 0xab, 0xf1, 0x15, 0xeb, 0xab, 0x71, 0xa3, 0x37, 0x4f, 0xbe, 0x2e, + 0x1f, 0x11, 0xeb, 0xf2, 0x81, 0x7d, 0x30, 0xf1, 0x7e, 0x4d, 0x9f, 0xfa, 0xb4, 0xc3, 0x5f, 0xfd, + 0xea, 0xa9, 0xf2, 0x6d, 0x9a, 0x2a, 0xdf, 0x8a, 0xcd, 0x77, 0x87, 0x74, 0xdd, 0xf3, 0xd7, 0x1c, + 0x38, 0x9d, 0xb7, 0x23, 0xe5, 0x34, 0xe9, 0x23, 0x66, 0x93, 0x2c, 0x9e, 0xb2, 0xf4, 0x06, 0x59, + 0x79, 0xf6, 0x64, 0xea, 0x2a, 0x3c, 0x7c, 0xa7, 0xaf, 0x78, 0x27, 0x7a, 0x23, 0xba, 0x5a, 0xfc, + 0x67, 0xa3, 0x9a, 0x17, 0x32, 0x21, 0x6d, 0xeb, 0x31, 0xdc, 0x01, 0x0c, 0xf9, 0x41, 0xd3, 0x0f, + 0x88, 0xb8, 0xaf, 0x69, 0xf3, 0x0c, 0x2b, 0x9e, 0x2d, 0xa2, 0xd4, 0xb1, 0xe0, 0x72, 0x8f, 0x9d, + 0x92, 0xd9, 0x87, 0xe0, 0x06, 0x8f, 0xff, 0x21, 0xb8, 0x1b, 0x30, 0x7a, 0xc3, 0x4f, 0x1a, 0x2c, + 0x98, 0x42, 0xf8, 0xfa, 0x2c, 0xdc, 0x73, 0xa4, 0xe4, 0xd2, 0xbe, 0x5f, 0x97, 0x0c, 0x70, 0xca, + 0x0b, 0x5d, 0xe0, 0x8c, 0x59, 0xe4, 0x76, 0x36, 0xa4, 0xf6, 0xba, 0x2c, 0xc0, 0x29, 0x0e, 0x1d, + 0xac, 0x31, 0xfa, 0x4b, 0xe6, 0x80, 0x12, 0x99, 0x91, 0x6d, 0x64, 0xbc, 0x14, 0x14, 0xf9, 0x6d, + 0xe2, 0xeb, 0x1a, 0x0f, 0x6c, 0x70, 0x54, 0xc9, 0xa9, 0x47, 0x7a, 0x26, 0xa7, 0x7e, 0x9d, 0x29, + 0x6c, 0x89, 0x1f, 0x74, 0xc8, 0x5a, 0x20, 0xe2, 0xbd, 0x57, 0xec, 0xdc, 0x7d, 0xe6, 0x34, 0xf9, + 0x11, 0x3c, 0xfd, 0x8d, 0x35, 0x7e, 0x9a, 0xcb, 0xa5, 0xb4, 0xaf, 0xcb, 0x25, 0x35, 0xb9, 0x8c, + 0x59, 0x37, 0xb9, 0x24, 0xa4, 0x6d, 0xc5, 0xe4, 0xf2, 0x33, 0x65, 0x0e, 0xf8, 0x73, 0x07, 0x90, + 0xd2, 0xbb, 0x94, 0x40, 0x3d, 0x86, 0xa0, 0xca, 0x8f, 0x3b, 0x00, 0x81, 0x7a, 0x2e, 0xd4, 0xee, + 0x2e, 0xc8, 0x69, 0xa6, 0x0d, 0x48, 0x61, 0x58, 0xe3, 0xe9, 0xfe, 0xa9, 0x93, 0xc6, 0x2e, 0xa7, + 0x7d, 0x3f, 0x86, 0x20, 0xb2, 0x5d, 0x33, 0x88, 0x6c, 0xc3, 0xa2, 0xe9, 0x5e, 0x75, 0xa3, 0x47, + 0x38, 0xd9, 0x4f, 0x0a, 0x70, 0x42, 0x47, 0xae, 0x90, 0xe3, 0xf8, 0xd8, 0x37, 0x8c, 0x08, 0xda, + 0x6b, 0x76, 0xfb, 0x5b, 0x11, 0x1e, 0xa0, 0xbc, 0x68, 0xed, 0x8f, 0x65, 0xa2, 0xb5, 0xaf, 0xdb, + 0x67, 0xbd, 0x7f, 0xc8, 0xf6, 0x7f, 0x76, 0xe0, 0x54, 0xa6, 0xc6, 0x31, 0x4c, 0xb0, 0x1d, 0x73, + 0x82, 0x3d, 0x67, 0xbd, 0xd7, 0x3d, 0x66, 0xd7, 0xb7, 0x0a, 0x5d, 0xbd, 0x65, 0x87, 0xb8, 0x4f, + 0x39, 0x50, 0xa4, 0xda, 0xb2, 0x8c, 0xe7, 0xfa, 0xc8, 0x91, 0xcc, 0x00, 0xa6, 0xd7, 0x0b, 0xe9, + 0xac, 0xda, 0xc7, 0x60, 0x98, 0x73, 0x9f, 0xfa, 0xa4, 0x03, 0x90, 0x22, 0xdd, 0x2b, 0x15, 0xd8, + 0xfd, 0x4e, 0x01, 0xce, 0xe4, 0x4e, 0x23, 0xf4, 0x19, 0x65, 0x91, 0x73, 0x6c, 0x47, 0x2b, 0x1a, + 0x8c, 0x74, 0xc3, 0xdc, 0xb8, 0x61, 0x98, 0x13, 0xf6, 0xb8, 0x7b, 0x75, 0x80, 0x11, 0x62, 0x5a, + 0x1b, 0xac, 0x1f, 0x3b, 0x69, 0x00, 0xac, 0xca, 0x6b, 0xf4, 0x17, 0xf0, 0x12, 0x8f, 0xfb, 0x13, + 0xed, 0x86, 0x83, 0xec, 0xe8, 0x31, 0xc8, 0x8a, 0x1b, 0xa6, 0xac, 0xc0, 0xf6, 0xfd, 0xc8, 0x3d, + 0x84, 0xc5, 0x2b, 0x90, 0xe7, 0x58, 0xee, 0x2f, 0x09, 0xa4, 0x71, 0x1d, 0xb6, 0xd0, 0xf7, 0x75, + 0xd8, 0x71, 0x28, 0xbd, 0xe8, 0xab, 0x04, 0xa2, 0x73, 0x33, 0xdf, 0xfd, 0xd1, 0xf9, 0xfb, 0xbe, + 0xf7, 0xa3, 0xf3, 0xf7, 0xfd, 0xf0, 0x47, 0xe7, 0xef, 0xfb, 0xf8, 0xad, 0xf3, 0xce, 0x77, 0x6f, + 0x9d, 0x77, 0xbe, 0x77, 0xeb, 0xbc, 0xf3, 0xc3, 0x5b, 0xe7, 0x9d, 0x7f, 0x7b, 0xeb, 0xbc, 0xf3, + 0xb7, 0xfe, 0xdd, 0xf9, 0xfb, 0x5e, 0x1c, 0x91, 0x1d, 0xfb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xbf, 0x5e, 0x27, 0xac, 0x92, 0xd8, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -11109,9 +11109,9 @@ func (m *StopStrategy) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - i -= len(m.Condition) - copy(dAtA[i:], m.Condition) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Condition))) + 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 @@ -16364,7 +16364,7 @@ func (m *StopStrategy) Size() (n int) { } var l int _ = l - l = len(m.Condition) + l = len(m.Expression) n += 1 + l + sovGenerated(uint64(l)) return n } @@ -19021,7 +19021,7 @@ func (this *StopStrategy) String() string { return "nil" } s := strings.Join([]string{`&StopStrategy{`, - `Condition:` + fmt.Sprintf("%v", this.Condition) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, `}`, }, "") return s @@ -38336,7 +38336,7 @@ func (m *StopStrategy) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Condition", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -38364,7 +38364,7 @@ func (m *StopStrategy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Condition = string(dAtA[iNdEx:postIndex]) + m.Expression = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto index 8bc4eb9b9dec3..5280f8c1f9610 100644 --- a/pkg/apis/workflow/v1alpha1/generated.proto +++ b/pkg/apis/workflow/v1alpha1/generated.proto @@ -1490,11 +1490,11 @@ message Sequence { optional string format = 4; } -// v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +// StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after message StopStrategy { - // v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the - // variables `failed` or `succeeded` to access the number of failed or successful child workflows. - optional string condition = 1; + // v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables + // `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. + optional string expression = 1; } message Submit { diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index 90bc5cd7ad1dd..893b7bebc77ae 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -5972,19 +5972,19 @@ func schema_pkg_apis_workflow_v1alpha1_StopStrategy(ref common.ReferenceCallback return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition", + Description: "StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "condition": { + "expression": { SchemaProps: spec.SchemaProps{ - Description: "v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.", + Description: "v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.", Default: "", Type: []string{"string"}, Format: "", }, }, }, - Required: []string{"condition"}, + Required: []string{"expression"}, }, }, } diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md index f644e834e4938..0d52970e5b80c 100644 --- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md @@ -2,13 +2,13 @@ # IoArgoprojWorkflowV1alpha1StopStrategy -v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**condition** | **String** | v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. | +**expression** | **String** | v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. | diff --git a/sdks/java/client/docs/WorkflowServiceApi.md b/sdks/java/client/docs/WorkflowServiceApi.md index ab2d95d3fbbd9..d99bc3d916239 100644 --- a/sdks/java/client/docs/WorkflowServiceApi.md +++ b/sdks/java/client/docs/WorkflowServiceApi.md @@ -323,7 +323,7 @@ Name | Type | Description | Notes # **workflowServiceListWorkflows** -> IoArgoprojWorkflowV1alpha1WorkflowList workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields) +> IoArgoprojWorkflowV1alpha1WorkflowList workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields, nameFilter) @@ -361,8 +361,9 @@ public class Example { String listOptionsContinue = "listOptionsContinue_example"; // String | The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. Boolean listOptionsSendInitialEvents = true; // Boolean | `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional String fields = "fields_example"; // String | Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". + String nameFilter = "nameFilter_example"; // String | Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. try { - IoArgoprojWorkflowV1alpha1WorkflowList result = apiInstance.workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields); + IoArgoprojWorkflowV1alpha1WorkflowList result = apiInstance.workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields, nameFilter); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling WorkflowServiceApi#workflowServiceListWorkflows"); @@ -391,6 +392,7 @@ Name | Type | Description | Notes **listOptionsContinue** | **String**| The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. | [optional] **listOptionsSendInitialEvents** | **Boolean**| `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional | [optional] **fields** | **String**| Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". | [optional] + **nameFilter** | **String**| Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. | [optional] ### Return type diff --git a/sdks/python/README.md b/sdks/python/README.md index 2c1c7c4be57c9..8fe16af8e04f3 100644 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -2,6 +2,10 @@ This is the Python SDK for Argo Workflows. +> [!WARNING] +> This SDK is deprecated and will be removed in version 3.7 of Argo Workflows. +> We recommend migrating to [Hera](https://github.com/argoproj-labs/hera). + ## Requirements Python >= 3.6 diff --git a/sdks/python/client/argo_workflows/api/workflow_service_api.py b/sdks/python/client/argo_workflows/api/workflow_service_api.py index b000b92a4a624..29d73f0bac40d 100644 --- a/sdks/python/client/argo_workflows/api/workflow_service_api.py +++ b/sdks/python/client/argo_workflows/api/workflow_service_api.py @@ -351,6 +351,7 @@ def __init__(self, api_client=None): 'list_options_continue', 'list_options_send_initial_events', 'fields', + 'name_filter', ], 'required': [ 'namespace', @@ -392,6 +393,8 @@ def __init__(self, api_client=None): (bool,), 'fields': (str,), + 'name_filter': + (str,), }, 'attribute_map': { 'namespace': 'namespace', @@ -406,6 +409,7 @@ def __init__(self, api_client=None): 'list_options_continue': 'listOptions.continue', 'list_options_send_initial_events': 'listOptions.sendInitialEvents', 'fields': 'fields', + 'name_filter': 'nameFilter', }, 'location_map': { 'namespace': 'path', @@ -420,6 +424,7 @@ def __init__(self, api_client=None): 'list_options_continue': 'query', 'list_options_send_initial_events': 'query', 'fields': 'query', + 'name_filter': 'query', }, 'collection_format_map': { } @@ -1752,6 +1757,7 @@ def list_workflows( list_options_continue (str): The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.. [optional] list_options_send_initial_events (bool): `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional. [optional] fields (str): Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\".. [optional] + name_filter (str): Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact.. [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py index 9bf92e344fbc2..4293f0145f15e 100644 --- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py @@ -81,7 +81,7 @@ def openapi_types(): and the value is attribute type. """ return { - 'condition': (str,), # noqa: E501 + 'expression': (str,), # noqa: E501 } @cached_property @@ -90,7 +90,7 @@ def discriminator(): attribute_map = { - 'condition': 'condition', # noqa: E501 + 'expression': 'expression', # noqa: E501 } read_only_vars = { @@ -100,11 +100,11 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, condition, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, expression, *args, **kwargs): # noqa: E501 """IoArgoprojWorkflowV1alpha1StopStrategy - a model defined in OpenAPI Args: - condition (str): v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. + expression (str): v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -164,7 +164,7 @@ def _from_openapi_data(cls, condition, *args, **kwargs): # noqa: E501 self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.condition = condition + self.expression = expression for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -185,11 +185,11 @@ def _from_openapi_data(cls, condition, *args, **kwargs): # noqa: E501 ]) @convert_js_args_to_python_args - def __init__(self, condition, *args, **kwargs): # noqa: E501 + def __init__(self, expression, *args, **kwargs): # noqa: E501 """IoArgoprojWorkflowV1alpha1StopStrategy - a model defined in OpenAPI Args: - condition (str): v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. + expression (str): v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -247,7 +247,7 @@ def __init__(self, condition, *args, **kwargs): # noqa: E501 self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.condition = condition + self.expression = expression for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/sdks/python/client/docs/CronWorkflowServiceApi.md b/sdks/python/client/docs/CronWorkflowServiceApi.md index c7c5ec6a921ee..3fe110e35addc 100644 --- a/sdks/python/client/docs/CronWorkflowServiceApi.md +++ b/sdks/python/client/docs/CronWorkflowServiceApi.md @@ -115,7 +115,7 @@ with argo_workflows.ApiClient(configuration) as api_client: ], starting_deadline_seconds=1, stop_strategy=IoArgoprojWorkflowV1alpha1StopStrategy( - condition="condition_example", + expression="expression_example", ), successful_jobs_history_limit=1, suspend=True, @@ -11684,7 +11684,7 @@ with argo_workflows.ApiClient(configuration) as api_client: ], starting_deadline_seconds=1, stop_strategy=IoArgoprojWorkflowV1alpha1StopStrategy( - condition="condition_example", + expression="expression_example", ), successful_jobs_history_limit=1, suspend=True, @@ -23340,7 +23340,7 @@ with argo_workflows.ApiClient(configuration) as api_client: ], starting_deadline_seconds=1, stop_strategy=IoArgoprojWorkflowV1alpha1StopStrategy( - condition="condition_example", + expression="expression_example", ), successful_jobs_history_limit=1, suspend=True, diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md index 035cce4f5b22e..5c3dc47771147 100644 --- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md @@ -1,11 +1,11 @@ # IoArgoprojWorkflowV1alpha1StopStrategy -v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**condition** | **str** | v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. | +**expression** | **str** | v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/sdks/python/client/docs/WorkflowServiceApi.md b/sdks/python/client/docs/WorkflowServiceApi.md index 9a7be230c42cc..b2288e27aaeef 100644 --- a/sdks/python/client/docs/WorkflowServiceApi.md +++ b/sdks/python/client/docs/WorkflowServiceApi.md @@ -57770,6 +57770,7 @@ with argo_workflows.ApiClient(configuration) as api_client: list_options_continue = "listOptions.continue_example" # str | The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. (optional) list_options_send_initial_events = True # bool | `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional (optional) fields = "fields_example" # str | Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". (optional) + name_filter = "nameFilter_example" # str | Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. (optional) # example passing only required values which don't have defaults set try: @@ -57781,7 +57782,7 @@ with argo_workflows.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.list_workflows(namespace, list_options_label_selector=list_options_label_selector, list_options_field_selector=list_options_field_selector, list_options_watch=list_options_watch, list_options_allow_watch_bookmarks=list_options_allow_watch_bookmarks, list_options_resource_version=list_options_resource_version, list_options_resource_version_match=list_options_resource_version_match, list_options_timeout_seconds=list_options_timeout_seconds, list_options_limit=list_options_limit, list_options_continue=list_options_continue, list_options_send_initial_events=list_options_send_initial_events, fields=fields) + api_response = api_instance.list_workflows(namespace, list_options_label_selector=list_options_label_selector, list_options_field_selector=list_options_field_selector, list_options_watch=list_options_watch, list_options_allow_watch_bookmarks=list_options_allow_watch_bookmarks, list_options_resource_version=list_options_resource_version, list_options_resource_version_match=list_options_resource_version_match, list_options_timeout_seconds=list_options_timeout_seconds, list_options_limit=list_options_limit, list_options_continue=list_options_continue, list_options_send_initial_events=list_options_send_initial_events, fields=fields, name_filter=name_filter) pprint(api_response) except argo_workflows.ApiException as e: print("Exception when calling WorkflowServiceApi->list_workflows: %s\n" % e) @@ -57804,6 +57805,7 @@ Name | Type | Description | Notes **list_options_continue** | **str**| The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. | [optional] **list_options_send_initial_events** | **bool**| `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional | [optional] **fields** | **str**| Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". | [optional] + **name_filter** | **str**| Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. | [optional] ### Return type diff --git a/server/cronworkflow/cron_workflow_server.go b/server/cronworkflow/cron_workflow_server.go index 49d45bffea4cd..cd8012a613208 100644 --- a/server/cronworkflow/cron_workflow_server.go +++ b/server/cronworkflow/cron_workflow_server.go @@ -35,7 +35,7 @@ func (c *cronWorkflowServiceServer) LintCronWorkflow(ctx context.Context, req *c cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().ClusterWorkflowTemplates()) c.instanceIDService.Label(req.CronWorkflow) creator.Label(ctx, req.CronWorkflow) - err := validate.ValidateCronWorkflow(wftmplGetter, cwftmplGetter, req.CronWorkflow) + err := validate.ValidateCronWorkflow(ctx, wftmplGetter, cwftmplGetter, req.CronWorkflow) if err != nil { return nil, sutils.ToStatusError(err, codes.InvalidArgument) } @@ -64,7 +64,7 @@ func (c *cronWorkflowServiceServer) CreateCronWorkflow(ctx context.Context, req creator.Label(ctx, req.CronWorkflow) wftmplGetter := templateresolution.WrapWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().WorkflowTemplates(req.Namespace)) cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().ClusterWorkflowTemplates()) - err := validate.ValidateCronWorkflow(wftmplGetter, cwftmplGetter, req.CronWorkflow) + err := validate.ValidateCronWorkflow(ctx, wftmplGetter, cwftmplGetter, req.CronWorkflow) if err != nil { return nil, sutils.ToStatusError(err, codes.InvalidArgument) } @@ -91,7 +91,7 @@ func (c *cronWorkflowServiceServer) UpdateCronWorkflow(ctx context.Context, req } wftmplGetter := templateresolution.WrapWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().WorkflowTemplates(req.Namespace)) cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().ClusterWorkflowTemplates()) - if err := validate.ValidateCronWorkflow(wftmplGetter, cwftmplGetter, req.CronWorkflow); err != nil { + if err := validate.ValidateCronWorkflow(ctx, wftmplGetter, cwftmplGetter, req.CronWorkflow); err != nil { return nil, sutils.ToStatusError(err, codes.InvalidArgument) } crWf, err := auth.GetWfClient(ctx).ArgoprojV1alpha1().CronWorkflows(req.Namespace).Update(ctx, req.CronWorkflow, metav1.UpdateOptions{}) diff --git a/server/utils/list_options.go b/server/utils/list_options.go index 69a03456cbd56..978592db3a146 100644 --- a/server/utils/list_options.go +++ b/server/utils/list_options.go @@ -13,12 +13,13 @@ import ( ) type ListOptions struct { - Namespace, Name, NamePrefix string - MinStartedAt, MaxStartedAt time.Time - LabelRequirements labels.Requirements - Limit, Offset int - ShowRemainingItemCount bool - StartedAtAscending bool + Namespace, Name string + NamePrefix, NameFilter string + MinStartedAt, MaxStartedAt time.Time + LabelRequirements labels.Requirements + Limit, Offset int + ShowRemainingItemCount bool + StartedAtAscending bool } func (l ListOptions) WithLimit(limit int) ListOptions { @@ -51,10 +52,11 @@ func (l ListOptions) WithStartedAtAscending(ascending bool) ListOptions { return l } -func BuildListOptions(options metav1.ListOptions, ns, namePrefix string) (ListOptions, error) { +func BuildListOptions(options metav1.ListOptions, ns, namePrefix, nameFilter string) (ListOptions, error) { if options.Continue == "" { options.Continue = "0" } + limit := int(options.Limit) offset, err := strconv.Atoi(options.Continue) @@ -123,6 +125,7 @@ func BuildListOptions(options metav1.ListOptions, ns, namePrefix string) (ListOp Namespace: namespace, Name: name, NamePrefix: namePrefix, + NameFilter: nameFilter, MinStartedAt: minStartedAt, MaxStartedAt: maxStartedAt, LabelRequirements: requirements, diff --git a/server/workflow/store/lister.go b/server/workflow/store/lister.go index 3a2dc0870a7a4..e50ab6938e3e8 100644 --- a/server/workflow/store/lister.go +++ b/server/workflow/store/lister.go @@ -10,8 +10,8 @@ import ( ) type WorkflowLister interface { - ListWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) - CountWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (int64, error) + ListWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) + CountWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (int64, error) } type kubeLister struct { @@ -24,7 +24,7 @@ func NewKubeLister(wfClient versioned.Interface) WorkflowLister { return &kubeLister{wfClient: wfClient} } -func (k *kubeLister) ListWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { +func (k *kubeLister) ListWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { wfList, err := k.wfClient.ArgoprojV1alpha1().Workflows(namespace).List(ctx, listOptions) if err != nil { return nil, err @@ -32,7 +32,7 @@ func (k *kubeLister) ListWorkflows(ctx context.Context, namespace, namePrefix st return wfList, nil } -func (k *kubeLister) CountWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (int64, error) { +func (k *kubeLister) CountWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (int64, error) { wfList, err := k.wfClient.ArgoprojV1alpha1().Workflows(namespace).List(ctx, listOptions) if err != nil { return 0, err diff --git a/server/workflow/store/sqlite_store.go b/server/workflow/store/sqlite_store.go index c06eda14e4c3e..2c8aecfbc84e8 100644 --- a/server/workflow/store/sqlite_store.go +++ b/server/workflow/store/sqlite_store.go @@ -88,8 +88,8 @@ func NewSQLiteStore(instanceService instanceid.Service) (*SQLiteStore, error) { return &SQLiteStore{conn: conn, instanceService: instanceService}, nil } -func (s *SQLiteStore) ListWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { - options, err := sutils.BuildListOptions(listOptions, namespace, namePrefix) +func (s *SQLiteStore) ListWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { + options, err := sutils.BuildListOptions(listOptions, namespace, "", nameFilter) if err != nil { return nil, err } @@ -129,8 +129,8 @@ where instanceid = ? }, nil } -func (s *SQLiteStore) CountWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (int64, error) { - options, err := sutils.BuildListOptions(listOptions, namespace, namePrefix) +func (s *SQLiteStore) CountWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (int64, error) { + options, err := sutils.BuildListOptions(listOptions, namespace, "", nameFilter) if err != nil { return 0, err } diff --git a/server/workflow/store/sqlite_store_test.go b/server/workflow/store/sqlite_store_test.go index e79477aa4d0bb..cc96e4d0b8f9d 100644 --- a/server/workflow/store/sqlite_store_test.go +++ b/server/workflow/store/sqlite_store_test.go @@ -133,6 +133,45 @@ func TestStoreOperation(t *testing.T) { require.NoError(t, err) assert.Len(t, wfList.Items, 5) }) + t.Run("TestListWorkflows name", func(t *testing.T) { + wfList, err := store.ListWorkflows(context.Background(), "argo", "Exact", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=flow"}) + require.NoError(t, err) + assert.Empty(t, wfList.Items) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Exact", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + }) + t.Run("TestListWorkflows namePrefix", func(t *testing.T) { + wfList, err := store.ListWorkflows(context.Background(), "argo", "Prefix", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=flow"}) + require.NoError(t, err) + assert.Empty(t, wfList.Items) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Prefix", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 5) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Prefix", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + }) + t.Run("TestListWorkflows namePattern", func(t *testing.T) { + wfList, err := store.ListWorkflows(context.Background(), "argo", "Contains", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=non-existing-pattern"}) + require.NoError(t, err) + assert.Empty(t, wfList.Items) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Contains", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=flow"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 5) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Contains", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + }) t.Run("TestCountWorkflows", func(t *testing.T) { num, err := store.CountWorkflows(context.Background(), "argo", "", metav1.ListOptions{}) require.NoError(t, err) diff --git a/server/workflow/workflow_server.go b/server/workflow/workflow_server.go index 7c0c36182e3b3..6f8e08a7386d5 100644 --- a/server/workflow/workflow_server.go +++ b/server/workflow/workflow_server.go @@ -173,7 +173,8 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor } s.instanceIDService.With(&listOption) - options, err := sutils.BuildListOptions(listOption, req.Namespace, "") + options, err := sutils.BuildListOptions(listOption, req.Namespace, "", req.NameFilter) + if err != nil { return nil, err } @@ -187,7 +188,7 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor } var wfs wfv1.Workflows - liveWfCount, err := s.wfLister.CountWorkflows(ctx, req.Namespace, "", listOption) + liveWfCount, err := s.wfLister.CountWorkflows(ctx, req.Namespace, req.NameFilter, listOption) if err != nil { return nil, sutils.ToStatusError(err, codes.Internal) } @@ -200,7 +201,7 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor // first fetch live workflows liveWfList := &wfv1.WorkflowList{} if liveWfCount > 0 && (options.Limit == 0 || options.Offset < int(liveWfCount)) { - liveWfList, err = s.wfLister.ListWorkflows(ctx, req.Namespace, "", listOption) + liveWfList, err = s.wfLister.ListWorkflows(ctx, req.Namespace, req.NameFilter, listOption) if err != nil { return nil, sutils.ToStatusError(err, codes.Internal) } diff --git a/server/workflowarchive/archived_workflow_server.go b/server/workflowarchive/archived_workflow_server.go index 2f6c69369dce4..a3c8500783b2b 100644 --- a/server/workflowarchive/archived_workflow_server.go +++ b/server/workflowarchive/archived_workflow_server.go @@ -41,7 +41,7 @@ func NewWorkflowArchiveServer(wfArchive sqldb.WorkflowArchive, offloadNodeStatus func (w *archivedWorkflowServer) ListArchivedWorkflows(ctx context.Context, req *workflowarchivepkg.ListArchivedWorkflowsRequest) (*wfv1.WorkflowList, error) { - options, err := sutils.BuildListOptions(*req.ListOptions, req.Namespace, req.NamePrefix) + options, err := sutils.BuildListOptions(*req.ListOptions, req.Namespace, req.NamePrefix, "") if err != nil { return nil, err } diff --git a/test/e2e/cron_test.go b/test/e2e/cron_test.go index ebe4101016636..3e51d6ef618ba 100644 --- a/test/e2e/cron_test.go +++ b/test/e2e/cron_test.go @@ -357,7 +357,7 @@ spec: successfulJobsHistoryLimit: 4 failedJobsHistoryLimit: 2 stopStrategy: - condition: "succeeded >= 1" + expression: "cronworkflow.succeeded >= 1" workflowSpec: metadata: labels: @@ -391,7 +391,7 @@ spec: schedule: "* * * * *" concurrencyPolicy: "Allow" stopStrategy: - condition: "failed >= 1" + expression: "cronworkflow.failed >= 1" workflowSpec: metadata: labels: diff --git a/test/e2e/metrics_test.go b/test/e2e/metrics_test.go index 3c17afdc0175e..61d8d092d6ac1 100644 --- a/test/e2e/metrics_test.go +++ b/test/e2e/metrics_test.go @@ -94,6 +94,74 @@ func (s *MetricsSuite) TestDAGMetrics() { }) } +func (s *MetricsSuite) TestDeprecatedCronSchedule() { + s.Given(). + CronWorkflow(`@testdata/cronworkflow-deprecated-schedule.yaml`). + When(). + CreateCronWorkflow(). + Wait(1 * time.Minute). // This pattern is used in cron_test.go too + Then(). + ExpectCron(func(t *testing.T, cronWf *wfv1.CronWorkflow) { + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="cronworkflow schedule",namespace="argo"}`) // Count unimportant and unknown + }) +} + +func (s *MetricsSuite) TestDeprecatedMutex() { + s.Given(). + Workflow(`@testdata/synchronization-deprecated-mutex.yaml`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="synchronization mutex",namespace="argo"}`) // Count unimportant and unknown + }) +} + +func (s *MetricsSuite) TestDeprecatedPodPriority() { + s.Given(). + Workflow(`@testdata/workflow-deprecated-podpriority.yaml`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeErrored). // Fails as kubernetes we test on do not support this1 + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="workflow podpriority",namespace="argo"}`) // Count unimportant and unknown + }) +} + +func (s *MetricsSuite) TestDeprecatedSemaphore() { + s.Given(). + Workflow(`@testdata/synchronization-deprecated-semaphore.yaml`). + When(). + CreateConfigMap("my-config", map[string]string{"workflow": "1"}, map[string]string{}). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + DeleteConfigMap("my-config"). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="synchronization semaphore",namespace="argo"}`) // Count unimportant and unknown + }) +} + func (s *MetricsSuite) TestFailedMetric() { s.Given(). Workflow(`@testdata/template-status-failed-conditional-metric.yaml`). diff --git a/test/e2e/testdata/cronworkflow-deprecated-schedule.yaml b/test/e2e/testdata/cronworkflow-deprecated-schedule.yaml new file mode 100644 index 0000000000000..abfda0b51fde6 --- /dev/null +++ b/test/e2e/testdata/cronworkflow-deprecated-schedule.yaml @@ -0,0 +1,21 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: test-cron-deprecated-schedule +spec: + schedules: + - "* * * * *" + concurrencyPolicy: "Forbid" + startingDeadlineSeconds: 0 + workflowSpec: + metadata: + labels: + workflows.argoproj.io/test: "true" + podGC: + strategy: OnPodCompletion + entrypoint: sleep + templates: + - name: sleep + container: + image: alpine:latest + command: [sh, -c, "sleep 120"] diff --git a/test/e2e/testdata/cronworkflow-metrics-forbid.yaml b/test/e2e/testdata/cronworkflow-metrics-forbid.yaml index 7e4cb97c4ad72..0b3a40ad97a98 100644 --- a/test/e2e/testdata/cronworkflow-metrics-forbid.yaml +++ b/test/e2e/testdata/cronworkflow-metrics-forbid.yaml @@ -3,7 +3,8 @@ kind: CronWorkflow metadata: name: test-cron-metric-forbid spec: - schedule: "* * * * *" + schedules: + - "* * * * *" concurrencyPolicy: "Forbid" startingDeadlineSeconds: 0 workflowSpec: diff --git a/test/e2e/testdata/cronworkflow-metrics-replace.yaml b/test/e2e/testdata/cronworkflow-metrics-replace.yaml index 7b2a8534b24fb..e67b490c8aa28 100644 --- a/test/e2e/testdata/cronworkflow-metrics-replace.yaml +++ b/test/e2e/testdata/cronworkflow-metrics-replace.yaml @@ -3,7 +3,8 @@ kind: CronWorkflow metadata: name: test-cron-metric-replace spec: - schedule: "* * * * *" + schedules: + - "* * * * *" concurrencyPolicy: "Replace" startingDeadlineSeconds: 0 workflowSpec: diff --git a/test/e2e/testdata/cronworkflow_deprecated_schedule.yaml b/test/e2e/testdata/cronworkflow_deprecated_schedule.yaml new file mode 100644 index 0000000000000..0b3a40ad97a98 --- /dev/null +++ b/test/e2e/testdata/cronworkflow_deprecated_schedule.yaml @@ -0,0 +1,21 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: test-cron-metric-forbid +spec: + schedules: + - "* * * * *" + concurrencyPolicy: "Forbid" + startingDeadlineSeconds: 0 + workflowSpec: + metadata: + labels: + workflows.argoproj.io/test: "true" + podGC: + strategy: OnPodCompletion + entrypoint: sleep + templates: + - name: sleep + container: + image: alpine:latest + command: [sh, -c, "sleep 120"] diff --git a/test/e2e/testdata/synchronization-deprecated-mutex.yaml b/test/e2e/testdata/synchronization-deprecated-mutex.yaml new file mode 100644 index 0000000000000..31dfd1a912a0b --- /dev/null +++ b/test/e2e/testdata/synchronization-deprecated-mutex.yaml @@ -0,0 +1,13 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: mutex-deprecated- +spec: + entrypoint: whalesay + synchronization: + mutex: + name: test-mutex + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 diff --git a/test/e2e/testdata/synchronization-deprecated-semaphore.yaml b/test/e2e/testdata/synchronization-deprecated-semaphore.yaml new file mode 100644 index 0000000000000..5f2b9e8a5d227 --- /dev/null +++ b/test/e2e/testdata/synchronization-deprecated-semaphore.yaml @@ -0,0 +1,15 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: semaphore-deprecated- +spec: + entrypoint: whalesay + synchronization: + semaphore: + configMapKeyRef: + name: my-config + key: workflow + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 diff --git a/test/e2e/testdata/workflow-deprecated-podpriority.yaml b/test/e2e/testdata/workflow-deprecated-podpriority.yaml new file mode 100644 index 0000000000000..17c1e7e434716 --- /dev/null +++ b/test/e2e/testdata/workflow-deprecated-podpriority.yaml @@ -0,0 +1,11 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: podpriority-deprecated- +spec: + entrypoint: whalesay + podPriority: 9999 + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 diff --git a/ui/package.json b/ui/package.json index 88804680aea67..dd456cdb1dc19 100644 --- a/ui/package.json +++ b/ui/package.json @@ -24,7 +24,6 @@ "cronstrue": "^2.50.0", "dagre": "^0.8.5", "history": "^4.10.1", - "js-yaml": "^4.1.0", "moment": "^2.30.1", "monaco-editor": "^0.45.0", "prop-types": "^15.8.1", @@ -37,7 +36,8 @@ "react-router-dom": "^4.2.2", "remark-gfm": "^3.0.0", "superagent": "^8.1.2", - "swagger-ui-react": "^5.17.12" + "swagger-ui-react": "^5.17.12", + "yaml": "^2.5.1" }, "devDependencies": { "@babel/core": "^7.22.11", @@ -48,7 +48,6 @@ "@types/dagre": "^0.7.52", "@types/history": "^4.6.2", "@types/jest": "^26.0.15", - "@types/js-yaml": "^4.0.9", "@types/prop-types": "^15.7.11", "@types/react": "^16.8.5", "@types/react-autocomplete": "^1.8.10", diff --git a/ui/src/app/shared/components/dropdown/dropdown.tsx b/ui/src/app/shared/components/dropdown/dropdown.tsx index 5c9253d8125dc..50b1569e531a3 100644 --- a/ui/src/app/shared/components/dropdown/dropdown.tsx +++ b/ui/src/app/shared/components/dropdown/dropdown.tsx @@ -7,10 +7,11 @@ import './dropdown.scss'; export interface DropDownProps { isMenu?: boolean; anchor: JSX.Element; + closeOnInsideClick?: boolean; children: ReactNode; } -export function DropDown({isMenu, anchor, children}: DropDownProps) { +export function DropDown({isMenu, anchor, closeOnInsideClick, children}: DropDownProps) { const [opened, setOpened] = useState(false); const [left, setLeft] = useState(0); const [top, setTop] = useState(0); @@ -56,7 +57,7 @@ export function DropDown({isMenu, anchor, children}: DropDownProps) { function close(event: MouseEvent) { // Doesn't close when clicked inside the portal area - if (contentEl.contains(event.target as Node) || anchorEl.contains(event.target as Node)) { + if (!closeOnInsideClick && (contentEl.contains(event.target as Node) || anchorEl.contains(event.target as Node))) { return; } diff --git a/ui/src/app/shared/components/input-filter.scss b/ui/src/app/shared/components/input-filter.scss new file mode 100644 index 0000000000000..76dfe8e6785cb --- /dev/null +++ b/ui/src/app/shared/components/input-filter.scss @@ -0,0 +1,10 @@ +.input-filter { + display: flex; + align-items: center; + justify-content: space-between; + + div:first-child { + flex: 1; + } +} + diff --git a/ui/src/app/shared/components/input-filter.tsx b/ui/src/app/shared/components/input-filter.tsx index 14e781aa420ca..c73cb4c7e9e45 100644 --- a/ui/src/app/shared/components/input-filter.tsx +++ b/ui/src/app/shared/components/input-filter.tsx @@ -1,11 +1,15 @@ import {Autocomplete} from 'argo-ui/src/components/autocomplete/autocomplete'; import React, {useState} from 'react'; +import './input-filter.scss'; + interface InputProps { value: string; placeholder?: string; name: string; onChange: (input: string) => void; + filterSuggestions?: boolean; + autoHighlight?: boolean; } export function InputFilter(props: InputProps) { @@ -44,7 +48,7 @@ export function InputFilter(props: InputProps) { } return ( - <> +
{ @@ -62,6 +68,6 @@ export function InputFilter(props: InputProps) { }}> - +
); } diff --git a/ui/src/app/shared/components/links.test.ts b/ui/src/app/shared/components/links.test.ts index 384de4c21b71f..0c547b9010679 100644 --- a/ui/src/app/shared/components/links.test.ts +++ b/ui/src/app/shared/components/links.test.ts @@ -56,4 +56,19 @@ describe('process URL', () => { expect(processURL('https://logging?${workflow.annotations.logQuery}${workflow.annotations.additionalLogParams}', object)).toBe('https://logging?query=env:qa'); }); + + test('workflows annotation.', () => { + const object = { + status: {}, + workflow: { + metadata: { + annotations: { + 'workflows.argoproj.io/pod-name-format': 'v2' + } + } + } + }; + + expect(processURL('https://logging?${workflow.metadata.annotations.workflows.argoproj.io/pod-name-format}', object)).toBe('https://logging?v2'); + }); }); diff --git a/ui/src/app/shared/components/links.tsx b/ui/src/app/shared/components/links.tsx index 0808d7d2d0050..cb672b387efb2 100644 --- a/ui/src/app/shared/components/links.tsx +++ b/ui/src/app/shared/components/links.tsx @@ -23,12 +23,25 @@ function addEpochTimestamp(jsonObject: {metadata: ObjectMeta; workflow?: Workflo jsonObject.status.finishedAtEpoch = toEpoch(jsonObject.status.finishedAt); } +function splitWithMetadataKnowledge(replaceable: string) { + const parts = replaceable.split('.'); + if (replaceable.startsWith('workflow.metadata.labels') || replaceable.startsWith('workflow.metadata.annotations')) { + // Take the first 3 parts, then join the rest + const result = parts.slice(0, 3); + result.push(parts.slice(3).join('.')); + + return result; + } + return parts; +} + export function processURL(urlExpression: string, jsonObject: any) { addEpochTimestamp(jsonObject); /* replace ${} from input url with corresponding elements from object only return null for known variables, otherwise empty string*/ return urlExpression.replace(/\${[^}]*}/g, x => { - const parts = x.replace(/(\$%7B|%7D|\${|})/g, '').split('.'); + const replaced = x.replace(/(\$%7B|%7D|\${|})/g, ''); + const parts = splitWithMetadataKnowledge(replaced); const emptyVal = parts[0] === 'workflow' ? '' : null; const res = parts.reduce((p: any, c: string) => (p && p[c]) || emptyVal, jsonObject); return res; diff --git a/ui/src/app/shared/components/object-parser.test.ts b/ui/src/app/shared/components/object-parser.test.ts new file mode 100644 index 0000000000000..e3f868fe47a37 --- /dev/null +++ b/ui/src/app/shared/components/object-parser.test.ts @@ -0,0 +1,127 @@ +import {parse, stringify} from './object-parser'; +import {exampleWorkflowTemplate} from '../examples'; + +describe('parse', () => { + it('handles a valid JSON string', () => { + expect(parse('{}')).toEqual({}); + expect(parse('{"a": 1}')).toEqual({a: 1}); + }); + + it('handles a malformed JSON string', () => { + expect(() => parse('{1}')).toThrow(); + }); + + it('handles a valid YAML string', () => { + expect(parse('')).toEqual(null); + expect(parse('a: 1')).toEqual({a: 1}); + }); + + it('handles a malformed YAML string', () => { + expect(() => parse('!foo')).toThrow(); + }); + + it('parses a YAML string as YAML 1.1, not YAML 1.2', () => { + expect(parse('foo: 0755')).toEqual({foo: 493}); + }); +}); + +describe('stringify', () => { + const testWorkflowTemplate = exampleWorkflowTemplate('test'); + testWorkflowTemplate.metadata.name = 'test-workflowtemplate'; + + it('encodes to YAML', () => { + // Can't use toMatchInlineSnapshot() until we upgrade to Jest 30: https://github.com/jestjs/jest/issues/14305 + expect(stringify(testWorkflowTemplate, 'yaml')).toEqual(`\ +metadata: + name: test-workflowtemplate + namespace: test + labels: + example: "true" +spec: + workflowMetadata: + labels: + example: "true" + entrypoint: argosay + arguments: + parameters: + - name: message + value: hello argo + templates: + - name: argosay + inputs: + parameters: + - name: message + value: "{{workflow.parameters.message}}" + container: + name: main + image: argoproj/argosay:v2 + command: + - /argosay + args: + - echo + - "{{inputs.parameters.message}}" + ttlStrategy: + secondsAfterCompletion: 300 + podGC: + strategy: OnPodCompletion +`); + }); + + it('encodes to JSON', () => { + expect(stringify(testWorkflowTemplate, 'json')).toEqual(`{ + "metadata": { + "name": "test-workflowtemplate", + "namespace": "test", + "labels": { + "example": "true" + } + }, + "spec": { + "workflowMetadata": { + "labels": { + "example": "true" + } + }, + "entrypoint": "argosay", + "arguments": { + "parameters": [ + { + "name": "message", + "value": "hello argo" + } + ] + }, + "templates": [ + { + "name": "argosay", + "inputs": { + "parameters": [ + { + "name": "message", + "value": "{{workflow.parameters.message}}" + } + ] + }, + "container": { + "name": "main", + "image": "argoproj/argosay:v2", + "command": [ + "/argosay" + ], + "args": [ + "echo", + "{{inputs.parameters.message}}" + ] + } + } + ], + "ttlStrategy": { + "secondsAfterCompletion": 300 + }, + "podGC": { + "strategy": "OnPodCompletion" + } + } +}`); + }); +}); diff --git a/ui/src/app/shared/components/object-parser.ts b/ui/src/app/shared/components/object-parser.ts index 96f2e15d3e914..7b4800abf6600 100644 --- a/ui/src/app/shared/components/object-parser.ts +++ b/ui/src/app/shared/components/object-parser.ts @@ -1,12 +1,17 @@ -import jsyaml from 'js-yaml'; +import YAML from 'yaml'; export function parse(value: string): T { if (value.startsWith('{')) { return JSON.parse(value); } - return jsyaml.load(value) as T; + return YAML.parse(value, { + // Default is YAML 1.2, but Kubernetes uses YAML 1.1, which leads to subtle bugs. + // See https://github.com/argoproj/argo-workflows/issues/12205#issuecomment-2111572189 + version: '1.1', + strict: false + }) as T; } export function stringify(value: T, type: string) { - return type === 'yaml' ? jsyaml.dump(value, {noRefs: true}) : JSON.stringify(value, null, ' '); + return type === 'yaml' ? YAML.stringify(value, {aliasDuplicateObjects: false}) : JSON.stringify(value, null, ' '); } diff --git a/ui/src/app/shared/services/utils.ts b/ui/src/app/shared/services/utils.ts index 102955ad6fa2e..7b74e1c87b06a 100644 --- a/ui/src/app/shared/services/utils.ts +++ b/ui/src/app/shared/services/utils.ts @@ -1,3 +1,4 @@ +import {NameFilterKeys} from '../../workflows/components/workflow-filters/workflow-filters'; import {Pagination} from '../pagination'; export function queryParams(filter: { @@ -5,6 +6,7 @@ export function queryParams(filter: { name?: string; namePrefix?: string; namePattern?: string; + nameFilter?: NameFilterKeys; phases?: Array; labels?: Array; createdAfter?: Date; @@ -35,6 +37,9 @@ export function queryParams(filter: { if (filter.namePattern) { queryParams.push(`namePattern=${filter.namePattern}`); } + if (filter.nameFilter) { + queryParams.push(`nameFilter=${filter.nameFilter}`); + } if (filter.resourceVersion) { queryParams.push(`listOptions.resourceVersion=${filter.resourceVersion}`); } diff --git a/ui/src/app/shared/services/workflows-service.ts b/ui/src/app/shared/services/workflows-service.ts index a5cef79434b94..71a549edc3971 100644 --- a/ui/src/app/shared/services/workflows-service.ts +++ b/ui/src/app/shared/services/workflows-service.ts @@ -9,6 +9,7 @@ import {Pagination} from '../pagination'; import {queryParams} from './utils'; import requests from './requests'; import {WorkflowDeleteResponse} from './responses'; +import {NameFilterKeys} from '../../workflows/components/workflow-filters/workflow-filters'; function isString(value: any): value is string { return typeof value === 'string'; @@ -51,9 +52,11 @@ export const WorkflowsService = { 'items.status.estimatedDuration', 'items.status.progress', 'items.spec.suspend' - ] + ], + name?: string, + nameFilter?: NameFilterKeys ) { - const params = queryParams({phases, labels, pagination}); + const params = queryParams({phases, labels, pagination, name, nameFilter}); params.push(`fields=${fields.join(',')}`); return requests.get(`api/v1/workflows/${namespace}?${params.join('&')}`).then(res => res.body as WorkflowList); }, diff --git a/ui/src/app/webpack.config.js b/ui/src/app/webpack.config.js index b2bb70d6973ce..39ae90f9346b3 100644 --- a/ui/src/app/webpack.config.js +++ b/ui/src/app/webpack.config.js @@ -7,10 +7,11 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const isProd = process.env.NODE_ENV === 'production'; -const proxyConf = { - target: isProd ? '' : 'http://localhost:2746', - secure: false -}; +let proxyTarget = ''; +if (!isProd) { + const isSecure = process.env.ARGO_SECURE === 'true'; + proxyTarget = `${isSecure ? 'https' : 'http'}://localhost:2746`; +} console.log(`Bundling for ${isProd ? 'production' : 'development'}...`); @@ -99,6 +100,7 @@ const config = { ], devServer: { + server: process.env.ARGO_UI_SECURE === 'true' ? 'https' : 'http', // this needs to be disabled to allow EventSource to work compress: false, historyApiFallback: { @@ -107,15 +109,14 @@ const config = { headers: { 'X-Frame-Options': 'SAMEORIGIN' }, - proxy: { - '/api/v1': proxyConf, - '/artifact-files': proxyConf, - '/artifacts': proxyConf, - '/input-artifacts': proxyConf, - '/artifacts-by-uid': proxyConf, - '/input-artifacts-by-uid': proxyConf, - '/oauth2': proxyConf - } + proxy: [ + { + context: ['/api/v1', '/artifact-files', '/artifacts', '/input-artifacts', '/artifacts-by-uid', '/input-artifacts-by-uid', '/oauth2'], + target: proxyTarget, + secure: false, + xfwd: true // add x-forwarded-* headers to simulate real-world reverse proxy servers + } + ] } }; diff --git a/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss b/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss index 3e9a03ad1463b..1749070ee4e80 100644 --- a/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss +++ b/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss @@ -32,4 +32,8 @@ flex-direction: row; align-items: center; justify-content: space-between; -} \ No newline at end of file +} + +#top-bar__filter-list { + column-count: 1; +} diff --git a/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx b/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx index 9a29c75e3a9b8..58c865f6fc368 100644 --- a/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx +++ b/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; import {useMemo} from 'react'; import DatePicker from 'react-datepicker'; +import classNames from 'classnames'; + import 'react-datepicker/dist/react-datepicker.css'; import * as models from '../../../../models'; @@ -10,9 +12,30 @@ import {DataLoaderDropdown} from '../../../shared/components/data-loader-dropdow import {NamespaceFilter} from '../../../shared/components/namespace-filter'; import {TagsInput} from '../../../shared/components/tags-input/tags-input'; import {services} from '../../../shared/services'; +import {InputFilter} from '../../../shared/components/input-filter'; +import {DropDown} from '../../../shared/components/dropdown/dropdown'; import './workflow-filters.scss'; +const NAME_FILTERS = [ + { + title: 'Name Contains', + id: 'Contains' as const + }, + { + title: 'Name Prefix', + id: 'Prefix' as const + }, + { + title: 'Name Exact', + id: 'Exact' as const + } +]; + +export const NAME_FILTER_KEYS = NAME_FILTERS.map(item => item.id); + +export type NameFilterKeys = (typeof NAME_FILTER_KEYS)[number]; + interface WorkflowFilterProps { workflows: models.Workflow[]; namespace: string; @@ -26,9 +49,14 @@ interface WorkflowFilterProps { setLabels: (labels: string[]) => void; setCreatedAfter: (createdAfter: Date) => void; setFinishedBefore: (finishedBefore: Date) => void; + nameFilter: NameFilterKeys; + nameValue: string; + setNameFilter: (nameFilter: NameFilterKeys) => void; + setNameValue: (nameValue: string) => void; } export function WorkflowFilters(props: WorkflowFilterProps) { + const nameFilter = NAME_FILTERS.find(item => item.id === props.nameFilter); function setLabel(name: string, value: string) { props.setLabels([name.concat('=' + value)]); } @@ -57,6 +85,10 @@ export function WorkflowFilters(props: WorkflowFilterProps) { return results; }, [props.workflows, props.phaseItems]); + function handleNameFilterChange(item: {title: string; id: string}) { + props.setNameFilter(item.id as NameFilterKeys); + } + return (
@@ -64,6 +96,27 @@ export function WorkflowFilters(props: WorkflowFilterProps) {

Namespace

+
+ +

+ {nameFilter.title}