diff --git a/.spelling b/.spelling
index 56808b006eee..081512ac8697 100644
--- a/.spelling
+++ b/.spelling
@@ -183,6 +183,7 @@ memoizing
metadata
minikube
mutex
+mutexes
namespace
namespaces
natively
diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json
index 54b359072bea..c9f3020e944c 100644
--- a/api/jsonschema/schema.json
+++ b/api/jsonschema/schema.json
@@ -6878,11 +6878,25 @@
"properties": {
"mutex": {
"$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Mutex",
- "description": "Mutex holds the Mutex lock details"
+ "description": "Mutex holds the Mutex lock details - deprecated, use mutexes instead"
+ },
+ "mutexes": {
+ "description": "Mutexes holds the list of Mutex lock details",
+ "items": {
+ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Mutex"
+ },
+ "type": "array"
},
"semaphore": {
"$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreRef",
- "description": "Semaphore holds the Semaphore configuration"
+ "description": "Semaphore holds the Semaphore configuration - deprecated, use semaphores instead"
+ },
+ "semaphores": {
+ "description": "Semaphores holds the list of Semaphores configuration",
+ "items": {
+ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreRef"
+ },
+ "type": "array"
}
},
"type": "object"
diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json
index 3dcf26481085..7a82b10e159a 100644
--- a/api/openapi-spec/swagger.json
+++ b/api/openapi-spec/swagger.json
@@ -10818,12 +10818,26 @@
"type": "object",
"properties": {
"mutex": {
- "description": "Mutex holds the Mutex lock details",
+ "description": "Mutex holds the Mutex lock details - deprecated, use mutexes instead",
"$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Mutex"
},
+ "mutexes": {
+ "description": "Mutexes holds the list of Mutex lock details",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Mutex"
+ }
+ },
"semaphore": {
- "description": "Semaphore holds the Semaphore configuration",
+ "description": "Semaphore holds the Semaphore configuration - deprecated, use semaphores instead",
"$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreRef"
+ },
+ "semaphores": {
+ "description": "Semaphores holds the list of Semaphores configuration",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreRef"
+ }
}
}
},
diff --git a/docs/executor_swagger.md b/docs/executor_swagger.md
index 2e35fbabe2db..01071f904106 100644
--- a/docs/executor_swagger.md
+++ b/docs/executor_swagger.md
@@ -3534,7 +3534,9 @@ otherwise).
| Name | Type | Go type | Required | Default | Description | Example |
|------|------|---------|:--------:| ------- |-------------|---------|
| mutex | [Mutex](#mutex)| `Mutex` | | | | |
+| mutexes | [][Mutex](#mutex)| `[]*Mutex` | | | Mutexes holds the list of Mutex lock details | |
| semaphore | [SemaphoreRef](#semaphore-ref)| `SemaphoreRef` | | | | |
+| semaphores | [][SemaphoreRef](#semaphore-ref)| `[]*SemaphoreRef` | | | Semaphores holds the list of Semaphores configuration | |
diff --git a/docs/fields.md b/docs/fields.md
index d74d4a6ad180..f1dc3fa2568a 100644
--- a/docs/fields.md
+++ b/docs/fields.md
@@ -1632,8 +1632,10 @@ Synchronization holds synchronization lock configuration
### Fields
| Field Name | Field Type | Description |
|:----------:|:----------:|---------------|
-|`mutex`|[`Mutex`](#mutex)|Mutex holds the Mutex lock details|
-|`semaphore`|[`SemaphoreRef`](#semaphoreref)|Semaphore holds the Semaphore configuration|
+|`mutex`|[`Mutex`](#mutex)|Mutex holds the Mutex lock details - deprecated, use mutexes instead|
+|`mutexes`|`Array<`[`Mutex`](#mutex)`>`|Mutexes holds the list of Mutex lock details|
+|`semaphore`|[`SemaphoreRef`](#semaphoreref)|Semaphore holds the Semaphore configuration - deprecated, use semaphores instead|
+|`semaphores`|`Array<`[`SemaphoreRef`](#semaphoreref)`>`|Semaphores holds the list of Semaphores configuration|
## Template
@@ -2349,14 +2351,6 @@ Backoff is a backoff strategy to use within retryStrategy
Mutex holds Mutex configuration
-
-Examples with this field (click to open)
-
-- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml)
-
-- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml)
-
-
### Fields
| Field Name | Field Type | Description |
|:----------:|:----------:|---------------|
@@ -3231,14 +3225,6 @@ NodeSynchronizationStatus stores the status of a node
MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks.
-
-Examples with this field (click to open)
-
-- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml)
-
-- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml)
-
-
### Fields
| Field Name | Field Type | Description |
|:----------:|:----------:|---------------|
diff --git a/docs/parallelism.md b/docs/parallelism.md
new file mode 100644
index 000000000000..2c2a79c38614
--- /dev/null
+++ b/docs/parallelism.md
@@ -0,0 +1,38 @@
+# Limiting parallelism
+
+You can restrict the number of workflows being executed at any time using a number of mechanisms
+
+## Controller level
+
+You can limit the total number of workflows that can execute at any one time in the [workflow controller ConfigMap](./workflow-controller-configmap.yaml).
+
+```yaml
+data:
+ parallelism: "10"
+```
+
+You can also limit the number of workflows that can execute in a single namespace.
+
+```yaml
+data:
+ namespaceParallelism: "4"
+```
+
+Workflows that are executing but restricted from running more nodes due to the other mechanisms on this page will still count towards the parallelism limits.
+
+## Workflow level
+
+You can restrict parallelism within a workflow using `parallelism` within a workflow or template.
+This only restricts total concurrent executions of steps or tasks within the same workflow.
+
+Examples
+
+1 [`parallelism-limit.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/parallelism-limit.yaml) restricts the parallelism of a [loop](./walk-through/loops.md)
+1 [`parallelism-nested.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/parallelism-nested.yaml) restricts the parallelism of a nested loop
+1 [`parallelism-nested-dag.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/parallelism-nested-dag.yaml) restricts the number of dag tasks that can be run at any one time
+1 [`parallelism-nested-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/parallelism-nested-workflow.yaml) shows how parallelism is inherited by children
+1 [`parallelism-template-limit.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/parallelism-template-limit.yaml) shows how parallelism of looped templates is also restricted
+
+## Synchronization
+
+You can use [mutexes and semaphores](./synchronization.md) to control the parallel execution of sections of a workflow.
diff --git a/docs/synchronization.md b/docs/synchronization.md
index 0897d96cb038..cc9054d8eb85 100644
--- a/docs/synchronization.md
+++ b/docs/synchronization.md
@@ -1,16 +1,15 @@
# Synchronization
> v2.10 and after
+> v3.6 for multiple
## Introduction
-Synchronization enables users to limit the parallel execution of certain workflows or
-templates within a workflow without having to restrict others.
+You can use synchronization to limit the parallel execution of workflows or templates.
+You can use mutexes to restrict workflows or templates to only having a single concurrent section.
+You can use semaphores to restrict workflows or templates to a configured number of parallel runs.
-Users can create multiple synchronization configurations in the `ConfigMap` that can be referred to
-from a workflow or template within a workflow. Alternatively, users can
-configure a mutex to prevent concurrent execution of templates or
-workflows using the same mutex.
+You can create multiple synchronization configurations in the `ConfigMap` that can be referred to from a workflow or template.
For example:
@@ -26,9 +25,10 @@ data:
### Workflow-level Synchronization
-Workflow-level synchronization limits parallel execution of the workflow if workflows have the same synchronization reference.
-In this example, Workflow refers to `workflow` synchronization key which is configured as limit 1,
-so only one workflow instance will be executed at given time even multiple workflows created.
+You can limit parallel execution of a workflow by using Workflow-level synchronization.
+If multiple workflows have the same synchronization reference they will be limited by that synchronization reference.
+
+In this example, Workflow refers to `workflow` synchronization key which is configured as limit `"1"`, so only one workflow instance will be executed at given time even if multiple workflows are created.
Using a semaphore configured by a `ConfigMap`:
@@ -40,10 +40,10 @@ metadata:
spec:
entrypoint: whalesay
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: workflow
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
templates:
- name: whalesay
container:
@@ -52,7 +52,7 @@ spec:
args: ["hello world"]
```
-Using a mutex:
+Using a mutex achieves the same thing as a count `"1"` semaphore:
```yaml
apiVersion: argoproj.io/v1alpha1
@@ -62,8 +62,8 @@ metadata:
spec:
entrypoint: whalesay
synchronization:
- mutex:
- name: workflow
+ mutexes:
+ - name: workflow
templates:
- name: whalesay
container:
@@ -74,9 +74,11 @@ spec:
### Template-level Synchronization
-Template-level synchronization limits parallel execution of the template across workflows, if templates have the same synchronization reference.
-In this example, `acquire-lock` template has synchronization reference of `template` key which is configured as limit 2,
-so two instances of templates will be executed at a given time: even multiple steps/tasks within workflow or different workflows referring to the same template.
+You can limit parallel execution of a template by using Template-level synchronization.
+If templates have the same synchronization reference they will be limited by that synchronization reference, across all workflows.
+
+In this example, `acquire-lock` template has synchronization reference of `template` key which is configured as limit `"2"` so a maximum of two instances of the `acquire-lock` template will be executed at a given time.
+This applies even multiple steps or tasks within a workflow or different workflows refer to the same template.
Using a semaphore configured by a `ConfigMap`:
@@ -100,17 +102,17 @@ spec:
- name: acquire-lock
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: template
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: template
container:
image: alpine:latest
command: [sh, -c]
args: ["sleep 10; echo acquired lock"]
```
-Using a mutex:
+Using a mutex will limit to a single execution of the template at any one time:
```yaml
apiVersion: argoproj.io/v1alpha1
@@ -132,8 +134,8 @@ spec:
- name: acquire-lock
synchronization:
- mutex:
- name: template
+ mutexes:
+ - name: template
container:
image: alpine:latest
command: [sh, -c]
@@ -142,13 +144,64 @@ spec:
Examples:
-1. [Workflow level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-wf-level.yaml)
+1. [Workflow level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-wf-level.yamlxb)
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)
-### Other Parallelism support
+### Multiple synchronization
+
+You can specify multiple mutexes and semaphores to lock in a single workflow or template.
+
+```yaml
+synchronization:
+ mutexes:
+ - name: alpha
+ - name: beta
+ semaphores:
+ - configMapKeyRef:
+ key: foo
+ name: my-config
+ - configMapKeyRef:
+ key: bar
+ name: my-config
+```
+
+The workflow will block until all of these mutexes and semaphores are available.
+
+### Priority
+
+Workflows can have a `priority` set in their specification.
+Workflows with a higher priority value will be queued to take a semaphore or mutex before a lower priority workflow, even if they have been waiting for less time.
+
+!!! Warning
+ A high priority workflow waiting on multiple mutexes or semaphore will make all other workflows which want to acquire those mutexes wait for it to acquire and release all the mutexes or semaphores it is waiting on.
+ This applies even if the lower priority workflows only wish to acquire a subset of those mutexes or semaphores.
+
+### Legacy
+
+In workflows prior to 3.6 you can only specify one mutex or semaphore to 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 mutex and semaphore will be taken in version 3.6 with this syntax.
+This syntax can be mixed with `mutexes` and `semaphores`, all mutexes and semaphores will be used.
+
+## Parallelism
-In addition to this synchronization, the workflow controller supports a parallelism setting that applies to all workflows
-in the system (it is not granular to a class of workflows, or tasks withing them). Furthermore, there is a parallelism setting
-at the workflow and template level, but this only restricts total concurrent executions of tasks within the same workflow.
+See also [how you can restrict parallelism](./parallelism.md) in other ways.
diff --git a/examples/synchronization-mutex-tmpl-level.yaml b/examples/synchronization-mutex-tmpl-level.yaml
index 9652e48a7d0a..c2368cca835d 100644
--- a/examples/synchronization-mutex-tmpl-level.yaml
+++ b/examples/synchronization-mutex-tmpl-level.yaml
@@ -28,8 +28,8 @@ spec:
- name: acquire-lock
synchronization:
- mutex:
- name: welcome
+ mutexes:
+ - name: welcome
container:
image: alpine:latest
command: [sh, -c]
@@ -37,9 +37,9 @@ spec:
- name: acquire-lock-1
synchronization:
- mutex:
- name: test
+ mutexes:
+ - 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-wf-level.yaml b/examples/synchronization-mutex-wf-level.yaml
index 30bae7caace9..ff1d6e6437b2 100644
--- a/examples/synchronization-mutex-wf-level.yaml
+++ b/examples/synchronization-mutex-wf-level.yaml
@@ -7,8 +7,8 @@ metadata:
spec:
entrypoint: whalesay
synchronization:
- mutex:
- name: test
+ mutexes:
+ - name: test
templates:
- name: whalesay
container:
diff --git a/examples/synchronization-tmpl-level.yaml b/examples/synchronization-tmpl-level.yaml
index b8c0f79c6c6f..d9eafd230ca1 100644
--- a/examples/synchronization-tmpl-level.yaml
+++ b/examples/synchronization-tmpl-level.yaml
@@ -27,10 +27,10 @@ spec:
- name: acquire-lock
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: template
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: template
container:
image: alpine:latest
command: [sh, -c]
diff --git a/examples/synchronization-wf-level.yaml b/examples/synchronization-wf-level.yaml
index f0d58a5d7666..0295bf410bea 100644
--- a/examples/synchronization-wf-level.yaml
+++ b/examples/synchronization-wf-level.yaml
@@ -1,4 +1,4 @@
-# This example demonstrates the use of a Synchronization lock on workflow execution. Synchronization lock limits
+# This example demonstrates the use of a Synchronization lock on workflow execution. Synchronization lock limits
# the number of concurrent workflow execution in the namespace which has same Synchronization lock. Synchronization
# limit value can be configured in configmap.
# Eg.:
@@ -16,10 +16,10 @@ metadata:
spec:
entrypoint: whalesay
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: workflow
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
templates:
- name: whalesay
container:
diff --git a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
index 78a364fb9e80..9182f46eb30a 100644
--- a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
+++ b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
@@ -1939,6 +1939,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -1956,6 +1965,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
templateDefaults:
properties:
@@ -9694,6 +9722,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -9711,6 +9748,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -18180,6 +18236,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -18197,6 +18262,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml
index 3bd8d118f6a0..e5a067b666fd 100644
--- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml
+++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml
@@ -1971,6 +1971,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -1988,6 +1997,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
templateDefaults:
properties:
@@ -9726,6 +9754,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -9743,6 +9780,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -18212,6 +18268,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -18229,6 +18294,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
diff --git a/manifests/base/crds/full/argoproj.io_workflows.yaml b/manifests/base/crds/full/argoproj.io_workflows.yaml
index d0c5aa874f0d..5bcb3b94372a 100644
--- a/manifests/base/crds/full/argoproj.io_workflows.yaml
+++ b/manifests/base/crds/full/argoproj.io_workflows.yaml
@@ -1953,6 +1953,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -1970,6 +1979,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
templateDefaults:
properties:
@@ -9708,6 +9736,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -9725,6 +9762,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -18194,6 +18250,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -18211,6 +18276,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -30491,6 +30575,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -30508,6 +30601,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -33154,6 +33266,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -33171,6 +33292,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
templateDefaults:
properties:
@@ -40909,6 +41049,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -40926,6 +41075,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -49395,6 +49563,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -49412,6 +49589,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
diff --git a/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml b/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
index 9f4475e344ee..8aadd47a4664 100644
--- a/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
+++ b/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
@@ -7764,6 +7764,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -7781,6 +7790,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
diff --git a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
index e971cf10d51c..51380b5c92ba 100644
--- a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
+++ b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
@@ -1938,6 +1938,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -1955,6 +1964,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
templateDefaults:
properties:
@@ -9693,6 +9721,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -9710,6 +9747,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
@@ -18179,6 +18235,15 @@ spec:
namespace:
type: string
type: object
+ mutexes:
+ items:
+ properties:
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: array
semaphore:
properties:
configMapKeyRef:
@@ -18196,6 +18261,25 @@ spec:
namespace:
type: string
type: object
+ semaphores:
+ items:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ namespace:
+ type: string
+ type: object
+ type: array
type: object
timeout:
type: string
diff --git a/mkdocs.yml b/mkdocs.yml
index 3403c489f3d3..b121645e439f 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -122,6 +122,7 @@ nav:
- retries.md
- lifecyclehook.md
- synchronization.md
+ - parallelism.md
- memoization.md
- template-defaults.md
- enhanced-depends-logic.md
diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list
index ccf495af1bfb..dc3b89a0917c 100644
--- a/pkg/apis/api-rules/violation_exceptions.list
+++ b/pkg/apis/api-rules/violation_exceptions.list
@@ -28,6 +28,8 @@ API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/
API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,SemaphoreStatus,Holding
API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,SemaphoreStatus,Waiting
API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,SubmitOpts,Parameters
+API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,Synchronization,Mutexes
+API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,Synchronization,Semaphores
API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,Template,HostAliases
API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,Template,InitContainers
API rule violation: list_type_missing,github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1,Template,Sidecars
diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go
index e068bc96bf88..c311ebe108a4 100644
--- a/pkg/apis/workflow/v1alpha1/generated.pb.go
+++ b/pkg/apis/workflow/v1alpha1/generated.pb.go
@@ -4448,699 +4448,701 @@ func init() {
}
var fileDescriptor_724696e352c3df5f = []byte{
- // 11059 bytes of a gzipped FileDescriptorProto
+ // 11102 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x6b, 0x70, 0x24, 0xc7,
0x79, 0x18, 0x67, 0x81, 0x05, 0xb0, 0xdf, 0x02, 0x38, 0x5c, 0xdf, 0x6b, 0x09, 0x92, 0x07, 0x7a,
0x28, 0x32, 0xa4, 0x4d, 0xe1, 0xcc, 0xa3, 0x94, 0x30, 0x52, 0x22, 0x09, 0x8f, 0x03, 0xee, 0x88,
0xc3, 0x01, 0xec, 0xc5, 0xf1, 0x4c, 0x8a, 0x96, 0x34, 0xd8, 0x6d, 0xec, 0x0e, 0xb1, 0x3b, 0xb3,
0x9c, 0x99, 0xc5, 0x1d, 0xf8, 0x90, 0x14, 0x5a, 0xcf, 0x58, 0xb6, 0x62, 0x59, 0x92, 0x25, 0x25,
0xa9, 0x52, 0x14, 0x29, 0x61, 0xc9, 0xae, 0xb8, 0xec, 0x5f, 0x29, 0xbb, 0xf2, 0x27, 0x95, 0x72,
- 0x29, 0xe5, 0x54, 0x45, 0xae, 0x28, 0x25, 0xfd, 0xb0, 0xc1, 0xe8, 0x92, 0xe8, 0x47, 0x12, 0x55,
- 0x25, 0xaa, 0xd8, 0xb1, 0x2f, 0x8f, 0x4a, 0xf5, 0x73, 0xba, 0x67, 0x67, 0x71, 0x8b, 0xbb, 0x06,
- 0x4e, 0x65, 0xff, 0x02, 0xf6, 0xeb, 0xee, 0xef, 0xeb, 0xee, 0xe9, 0xfe, 0xfa, 0x7b, 0xf5, 0xd7,
- 0xb0, 0xde, 0xf0, 0x93, 0x66, 0x77, 0x73, 0xb6, 0x16, 0xb6, 0xcf, 0x79, 0x51, 0x23, 0xec, 0x44,
- 0xe1, 0xcb, 0xec, 0x9f, 0x77, 0x5e, 0x0f, 0xa3, 0xed, 0xad, 0x56, 0x78, 0x3d, 0x3e, 0xb7, 0xf3,
- 0xf4, 0xb9, 0xce, 0x76, 0xe3, 0x9c, 0xd7, 0xf1, 0xe3, 0x73, 0x12, 0x7a, 0x6e, 0xe7, 0x29, 0xaf,
- 0xd5, 0x69, 0x7a, 0x4f, 0x9d, 0x6b, 0x90, 0x80, 0x44, 0x5e, 0x42, 0xea, 0xb3, 0x9d, 0x28, 0x4c,
- 0x42, 0xf4, 0x81, 0x14, 0xe3, 0xac, 0xc4, 0xc8, 0xfe, 0xf9, 0xb0, 0xc2, 0x38, 0xbb, 0xf3, 0xf4,
- 0x6c, 0x67, 0xbb, 0x31, 0x4b, 0x31, 0xce, 0x4a, 0xe8, 0xac, 0xc4, 0x38, 0xfd, 0x4e, 0xad, 0x4f,
- 0x8d, 0xb0, 0x11, 0x9e, 0x63, 0x88, 0x37, 0xbb, 0x5b, 0xec, 0x17, 0xfb, 0xc1, 0xfe, 0xe3, 0x04,
- 0xa7, 0xdd, 0xed, 0x67, 0xe2, 0x59, 0x3f, 0xa4, 0xfd, 0x3b, 0x57, 0x0b, 0x23, 0x72, 0x6e, 0xa7,
- 0xa7, 0x53, 0xd3, 0xef, 0xd0, 0xea, 0x74, 0xc2, 0x96, 0x5f, 0xdb, 0xcd, 0xab, 0xf5, 0xae, 0xb4,
- 0x56, 0xdb, 0xab, 0x35, 0xfd, 0x80, 0x44, 0xbb, 0xe9, 0xd0, 0xdb, 0x24, 0xf1, 0xf2, 0x5a, 0x9d,
- 0xeb, 0xd7, 0x2a, 0xea, 0x06, 0x89, 0xdf, 0x26, 0x3d, 0x0d, 0xfe, 0xfa, 0xed, 0x1a, 0xc4, 0xb5,
- 0x26, 0x69, 0x7b, 0x3d, 0xed, 0x9e, 0xee, 0xd7, 0xae, 0x9b, 0xf8, 0xad, 0x73, 0x7e, 0x90, 0xc4,
- 0x49, 0x94, 0x6d, 0xe4, 0x5e, 0x80, 0x91, 0xb9, 0x76, 0xd8, 0x0d, 0x12, 0xf4, 0x5e, 0x28, 0xee,
- 0x78, 0xad, 0x2e, 0xa9, 0x38, 0x0f, 0x3b, 0x8f, 0x97, 0xe6, 0x1f, 0xfd, 0xce, 0xde, 0xcc, 0x7d,
- 0x37, 0xf7, 0x66, 0x8a, 0xcf, 0x53, 0xe0, 0xad, 0xbd, 0x99, 0x93, 0x24, 0xa8, 0x85, 0x75, 0x3f,
- 0x68, 0x9c, 0x7b, 0x39, 0x0e, 0x83, 0xd9, 0x2b, 0xdd, 0xf6, 0x26, 0x89, 0x30, 0x6f, 0xe3, 0xfe,
- 0xbb, 0x02, 0x1c, 0x9b, 0x8b, 0x6a, 0x4d, 0x7f, 0x87, 0x54, 0x13, 0x8a, 0xbf, 0xb1, 0x8b, 0x9a,
- 0x30, 0x94, 0x78, 0x11, 0x43, 0x57, 0x3e, 0xbf, 0x3a, 0x7b, 0xb7, 0xdf, 0x7d, 0x76, 0xc3, 0x8b,
- 0x24, 0xee, 0xf9, 0xd1, 0x9b, 0x7b, 0x33, 0x43, 0x1b, 0x5e, 0x84, 0x29, 0x09, 0xd4, 0x82, 0xe1,
- 0x20, 0x0c, 0x48, 0xa5, 0xc0, 0x48, 0x5d, 0xb9, 0x7b, 0x52, 0x57, 0xc2, 0x40, 0x8d, 0x63, 0x7e,
- 0xec, 0xe6, 0xde, 0xcc, 0x30, 0x85, 0x60, 0x46, 0x85, 0x8e, 0xeb, 0x55, 0xbf, 0x53, 0x19, 0xb2,
- 0x35, 0xae, 0x17, 0xfd, 0x8e, 0x39, 0xae, 0x17, 0xfd, 0x0e, 0xa6, 0x24, 0xdc, 0xcf, 0x16, 0xa0,
- 0x34, 0x17, 0x35, 0xba, 0x6d, 0x12, 0x24, 0x31, 0xfa, 0x18, 0x40, 0xc7, 0x8b, 0xbc, 0x36, 0x49,
- 0x48, 0x14, 0x57, 0x9c, 0x87, 0x87, 0x1e, 0x2f, 0x9f, 0x5f, 0xb9, 0x7b, 0xf2, 0xeb, 0x12, 0xe7,
- 0x3c, 0x12, 0x9f, 0x1c, 0x14, 0x28, 0xc6, 0x1a, 0x49, 0xf4, 0x1a, 0x94, 0xbc, 0x28, 0xf1, 0xb7,
- 0xbc, 0x5a, 0x12, 0x57, 0x0a, 0x8c, 0xfe, 0xb3, 0x77, 0x4f, 0x7f, 0x4e, 0xa0, 0x9c, 0x3f, 0x2e,
- 0xc8, 0x97, 0x24, 0x24, 0xc6, 0x29, 0x3d, 0xf7, 0xf7, 0x86, 0xa1, 0x3c, 0x17, 0x25, 0xcb, 0x0b,
- 0xd5, 0xc4, 0x4b, 0xba, 0x31, 0xfa, 0x43, 0x07, 0x4e, 0xc4, 0x7c, 0xda, 0x7c, 0x12, 0xaf, 0x47,
- 0x61, 0x8d, 0xc4, 0x31, 0xa9, 0x8b, 0x79, 0xd9, 0xb2, 0xd2, 0x2f, 0x49, 0x6c, 0xb6, 0xda, 0x4b,
- 0xe8, 0x42, 0x90, 0x44, 0xbb, 0xf3, 0x4f, 0x89, 0x3e, 0x9f, 0xc8, 0xa9, 0xf1, 0xe6, 0xdb, 0x33,
- 0x48, 0x0e, 0x85, 0x62, 0xe2, 0x9f, 0x18, 0xe7, 0xf5, 0x1a, 0x7d, 0xd5, 0x81, 0xf1, 0x4e, 0x58,
- 0x8f, 0x31, 0xa9, 0x85, 0xdd, 0x0e, 0xa9, 0x8b, 0xe9, 0xfd, 0xb0, 0xdd, 0x61, 0xac, 0x6b, 0x14,
- 0x78, 0xff, 0x4f, 0x8a, 0xfe, 0x8f, 0xeb, 0x45, 0xd8, 0xe8, 0x0a, 0x7a, 0x06, 0xc6, 0x83, 0x30,
- 0xa9, 0x76, 0x48, 0xcd, 0xdf, 0xf2, 0x49, 0x9d, 0x2d, 0xfc, 0xb1, 0xb4, 0xe5, 0x15, 0xad, 0x0c,
- 0x1b, 0x35, 0xa7, 0x97, 0xa0, 0xd2, 0x6f, 0xe6, 0xd0, 0x14, 0x0c, 0x6d, 0x93, 0x5d, 0xce, 0x6c,
- 0x30, 0xfd, 0x17, 0x9d, 0x94, 0x0c, 0x88, 0x6e, 0xe3, 0x31, 0xc1, 0x59, 0xde, 0x53, 0x78, 0xc6,
- 0x99, 0x7e, 0x3f, 0x1c, 0xef, 0xe9, 0xfa, 0x41, 0x10, 0xb8, 0xdf, 0x1d, 0x81, 0x31, 0xf9, 0x29,
- 0xd0, 0xc3, 0x30, 0x1c, 0x78, 0x6d, 0xc9, 0xe7, 0xc6, 0xc5, 0x38, 0x86, 0xaf, 0x78, 0x6d, 0xba,
- 0xc3, 0xbd, 0x36, 0xa1, 0x35, 0x3a, 0x5e, 0xd2, 0x64, 0x78, 0xb4, 0x1a, 0xeb, 0x5e, 0xd2, 0xc4,
- 0xac, 0x04, 0x3d, 0x08, 0xc3, 0xed, 0xb0, 0x4e, 0xd8, 0x5c, 0x14, 0x39, 0x87, 0x58, 0x0d, 0xeb,
- 0x04, 0x33, 0x28, 0x6d, 0xbf, 0x15, 0x85, 0xed, 0xca, 0xb0, 0xd9, 0x7e, 0x29, 0x0a, 0xdb, 0x98,
- 0x95, 0xa0, 0xaf, 0x38, 0x30, 0x25, 0xd7, 0xf6, 0xe5, 0xb0, 0xe6, 0x25, 0x7e, 0x18, 0x54, 0x8a,
- 0x8c, 0xa3, 0x60, 0x7b, 0x5b, 0x4a, 0x62, 0x9e, 0xaf, 0x88, 0x2e, 0x4c, 0x65, 0x4b, 0x70, 0x4f,
- 0x2f, 0xd0, 0x79, 0x80, 0x46, 0x2b, 0xdc, 0xf4, 0x5a, 0x74, 0x42, 0x2a, 0x23, 0x6c, 0x08, 0x8a,
- 0x33, 0x2c, 0xab, 0x12, 0xac, 0xd5, 0x42, 0x37, 0x60, 0xd4, 0xe3, 0xdc, 0xbf, 0x32, 0xca, 0x06,
- 0xf1, 0x9c, 0x8d, 0x41, 0x18, 0xc7, 0xc9, 0x7c, 0xf9, 0xe6, 0xde, 0xcc, 0xa8, 0x00, 0x62, 0x49,
- 0x0e, 0x3d, 0x09, 0x63, 0x61, 0x87, 0xf6, 0xdb, 0x6b, 0x55, 0xc6, 0xd8, 0xc2, 0x9c, 0x12, 0x7d,
- 0x1d, 0x5b, 0x13, 0x70, 0xac, 0x6a, 0xa0, 0x27, 0x60, 0x34, 0xee, 0x6e, 0xd2, 0xef, 0x58, 0x29,
- 0xb1, 0x81, 0x1d, 0x13, 0x95, 0x47, 0xab, 0x1c, 0x8c, 0x65, 0x39, 0x7a, 0x37, 0x94, 0x23, 0x52,
- 0xeb, 0x46, 0x31, 0xa1, 0x1f, 0xb6, 0x02, 0x0c, 0xf7, 0x09, 0x51, 0xbd, 0x8c, 0xd3, 0x22, 0xac,
- 0xd7, 0x43, 0xef, 0x83, 0x49, 0xfa, 0x81, 0x2f, 0xdc, 0xe8, 0x44, 0x24, 0x8e, 0xe9, 0x57, 0x2d,
- 0x33, 0x42, 0xa7, 0x45, 0xcb, 0xc9, 0x25, 0xa3, 0x14, 0x67, 0x6a, 0xa3, 0xd7, 0x01, 0x3c, 0xc5,
- 0x33, 0x2a, 0xe3, 0x6c, 0x32, 0x2f, 0xdb, 0x5b, 0x11, 0xcb, 0x0b, 0xf3, 0x93, 0xf4, 0x3b, 0xa6,
- 0xbf, 0xb1, 0x46, 0x8f, 0xce, 0x4f, 0x9d, 0xb4, 0x48, 0x42, 0xea, 0x95, 0x09, 0x36, 0x60, 0x35,
- 0x3f, 0x8b, 0x1c, 0x8c, 0x65, 0xb9, 0xfb, 0xf7, 0x0b, 0xa0, 0x61, 0x41, 0xf3, 0x30, 0x26, 0xf8,
- 0x9a, 0xd8, 0x92, 0xf3, 0x8f, 0xc9, 0xef, 0x20, 0xbf, 0xe0, 0xad, 0xbd, 0x5c, 0x7e, 0xa8, 0xda,
- 0xa1, 0x37, 0xa0, 0xdc, 0x09, 0xeb, 0xab, 0x24, 0xf1, 0xea, 0x5e, 0xe2, 0x89, 0xd3, 0xdc, 0xc2,
- 0x09, 0x23, 0x31, 0xce, 0x1f, 0xa3, 0x9f, 0x6e, 0x3d, 0x25, 0x81, 0x75, 0x7a, 0xe8, 0x59, 0x40,
- 0x31, 0x89, 0x76, 0xfc, 0x1a, 0x99, 0xab, 0xd5, 0xa8, 0x48, 0xc4, 0x36, 0xc0, 0x10, 0x1b, 0xcc,
- 0xb4, 0x18, 0x0c, 0xaa, 0xf6, 0xd4, 0xc0, 0x39, 0xad, 0xdc, 0xef, 0x15, 0x60, 0x52, 0x1b, 0x6b,
- 0x87, 0xd4, 0xd0, 0x5b, 0x0e, 0x1c, 0x53, 0xc7, 0xd9, 0xfc, 0xee, 0x15, 0xba, 0xaa, 0xf8, 0x61,
- 0x45, 0x6c, 0x7e, 0x5f, 0x4a, 0x4b, 0xfd, 0x14, 0x74, 0x38, 0xaf, 0x3f, 0x23, 0xc6, 0x70, 0x2c,
- 0x53, 0x8a, 0xb3, 0xdd, 0x9a, 0xfe, 0xb2, 0x03, 0x27, 0xf3, 0x50, 0xe4, 0xf0, 0xdc, 0xa6, 0xce,
- 0x73, 0xad, 0x32, 0x2f, 0x4a, 0x95, 0x0e, 0x46, 0xe7, 0xe3, 0xff, 0xaf, 0x00, 0x53, 0xfa, 0x12,
- 0x62, 0x92, 0xc0, 0xbf, 0x74, 0xe0, 0x94, 0x1c, 0x01, 0x26, 0x71, 0xb7, 0x95, 0x99, 0xde, 0xb6,
- 0xd5, 0xe9, 0xe5, 0x27, 0xe9, 0x5c, 0x1e, 0x3d, 0x3e, 0xcd, 0x0f, 0x89, 0x69, 0x3e, 0x95, 0x5b,
- 0x07, 0xe7, 0x77, 0x75, 0xfa, 0x9b, 0x0e, 0x4c, 0xf7, 0x47, 0x9a, 0x33, 0xf1, 0x1d, 0x73, 0xe2,
- 0x5f, 0xb4, 0x37, 0x48, 0x4e, 0x9e, 0x4d, 0x3f, 0x1b, 0xac, 0xfe, 0x01, 0x7e, 0x6b, 0x0c, 0x7a,
- 0xce, 0x10, 0xf4, 0x14, 0x94, 0x05, 0x3b, 0xbe, 0x1c, 0x36, 0x62, 0xd6, 0xc9, 0x31, 0xbe, 0xd7,
- 0xe6, 0x52, 0x30, 0xd6, 0xeb, 0xa0, 0x3a, 0x14, 0xe2, 0xa7, 0x45, 0xd7, 0x2d, 0xb0, 0xb7, 0xea,
- 0xd3, 0x4a, 0x8a, 0x1c, 0xb9, 0xb9, 0x37, 0x53, 0xa8, 0x3e, 0x8d, 0x0b, 0xf1, 0xd3, 0x54, 0x52,
- 0x6f, 0xf8, 0x89, 0x3d, 0x49, 0x7d, 0xd9, 0x4f, 0x14, 0x1d, 0x26, 0xa9, 0x2f, 0xfb, 0x09, 0xa6,
- 0x24, 0xa8, 0x06, 0xd2, 0x4c, 0x92, 0x0e, 0x3b, 0xf1, 0xad, 0x68, 0x20, 0x17, 0x37, 0x36, 0xd6,
- 0x15, 0x2d, 0x26, 0x5f, 0x50, 0x08, 0x66, 0x54, 0xd0, 0x67, 0x1c, 0x3a, 0xe3, 0xbc, 0x30, 0x8c,
- 0x76, 0x85, 0xe0, 0x70, 0xd5, 0xde, 0x12, 0x08, 0xa3, 0x5d, 0x45, 0x5c, 0x7c, 0x48, 0x55, 0x80,
- 0x75, 0xd2, 0x6c, 0xe0, 0xf5, 0xad, 0x98, 0xc9, 0x09, 0x76, 0x06, 0xbe, 0xb8, 0x54, 0xcd, 0x0c,
- 0x7c, 0x71, 0xa9, 0x8a, 0x19, 0x15, 0xfa, 0x41, 0x23, 0xef, 0xba, 0x90, 0x31, 0x2c, 0x7c, 0x50,
- 0xec, 0x5d, 0x37, 0x3f, 0x28, 0xf6, 0xae, 0x63, 0x4a, 0x82, 0x52, 0x0a, 0xe3, 0x98, 0x89, 0x14,
- 0x56, 0x28, 0xad, 0x55, 0xab, 0x26, 0xa5, 0xb5, 0x6a, 0x15, 0x53, 0x12, 0x6c, 0x91, 0xd6, 0x62,
- 0x26, 0x8f, 0xd8, 0x59, 0xa4, 0x0b, 0x19, 0x4a, 0xcb, 0x0b, 0x55, 0x4c, 0x49, 0x50, 0x96, 0xe1,
- 0xbd, 0xda, 0x8d, 0xb8, 0x30, 0x53, 0x3e, 0xbf, 0x66, 0x61, 0xbd, 0x50, 0x74, 0x8a, 0x5a, 0xe9,
- 0xe6, 0xde, 0x4c, 0x91, 0x81, 0x30, 0x27, 0xe4, 0xfe, 0xc1, 0x50, 0xca, 0x2e, 0x24, 0x3f, 0x47,
- 0xbf, 0xc6, 0x0e, 0x42, 0xc1, 0x0b, 0x84, 0xe8, 0xeb, 0x1c, 0x9a, 0xe8, 0x7b, 0x82, 0x9f, 0x78,
- 0x06, 0x39, 0x9c, 0xa5, 0x8f, 0xbe, 0xe0, 0xf4, 0xea, 0xb6, 0x9e, 0xfd, 0xb3, 0x2c, 0x3d, 0x98,
- 0xf9, 0x59, 0xb1, 0xaf, 0xca, 0x3b, 0xfd, 0x19, 0x27, 0x15, 0x22, 0xe2, 0x7e, 0xe7, 0xc0, 0x47,
- 0xcc, 0x73, 0xc0, 0xa2, 0x42, 0xae, 0xf3, 0xfd, 0xcf, 0x3a, 0x30, 0x21, 0xe1, 0x54, 0x3c, 0x8e,
- 0xd1, 0x0d, 0x18, 0x93, 0x3d, 0x15, 0x5f, 0xcf, 0xa6, 0x2d, 0x40, 0x09, 0xf1, 0xaa, 0x33, 0x8a,
- 0x9a, 0xfb, 0xd6, 0x08, 0xa0, 0xf4, 0xac, 0xea, 0x84, 0xb1, 0xcf, 0x38, 0xd1, 0x1d, 0x9c, 0x42,
- 0x81, 0x76, 0x0a, 0x3d, 0x6f, 0xf3, 0x14, 0x4a, 0xbb, 0x65, 0x9c, 0x47, 0x5f, 0xc8, 0xf0, 0x6d,
- 0x7e, 0x30, 0x7d, 0xf8, 0x50, 0xf8, 0xb6, 0xd6, 0x85, 0xfd, 0x39, 0xf8, 0x8e, 0xe0, 0xe0, 0xfc,
- 0xe8, 0xfa, 0x05, 0xbb, 0x1c, 0x5c, 0xeb, 0x45, 0x96, 0x97, 0x47, 0x9c, 0xc3, 0xf2, 0xb3, 0xeb,
- 0x9a, 0x55, 0x0e, 0xab, 0x51, 0x35, 0x79, 0x6d, 0xc4, 0x79, 0xed, 0x88, 0x2d, 0x9a, 0x1a, 0xaf,
- 0xcd, 0xd2, 0x54, 0x5c, 0xf7, 0x55, 0xc9, 0x75, 0xf9, 0xa9, 0xf5, 0x82, 0x65, 0xae, 0xab, 0xd1,
- 0xed, 0xe5, 0xbf, 0xaf, 0xc0, 0xa9, 0xde, 0x7a, 0x98, 0x6c, 0xa1, 0x73, 0x50, 0xaa, 0x85, 0xc1,
- 0x96, 0xdf, 0x58, 0xf5, 0x3a, 0x42, 0x5f, 0x53, 0xbc, 0x68, 0x41, 0x16, 0xe0, 0xb4, 0x0e, 0x7a,
- 0x88, 0x33, 0x1e, 0x6e, 0x11, 0x29, 0x8b, 0xaa, 0x43, 0x2b, 0x64, 0x97, 0x71, 0xa1, 0xf7, 0x8c,
- 0x7d, 0xe5, 0xeb, 0x33, 0xf7, 0x7d, 0xfc, 0x8f, 0x1f, 0xbe, 0xcf, 0xfd, 0xa3, 0x21, 0x78, 0x20,
- 0x97, 0xa6, 0x90, 0xd6, 0x7f, 0xcb, 0x90, 0xd6, 0xb5, 0x72, 0xc1, 0x45, 0xae, 0xd9, 0x14, 0x64,
- 0x35, 0xf4, 0x79, 0x72, 0xb9, 0x56, 0x8c, 0xf3, 0x3b, 0x45, 0x27, 0x2a, 0xf0, 0xda, 0x24, 0xee,
- 0x78, 0x35, 0x22, 0x46, 0xaf, 0x26, 0xea, 0x8a, 0x2c, 0xc0, 0x69, 0x1d, 0xae, 0x42, 0x6f, 0x79,
- 0xdd, 0x56, 0x22, 0x0c, 0x65, 0x9a, 0x0a, 0xcd, 0xc0, 0x58, 0x96, 0xa3, 0x7f, 0xe0, 0x00, 0xea,
- 0xa5, 0x2a, 0x36, 0xe2, 0xc6, 0x61, 0xcc, 0xc3, 0xfc, 0xe9, 0x9b, 0x9a, 0x12, 0xae, 0x8d, 0x34,
- 0xa7, 0x1f, 0xda, 0x37, 0xfd, 0x68, 0x7a, 0x0e, 0x71, 0xe5, 0x60, 0x00, 0x1b, 0x1a, 0x33, 0xb5,
- 0xd4, 0x6a, 0x24, 0x8e, 0xb9, 0x39, 0x4e, 0x37, 0xb5, 0x30, 0x30, 0x96, 0xe5, 0x68, 0x06, 0x8a,
- 0x24, 0x8a, 0xc2, 0x48, 0xe8, 0xda, 0x6c, 0x19, 0x5f, 0xa0, 0x00, 0xcc, 0xe1, 0xee, 0x8f, 0x0a,
- 0x50, 0xe9, 0xa7, 0x9d, 0xa0, 0xdf, 0xd5, 0xf4, 0x6a, 0xa1, 0x39, 0x09, 0xc5, 0x2f, 0x3c, 0x3c,
- 0x9d, 0x28, 0xab, 0x00, 0xf6, 0xd1, 0xb0, 0x45, 0x29, 0xce, 0x76, 0x70, 0xfa, 0x8b, 0x9a, 0x86,
- 0xad, 0xa3, 0xc8, 0x39, 0xe0, 0xb7, 0xcc, 0x03, 0x7e, 0xdd, 0xf6, 0xa0, 0xf4, 0x63, 0xfe, 0x4f,
- 0x8a, 0x70, 0x42, 0x96, 0x56, 0x09, 0x3d, 0x2a, 0x9f, 0xeb, 0x92, 0x68, 0x17, 0x7d, 0xdf, 0x81,
- 0x93, 0x5e, 0xd6, 0x74, 0xe3, 0x93, 0x43, 0x98, 0x68, 0x8d, 0xea, 0xec, 0x5c, 0x0e, 0x45, 0x3e,
- 0xd1, 0xe7, 0xc5, 0x44, 0x9f, 0xcc, 0xab, 0xd2, 0xc7, 0xee, 0x9e, 0x3b, 0x00, 0xf4, 0x0c, 0x8c,
- 0x4b, 0x38, 0x33, 0xf7, 0xf0, 0x2d, 0xae, 0x8c, 0xdb, 0x73, 0x5a, 0x19, 0x36, 0x6a, 0xd2, 0x96,
- 0x09, 0x69, 0x77, 0x5a, 0x5e, 0x42, 0x34, 0x43, 0x91, 0x6a, 0xb9, 0xa1, 0x95, 0x61, 0xa3, 0x26,
- 0x7a, 0x0c, 0x46, 0x82, 0xb0, 0x4e, 0x2e, 0xd5, 0x85, 0x81, 0x78, 0x52, 0xb4, 0x19, 0xb9, 0xc2,
- 0xa0, 0x58, 0x94, 0xa2, 0x47, 0x53, 0x6b, 0x5c, 0x91, 0x6d, 0xa1, 0x72, 0x9e, 0x25, 0x0e, 0xfd,
- 0x23, 0x07, 0x4a, 0xb4, 0xc5, 0xc6, 0x6e, 0x87, 0xd0, 0xb3, 0x8d, 0x7e, 0x91, 0xfa, 0xe1, 0x7c,
- 0x91, 0x2b, 0x92, 0x8c, 0x69, 0xea, 0x28, 0x29, 0xf8, 0x9b, 0x6f, 0xcf, 0x8c, 0xc9, 0x1f, 0x38,
- 0xed, 0xd5, 0xf4, 0x32, 0xdc, 0xdf, 0xf7, 0x6b, 0x1e, 0xc8, 0x15, 0xf0, 0xb7, 0x60, 0xd2, 0xec,
- 0xc4, 0x81, 0xfc, 0x00, 0xff, 0x5c, 0xdb, 0x76, 0x7c, 0x5c, 0x82, 0x9f, 0xdd, 0x33, 0x69, 0x56,
- 0x2d, 0x86, 0x45, 0xb1, 0xf4, 0xcc, 0xc5, 0xb0, 0x28, 0x16, 0xc3, 0xa2, 0xfb, 0x87, 0x4e, 0xba,
- 0x35, 0x35, 0x31, 0x8f, 0x1e, 0xcc, 0xdd, 0xa8, 0x25, 0x18, 0xb1, 0x3a, 0x98, 0xaf, 0xe2, 0xcb,
- 0x98, 0xc2, 0xd1, 0x17, 0x35, 0xee, 0x48, 0x9b, 0x75, 0x85, 0x5b, 0xc3, 0x92, 0x89, 0xde, 0x40,
- 0xdc, 0xcb, 0xff, 0x44, 0x01, 0xce, 0x76, 0xc1, 0xfd, 0x42, 0x01, 0x1e, 0xda, 0x57, 0x68, 0xcd,
- 0xed, 0xb8, 0x73, 0xcf, 0x3b, 0x4e, 0x8f, 0xb5, 0x88, 0x74, 0xc2, 0xab, 0xf8, 0xb2, 0xf8, 0x5e,
- 0xea, 0x58, 0xc3, 0x1c, 0x8c, 0x65, 0x39, 0x15, 0x1d, 0xb6, 0xc9, 0xee, 0x52, 0x18, 0xb5, 0xbd,
- 0x44, 0x70, 0x07, 0x25, 0x3a, 0xac, 0xc8, 0x02, 0x9c, 0xd6, 0x71, 0xbf, 0xef, 0x40, 0xb6, 0x03,
- 0xc8, 0x83, 0xc9, 0x6e, 0x4c, 0x22, 0x7a, 0xa4, 0x56, 0x49, 0x2d, 0x22, 0x72, 0x79, 0x3e, 0x3a,
- 0xcb, 0xbd, 0xfd, 0x74, 0x84, 0xb3, 0xb5, 0x30, 0x22, 0xb3, 0x3b, 0x4f, 0xcd, 0xf2, 0x1a, 0x2b,
- 0x64, 0xb7, 0x4a, 0x5a, 0x84, 0xe2, 0x98, 0x47, 0x37, 0xf7, 0x66, 0x26, 0xaf, 0x1a, 0x08, 0x70,
- 0x06, 0x21, 0x25, 0xd1, 0xf1, 0xe2, 0xf8, 0x7a, 0x18, 0xd5, 0x05, 0x89, 0xc2, 0x81, 0x49, 0xac,
- 0x1b, 0x08, 0x70, 0x06, 0xa1, 0xfb, 0x3d, 0xaa, 0x3e, 0xea, 0x52, 0x2b, 0xfa, 0x3a, 0x95, 0x7d,
- 0x28, 0x64, 0xbe, 0x15, 0x6e, 0x2e, 0x84, 0x41, 0xe2, 0xf9, 0x01, 0x91, 0xc1, 0x02, 0x1b, 0x96,
- 0x64, 0x64, 0x03, 0x77, 0x6a, 0xc3, 0xef, 0x2d, 0xc3, 0x39, 0x7d, 0xa1, 0x32, 0xce, 0x66, 0x2b,
- 0xdc, 0xcc, 0x7a, 0x01, 0x69, 0x25, 0xcc, 0x4a, 0xdc, 0x9f, 0x38, 0x70, 0xa6, 0x8f, 0x30, 0x8e,
- 0xbe, 0xec, 0xc0, 0xc4, 0xe6, 0x4f, 0xc5, 0xd8, 0xcc, 0x6e, 0xa0, 0xf7, 0xc1, 0x24, 0x05, 0xd0,
- 0x93, 0x48, 0xac, 0xcd, 0x82, 0xe9, 0xa1, 0x9a, 0x37, 0x4a, 0x71, 0xa6, 0xb6, 0xfb, 0xeb, 0x05,
- 0xc8, 0xa1, 0x82, 0x9e, 0x84, 0x31, 0x12, 0xd4, 0x3b, 0xa1, 0x1f, 0x24, 0x82, 0x19, 0x29, 0xae,
- 0x77, 0x41, 0xc0, 0xb1, 0xaa, 0x21, 0xf4, 0x0f, 0x31, 0x31, 0x85, 0x1e, 0xfd, 0x43, 0xf4, 0x3c,
- 0xad, 0x83, 0x1a, 0x30, 0xe5, 0x71, 0xff, 0x0a, 0x5b, 0x7b, 0x6c, 0x99, 0x0e, 0x1d, 0x64, 0x99,
- 0x9e, 0x64, 0xee, 0xcf, 0x0c, 0x0a, 0xdc, 0x83, 0x14, 0xbd, 0x1b, 0xca, 0xdd, 0x98, 0x54, 0x17,
- 0x57, 0x16, 0x22, 0x52, 0xe7, 0x5a, 0xb1, 0xe6, 0xf7, 0xbb, 0x9a, 0x16, 0x61, 0xbd, 0x9e, 0xfb,
- 0xaf, 0x1c, 0x18, 0x9d, 0xf7, 0x6a, 0xdb, 0xe1, 0xd6, 0x16, 0x9d, 0x8a, 0x7a, 0x37, 0x4a, 0x0d,
- 0x5b, 0xda, 0x54, 0x2c, 0x0a, 0x38, 0x56, 0x35, 0xd0, 0x06, 0x8c, 0xf0, 0x0d, 0x2f, 0xb6, 0xdd,
- 0xcf, 0x6b, 0xe3, 0x51, 0x71, 0x3c, 0x6c, 0x39, 0x74, 0x13, 0xbf, 0x35, 0xcb, 0xe3, 0x78, 0x66,
- 0x2f, 0x05, 0xc9, 0x5a, 0x54, 0x4d, 0x22, 0x3f, 0x68, 0xcc, 0x03, 0x3d, 0x2e, 0x96, 0x18, 0x0e,
- 0x2c, 0x70, 0xd1, 0x61, 0xb4, 0xbd, 0x1b, 0x92, 0x9c, 0x60, 0x3f, 0x6a, 0x18, 0xab, 0x69, 0x11,
- 0xd6, 0xeb, 0xb9, 0x7f, 0xe4, 0x40, 0x69, 0xde, 0x8b, 0xfd, 0xda, 0x5f, 0x22, 0xe6, 0xf3, 0x21,
- 0x28, 0x2e, 0x78, 0xb5, 0x26, 0x41, 0x57, 0xb3, 0x4a, 0x6f, 0xf9, 0xfc, 0xe3, 0x79, 0x64, 0x94,
- 0x02, 0xac, 0x53, 0x9a, 0xe8, 0xa7, 0x1a, 0xbb, 0x6f, 0x3b, 0x30, 0xb9, 0xd0, 0xf2, 0x49, 0x90,
- 0x2c, 0x90, 0x28, 0x61, 0x13, 0xd7, 0x80, 0xa9, 0x9a, 0x82, 0xdc, 0xc9, 0xd4, 0xb1, 0xd5, 0xba,
- 0x90, 0x41, 0x81, 0x7b, 0x90, 0xa2, 0x3a, 0x1c, 0xe3, 0xb0, 0x74, 0x57, 0x1c, 0x68, 0xfe, 0x98,
- 0x75, 0x74, 0xc1, 0xc4, 0x80, 0xb3, 0x28, 0xdd, 0x1f, 0x3b, 0x70, 0x66, 0xa1, 0xd5, 0x8d, 0x13,
- 0x12, 0x5d, 0x13, 0xdc, 0x48, 0x8a, 0xb7, 0xe8, 0x23, 0x30, 0xd6, 0x96, 0x1e, 0x5b, 0xe7, 0x36,
- 0x0b, 0x98, 0xf1, 0x33, 0x5a, 0x9b, 0x76, 0x66, 0x6d, 0xf3, 0x65, 0x52, 0x4b, 0x56, 0x49, 0xe2,
- 0xa5, 0xe1, 0x05, 0x29, 0x0c, 0x2b, 0xac, 0xa8, 0x03, 0xc3, 0x71, 0x87, 0xd4, 0xec, 0x45, 0x77,
- 0xc9, 0x31, 0x54, 0x3b, 0xa4, 0x96, 0xf2, 0x75, 0xe6, 0x6b, 0x64, 0x94, 0xdc, 0xff, 0xed, 0xc0,
- 0x03, 0x7d, 0xc6, 0x7b, 0xd9, 0x8f, 0x13, 0xf4, 0x52, 0xcf, 0x98, 0x67, 0x07, 0x1b, 0x33, 0x6d,
- 0xcd, 0x46, 0xac, 0x18, 0x82, 0x84, 0x68, 0xe3, 0xfd, 0x28, 0x14, 0xfd, 0x84, 0xb4, 0xa5, 0x19,
- 0xda, 0x82, 0xc1, 0xa8, 0xcf, 0x58, 0xe6, 0x27, 0x64, 0x8c, 0xdf, 0x25, 0x4a, 0x0f, 0x73, 0xb2,
- 0xee, 0x36, 0x8c, 0x2c, 0x84, 0xad, 0x6e, 0x3b, 0x18, 0x2c, 0x52, 0x26, 0xd9, 0xed, 0x90, 0xec,
- 0x19, 0xc9, 0xc4, 0x7f, 0x56, 0x22, 0x0d, 0x47, 0x43, 0xf9, 0x86, 0x23, 0xf7, 0x5f, 0x3b, 0x40,
- 0x77, 0x55, 0xdd, 0x17, 0x9e, 0x44, 0x8e, 0x8e, 0x13, 0x7c, 0x48, 0x47, 0x77, 0x6b, 0x6f, 0x66,
- 0x42, 0x55, 0xd4, 0xf0, 0x7f, 0x08, 0x46, 0x62, 0xa6, 0x92, 0x8b, 0x3e, 0x2c, 0x49, 0xf9, 0x99,
- 0x2b, 0xea, 0xb7, 0xf6, 0x66, 0x06, 0x0a, 0xdb, 0x9c, 0x55, 0xb8, 0x85, 0xd3, 0x53, 0x60, 0xa5,
- 0x02, 0x5f, 0x9b, 0xc4, 0xb1, 0xd7, 0x90, 0x1a, 0x9e, 0x12, 0xf8, 0x56, 0x39, 0x18, 0xcb, 0x72,
- 0xf7, 0x4b, 0x0e, 0x4c, 0xa8, 0xc3, 0x8b, 0x8a, 0xef, 0xe8, 0x8a, 0x7e, 0xcc, 0xf1, 0x95, 0xf2,
- 0x50, 0x1f, 0x8e, 0x23, 0x0e, 0xf2, 0xfd, 0x4f, 0xc1, 0x77, 0xc1, 0x78, 0x9d, 0x74, 0x48, 0x50,
- 0x27, 0x41, 0x8d, 0xaa, 0xdf, 0x74, 0x85, 0x94, 0xe6, 0xa7, 0xa8, 0xbe, 0xb9, 0xa8, 0xc1, 0xb1,
- 0x51, 0xcb, 0xfd, 0x86, 0x03, 0xf7, 0x2b, 0x74, 0x55, 0x92, 0x60, 0x92, 0x44, 0xbb, 0x2a, 0x4c,
- 0xf3, 0x60, 0xa7, 0xd5, 0x35, 0x2a, 0xff, 0x26, 0x11, 0x27, 0x7e, 0x67, 0xc7, 0x55, 0x99, 0x4b,
- 0xcb, 0x0c, 0x09, 0x96, 0xd8, 0xdc, 0x5f, 0x1d, 0x82, 0x93, 0x7a, 0x27, 0x15, 0x83, 0xf9, 0x25,
- 0x07, 0x40, 0xcd, 0x00, 0x3d, 0x90, 0x87, 0xec, 0xf8, 0xae, 0x8c, 0x2f, 0x95, 0xb2, 0x20, 0x05,
- 0x8e, 0xb1, 0x46, 0x16, 0xbd, 0x00, 0xe3, 0x3b, 0x74, 0x53, 0x90, 0x55, 0x2a, 0x2e, 0xc4, 0x95,
- 0x21, 0xd6, 0x8d, 0x99, 0xbc, 0x8f, 0xf9, 0x7c, 0x5a, 0x2f, 0x35, 0x07, 0x68, 0xc0, 0x18, 0x1b,
- 0xa8, 0xa8, 0xa6, 0x33, 0x11, 0xe9, 0x9f, 0x44, 0xd8, 0xc4, 0x3f, 0x68, 0x71, 0x8c, 0xd9, 0xaf,
- 0x3e, 0x7f, 0xfc, 0xe6, 0xde, 0xcc, 0x84, 0x01, 0xc2, 0x66, 0x27, 0xdc, 0x17, 0x80, 0xcd, 0x85,
- 0x1f, 0x74, 0xc9, 0x5a, 0x80, 0x1e, 0x91, 0x36, 0x3a, 0xee, 0x57, 0x51, 0x9c, 0x43, 0xb7, 0xd3,
- 0x51, 0x5d, 0x76, 0xcb, 0xf3, 0x5b, 0x2c, 0x7c, 0x91, 0xd6, 0x52, 0xba, 0xec, 0x12, 0x83, 0x62,
- 0x51, 0xea, 0xce, 0xc2, 0xe8, 0x02, 0x1d, 0x3b, 0x89, 0x28, 0x5e, 0x3d, 0xea, 0x78, 0xc2, 0x88,
- 0x3a, 0x96, 0xd1, 0xc5, 0x1b, 0x70, 0x6a, 0x21, 0x22, 0x5e, 0x42, 0xaa, 0x4f, 0xcf, 0x77, 0x6b,
- 0xdb, 0x24, 0xe1, 0xa1, 0x5d, 0x31, 0x7a, 0x2f, 0x4c, 0x84, 0xec, 0xc8, 0xb8, 0x1c, 0xd6, 0xb6,
- 0xfd, 0xa0, 0x21, 0x4c, 0xae, 0xa7, 0x04, 0x96, 0x89, 0x35, 0xbd, 0x10, 0x9b, 0x75, 0xdd, 0xff,
- 0x54, 0x80, 0xf1, 0x85, 0x28, 0x0c, 0x24, 0x5b, 0x3c, 0x82, 0xa3, 0x2c, 0x31, 0x8e, 0x32, 0x0b,
- 0xee, 0x4e, 0xbd, 0xff, 0xfd, 0x8e, 0x33, 0xf4, 0xba, 0x62, 0x91, 0x43, 0xb6, 0x54, 0x10, 0x83,
- 0x2e, 0xc3, 0x9d, 0x7e, 0x6c, 0x93, 0x81, 0xba, 0xff, 0xd9, 0x81, 0x29, 0xbd, 0xfa, 0x11, 0x9c,
- 0xa0, 0xb1, 0x79, 0x82, 0x5e, 0xb1, 0x3b, 0xde, 0x3e, 0xc7, 0xe6, 0xbf, 0x18, 0x35, 0xc7, 0xc9,
- 0x7c, 0xdd, 0x5f, 0x71, 0x60, 0xfc, 0xba, 0x06, 0x10, 0x83, 0xb5, 0x2d, 0xc4, 0xbc, 0x43, 0xb2,
- 0x19, 0x1d, 0x7a, 0x2b, 0xf3, 0x1b, 0x1b, 0x3d, 0xa1, 0x7c, 0x3f, 0xae, 0x35, 0x49, 0xbd, 0xdb,
- 0x92, 0xc7, 0xb7, 0x9a, 0xd2, 0xaa, 0x80, 0x63, 0x55, 0x03, 0xbd, 0x04, 0xc7, 0x6b, 0x61, 0x50,
- 0xeb, 0x46, 0x11, 0x09, 0x6a, 0xbb, 0xeb, 0xec, 0x8e, 0x84, 0x38, 0x10, 0x67, 0x45, 0xb3, 0xe3,
- 0x0b, 0xd9, 0x0a, 0xb7, 0xf2, 0x80, 0xb8, 0x17, 0x11, 0x77, 0x16, 0xc4, 0xf4, 0xc8, 0x12, 0x0a,
- 0x97, 0xe6, 0x2c, 0x60, 0x60, 0x2c, 0xcb, 0xd1, 0x55, 0x38, 0x13, 0x27, 0x5e, 0x94, 0xf8, 0x41,
- 0x63, 0x91, 0x78, 0xf5, 0x96, 0x1f, 0x50, 0x55, 0x22, 0x0c, 0xea, 0xdc, 0x95, 0x38, 0x34, 0xff,
- 0xc0, 0xcd, 0xbd, 0x99, 0x33, 0xd5, 0xfc, 0x2a, 0xb8, 0x5f, 0x5b, 0xf4, 0x21, 0x98, 0x16, 0xee,
- 0x88, 0xad, 0x6e, 0xeb, 0xd9, 0x70, 0x33, 0xbe, 0xe8, 0xc7, 0x54, 0x8f, 0xbf, 0xec, 0xb7, 0xfd,
- 0x84, 0x39, 0x0c, 0x8b, 0xf3, 0x67, 0x6f, 0xee, 0xcd, 0x4c, 0x57, 0xfb, 0xd6, 0xc2, 0xfb, 0x60,
- 0x40, 0x18, 0x4e, 0x73, 0xe6, 0xd7, 0x83, 0x7b, 0x94, 0xe1, 0x9e, 0xbe, 0xb9, 0x37, 0x73, 0x7a,
- 0x29, 0xb7, 0x06, 0xee, 0xd3, 0x92, 0x7e, 0xc1, 0xc4, 0x6f, 0x93, 0x57, 0xc3, 0x80, 0xb0, 0x40,
- 0x15, 0xed, 0x0b, 0x6e, 0x08, 0x38, 0x56, 0x35, 0xd0, 0xcb, 0xe9, 0x4a, 0xa4, 0xdb, 0x45, 0x04,
- 0x9c, 0x1c, 0x9c, 0xc3, 0x31, 0xd5, 0xe4, 0x9a, 0x86, 0x89, 0x45, 0x52, 0x1a, 0xb8, 0xd1, 0x27,
- 0x1c, 0x18, 0x8f, 0x93, 0x50, 0xdd, 0x6b, 0x10, 0x11, 0x27, 0x16, 0x96, 0x7d, 0x55, 0xc3, 0xca,
- 0x05, 0x1f, 0x1d, 0x82, 0x0d, 0xaa, 0xe8, 0xe7, 0xa0, 0x24, 0x17, 0x70, 0x5c, 0x29, 0x33, 0x59,
- 0x89, 0xa9, 0x71, 0x72, 0x7d, 0xc7, 0x38, 0x2d, 0x77, 0x7f, 0x34, 0x04, 0xa8, 0x97, 0xad, 0xa1,
- 0x15, 0x18, 0xf1, 0x6a, 0x89, 0xbf, 0x23, 0xa3, 0x09, 0x1f, 0xc9, 0x3b, 0xf2, 0xf9, 0xf4, 0x60,
- 0xb2, 0x45, 0xe8, 0xaa, 0x26, 0x29, 0x2f, 0x9c, 0x63, 0x4d, 0xb1, 0x40, 0x81, 0x42, 0x38, 0xde,
- 0xf2, 0xe2, 0x44, 0xd2, 0xaf, 0xd3, 0xcf, 0x24, 0x0e, 0x83, 0x9f, 0x1d, 0xec, 0x43, 0xd0, 0x16,
- 0xf3, 0xa7, 0xe8, 0x6e, 0xbb, 0x9c, 0x45, 0x84, 0x7b, 0x71, 0xa3, 0x8f, 0x31, 0xd9, 0x89, 0x0b,
- 0xb6, 0x52, 0x68, 0x59, 0xb1, 0x22, 0x57, 0x70, 0x9c, 0x86, 0xdc, 0x24, 0xc8, 0x60, 0x8d, 0x24,
- 0x3a, 0x07, 0x25, 0xb6, 0x2b, 0x48, 0x9d, 0xf0, 0xbd, 0x3d, 0x94, 0x8a, 0xb8, 0x55, 0x59, 0x80,
- 0xd3, 0x3a, 0x9a, 0x0c, 0xc1, 0xb7, 0x73, 0x1f, 0x19, 0x02, 0x3d, 0x03, 0xc5, 0x4e, 0xd3, 0x8b,
- 0x65, 0x84, 0xba, 0x2b, 0x79, 0xf2, 0x3a, 0x05, 0x32, 0xc6, 0xa3, 0x7d, 0x4b, 0x06, 0xc4, 0xbc,
- 0x81, 0xfb, 0x6f, 0x00, 0x46, 0x17, 0xe7, 0x96, 0x37, 0xbc, 0x78, 0x7b, 0x00, 0x0d, 0x87, 0x6e,
- 0x32, 0x21, 0x8a, 0x66, 0xd9, 0xa4, 0x14, 0x51, 0xb1, 0xaa, 0x81, 0x02, 0x18, 0xf1, 0x03, 0xca,
- 0x57, 0x2a, 0x93, 0xb6, 0xbc, 0x08, 0x4a, 0x5b, 0x63, 0x66, 0x9e, 0x4b, 0x0c, 0x3b, 0x16, 0x54,
- 0xd0, 0xeb, 0x50, 0xf2, 0xe4, 0x05, 0x21, 0x71, 0xba, 0xaf, 0xd8, 0x30, 0x8f, 0x0b, 0x94, 0x7a,
- 0x80, 0x92, 0x00, 0xe1, 0x94, 0x20, 0xfa, 0xb8, 0x03, 0x65, 0x39, 0x74, 0x4c, 0xb6, 0x84, 0xe7,
- 0x7a, 0xd5, 0xde, 0x98, 0x31, 0xd9, 0xe2, 0xd1, 0x2b, 0x1a, 0x00, 0xeb, 0x24, 0x7b, 0x34, 0xa2,
- 0xe2, 0x20, 0x1a, 0x11, 0xba, 0x0e, 0xa5, 0xeb, 0x7e, 0xd2, 0x64, 0xe7, 0xb7, 0xf0, 0x98, 0x2d,
- 0xdd, 0x7d, 0xaf, 0x29, 0xba, 0x74, 0xc6, 0xae, 0x49, 0x02, 0x38, 0xa5, 0x45, 0xb7, 0x03, 0xfd,
- 0xc1, 0x2e, 0x58, 0x31, 0xce, 0x5f, 0x32, 0x1b, 0xb0, 0x02, 0x9c, 0xd6, 0xa1, 0x53, 0x3c, 0x4e,
- 0x7f, 0x55, 0xc9, 0x2b, 0x5d, 0xca, 0x5a, 0x44, 0x44, 0xa2, 0x85, 0x75, 0x25, 0x31, 0xf2, 0xc9,
- 0xba, 0xa6, 0xd1, 0xc0, 0x06, 0x45, 0xba, 0x47, 0xae, 0x37, 0x49, 0x20, 0x6e, 0x4c, 0xa8, 0x3d,
- 0x72, 0xad, 0x49, 0x02, 0xcc, 0x4a, 0xd0, 0xeb, 0x5c, 0x43, 0xe3, 0xaa, 0x82, 0xe0, 0xf5, 0x97,
- 0xed, 0x68, 0x2f, 0x1c, 0x27, 0xbf, 0xb4, 0x90, 0xfe, 0xc6, 0x1a, 0x3d, 0xca, 0x31, 0xc2, 0xe0,
- 0xc2, 0x0d, 0x3f, 0x11, 0x57, 0x2d, 0x14, 0xc7, 0x58, 0x63, 0x50, 0x2c, 0x4a, 0x79, 0x64, 0x06,
- 0x5d, 0x04, 0x31, 0xbb, 0x57, 0x51, 0xd2, 0x23, 0x33, 0x18, 0x18, 0xcb, 0x72, 0xf4, 0x0f, 0x1d,
- 0x28, 0x36, 0xc3, 0x70, 0x3b, 0xae, 0x4c, 0xb0, 0xc5, 0x61, 0x41, 0x62, 0x16, 0x1c, 0x67, 0xf6,
- 0x22, 0x45, 0x6b, 0x5e, 0x1e, 0x2b, 0x32, 0xd8, 0xad, 0xbd, 0x99, 0xc9, 0xcb, 0xfe, 0x16, 0xa9,
- 0xed, 0xd6, 0x5a, 0x84, 0x41, 0xde, 0x7c, 0x5b, 0x83, 0x5c, 0xd8, 0x21, 0x41, 0x82, 0x79, 0xaf,
- 0xa6, 0x3f, 0xeb, 0x00, 0xa4, 0x88, 0x72, 0x5c, 0xa0, 0xc4, 0x0c, 0x1a, 0xb0, 0xa0, 0x2e, 0x1b,
- 0x5d, 0xd3, 0x7d, 0xaa, 0xff, 0xd6, 0x81, 0x32, 0x1d, 0x9c, 0x64, 0x81, 0x8f, 0xc1, 0x48, 0xe2,
- 0x45, 0x0d, 0x22, 0xdd, 0x00, 0xea, 0x73, 0x6c, 0x30, 0x28, 0x16, 0xa5, 0x28, 0x80, 0x62, 0xe2,
- 0xc5, 0xdb, 0x52, 0x48, 0xbf, 0x64, 0x6d, 0x8a, 0x53, 0xf9, 0x9c, 0xfe, 0x8a, 0x31, 0x27, 0x83,
- 0x1e, 0x87, 0x31, 0x7a, 0x74, 0x2c, 0x79, 0xb1, 0x8c, 0xcc, 0x19, 0xa7, 0x4c, 0x7c, 0x49, 0xc0,
- 0xb0, 0x2a, 0x75, 0x7f, 0xbd, 0x00, 0xc3, 0x8b, 0x5c, 0x5d, 0x1b, 0x89, 0xc3, 0x6e, 0x54, 0x23,
- 0x42, 0x6c, 0xb7, 0xb0, 0xa6, 0x29, 0xde, 0x2a, 0xc3, 0xa9, 0x29, 0x4c, 0xec, 0x37, 0x16, 0xb4,
- 0xd0, 0x17, 0x1d, 0x98, 0x4c, 0x22, 0x2f, 0x88, 0xb7, 0x98, 0xc3, 0xc5, 0x0f, 0x03, 0x31, 0x45,
- 0x16, 0x56, 0xe1, 0x86, 0x81, 0xb7, 0x9a, 0x90, 0x4e, 0xea, 0xf7, 0x31, 0xcb, 0x70, 0xa6, 0x0f,
- 0xee, 0x6f, 0x38, 0x00, 0x69, 0xef, 0xd1, 0x67, 0x1c, 0x98, 0xf0, 0xf4, 0x88, 0x50, 0x31, 0x47,
- 0x6b, 0xf6, 0xbc, 0xb3, 0x0c, 0x2d, 0xb7, 0x54, 0x18, 0x20, 0x6c, 0x12, 0x76, 0xdf, 0x0d, 0x45,
- 0xb6, 0x3b, 0x98, 0x4a, 0x23, 0x2c, 0xdb, 0x59, 0x53, 0x96, 0xb4, 0x78, 0x63, 0x55, 0xc3, 0x7d,
- 0x09, 0x26, 0x2f, 0xdc, 0x20, 0xb5, 0x6e, 0x12, 0x46, 0xdc, 0xae, 0xdf, 0xe7, 0x06, 0x90, 0x73,
- 0x47, 0x37, 0x80, 0xbe, 0xed, 0x40, 0x59, 0x0b, 0x0f, 0xa4, 0x27, 0x75, 0x63, 0xa1, 0xca, 0xcd,
- 0x17, 0x62, 0xaa, 0x56, 0xac, 0x04, 0x20, 0x72, 0x94, 0xe9, 0x31, 0xa2, 0x40, 0x38, 0x25, 0x78,
- 0x9b, 0xf0, 0x3d, 0xf7, 0x0f, 0x1c, 0x38, 0x95, 0x1b, 0xcb, 0x78, 0x8f, 0xbb, 0x6d, 0xb8, 0xd0,
- 0x0b, 0x03, 0xb8, 0xd0, 0x7f, 0xc7, 0x81, 0x14, 0x13, 0x65, 0x45, 0x9b, 0x69, 0xcf, 0x35, 0x56,
- 0x24, 0x28, 0x89, 0x52, 0xf4, 0x3a, 0x9c, 0x31, 0xbf, 0xe0, 0x1d, 0x7a, 0x53, 0xb8, 0xea, 0x99,
- 0x8f, 0x09, 0xf7, 0x23, 0xe1, 0x7e, 0xd5, 0x81, 0xe2, 0xb2, 0xd7, 0x6d, 0x90, 0x81, 0x8c, 0x61,
- 0x94, 0x8f, 0x45, 0xc4, 0x6b, 0x25, 0x52, 0x75, 0x10, 0x7c, 0x0c, 0x0b, 0x18, 0x56, 0xa5, 0x68,
- 0x0e, 0x4a, 0x61, 0x87, 0x18, 0x1e, 0xc0, 0x47, 0xe4, 0xec, 0xad, 0xc9, 0x02, 0x7a, 0xec, 0x30,
- 0xea, 0x0a, 0x82, 0xd3, 0x56, 0xee, 0xf7, 0x8b, 0x50, 0xd6, 0x6e, 0xbd, 0x50, 0x59, 0x20, 0x22,
- 0x9d, 0x30, 0x2b, 0x2f, 0xd3, 0x05, 0x83, 0x59, 0x09, 0xdd, 0x83, 0x11, 0xd9, 0xf1, 0x63, 0xce,
- 0xb6, 0x8c, 0x3d, 0x88, 0x05, 0x1c, 0xab, 0x1a, 0x68, 0x06, 0x8a, 0x75, 0xd2, 0x49, 0x9a, 0xac,
- 0x7b, 0xc3, 0x3c, 0xf4, 0x6f, 0x91, 0x02, 0x30, 0x87, 0xd3, 0x0a, 0x5b, 0x24, 0xa9, 0x35, 0x99,
- 0xdd, 0x57, 0xc4, 0x06, 0x2e, 0x51, 0x00, 0xe6, 0xf0, 0x1c, 0x1f, 0x65, 0xf1, 0xf0, 0x7d, 0x94,
- 0x23, 0x96, 0x7d, 0x94, 0xa8, 0x03, 0x27, 0xe2, 0xb8, 0xb9, 0x1e, 0xf9, 0x3b, 0x5e, 0x42, 0xd2,
- 0xd5, 0x37, 0x7a, 0x10, 0x3a, 0x67, 0xd8, 0x3d, 0xf4, 0xea, 0xc5, 0x2c, 0x16, 0x9c, 0x87, 0x1a,
- 0x55, 0xe1, 0x94, 0x1f, 0xc4, 0xa4, 0xd6, 0x8d, 0xc8, 0xa5, 0x46, 0x10, 0x46, 0xe4, 0x62, 0x18,
- 0x53, 0x74, 0xe2, 0x16, 0xad, 0x8a, 0x96, 0xbd, 0x94, 0x57, 0x09, 0xe7, 0xb7, 0x45, 0xcb, 0x70,
- 0xbc, 0xee, 0xc7, 0xde, 0x66, 0x8b, 0x54, 0xbb, 0x9b, 0xed, 0x90, 0x2b, 0xde, 0x25, 0x86, 0xf0,
- 0x7e, 0x69, 0x25, 0x5a, 0xcc, 0x56, 0xc0, 0xbd, 0x6d, 0xd0, 0x33, 0x30, 0x1e, 0xfb, 0x41, 0xa3,
- 0x45, 0xe6, 0x23, 0x2f, 0xa8, 0x35, 0xc5, 0xf5, 0x5b, 0x65, 0x4d, 0xaf, 0x6a, 0x65, 0xd8, 0xa8,
- 0xc9, 0xf6, 0x3c, 0x6f, 0x93, 0x91, 0x06, 0x45, 0x6d, 0x51, 0xea, 0xfe, 0xc0, 0x81, 0x71, 0x3d,
- 0x52, 0x9d, 0x4a, 0xda, 0xd0, 0x5c, 0x5c, 0xaa, 0xf2, 0xb3, 0xc0, 0xde, 0x89, 0x7f, 0x51, 0xe1,
- 0x4c, 0x95, 0xe5, 0x14, 0x86, 0x35, 0x9a, 0x03, 0xdc, 0x3b, 0x7f, 0x04, 0x8a, 0x5b, 0x21, 0x15,
- 0x48, 0x86, 0x4c, 0x33, 0xfc, 0x12, 0x05, 0x62, 0x5e, 0xe6, 0xfe, 0x4f, 0x07, 0x4e, 0xe7, 0x07,
- 0xe1, 0xff, 0x34, 0x0c, 0xf2, 0x3c, 0x00, 0x1d, 0x8a, 0xc1, 0xd4, 0xb5, 0xcc, 0x13, 0xb2, 0x04,
- 0x6b, 0xb5, 0x06, 0x1b, 0xf6, 0x9f, 0x51, 0xa1, 0x38, 0xa5, 0xf3, 0x39, 0x07, 0x26, 0x28, 0xd9,
- 0x95, 0x68, 0xd3, 0x18, 0xed, 0x9a, 0x9d, 0xd1, 0x2a, 0xb4, 0xa9, 0xb7, 0xc1, 0x00, 0x63, 0x93,
- 0x38, 0xfa, 0x39, 0x28, 0x79, 0xf5, 0x7a, 0x44, 0xe2, 0x58, 0xf9, 0xed, 0x98, 0x2d, 0x6a, 0x4e,
- 0x02, 0x71, 0x5a, 0x4e, 0x99, 0x68, 0xb3, 0xbe, 0x15, 0x53, 0xbe, 0x24, 0x18, 0xb7, 0x62, 0xa2,
- 0x94, 0x08, 0x85, 0x63, 0x55, 0xc3, 0xfd, 0x95, 0x61, 0x30, 0x69, 0xa3, 0x3a, 0x1c, 0xdb, 0x8e,
- 0x36, 0x17, 0x58, 0xd8, 0xc3, 0x9d, 0x84, 0x1f, 0xb0, 0xb0, 0x80, 0x15, 0x13, 0x03, 0xce, 0xa2,
- 0x14, 0x54, 0x56, 0xc8, 0x6e, 0xe2, 0x6d, 0xde, 0x71, 0xf0, 0xc1, 0x8a, 0x89, 0x01, 0x67, 0x51,
- 0xa2, 0x77, 0x43, 0x79, 0x3b, 0xda, 0x94, 0x2c, 0x3a, 0x1b, 0xc9, 0xb2, 0x92, 0x16, 0x61, 0xbd,
- 0x1e, 0x9d, 0xc2, 0xed, 0x68, 0x93, 0x9e, 0x8a, 0x32, 0x0f, 0x83, 0x9a, 0xc2, 0x15, 0x01, 0xc7,
- 0xaa, 0x06, 0xea, 0x00, 0xda, 0x96, 0xb3, 0xa7, 0x82, 0x3c, 0xc4, 0x49, 0x32, 0x78, 0x8c, 0x08,
- 0x8b, 0xae, 0x5f, 0xe9, 0xc1, 0x83, 0x73, 0x70, 0xa3, 0x17, 0xe0, 0xcc, 0x76, 0xb4, 0x29, 0x84,
- 0x85, 0xf5, 0xc8, 0x0f, 0x6a, 0x7e, 0xc7, 0xc8, 0xb9, 0x30, 0x23, 0xba, 0x7b, 0x66, 0x25, 0xbf,
- 0x1a, 0xee, 0xd7, 0xde, 0xfd, 0xdd, 0x61, 0x60, 0xb7, 0x45, 0x29, 0x2f, 0x6c, 0x93, 0xa4, 0x19,
- 0xd6, 0xb3, 0xf2, 0xcf, 0x2a, 0x83, 0x62, 0x51, 0x2a, 0x63, 0x48, 0x0b, 0x7d, 0x62, 0x48, 0xaf,
- 0xc3, 0x68, 0x93, 0x78, 0x75, 0x12, 0x49, 0x0b, 0xe2, 0x65, 0x3b, 0xf7, 0x5b, 0x2f, 0x32, 0xa4,
- 0xa9, 0x1a, 0xce, 0x7f, 0xc7, 0x58, 0x52, 0x43, 0xef, 0x81, 0x49, 0x2a, 0xc8, 0x84, 0xdd, 0x44,
- 0x9a, 0xf8, 0xb9, 0x05, 0x91, 0x9d, 0xa8, 0x1b, 0x46, 0x09, 0xce, 0xd4, 0x44, 0x8b, 0x30, 0x25,
- 0xcc, 0xf1, 0xca, 0x32, 0x29, 0x26, 0x56, 0x25, 0xc3, 0xa8, 0x66, 0xca, 0x71, 0x4f, 0x0b, 0x16,
- 0x03, 0x18, 0xd6, 0xb9, 0x47, 0x56, 0x8f, 0x01, 0x0c, 0xeb, 0xbb, 0x98, 0x95, 0xa0, 0x57, 0x61,
- 0x8c, 0xfe, 0x5d, 0x8a, 0xc2, 0xb6, 0xb0, 0xcd, 0xac, 0xdb, 0x99, 0x1d, 0x4a, 0x43, 0x68, 0x8a,
- 0x4c, 0xc0, 0x9b, 0x17, 0x54, 0xb0, 0xa2, 0x47, 0xf5, 0x15, 0x79, 0x0e, 0x57, 0xb7, 0xfd, 0xce,
- 0xf3, 0x24, 0xf2, 0xb7, 0x76, 0x99, 0xd0, 0x30, 0x96, 0xea, 0x2b, 0x97, 0x7a, 0x6a, 0xe0, 0x9c,
- 0x56, 0xee, 0xe7, 0x0a, 0x30, 0xae, 0x5f, 0x3a, 0xbe, 0x5d, 0x60, 0x71, 0x9c, 0x2e, 0x0a, 0xae,
- 0x9d, 0x5e, 0xb4, 0x30, 0xec, 0xdb, 0x2d, 0x88, 0x26, 0x0c, 0x7b, 0x5d, 0x21, 0x2d, 0x5a, 0x31,
- 0x82, 0xb1, 0x11, 0x77, 0x93, 0x26, 0xbf, 0x9d, 0xc6, 0x42, 0x7e, 0x19, 0x05, 0xf7, 0x93, 0x43,
- 0x30, 0x26, 0x0b, 0xd1, 0x27, 0x1c, 0x80, 0x34, 0xf4, 0x4a, 0xb0, 0xd2, 0x75, 0x1b, 0x71, 0x39,
- 0x7a, 0xd4, 0x98, 0x66, 0x4b, 0x57, 0x70, 0xac, 0xd1, 0x45, 0x09, 0x8c, 0x84, 0xb4, 0x73, 0xe7,
- 0xed, 0x5d, 0x9c, 0x5f, 0xa3, 0x84, 0xcf, 0x33, 0xea, 0xa9, 0xd9, 0x8c, 0xc1, 0xb0, 0xa0, 0x45,
- 0x35, 0xc0, 0x4d, 0x19, 0x11, 0x68, 0xcf, 0xc4, 0xac, 0x82, 0x0c, 0x53, 0x85, 0x4e, 0x81, 0x70,
- 0x4a, 0xd0, 0x7d, 0x0a, 0x26, 0xcd, 0xcd, 0x40, 0x35, 0x82, 0xcd, 0xdd, 0x84, 0x70, 0x7b, 0xc3,
- 0x38, 0xd7, 0x08, 0xe6, 0x29, 0x00, 0x73, 0xb8, 0xfb, 0x3d, 0x2a, 0x07, 0x28, 0xf6, 0x32, 0x80,
- 0x89, 0xff, 0x11, 0xdd, 0x58, 0xd6, 0x4f, 0xed, 0xfa, 0x18, 0x94, 0xd8, 0x3f, 0x6c, 0xa3, 0x0f,
- 0xd9, 0xf2, 0xdf, 0xa7, 0xfd, 0x14, 0x5b, 0x9d, 0xc9, 0x04, 0xcf, 0x4b, 0x42, 0x38, 0xa5, 0xe9,
- 0x86, 0x30, 0x95, 0xad, 0x8d, 0x3e, 0x08, 0xe3, 0xb1, 0x3c, 0x56, 0xd3, 0x2b, 0x74, 0x03, 0x1e,
- 0xbf, 0xdc, 0x7b, 0xa6, 0x35, 0xc7, 0x06, 0x32, 0x77, 0x0d, 0x46, 0xac, 0x4e, 0xa1, 0xfb, 0x2d,
- 0x07, 0x4a, 0xcc, 0x81, 0xd9, 0x88, 0xbc, 0x76, 0xda, 0x64, 0x68, 0x9f, 0x59, 0x8f, 0x61, 0x94,
- 0xeb, 0xe8, 0x32, 0xf0, 0xc7, 0x02, 0x97, 0xe1, 0xf9, 0xee, 0x52, 0x2e, 0xc3, 0x8d, 0x01, 0x31,
- 0x96, 0x94, 0xdc, 0x4f, 0x15, 0x60, 0xe4, 0x52, 0xd0, 0xe9, 0xfe, 0x95, 0xcf, 0xb9, 0xb6, 0x0a,
- 0xc3, 0x97, 0x12, 0xd2, 0x36, 0x53, 0x03, 0x8e, 0xcf, 0x3f, 0xaa, 0xa7, 0x05, 0xac, 0x98, 0x69,
- 0x01, 0xb1, 0x77, 0x5d, 0xc6, 0xc5, 0x09, 0x1b, 0x71, 0x7a, 0x8d, 0xf0, 0x49, 0x28, 0x5d, 0xf6,
- 0x36, 0x49, 0x6b, 0x85, 0xec, 0xb2, 0x4b, 0x7f, 0x3c, 0x46, 0xc3, 0x49, 0x15, 0x7b, 0x23, 0x9e,
- 0x62, 0x11, 0x26, 0x59, 0x6d, 0xb5, 0x19, 0xa8, 0xe6, 0x40, 0xd2, 0xbc, 0x4a, 0x8e, 0xa9, 0x39,
- 0x68, 0x39, 0x95, 0xb4, 0x5a, 0xee, 0x2c, 0x94, 0x53, 0x2c, 0x03, 0x50, 0xfd, 0x49, 0x01, 0x26,
- 0x0c, 0x53, 0xb7, 0xe1, 0x00, 0x74, 0x6e, 0xeb, 0x00, 0x34, 0x1c, 0x72, 0x85, 0x7b, 0xed, 0x90,
- 0x1b, 0x3a, 0x7a, 0x87, 0x9c, 0xf9, 0x91, 0x86, 0x07, 0xfa, 0x48, 0x2d, 0x18, 0xbe, 0xec, 0x07,
- 0xdb, 0x83, 0xf1, 0x99, 0xb8, 0x16, 0x76, 0x7a, 0xf8, 0x4c, 0x95, 0x02, 0x31, 0x2f, 0x93, 0x92,
- 0xcb, 0x50, 0xbe, 0xe4, 0xe2, 0x7e, 0xc2, 0x81, 0xf1, 0x55, 0x2f, 0xf0, 0xb7, 0x48, 0x9c, 0xb0,
- 0x75, 0x95, 0x1c, 0xea, 0xe5, 0xaf, 0xf1, 0x3e, 0x69, 0x0c, 0xde, 0x74, 0xe0, 0xf8, 0x2a, 0x69,
- 0x87, 0xfe, 0xab, 0x5e, 0x1a, 0x76, 0x4a, 0xfb, 0xde, 0xf4, 0x13, 0x11, 0x65, 0xa7, 0xfa, 0x7e,
- 0xd1, 0x4f, 0x30, 0x85, 0xdf, 0xc6, 0x8e, 0xcb, 0xae, 0x55, 0x50, 0x05, 0x4d, 0xbb, 0x90, 0x98,
- 0x06, 0x94, 0xca, 0x02, 0x9c, 0xd6, 0x71, 0x7f, 0xcf, 0x81, 0x51, 0xde, 0x09, 0x15, 0xa9, 0xeb,
- 0xf4, 0xc1, 0xdd, 0x84, 0x22, 0x6b, 0x27, 0x56, 0xf5, 0xb2, 0x05, 0xf1, 0x87, 0xa2, 0xe3, 0x7b,
- 0x90, 0xfd, 0x8b, 0x39, 0x01, 0xa6, 0xb6, 0x78, 0x37, 0xe6, 0x54, 0xc4, 0x6d, 0xaa, 0xb6, 0x30,
- 0x28, 0x16, 0xa5, 0xee, 0xd7, 0x86, 0x60, 0x4c, 0x65, 0xef, 0x62, 0xb9, 0x15, 0x82, 0x20, 0x4c,
- 0x3c, 0x1e, 0xeb, 0xc0, 0x79, 0xf5, 0x07, 0xed, 0x65, 0x0f, 0x9b, 0x9d, 0x4b, 0xb1, 0x73, 0xff,
- 0x9d, 0x52, 0x42, 0xb5, 0x12, 0xac, 0x77, 0x02, 0x7d, 0x14, 0x46, 0x5a, 0x94, 0xfb, 0x48, 0xd6,
- 0xfd, 0xbc, 0xc5, 0xee, 0x30, 0xb6, 0x26, 0x7a, 0xa2, 0x66, 0x88, 0x03, 0xb1, 0xa0, 0x3a, 0xfd,
- 0x3e, 0x98, 0xca, 0xf6, 0xfa, 0x76, 0xf7, 0x25, 0x4b, 0xfa, 0x6d, 0xcb, 0xbf, 0x29, 0xb8, 0xe7,
- 0xc1, 0x9b, 0xba, 0xcf, 0x41, 0x79, 0x95, 0x24, 0x91, 0x5f, 0x63, 0x08, 0x6e, 0xb7, 0xb8, 0x06,
- 0x92, 0x1f, 0x3e, 0xcd, 0x16, 0x2b, 0xc5, 0x19, 0xa3, 0xd7, 0x01, 0x3a, 0x51, 0x48, 0xf5, 0x57,
- 0xd2, 0x95, 0x1f, 0xdb, 0x82, 0x3c, 0xbc, 0xae, 0x70, 0x72, 0x97, 0x73, 0xfa, 0x1b, 0x6b, 0xf4,
- 0xdc, 0x17, 0xa1, 0xb8, 0xda, 0x4d, 0xc8, 0x8d, 0x01, 0x38, 0xd6, 0x41, 0x13, 0x08, 0xb8, 0x1f,
- 0x84, 0x71, 0x86, 0xfb, 0x62, 0xd8, 0xa2, 0xc7, 0x2a, 0x9d, 0x9a, 0x36, 0xfd, 0x9d, 0x75, 0x0a,
- 0xb0, 0x4a, 0x98, 0x97, 0xd1, 0x2d, 0xd3, 0x0c, 0x5b, 0x75, 0x75, 0x99, 0x4a, 0x2d, 0x88, 0x8b,
- 0x0c, 0x8a, 0x45, 0xa9, 0xfb, 0x4b, 0x05, 0x28, 0xb3, 0x86, 0x82, 0xdd, 0xec, 0xc2, 0x68, 0x93,
- 0xd3, 0x11, 0x73, 0x68, 0x21, 0x44, 0x4b, 0xef, 0xbd, 0xa6, 0xcb, 0x71, 0x00, 0x96, 0xf4, 0x28,
- 0xe9, 0xeb, 0x9e, 0x9f, 0x50, 0xd2, 0x85, 0xc3, 0x25, 0x7d, 0x8d, 0x93, 0xc1, 0x92, 0x9e, 0xfb,
- 0x8b, 0xc0, 0x2e, 0x29, 0x2f, 0xb5, 0xbc, 0x06, 0x9f, 0xb9, 0x70, 0x9b, 0xd4, 0x05, 0xcf, 0xd5,
- 0x66, 0x8e, 0x42, 0xb1, 0x28, 0xe5, 0x17, 0x3f, 0x93, 0xc8, 0x57, 0xc1, 0xcd, 0xda, 0xc5, 0x4f,
- 0x06, 0x96, 0xa1, 0xec, 0x75, 0xf7, 0x4b, 0x05, 0x00, 0x96, 0xeb, 0x8d, 0xdf, 0x2d, 0xfe, 0x79,
- 0x19, 0xa9, 0x64, 0x3a, 0x12, 0x55, 0xa4, 0x12, 0xbb, 0x3d, 0xad, 0x47, 0x28, 0xe9, 0x77, 0x0e,
- 0x0a, 0xfb, 0xdf, 0x39, 0x40, 0x1d, 0x18, 0x0d, 0xbb, 0x09, 0x95, 0x55, 0xc5, 0x61, 0x6f, 0xc1,
- 0x8f, 0xbe, 0xc6, 0x11, 0xf2, 0x40, 0x7d, 0xf1, 0x03, 0x4b, 0x32, 0xe8, 0x19, 0x18, 0xeb, 0x44,
- 0x61, 0x83, 0x9e, 0xdd, 0xe2, 0x78, 0x7f, 0x50, 0xca, 0x43, 0xeb, 0x02, 0x7e, 0x4b, 0xfb, 0x1f,
- 0xab, 0xda, 0xee, 0x1f, 0x4f, 0xf1, 0x79, 0x11, 0x6b, 0x6f, 0x1a, 0x0a, 0xbe, 0xb4, 0x4c, 0x81,
- 0x40, 0x51, 0xb8, 0xb4, 0x88, 0x0b, 0x7e, 0x5d, 0xed, 0xab, 0x42, 0xdf, 0x7d, 0xf5, 0x6e, 0x28,
- 0xd7, 0xfd, 0xb8, 0xd3, 0xf2, 0x76, 0xaf, 0xe4, 0x98, 0x05, 0x17, 0xd3, 0x22, 0xac, 0xd7, 0x43,
- 0x4f, 0x8a, 0x1b, 0x26, 0xc3, 0x86, 0x29, 0x48, 0xde, 0x30, 0x49, 0xef, 0xae, 0xf3, 0xcb, 0x25,
- 0xd9, 0x3b, 0xfe, 0xc5, 0x81, 0xef, 0xf8, 0x67, 0x25, 0xb1, 0x91, 0xa3, 0x97, 0xc4, 0xde, 0x0b,
- 0x13, 0xf2, 0x27, 0x13, 0x8f, 0x2a, 0x27, 0x59, 0xef, 0x95, 0xb9, 0x7a, 0x43, 0x2f, 0xc4, 0x66,
- 0xdd, 0x74, 0xd1, 0x8e, 0x0e, 0xba, 0x68, 0xcf, 0x03, 0x6c, 0x86, 0xdd, 0xa0, 0xee, 0x45, 0xbb,
- 0x97, 0x16, 0x45, 0x3c, 0xaa, 0x12, 0xfc, 0xe6, 0x55, 0x09, 0xd6, 0x6a, 0xe9, 0x0b, 0xbd, 0x74,
- 0x9b, 0x85, 0xfe, 0x41, 0x28, 0xb1, 0xd8, 0x5d, 0x52, 0x9f, 0x4b, 0x44, 0x88, 0xd1, 0x41, 0x42,
- 0x26, 0xd3, 0xa0, 0x43, 0x89, 0x04, 0xa7, 0xf8, 0xd0, 0x87, 0x00, 0xb6, 0xfc, 0xc0, 0x8f, 0x9b,
- 0x0c, 0x7b, 0xf9, 0xc0, 0xd8, 0xd5, 0x38, 0x97, 0x14, 0x16, 0xac, 0x61, 0x44, 0x2f, 0xc1, 0x71,
- 0x12, 0x27, 0x7e, 0xdb, 0x4b, 0x48, 0x5d, 0xdd, 0xc9, 0xac, 0x30, 0x5b, 0xa6, 0x8a, 0x9e, 0xbe,
- 0x90, 0xad, 0x70, 0x2b, 0x0f, 0x88, 0x7b, 0x11, 0x19, 0x3b, 0x72, 0xfa, 0x20, 0x3b, 0x12, 0xfd,
- 0xb9, 0x03, 0xc7, 0x23, 0xc2, 0xe3, 0x4e, 0x62, 0xd5, 0xb1, 0x53, 0x8c, 0x1d, 0xd7, 0x6c, 0xa4,
- 0x51, 0x57, 0xf9, 0x52, 0x70, 0x96, 0x0a, 0x17, 0x5c, 0x88, 0x1c, 0x7d, 0x4f, 0xf9, 0xad, 0x3c,
- 0xe0, 0x9b, 0x6f, 0xcf, 0xcc, 0xf4, 0xa6, 0xf3, 0x57, 0xc8, 0xe9, 0xce, 0xfb, 0xbb, 0x6f, 0xcf,
- 0x4c, 0xc9, 0xdf, 0xe9, 0xa4, 0xf5, 0x0c, 0x92, 0x1e, 0xab, 0x9d, 0xb0, 0x7e, 0x69, 0x5d, 0xc4,
- 0x82, 0xa9, 0x63, 0x75, 0x9d, 0x02, 0x31, 0x2f, 0x43, 0x8f, 0xc3, 0x58, 0xdd, 0x23, 0xed, 0x30,
- 0x50, 0x09, 0x71, 0x99, 0x34, 0xbf, 0x28, 0x60, 0x58, 0x95, 0x52, 0x1d, 0x22, 0x10, 0x47, 0x4a,
- 0xe5, 0x01, 0x5b, 0x3a, 0x84, 0x3c, 0xa4, 0x38, 0x55, 0xf9, 0x0b, 0x2b, 0x4a, 0xa8, 0x05, 0x23,
- 0x3e, 0x33, 0x54, 0x88, 0x70, 0x53, 0x0b, 0xd6, 0x11, 0x6e, 0xf8, 0x90, 0xc1, 0xa6, 0x8c, 0xf5,
- 0x0b, 0x1a, 0xfa, 0x59, 0x73, 0xec, 0x68, 0xce, 0x9a, 0xc7, 0x61, 0xac, 0xd6, 0xf4, 0x5b, 0xf5,
- 0x88, 0x04, 0x95, 0x29, 0xa6, 0xb1, 0xb3, 0x99, 0x58, 0x10, 0x30, 0xac, 0x4a, 0xd1, 0xdf, 0x80,
- 0x89, 0xb0, 0x9b, 0x30, 0xd6, 0x42, 0xe7, 0x29, 0xae, 0x1c, 0x67, 0xd5, 0x59, 0xf0, 0xd0, 0x9a,
- 0x5e, 0x80, 0xcd, 0x7a, 0x94, 0xc5, 0x37, 0xc3, 0x98, 0xa5, 0xf6, 0x61, 0x2c, 0xfe, 0xb4, 0xc9,
- 0xe2, 0x2f, 0x6a, 0x65, 0xd8, 0xa8, 0x89, 0xbe, 0xe2, 0xc0, 0xf1, 0x76, 0x56, 0x81, 0xab, 0x9c,
- 0x61, 0x33, 0x53, 0xb5, 0x21, 0xe8, 0x67, 0x50, 0xf3, 0xb0, 0xef, 0x1e, 0x30, 0xee, 0xed, 0x04,
- 0x4b, 0xb2, 0x15, 0xef, 0x06, 0xb5, 0x66, 0x14, 0x06, 0x66, 0xf7, 0xee, 0xb7, 0x75, 0xb5, 0x8c,
- 0xed, 0xed, 0x3c, 0x12, 0xf3, 0xf7, 0xdf, 0xdc, 0x9b, 0x39, 0x95, 0x5b, 0x84, 0xf3, 0x3b, 0x35,
- 0xbd, 0x08, 0xa7, 0xf3, 0xf9, 0xc3, 0xed, 0x34, 0x8e, 0x21, 0x5d, 0xe3, 0x58, 0x82, 0xfb, 0xfb,
- 0x76, 0x8a, 0x9e, 0x34, 0x52, 0xda, 0x74, 0xcc, 0x93, 0xa6, 0x47, 0x3a, 0x9c, 0x84, 0x71, 0xfd,
- 0xfd, 0x07, 0xf7, 0xff, 0x0e, 0x01, 0xa4, 0x76, 0x72, 0xe4, 0xc1, 0x24, 0xb7, 0xc9, 0x5f, 0x5a,
- 0xbc, 0xe3, 0x4b, 0xf1, 0x0b, 0x06, 0x02, 0x9c, 0x41, 0x88, 0xda, 0x80, 0x38, 0x84, 0xff, 0xbe,
- 0x13, 0xdf, 0x2a, 0x73, 0x45, 0x2e, 0xf4, 0x20, 0xc1, 0x39, 0x88, 0xe9, 0x88, 0x92, 0x70, 0x9b,
- 0x04, 0x57, 0xf1, 0xe5, 0x3b, 0xc9, 0xac, 0xc0, 0xbd, 0x71, 0x06, 0x02, 0x9c, 0x41, 0x88, 0x5c,
- 0x18, 0x61, 0xb6, 0x19, 0x19, 0xa0, 0xcd, 0xd8, 0x0b, 0x93, 0x34, 0x62, 0x2c, 0x4a, 0xd0, 0x97,
- 0x1c, 0x98, 0x94, 0x09, 0x22, 0x98, 0x35, 0x54, 0x86, 0x66, 0x5f, 0xb5, 0xe5, 0xe7, 0xb8, 0xa0,
- 0x63, 0x4f, 0x03, 0x1f, 0x0d, 0x70, 0x8c, 0x33, 0x9d, 0x70, 0x5f, 0x80, 0x13, 0x39, 0xcd, 0xad,
- 0x68, 0xb4, 0xdf, 0x76, 0xa0, 0xac, 0xe5, 0x2d, 0x44, 0xaf, 0x43, 0x29, 0xac, 0x5a, 0x8f, 0xb6,
- 0x5b, 0xab, 0xf6, 0x44, 0xdb, 0x29, 0x10, 0x4e, 0x09, 0x0e, 0x12, 0x24, 0x98, 0x9b, 0x64, 0xf1,
- 0x1e, 0x77, 0xfb, 0xc0, 0x41, 0x82, 0xbf, 0x52, 0x84, 0x14, 0xd3, 0x01, 0x13, 0x97, 0xa4, 0x21,
- 0x85, 0x85, 0x7d, 0x43, 0x0a, 0xeb, 0x70, 0xcc, 0x63, 0xbe, 0xe4, 0x3b, 0x4c, 0x57, 0xc2, 0xd3,
- 0xd6, 0x9a, 0x18, 0x70, 0x16, 0x25, 0xa5, 0x12, 0xa7, 0x4d, 0x19, 0x95, 0xe1, 0x03, 0x53, 0xa9,
- 0x9a, 0x18, 0x70, 0x16, 0x25, 0x7a, 0x09, 0x2a, 0x35, 0x76, 0xfd, 0x96, 0x8f, 0xf1, 0xd2, 0xd6,
- 0x95, 0x30, 0x59, 0x8f, 0x48, 0x4c, 0x82, 0x44, 0x24, 0x26, 0x7b, 0x58, 0xcc, 0x42, 0x65, 0xa1,
- 0x4f, 0x3d, 0xdc, 0x17, 0x03, 0x55, 0x53, 0x98, 0x33, 0xda, 0x4f, 0x76, 0x19, 0x13, 0x11, 0x5e,
- 0x7a, 0xa5, 0xa6, 0x54, 0xf5, 0x42, 0x6c, 0xd6, 0x45, 0xbf, 0xec, 0xc0, 0x44, 0x4b, 0x9a, 0xeb,
- 0x71, 0xb7, 0x25, 0xb3, 0x6c, 0x62, 0x2b, 0xcb, 0xef, 0xb2, 0x8e, 0x99, 0xcb, 0x12, 0x06, 0x08,
- 0x9b, 0xb4, 0xb3, 0xb9, 0x63, 0xc6, 0x06, 0xcc, 0x1d, 0xf3, 0x3d, 0x07, 0xa6, 0xb2, 0xd4, 0xd0,
- 0x36, 0x3c, 0xd4, 0xf6, 0xa2, 0xed, 0x4b, 0xc1, 0x56, 0xc4, 0x2e, 0x62, 0x24, 0x7c, 0x31, 0xcc,
- 0x6d, 0x25, 0x24, 0x5a, 0xf4, 0x76, 0xb9, 0xfb, 0xb3, 0xa8, 0x9e, 0x69, 0x7a, 0x68, 0x75, 0xbf,
- 0xca, 0x78, 0x7f, 0x5c, 0xa8, 0x0a, 0xa7, 0x68, 0x05, 0x96, 0x5a, 0xce, 0x0f, 0x83, 0x94, 0x48,
- 0x81, 0x11, 0x51, 0xc1, 0x80, 0xab, 0x79, 0x95, 0x70, 0x7e, 0x5b, 0xf7, 0x02, 0x8c, 0xf0, 0x7b,
- 0x71, 0x77, 0xe5, 0x3f, 0x72, 0xff, 0x7d, 0x01, 0xa4, 0x60, 0xf8, 0x57, 0xdb, 0x1d, 0x47, 0x0f,
- 0xd1, 0x88, 0x99, 0x94, 0x84, 0xb5, 0x83, 0x1d, 0xa2, 0x22, 0x89, 0xa3, 0x28, 0xa1, 0x12, 0x33,
- 0xb9, 0xe1, 0x27, 0x0b, 0x61, 0x5d, 0xda, 0x38, 0x98, 0xc4, 0x7c, 0x41, 0xc0, 0xb0, 0x2a, 0x75,
- 0x3f, 0xe1, 0xc0, 0x04, 0x1d, 0x65, 0xab, 0x45, 0x5a, 0xd5, 0x84, 0x74, 0x62, 0x14, 0x43, 0x31,
- 0xa6, 0xff, 0xd8, 0x33, 0x05, 0xa6, 0x77, 0x29, 0x49, 0x47, 0x73, 0xd6, 0x50, 0x22, 0x98, 0xd3,
- 0x72, 0xdf, 0x1a, 0x82, 0x92, 0x9a, 0xec, 0x01, 0xec, 0xa9, 0xe7, 0xd3, 0xfc, 0xaa, 0x9c, 0x03,
- 0x57, 0xb4, 0xdc, 0xaa, 0xb7, 0xe8, 0xd4, 0x05, 0xbb, 0x3c, 0xd1, 0x44, 0x9a, 0x68, 0xf5, 0x49,
- 0xd3, 0xd5, 0x7c, 0x5a, 0x5f, 0x7f, 0x5a, 0x7d, 0xe1, 0x73, 0xbe, 0xa1, 0x7b, 0xfa, 0x87, 0x6d,
- 0x9d, 0x66, 0xca, 0x8d, 0xd9, 0xdf, 0xc5, 0x9f, 0x79, 0x7a, 0xa7, 0x38, 0xd0, 0xd3, 0x3b, 0x4f,
- 0xc0, 0x30, 0x09, 0xba, 0x6d, 0x26, 0x2a, 0x95, 0x98, 0x8a, 0x30, 0x7c, 0x21, 0xe8, 0xb6, 0xcd,
- 0x91, 0xb1, 0x2a, 0xe8, 0x7d, 0x50, 0xae, 0x93, 0xb8, 0x16, 0xf9, 0x2c, 0x7b, 0x82, 0xb0, 0xec,
- 0x3c, 0xc8, 0xcc, 0x65, 0x29, 0xd8, 0x6c, 0xa8, 0x37, 0x70, 0x5f, 0x85, 0x91, 0xf5, 0x56, 0xb7,
- 0xe1, 0x07, 0xa8, 0x03, 0x23, 0x3c, 0x97, 0x82, 0x38, 0xed, 0x2d, 0xe8, 0x9d, 0x9c, 0x55, 0x68,
- 0x51, 0x28, 0xfc, 0x4a, 0xad, 0xa0, 0xe3, 0xfe, 0x76, 0x01, 0xa8, 0x6a, 0xbe, 0xbc, 0x80, 0xfe,
- 0x76, 0xcf, 0x4b, 0x33, 0x3f, 0x93, 0xf3, 0xd2, 0xcc, 0x04, 0xab, 0x9c, 0xf3, 0xc8, 0x4c, 0x0b,
- 0x26, 0x98, 0x73, 0x44, 0x9e, 0x81, 0x42, 0xac, 0x7e, 0x7a, 0xc0, 0xf4, 0x03, 0x7a, 0x53, 0x71,
- 0x22, 0xe8, 0x20, 0x6c, 0x22, 0x47, 0xbb, 0x70, 0x82, 0xa7, 0xe9, 0x5c, 0x24, 0x2d, 0x6f, 0xd7,
- 0x48, 0xc7, 0x35, 0x70, 0xca, 0x03, 0xd9, 0x8a, 0x07, 0x78, 0x2f, 0xf6, 0xa2, 0xc3, 0x79, 0x34,
- 0xdc, 0xdf, 0x1f, 0x06, 0xcd, 0x7d, 0x31, 0xc0, 0xce, 0x7a, 0x25, 0xe3, 0xac, 0x5a, 0xb5, 0xe2,
- 0xac, 0x92, 0x1e, 0x20, 0xce, 0xad, 0x4c, 0xff, 0x14, 0xed, 0x54, 0x93, 0xb4, 0x3a, 0x62, 0x5f,
- 0xaa, 0x4e, 0x5d, 0x24, 0xad, 0x0e, 0x66, 0x25, 0xea, 0xf2, 0xe1, 0x70, 0xdf, 0xcb, 0x87, 0x4d,
- 0x28, 0x36, 0xbc, 0x6e, 0x83, 0x88, 0x68, 0x4d, 0x0b, 0x7e, 0x49, 0x76, 0x1d, 0x82, 0xfb, 0x25,
- 0xd9, 0xbf, 0x98, 0x13, 0xa0, 0x8c, 0xa1, 0x29, 0xc3, 0x57, 0x84, 0x41, 0xd7, 0x02, 0x63, 0x50,
- 0x11, 0x31, 0x9c, 0x31, 0xa8, 0x9f, 0x38, 0x25, 0x86, 0x3a, 0x30, 0x5a, 0xe3, 0x09, 0x53, 0x84,
- 0x7c, 0x73, 0xc9, 0xc6, 0xed, 0x4a, 0x86, 0x90, 0x5b, 0x5e, 0xc4, 0x0f, 0x2c, 0xc9, 0xb8, 0xe7,
- 0xa0, 0xac, 0x3d, 0x8e, 0x41, 0x3f, 0x83, 0xca, 0xd5, 0xa1, 0x7d, 0x86, 0x45, 0x2f, 0xf1, 0x30,
- 0x2b, 0x71, 0xbf, 0x31, 0x0c, 0xca, 0xee, 0xa6, 0xdf, 0x05, 0xf4, 0x6a, 0x5a, 0x66, 0x21, 0xe3,
- 0x5e, 0x7c, 0x18, 0x60, 0x51, 0x4a, 0x65, 0xc0, 0x36, 0x89, 0x1a, 0x4a, 0xe7, 0x16, 0xac, 0x5d,
- 0xc9, 0x80, 0xab, 0x7a, 0x21, 0x36, 0xeb, 0x52, 0x01, 0xbe, 0x2d, 0xdc, 0xf9, 0xd9, 0x60, 0x69,
- 0xe9, 0xe6, 0xc7, 0xaa, 0x06, 0x4b, 0x4d, 0xd0, 0xd6, 0xbc, 0xff, 0x22, 0x68, 0xd3, 0x86, 0xf3,
- 0x49, 0xc3, 0xca, 0x83, 0xab, 0x74, 0x08, 0x36, 0xa8, 0xa2, 0x65, 0x38, 0x1e, 0x93, 0x64, 0xed,
- 0x7a, 0x40, 0x22, 0x95, 0x36, 0x40, 0xe4, 0xbe, 0x50, 0x37, 0x25, 0xaa, 0xd9, 0x0a, 0xb8, 0xb7,
- 0x4d, 0x6e, 0x9c, 0x6b, 0xf1, 0xc0, 0x71, 0xae, 0x8b, 0x30, 0xb5, 0xe5, 0xf9, 0xad, 0x6e, 0x44,
- 0xfa, 0x46, 0xcb, 0x2e, 0x65, 0xca, 0x71, 0x4f, 0x0b, 0x76, 0x59, 0xa7, 0xe5, 0x35, 0xe2, 0xca,
- 0xa8, 0x76, 0x59, 0x87, 0x02, 0x30, 0x87, 0xbb, 0xbf, 0xe9, 0x00, 0x4f, 0x3a, 0x34, 0xb7, 0xb5,
- 0xe5, 0x07, 0x7e, 0xb2, 0x8b, 0xbe, 0xea, 0xc0, 0x54, 0x10, 0xd6, 0xc9, 0x5c, 0x90, 0xf8, 0x12,
- 0x68, 0x2f, 0x13, 0x3c, 0xa3, 0x75, 0x25, 0x83, 0x9e, 0x67, 0xb0, 0xc8, 0x42, 0x71, 0x4f, 0x37,
- 0xdc, 0x33, 0x70, 0x2a, 0x17, 0x81, 0xfb, 0xbd, 0x21, 0x30, 0x73, 0x27, 0xa1, 0xe7, 0xa0, 0xd8,
- 0x62, 0xd9, 0x3c, 0x9c, 0x3b, 0x4c, 0x8a, 0xc5, 0xe6, 0x8a, 0xa7, 0xfb, 0xe0, 0x98, 0xd0, 0x22,
- 0x94, 0x59, 0x42, 0x26, 0x91, 0x6b, 0xa5, 0x60, 0xa4, 0x39, 0x28, 0xe3, 0xb4, 0xe8, 0x96, 0xf9,
- 0x13, 0xeb, 0xcd, 0xd0, 0x6b, 0x30, 0xba, 0xc9, 0xd3, 0x52, 0xda, 0xf3, 0x0f, 0x8a, 0x3c, 0x97,
- 0x4c, 0x8e, 0x92, 0x49, 0x2f, 0x6f, 0xa5, 0xff, 0x62, 0x49, 0x11, 0xed, 0xc2, 0x98, 0x27, 0xbf,
- 0xe9, 0xb0, 0xad, 0xcb, 0x17, 0xc6, 0xfa, 0x11, 0xd1, 0x35, 0xf2, 0x1b, 0x2a, 0x72, 0x99, 0x30,
- 0xa4, 0xe2, 0x40, 0x61, 0x48, 0xdf, 0x72, 0x00, 0xd2, 0x37, 0x3c, 0xd0, 0x0d, 0x18, 0x8b, 0x9f,
- 0x36, 0x8c, 0x1a, 0x36, 0x6e, 0xdd, 0x0b, 0x8c, 0xda, 0xcd, 0x54, 0x01, 0xc1, 0x8a, 0xda, 0xed,
- 0x0c, 0x31, 0x3f, 0x71, 0xe0, 0x64, 0xde, 0x5b, 0x23, 0xf7, 0xb0, 0xc7, 0x07, 0xb5, 0xc1, 0x88,
- 0x06, 0xeb, 0x11, 0xd9, 0xf2, 0x6f, 0xe4, 0x24, 0x47, 0xe6, 0x05, 0x38, 0xad, 0xe3, 0xbe, 0x39,
- 0x0a, 0x8a, 0xf0, 0x21, 0xd9, 0x6c, 0x1e, 0xa3, 0xfa, 0x55, 0x23, 0xbd, 0x2c, 0xa9, 0xea, 0x61,
- 0x06, 0xc5, 0xa2, 0x94, 0xea, 0x58, 0x32, 0x80, 0x5e, 0xb0, 0x6c, 0xb6, 0x0a, 0x65, 0xa0, 0x3d,
- 0x56, 0xa5, 0x79, 0x56, 0xa0, 0xe2, 0x91, 0x58, 0x81, 0x46, 0xec, 0x5b, 0x81, 0x9e, 0x80, 0xd1,
- 0x28, 0x6c, 0x91, 0x39, 0x7c, 0x45, 0x68, 0x0e, 0x69, 0x00, 0x04, 0x07, 0x63, 0x59, 0x7e, 0x87,
- 0x76, 0x10, 0xf4, 0x3b, 0xce, 0x3e, 0x86, 0xa6, 0x92, 0xad, 0x33, 0x21, 0x37, 0x93, 0x1c, 0x53,
- 0x83, 0xee, 0xc4, 0x7a, 0xf5, 0x35, 0x07, 0x8e, 0x93, 0xa0, 0x16, 0xed, 0x32, 0x3c, 0x02, 0x9b,
- 0xf0, 0x4f, 0x5f, 0xb5, 0xb1, 0xf9, 0x2e, 0x64, 0x91, 0x73, 0x37, 0x50, 0x0f, 0x18, 0xf7, 0x76,
- 0x03, 0xad, 0xc1, 0x58, 0xcd, 0x13, 0x2b, 0xa2, 0x7c, 0x90, 0x15, 0xc1, 0xbd, 0x6c, 0x73, 0x62,
- 0x29, 0x28, 0x24, 0xee, 0x8f, 0x0a, 0x70, 0x22, 0xa7, 0x4b, 0xec, 0xb2, 0x55, 0x9b, 0xae, 0xc8,
- 0x4b, 0xf5, 0xec, 0x7e, 0x5c, 0x11, 0x70, 0xac, 0x6a, 0xa0, 0x75, 0x38, 0xb9, 0xdd, 0x8e, 0x53,
- 0x2c, 0x0b, 0x61, 0x90, 0x90, 0x1b, 0x72, 0x77, 0x4a, 0xdf, 0xf5, 0xc9, 0x95, 0x9c, 0x3a, 0x38,
- 0xb7, 0x25, 0x15, 0x5f, 0x48, 0xe0, 0x6d, 0xb6, 0x48, 0x5a, 0x24, 0xae, 0x0a, 0x2a, 0xf1, 0xe5,
- 0x42, 0xa6, 0x1c, 0xf7, 0xb4, 0x40, 0x9f, 0x71, 0xe0, 0x81, 0x98, 0x44, 0x3b, 0x24, 0xaa, 0xfa,
- 0x75, 0xb2, 0xd0, 0x8d, 0x93, 0xb0, 0x4d, 0xa2, 0x3b, 0x34, 0xad, 0xce, 0xdc, 0xdc, 0x9b, 0x79,
- 0xa0, 0xda, 0x1f, 0x1b, 0xde, 0x8f, 0x94, 0xfb, 0x19, 0x07, 0x26, 0xab, 0x4c, 0xf1, 0x56, 0xb2,
- 0xb4, 0xed, 0x5c, 0xa2, 0x8f, 0xa9, 0xe4, 0x16, 0x19, 0xae, 0x68, 0xa6, 0xa3, 0x70, 0x5f, 0x86,
- 0xa9, 0x2a, 0x69, 0x7b, 0x9d, 0x26, 0xbb, 0xe7, 0xcb, 0x63, 0xb7, 0xce, 0x41, 0x29, 0x96, 0xb0,
- 0xec, 0xf3, 0x41, 0xaa, 0x32, 0x4e, 0xeb, 0xa0, 0x47, 0x79, 0x9c, 0x99, 0xbc, 0x2d, 0x54, 0xe2,
- 0x5a, 0x07, 0x0f, 0x4e, 0x8b, 0xb1, 0x2c, 0x73, 0xdf, 0x72, 0x60, 0x3c, 0x6d, 0x4f, 0xb6, 0x50,
- 0x03, 0x8e, 0xd5, 0xb4, 0x9b, 0x76, 0xe9, 0x1d, 0x87, 0xc1, 0x2f, 0xe5, 0xf1, 0x14, 0xc7, 0x26,
- 0x12, 0x9c, 0xc5, 0x7a, 0xf0, 0x30, 0xbd, 0xcf, 0x17, 0xe0, 0x98, 0xea, 0xaa, 0x70, 0x32, 0xbe,
- 0x91, 0x8d, 0xa6, 0xc3, 0x36, 0xd2, 0xf4, 0x98, 0x73, 0xbf, 0x4f, 0x44, 0xdd, 0x1b, 0xd9, 0x88,
- 0xba, 0x43, 0x25, 0xdf, 0xe3, 0x37, 0xfd, 0x56, 0x01, 0xc6, 0x54, 0xd2, 0xa0, 0xe7, 0xa0, 0xc8,
- 0x54, 0xc9, 0xbb, 0x13, 0x88, 0x99, 0x5a, 0x8a, 0x39, 0x26, 0x8a, 0x92, 0x45, 0xec, 0xdc, 0x71,
- 0xe2, 0xd9, 0x12, 0x37, 0x3e, 0x7a, 0x51, 0x82, 0x39, 0x26, 0xb4, 0x02, 0x43, 0x24, 0xa8, 0x0b,
- 0xc9, 0xf8, 0xe0, 0x08, 0xd9, 0x43, 0x5f, 0x17, 0x82, 0x3a, 0xa6, 0x58, 0x58, 0xe6, 0x32, 0x2e,
- 0x00, 0x65, 0x9e, 0x75, 0x11, 0xd2, 0x8f, 0x28, 0x75, 0xdf, 0x0f, 0x46, 0xce, 0x3a, 0x91, 0x0b,
- 0x5f, 0x28, 0x5d, 0xbd, 0x6f, 0x71, 0x09, 0x6d, 0x2b, 0xad, 0xe3, 0xfe, 0xf2, 0x10, 0x8c, 0x54,
- 0xbb, 0x9b, 0x54, 0x49, 0xf8, 0xa6, 0x03, 0x27, 0xae, 0x67, 0xd2, 0x3a, 0xa7, 0x9b, 0xe4, 0xaa,
- 0x3d, 0x0b, 0xae, 0x1e, 0x76, 0xf6, 0x80, 0x7c, 0xf4, 0x3e, 0xa7, 0x10, 0xe7, 0x75, 0xc7, 0xc8,
- 0xac, 0x3a, 0x74, 0x28, 0x99, 0x55, 0x6f, 0x1c, 0xf2, 0xbd, 0x8b, 0x89, 0x7e, 0x77, 0x2e, 0xdc,
- 0xdf, 0x2f, 0x02, 0xf0, 0xaf, 0xb1, 0xd6, 0x49, 0x06, 0xb1, 0xb3, 0x3d, 0x03, 0xe3, 0x0d, 0x12,
- 0x90, 0x48, 0x06, 0x15, 0x66, 0x9e, 0x1c, 0x5a, 0xd6, 0xca, 0xb0, 0x51, 0x93, 0x29, 0x35, 0x41,
- 0x12, 0xed, 0x72, 0xc1, 0x37, 0x7b, 0xb7, 0x42, 0x95, 0x60, 0xad, 0x16, 0x9a, 0x35, 0x5c, 0x26,
- 0xdc, 0xfb, 0x3e, 0xb9, 0x8f, 0x87, 0xe3, 0x7d, 0x30, 0x69, 0x26, 0x2a, 0x11, 0xd2, 0x9e, 0xf2,
- 0x96, 0x9b, 0xf9, 0x4d, 0x70, 0xa6, 0x36, 0xdd, 0x05, 0xf5, 0x68, 0x17, 0x77, 0x03, 0x21, 0xf6,
- 0xa9, 0x5d, 0xb0, 0xc8, 0xa0, 0x58, 0x94, 0xb2, 0x0c, 0x0f, 0xec, 0x00, 0xe4, 0x70, 0x91, 0x25,
- 0x22, 0xcd, 0xf0, 0xa0, 0x95, 0x61, 0xa3, 0x26, 0xa5, 0x20, 0xec, 0x94, 0x60, 0xee, 0xb3, 0x8c,
- 0x71, 0xb1, 0x03, 0x93, 0xa1, 0x69, 0x5f, 0xe1, 0x32, 0xd0, 0xbb, 0x06, 0x5c, 0x7a, 0x46, 0x5b,
- 0x1e, 0xe5, 0x90, 0x31, 0xc7, 0x64, 0xf0, 0x53, 0xb9, 0x57, 0xbf, 0x82, 0x30, 0x6e, 0xc6, 0xa4,
- 0xf6, 0xbd, 0x25, 0xb0, 0x0e, 0x27, 0x3b, 0x61, 0x7d, 0x3d, 0xf2, 0xc3, 0xc8, 0x4f, 0x76, 0x17,
- 0x5a, 0x5e, 0x1c, 0xb3, 0x85, 0x31, 0x61, 0xca, 0x43, 0xeb, 0x39, 0x75, 0x70, 0x6e, 0x4b, 0xaa,
- 0xa1, 0x74, 0x04, 0x90, 0x45, 0x86, 0x15, 0xb9, 0x44, 0x27, 0x2b, 0x62, 0x55, 0xea, 0x9e, 0x80,
- 0xe3, 0xd5, 0x6e, 0xa7, 0xd3, 0xf2, 0x49, 0x5d, 0xb9, 0x24, 0xdc, 0xf7, 0xc3, 0x31, 0x91, 0x77,
- 0x55, 0x49, 0x1f, 0x07, 0xca, 0x12, 0xee, 0xfe, 0xb9, 0x03, 0xc7, 0x32, 0x71, 0x38, 0xe8, 0xb5,
- 0xac, 0xcc, 0x60, 0x27, 0x1f, 0xa8, 0x26, 0x2d, 0x88, 0xe4, 0x9e, 0x79, 0xf2, 0x47, 0x53, 0x06,
- 0xd1, 0x5b, 0xbb, 0xbc, 0xc2, 0x42, 0xcd, 0xf9, 0x91, 0xa2, 0x47, 0xe2, 0xbb, 0x9f, 0x2e, 0x40,
- 0x7e, 0xf0, 0x13, 0xfa, 0x68, 0xef, 0x04, 0x3c, 0x67, 0x71, 0x02, 0x44, 0xf4, 0x55, 0xff, 0x39,
- 0x08, 0xcc, 0x39, 0x58, 0xb5, 0x34, 0x07, 0x82, 0x6e, 0xef, 0x4c, 0xfc, 0x2f, 0x07, 0xca, 0x1b,
- 0x1b, 0x97, 0xd5, 0x39, 0x87, 0xe1, 0x74, 0xcc, 0x2f, 0xe7, 0x33, 0x1f, 0xf1, 0x42, 0xd8, 0xee,
- 0x70, 0x97, 0xb1, 0x70, 0x65, 0xb3, 0x14, 0xb8, 0xd5, 0xdc, 0x1a, 0xb8, 0x4f, 0x4b, 0x74, 0x09,
- 0x4e, 0xe8, 0x25, 0x55, 0xed, 0xc5, 0xc1, 0xa2, 0x48, 0x88, 0xd3, 0x5b, 0x8c, 0xf3, 0xda, 0x64,
- 0x51, 0x09, 0x73, 0x27, 0x3b, 0xae, 0x72, 0x50, 0x89, 0x62, 0x9c, 0xd7, 0xc6, 0x5d, 0x83, 0xf2,
- 0x86, 0x17, 0xa9, 0x81, 0x7f, 0x00, 0xa6, 0x6a, 0x61, 0x5b, 0x9a, 0x99, 0x2e, 0x93, 0x1d, 0xd2,
- 0x12, 0x43, 0xe6, 0xcf, 0x7c, 0x64, 0xca, 0x70, 0x4f, 0x6d, 0xf7, 0xbf, 0x9f, 0x05, 0x75, 0xd9,
- 0x70, 0x80, 0x13, 0xa6, 0xa3, 0xc2, 0x42, 0x8b, 0x96, 0xc3, 0x42, 0x15, 0xaf, 0xcd, 0x84, 0x86,
- 0x26, 0x69, 0x68, 0xe8, 0x88, 0xed, 0xd0, 0x50, 0x25, 0x71, 0xf6, 0x84, 0x87, 0x7e, 0xd9, 0x81,
- 0xf1, 0x20, 0xac, 0x13, 0xe5, 0xcb, 0x1b, 0x65, 0x62, 0xef, 0x4b, 0xf6, 0xa2, 0xec, 0x79, 0x98,
- 0xa3, 0x40, 0xcf, 0x43, 0x96, 0xd5, 0x11, 0xa5, 0x17, 0x61, 0xa3, 0x1f, 0x68, 0x49, 0x33, 0x7c,
- 0x72, 0xff, 0xc2, 0x83, 0x79, 0xfa, 0xca, 0x6d, 0xad, 0x98, 0x37, 0x34, 0xb9, 0xa9, 0x64, 0xcb,
- 0xa0, 0x27, 0x6f, 0x90, 0x69, 0x6e, 0x12, 0x99, 0xc5, 0x39, 0x95, 0xa7, 0x5c, 0x18, 0xe1, 0xb1,
- 0xcd, 0x22, 0xf5, 0x12, 0xf3, 0xde, 0xf1, 0xb8, 0x67, 0x2c, 0x4a, 0x50, 0x22, 0xe3, 0x05, 0xca,
- 0xb6, 0xde, 0x64, 0x30, 0xe2, 0x11, 0xf2, 0x03, 0x06, 0xd0, 0xb3, 0xba, 0x1e, 0x3c, 0x3e, 0x88,
- 0x1e, 0x3c, 0xd1, 0x57, 0x07, 0xfe, 0x9c, 0x03, 0xe3, 0x35, 0xed, 0x8d, 0x84, 0xca, 0xe3, 0xb6,
- 0xde, 0x82, 0xce, 0x7b, 0xca, 0x82, 0x3b, 0x85, 0x8c, 0x37, 0x19, 0x0c, 0xea, 0x2c, 0xdf, 0x24,
- 0x53, 0xfa, 0xd9, 0xd1, 0x6f, 0x25, 0xc5, 0x84, 0x69, 0x44, 0x90, 0x71, 0x97, 0x14, 0x86, 0x05,
- 0x2d, 0xf4, 0x3a, 0x8c, 0xc9, 0xf0, 0x78, 0x11, 0x46, 0x8e, 0x6d, 0x58, 0xe9, 0x4d, 0x57, 0xa0,
- 0x4c, 0x52, 0xc7, 0xa1, 0x58, 0x51, 0x44, 0x4d, 0x18, 0xaa, 0x7b, 0x0d, 0x11, 0x50, 0xbe, 0x6a,
- 0x27, 0x09, 0xa8, 0xa4, 0xc9, 0xf4, 0xb3, 0xc5, 0xb9, 0x65, 0x4c, 0x49, 0xa0, 0x1b, 0x69, 0x92,
- 0xf9, 0x29, 0x6b, 0xa7, 0xaf, 0x29, 0x26, 0x71, 0xb3, 0x46, 0x4f, 0xce, 0xfa, 0xba, 0xf0, 0x9e,
- 0xfe, 0x35, 0x46, 0x76, 0xc9, 0x4e, 0x16, 0x51, 0x9e, 0xb2, 0x24, 0xf5, 0xc0, 0x52, 0x2a, 0xcd,
- 0x24, 0xe9, 0x54, 0x7e, 0xd6, 0x16, 0x15, 0x96, 0x78, 0x83, 0x3f, 0xdb, 0xbd, 0xb1, 0xb1, 0x8e,
- 0x19, 0x76, 0xd4, 0x82, 0x91, 0x0e, 0x0b, 0x02, 0xa9, 0xfc, 0x9c, 0xad, 0xb3, 0x85, 0x07, 0x95,
- 0xf0, 0xb5, 0xc9, 0xff, 0xc7, 0x82, 0x06, 0xba, 0x00, 0xa3, 0xfc, 0xad, 0x14, 0x1e, 0xd0, 0x5f,
- 0x3e, 0x3f, 0xdd, 0xff, 0xc5, 0x95, 0xf4, 0xa0, 0xe0, 0xbf, 0x63, 0x2c, 0xdb, 0xa2, 0xcf, 0x3b,
- 0x30, 0x49, 0x39, 0x6a, 0xfa, 0xb8, 0x4b, 0x05, 0xd9, 0xe2, 0x59, 0x57, 0x63, 0x2a, 0x91, 0x48,
- 0x5e, 0xa3, 0xd4, 0xa4, 0x4b, 0x06, 0x39, 0x9c, 0x21, 0x8f, 0xde, 0x80, 0xb1, 0xd8, 0xaf, 0x93,
- 0x9a, 0x17, 0xc5, 0x95, 0x13, 0x87, 0xd3, 0x95, 0xd4, 0x5f, 0x23, 0x08, 0x61, 0x45, 0x12, 0xfd,
- 0x1a, 0x7b, 0x5d, 0x53, 0xbc, 0x84, 0x5f, 0xe3, 0x62, 0xfd, 0x49, 0x5b, 0x7b, 0x5f, 0x7a, 0xa6,
- 0x24, 0x66, 0xe1, 0xc6, 0x30, 0xc9, 0xe1, 0x2c, 0x7d, 0xf4, 0x77, 0x1c, 0x38, 0xc5, 0xf3, 0xe4,
- 0x67, 0x1f, 0x76, 0x38, 0x75, 0x87, 0xf6, 0x19, 0x76, 0x13, 0x61, 0x2e, 0x0f, 0x25, 0xce, 0xa7,
- 0xc4, 0xb2, 0xda, 0x9a, 0x6f, 0xf1, 0x9c, 0xb6, 0xea, 0xb7, 0x1c, 0xfc, 0xfd, 0x1d, 0xf4, 0x14,
- 0x94, 0x3b, 0xe2, 0x38, 0xf4, 0xe3, 0x36, 0xbb, 0x57, 0x32, 0xc4, 0x6f, 0xfc, 0xad, 0xa7, 0x60,
- 0xac, 0xd7, 0x31, 0x52, 0x1c, 0x3f, 0xb1, 0x5f, 0x8a, 0x63, 0x74, 0x15, 0xca, 0x49, 0xd8, 0x12,
- 0x59, 0x3e, 0xe3, 0x4a, 0x85, 0xad, 0xc0, 0xb3, 0x79, 0x7b, 0x6b, 0x43, 0x55, 0x4b, 0x35, 0xd9,
- 0x14, 0x16, 0x63, 0x1d, 0x0f, 0x8b, 0xe5, 0x15, 0xef, 0x0f, 0x44, 0x4c, 0x85, 0xbd, 0x3f, 0x13,
- 0xcb, 0xab, 0x17, 0x62, 0xb3, 0x2e, 0x5a, 0x86, 0xe3, 0x9d, 0x1e, 0x1d, 0x98, 0xdf, 0x67, 0x53,
- 0x21, 0x11, 0xbd, 0x0a, 0x70, 0x6f, 0x1b, 0x43, 0xfb, 0x7d, 0x60, 0x3f, 0xed, 0xb7, 0x4f, 0xc2,
- 0xdf, 0x07, 0xef, 0x24, 0xe1, 0x2f, 0xaa, 0xc3, 0x83, 0x5e, 0x37, 0x09, 0x59, 0x72, 0x19, 0xb3,
- 0x09, 0x0f, 0x6b, 0x7e, 0x98, 0x47, 0x4a, 0xdf, 0xdc, 0x9b, 0x79, 0x70, 0x6e, 0x9f, 0x7a, 0x78,
- 0x5f, 0x2c, 0xe8, 0x55, 0x18, 0x23, 0x22, 0x69, 0x71, 0xe5, 0x67, 0x6c, 0x09, 0x09, 0x66, 0x1a,
- 0x64, 0x19, 0x31, 0xca, 0x61, 0x58, 0xd1, 0x43, 0x1b, 0x50, 0x6e, 0x86, 0x71, 0x32, 0xd7, 0xf2,
- 0xbd, 0x98, 0xc4, 0x95, 0x87, 0xd8, 0xa2, 0xc9, 0x95, 0xbd, 0x2e, 0xca, 0x6a, 0xe9, 0x9a, 0xb9,
- 0x98, 0xb6, 0xc4, 0x3a, 0x1a, 0x44, 0x98, 0xf7, 0x92, 0xc5, 0x74, 0x4b, 0x47, 0xd0, 0x59, 0x36,
- 0xb0, 0xc7, 0xf2, 0x30, 0xaf, 0x87, 0xf5, 0xaa, 0x59, 0x5b, 0xb9, 0x2f, 0x75, 0x20, 0xce, 0xe2,
- 0x44, 0xcf, 0xc0, 0x78, 0x27, 0xac, 0x57, 0x3b, 0xa4, 0xb6, 0xee, 0x25, 0xb5, 0x66, 0x65, 0xc6,
- 0xb4, 0xba, 0xad, 0x6b, 0x65, 0xd8, 0xa8, 0x89, 0x3a, 0x30, 0xda, 0xe6, 0x59, 0x07, 0x2a, 0x8f,
- 0xd8, 0xd2, 0x6d, 0x44, 0x1a, 0x03, 0x2e, 0x2f, 0x88, 0x1f, 0x58, 0x92, 0x41, 0xff, 0xd8, 0x81,
- 0x63, 0x99, 0x9b, 0x52, 0x95, 0x77, 0x58, 0x13, 0x59, 0x4c, 0xc4, 0xf3, 0x8f, 0xb1, 0xe9, 0x33,
- 0x81, 0xb7, 0x7a, 0x41, 0x38, 0xdb, 0x23, 0x3e, 0x2f, 0x2c, 0x75, 0x48, 0xe5, 0x51, 0x7b, 0xf3,
- 0xc2, 0x10, 0xca, 0x79, 0x61, 0x3f, 0xb0, 0x24, 0x83, 0x9e, 0x80, 0x51, 0x91, 0xe5, 0xaf, 0xf2,
- 0x98, 0xe9, 0x82, 0x16, 0xc9, 0x00, 0xb1, 0x2c, 0x9f, 0x7e, 0x3f, 0x1c, 0xef, 0x51, 0xdd, 0x0e,
- 0x94, 0xbf, 0xe2, 0x37, 0x1c, 0xd0, 0xaf, 0x56, 0x5b, 0x7f, 0x29, 0xe4, 0x19, 0x18, 0xaf, 0xf1,
- 0x67, 0x19, 0xf9, 0xe5, 0xec, 0x61, 0xd3, 0xfe, 0xb9, 0xa0, 0x95, 0x61, 0xa3, 0xa6, 0x7b, 0x11,
- 0x50, 0x6f, 0x1a, 0xf7, 0x3b, 0x4a, 0x8e, 0xf4, 0x4f, 0x1d, 0x98, 0x30, 0x64, 0x06, 0xeb, 0x4e,
- 0xc6, 0x25, 0x40, 0x6d, 0x3f, 0x8a, 0xc2, 0x48, 0x7f, 0xff, 0x4e, 0x24, 0x50, 0x60, 0x57, 0xd4,
- 0x56, 0x7b, 0x4a, 0x71, 0x4e, 0x0b, 0xf7, 0xb7, 0x87, 0x21, 0x0d, 0x99, 0x56, 0x79, 0x72, 0x9d,
- 0xbe, 0x79, 0x72, 0x9f, 0x84, 0xb1, 0x97, 0xe3, 0x30, 0x58, 0x4f, 0xb3, 0xe9, 0xaa, 0x6f, 0xf1,
- 0x6c, 0x75, 0xed, 0x0a, 0xab, 0xa9, 0x6a, 0xb0, 0xda, 0xaf, 0x2c, 0xf9, 0xad, 0xa4, 0x37, 0xdd,
- 0xea, 0xb3, 0xcf, 0x71, 0x38, 0x56, 0x35, 0xd8, 0x53, 0x78, 0x3b, 0x44, 0x19, 0xc6, 0xd3, 0xa7,
- 0xf0, 0xf8, 0x0b, 0x0d, 0xac, 0x0c, 0x9d, 0x83, 0x92, 0x32, 0xaa, 0x0b, 0x4b, 0xbd, 0x9a, 0x29,
- 0x65, 0x79, 0xc7, 0x69, 0x1d, 0x26, 0x10, 0x0a, 0x43, 0xac, 0x30, 0xa1, 0x54, 0x6d, 0xa8, 0x27,
- 0x19, 0xd3, 0x2e, 0xe7, 0xed, 0x12, 0x8c, 0x15, 0xc9, 0x3c, 0x47, 0x6b, 0xe9, 0x50, 0x1c, 0xad,
- 0x5a, 0xfc, 0x7e, 0x71, 0xd0, 0xf8, 0x7d, 0x73, 0x6d, 0x8f, 0x0d, 0xb4, 0xb6, 0x3f, 0x39, 0x04,
- 0xa3, 0xcf, 0x93, 0x88, 0x65, 0x19, 0x7f, 0x02, 0x46, 0x77, 0xf8, 0xbf, 0xd9, 0xcb, 0x9f, 0xa2,
- 0x06, 0x96, 0xe5, 0xf4, 0xbb, 0x6d, 0x76, 0xfd, 0x56, 0x7d, 0x31, 0xdd, 0xc5, 0x69, 0x82, 0x42,
- 0x59, 0x80, 0xd3, 0x3a, 0xb4, 0x41, 0x83, 0x4a, 0xf6, 0xed, 0xb6, 0xdf, 0xf3, 0xca, 0xfb, 0xb2,
- 0x2c, 0xc0, 0x69, 0x1d, 0xf4, 0x18, 0x8c, 0x34, 0xfc, 0x64, 0xc3, 0x6b, 0x64, 0xdd, 0x84, 0xcb,
- 0x0c, 0x8a, 0x45, 0x29, 0x73, 0x13, 0xf9, 0xc9, 0x46, 0x44, 0x98, 0x65, 0xb7, 0x27, 0xf7, 0xc4,
- 0xb2, 0x56, 0x86, 0x8d, 0x9a, 0xac, 0x4b, 0xa1, 0x18, 0x99, 0x88, 0xe2, 0x4c, 0xbb, 0x24, 0x0b,
- 0x70, 0x5a, 0x87, 0xae, 0xff, 0x5a, 0xd8, 0xee, 0xf8, 0x2d, 0x11, 0x5f, 0xac, 0xad, 0xff, 0x05,
- 0x01, 0xc7, 0xaa, 0x06, 0xad, 0x4d, 0x59, 0x18, 0x65, 0x3f, 0xd9, 0x67, 0xc7, 0xd6, 0x05, 0x1c,
- 0xab, 0x1a, 0xee, 0xf3, 0x30, 0xc1, 0x77, 0xf2, 0x42, 0xcb, 0xf3, 0xdb, 0xcb, 0x0b, 0xe8, 0x42,
- 0x4f, 0xfc, 0xfe, 0x13, 0x39, 0xf1, 0xfb, 0xa7, 0x8c, 0x46, 0xbd, 0x71, 0xfc, 0xee, 0x0f, 0x0a,
- 0x30, 0x76, 0x84, 0x2f, 0x37, 0x1e, 0xf9, 0x23, 0xc4, 0xe8, 0x46, 0xe6, 0xd5, 0xc6, 0x75, 0x9b,
- 0xd7, 0x71, 0xf6, 0x7d, 0xb1, 0xf1, 0xbf, 0x14, 0xe0, 0xb4, 0xac, 0x2a, 0x75, 0xb9, 0xe5, 0x05,
- 0xf6, 0x5e, 0xd6, 0xe1, 0x4f, 0x74, 0x64, 0x4c, 0xf4, 0xba, 0x3d, 0x6d, 0x74, 0x79, 0xa1, 0xef,
- 0x54, 0xbf, 0x9a, 0x99, 0x6a, 0x6c, 0x95, 0xea, 0xfe, 0x93, 0xfd, 0x17, 0x0e, 0x4c, 0xe7, 0x4f,
- 0xf6, 0x11, 0x3c, 0x94, 0xf9, 0x86, 0xf9, 0x50, 0xe6, 0x2f, 0xd8, 0x5b, 0x62, 0xe6, 0x50, 0xfa,
- 0x3c, 0x99, 0xf9, 0x67, 0x0e, 0x9c, 0x94, 0x0d, 0xd8, 0xe9, 0x39, 0xef, 0x07, 0x2c, 0x92, 0xe5,
- 0xf0, 0x97, 0xd9, 0xeb, 0xc6, 0x32, 0x7b, 0xd1, 0xde, 0xc0, 0xf5, 0x71, 0xf4, 0x7d, 0x60, 0xfc,
- 0x4f, 0x1d, 0xa8, 0xe4, 0x35, 0x38, 0x82, 0x4f, 0xfe, 0x9a, 0xf9, 0xc9, 0x9f, 0x3f, 0x9c, 0x91,
- 0xf7, 0xff, 0xe0, 0x95, 0x7e, 0x13, 0x85, 0x5a, 0x52, 0xae, 0x72, 0x6c, 0xf9, 0x68, 0x39, 0x89,
- 0x7c, 0x01, 0xad, 0x05, 0x23, 0x31, 0x8b, 0xda, 0x10, 0x4b, 0xe0, 0xa2, 0x0d, 0x69, 0x8b, 0xe2,
- 0x13, 0x36, 0x76, 0xf6, 0x3f, 0x16, 0x34, 0xdc, 0xdf, 0x2c, 0xc0, 0x19, 0xf5, 0x00, 0x2e, 0xd9,
- 0x21, 0xad, 0x74, 0x7f, 0xb0, 0x37, 0x19, 0x3c, 0xf5, 0xd3, 0xde, 0x9b, 0x0c, 0x29, 0x89, 0x74,
- 0x2f, 0xa4, 0x30, 0xac, 0xd1, 0x44, 0x55, 0x38, 0xc5, 0xde, 0x50, 0x58, 0xf2, 0x03, 0xaf, 0xe5,
- 0xbf, 0x4a, 0x22, 0x4c, 0xda, 0xe1, 0x8e, 0xd7, 0x12, 0x92, 0xba, 0xba, 0xff, 0xbb, 0x94, 0x57,
- 0x09, 0xe7, 0xb7, 0xed, 0xd1, 0xb8, 0x87, 0x06, 0xd5, 0xb8, 0xdd, 0x3f, 0x71, 0x60, 0xfc, 0x08,
- 0x9f, 0x0b, 0x0e, 0xcd, 0x2d, 0xf1, 0xac, 0xbd, 0x2d, 0xd1, 0x67, 0x1b, 0xec, 0x15, 0xa1, 0xe7,
- 0x05, 0x55, 0xf4, 0x29, 0x47, 0xc5, 0xb5, 0xf0, 0xe0, 0xc1, 0x0f, 0xd9, 0xeb, 0xc7, 0x41, 0x92,
- 0x46, 0xa2, 0xaf, 0x65, 0x32, 0x69, 0x16, 0x6c, 0xa5, 0x83, 0xea, 0xe9, 0xcd, 0x1d, 0x64, 0xd4,
- 0xfc, 0xb2, 0x03, 0xc0, 0xfb, 0x29, 0x12, 0x71, 0xd3, 0xbe, 0x6d, 0x1e, 0xda, 0x4c, 0x51, 0x22,
- 0xbc, 0x6b, 0x6a, 0x0b, 0xa5, 0x05, 0x58, 0xeb, 0xc9, 0x5d, 0xa4, 0xca, 0xbc, 0xeb, 0x2c, 0x9d,
- 0x9f, 0x77, 0xe0, 0x58, 0xa6, 0xbb, 0x39, 0xed, 0xb7, 0xcc, 0x27, 0x01, 0x2d, 0x48, 0x56, 0x66,
- 0x7a, 0x66, 0xdd, 0x78, 0xf2, 0xdf, 0x5c, 0x30, 0x9e, 0x9e, 0x46, 0xaf, 0x41, 0x49, 0x5a, 0x3e,
- 0xe4, 0xf2, 0xb6, 0xf9, 0x34, 0xaa, 0x52, 0x6f, 0x24, 0x24, 0xc6, 0x29, 0xbd, 0x4c, 0xd8, 0x5c,
- 0x61, 0xa0, 0xb0, 0xb9, 0x7b, 0xfb, 0xb0, 0x6a, 0xbe, 0x5d, 0x7a, 0xf8, 0x50, 0xec, 0xd2, 0x0f,
- 0x5a, 0xb7, 0x4b, 0x3f, 0x74, 0xc4, 0x76, 0x69, 0xcd, 0x49, 0x58, 0xbc, 0x0b, 0x27, 0xe1, 0x6b,
- 0x70, 0x72, 0x27, 0x55, 0x3a, 0xd5, 0x4a, 0x12, 0x49, 0x88, 0x9e, 0xc8, 0xb5, 0x46, 0x53, 0x05,
- 0x3a, 0x4e, 0x48, 0x90, 0x68, 0xea, 0x6a, 0x1a, 0xb1, 0xf7, 0x7c, 0x0e, 0x3a, 0x9c, 0x4b, 0x24,
- 0xeb, 0xed, 0x19, 0x1d, 0xc0, 0xdb, 0xf3, 0x96, 0x03, 0xa7, 0xbc, 0x9e, 0x4b, 0x60, 0x98, 0x6c,
- 0x89, 0x90, 0x93, 0x6b, 0xf6, 0x44, 0x08, 0x03, 0xbd, 0x70, 0xab, 0xe5, 0x15, 0xe1, 0xfc, 0x0e,
- 0xa1, 0x47, 0x53, 0xd7, 0x3b, 0x8f, 0xf3, 0xcc, 0xf7, 0x93, 0x7f, 0x2d, 0x1b, 0xcf, 0x03, 0x6c,
- 0xea, 0x3f, 0x62, 0x57, 0xdb, 0xb6, 0x10, 0xd3, 0x53, 0xbe, 0x8b, 0x98, 0x9e, 0x8c, 0xeb, 0x6d,
- 0xdc, 0x92, 0xeb, 0x2d, 0x80, 0x29, 0xbf, 0xed, 0x35, 0xc8, 0x7a, 0xb7, 0xd5, 0xe2, 0x97, 0x48,
- 0xe4, 0xe3, 0xb5, 0xb9, 0x16, 0xbc, 0xcb, 0x61, 0xcd, 0x6b, 0x65, 0x9f, 0x2d, 0x57, 0x97, 0x65,
- 0x2e, 0x65, 0x30, 0xe1, 0x1e, 0xdc, 0x74, 0xc1, 0xb2, 0x6c, 0x78, 0x24, 0xa1, 0xb3, 0xcd, 0x02,
- 0x47, 0xc6, 0xf8, 0x82, 0xbd, 0x98, 0x82, 0xb1, 0x5e, 0x07, 0xad, 0x40, 0xa9, 0x1e, 0xc4, 0xe2,
- 0x3e, 0xeb, 0x31, 0xc6, 0xcc, 0xde, 0x49, 0x59, 0xe0, 0xe2, 0x95, 0xaa, 0xba, 0xc9, 0xfa, 0x60,
- 0x4e, 0x7a, 0x47, 0x55, 0x8e, 0xd3, 0xf6, 0x68, 0x95, 0x21, 0x13, 0x2f, 0x7b, 0xf1, 0x78, 0x8e,
- 0x87, 0xfb, 0x38, 0x8c, 0x16, 0xaf, 0xc8, 0xb7, 0xc9, 0x26, 0x04, 0x39, 0xf1, 0x44, 0x57, 0x8a,
- 0x41, 0x7b, 0x44, 0xf8, 0xf8, 0xbe, 0x8f, 0x08, 0xb3, 0xbc, 0xae, 0x49, 0x4b, 0xb9, 0x87, 0xcf,
- 0x5a, 0xcb, 0xeb, 0x9a, 0x46, 0x4a, 0x8a, 0xbc, 0xae, 0x29, 0x00, 0xeb, 0x24, 0xd1, 0x5a, 0x3f,
- 0x37, 0xf9, 0x09, 0xc6, 0x34, 0x0e, 0xee, 0xf4, 0xd6, 0xfd, 0xa5, 0x27, 0xf7, 0xf5, 0x97, 0xf6,
- 0xf8, 0x77, 0x4f, 0x1d, 0xc0, 0xbf, 0xdb, 0x64, 0x19, 0x37, 0x97, 0x17, 0x84, 0x4b, 0xdd, 0x82,
- 0x7e, 0xc7, 0x72, 0x7c, 0xf0, 0xc8, 0x53, 0xf6, 0x2f, 0xe6, 0x04, 0xfa, 0x06, 0x54, 0x9f, 0xb9,
- 0xe3, 0x80, 0x6a, 0xca, 0x9e, 0x53, 0x38, 0x4b, 0xdd, 0x5a, 0x14, 0xec, 0x39, 0x05, 0x63, 0xbd,
- 0x4e, 0xd6, 0x5b, 0x7a, 0xff, 0xa1, 0x79, 0x4b, 0xa7, 0x8f, 0xc0, 0x5b, 0xfa, 0xc0, 0xc0, 0xde,
- 0xd2, 0x1b, 0x70, 0xa2, 0x13, 0xd6, 0x17, 0xfd, 0x38, 0xea, 0xb2, 0x5b, 0x75, 0xf3, 0xdd, 0x7a,
- 0x83, 0x24, 0xcc, 0xdd, 0x5a, 0x3e, 0xff, 0x4e, 0xbd, 0x93, 0x1d, 0xb6, 0x91, 0xe5, 0x1e, 0xcd,
- 0x34, 0x60, 0xa6, 0x13, 0x16, 0x75, 0x9b, 0x53, 0x88, 0xf3, 0x48, 0xe8, 0x7e, 0xda, 0x87, 0x8f,
- 0xc6, 0x4f, 0xfb, 0x01, 0x18, 0x8b, 0x9b, 0xdd, 0xa4, 0x1e, 0x5e, 0x0f, 0x98, 0x33, 0xbe, 0x34,
- 0xff, 0x0e, 0x65, 0xca, 0x16, 0xf0, 0x5b, 0x7b, 0x33, 0x53, 0xf2, 0x7f, 0xcd, 0x8a, 0x2d, 0x20,
- 0xe8, 0xeb, 0x7d, 0xee, 0xef, 0xb8, 0x87, 0x79, 0x7f, 0xe7, 0xcc, 0x81, 0xee, 0xee, 0xe4, 0x39,
- 0xa3, 0x1f, 0xf9, 0xa9, 0x73, 0x46, 0x7f, 0xd5, 0x81, 0x89, 0x1d, 0xdd, 0x65, 0x20, 0x1c, 0xe6,
- 0x16, 0x02, 0x77, 0x0c, 0x4f, 0xc4, 0xbc, 0x4b, 0xf9, 0x9c, 0x01, 0xba, 0x95, 0x05, 0x60, 0xb3,
- 0x27, 0x39, 0x41, 0x45, 0x8f, 0xde, 0xab, 0xa0, 0xa2, 0x37, 0x18, 0x1f, 0x93, 0x4a, 0x2e, 0xf3,
- 0xa2, 0xdb, 0x8d, 0x29, 0x96, 0x3c, 0x51, 0x85, 0x14, 0xeb, 0xf4, 0xd0, 0xe7, 0x1c, 0x98, 0x92,
- 0x7a, 0x99, 0x70, 0xf9, 0xc5, 0x22, 0x2a, 0xd2, 0xa6, 0x3a, 0xc8, 0xc2, 0xea, 0x37, 0x32, 0x74,
- 0x70, 0x0f, 0x65, 0xca, 0xd5, 0x55, 0x10, 0x5a, 0x23, 0x66, 0xc1, 0xbf, 0x42, 0x86, 0x99, 0x4b,
- 0xc1, 0x58, 0xaf, 0x83, 0xbe, 0xe1, 0x00, 0x7f, 0x83, 0xbf, 0xf2, 0x04, 0x63, 0xe8, 0x2f, 0x58,
- 0x96, 0x4d, 0xd3, 0x57, 0xfd, 0xe7, 0x9f, 0x92, 0xb6, 0x23, 0x06, 0xbb, 0xb5, 0x37, 0x33, 0x69,
- 0x3c, 0x4c, 0x14, 0xbf, 0xf9, 0xb6, 0x06, 0x11, 0xb6, 0x4d, 0xd6, 0x35, 0xf4, 0x45, 0x07, 0xa6,
- 0xae, 0x67, 0x0c, 0x1a, 0x22, 0x2c, 0x14, 0xdb, 0x37, 0x95, 0xf0, 0xe9, 0xce, 0x42, 0x71, 0x4f,
- 0x0f, 0xd0, 0x67, 0x4d, 0x43, 0x27, 0x8f, 0x1f, 0xb5, 0x38, 0x81, 0x19, 0xc3, 0x2a, 0xbf, 0xe6,
- 0x96, 0x6f, 0xf1, 0xbc, 0xeb, 0xf8, 0x90, 0x69, 0x3a, 0x98, 0xf4, 0x63, 0xe5, 0x34, 0x25, 0xa6,
- 0xbd, 0xc5, 0xc2, 0x66, 0x37, 0x3e, 0xbf, 0x6e, 0x6e, 0xf9, 0xe2, 0x69, 0x98, 0x34, 0x7d, 0x7b,
- 0xe8, 0x5d, 0xe6, 0xa3, 0x13, 0x67, 0xb3, 0xf9, 0xfb, 0x27, 0x64, 0x7d, 0x23, 0x87, 0xbf, 0x91,
- 0x64, 0xbf, 0x70, 0xa8, 0x49, 0xf6, 0x87, 0x8e, 0x26, 0xc9, 0xfe, 0xd4, 0x61, 0x24, 0xd9, 0x3f,
- 0x7e, 0xa0, 0x24, 0xfb, 0xda, 0x23, 0x07, 0xc3, 0xb7, 0x79, 0xe4, 0x60, 0x0e, 0x8e, 0xc9, 0xbb,
- 0x3f, 0x44, 0xe4, 0x31, 0xe7, 0x6e, 0xff, 0x33, 0xa2, 0xc9, 0xb1, 0x05, 0xb3, 0x18, 0x67, 0xeb,
- 0xd3, 0x4d, 0x56, 0x0c, 0x58, 0xcb, 0x11, 0x5b, 0x2f, 0x20, 0x99, 0x4b, 0x8b, 0xa9, 0xcf, 0x82,
- 0x45, 0xc9, 0x68, 0xe7, 0x22, 0x83, 0xdd, 0x92, 0xff, 0x60, 0xde, 0x03, 0xf4, 0x12, 0x54, 0xc2,
- 0xad, 0xad, 0x56, 0xe8, 0xd5, 0xd3, 0x97, 0x00, 0x64, 0x5c, 0x02, 0xbf, 0xbb, 0xa9, 0x12, 0xc7,
- 0xae, 0xf5, 0xa9, 0x87, 0xfb, 0x62, 0x40, 0x6f, 0x51, 0xc1, 0x24, 0x09, 0x23, 0x52, 0x4f, 0x6d,
- 0x35, 0x25, 0x36, 0x66, 0x62, 0x7d, 0xcc, 0x55, 0x93, 0x0e, 0x1f, 0xbd, 0xfa, 0x28, 0x99, 0x52,
- 0x9c, 0xed, 0x16, 0x8a, 0xe0, 0x74, 0x27, 0xcf, 0x54, 0x14, 0x8b, 0x1b, 0x4b, 0xfb, 0x19, 0xac,
- 0xe4, 0xd6, 0x3d, 0x9d, 0x6b, 0x6c, 0x8a, 0x71, 0x1f, 0xcc, 0x7a, 0xb6, 0xfe, 0xb1, 0xa3, 0xc9,
- 0xd6, 0xff, 0x31, 0x00, 0x75, 0x49, 0x5d, 0x1a, 0x1f, 0x56, 0xac, 0x5c, 0xa5, 0xe1, 0x38, 0xb5,
- 0x07, 0x52, 0x15, 0x19, 0xac, 0x91, 0x44, 0xff, 0x27, 0xf7, 0x39, 0x0b, 0x6e, 0x61, 0x69, 0x58,
- 0x5f, 0x13, 0x3f, 0x75, 0x4f, 0x5a, 0xfc, 0x13, 0x07, 0xa6, 0xf9, 0xca, 0xcb, 0x0a, 0xf7, 0x54,
- 0xb4, 0x10, 0x77, 0x7b, 0x6c, 0x87, 0xae, 0xb0, 0x28, 0xbe, 0xaa, 0x41, 0x95, 0x39, 0xba, 0xf7,
- 0xe9, 0x09, 0xfa, 0x72, 0x8e, 0x4a, 0x71, 0xcc, 0x96, 0xcd, 0x32, 0xff, 0x51, 0x82, 0x13, 0x37,
- 0x07, 0xd1, 0x22, 0xfe, 0x59, 0x5f, 0x93, 0x2a, 0x62, 0xdd, 0xfb, 0xc5, 0x43, 0x32, 0xa9, 0xea,
- 0x2f, 0x27, 0x1c, 0xc8, 0xb0, 0xfa, 0x79, 0x07, 0xa6, 0xbc, 0x4c, 0xa8, 0x09, 0xb3, 0x03, 0x59,
- 0xb1, 0x49, 0xcd, 0x45, 0x69, 0xfc, 0x0a, 0x13, 0xf2, 0xb2, 0x51, 0x2d, 0xb8, 0x87, 0x38, 0xfa,
- 0x81, 0x03, 0x0f, 0x24, 0x5e, 0xbc, 0xcd, 0xf3, 0x12, 0xc7, 0xe9, 0x5d, 0x5d, 0xd1, 0xb9, 0x93,
- 0x6c, 0x37, 0xbe, 0x62, 0x7d, 0x37, 0x6e, 0xf4, 0xa7, 0xc9, 0xf7, 0xe5, 0x23, 0x62, 0x5f, 0x3e,
- 0xb0, 0x4f, 0x4d, 0xbc, 0x5f, 0xd7, 0xa7, 0x3f, 0xe5, 0xf0, 0xf7, 0xab, 0xfa, 0x8a, 0x7c, 0x9b,
- 0xa6, 0xc8, 0x77, 0xd9, 0xe6, 0x0b, 0x3a, 0xba, 0xec, 0xf9, 0xab, 0x0e, 0x9c, 0xcc, 0x3b, 0x91,
- 0x72, 0xba, 0xf4, 0x11, 0xb3, 0x4b, 0x16, 0xb5, 0x2c, 0xbd, 0x43, 0x56, 0x1e, 0xf0, 0x98, 0xbe,
- 0x02, 0x0f, 0xdf, 0xee, 0x2b, 0xde, 0x0e, 0xdf, 0x98, 0x2e, 0x16, 0xff, 0x69, 0x49, 0xf3, 0x42,
- 0x26, 0xa4, 0x63, 0x3d, 0x86, 0x3b, 0x80, 0x11, 0x3f, 0x68, 0xf9, 0x01, 0x11, 0xf7, 0x35, 0x6d,
- 0xea, 0xb0, 0xe2, 0x01, 0x1e, 0x8a, 0x1d, 0x0b, 0x2a, 0xf7, 0xd8, 0x29, 0x99, 0x7d, 0xd2, 0x6c,
- 0xf8, 0xe8, 0x9f, 0x34, 0xbb, 0x0e, 0xa5, 0xeb, 0x7e, 0xd2, 0x64, 0xc1, 0x14, 0xc2, 0xd7, 0x67,
- 0xe1, 0x9e, 0x23, 0x45, 0x97, 0x8e, 0xfd, 0x9a, 0x24, 0x80, 0x53, 0x5a, 0xe8, 0x1c, 0x27, 0xcc,
- 0x22, 0xb7, 0xb3, 0x21, 0xb5, 0xd7, 0x64, 0x01, 0x4e, 0xeb, 0xd0, 0xc9, 0x1a, 0xa7, 0xbf, 0x64,
- 0x42, 0x24, 0x91, 0xb7, 0xd7, 0x46, 0x3e, 0x46, 0x81, 0x91, 0xdf, 0x26, 0xbe, 0xa6, 0xd1, 0xc0,
- 0x06, 0x45, 0x95, 0x3a, 0x79, 0xac, 0x6f, 0xea, 0xe4, 0xd7, 0x99, 0xc0, 0x96, 0xf8, 0x41, 0x97,
- 0xac, 0x05, 0x22, 0xde, 0xfb, 0xb2, 0x9d, 0xbb, 0xcf, 0x1c, 0x27, 0x57, 0xc1, 0xd3, 0xdf, 0x58,
- 0xa3, 0xa7, 0xb9, 0x5c, 0xca, 0xfb, 0xba, 0x5c, 0x52, 0x93, 0xcb, 0xb8, 0x75, 0x93, 0x4b, 0x42,
- 0x3a, 0x56, 0x4c, 0x2e, 0x3f, 0x55, 0xe6, 0x80, 0xbf, 0x70, 0x00, 0x29, 0xb9, 0x4b, 0x31, 0xd4,
- 0x23, 0x08, 0xaa, 0xfc, 0xb8, 0x03, 0x10, 0xa8, 0x87, 0x2f, 0xed, 0x9e, 0x82, 0x1c, 0x67, 0xda,
- 0x81, 0x14, 0x86, 0x35, 0x9a, 0xee, 0xff, 0x70, 0xd2, 0xd8, 0xe5, 0x74, 0xec, 0x47, 0x10, 0x44,
- 0xb6, 0x6b, 0x06, 0x91, 0x6d, 0x58, 0x34, 0xdd, 0xab, 0x61, 0xf4, 0x09, 0x27, 0xfb, 0x71, 0x01,
- 0x8e, 0xe9, 0x95, 0xab, 0xe4, 0x28, 0x3e, 0xf6, 0x75, 0x23, 0x82, 0xf6, 0xaa, 0xdd, 0xf1, 0x56,
- 0x85, 0x07, 0x28, 0x2f, 0x5a, 0xfb, 0x63, 0x99, 0x68, 0xed, 0x6b, 0xf6, 0x49, 0xef, 0x1f, 0xb2,
- 0xfd, 0x5f, 0x1d, 0x38, 0x91, 0x69, 0x71, 0x04, 0x0b, 0x6c, 0xc7, 0x5c, 0x60, 0xcf, 0x59, 0x1f,
- 0x75, 0x9f, 0xd5, 0xf5, 0xcd, 0x42, 0xcf, 0x68, 0x99, 0x12, 0xf7, 0x49, 0x07, 0x8a, 0x54, 0x5a,
- 0x96, 0xf1, 0x5c, 0x1f, 0x39, 0x94, 0x15, 0xc0, 0xe4, 0x7a, 0xc1, 0x9d, 0x55, 0xff, 0x18, 0x0c,
- 0x73, 0xea, 0xd3, 0x9f, 0x70, 0x00, 0xd2, 0x4a, 0xf7, 0x4a, 0x04, 0x76, 0xbf, 0x5d, 0x80, 0x53,
- 0xb9, 0xcb, 0x08, 0x7d, 0x5a, 0x59, 0xe4, 0x1c, 0xdb, 0xd1, 0x8a, 0x06, 0x21, 0xdd, 0x30, 0x37,
- 0x61, 0x18, 0xe6, 0x84, 0x3d, 0xee, 0x5e, 0x29, 0x30, 0x82, 0x4d, 0x6b, 0x93, 0xf5, 0x23, 0x27,
- 0x0d, 0x80, 0x55, 0x79, 0x8d, 0xfe, 0x12, 0x5e, 0xe2, 0x71, 0x7f, 0xac, 0xdd, 0x70, 0x90, 0x03,
- 0x3d, 0x02, 0x5e, 0x71, 0xdd, 0xe4, 0x15, 0xd8, 0xbe, 0x1f, 0xb9, 0x0f, 0xb3, 0x78, 0x05, 0xf2,
- 0x1c, 0xcb, 0x83, 0x25, 0x45, 0x34, 0xae, 0xc3, 0x16, 0x06, 0xbe, 0x0e, 0x3b, 0x01, 0xe5, 0x17,
- 0x7d, 0x95, 0x4d, 0x73, 0x7e, 0xf6, 0x3b, 0x3f, 0x3c, 0x7b, 0xdf, 0x77, 0x7f, 0x78, 0xf6, 0xbe,
- 0x1f, 0xfc, 0xf0, 0xec, 0x7d, 0x1f, 0xbf, 0x79, 0xd6, 0xf9, 0xce, 0xcd, 0xb3, 0xce, 0x77, 0x6f,
- 0x9e, 0x75, 0x7e, 0x70, 0xf3, 0xac, 0xf3, 0x1f, 0x6e, 0x9e, 0x75, 0xfe, 0xde, 0x7f, 0x3c, 0x7b,
- 0xdf, 0x8b, 0x63, 0x72, 0x60, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x84, 0x02, 0x48, 0xf8, 0xe2,
- 0xd6, 0x00, 0x00,
+ 0x29, 0xe5, 0x54, 0x45, 0xae, 0x28, 0x25, 0xfd, 0xb0, 0xc1, 0xe8, 0x92, 0xa8, 0x52, 0x49, 0x54,
+ 0x95, 0xa8, 0x62, 0x27, 0xbe, 0x3c, 0x2a, 0xd5, 0xcf, 0xe9, 0x9e, 0x9d, 0xc5, 0x2d, 0xee, 0x1a,
+ 0x38, 0x95, 0xfd, 0x0b, 0xd8, 0xaf, 0xbb, 0xbf, 0xaf, 0xbb, 0xa7, 0xfb, 0xeb, 0xef, 0xd5, 0x5f,
+ 0xc3, 0x7a, 0xc3, 0x4f, 0x9a, 0xdd, 0xcd, 0xd9, 0x5a, 0xd8, 0x3e, 0xe7, 0x45, 0x8d, 0xb0, 0x13,
+ 0x85, 0x2f, 0xb3, 0x7f, 0xde, 0x79, 0x3d, 0x8c, 0xb6, 0xb7, 0x5a, 0xe1, 0xf5, 0xf8, 0xdc, 0xce,
+ 0xd3, 0xe7, 0x3a, 0xdb, 0x8d, 0x73, 0x5e, 0xc7, 0x8f, 0xcf, 0x49, 0xe8, 0xb9, 0x9d, 0xa7, 0xbc,
+ 0x56, 0xa7, 0xe9, 0x3d, 0x75, 0xae, 0x41, 0x02, 0x12, 0x79, 0x09, 0xa9, 0xcf, 0x76, 0xa2, 0x30,
+ 0x09, 0xd1, 0x07, 0x52, 0x8c, 0xb3, 0x12, 0x23, 0xfb, 0xe7, 0xc3, 0x0a, 0xe3, 0xec, 0xce, 0xd3,
+ 0xb3, 0x9d, 0xed, 0xc6, 0x2c, 0xc5, 0x38, 0x2b, 0xa1, 0xb3, 0x12, 0xe3, 0xf4, 0x3b, 0xb5, 0x3e,
+ 0x35, 0xc2, 0x46, 0x78, 0x8e, 0x21, 0xde, 0xec, 0x6e, 0xb1, 0x5f, 0xec, 0x07, 0xfb, 0x8f, 0x13,
+ 0x9c, 0x76, 0xb7, 0x9f, 0x89, 0x67, 0xfd, 0x90, 0xf6, 0xef, 0x5c, 0x2d, 0x8c, 0xc8, 0xb9, 0x9d,
+ 0x9e, 0x4e, 0x4d, 0xbf, 0x43, 0xab, 0xd3, 0x09, 0x5b, 0x7e, 0x6d, 0x37, 0xaf, 0xd6, 0xbb, 0xd2,
+ 0x5a, 0x6d, 0xaf, 0xd6, 0xf4, 0x03, 0x12, 0xed, 0xa6, 0x43, 0x6f, 0x93, 0xc4, 0xcb, 0x6b, 0x75,
+ 0xae, 0x5f, 0xab, 0xa8, 0x1b, 0x24, 0x7e, 0x9b, 0xf4, 0x34, 0xf8, 0xab, 0xb7, 0x6b, 0x10, 0xd7,
+ 0x9a, 0xa4, 0xed, 0xf5, 0xb4, 0x7b, 0xba, 0x5f, 0xbb, 0x6e, 0xe2, 0xb7, 0xce, 0xf9, 0x41, 0x12,
+ 0x27, 0x51, 0xb6, 0x91, 0x7b, 0x01, 0x46, 0xe6, 0xda, 0x61, 0x37, 0x48, 0xd0, 0x7b, 0xa1, 0xb8,
+ 0xe3, 0xb5, 0xba, 0xa4, 0xe2, 0x3c, 0xec, 0x3c, 0x5e, 0x9a, 0x7f, 0xf4, 0x3b, 0x7b, 0x33, 0xf7,
+ 0xdd, 0xdc, 0x9b, 0x29, 0x3e, 0x4f, 0x81, 0xb7, 0xf6, 0x66, 0x4e, 0x92, 0xa0, 0x16, 0xd6, 0xfd,
+ 0xa0, 0x71, 0xee, 0xe5, 0x38, 0x0c, 0x66, 0xaf, 0x74, 0xdb, 0x9b, 0x24, 0xc2, 0xbc, 0x8d, 0xfb,
+ 0x6f, 0x0a, 0x70, 0x6c, 0x2e, 0xaa, 0x35, 0xfd, 0x1d, 0x52, 0x4d, 0x28, 0xfe, 0xc6, 0x2e, 0x6a,
+ 0xc2, 0x50, 0xe2, 0x45, 0x0c, 0x5d, 0xf9, 0xfc, 0xea, 0xec, 0xdd, 0x7e, 0xf7, 0xd9, 0x0d, 0x2f,
+ 0x92, 0xb8, 0xe7, 0x47, 0x6f, 0xee, 0xcd, 0x0c, 0x6d, 0x78, 0x11, 0xa6, 0x24, 0x50, 0x0b, 0x86,
+ 0x83, 0x30, 0x20, 0x95, 0x02, 0x23, 0x75, 0xe5, 0xee, 0x49, 0x5d, 0x09, 0x03, 0x35, 0x8e, 0xf9,
+ 0xb1, 0x9b, 0x7b, 0x33, 0xc3, 0x14, 0x82, 0x19, 0x15, 0x3a, 0xae, 0x57, 0xfd, 0x4e, 0x65, 0xc8,
+ 0xd6, 0xb8, 0x5e, 0xf4, 0x3b, 0xe6, 0xb8, 0x5e, 0xf4, 0x3b, 0x98, 0x92, 0x70, 0x3f, 0x5b, 0x80,
+ 0xd2, 0x5c, 0xd4, 0xe8, 0xb6, 0x49, 0x90, 0xc4, 0xe8, 0x63, 0x00, 0x1d, 0x2f, 0xf2, 0xda, 0x24,
+ 0x21, 0x51, 0x5c, 0x71, 0x1e, 0x1e, 0x7a, 0xbc, 0x7c, 0x7e, 0xe5, 0xee, 0xc9, 0xaf, 0x4b, 0x9c,
+ 0xf3, 0x48, 0x7c, 0x72, 0x50, 0xa0, 0x18, 0x6b, 0x24, 0xd1, 0x6b, 0x50, 0xf2, 0xa2, 0xc4, 0xdf,
+ 0xf2, 0x6a, 0x49, 0x5c, 0x29, 0x30, 0xfa, 0xcf, 0xde, 0x3d, 0xfd, 0x39, 0x81, 0x72, 0xfe, 0xb8,
+ 0x20, 0x5f, 0x92, 0x90, 0x18, 0xa7, 0xf4, 0xdc, 0xdf, 0x1b, 0x86, 0xf2, 0x5c, 0x94, 0x2c, 0x2f,
+ 0x54, 0x13, 0x2f, 0xe9, 0xc6, 0xe8, 0x0f, 0x1d, 0x38, 0x11, 0xf3, 0x69, 0xf3, 0x49, 0xbc, 0x1e,
+ 0x85, 0x35, 0x12, 0xc7, 0xa4, 0x2e, 0xe6, 0x65, 0xcb, 0x4a, 0xbf, 0x24, 0xb1, 0xd9, 0x6a, 0x2f,
+ 0xa1, 0x0b, 0x41, 0x12, 0xed, 0xce, 0x3f, 0x25, 0xfa, 0x7c, 0x22, 0xa7, 0xc6, 0x9b, 0x6f, 0xcf,
+ 0x20, 0x39, 0x14, 0x8a, 0x89, 0x7f, 0x62, 0x9c, 0xd7, 0x6b, 0xf4, 0x55, 0x07, 0xc6, 0x3b, 0x61,
+ 0x3d, 0xc6, 0xa4, 0x16, 0x76, 0x3b, 0xa4, 0x2e, 0xa6, 0xf7, 0xc3, 0x76, 0x87, 0xb1, 0xae, 0x51,
+ 0xe0, 0xfd, 0x3f, 0x29, 0xfa, 0x3f, 0xae, 0x17, 0x61, 0xa3, 0x2b, 0xe8, 0x19, 0x18, 0x0f, 0xc2,
+ 0xa4, 0xda, 0x21, 0x35, 0x7f, 0xcb, 0x27, 0x75, 0xb6, 0xf0, 0xc7, 0xd2, 0x96, 0x57, 0xb4, 0x32,
+ 0x6c, 0xd4, 0x9c, 0x5e, 0x82, 0x4a, 0xbf, 0x99, 0x43, 0x53, 0x30, 0xb4, 0x4d, 0x76, 0x39, 0xb3,
+ 0xc1, 0xf4, 0x5f, 0x74, 0x52, 0x32, 0x20, 0xba, 0x8d, 0xc7, 0x04, 0x67, 0x79, 0x4f, 0xe1, 0x19,
+ 0x67, 0xfa, 0xfd, 0x70, 0xbc, 0xa7, 0xeb, 0x07, 0x41, 0xe0, 0x7e, 0x77, 0x04, 0xc6, 0xe4, 0xa7,
+ 0x40, 0x0f, 0xc3, 0x70, 0xe0, 0xb5, 0x25, 0x9f, 0x1b, 0x17, 0xe3, 0x18, 0xbe, 0xe2, 0xb5, 0xe9,
+ 0x0e, 0xf7, 0xda, 0x84, 0xd6, 0xe8, 0x78, 0x49, 0x93, 0xe1, 0xd1, 0x6a, 0xac, 0x7b, 0x49, 0x13,
+ 0xb3, 0x12, 0xf4, 0x20, 0x0c, 0xb7, 0xc3, 0x3a, 0x61, 0x73, 0x51, 0xe4, 0x1c, 0x62, 0x35, 0xac,
+ 0x13, 0xcc, 0xa0, 0xb4, 0xfd, 0x56, 0x14, 0xb6, 0x2b, 0xc3, 0x66, 0xfb, 0xa5, 0x28, 0x6c, 0x63,
+ 0x56, 0x82, 0xbe, 0xe2, 0xc0, 0x94, 0x5c, 0xdb, 0x97, 0xc3, 0x9a, 0x97, 0xf8, 0x61, 0x50, 0x29,
+ 0x32, 0x8e, 0x82, 0xed, 0x6d, 0x29, 0x89, 0x79, 0xbe, 0x22, 0xba, 0x30, 0x95, 0x2d, 0xc1, 0x3d,
+ 0xbd, 0x40, 0xe7, 0x01, 0x1a, 0xad, 0x70, 0xd3, 0x6b, 0xd1, 0x09, 0xa9, 0x8c, 0xb0, 0x21, 0x28,
+ 0xce, 0xb0, 0xac, 0x4a, 0xb0, 0x56, 0x0b, 0xdd, 0x80, 0x51, 0x8f, 0x73, 0xff, 0xca, 0x28, 0x1b,
+ 0xc4, 0x73, 0x36, 0x06, 0x61, 0x1c, 0x27, 0xf3, 0xe5, 0x9b, 0x7b, 0x33, 0xa3, 0x02, 0x88, 0x25,
+ 0x39, 0xf4, 0x24, 0x8c, 0x85, 0x1d, 0xda, 0x6f, 0xaf, 0x55, 0x19, 0x63, 0x0b, 0x73, 0x4a, 0xf4,
+ 0x75, 0x6c, 0x4d, 0xc0, 0xb1, 0xaa, 0x81, 0x9e, 0x80, 0xd1, 0xb8, 0xbb, 0x49, 0xbf, 0x63, 0xa5,
+ 0xc4, 0x06, 0x76, 0x4c, 0x54, 0x1e, 0xad, 0x72, 0x30, 0x96, 0xe5, 0xe8, 0xdd, 0x50, 0x8e, 0x48,
+ 0xad, 0x1b, 0xc5, 0x84, 0x7e, 0xd8, 0x0a, 0x30, 0xdc, 0x27, 0x44, 0xf5, 0x32, 0x4e, 0x8b, 0xb0,
+ 0x5e, 0x0f, 0xbd, 0x0f, 0x26, 0xe9, 0x07, 0xbe, 0x70, 0xa3, 0x13, 0x91, 0x38, 0xa6, 0x5f, 0xb5,
+ 0xcc, 0x08, 0x9d, 0x16, 0x2d, 0x27, 0x97, 0x8c, 0x52, 0x9c, 0xa9, 0x8d, 0x5e, 0x07, 0xf0, 0x14,
+ 0xcf, 0xa8, 0x8c, 0xb3, 0xc9, 0xbc, 0x6c, 0x6f, 0x45, 0x2c, 0x2f, 0xcc, 0x4f, 0xd2, 0xef, 0x98,
+ 0xfe, 0xc6, 0x1a, 0x3d, 0x3a, 0x3f, 0x75, 0xd2, 0x22, 0x09, 0xa9, 0x57, 0x26, 0xd8, 0x80, 0xd5,
+ 0xfc, 0x2c, 0x72, 0x30, 0x96, 0xe5, 0xee, 0xdf, 0x2d, 0x80, 0x86, 0x05, 0xcd, 0xc3, 0x98, 0xe0,
+ 0x6b, 0x62, 0x4b, 0xce, 0x3f, 0x26, 0xbf, 0x83, 0xfc, 0x82, 0xb7, 0xf6, 0x72, 0xf9, 0xa1, 0x6a,
+ 0x87, 0xde, 0x80, 0x72, 0x27, 0xac, 0xaf, 0x92, 0xc4, 0xab, 0x7b, 0x89, 0x27, 0x4e, 0x73, 0x0b,
+ 0x27, 0x8c, 0xc4, 0x38, 0x7f, 0x8c, 0x7e, 0xba, 0xf5, 0x94, 0x04, 0xd6, 0xe9, 0xa1, 0x67, 0x01,
+ 0xc5, 0x24, 0xda, 0xf1, 0x6b, 0x64, 0xae, 0x56, 0xa3, 0x22, 0x11, 0xdb, 0x00, 0x43, 0x6c, 0x30,
+ 0xd3, 0x62, 0x30, 0xa8, 0xda, 0x53, 0x03, 0xe7, 0xb4, 0x72, 0xbf, 0x57, 0x80, 0x49, 0x6d, 0xac,
+ 0x1d, 0x52, 0x43, 0x6f, 0x39, 0x70, 0x4c, 0x1d, 0x67, 0xf3, 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, 0xfa, 0xcb, 0x0e, 0x9c, 0xcc, 0x43, 0x91, 0xc3, 0x73, 0x9b, 0x3a,
+ 0xcf, 0xb5, 0xca, 0xbc, 0x28, 0x55, 0x3a, 0x18, 0x9d, 0x8f, 0xff, 0xbf, 0x02, 0x4c, 0xe9, 0x4b,
+ 0x88, 0x49, 0x02, 0xff, 0xdc, 0x81, 0x53, 0x72, 0x04, 0x98, 0xc4, 0xdd, 0x56, 0x66, 0x7a, 0xdb,
+ 0x56, 0xa7, 0x97, 0x9f, 0xa4, 0x73, 0x79, 0xf4, 0xf8, 0x34, 0x3f, 0x24, 0xa6, 0xf9, 0x54, 0x6e,
+ 0x1d, 0x9c, 0xdf, 0xd5, 0xe9, 0x6f, 0x3a, 0x30, 0xdd, 0x1f, 0x69, 0xce, 0xc4, 0x77, 0xcc, 0x89,
+ 0x7f, 0xd1, 0xde, 0x20, 0x39, 0x79, 0x36, 0xfd, 0x6c, 0xb0, 0xfa, 0x07, 0xf8, 0xad, 0x31, 0xe8,
+ 0x39, 0x43, 0xd0, 0x53, 0x50, 0x16, 0xec, 0xf8, 0x72, 0xd8, 0x88, 0x59, 0x27, 0xc7, 0xf8, 0x5e,
+ 0x9b, 0x4b, 0xc1, 0x58, 0xaf, 0x83, 0xea, 0x50, 0x88, 0x9f, 0x16, 0x5d, 0xb7, 0xc0, 0xde, 0xaa,
+ 0x4f, 0x2b, 0x29, 0x72, 0xe4, 0xe6, 0xde, 0x4c, 0xa1, 0xfa, 0x34, 0x2e, 0xc4, 0x4f, 0x53, 0x49,
+ 0xbd, 0xe1, 0x27, 0xf6, 0x24, 0xf5, 0x65, 0x3f, 0x51, 0x74, 0x98, 0xa4, 0xbe, 0xec, 0x27, 0x98,
+ 0x92, 0xa0, 0x1a, 0x48, 0x33, 0x49, 0x3a, 0xec, 0xc4, 0xb7, 0xa2, 0x81, 0x5c, 0xdc, 0xd8, 0x58,
+ 0x57, 0xb4, 0x98, 0x7c, 0x41, 0x21, 0x98, 0x51, 0x41, 0x9f, 0x71, 0xe8, 0x8c, 0xf3, 0xc2, 0x30,
+ 0xda, 0x15, 0x82, 0xc3, 0x55, 0x7b, 0x4b, 0x20, 0x8c, 0x76, 0x15, 0x71, 0xf1, 0x21, 0x55, 0x01,
+ 0xd6, 0x49, 0xb3, 0x81, 0xd7, 0xb7, 0x62, 0x26, 0x27, 0xd8, 0x19, 0xf8, 0xe2, 0x52, 0x35, 0x33,
+ 0xf0, 0xc5, 0xa5, 0x2a, 0x66, 0x54, 0xe8, 0x07, 0x8d, 0xbc, 0xeb, 0x42, 0xc6, 0xb0, 0xf0, 0x41,
+ 0xb1, 0x77, 0xdd, 0xfc, 0xa0, 0xd8, 0xbb, 0x8e, 0x29, 0x09, 0x4a, 0x29, 0x8c, 0x63, 0x26, 0x52,
+ 0x58, 0xa1, 0xb4, 0x56, 0xad, 0x9a, 0x94, 0xd6, 0xaa, 0x55, 0x4c, 0x49, 0xb0, 0x45, 0x5a, 0x8b,
+ 0x99, 0x3c, 0x62, 0x67, 0x91, 0x2e, 0x64, 0x28, 0x2d, 0x2f, 0x54, 0x31, 0x25, 0x41, 0x59, 0x86,
+ 0xf7, 0x6a, 0x37, 0xe2, 0xc2, 0x4c, 0xf9, 0xfc, 0x9a, 0x85, 0xf5, 0x42, 0xd1, 0x29, 0x6a, 0xa5,
+ 0x9b, 0x7b, 0x33, 0x45, 0x06, 0xc2, 0x9c, 0x90, 0xfb, 0x07, 0x43, 0x29, 0xbb, 0x90, 0xfc, 0x1c,
+ 0xfd, 0x1a, 0x3b, 0x08, 0x05, 0x2f, 0x10, 0xa2, 0xaf, 0x73, 0x68, 0xa2, 0xef, 0x09, 0x7e, 0xe2,
+ 0x19, 0xe4, 0x70, 0x96, 0x3e, 0xfa, 0x82, 0xd3, 0xab, 0xdb, 0x7a, 0xf6, 0xcf, 0xb2, 0xf4, 0x60,
+ 0xe6, 0x67, 0xc5, 0xbe, 0x2a, 0xef, 0xf4, 0x67, 0x9c, 0x54, 0x88, 0x88, 0xfb, 0x9d, 0x03, 0x1f,
+ 0x31, 0xcf, 0x01, 0x8b, 0x0a, 0xb9, 0xce, 0xf7, 0x3f, 0xeb, 0xc0, 0x84, 0x84, 0x53, 0xf1, 0x38,
+ 0x46, 0x37, 0x60, 0x4c, 0xf6, 0x54, 0x7c, 0x3d, 0x9b, 0xb6, 0x00, 0x25, 0xc4, 0xab, 0xce, 0x28,
+ 0x6a, 0xee, 0x5b, 0x23, 0x80, 0xd2, 0xb3, 0xaa, 0x13, 0xc6, 0x3e, 0xe3, 0x44, 0x77, 0x70, 0x0a,
+ 0x05, 0xda, 0x29, 0xf4, 0xbc, 0xcd, 0x53, 0x28, 0xed, 0x96, 0x71, 0x1e, 0x7d, 0x21, 0xc3, 0xb7,
+ 0xf9, 0xc1, 0xf4, 0xe1, 0x43, 0xe1, 0xdb, 0x5a, 0x17, 0xf6, 0xe7, 0xe0, 0x3b, 0x82, 0x83, 0xf3,
+ 0xa3, 0xeb, 0x17, 0xec, 0x72, 0x70, 0xad, 0x17, 0x59, 0x5e, 0x1e, 0x71, 0x0e, 0xcb, 0xcf, 0xae,
+ 0x6b, 0x56, 0x39, 0xac, 0x46, 0xd5, 0xe4, 0xb5, 0x11, 0xe7, 0xb5, 0x23, 0xb6, 0x68, 0x6a, 0xbc,
+ 0x36, 0x4b, 0x53, 0x71, 0xdd, 0x57, 0x25, 0xd7, 0xe5, 0xa7, 0xd6, 0x0b, 0x96, 0xb9, 0xae, 0x46,
+ 0xb7, 0x97, 0xff, 0xbe, 0x02, 0xa7, 0x7a, 0xeb, 0x61, 0xb2, 0x85, 0xce, 0x41, 0xa9, 0x16, 0x06,
+ 0x5b, 0x7e, 0x63, 0xd5, 0xeb, 0x08, 0x7d, 0x4d, 0xf1, 0xa2, 0x05, 0x59, 0x80, 0xd3, 0x3a, 0xe8,
+ 0x21, 0xce, 0x78, 0xb8, 0x45, 0xa4, 0x2c, 0xaa, 0x0e, 0xad, 0x90, 0x5d, 0xc6, 0x85, 0xde, 0x33,
+ 0xf6, 0x95, 0xaf, 0xcf, 0xdc, 0xf7, 0xf1, 0x3f, 0x7e, 0xf8, 0x3e, 0xf7, 0x8f, 0x86, 0xe0, 0x81,
+ 0x5c, 0x9a, 0x42, 0x5a, 0xff, 0x2d, 0x43, 0x5a, 0xd7, 0xca, 0x05, 0x17, 0xb9, 0x66, 0x53, 0x90,
+ 0xd5, 0xd0, 0xe7, 0xc9, 0xe5, 0x5a, 0x31, 0xce, 0xef, 0x14, 0x9d, 0xa8, 0xc0, 0x6b, 0x93, 0xb8,
+ 0xe3, 0xd5, 0x88, 0x18, 0xbd, 0x9a, 0xa8, 0x2b, 0xb2, 0x00, 0xa7, 0x75, 0xb8, 0x0a, 0xbd, 0xe5,
+ 0x75, 0x5b, 0x89, 0x30, 0x94, 0x69, 0x2a, 0x34, 0x03, 0x63, 0x59, 0x8e, 0xfe, 0x9e, 0x03, 0xa8,
+ 0x97, 0xaa, 0xd8, 0x88, 0x1b, 0x87, 0x31, 0x0f, 0xf3, 0xa7, 0x6f, 0x6a, 0x4a, 0xb8, 0x36, 0xd2,
+ 0x9c, 0x7e, 0x68, 0xdf, 0xf4, 0xa3, 0xe9, 0x39, 0xc4, 0x95, 0x83, 0x01, 0x6c, 0x68, 0xcc, 0xd4,
+ 0x52, 0xab, 0x91, 0x38, 0xe6, 0xe6, 0x38, 0xdd, 0xd4, 0xc2, 0xc0, 0x58, 0x96, 0xa3, 0x19, 0x28,
+ 0x92, 0x28, 0x0a, 0x23, 0xa1, 0x6b, 0xb3, 0x65, 0x7c, 0x81, 0x02, 0x30, 0x87, 0xbb, 0x3f, 0x2a,
+ 0x40, 0xa5, 0x9f, 0x76, 0x82, 0x7e, 0x57, 0xd3, 0xab, 0x85, 0xe6, 0x24, 0x14, 0xbf, 0xf0, 0xf0,
+ 0x74, 0xa2, 0xac, 0x02, 0xd8, 0x47, 0xc3, 0x16, 0xa5, 0x38, 0xdb, 0xc1, 0xe9, 0x2f, 0x6a, 0x1a,
+ 0xb6, 0x8e, 0x22, 0xe7, 0x80, 0xdf, 0x32, 0x0f, 0xf8, 0x75, 0xdb, 0x83, 0xd2, 0x8f, 0xf9, 0x3f,
+ 0x29, 0xc2, 0x09, 0x59, 0x5a, 0x25, 0xf4, 0xa8, 0x7c, 0xae, 0x4b, 0xa2, 0x5d, 0xf4, 0x7d, 0x07,
+ 0x4e, 0x7a, 0x59, 0xd3, 0x8d, 0x4f, 0x0e, 0x61, 0xa2, 0x35, 0xaa, 0xb3, 0x73, 0x39, 0x14, 0xf9,
+ 0x44, 0x9f, 0x17, 0x13, 0x7d, 0x32, 0xaf, 0x4a, 0x1f, 0xbb, 0x7b, 0xee, 0x00, 0xd0, 0x33, 0x30,
+ 0x2e, 0xe1, 0xcc, 0xdc, 0xc3, 0xb7, 0xb8, 0x32, 0x6e, 0xcf, 0x69, 0x65, 0xd8, 0xa8, 0x49, 0x5b,
+ 0x26, 0xa4, 0xdd, 0x69, 0x79, 0x09, 0xd1, 0x0c, 0x45, 0xaa, 0xe5, 0x86, 0x56, 0x86, 0x8d, 0x9a,
+ 0xe8, 0x31, 0x18, 0x09, 0xc2, 0x3a, 0xb9, 0x54, 0x17, 0x06, 0xe2, 0x49, 0xd1, 0x66, 0xe4, 0x0a,
+ 0x83, 0x62, 0x51, 0x8a, 0x1e, 0x4d, 0xad, 0x71, 0x45, 0xb6, 0x85, 0xca, 0x79, 0x96, 0x38, 0xf4,
+ 0x0f, 0x1c, 0x28, 0xd1, 0x16, 0x1b, 0xbb, 0x1d, 0x42, 0xcf, 0x36, 0xfa, 0x45, 0xea, 0x87, 0xf3,
+ 0x45, 0xae, 0x48, 0x32, 0xa6, 0xa9, 0xa3, 0xa4, 0xe0, 0x6f, 0xbe, 0x3d, 0x33, 0x26, 0x7f, 0xe0,
+ 0xb4, 0x57, 0xd3, 0xcb, 0x70, 0x7f, 0xdf, 0xaf, 0x79, 0x20, 0x57, 0xc0, 0xdf, 0x80, 0x49, 0xb3,
+ 0x13, 0x07, 0xf2, 0x03, 0xfc, 0x53, 0x6d, 0xdb, 0xf1, 0x71, 0x09, 0x7e, 0x76, 0xcf, 0xa4, 0x59,
+ 0xb5, 0x18, 0x16, 0xc5, 0xd2, 0x33, 0x17, 0xc3, 0xa2, 0x58, 0x0c, 0x8b, 0xee, 0x1f, 0x3a, 0xe9,
+ 0xd6, 0xd4, 0xc4, 0x3c, 0x7a, 0x30, 0x77, 0xa3, 0x96, 0x60, 0xc4, 0xea, 0x60, 0xbe, 0x8a, 0x2f,
+ 0x63, 0x0a, 0x47, 0x5f, 0xd4, 0xb8, 0x23, 0x6d, 0xd6, 0x15, 0x6e, 0x0d, 0x4b, 0x26, 0x7a, 0x03,
+ 0x71, 0x2f, 0xff, 0x13, 0x05, 0x38, 0xdb, 0x05, 0xf7, 0x0b, 0x05, 0x78, 0x68, 0x5f, 0xa1, 0x35,
+ 0xb7, 0xe3, 0xce, 0x3d, 0xef, 0x38, 0x3d, 0xd6, 0x22, 0xd2, 0x09, 0xaf, 0xe2, 0xcb, 0xe2, 0x7b,
+ 0xa9, 0x63, 0x0d, 0x73, 0x30, 0x96, 0xe5, 0x54, 0x74, 0xd8, 0x26, 0xbb, 0x4b, 0x61, 0xd4, 0xf6,
+ 0x12, 0xc1, 0x1d, 0x94, 0xe8, 0xb0, 0x22, 0x0b, 0x70, 0x5a, 0xc7, 0xfd, 0xbe, 0x03, 0xd9, 0x0e,
+ 0x20, 0x0f, 0x26, 0xbb, 0x31, 0x89, 0xe8, 0x91, 0x5a, 0x25, 0xb5, 0x88, 0xc8, 0xe5, 0xf9, 0xe8,
+ 0x2c, 0xf7, 0xf6, 0xd3, 0x11, 0xce, 0xd6, 0xc2, 0x88, 0xcc, 0xee, 0x3c, 0x35, 0xcb, 0x6b, 0xac,
+ 0x90, 0xdd, 0x2a, 0x69, 0x11, 0x8a, 0x63, 0x1e, 0xdd, 0xdc, 0x9b, 0x99, 0xbc, 0x6a, 0x20, 0xc0,
+ 0x19, 0x84, 0x94, 0x44, 0xc7, 0x8b, 0xe3, 0xeb, 0x61, 0x54, 0x17, 0x24, 0x0a, 0x07, 0x26, 0xb1,
+ 0x6e, 0x20, 0xc0, 0x19, 0x84, 0xee, 0xf7, 0xa8, 0xfa, 0xa8, 0x4b, 0xad, 0xe8, 0xeb, 0x54, 0xf6,
+ 0xa1, 0x90, 0xf9, 0x56, 0xb8, 0xb9, 0x10, 0x06, 0x89, 0xe7, 0x07, 0x44, 0x06, 0x0b, 0x6c, 0x58,
+ 0x92, 0x91, 0x0d, 0xdc, 0xa9, 0x0d, 0xbf, 0xb7, 0x0c, 0xe7, 0xf4, 0x85, 0xca, 0x38, 0x9b, 0xad,
+ 0x70, 0x33, 0xeb, 0x05, 0xa4, 0x95, 0x30, 0x2b, 0x71, 0x7f, 0xe2, 0xc0, 0x99, 0x3e, 0xc2, 0x38,
+ 0xfa, 0xb2, 0x03, 0x13, 0x9b, 0x3f, 0x15, 0x63, 0x33, 0xbb, 0x81, 0xde, 0x07, 0x93, 0x14, 0x40,
+ 0x4f, 0x22, 0xb1, 0x36, 0x0b, 0xa6, 0x87, 0x6a, 0xde, 0x28, 0xc5, 0x99, 0xda, 0xee, 0xaf, 0x17,
+ 0x20, 0x87, 0x0a, 0x7a, 0x12, 0xc6, 0x48, 0x50, 0xef, 0x84, 0x7e, 0x90, 0x08, 0x66, 0xa4, 0xb8,
+ 0xde, 0x05, 0x01, 0xc7, 0xaa, 0x86, 0xd0, 0x3f, 0xc4, 0xc4, 0x14, 0x7a, 0xf4, 0x0f, 0xd1, 0xf3,
+ 0xb4, 0x0e, 0x6a, 0xc0, 0x94, 0xc7, 0xfd, 0x2b, 0x6c, 0xed, 0xb1, 0x65, 0x3a, 0x74, 0x90, 0x65,
+ 0x7a, 0x92, 0xb9, 0x3f, 0x33, 0x28, 0x70, 0x0f, 0x52, 0xf4, 0x6e, 0x28, 0x77, 0x63, 0x52, 0x5d,
+ 0x5c, 0x59, 0x88, 0x48, 0x9d, 0x6b, 0xc5, 0x9a, 0xdf, 0xef, 0x6a, 0x5a, 0x84, 0xf5, 0x7a, 0xee,
+ 0xbf, 0x70, 0x60, 0x74, 0xde, 0xab, 0x6d, 0x87, 0x5b, 0x5b, 0x74, 0x2a, 0xea, 0xdd, 0x28, 0x35,
+ 0x6c, 0x69, 0x53, 0xb1, 0x28, 0xe0, 0x58, 0xd5, 0x40, 0x1b, 0x30, 0xc2, 0x37, 0xbc, 0xd8, 0x76,
+ 0x3f, 0xaf, 0x8d, 0x47, 0xc5, 0xf1, 0xb0, 0xe5, 0xd0, 0x4d, 0xfc, 0xd6, 0x2c, 0x8f, 0xe3, 0x99,
+ 0xbd, 0x14, 0x24, 0x6b, 0x51, 0x35, 0x89, 0xfc, 0xa0, 0x31, 0x0f, 0xf4, 0xb8, 0x58, 0x62, 0x38,
+ 0xb0, 0xc0, 0x45, 0x87, 0xd1, 0xf6, 0x6e, 0x48, 0x72, 0x82, 0xfd, 0xa8, 0x61, 0xac, 0xa6, 0x45,
+ 0x58, 0xaf, 0xe7, 0xfe, 0x91, 0x03, 0xa5, 0x79, 0x2f, 0xf6, 0x6b, 0x7f, 0x81, 0x98, 0xcf, 0x87,
+ 0xa0, 0xb8, 0xe0, 0xd5, 0x9a, 0x04, 0x5d, 0xcd, 0x2a, 0xbd, 0xe5, 0xf3, 0x8f, 0xe7, 0x91, 0x51,
+ 0x0a, 0xb0, 0x4e, 0x69, 0xa2, 0x9f, 0x6a, 0xec, 0xbe, 0xed, 0xc0, 0xe4, 0x42, 0xcb, 0x27, 0x41,
+ 0xb2, 0x40, 0xa2, 0x84, 0x4d, 0x5c, 0x03, 0xa6, 0x6a, 0x0a, 0x72, 0x27, 0x53, 0xc7, 0x56, 0xeb,
+ 0x42, 0x06, 0x05, 0xee, 0x41, 0x8a, 0xea, 0x70, 0x8c, 0xc3, 0xd2, 0x5d, 0x71, 0xa0, 0xf9, 0x63,
+ 0xd6, 0xd1, 0x05, 0x13, 0x03, 0xce, 0xa2, 0x74, 0x7f, 0xec, 0xc0, 0x99, 0x85, 0x56, 0x37, 0x4e,
+ 0x48, 0x74, 0x4d, 0x70, 0x23, 0x29, 0xde, 0xa2, 0x8f, 0xc0, 0x58, 0x5b, 0x7a, 0x6c, 0x9d, 0xdb,
+ 0x2c, 0x60, 0xc6, 0xcf, 0x68, 0x6d, 0xda, 0x99, 0xb5, 0xcd, 0x97, 0x49, 0x2d, 0x59, 0x25, 0x89,
+ 0x97, 0x86, 0x17, 0xa4, 0x30, 0xac, 0xb0, 0xa2, 0x0e, 0x0c, 0xc7, 0x1d, 0x52, 0xb3, 0x17, 0xdd,
+ 0x25, 0xc7, 0x50, 0xed, 0x90, 0x5a, 0xca, 0xd7, 0x99, 0xaf, 0x91, 0x51, 0x72, 0xff, 0xb7, 0x03,
+ 0x0f, 0xf4, 0x19, 0xef, 0x65, 0x3f, 0x4e, 0xd0, 0x4b, 0x3d, 0x63, 0x9e, 0x1d, 0x6c, 0xcc, 0xb4,
+ 0x35, 0x1b, 0xb1, 0x62, 0x08, 0x12, 0xa2, 0x8d, 0xf7, 0xa3, 0x50, 0xf4, 0x13, 0xd2, 0x96, 0x66,
+ 0x68, 0x0b, 0x06, 0xa3, 0x3e, 0x63, 0x99, 0x9f, 0x90, 0x31, 0x7e, 0x97, 0x28, 0x3d, 0xcc, 0xc9,
+ 0xba, 0xdb, 0x30, 0xb2, 0x10, 0xb6, 0xba, 0xed, 0x60, 0xb0, 0x48, 0x99, 0x64, 0xb7, 0x43, 0xb2,
+ 0x67, 0x24, 0x13, 0xff, 0x59, 0x89, 0x34, 0x1c, 0x0d, 0xe5, 0x1b, 0x8e, 0xdc, 0x7f, 0xe9, 0x00,
+ 0xdd, 0x55, 0x75, 0x5f, 0x78, 0x12, 0x39, 0x3a, 0x4e, 0xf0, 0x21, 0x1d, 0xdd, 0xad, 0xbd, 0x99,
+ 0x09, 0x55, 0x51, 0xc3, 0xff, 0x21, 0x18, 0x89, 0x99, 0x4a, 0x2e, 0xfa, 0xb0, 0x24, 0xe5, 0x67,
+ 0xae, 0xa8, 0xdf, 0xda, 0x9b, 0x19, 0x28, 0x6c, 0x73, 0x56, 0xe1, 0x16, 0x4e, 0x4f, 0x81, 0x95,
+ 0x0a, 0x7c, 0x6d, 0x12, 0xc7, 0x5e, 0x43, 0x6a, 0x78, 0x4a, 0xe0, 0x5b, 0xe5, 0x60, 0x2c, 0xcb,
+ 0xdd, 0x2f, 0x39, 0x30, 0xa1, 0x0e, 0x2f, 0x2a, 0xbe, 0xa3, 0x2b, 0xfa, 0x31, 0xc7, 0x57, 0xca,
+ 0x43, 0x7d, 0x38, 0x8e, 0x38, 0xc8, 0xf7, 0x3f, 0x05, 0xdf, 0x05, 0xe3, 0x75, 0xd2, 0x21, 0x41,
+ 0x9d, 0x04, 0x35, 0xaa, 0x7e, 0xd3, 0x15, 0x52, 0x9a, 0x9f, 0xa2, 0xfa, 0xe6, 0xa2, 0x06, 0xc7,
+ 0x46, 0x2d, 0xf7, 0x1b, 0x0e, 0xdc, 0xaf, 0xd0, 0x55, 0x49, 0x82, 0x49, 0x12, 0xed, 0xaa, 0x30,
+ 0xcd, 0x83, 0x9d, 0x56, 0xd7, 0xa8, 0xfc, 0x9b, 0x44, 0x9c, 0xf8, 0x9d, 0x1d, 0x57, 0x65, 0x2e,
+ 0x2d, 0x33, 0x24, 0x58, 0x62, 0x73, 0x7f, 0x75, 0x08, 0x4e, 0xea, 0x9d, 0x54, 0x0c, 0xe6, 0x97,
+ 0x1c, 0x00, 0x35, 0x03, 0xf4, 0x40, 0x1e, 0xb2, 0xe3, 0xbb, 0x32, 0xbe, 0x54, 0xca, 0x82, 0x14,
+ 0x38, 0xc6, 0x1a, 0x59, 0xf4, 0x02, 0x8c, 0xef, 0xd0, 0x4d, 0x41, 0x56, 0xa9, 0xb8, 0x10, 0x57,
+ 0x86, 0x58, 0x37, 0x66, 0xf2, 0x3e, 0xe6, 0xf3, 0x69, 0xbd, 0xd4, 0x1c, 0xa0, 0x01, 0x63, 0x6c,
+ 0xa0, 0xa2, 0x9a, 0xce, 0x44, 0xa4, 0x7f, 0x12, 0x61, 0x13, 0xff, 0xa0, 0xc5, 0x31, 0x66, 0xbf,
+ 0xfa, 0xfc, 0xf1, 0x9b, 0x7b, 0x33, 0x13, 0x06, 0x08, 0x9b, 0x9d, 0x70, 0x5f, 0x00, 0x36, 0x17,
+ 0x7e, 0xd0, 0x25, 0x6b, 0x01, 0x7a, 0x44, 0xda, 0xe8, 0xb8, 0x5f, 0x45, 0x71, 0x0e, 0xdd, 0x4e,
+ 0x47, 0x75, 0xd9, 0x2d, 0xcf, 0x6f, 0xb1, 0xf0, 0x45, 0x5a, 0x4b, 0xe9, 0xb2, 0x4b, 0x0c, 0x8a,
+ 0x45, 0xa9, 0x3b, 0x0b, 0xa3, 0x0b, 0x74, 0xec, 0x24, 0xa2, 0x78, 0xf5, 0xa8, 0xe3, 0x09, 0x23,
+ 0xea, 0x58, 0x46, 0x17, 0x6f, 0xc0, 0xa9, 0x85, 0x88, 0x78, 0x09, 0xa9, 0x3e, 0x3d, 0xdf, 0xad,
+ 0x6d, 0x93, 0x84, 0x87, 0x76, 0xc5, 0xe8, 0xbd, 0x30, 0x11, 0xb2, 0x23, 0xe3, 0x72, 0x58, 0xdb,
+ 0xf6, 0x83, 0x86, 0x30, 0xb9, 0x9e, 0x12, 0x58, 0x26, 0xd6, 0xf4, 0x42, 0x6c, 0xd6, 0x75, 0xff,
+ 0x43, 0x01, 0xc6, 0x17, 0xa2, 0x30, 0x90, 0x6c, 0xf1, 0x08, 0x8e, 0xb2, 0xc4, 0x38, 0xca, 0x2c,
+ 0xb8, 0x3b, 0xf5, 0xfe, 0xf7, 0x3b, 0xce, 0xd0, 0xeb, 0x8a, 0x45, 0x0e, 0xd9, 0x52, 0x41, 0x0c,
+ 0xba, 0x0c, 0x77, 0xfa, 0xb1, 0x4d, 0x06, 0xea, 0xfe, 0x47, 0x07, 0xa6, 0xf4, 0xea, 0x47, 0x70,
+ 0x82, 0xc6, 0xe6, 0x09, 0x7a, 0xc5, 0xee, 0x78, 0xfb, 0x1c, 0x9b, 0xff, 0x6c, 0xd4, 0x1c, 0x27,
+ 0xf3, 0x75, 0x7f, 0xc5, 0x81, 0xf1, 0xeb, 0x1a, 0x40, 0x0c, 0xd6, 0xb6, 0x10, 0xf3, 0x0e, 0xc9,
+ 0x66, 0x74, 0xe8, 0xad, 0xcc, 0x6f, 0x6c, 0xf4, 0x84, 0xf2, 0xfd, 0xb8, 0xd6, 0x24, 0xf5, 0x6e,
+ 0x4b, 0x1e, 0xdf, 0x6a, 0x4a, 0xab, 0x02, 0x8e, 0x55, 0x0d, 0xf4, 0x12, 0x1c, 0xaf, 0x85, 0x41,
+ 0xad, 0x1b, 0x45, 0x24, 0xa8, 0xed, 0xae, 0xb3, 0x3b, 0x12, 0xe2, 0x40, 0x9c, 0x15, 0xcd, 0x8e,
+ 0x2f, 0x64, 0x2b, 0xdc, 0xca, 0x03, 0xe2, 0x5e, 0x44, 0xdc, 0x59, 0x10, 0xd3, 0x23, 0x4b, 0x28,
+ 0x5c, 0x9a, 0xb3, 0x80, 0x81, 0xb1, 0x2c, 0x47, 0x57, 0xe1, 0x4c, 0x9c, 0x78, 0x51, 0xe2, 0x07,
+ 0x8d, 0x45, 0xe2, 0xd5, 0x5b, 0x7e, 0x40, 0x55, 0x89, 0x30, 0xa8, 0x73, 0x57, 0xe2, 0xd0, 0xfc,
+ 0x03, 0x37, 0xf7, 0x66, 0xce, 0x54, 0xf3, 0xab, 0xe0, 0x7e, 0x6d, 0xd1, 0x87, 0x60, 0x5a, 0xb8,
+ 0x23, 0xb6, 0xba, 0xad, 0x67, 0xc3, 0xcd, 0xf8, 0xa2, 0x1f, 0x53, 0x3d, 0xfe, 0xb2, 0xdf, 0xf6,
+ 0x13, 0xe6, 0x30, 0x2c, 0xce, 0x9f, 0xbd, 0xb9, 0x37, 0x33, 0x5d, 0xed, 0x5b, 0x0b, 0xef, 0x83,
+ 0x01, 0x61, 0x38, 0xcd, 0x99, 0x5f, 0x0f, 0xee, 0x51, 0x86, 0x7b, 0xfa, 0xe6, 0xde, 0xcc, 0xe9,
+ 0xa5, 0xdc, 0x1a, 0xb8, 0x4f, 0x4b, 0xfa, 0x05, 0x13, 0xbf, 0x4d, 0x5e, 0x0d, 0x03, 0xc2, 0x02,
+ 0x55, 0xb4, 0x2f, 0xb8, 0x21, 0xe0, 0x58, 0xd5, 0x40, 0x2f, 0xa7, 0x2b, 0x91, 0x6e, 0x17, 0x11,
+ 0x70, 0x72, 0x70, 0x0e, 0xc7, 0x54, 0x93, 0x6b, 0x1a, 0x26, 0x16, 0x49, 0x69, 0xe0, 0x46, 0x9f,
+ 0x70, 0x60, 0x3c, 0x4e, 0x42, 0x75, 0xaf, 0x41, 0x44, 0x9c, 0x58, 0x58, 0xf6, 0x55, 0x0d, 0x2b,
+ 0x17, 0x7c, 0x74, 0x08, 0x36, 0xa8, 0xa2, 0x9f, 0x83, 0x92, 0x5c, 0xc0, 0x71, 0xa5, 0xcc, 0x64,
+ 0x25, 0xa6, 0xc6, 0xc9, 0xf5, 0x1d, 0xe3, 0xb4, 0xdc, 0xfd, 0xd1, 0x10, 0xa0, 0x5e, 0xb6, 0x86,
+ 0x56, 0x60, 0xc4, 0xab, 0x25, 0xfe, 0x8e, 0x8c, 0x26, 0x7c, 0x24, 0xef, 0xc8, 0xe7, 0xd3, 0x83,
+ 0xc9, 0x16, 0xa1, 0xab, 0x9a, 0xa4, 0xbc, 0x70, 0x8e, 0x35, 0xc5, 0x02, 0x05, 0x0a, 0xe1, 0x78,
+ 0xcb, 0x8b, 0x13, 0x49, 0xbf, 0x4e, 0x3f, 0x93, 0x38, 0x0c, 0x7e, 0x76, 0xb0, 0x0f, 0x41, 0x5b,
+ 0xcc, 0x9f, 0xa2, 0xbb, 0xed, 0x72, 0x16, 0x11, 0xee, 0xc5, 0x8d, 0x3e, 0xc6, 0x64, 0x27, 0x2e,
+ 0xd8, 0x4a, 0xa1, 0x65, 0xc5, 0x8a, 0x5c, 0xc1, 0x71, 0x1a, 0x72, 0x93, 0x20, 0x83, 0x35, 0x92,
+ 0xe8, 0x1c, 0x94, 0xd8, 0xae, 0x20, 0x75, 0xc2, 0xf7, 0xf6, 0x50, 0x2a, 0xe2, 0x56, 0x65, 0x01,
+ 0x4e, 0xeb, 0x68, 0x32, 0x04, 0xdf, 0xce, 0x7d, 0x64, 0x08, 0xf4, 0x0c, 0x14, 0x3b, 0x4d, 0x2f,
+ 0x96, 0x11, 0xea, 0xae, 0xe4, 0xc9, 0xeb, 0x14, 0xc8, 0x18, 0x8f, 0xf6, 0x2d, 0x19, 0x10, 0xf3,
+ 0x06, 0xee, 0xbf, 0x02, 0x18, 0x5d, 0x9c, 0x5b, 0xde, 0xf0, 0xe2, 0xed, 0x01, 0x34, 0x1c, 0xba,
+ 0xc9, 0x84, 0x28, 0x9a, 0x65, 0x93, 0x52, 0x44, 0xc5, 0xaa, 0x06, 0x0a, 0x60, 0xc4, 0x0f, 0x28,
+ 0x5f, 0xa9, 0x4c, 0xda, 0xf2, 0x22, 0x28, 0x6d, 0x8d, 0x99, 0x79, 0x2e, 0x31, 0xec, 0x58, 0x50,
+ 0x41, 0xaf, 0x43, 0xc9, 0x93, 0x17, 0x84, 0xc4, 0xe9, 0xbe, 0x62, 0xc3, 0x3c, 0x2e, 0x50, 0xea,
+ 0x01, 0x4a, 0x02, 0x84, 0x53, 0x82, 0xe8, 0xe3, 0x0e, 0x94, 0xe5, 0xd0, 0x31, 0xd9, 0x12, 0x9e,
+ 0xeb, 0x55, 0x7b, 0x63, 0xc6, 0x64, 0x8b, 0x47, 0xaf, 0x68, 0x00, 0xac, 0x93, 0xec, 0xd1, 0x88,
+ 0x8a, 0x83, 0x68, 0x44, 0xe8, 0x3a, 0x94, 0xae, 0xfb, 0x49, 0x93, 0x9d, 0xdf, 0xc2, 0x63, 0xb6,
+ 0x74, 0xf7, 0xbd, 0xa6, 0xe8, 0xd2, 0x19, 0xbb, 0x26, 0x09, 0xe0, 0x94, 0x16, 0xdd, 0x0e, 0xf4,
+ 0x07, 0xbb, 0x60, 0xc5, 0x38, 0x7f, 0xc9, 0x6c, 0xc0, 0x0a, 0x70, 0x5a, 0x87, 0x4e, 0xf1, 0x38,
+ 0xfd, 0x55, 0x25, 0xaf, 0x74, 0x29, 0x6b, 0x11, 0x11, 0x89, 0x16, 0xd6, 0x95, 0xc4, 0xc8, 0x27,
+ 0xeb, 0x9a, 0x46, 0x03, 0x1b, 0x14, 0xe9, 0x1e, 0xb9, 0xde, 0x24, 0x81, 0xb8, 0x31, 0xa1, 0xf6,
+ 0xc8, 0xb5, 0x26, 0x09, 0x30, 0x2b, 0x41, 0xaf, 0x73, 0x0d, 0x8d, 0xab, 0x0a, 0x82, 0xd7, 0x5f,
+ 0xb6, 0xa3, 0xbd, 0x70, 0x9c, 0xfc, 0xd2, 0x42, 0xfa, 0x1b, 0x6b, 0xf4, 0x28, 0xc7, 0x08, 0x83,
+ 0x0b, 0x37, 0xfc, 0x44, 0x5c, 0xb5, 0x50, 0x1c, 0x63, 0x8d, 0x41, 0xb1, 0x28, 0xe5, 0x91, 0x19,
+ 0x74, 0x11, 0xc4, 0xec, 0x5e, 0x45, 0x49, 0x8f, 0xcc, 0x60, 0x60, 0x2c, 0xcb, 0xd1, 0xdf, 0x77,
+ 0xa0, 0xd8, 0x0c, 0xc3, 0xed, 0xb8, 0x32, 0xc1, 0x16, 0x87, 0x05, 0x89, 0x59, 0x70, 0x9c, 0xd9,
+ 0x8b, 0x14, 0xad, 0x79, 0x79, 0xac, 0xc8, 0x60, 0xb7, 0xf6, 0x66, 0x26, 0x2f, 0xfb, 0x5b, 0xa4,
+ 0xb6, 0x5b, 0x6b, 0x11, 0x06, 0x79, 0xf3, 0x6d, 0x0d, 0x72, 0x61, 0x87, 0x04, 0x09, 0xe6, 0xbd,
+ 0x9a, 0xfe, 0xac, 0x03, 0x90, 0x22, 0xca, 0x71, 0x81, 0x12, 0x33, 0x68, 0xc0, 0x82, 0xba, 0x6c,
+ 0x74, 0x4d, 0xf7, 0xa9, 0xfe, 0x6b, 0x07, 0xca, 0x74, 0x70, 0x92, 0x05, 0x3e, 0x06, 0x23, 0x89,
+ 0x17, 0x35, 0x88, 0x74, 0x03, 0xa8, 0xcf, 0xb1, 0xc1, 0xa0, 0x58, 0x94, 0xa2, 0x00, 0x8a, 0x89,
+ 0x17, 0x6f, 0x4b, 0x21, 0xfd, 0x92, 0xb5, 0x29, 0x4e, 0xe5, 0x73, 0xfa, 0x2b, 0xc6, 0x9c, 0x0c,
+ 0x7a, 0x1c, 0xc6, 0xe8, 0xd1, 0xb1, 0xe4, 0xc5, 0x32, 0x32, 0x67, 0x9c, 0x32, 0xf1, 0x25, 0x01,
+ 0xc3, 0xaa, 0xd4, 0xfd, 0xf5, 0x02, 0x0c, 0x2f, 0x72, 0x75, 0x6d, 0x24, 0x0e, 0xbb, 0x51, 0x8d,
+ 0x08, 0xb1, 0xdd, 0xc2, 0x9a, 0xa6, 0x78, 0xab, 0x0c, 0xa7, 0xa6, 0x30, 0xb1, 0xdf, 0x58, 0xd0,
+ 0x42, 0x5f, 0x74, 0x60, 0x32, 0x89, 0xbc, 0x20, 0xde, 0x62, 0x0e, 0x17, 0x3f, 0x0c, 0xc4, 0x14,
+ 0x59, 0x58, 0x85, 0x1b, 0x06, 0xde, 0x6a, 0x42, 0x3a, 0xa9, 0xdf, 0xc7, 0x2c, 0xc3, 0x99, 0x3e,
+ 0xb8, 0xbf, 0xe1, 0x00, 0xa4, 0xbd, 0x47, 0x9f, 0x71, 0x60, 0xc2, 0xd3, 0x23, 0x42, 0xc5, 0x1c,
+ 0xad, 0xd9, 0xf3, 0xce, 0x32, 0xb4, 0xdc, 0x52, 0x61, 0x80, 0xb0, 0x49, 0xd8, 0x7d, 0x37, 0x14,
+ 0xd9, 0xee, 0x60, 0x2a, 0x8d, 0xb0, 0x6c, 0x67, 0x4d, 0x59, 0xd2, 0xe2, 0x8d, 0x55, 0x0d, 0xf7,
+ 0x25, 0x98, 0xbc, 0x70, 0x83, 0xd4, 0xba, 0x49, 0x18, 0x71, 0xbb, 0x7e, 0x9f, 0x1b, 0x40, 0xce,
+ 0x1d, 0xdd, 0x00, 0xfa, 0xb6, 0x03, 0x65, 0x2d, 0x3c, 0x90, 0x9e, 0xd4, 0x8d, 0x85, 0x2a, 0x37,
+ 0x5f, 0x88, 0xa9, 0x5a, 0xb1, 0x12, 0x80, 0xc8, 0x51, 0xa6, 0xc7, 0x88, 0x02, 0xe1, 0x94, 0xe0,
+ 0x6d, 0xc2, 0xf7, 0xdc, 0x3f, 0x70, 0xe0, 0x54, 0x6e, 0x2c, 0xe3, 0x3d, 0xee, 0xb6, 0xe1, 0x42,
+ 0x2f, 0x0c, 0xe0, 0x42, 0xff, 0x1d, 0x07, 0x52, 0x4c, 0x94, 0x15, 0x6d, 0xa6, 0x3d, 0xd7, 0x58,
+ 0x91, 0xa0, 0x24, 0x4a, 0xd1, 0xeb, 0x70, 0xc6, 0xfc, 0x82, 0x77, 0xe8, 0x4d, 0xe1, 0xaa, 0x67,
+ 0x3e, 0x26, 0xdc, 0x8f, 0x84, 0xfb, 0x55, 0x07, 0x8a, 0xcb, 0x5e, 0xb7, 0x41, 0x06, 0x32, 0x86,
+ 0x51, 0x3e, 0x16, 0x11, 0xaf, 0x95, 0x48, 0xd5, 0x41, 0xf0, 0x31, 0x2c, 0x60, 0x58, 0x95, 0xa2,
+ 0x39, 0x28, 0x85, 0x1d, 0x62, 0x78, 0x00, 0x1f, 0x91, 0xb3, 0xb7, 0x26, 0x0b, 0xe8, 0xb1, 0xc3,
+ 0xa8, 0x2b, 0x08, 0x4e, 0x5b, 0xb9, 0xdf, 0x2f, 0x42, 0x59, 0xbb, 0xf5, 0x42, 0x65, 0x81, 0x88,
+ 0x74, 0xc2, 0xac, 0xbc, 0x4c, 0x17, 0x0c, 0x66, 0x25, 0x74, 0x0f, 0x46, 0x64, 0xc7, 0x8f, 0x39,
+ 0xdb, 0x32, 0xf6, 0x20, 0x16, 0x70, 0xac, 0x6a, 0xa0, 0x19, 0x28, 0xd6, 0x49, 0x27, 0x69, 0xb2,
+ 0xee, 0x0d, 0xf3, 0xd0, 0xbf, 0x45, 0x0a, 0xc0, 0x1c, 0x4e, 0x2b, 0x6c, 0x91, 0xa4, 0xd6, 0x64,
+ 0x76, 0x5f, 0x11, 0x1b, 0xb8, 0x44, 0x01, 0x98, 0xc3, 0x73, 0x7c, 0x94, 0xc5, 0xc3, 0xf7, 0x51,
+ 0x8e, 0x58, 0xf6, 0x51, 0xa2, 0x0e, 0x9c, 0x88, 0xe3, 0xe6, 0x7a, 0xe4, 0xef, 0x78, 0x09, 0x49,
+ 0x57, 0xdf, 0xe8, 0x41, 0xe8, 0x9c, 0x61, 0xf7, 0xd0, 0xab, 0x17, 0xb3, 0x58, 0x70, 0x1e, 0x6a,
+ 0x54, 0x85, 0x53, 0x7e, 0x10, 0x93, 0x5a, 0x37, 0x22, 0x97, 0x1a, 0x41, 0x18, 0x91, 0x8b, 0x61,
+ 0x4c, 0xd1, 0x89, 0x5b, 0xb4, 0x2a, 0x5a, 0xf6, 0x52, 0x5e, 0x25, 0x9c, 0xdf, 0x16, 0x2d, 0xc3,
+ 0xf1, 0xba, 0x1f, 0x7b, 0x9b, 0x2d, 0x52, 0xed, 0x6e, 0xb6, 0x43, 0xae, 0x78, 0x97, 0x18, 0xc2,
+ 0xfb, 0xa5, 0x95, 0x68, 0x31, 0x5b, 0x01, 0xf7, 0xb6, 0x41, 0xcf, 0xc0, 0x78, 0xec, 0x07, 0x8d,
+ 0x16, 0x99, 0x8f, 0xbc, 0xa0, 0xd6, 0x14, 0xd7, 0x6f, 0x95, 0x35, 0xbd, 0xaa, 0x95, 0x61, 0xa3,
+ 0x26, 0xdb, 0xf3, 0xbc, 0x4d, 0x46, 0x1a, 0x14, 0xb5, 0x45, 0xa9, 0xfb, 0x03, 0x07, 0xc6, 0xf5,
+ 0x48, 0x75, 0x2a, 0x69, 0x43, 0x73, 0x71, 0xa9, 0xca, 0xcf, 0x02, 0x7b, 0x27, 0xfe, 0x45, 0x85,
+ 0x33, 0x55, 0x96, 0x53, 0x18, 0xd6, 0x68, 0x0e, 0x70, 0xef, 0xfc, 0x11, 0x28, 0x6e, 0x85, 0x54,
+ 0x20, 0x19, 0x32, 0xcd, 0xf0, 0x4b, 0x14, 0x88, 0x79, 0x99, 0xfb, 0x3f, 0x1c, 0x38, 0x9d, 0x1f,
+ 0x84, 0xff, 0xd3, 0x30, 0xc8, 0xf3, 0x00, 0x74, 0x28, 0x06, 0x53, 0xd7, 0x32, 0x4f, 0xc8, 0x12,
+ 0xac, 0xd5, 0x1a, 0x6c, 0xd8, 0x7f, 0x46, 0x85, 0xe2, 0x94, 0xce, 0xe7, 0x1c, 0x98, 0xa0, 0x64,
+ 0x57, 0xa2, 0x4d, 0x63, 0xb4, 0x6b, 0x76, 0x46, 0xab, 0xd0, 0xa6, 0xde, 0x06, 0x03, 0x8c, 0x4d,
+ 0xe2, 0xe8, 0xe7, 0xa0, 0xe4, 0xd5, 0xeb, 0x11, 0x89, 0x63, 0xe5, 0xb7, 0x63, 0xb6, 0xa8, 0x39,
+ 0x09, 0xc4, 0x69, 0x39, 0x65, 0xa2, 0xcd, 0xfa, 0x56, 0x4c, 0xf9, 0x92, 0x60, 0xdc, 0x8a, 0x89,
+ 0x52, 0x22, 0x14, 0x8e, 0x55, 0x0d, 0xf7, 0x57, 0x86, 0xc1, 0xa4, 0x8d, 0xea, 0x70, 0x6c, 0x3b,
+ 0xda, 0x5c, 0x60, 0x61, 0x0f, 0x77, 0x12, 0x7e, 0xc0, 0xc2, 0x02, 0x56, 0x4c, 0x0c, 0x38, 0x8b,
+ 0x52, 0x50, 0x59, 0x21, 0xbb, 0x89, 0xb7, 0x79, 0xc7, 0xc1, 0x07, 0x2b, 0x26, 0x06, 0x9c, 0x45,
+ 0x89, 0xde, 0x0d, 0xe5, 0xed, 0x68, 0x53, 0xb2, 0xe8, 0x6c, 0x24, 0xcb, 0x4a, 0x5a, 0x84, 0xf5,
+ 0x7a, 0x74, 0x0a, 0xb7, 0xa3, 0x4d, 0x7a, 0x2a, 0xca, 0x3c, 0x0c, 0x6a, 0x0a, 0x57, 0x04, 0x1c,
+ 0xab, 0x1a, 0xa8, 0x03, 0x68, 0x5b, 0xce, 0x9e, 0x0a, 0xf2, 0x10, 0x27, 0xc9, 0xe0, 0x31, 0x22,
+ 0x2c, 0xba, 0x7e, 0xa5, 0x07, 0x0f, 0xce, 0xc1, 0x8d, 0x5e, 0x80, 0x33, 0xdb, 0xd1, 0xa6, 0x10,
+ 0x16, 0xd6, 0x23, 0x3f, 0xa8, 0xf9, 0x1d, 0x23, 0xe7, 0xc2, 0x8c, 0xe8, 0xee, 0x99, 0x95, 0xfc,
+ 0x6a, 0xb8, 0x5f, 0x7b, 0xf7, 0x77, 0x87, 0x81, 0xdd, 0x16, 0xa5, 0xbc, 0xb0, 0x4d, 0x92, 0x66,
+ 0x58, 0xcf, 0xca, 0x3f, 0xab, 0x0c, 0x8a, 0x45, 0xa9, 0x8c, 0x21, 0x2d, 0xf4, 0x89, 0x21, 0xbd,
+ 0x0e, 0xa3, 0x4d, 0xe2, 0xd5, 0x49, 0x24, 0x2d, 0x88, 0x97, 0xed, 0xdc, 0x6f, 0xbd, 0xc8, 0x90,
+ 0xa6, 0x6a, 0x38, 0xff, 0x1d, 0x63, 0x49, 0x0d, 0xbd, 0x07, 0x26, 0xa9, 0x20, 0x13, 0x76, 0x13,
+ 0x69, 0xe2, 0xe7, 0x16, 0x44, 0x76, 0xa2, 0x6e, 0x18, 0x25, 0x38, 0x53, 0x13, 0x2d, 0xc2, 0x94,
+ 0x30, 0xc7, 0x2b, 0xcb, 0xa4, 0x98, 0x58, 0x95, 0x0c, 0xa3, 0x9a, 0x29, 0xc7, 0x3d, 0x2d, 0x58,
+ 0x0c, 0x60, 0x58, 0xe7, 0x1e, 0x59, 0x3d, 0x06, 0x30, 0xac, 0xef, 0x62, 0x56, 0x82, 0x5e, 0x85,
+ 0x31, 0xfa, 0x77, 0x29, 0x0a, 0xdb, 0xc2, 0x36, 0xb3, 0x6e, 0x67, 0x76, 0x28, 0x0d, 0xa1, 0x29,
+ 0x32, 0x01, 0x6f, 0x5e, 0x50, 0xc1, 0x8a, 0x1e, 0xd5, 0x57, 0xe4, 0x39, 0x5c, 0xdd, 0xf6, 0x3b,
+ 0xcf, 0x93, 0xc8, 0xdf, 0xda, 0x65, 0x42, 0xc3, 0x58, 0xaa, 0xaf, 0x5c, 0xea, 0xa9, 0x81, 0x73,
+ 0x5a, 0xb9, 0x9f, 0x2b, 0xc0, 0xb8, 0x7e, 0xe9, 0xf8, 0x76, 0x81, 0xc5, 0x71, 0xba, 0x28, 0xb8,
+ 0x76, 0x7a, 0xd1, 0xc2, 0xb0, 0x6f, 0xb7, 0x20, 0x9a, 0x30, 0xec, 0x75, 0x85, 0xb4, 0x68, 0xc5,
+ 0x08, 0xc6, 0x46, 0xdc, 0x4d, 0x9a, 0xfc, 0x76, 0x1a, 0x0b, 0xf9, 0x65, 0x14, 0xdc, 0x4f, 0x0e,
+ 0xc1, 0x98, 0x2c, 0x44, 0x9f, 0x70, 0x00, 0xd2, 0xd0, 0x2b, 0xc1, 0x4a, 0xd7, 0x6d, 0xc4, 0xe5,
+ 0xe8, 0x51, 0x63, 0x9a, 0x2d, 0x5d, 0xc1, 0xb1, 0x46, 0x17, 0x25, 0x30, 0x12, 0xd2, 0xce, 0x9d,
+ 0xb7, 0x77, 0x71, 0x7e, 0x8d, 0x12, 0x3e, 0xcf, 0xa8, 0xa7, 0x66, 0x33, 0x06, 0xc3, 0x82, 0x16,
+ 0xd5, 0x00, 0x37, 0x65, 0x44, 0xa0, 0x3d, 0x13, 0xb3, 0x0a, 0x32, 0x4c, 0x15, 0x3a, 0x05, 0xc2,
+ 0x29, 0x41, 0xf7, 0x29, 0x98, 0x34, 0x37, 0x03, 0xd5, 0x08, 0x36, 0x77, 0x13, 0xc2, 0xed, 0x0d,
+ 0xe3, 0x5c, 0x23, 0x98, 0xa7, 0x00, 0xcc, 0xe1, 0xee, 0xf7, 0xa8, 0x1c, 0xa0, 0xd8, 0xcb, 0x00,
+ 0x26, 0xfe, 0x47, 0x74, 0x63, 0x59, 0x3f, 0xb5, 0xeb, 0x63, 0x50, 0x62, 0xff, 0xb0, 0x8d, 0x3e,
+ 0x64, 0xcb, 0x7f, 0x9f, 0xf6, 0x53, 0x6c, 0x75, 0x26, 0x13, 0x3c, 0x2f, 0x09, 0xe1, 0x94, 0xa6,
+ 0x1b, 0xc2, 0x54, 0xb6, 0x36, 0xfa, 0x20, 0x8c, 0xc7, 0xf2, 0x58, 0x4d, 0xaf, 0xd0, 0x0d, 0x78,
+ 0xfc, 0x72, 0xef, 0x99, 0xd6, 0x1c, 0x1b, 0xc8, 0xdc, 0x35, 0x18, 0xb1, 0x3a, 0x85, 0xee, 0xb7,
+ 0x1c, 0x28, 0x31, 0x07, 0x66, 0x23, 0xf2, 0xda, 0x69, 0x93, 0xa1, 0x7d, 0x66, 0x3d, 0x86, 0x51,
+ 0xae, 0xa3, 0xcb, 0xc0, 0x1f, 0x0b, 0x5c, 0x86, 0xe7, 0xbb, 0x4b, 0xb9, 0x0c, 0x37, 0x06, 0xc4,
+ 0x58, 0x52, 0x72, 0x3f, 0x55, 0x80, 0x91, 0x4b, 0x41, 0xa7, 0xfb, 0x97, 0x3e, 0xe7, 0xda, 0x2a,
+ 0x0c, 0x5f, 0x4a, 0x48, 0xdb, 0x4c, 0x0d, 0x38, 0x3e, 0xff, 0xa8, 0x9e, 0x16, 0xb0, 0x62, 0xa6,
+ 0x05, 0xc4, 0xde, 0x75, 0x19, 0x17, 0x27, 0x6c, 0xc4, 0xe9, 0x35, 0xc2, 0x27, 0xa1, 0x74, 0xd9,
+ 0xdb, 0x24, 0xad, 0x15, 0xb2, 0xcb, 0x2e, 0xfd, 0xf1, 0x18, 0x0d, 0x27, 0x55, 0xec, 0x8d, 0x78,
+ 0x8a, 0x45, 0x98, 0x64, 0xb5, 0xd5, 0x66, 0xa0, 0x9a, 0x03, 0x49, 0xf3, 0x2a, 0x39, 0xa6, 0xe6,
+ 0xa0, 0xe5, 0x54, 0xd2, 0x6a, 0xb9, 0xb3, 0x50, 0x4e, 0xb1, 0x0c, 0x40, 0xf5, 0x27, 0x05, 0x98,
+ 0x30, 0x4c, 0xdd, 0x86, 0x03, 0xd0, 0xb9, 0xad, 0x03, 0xd0, 0x70, 0xc8, 0x15, 0xee, 0xb5, 0x43,
+ 0x6e, 0xe8, 0xe8, 0x1d, 0x72, 0xe6, 0x47, 0x1a, 0x1e, 0xe8, 0x23, 0xb5, 0x60, 0xf8, 0xb2, 0x1f,
+ 0x6c, 0x0f, 0xc6, 0x67, 0xe2, 0x5a, 0xd8, 0xe9, 0xe1, 0x33, 0x55, 0x0a, 0xc4, 0xbc, 0x4c, 0x4a,
+ 0x2e, 0x43, 0xf9, 0x92, 0x8b, 0xfb, 0x09, 0x07, 0xc6, 0x57, 0xbd, 0xc0, 0xdf, 0x22, 0x71, 0xc2,
+ 0xd6, 0x55, 0x72, 0xa8, 0x97, 0xbf, 0xc6, 0xfb, 0xa4, 0x31, 0x78, 0xd3, 0x81, 0xe3, 0xab, 0xa4,
+ 0x1d, 0xfa, 0xaf, 0x7a, 0x69, 0xd8, 0x29, 0xed, 0x7b, 0xd3, 0x4f, 0x44, 0x94, 0x9d, 0xea, 0xfb,
+ 0x45, 0x3f, 0xc1, 0x14, 0x7e, 0x1b, 0x3b, 0x2e, 0xbb, 0x56, 0x41, 0x15, 0x34, 0xed, 0x42, 0x62,
+ 0x1a, 0x50, 0x2a, 0x0b, 0x70, 0x5a, 0xc7, 0xfd, 0x3d, 0x07, 0x46, 0x79, 0x27, 0x54, 0xa4, 0xae,
+ 0xd3, 0x07, 0x77, 0x13, 0x8a, 0xac, 0x9d, 0x58, 0xd5, 0xcb, 0x16, 0xc4, 0x1f, 0x8a, 0x8e, 0xef,
+ 0x41, 0xf6, 0x2f, 0xe6, 0x04, 0x98, 0xda, 0xe2, 0xdd, 0x98, 0x53, 0x11, 0xb7, 0xa9, 0xda, 0xc2,
+ 0xa0, 0x58, 0x94, 0xba, 0x5f, 0x1b, 0x82, 0x31, 0x95, 0xbd, 0x8b, 0xe5, 0x56, 0x08, 0x82, 0x30,
+ 0xf1, 0x78, 0xac, 0x03, 0xe7, 0xd5, 0x1f, 0xb4, 0x97, 0x3d, 0x6c, 0x76, 0x2e, 0xc5, 0xce, 0xfd,
+ 0x77, 0x4a, 0x09, 0xd5, 0x4a, 0xb0, 0xde, 0x09, 0xf4, 0x51, 0x18, 0x69, 0x51, 0xee, 0x23, 0x59,
+ 0xf7, 0xf3, 0x16, 0xbb, 0xc3, 0xd8, 0x9a, 0xe8, 0x89, 0x9a, 0x21, 0x0e, 0xc4, 0x82, 0xea, 0xf4,
+ 0xfb, 0x60, 0x2a, 0xdb, 0xeb, 0xdb, 0xdd, 0x97, 0x2c, 0xe9, 0xb7, 0x2d, 0xff, 0xba, 0xe0, 0x9e,
+ 0x07, 0x6f, 0xea, 0x3e, 0x07, 0xe5, 0x55, 0x92, 0x44, 0x7e, 0x8d, 0x21, 0xb8, 0xdd, 0xe2, 0x1a,
+ 0x48, 0x7e, 0xf8, 0x34, 0x5b, 0xac, 0x14, 0x67, 0x8c, 0x5e, 0x07, 0xe8, 0x44, 0x21, 0xd5, 0x5f,
+ 0x49, 0x57, 0x7e, 0x6c, 0x0b, 0xf2, 0xf0, 0xba, 0xc2, 0xc9, 0x5d, 0xce, 0xe9, 0x6f, 0xac, 0xd1,
+ 0x73, 0x5f, 0x84, 0xe2, 0x6a, 0x37, 0x21, 0x37, 0x06, 0xe0, 0x58, 0x07, 0x4d, 0x20, 0xe0, 0x7e,
+ 0x10, 0xc6, 0x19, 0xee, 0x8b, 0x61, 0x8b, 0x1e, 0xab, 0x74, 0x6a, 0xda, 0xf4, 0x77, 0xd6, 0x29,
+ 0xc0, 0x2a, 0x61, 0x5e, 0x46, 0xb7, 0x4c, 0x33, 0x6c, 0xd5, 0xd5, 0x65, 0x2a, 0xb5, 0x20, 0x2e,
+ 0x32, 0x28, 0x16, 0xa5, 0xee, 0x2f, 0x15, 0xa0, 0xcc, 0x1a, 0x0a, 0x76, 0xb3, 0x0b, 0xa3, 0x4d,
+ 0x4e, 0x47, 0xcc, 0xa1, 0x85, 0x10, 0x2d, 0xbd, 0xf7, 0x9a, 0x2e, 0xc7, 0x01, 0x58, 0xd2, 0xa3,
+ 0xa4, 0xaf, 0x7b, 0x7e, 0x42, 0x49, 0x17, 0x0e, 0x97, 0xf4, 0x35, 0x4e, 0x06, 0x4b, 0x7a, 0xee,
+ 0x2f, 0x02, 0xbb, 0xa4, 0xbc, 0xd4, 0xf2, 0x1a, 0x7c, 0xe6, 0xc2, 0x6d, 0x52, 0x17, 0x3c, 0x57,
+ 0x9b, 0x39, 0x0a, 0xc5, 0xa2, 0x94, 0x5f, 0xfc, 0x4c, 0x22, 0x5f, 0x05, 0x37, 0x6b, 0x17, 0x3f,
+ 0x19, 0x58, 0x86, 0xb2, 0xd7, 0xdd, 0x2f, 0x15, 0x00, 0x58, 0xae, 0x37, 0x7e, 0xb7, 0xf8, 0xe7,
+ 0x65, 0xa4, 0x92, 0xe9, 0x48, 0x54, 0x91, 0x4a, 0xec, 0xf6, 0xb4, 0x1e, 0xa1, 0xa4, 0xdf, 0x39,
+ 0x28, 0xec, 0x7f, 0xe7, 0x00, 0x75, 0x60, 0x34, 0xec, 0x26, 0x54, 0x56, 0x15, 0x87, 0xbd, 0x05,
+ 0x3f, 0xfa, 0x1a, 0x47, 0xc8, 0x03, 0xf5, 0xc5, 0x0f, 0x2c, 0xc9, 0xa0, 0x67, 0x60, 0xac, 0x13,
+ 0x85, 0x0d, 0x7a, 0x76, 0x8b, 0xe3, 0xfd, 0x41, 0x29, 0x0f, 0xad, 0x0b, 0xf8, 0x2d, 0xed, 0x7f,
+ 0xac, 0x6a, 0xbb, 0x7f, 0x3c, 0xc5, 0xe7, 0x45, 0xac, 0xbd, 0x69, 0x28, 0xf8, 0xd2, 0x32, 0x05,
+ 0x02, 0x45, 0xe1, 0xd2, 0x22, 0x2e, 0xf8, 0x75, 0xb5, 0xaf, 0x0a, 0x7d, 0xf7, 0xd5, 0xbb, 0xa1,
+ 0x5c, 0xf7, 0xe3, 0x4e, 0xcb, 0xdb, 0xbd, 0x92, 0x63, 0x16, 0x5c, 0x4c, 0x8b, 0xb0, 0x5e, 0x0f,
+ 0x3d, 0x29, 0x6e, 0x98, 0x0c, 0x1b, 0xa6, 0x20, 0x79, 0xc3, 0x24, 0xbd, 0xbb, 0xce, 0x2f, 0x97,
+ 0x64, 0xef, 0xf8, 0x17, 0x07, 0xbe, 0xe3, 0x9f, 0x95, 0xc4, 0x46, 0x8e, 0x5e, 0x12, 0x7b, 0x2f,
+ 0x4c, 0xc8, 0x9f, 0x4c, 0x3c, 0xaa, 0x9c, 0x64, 0xbd, 0x57, 0xe6, 0xea, 0x0d, 0xbd, 0x10, 0x9b,
+ 0x75, 0xd3, 0x45, 0x3b, 0x3a, 0xe8, 0xa2, 0x3d, 0x0f, 0xb0, 0x19, 0x76, 0x83, 0xba, 0x17, 0xed,
+ 0x5e, 0x5a, 0x14, 0xf1, 0xa8, 0x4a, 0xf0, 0x9b, 0x57, 0x25, 0x58, 0xab, 0xa5, 0x2f, 0xf4, 0xd2,
+ 0x6d, 0x16, 0xfa, 0x07, 0xa1, 0xc4, 0x62, 0x77, 0x49, 0x7d, 0x2e, 0x11, 0x21, 0x46, 0x07, 0x09,
+ 0x99, 0x4c, 0x83, 0x0e, 0x25, 0x12, 0x9c, 0xe2, 0x43, 0x1f, 0x02, 0xd8, 0xf2, 0x03, 0x3f, 0x6e,
+ 0x32, 0xec, 0xe5, 0x03, 0x63, 0x57, 0xe3, 0x5c, 0x52, 0x58, 0xb0, 0x86, 0x11, 0xbd, 0x04, 0xc7,
+ 0x49, 0x9c, 0xf8, 0x6d, 0x2f, 0x21, 0x75, 0x75, 0x27, 0xb3, 0xc2, 0x6c, 0x99, 0x2a, 0x7a, 0xfa,
+ 0x42, 0xb6, 0xc2, 0xad, 0x3c, 0x20, 0xee, 0x45, 0x64, 0xec, 0xc8, 0xe9, 0x83, 0xec, 0x48, 0xf4,
+ 0xbf, 0x1c, 0x38, 0x1e, 0x11, 0x1e, 0x77, 0x12, 0xab, 0x8e, 0x9d, 0x62, 0xec, 0xb8, 0x66, 0x23,
+ 0x8d, 0xba, 0xca, 0x97, 0x82, 0xb3, 0x54, 0xb8, 0xe0, 0x42, 0xe4, 0xe8, 0x7b, 0xca, 0x6f, 0xe5,
+ 0x01, 0xdf, 0x7c, 0x7b, 0x66, 0xa6, 0x37, 0x9d, 0xbf, 0x42, 0x4e, 0x77, 0xde, 0xdf, 0x7e, 0x7b,
+ 0x66, 0x4a, 0xfe, 0x4e, 0x27, 0xad, 0x67, 0x90, 0xf4, 0x58, 0xed, 0x84, 0xf5, 0x4b, 0xeb, 0x22,
+ 0x16, 0x4c, 0x1d, 0xab, 0xeb, 0x14, 0x88, 0x79, 0x19, 0x7a, 0x1c, 0xc6, 0xea, 0x1e, 0x69, 0x87,
+ 0x81, 0x4a, 0x88, 0xcb, 0xa4, 0xf9, 0x45, 0x01, 0xc3, 0xaa, 0x94, 0xea, 0x10, 0x81, 0x38, 0x52,
+ 0x2a, 0x0f, 0xd8, 0xd2, 0x21, 0xe4, 0x21, 0xc5, 0xa9, 0xca, 0x5f, 0x58, 0x51, 0x42, 0x2d, 0x18,
+ 0xf1, 0x99, 0xa1, 0x42, 0x84, 0x9b, 0x5a, 0xb0, 0x8e, 0x70, 0xc3, 0x87, 0x0c, 0x36, 0x65, 0xac,
+ 0x5f, 0xd0, 0xd0, 0xcf, 0x9a, 0x63, 0x47, 0x73, 0xd6, 0x3c, 0x0e, 0x63, 0xb5, 0xa6, 0xdf, 0xaa,
+ 0x47, 0x24, 0xa8, 0x4c, 0x31, 0x8d, 0x9d, 0xcd, 0xc4, 0x82, 0x80, 0x61, 0x55, 0x8a, 0xfe, 0x1a,
+ 0x4c, 0x84, 0xdd, 0x84, 0xb1, 0x16, 0x3a, 0x4f, 0x71, 0xe5, 0x38, 0xab, 0xce, 0x82, 0x87, 0xd6,
+ 0xf4, 0x02, 0x6c, 0xd6, 0xa3, 0x2c, 0xbe, 0x19, 0xc6, 0x2c, 0xb5, 0x0f, 0x63, 0xf1, 0xa7, 0x4d,
+ 0x16, 0x7f, 0x51, 0x2b, 0xc3, 0x46, 0x4d, 0xf4, 0x15, 0x07, 0x8e, 0xb7, 0xb3, 0x0a, 0x5c, 0xe5,
+ 0x0c, 0x9b, 0x99, 0xaa, 0x0d, 0x41, 0x3f, 0x83, 0x9a, 0x87, 0x7d, 0xf7, 0x80, 0x71, 0x6f, 0x27,
+ 0x58, 0x92, 0xad, 0x78, 0x37, 0xa8, 0x35, 0xa3, 0x30, 0x30, 0xbb, 0x77, 0xbf, 0xad, 0xab, 0x65,
+ 0x6c, 0x6f, 0xe7, 0x91, 0x98, 0xbf, 0xff, 0xe6, 0xde, 0xcc, 0xa9, 0xdc, 0x22, 0x9c, 0xdf, 0xa9,
+ 0xe9, 0x45, 0x38, 0x9d, 0xcf, 0x1f, 0x6e, 0xa7, 0x71, 0x0c, 0xe9, 0x1a, 0xc7, 0x12, 0xdc, 0xdf,
+ 0xb7, 0x53, 0xf4, 0xa4, 0x91, 0xd2, 0xa6, 0x63, 0x9e, 0x34, 0x3d, 0xd2, 0xe1, 0x24, 0x8c, 0xeb,
+ 0xef, 0x3f, 0xb8, 0xff, 0x77, 0x08, 0x20, 0xb5, 0x93, 0x23, 0x0f, 0x26, 0xb9, 0x4d, 0xfe, 0xd2,
+ 0xe2, 0x1d, 0x5f, 0x8a, 0x5f, 0x30, 0x10, 0xe0, 0x0c, 0x42, 0xd4, 0x06, 0xc4, 0x21, 0xfc, 0xf7,
+ 0x9d, 0xf8, 0x56, 0x99, 0x2b, 0x72, 0xa1, 0x07, 0x09, 0xce, 0x41, 0x4c, 0x47, 0x94, 0x84, 0xdb,
+ 0x24, 0xb8, 0x8a, 0x2f, 0xdf, 0x49, 0x66, 0x05, 0xee, 0x8d, 0x33, 0x10, 0xe0, 0x0c, 0x42, 0xe4,
+ 0xc2, 0x08, 0xb3, 0xcd, 0xc8, 0x00, 0x6d, 0xc6, 0x5e, 0x98, 0xa4, 0x11, 0x63, 0x51, 0x82, 0xbe,
+ 0xe4, 0xc0, 0xa4, 0x4c, 0x10, 0xc1, 0xac, 0xa1, 0x32, 0x34, 0xfb, 0xaa, 0x2d, 0x3f, 0xc7, 0x05,
+ 0x1d, 0x7b, 0x1a, 0xf8, 0x68, 0x80, 0x63, 0x9c, 0xe9, 0x84, 0xfb, 0x02, 0x9c, 0xc8, 0x69, 0x6e,
+ 0x45, 0xa3, 0xfd, 0xb6, 0x03, 0x65, 0x2d, 0x6f, 0x21, 0x7a, 0x1d, 0x4a, 0x61, 0xd5, 0x7a, 0xb4,
+ 0xdd, 0x5a, 0xb5, 0x27, 0xda, 0x4e, 0x81, 0x70, 0x4a, 0x70, 0x90, 0x20, 0xc1, 0xdc, 0x24, 0x8b,
+ 0xf7, 0xb8, 0xdb, 0x07, 0x0e, 0x12, 0xfc, 0x95, 0x22, 0xa4, 0x98, 0x0e, 0x98, 0xb8, 0x24, 0x0d,
+ 0x29, 0x2c, 0xec, 0x1b, 0x52, 0x58, 0x87, 0x63, 0x1e, 0xf3, 0x25, 0xdf, 0x61, 0xba, 0x12, 0x9e,
+ 0xb6, 0xd6, 0xc4, 0x80, 0xb3, 0x28, 0x29, 0x95, 0x38, 0x6d, 0xca, 0xa8, 0x0c, 0x1f, 0x98, 0x4a,
+ 0xd5, 0xc4, 0x80, 0xb3, 0x28, 0xd1, 0x4b, 0x50, 0xa9, 0xb1, 0xeb, 0xb7, 0x7c, 0x8c, 0x97, 0xb6,
+ 0xae, 0x84, 0xc9, 0x7a, 0x44, 0x62, 0x12, 0x24, 0x22, 0x31, 0xd9, 0xc3, 0x62, 0x16, 0x2a, 0x0b,
+ 0x7d, 0xea, 0xe1, 0xbe, 0x18, 0xa8, 0x9a, 0xc2, 0x9c, 0xd1, 0x7e, 0xb2, 0xcb, 0x98, 0x88, 0xf0,
+ 0xd2, 0x2b, 0x35, 0xa5, 0xaa, 0x17, 0x62, 0xb3, 0x2e, 0xfa, 0x65, 0x07, 0x26, 0x5a, 0xd2, 0x5c,
+ 0x8f, 0xbb, 0x2d, 0x99, 0x65, 0x13, 0x5b, 0x59, 0x7e, 0x97, 0x75, 0xcc, 0x5c, 0x96, 0x30, 0x40,
+ 0xd8, 0xa4, 0x9d, 0xcd, 0x1d, 0x33, 0x36, 0x60, 0xee, 0x98, 0xef, 0x39, 0x30, 0x95, 0xa5, 0x86,
+ 0xb6, 0xe1, 0xa1, 0xb6, 0x17, 0x6d, 0x5f, 0x0a, 0xb6, 0x22, 0x76, 0x11, 0x23, 0xe1, 0x8b, 0x61,
+ 0x6e, 0x2b, 0x21, 0xd1, 0xa2, 0xb7, 0xcb, 0xdd, 0x9f, 0x45, 0xf5, 0x4c, 0xd3, 0x43, 0xab, 0xfb,
+ 0x55, 0xc6, 0xfb, 0xe3, 0x42, 0x55, 0x38, 0x45, 0x2b, 0xb0, 0xd4, 0x72, 0x7e, 0x18, 0xa4, 0x44,
+ 0x0a, 0x8c, 0x88, 0x0a, 0x06, 0x5c, 0xcd, 0xab, 0x84, 0xf3, 0xdb, 0xba, 0x17, 0x60, 0x84, 0xdf,
+ 0x8b, 0xbb, 0x2b, 0xff, 0x91, 0xfb, 0x6f, 0x0b, 0x20, 0x05, 0xc3, 0xbf, 0xdc, 0xee, 0x38, 0x7a,
+ 0x88, 0x46, 0xcc, 0xa4, 0x24, 0xac, 0x1d, 0xec, 0x10, 0x15, 0x49, 0x1c, 0x45, 0x09, 0x95, 0x98,
+ 0xc9, 0x0d, 0x3f, 0x59, 0x08, 0xeb, 0xd2, 0xc6, 0xc1, 0x24, 0xe6, 0x0b, 0x02, 0x86, 0x55, 0xa9,
+ 0xfb, 0x09, 0x07, 0x26, 0xe8, 0x28, 0x5b, 0x2d, 0xd2, 0xaa, 0x26, 0xa4, 0x13, 0xa3, 0x18, 0x8a,
+ 0x31, 0xfd, 0xc7, 0x9e, 0x29, 0x30, 0xbd, 0x4b, 0x49, 0x3a, 0x9a, 0xb3, 0x86, 0x12, 0xc1, 0x9c,
+ 0x96, 0xfb, 0xd6, 0x10, 0x94, 0xd4, 0x64, 0x0f, 0x60, 0x4f, 0x3d, 0x9f, 0xe6, 0x57, 0xe5, 0x1c,
+ 0xb8, 0xa2, 0xe5, 0x56, 0xbd, 0x45, 0xa7, 0x2e, 0xd8, 0xe5, 0x89, 0x26, 0xd2, 0x44, 0xab, 0x4f,
+ 0x9a, 0xae, 0xe6, 0xd3, 0xfa, 0xfa, 0xd3, 0xea, 0x0b, 0x9f, 0xf3, 0x0d, 0xdd, 0xd3, 0x3f, 0x6c,
+ 0xeb, 0x34, 0x53, 0x6e, 0xcc, 0xfe, 0x2e, 0xfe, 0xcc, 0xd3, 0x3b, 0xc5, 0x81, 0x9e, 0xde, 0x79,
+ 0x02, 0x86, 0x49, 0xd0, 0x6d, 0x33, 0x51, 0xa9, 0xc4, 0x54, 0x84, 0xe1, 0x0b, 0x41, 0xb7, 0x6d,
+ 0x8e, 0x8c, 0x55, 0x41, 0xef, 0x83, 0x72, 0x9d, 0xc4, 0xb5, 0xc8, 0x67, 0xd9, 0x13, 0x84, 0x65,
+ 0xe7, 0x41, 0x66, 0x2e, 0x4b, 0xc1, 0x66, 0x43, 0xbd, 0x81, 0xfb, 0x2a, 0x8c, 0xac, 0xb7, 0xba,
+ 0x0d, 0x3f, 0x40, 0x1d, 0x18, 0xe1, 0xb9, 0x14, 0xc4, 0x69, 0x6f, 0x41, 0xef, 0xe4, 0xac, 0x42,
+ 0x8b, 0x42, 0xe1, 0x57, 0x6a, 0x05, 0x1d, 0xf7, 0xb7, 0x0b, 0x40, 0x55, 0xf3, 0xe5, 0x05, 0xf4,
+ 0x37, 0x7b, 0x5e, 0x9a, 0xf9, 0x99, 0x9c, 0x97, 0x66, 0x26, 0x58, 0xe5, 0x9c, 0x47, 0x66, 0x5a,
+ 0x30, 0xc1, 0x9c, 0x23, 0xf2, 0x0c, 0x14, 0x62, 0xf5, 0xd3, 0x03, 0xa6, 0x1f, 0xd0, 0x9b, 0x8a,
+ 0x13, 0x41, 0x07, 0x61, 0x13, 0x39, 0xda, 0x85, 0x13, 0x3c, 0x4d, 0xe7, 0x22, 0x69, 0x79, 0xbb,
+ 0x46, 0x3a, 0xae, 0x81, 0x53, 0x1e, 0xc8, 0x56, 0x3c, 0xc0, 0x7b, 0xb1, 0x17, 0x1d, 0xce, 0xa3,
+ 0xe1, 0xfe, 0xfe, 0x30, 0x68, 0xee, 0x8b, 0x01, 0x76, 0xd6, 0x2b, 0x19, 0x67, 0xd5, 0xaa, 0x15,
+ 0x67, 0x95, 0xf4, 0x00, 0x71, 0x6e, 0x65, 0xfa, 0xa7, 0x68, 0xa7, 0x9a, 0xa4, 0xd5, 0x11, 0xfb,
+ 0x52, 0x75, 0xea, 0x22, 0x69, 0x75, 0x30, 0x2b, 0x51, 0x97, 0x0f, 0x87, 0xfb, 0x5e, 0x3e, 0x6c,
+ 0x42, 0xb1, 0xe1, 0x75, 0x1b, 0x44, 0x44, 0x6b, 0x5a, 0xf0, 0x4b, 0xb2, 0xeb, 0x10, 0xdc, 0x2f,
+ 0xc9, 0xfe, 0xc5, 0x9c, 0x00, 0x65, 0x0c, 0x4d, 0x19, 0xbe, 0x22, 0x0c, 0xba, 0x16, 0x18, 0x83,
+ 0x8a, 0x88, 0xe1, 0x8c, 0x41, 0xfd, 0xc4, 0x29, 0x31, 0xd4, 0x81, 0xd1, 0x1a, 0x4f, 0x98, 0x22,
+ 0xe4, 0x9b, 0x4b, 0x36, 0x6e, 0x57, 0x32, 0x84, 0xdc, 0xf2, 0x22, 0x7e, 0x60, 0x49, 0xc6, 0x3d,
+ 0x07, 0x65, 0xed, 0x71, 0x0c, 0xfa, 0x19, 0x54, 0xae, 0x0e, 0xed, 0x33, 0x2c, 0x7a, 0x89, 0x87,
+ 0x59, 0x89, 0xfb, 0x8d, 0x61, 0x50, 0x76, 0x37, 0xfd, 0x2e, 0xa0, 0x57, 0xd3, 0x32, 0x0b, 0x19,
+ 0xf7, 0xe2, 0xc3, 0x00, 0x8b, 0x52, 0x2a, 0x03, 0xb6, 0x49, 0xd4, 0x50, 0x3a, 0xb7, 0x60, 0xed,
+ 0x4a, 0x06, 0x5c, 0xd5, 0x0b, 0xb1, 0x59, 0x97, 0x0a, 0xf0, 0x6d, 0xe1, 0xce, 0xcf, 0x06, 0x4b,
+ 0x4b, 0x37, 0x3f, 0x56, 0x35, 0x58, 0x6a, 0x82, 0xb6, 0xe6, 0xfd, 0x17, 0x41, 0x9b, 0x36, 0x9c,
+ 0x4f, 0x1a, 0x56, 0x1e, 0x5c, 0xa5, 0x43, 0xb0, 0x41, 0x15, 0x2d, 0xc3, 0xf1, 0x98, 0x24, 0x6b,
+ 0xd7, 0x03, 0x12, 0xa9, 0xb4, 0x01, 0x22, 0xf7, 0x85, 0xba, 0x29, 0x51, 0xcd, 0x56, 0xc0, 0xbd,
+ 0x6d, 0x72, 0xe3, 0x5c, 0x8b, 0x07, 0x8e, 0x73, 0x5d, 0x84, 0xa9, 0x2d, 0xcf, 0x6f, 0x75, 0x23,
+ 0xd2, 0x37, 0x5a, 0x76, 0x29, 0x53, 0x8e, 0x7b, 0x5a, 0xb0, 0xcb, 0x3a, 0x2d, 0xaf, 0x11, 0x57,
+ 0x46, 0xb5, 0xcb, 0x3a, 0x14, 0x80, 0x39, 0xdc, 0xfd, 0x4d, 0x07, 0x78, 0xd2, 0xa1, 0xb9, 0xad,
+ 0x2d, 0x3f, 0xf0, 0x93, 0x5d, 0xf4, 0x55, 0x07, 0xa6, 0x82, 0xb0, 0x4e, 0xe6, 0x82, 0xc4, 0x97,
+ 0x40, 0x7b, 0x99, 0xe0, 0x19, 0xad, 0x2b, 0x19, 0xf4, 0x3c, 0x83, 0x45, 0x16, 0x8a, 0x7b, 0xba,
+ 0xe1, 0x9e, 0x81, 0x53, 0xb9, 0x08, 0xdc, 0xef, 0x0d, 0x81, 0x99, 0x3b, 0x09, 0x3d, 0x07, 0xc5,
+ 0x16, 0xcb, 0xe6, 0xe1, 0xdc, 0x61, 0x52, 0x2c, 0x36, 0x57, 0x3c, 0xdd, 0x07, 0xc7, 0x84, 0x16,
+ 0xa1, 0xcc, 0x12, 0x32, 0x89, 0x5c, 0x2b, 0x05, 0x23, 0xcd, 0x41, 0x19, 0xa7, 0x45, 0xb7, 0xcc,
+ 0x9f, 0x58, 0x6f, 0x86, 0x5e, 0x83, 0xd1, 0x4d, 0x9e, 0x96, 0xd2, 0x9e, 0x7f, 0x50, 0xe4, 0xb9,
+ 0x64, 0x72, 0x94, 0x4c, 0x7a, 0x79, 0x2b, 0xfd, 0x17, 0x4b, 0x8a, 0x68, 0x17, 0xc6, 0x3c, 0xf9,
+ 0x4d, 0x87, 0x6d, 0x5d, 0xbe, 0x30, 0xd6, 0x8f, 0x88, 0xae, 0x91, 0xdf, 0x50, 0x91, 0xcb, 0x84,
+ 0x21, 0x15, 0x07, 0x0a, 0x43, 0xfa, 0x96, 0x03, 0x90, 0xbe, 0xe1, 0x81, 0x6e, 0xc0, 0x58, 0xfc,
+ 0xb4, 0x61, 0xd4, 0xb0, 0x71, 0xeb, 0x5e, 0x60, 0xd4, 0x6e, 0xa6, 0x0a, 0x08, 0x56, 0xd4, 0x6e,
+ 0x67, 0x88, 0xf9, 0x89, 0x03, 0x27, 0xf3, 0xde, 0x1a, 0xb9, 0x87, 0x3d, 0x3e, 0xa8, 0x0d, 0x46,
+ 0x34, 0x58, 0x8f, 0xc8, 0x96, 0x7f, 0x23, 0x27, 0x39, 0x32, 0x2f, 0xc0, 0x69, 0x1d, 0xf7, 0xcd,
+ 0x51, 0x50, 0x84, 0x0f, 0xc9, 0x66, 0xf3, 0x18, 0xd5, 0xaf, 0x1a, 0xe9, 0x65, 0x49, 0x55, 0x0f,
+ 0x33, 0x28, 0x16, 0xa5, 0x54, 0xc7, 0x92, 0x01, 0xf4, 0x82, 0x65, 0xb3, 0x55, 0x28, 0x03, 0xed,
+ 0xb1, 0x2a, 0xcd, 0xb3, 0x02, 0x15, 0x8f, 0xc4, 0x0a, 0x34, 0x62, 0xdf, 0x0a, 0xf4, 0x04, 0x8c,
+ 0x46, 0x61, 0x8b, 0xcc, 0xe1, 0x2b, 0x42, 0x73, 0x48, 0x03, 0x20, 0x38, 0x18, 0xcb, 0xf2, 0x3b,
+ 0xb4, 0x83, 0xa0, 0xdf, 0x71, 0xf6, 0x31, 0x34, 0x95, 0x6c, 0x9d, 0x09, 0xb9, 0x99, 0xe4, 0x98,
+ 0x1a, 0x74, 0x27, 0xd6, 0xab, 0xaf, 0x39, 0x70, 0x9c, 0x04, 0xb5, 0x68, 0x97, 0xe1, 0x11, 0xd8,
+ 0x84, 0x7f, 0xfa, 0xaa, 0x8d, 0xcd, 0x77, 0x21, 0x8b, 0x9c, 0xbb, 0x81, 0x7a, 0xc0, 0xb8, 0xb7,
+ 0x1b, 0x68, 0x0d, 0xc6, 0x6a, 0x9e, 0x58, 0x11, 0xe5, 0x83, 0xac, 0x08, 0xee, 0x65, 0x9b, 0x13,
+ 0x4b, 0x41, 0x21, 0x71, 0x7f, 0x54, 0x80, 0x13, 0x39, 0x5d, 0x62, 0x97, 0xad, 0xda, 0x74, 0x45,
+ 0x5e, 0xaa, 0x67, 0xf7, 0xe3, 0x8a, 0x80, 0x63, 0x55, 0x03, 0xad, 0xc3, 0xc9, 0xed, 0x76, 0x9c,
+ 0x62, 0x59, 0x08, 0x83, 0x84, 0xdc, 0x90, 0xbb, 0x53, 0xfa, 0xae, 0x4f, 0xae, 0xe4, 0xd4, 0xc1,
+ 0xb9, 0x2d, 0xa9, 0xf8, 0x42, 0x02, 0x6f, 0xb3, 0x45, 0xd2, 0x22, 0x71, 0x55, 0x50, 0x89, 0x2f,
+ 0x17, 0x32, 0xe5, 0xb8, 0xa7, 0x05, 0xfa, 0x8c, 0x03, 0x0f, 0xc4, 0x24, 0xda, 0x21, 0x51, 0xd5,
+ 0xaf, 0x93, 0x85, 0x6e, 0x9c, 0x84, 0x6d, 0x12, 0xdd, 0xa1, 0x69, 0x75, 0xe6, 0xe6, 0xde, 0xcc,
+ 0x03, 0xd5, 0xfe, 0xd8, 0xf0, 0x7e, 0xa4, 0xdc, 0xcf, 0x38, 0x30, 0x59, 0x65, 0x8a, 0xb7, 0x92,
+ 0xa5, 0x6d, 0xe7, 0x12, 0x7d, 0x4c, 0x25, 0xb7, 0xc8, 0x70, 0x45, 0x33, 0x1d, 0x85, 0xfb, 0x32,
+ 0x4c, 0x55, 0x49, 0xdb, 0xeb, 0x34, 0xd9, 0x3d, 0x5f, 0x1e, 0xbb, 0x75, 0x0e, 0x4a, 0xb1, 0x84,
+ 0x65, 0x9f, 0x0f, 0x52, 0x95, 0x71, 0x5a, 0x07, 0x3d, 0xca, 0xe3, 0xcc, 0xe4, 0x6d, 0xa1, 0x12,
+ 0xd7, 0x3a, 0x78, 0x70, 0x5a, 0x8c, 0x65, 0x99, 0xfb, 0x96, 0x03, 0xe3, 0x69, 0x7b, 0xb2, 0x85,
+ 0x1a, 0x70, 0xac, 0xa6, 0xdd, 0xb4, 0x4b, 0xef, 0x38, 0x0c, 0x7e, 0x29, 0x8f, 0xa7, 0x38, 0x36,
+ 0x91, 0xe0, 0x2c, 0xd6, 0x83, 0x87, 0xe9, 0x7d, 0xbe, 0x00, 0xc7, 0x54, 0x57, 0x85, 0x93, 0xf1,
+ 0x8d, 0x6c, 0x34, 0x1d, 0xb6, 0x91, 0xa6, 0xc7, 0x9c, 0xfb, 0x7d, 0x22, 0xea, 0xde, 0xc8, 0x46,
+ 0xd4, 0x1d, 0x2a, 0xf9, 0x1e, 0xbf, 0xe9, 0xb7, 0x0a, 0x30, 0xa6, 0x92, 0x06, 0x3d, 0x07, 0x45,
+ 0xa6, 0x4a, 0xde, 0x9d, 0x40, 0xcc, 0xd4, 0x52, 0xcc, 0x31, 0x51, 0x94, 0x2c, 0x62, 0xe7, 0x8e,
+ 0x13, 0xcf, 0x96, 0xb8, 0xf1, 0xd1, 0x8b, 0x12, 0xcc, 0x31, 0xa1, 0x15, 0x18, 0x22, 0x41, 0x5d,
+ 0x48, 0xc6, 0x07, 0x47, 0xc8, 0x1e, 0xfa, 0xba, 0x10, 0xd4, 0x31, 0xc5, 0xc2, 0x32, 0x97, 0x71,
+ 0x01, 0x28, 0xf3, 0xac, 0x8b, 0x90, 0x7e, 0x44, 0xa9, 0xfb, 0x7e, 0x30, 0x72, 0xd6, 0x89, 0x5c,
+ 0xf8, 0x42, 0xe9, 0xea, 0x7d, 0x8b, 0x4b, 0x68, 0x5b, 0x69, 0x1d, 0xf7, 0x97, 0x87, 0x60, 0xa4,
+ 0xda, 0xdd, 0xa4, 0x4a, 0xc2, 0x37, 0x1d, 0x38, 0x71, 0x3d, 0x93, 0xd6, 0x39, 0xdd, 0x24, 0x57,
+ 0xed, 0x59, 0x70, 0xf5, 0xb0, 0xb3, 0x07, 0xe4, 0xa3, 0xf7, 0x39, 0x85, 0x38, 0xaf, 0x3b, 0x46,
+ 0x66, 0xd5, 0xa1, 0x43, 0xc9, 0xac, 0x7a, 0xe3, 0x90, 0xef, 0x5d, 0x4c, 0xf4, 0xbb, 0x73, 0xe1,
+ 0xfe, 0x7e, 0x11, 0x80, 0x7f, 0x8d, 0xb5, 0x4e, 0x32, 0x88, 0x9d, 0xed, 0x19, 0x18, 0x6f, 0x90,
+ 0x80, 0x44, 0x32, 0xa8, 0x30, 0xf3, 0xe4, 0xd0, 0xb2, 0x56, 0x86, 0x8d, 0x9a, 0x4c, 0xa9, 0x09,
+ 0x92, 0x68, 0x97, 0x0b, 0xbe, 0xd9, 0xbb, 0x15, 0xaa, 0x04, 0x6b, 0xb5, 0xd0, 0xac, 0xe1, 0x32,
+ 0xe1, 0xde, 0xf7, 0xc9, 0x7d, 0x3c, 0x1c, 0xef, 0x83, 0x49, 0x33, 0x51, 0x89, 0x90, 0xf6, 0x94,
+ 0xb7, 0xdc, 0xcc, 0x6f, 0x82, 0x33, 0xb5, 0xe9, 0x2e, 0xa8, 0x47, 0xbb, 0xb8, 0x1b, 0x08, 0xb1,
+ 0x4f, 0xed, 0x82, 0x45, 0x06, 0xc5, 0xa2, 0x94, 0x65, 0x78, 0x60, 0x07, 0x20, 0x87, 0x8b, 0x2c,
+ 0x11, 0x69, 0x86, 0x07, 0xad, 0x0c, 0x1b, 0x35, 0x29, 0x05, 0x61, 0xa7, 0x04, 0x73, 0x9f, 0x65,
+ 0x8c, 0x8b, 0x1d, 0x98, 0x0c, 0x4d, 0xfb, 0x0a, 0x97, 0x81, 0xde, 0x35, 0xe0, 0xd2, 0x33, 0xda,
+ 0xf2, 0x28, 0x87, 0x8c, 0x39, 0x26, 0x83, 0x9f, 0xca, 0xbd, 0xfa, 0x15, 0x84, 0x71, 0x33, 0x26,
+ 0xb5, 0xef, 0x2d, 0x81, 0x75, 0x38, 0xd9, 0x09, 0xeb, 0xeb, 0x91, 0x1f, 0x46, 0x7e, 0xb2, 0xbb,
+ 0xd0, 0xf2, 0xe2, 0x98, 0x2d, 0x8c, 0x09, 0x53, 0x1e, 0x5a, 0xcf, 0xa9, 0x83, 0x73, 0x5b, 0x52,
+ 0x0d, 0xa5, 0x23, 0x80, 0x2c, 0x32, 0xac, 0xc8, 0x25, 0x3a, 0x59, 0x11, 0xab, 0x52, 0xf7, 0x04,
+ 0x1c, 0xaf, 0x76, 0x3b, 0x9d, 0x96, 0x4f, 0xea, 0xca, 0x25, 0xe1, 0xbe, 0x1f, 0x8e, 0x89, 0xbc,
+ 0xab, 0x4a, 0xfa, 0x38, 0x50, 0x96, 0x70, 0xf7, 0x3f, 0x0d, 0xc1, 0xb1, 0x4c, 0x1c, 0x0e, 0x7a,
+ 0x2d, 0x2b, 0x33, 0xd8, 0xc9, 0x07, 0xaa, 0x49, 0x0b, 0x22, 0xb9, 0x67, 0x9e, 0xfc, 0xd1, 0x94,
+ 0x41, 0xf4, 0xd6, 0x2e, 0xaf, 0xb0, 0x50, 0x73, 0x7e, 0xa4, 0x18, 0x91, 0xf8, 0x1f, 0x05, 0x50,
+ 0x64, 0xe5, 0x7d, 0x79, 0xdb, 0xe3, 0x64, 0xfb, 0x57, 0x41, 0x62, 0xac, 0x51, 0x44, 0x01, 0x8c,
+ 0xb2, 0x8e, 0x10, 0x79, 0x63, 0xd2, 0xda, 0x58, 0x99, 0xc8, 0xb6, 0xca, 0x71, 0x63, 0x49, 0xc4,
+ 0xfd, 0x74, 0x01, 0xf2, 0x83, 0xbd, 0xd0, 0x47, 0x7b, 0x3f, 0xf8, 0x73, 0x16, 0x27, 0x42, 0x44,
+ 0x9b, 0xf5, 0xff, 0xe6, 0x81, 0xf9, 0xcd, 0x57, 0x2d, 0xcd, 0x83, 0xa0, 0xdb, 0xf3, 0xe5, 0xdd,
+ 0xff, 0xe9, 0x40, 0x79, 0x63, 0xe3, 0xb2, 0x3a, 0xd7, 0x31, 0x9c, 0x8e, 0x79, 0x32, 0x02, 0xe6,
+ 0x13, 0x5f, 0x08, 0xdb, 0x1d, 0xee, 0x22, 0x17, 0xae, 0x7b, 0x96, 0xf2, 0xb7, 0x9a, 0x5b, 0x03,
+ 0xf7, 0x69, 0x89, 0x2e, 0xc1, 0x09, 0xbd, 0xa4, 0xaa, 0xbd, 0xb0, 0x58, 0x14, 0x09, 0x80, 0x7a,
+ 0x8b, 0x71, 0x5e, 0x9b, 0x2c, 0x2a, 0x61, 0xde, 0x65, 0xc7, 0x73, 0x0e, 0x2a, 0x51, 0x8c, 0xf3,
+ 0xda, 0xb8, 0x6b, 0x50, 0xde, 0xf0, 0x22, 0x35, 0xf0, 0x0f, 0xc0, 0x54, 0x2d, 0x6c, 0x4b, 0xb3,
+ 0xda, 0x65, 0xb2, 0x43, 0x5a, 0x62, 0xc8, 0xfc, 0x59, 0x93, 0x4c, 0x19, 0xee, 0xa9, 0xed, 0xfe,
+ 0xb7, 0xb3, 0xa0, 0x2e, 0x57, 0x0e, 0x70, 0xa2, 0x76, 0x54, 0x18, 0x6c, 0xd1, 0x72, 0x18, 0xac,
+ 0x3a, 0x5b, 0x32, 0xa1, 0xb0, 0x49, 0x1a, 0x0a, 0x3b, 0x62, 0x3b, 0x14, 0x56, 0x49, 0xd8, 0x3d,
+ 0xe1, 0xb0, 0x5f, 0x76, 0x60, 0x3c, 0x08, 0xeb, 0x44, 0xf9, 0x2e, 0x47, 0xd9, 0x0e, 0x7f, 0xc9,
+ 0xde, 0xad, 0x02, 0x1e, 0xd6, 0x29, 0xd0, 0xf3, 0x10, 0x6d, 0x75, 0x24, 0xeb, 0x45, 0xd8, 0xe8,
+ 0x07, 0x5a, 0xd2, 0x0c, 0xbd, 0xdc, 0x9f, 0xf2, 0x60, 0x9e, 0x7e, 0x76, 0x5b, 0xab, 0xed, 0x0d,
+ 0x4d, 0x4e, 0x2c, 0xd9, 0x32, 0x60, 0xca, 0x1b, 0x73, 0x9a, 0x5b, 0x48, 0x66, 0xad, 0x4e, 0xe5,
+ 0x47, 0x17, 0x46, 0x78, 0x2c, 0xb7, 0x48, 0x35, 0xc5, 0xbc, 0x95, 0x3c, 0xce, 0x1b, 0x8b, 0x12,
+ 0x94, 0xc8, 0xf8, 0x88, 0xb2, 0xad, 0x37, 0x28, 0x8c, 0xf8, 0x8b, 0xfc, 0x00, 0x09, 0xf4, 0xac,
+ 0xae, 0xf7, 0x8f, 0x0f, 0xa2, 0xf7, 0x4f, 0xf4, 0xd5, 0xf9, 0x3f, 0xe7, 0xc0, 0x78, 0x4d, 0x7b,
+ 0x13, 0xa2, 0xf2, 0xb8, 0xad, 0xb7, 0xaf, 0xf3, 0x9e, 0xee, 0xe0, 0x4e, 0x30, 0xe3, 0x0d, 0x0a,
+ 0x83, 0x3a, 0xcb, 0xaf, 0xc9, 0x8c, 0x1c, 0x4c, 0xd4, 0xb1, 0x92, 0x52, 0xc3, 0x34, 0x9a, 0xc8,
+ 0x38, 0x53, 0x0a, 0xc3, 0x82, 0x16, 0x7a, 0x1d, 0xc6, 0xe4, 0x75, 0x00, 0x11, 0x36, 0x8f, 0x6d,
+ 0x78, 0x25, 0x4c, 0xd7, 0xa7, 0x4c, 0xca, 0xc7, 0xa1, 0x58, 0x51, 0x44, 0x4d, 0x18, 0xaa, 0x7b,
+ 0x0d, 0x11, 0x40, 0xbf, 0x6a, 0x27, 0xe9, 0xa9, 0xa4, 0xc9, 0xf4, 0xd1, 0xc5, 0xb9, 0x65, 0x4c,
+ 0x49, 0xa0, 0x1b, 0x69, 0x52, 0xfd, 0x29, 0x6b, 0xa7, 0xaf, 0x29, 0x16, 0x72, 0x99, 0xa0, 0x27,
+ 0x47, 0x7f, 0x5d, 0x78, 0x8b, 0xff, 0x0a, 0x23, 0xbb, 0x64, 0x27, 0x6b, 0x2a, 0x4f, 0xd1, 0x92,
+ 0x7a, 0x9c, 0x29, 0x95, 0x66, 0x92, 0x74, 0x2a, 0x3f, 0x6b, 0x8b, 0x0a, 0x4b, 0x34, 0xc2, 0x9f,
+ 0x29, 0xdf, 0xd8, 0x58, 0xc7, 0x0c, 0x3b, 0x6a, 0xc1, 0x48, 0x87, 0x05, 0xbd, 0x54, 0x7e, 0xce,
+ 0xd6, 0xd9, 0xc2, 0x83, 0x68, 0xf8, 0xda, 0xe4, 0xff, 0x63, 0x41, 0x03, 0x5d, 0x80, 0x51, 0xfe,
+ 0x36, 0x0c, 0xbf, 0xc0, 0x50, 0x3e, 0x3f, 0xdd, 0xff, 0x85, 0x99, 0xf4, 0xa0, 0xe0, 0xbf, 0x63,
+ 0x2c, 0xdb, 0xa2, 0xcf, 0x3b, 0x30, 0x49, 0x39, 0x6a, 0xfa, 0x98, 0x4d, 0x05, 0xd9, 0xe2, 0x59,
+ 0x57, 0x63, 0x2a, 0x91, 0x48, 0x5e, 0xa3, 0xd4, 0xc2, 0x4b, 0x06, 0x39, 0x9c, 0x21, 0x8f, 0xde,
+ 0x80, 0xb1, 0xd8, 0xaf, 0x93, 0x9a, 0x17, 0xc5, 0x95, 0x13, 0x87, 0xd3, 0x95, 0xd4, 0x3f, 0x25,
+ 0x08, 0x61, 0x45, 0x12, 0xfd, 0x1a, 0x7b, 0x4d, 0x54, 0xbc, 0xfc, 0x5f, 0xe3, 0x6a, 0xcc, 0x49,
+ 0x5b, 0x7b, 0x5f, 0x7a, 0xe2, 0x24, 0x66, 0xe1, 0xb6, 0x31, 0xc9, 0xe1, 0x2c, 0x7d, 0xf4, 0xb7,
+ 0x1c, 0x38, 0xc5, 0xdf, 0x05, 0xc8, 0x3e, 0x64, 0x71, 0xea, 0x0e, 0xed, 0x51, 0xec, 0xe6, 0xc5,
+ 0x5c, 0x1e, 0x4a, 0x9c, 0x4f, 0x89, 0x65, 0xf1, 0x35, 0xdf, 0x1e, 0x3a, 0x6d, 0xd5, 0x4f, 0x3b,
+ 0xf8, 0x7b, 0x43, 0xe8, 0x29, 0x28, 0x77, 0xc4, 0x71, 0xe8, 0xc7, 0x6d, 0x76, 0x8f, 0x66, 0x88,
+ 0xdf, 0x70, 0x5c, 0x4f, 0xc1, 0x58, 0xaf, 0x63, 0xa4, 0x74, 0x7e, 0x62, 0xbf, 0x94, 0xce, 0xe8,
+ 0x2a, 0x94, 0x93, 0xb0, 0x25, 0xb2, 0x9a, 0xc6, 0x95, 0x0a, 0x5b, 0x81, 0x67, 0xf3, 0xf6, 0xd6,
+ 0x86, 0xaa, 0x96, 0x6a, 0xee, 0x29, 0x2c, 0xc6, 0x3a, 0x1e, 0x16, 0xbb, 0x2c, 0xde, 0x5b, 0x88,
+ 0x98, 0xca, 0x7e, 0x7f, 0x26, 0x76, 0x59, 0x2f, 0xc4, 0x66, 0x5d, 0xb4, 0x0c, 0xc7, 0x3b, 0x3d,
+ 0x3a, 0x3f, 0xbf, 0xbf, 0xa7, 0x42, 0x40, 0x7a, 0x15, 0xfe, 0xde, 0x36, 0x86, 0xb6, 0xff, 0xc0,
+ 0x7e, 0xda, 0x7e, 0x9f, 0x04, 0xc7, 0x0f, 0xde, 0x49, 0x82, 0x63, 0x54, 0x87, 0x07, 0xbd, 0x6e,
+ 0x12, 0xb2, 0x64, 0x3a, 0x66, 0x13, 0x1e, 0xc6, 0xfd, 0x30, 0x8f, 0x0c, 0xbf, 0xb9, 0x37, 0xf3,
+ 0xe0, 0xdc, 0x3e, 0xf5, 0xf0, 0xbe, 0x58, 0xd0, 0xab, 0x30, 0x46, 0x44, 0x92, 0xe6, 0xca, 0xcf,
+ 0xd8, 0x12, 0x12, 0xcc, 0xb4, 0xcf, 0x32, 0x42, 0x96, 0xc3, 0xb0, 0xa2, 0x87, 0x36, 0xa0, 0xdc,
+ 0x0c, 0xe3, 0x64, 0xae, 0xe5, 0x7b, 0x31, 0x89, 0x2b, 0x0f, 0xb1, 0x45, 0x93, 0x2b, 0x7b, 0x5d,
+ 0x94, 0xd5, 0xd2, 0x35, 0x73, 0x31, 0x6d, 0x89, 0x75, 0x34, 0x88, 0x30, 0x6f, 0x2d, 0x8b, 0x61,
+ 0x97, 0x8e, 0xaf, 0xb3, 0x6c, 0x60, 0x8f, 0xe5, 0x61, 0x5e, 0x0f, 0xeb, 0x55, 0xb3, 0xb6, 0x72,
+ 0xd7, 0xea, 0x40, 0x9c, 0xc5, 0x89, 0x9e, 0x81, 0xf1, 0x4e, 0x58, 0xaf, 0x76, 0x48, 0x6d, 0xdd,
+ 0x4b, 0x6a, 0xcd, 0xca, 0x8c, 0x69, 0x65, 0x5c, 0xd7, 0xca, 0xb0, 0x51, 0x13, 0x75, 0x60, 0xb4,
+ 0xcd, 0xb3, 0x2c, 0x54, 0x1e, 0xb1, 0xa5, 0xdb, 0x88, 0xb4, 0x0d, 0xc2, 0x86, 0xc0, 0x7f, 0x60,
+ 0x49, 0x06, 0xfd, 0x43, 0x07, 0x8e, 0x65, 0x6e, 0x86, 0x55, 0xde, 0x61, 0x4d, 0x64, 0x31, 0x11,
+ 0xcf, 0x3f, 0xc6, 0xa6, 0xcf, 0x04, 0xde, 0xea, 0x05, 0xe1, 0x6c, 0x8f, 0xf8, 0xbc, 0xb0, 0x54,
+ 0x29, 0x95, 0x47, 0xed, 0xcd, 0x0b, 0x43, 0x28, 0xe7, 0x85, 0xfd, 0xc0, 0x92, 0x0c, 0x7a, 0x02,
+ 0x46, 0x45, 0x56, 0xc3, 0xca, 0x63, 0xa6, 0xcb, 0x5d, 0x24, 0x3f, 0xc4, 0xb2, 0x7c, 0xfa, 0xfd,
+ 0x70, 0xbc, 0x47, 0x75, 0x3b, 0x50, 0xbe, 0x8e, 0xdf, 0x70, 0x40, 0xbf, 0x4a, 0x6e, 0xfd, 0x65,
+ 0x94, 0x67, 0x60, 0xbc, 0xc6, 0x9f, 0xa1, 0xe4, 0x97, 0xd1, 0x87, 0x4d, 0x7b, 0xef, 0x82, 0x56,
+ 0x86, 0x8d, 0x9a, 0xee, 0x45, 0x40, 0xbd, 0x69, 0xeb, 0xef, 0x28, 0x19, 0xd4, 0x3f, 0x76, 0x60,
+ 0xc2, 0x90, 0x19, 0xac, 0x3b, 0x55, 0x97, 0x00, 0xb5, 0xfd, 0x28, 0x0a, 0x23, 0xfd, 0xbd, 0x3f,
+ 0x91, 0x30, 0x82, 0x5d, 0xc9, 0x5b, 0xed, 0x29, 0xc5, 0x39, 0x2d, 0xdc, 0xdf, 0x1e, 0x86, 0x34,
+ 0x44, 0x5c, 0xe5, 0x05, 0x76, 0xfa, 0xe6, 0x05, 0x7e, 0x12, 0xc6, 0x5e, 0x8e, 0xc3, 0x60, 0x3d,
+ 0xcd, 0x1e, 0xac, 0xbe, 0xc5, 0xb3, 0xd5, 0xb5, 0x2b, 0xac, 0xa6, 0xaa, 0xc1, 0x6a, 0xbf, 0xb2,
+ 0xe4, 0xb7, 0x92, 0xde, 0xf4, 0xb2, 0xcf, 0x3e, 0xc7, 0xe1, 0x58, 0xd5, 0x60, 0x4f, 0xff, 0xed,
+ 0x10, 0xe5, 0x08, 0x48, 0x9f, 0xfe, 0xe3, 0x2f, 0x52, 0xb0, 0x32, 0x74, 0x0e, 0x4a, 0xca, 0x89,
+ 0x20, 0x3c, 0x13, 0x6a, 0xa6, 0x94, 0xa7, 0x01, 0xa7, 0x75, 0x98, 0x40, 0x28, 0x0c, 0xcf, 0xc2,
+ 0x84, 0x52, 0xb5, 0xa1, 0x9e, 0x64, 0x4c, 0xd9, 0x9c, 0xb7, 0x4b, 0x30, 0x56, 0x24, 0xf3, 0x1c,
+ 0xcb, 0xa5, 0x43, 0x71, 0x2c, 0x6b, 0xf7, 0x15, 0x8a, 0x83, 0xde, 0x57, 0x30, 0xd7, 0xf6, 0xd8,
+ 0x40, 0x6b, 0xfb, 0x93, 0x43, 0x30, 0xfa, 0x3c, 0x89, 0x58, 0x56, 0xf5, 0x27, 0x60, 0x74, 0x87,
+ 0xff, 0x9b, 0xbd, 0xec, 0x2a, 0x6a, 0x60, 0x59, 0x4e, 0xbf, 0xdb, 0x66, 0xd7, 0x6f, 0xd5, 0x17,
+ 0xd3, 0x5d, 0x9c, 0x26, 0x64, 0x94, 0x05, 0x38, 0xad, 0x43, 0x1b, 0x34, 0xa8, 0x64, 0xdf, 0x6e,
+ 0xfb, 0x3d, 0xaf, 0xda, 0x2f, 0xcb, 0x02, 0x9c, 0xd6, 0x41, 0x8f, 0xc1, 0x48, 0xc3, 0x4f, 0x36,
+ 0xbc, 0x46, 0xd6, 0x2d, 0xba, 0xcc, 0xa0, 0x58, 0x94, 0x32, 0xb7, 0x98, 0x9f, 0x6c, 0x44, 0x84,
+ 0x59, 0x76, 0x7b, 0x72, 0x6d, 0x2c, 0x6b, 0x65, 0xd8, 0xa8, 0xc9, 0xba, 0x14, 0x8a, 0x91, 0x89,
+ 0xa8, 0xd5, 0xb4, 0x4b, 0xb2, 0x00, 0xa7, 0x75, 0xe8, 0xfa, 0xaf, 0x85, 0xed, 0x8e, 0xdf, 0x12,
+ 0xf1, 0xd4, 0xda, 0xfa, 0x5f, 0x10, 0x70, 0xac, 0x6a, 0xd0, 0xda, 0x94, 0x85, 0x51, 0xf6, 0x93,
+ 0x7d, 0x66, 0x6d, 0x5d, 0xc0, 0xb1, 0xaa, 0xe1, 0x3e, 0x0f, 0x13, 0x7c, 0x27, 0x2f, 0xb4, 0x3c,
+ 0xbf, 0xbd, 0xbc, 0x80, 0x2e, 0xf4, 0xdc, 0x57, 0x78, 0x22, 0xe7, 0xbe, 0xc2, 0x29, 0xa3, 0x51,
+ 0xef, 0xbd, 0x05, 0xf7, 0x07, 0x05, 0x18, 0x3b, 0xc2, 0x97, 0x2a, 0x8f, 0xfc, 0xd1, 0x65, 0x74,
+ 0x23, 0xf3, 0x4a, 0xe5, 0xba, 0xcd, 0xeb, 0x47, 0xfb, 0xbe, 0x50, 0xf9, 0x9f, 0x0b, 0x70, 0x5a,
+ 0x56, 0x95, 0xba, 0xdc, 0xf2, 0x02, 0x7b, 0x1f, 0xec, 0xf0, 0x27, 0x3a, 0x32, 0x26, 0x7a, 0xdd,
+ 0x9e, 0x36, 0xba, 0xbc, 0xd0, 0x77, 0xaa, 0x5f, 0xcd, 0x4c, 0x35, 0xb6, 0x4a, 0x75, 0xff, 0xc9,
+ 0xfe, 0x73, 0x07, 0xa6, 0xf3, 0x27, 0xfb, 0x08, 0x1e, 0x06, 0x7d, 0xc3, 0x7c, 0x18, 0xf4, 0x17,
+ 0xec, 0x2d, 0x31, 0x73, 0x28, 0x7d, 0x9e, 0x08, 0xfd, 0x33, 0x07, 0x4e, 0xca, 0x06, 0xec, 0xf4,
+ 0x9c, 0xf7, 0x03, 0x16, 0xb9, 0x73, 0xf8, 0xcb, 0xec, 0x75, 0x63, 0x99, 0xbd, 0x68, 0x6f, 0xe0,
+ 0xfa, 0x38, 0xfa, 0x3e, 0xa8, 0xfe, 0xa7, 0x0e, 0x54, 0xf2, 0x1a, 0x1c, 0xc1, 0x27, 0x7f, 0xcd,
+ 0xfc, 0xe4, 0xcf, 0x1f, 0xce, 0xc8, 0xfb, 0x7f, 0xf0, 0x4a, 0xbf, 0x89, 0x42, 0x2d, 0x29, 0x57,
+ 0x39, 0xb6, 0x7c, 0xd2, 0x9c, 0x44, 0xbe, 0x80, 0xd6, 0x82, 0x91, 0x98, 0x45, 0xa9, 0x88, 0x25,
+ 0x70, 0xd1, 0x86, 0xb4, 0x45, 0xf1, 0x09, 0x1b, 0x3b, 0xfb, 0x1f, 0x0b, 0x1a, 0xee, 0x6f, 0x16,
+ 0xe0, 0x8c, 0x7a, 0xf0, 0x97, 0xec, 0x90, 0x56, 0xba, 0x3f, 0xd8, 0x1b, 0x14, 0x9e, 0xfa, 0x69,
+ 0xef, 0x0d, 0x8a, 0x94, 0x44, 0xba, 0x17, 0x52, 0x18, 0xd6, 0x68, 0xa2, 0x2a, 0x9c, 0x62, 0x6f,
+ 0x46, 0x2c, 0xf9, 0x81, 0xd7, 0xf2, 0x5f, 0x25, 0x11, 0x26, 0xed, 0x70, 0xc7, 0x6b, 0x09, 0x49,
+ 0x5d, 0xdd, 0x77, 0x5e, 0xca, 0xab, 0x84, 0xf3, 0xdb, 0xf6, 0x68, 0xdc, 0x43, 0x83, 0x6a, 0xdc,
+ 0xee, 0x9f, 0x38, 0x30, 0x7e, 0x84, 0xcf, 0x23, 0x87, 0xe6, 0x96, 0x78, 0xd6, 0xde, 0x96, 0xe8,
+ 0xb3, 0x0d, 0xf6, 0x8a, 0xd0, 0xf3, 0x62, 0x2c, 0xfa, 0x94, 0xa3, 0xe2, 0x78, 0x78, 0xb0, 0xe4,
+ 0x87, 0xec, 0xf5, 0xe3, 0x20, 0x49, 0x32, 0xd1, 0xd7, 0x32, 0x99, 0x43, 0x0b, 0xb6, 0xd2, 0x5f,
+ 0xf5, 0xf4, 0xe6, 0x0e, 0x32, 0x88, 0x7e, 0xd9, 0x01, 0xe0, 0xfd, 0x14, 0x89, 0xc7, 0x69, 0xdf,
+ 0x36, 0x0f, 0x6d, 0xa6, 0x28, 0x11, 0xde, 0x35, 0xb5, 0x85, 0xd2, 0x02, 0xac, 0xf5, 0xe4, 0x2e,
+ 0x52, 0x83, 0xde, 0x75, 0x56, 0xd2, 0xcf, 0x3b, 0x70, 0x2c, 0xd3, 0xdd, 0x9c, 0xf6, 0x5b, 0xe6,
+ 0x13, 0x88, 0x16, 0x24, 0x2b, 0x33, 0x1d, 0xb5, 0x6e, 0x3c, 0xf9, 0xaf, 0x2e, 0x18, 0x4f, 0x6d,
+ 0xa3, 0xd7, 0xa0, 0x24, 0x2d, 0x1f, 0x72, 0x79, 0xdb, 0x7c, 0x0a, 0x56, 0xa9, 0x37, 0x12, 0x12,
+ 0xe3, 0x94, 0x5e, 0x26, 0x4c, 0xb0, 0x30, 0x50, 0x98, 0xe0, 0xbd, 0x7d, 0x48, 0x36, 0xdf, 0x2e,
+ 0x3d, 0x7c, 0x28, 0x76, 0xe9, 0x07, 0xad, 0xdb, 0xa5, 0x1f, 0x3a, 0x62, 0xbb, 0xb4, 0xe6, 0x24,
+ 0x2c, 0xde, 0x85, 0x93, 0xf0, 0x35, 0x38, 0xb9, 0x93, 0x2a, 0x9d, 0x6a, 0x25, 0x89, 0xa4, 0x4b,
+ 0x4f, 0xe4, 0x5a, 0xa3, 0xa9, 0x02, 0x1d, 0x27, 0x24, 0x48, 0x34, 0x75, 0x35, 0x8d, 0x50, 0x7c,
+ 0x3e, 0x07, 0x1d, 0xce, 0x25, 0x92, 0xf5, 0xf6, 0x8c, 0x0e, 0xe0, 0xed, 0x79, 0xcb, 0x81, 0x53,
+ 0x5e, 0xcf, 0xa5, 0x37, 0x4c, 0xb6, 0x44, 0xc8, 0xc9, 0x35, 0x7b, 0x22, 0x84, 0x81, 0x5e, 0xb8,
+ 0xd5, 0xf2, 0x8a, 0x70, 0x7e, 0x87, 0xd0, 0xa3, 0xa9, 0xeb, 0x9d, 0xc7, 0xb5, 0xe6, 0xfb, 0xc9,
+ 0xbf, 0x96, 0x8d, 0xe7, 0x01, 0x36, 0xf5, 0x1f, 0xb1, 0xab, 0x6d, 0x5b, 0x88, 0xe9, 0x29, 0xdf,
+ 0x45, 0x4c, 0x4f, 0xc6, 0xf5, 0x36, 0x6e, 0xc9, 0xf5, 0x16, 0xc0, 0x94, 0xdf, 0xf6, 0x1a, 0x64,
+ 0xbd, 0xdb, 0x6a, 0xf1, 0x4b, 0x33, 0xf2, 0xb1, 0xde, 0x5c, 0x0b, 0xde, 0xe5, 0xb0, 0xe6, 0xb5,
+ 0xb2, 0xcf, 0xb4, 0xab, 0xcb, 0x41, 0x97, 0x32, 0x98, 0x70, 0x0f, 0x6e, 0xba, 0x60, 0x59, 0xf6,
+ 0x3f, 0x92, 0xd0, 0xd9, 0x66, 0x81, 0x23, 0x63, 0x7c, 0xc1, 0x5e, 0x4c, 0xc1, 0x58, 0xaf, 0x83,
+ 0x56, 0xa0, 0x54, 0x0f, 0x62, 0x71, 0x7f, 0xf7, 0x18, 0x63, 0x66, 0xef, 0xa4, 0x2c, 0x70, 0xf1,
+ 0x4a, 0x55, 0xdd, 0xdc, 0x7d, 0x30, 0x27, 0x9d, 0xa5, 0x2a, 0xc7, 0x69, 0x7b, 0xb4, 0xca, 0x90,
+ 0x89, 0x97, 0xcc, 0x78, 0x3c, 0xc7, 0xc3, 0x7d, 0x1c, 0x46, 0x8b, 0x57, 0xe4, 0x5b, 0x6c, 0x13,
+ 0x82, 0x9c, 0x78, 0x92, 0x2c, 0xc5, 0xa0, 0x3d, 0x9a, 0x7c, 0x7c, 0xdf, 0x47, 0x93, 0x59, 0x1e,
+ 0xdb, 0xa4, 0xa5, 0xdc, 0xc3, 0x67, 0xad, 0xe5, 0xb1, 0x4d, 0x23, 0x25, 0x45, 0x1e, 0xdb, 0x14,
+ 0x80, 0x75, 0x92, 0x68, 0xad, 0x9f, 0x9b, 0xfc, 0x04, 0x63, 0x1a, 0x07, 0x77, 0x7a, 0xeb, 0xfe,
+ 0xd2, 0x93, 0xfb, 0xfa, 0x4b, 0x7b, 0xfc, 0xbb, 0xa7, 0x0e, 0xe0, 0xdf, 0x6d, 0xb2, 0x0c, 0xa3,
+ 0xcb, 0x0b, 0xc2, 0xa5, 0x6e, 0x41, 0xbf, 0x63, 0x39, 0x4d, 0x78, 0xe4, 0x29, 0xfb, 0x17, 0x73,
+ 0x02, 0x7d, 0x03, 0xc8, 0xcf, 0xdc, 0x71, 0x00, 0x39, 0x65, 0xcf, 0x29, 0x9c, 0xa5, 0xaa, 0x2d,
+ 0x0a, 0xf6, 0x9c, 0x82, 0xb1, 0x5e, 0x27, 0xeb, 0x2d, 0xbd, 0xff, 0xd0, 0xbc, 0xa5, 0xd3, 0x47,
+ 0xe0, 0x2d, 0x7d, 0x60, 0x60, 0x6f, 0xe9, 0x0d, 0x38, 0xd1, 0x09, 0xeb, 0x8b, 0x7e, 0x1c, 0x75,
+ 0xd9, 0x2d, 0xc2, 0xf9, 0x6e, 0xbd, 0x41, 0x12, 0xe6, 0x6e, 0x2d, 0x9f, 0x7f, 0xa7, 0xde, 0xc9,
+ 0x0e, 0xdb, 0xc8, 0x72, 0x8f, 0x66, 0x1a, 0x30, 0xd3, 0x09, 0x8b, 0xba, 0xcd, 0x29, 0xc4, 0x79,
+ 0x24, 0x74, 0x3f, 0xed, 0xc3, 0x47, 0xe3, 0xa7, 0xfd, 0x00, 0x8c, 0xc5, 0xcd, 0x6e, 0x52, 0x0f,
+ 0xaf, 0x07, 0xcc, 0x19, 0x5f, 0x9a, 0x7f, 0x87, 0x32, 0x65, 0x0b, 0xf8, 0xad, 0xbd, 0x99, 0x29,
+ 0xf9, 0xbf, 0x66, 0xc5, 0x16, 0x10, 0xf4, 0xf5, 0x3e, 0xf7, 0x95, 0xdc, 0xc3, 0xbc, 0xaf, 0x74,
+ 0xe6, 0x40, 0x77, 0x95, 0xf2, 0x9c, 0xd1, 0x8f, 0xfc, 0xd4, 0x39, 0xa3, 0xbf, 0xea, 0xc0, 0xc4,
+ 0x8e, 0xee, 0x32, 0x10, 0x0e, 0x73, 0x0b, 0x81, 0x3b, 0x86, 0x27, 0x62, 0xde, 0xa5, 0x7c, 0xce,
+ 0x00, 0xdd, 0xca, 0x02, 0xb0, 0xd9, 0x93, 0x9c, 0xa0, 0xa2, 0x47, 0xef, 0x55, 0x50, 0xd1, 0x1b,
+ 0x8c, 0x8f, 0x49, 0x25, 0x97, 0x79, 0xd1, 0xed, 0xc6, 0x14, 0x4b, 0x9e, 0xa8, 0x42, 0x8a, 0x75,
+ 0x7a, 0xe8, 0x73, 0x0e, 0x4c, 0x49, 0xbd, 0x4c, 0xb8, 0xfc, 0x62, 0x11, 0x15, 0x69, 0x53, 0x1d,
+ 0x64, 0x61, 0xf5, 0x1b, 0x19, 0x3a, 0xb8, 0x87, 0x32, 0xe5, 0xea, 0x2a, 0x08, 0xad, 0x11, 0xb3,
+ 0xe0, 0x5f, 0x21, 0xc3, 0xcc, 0xa5, 0x60, 0xac, 0xd7, 0x41, 0xdf, 0x70, 0xa0, 0xd8, 0x0c, 0xc3,
+ 0xed, 0xb8, 0xf2, 0x04, 0x63, 0xe8, 0x2f, 0x58, 0x96, 0x4d, 0x2f, 0x52, 0xdc, 0x5c, 0x28, 0x7d,
+ 0x4a, 0xda, 0x8e, 0x18, 0xec, 0xd6, 0xde, 0xcc, 0xa4, 0xf1, 0x10, 0x53, 0xfc, 0xe6, 0xdb, 0x1a,
+ 0x44, 0xd8, 0x36, 0x59, 0xd7, 0xd0, 0x17, 0x1d, 0x98, 0xba, 0x9e, 0x31, 0x68, 0x88, 0xb0, 0x50,
+ 0x6c, 0xdf, 0x54, 0xc2, 0xa7, 0x3b, 0x0b, 0xc5, 0x3d, 0x3d, 0x40, 0x9f, 0x35, 0x0d, 0x9d, 0x3c,
+ 0x7e, 0xd4, 0xe2, 0x04, 0x66, 0x0c, 0xab, 0xfc, 0x5a, 0x50, 0xbe, 0xc5, 0xf3, 0xae, 0xe3, 0x43,
+ 0xa6, 0xe9, 0x60, 0xd2, 0x8f, 0x95, 0xd3, 0x94, 0x98, 0xf6, 0x16, 0x0b, 0x9b, 0xdd, 0xf8, 0xfc,
+ 0xba, 0xb9, 0xe5, 0x8b, 0xa7, 0x61, 0xd2, 0xf4, 0xed, 0xa1, 0x77, 0x99, 0x8f, 0x6c, 0x9c, 0xcd,
+ 0xbe, 0x57, 0x30, 0x21, 0xeb, 0x1b, 0x6f, 0x16, 0x18, 0x8f, 0x0a, 0x14, 0x0e, 0xf5, 0x51, 0x81,
+ 0xa1, 0xa3, 0x79, 0x54, 0x60, 0xea, 0x30, 0x1e, 0x15, 0x38, 0x7e, 0xa0, 0x47, 0x05, 0xb4, 0x47,
+ 0x1d, 0x86, 0x6f, 0xf3, 0xa8, 0xc3, 0x1c, 0x1c, 0x93, 0x77, 0x7f, 0x88, 0xc8, 0xdb, 0xce, 0xdd,
+ 0xfe, 0x67, 0x44, 0x93, 0x63, 0x0b, 0x66, 0x31, 0xce, 0xd6, 0xa7, 0x9b, 0xac, 0x18, 0xb0, 0x96,
+ 0x23, 0xb6, 0x5e, 0x7c, 0x32, 0x97, 0x16, 0x53, 0x9f, 0x05, 0x8b, 0x92, 0xd1, 0xce, 0x45, 0x06,
+ 0xbb, 0x25, 0xff, 0xc1, 0xbc, 0x07, 0xe8, 0x25, 0xa8, 0x84, 0x5b, 0x5b, 0xad, 0xd0, 0xab, 0xa7,
+ 0x2f, 0x1f, 0xc8, 0xb8, 0x04, 0x7e, 0x57, 0x55, 0x25, 0xca, 0x5d, 0xeb, 0x53, 0x0f, 0xf7, 0xc5,
+ 0x80, 0xde, 0xa2, 0x82, 0x49, 0x12, 0x46, 0xa4, 0x9e, 0xda, 0x6a, 0x4a, 0x6c, 0xcc, 0xc4, 0xfa,
+ 0x98, 0xab, 0x26, 0x1d, 0x3e, 0x7a, 0xf5, 0x51, 0x32, 0xa5, 0x38, 0xdb, 0x2d, 0x14, 0xc1, 0xe9,
+ 0x4e, 0x9e, 0xa9, 0x28, 0x16, 0x37, 0x96, 0xf6, 0x33, 0x58, 0xc9, 0xad, 0x7b, 0x3a, 0xd7, 0xd8,
+ 0x14, 0xe3, 0x3e, 0x98, 0xf5, 0xd7, 0x09, 0xc6, 0x8e, 0xe6, 0x75, 0x82, 0x8f, 0x01, 0xa8, 0x4b,
+ 0xf9, 0xd2, 0xf8, 0xb0, 0x62, 0xe5, 0x2a, 0x0d, 0xc7, 0xa9, 0x3d, 0x08, 0xab, 0xc8, 0x60, 0x8d,
+ 0x24, 0xfa, 0x3f, 0xb9, 0xcf, 0x77, 0x70, 0x0b, 0x4b, 0xc3, 0xfa, 0x9a, 0xf8, 0xa9, 0x7b, 0xc2,
+ 0xe3, 0x1f, 0x39, 0x30, 0xcd, 0x57, 0x5e, 0x56, 0xb8, 0xa7, 0xa2, 0x85, 0xb8, 0xdb, 0x63, 0x3b,
+ 0x74, 0x85, 0x45, 0xf1, 0x55, 0x0d, 0xaa, 0xcc, 0xd1, 0xbd, 0x4f, 0x4f, 0xd0, 0x97, 0x73, 0x54,
+ 0x8a, 0x63, 0xb6, 0x6c, 0x96, 0xf9, 0x8f, 0x30, 0x9c, 0xb8, 0x39, 0x88, 0x16, 0xf1, 0x4f, 0xfa,
+ 0x9a, 0x54, 0x11, 0xeb, 0xde, 0x2f, 0x1e, 0x92, 0x49, 0x55, 0x7f, 0x29, 0xe2, 0x40, 0x86, 0xd5,
+ 0xcf, 0x3b, 0x30, 0xe5, 0x65, 0x42, 0x4d, 0x98, 0x1d, 0xc8, 0x8a, 0x4d, 0x6a, 0x2e, 0x4a, 0xe3,
+ 0x57, 0x98, 0x90, 0x97, 0x8d, 0x6a, 0xc1, 0x3d, 0xc4, 0xd1, 0x0f, 0x1c, 0x78, 0x20, 0xf1, 0xe2,
+ 0x6d, 0x9e, 0x87, 0x39, 0x4e, 0xef, 0xea, 0x8a, 0xce, 0x9d, 0x64, 0xbb, 0xf1, 0x15, 0xeb, 0xbb,
+ 0x71, 0xa3, 0x3f, 0x4d, 0xbe, 0x2f, 0x1f, 0x11, 0xfb, 0xf2, 0x81, 0x7d, 0x6a, 0xe2, 0xfd, 0xba,
+ 0x3e, 0xfd, 0x29, 0x87, 0xbf, 0xd7, 0xd5, 0x57, 0xe4, 0xdb, 0x34, 0x45, 0xbe, 0xcb, 0x36, 0x5f,
+ 0x0c, 0xd2, 0x65, 0xcf, 0x5f, 0x75, 0xe0, 0x64, 0xde, 0x89, 0x94, 0xd3, 0xa5, 0x8f, 0x98, 0x5d,
+ 0xb2, 0xa8, 0x65, 0xe9, 0x1d, 0xb2, 0xf2, 0x60, 0xc9, 0xf4, 0x15, 0x78, 0xf8, 0x76, 0x5f, 0xf1,
+ 0x76, 0xf8, 0xc6, 0x74, 0xb1, 0xf8, 0x4f, 0x4b, 0x9a, 0x17, 0x32, 0x21, 0x1d, 0xeb, 0x31, 0xdc,
+ 0x01, 0x8c, 0xf8, 0x41, 0xcb, 0x0f, 0x88, 0xb8, 0xaf, 0x69, 0x53, 0x87, 0x15, 0x0f, 0x0e, 0x51,
+ 0xec, 0x58, 0x50, 0xb9, 0xc7, 0x4e, 0xc9, 0xec, 0x13, 0x6e, 0xc3, 0x47, 0xff, 0x84, 0xdb, 0x75,
+ 0x28, 0x5d, 0xf7, 0x93, 0x26, 0x0b, 0xa6, 0x10, 0xbe, 0x3e, 0x0b, 0xf7, 0x1c, 0x29, 0xba, 0x74,
+ 0xec, 0xd7, 0x24, 0x01, 0x9c, 0xd2, 0x42, 0xe7, 0x38, 0x61, 0x16, 0xb9, 0x9d, 0x0d, 0xa9, 0xbd,
+ 0x26, 0x0b, 0x70, 0x5a, 0x87, 0x4e, 0xd6, 0x38, 0xfd, 0x25, 0x13, 0x40, 0x89, 0x3c, 0xc5, 0x36,
+ 0xf2, 0x4f, 0x0a, 0x8c, 0xfc, 0x36, 0xf1, 0x35, 0x8d, 0x06, 0x36, 0x28, 0xaa, 0x54, 0xd1, 0x63,
+ 0x7d, 0x53, 0x45, 0xbf, 0xce, 0x04, 0xb6, 0xc4, 0x0f, 0xba, 0x64, 0x2d, 0x10, 0xf1, 0xde, 0x97,
+ 0xed, 0xdc, 0x7d, 0xe6, 0x38, 0xb9, 0x0a, 0x9e, 0xfe, 0xc6, 0x1a, 0x3d, 0xcd, 0xe5, 0x52, 0xde,
+ 0xd7, 0xe5, 0x92, 0x9a, 0x5c, 0xc6, 0xad, 0x9b, 0x5c, 0x12, 0xd2, 0xb1, 0x62, 0x72, 0xf9, 0xa9,
+ 0x32, 0x07, 0xfc, 0xb9, 0x03, 0x48, 0xc9, 0x5d, 0x8a, 0xa1, 0x1e, 0x41, 0x50, 0xe5, 0xc7, 0x1d,
+ 0x80, 0x40, 0x3d, 0xf4, 0x69, 0xf7, 0x14, 0xe4, 0x38, 0xd3, 0x0e, 0xa4, 0x30, 0xac, 0xd1, 0x74,
+ 0xff, 0xbb, 0x93, 0xc6, 0x2e, 0xa7, 0x63, 0x3f, 0x82, 0x20, 0xb2, 0x5d, 0x33, 0x88, 0x6c, 0xc3,
+ 0xa2, 0xe9, 0x5e, 0x0d, 0xa3, 0x4f, 0x38, 0xd9, 0x8f, 0x0b, 0x70, 0x4c, 0xaf, 0x5c, 0x25, 0x47,
+ 0xf1, 0xb1, 0xaf, 0x1b, 0x11, 0xb4, 0x57, 0xed, 0x8e, 0xb7, 0x2a, 0x3c, 0x40, 0x79, 0xd1, 0xda,
+ 0x1f, 0xcb, 0x44, 0x6b, 0x5f, 0xb3, 0x4f, 0x7a, 0xff, 0x90, 0xed, 0xff, 0xe2, 0xc0, 0x89, 0x4c,
+ 0x8b, 0x23, 0x58, 0x60, 0x3b, 0xe6, 0x02, 0x7b, 0xce, 0xfa, 0xa8, 0xfb, 0xac, 0xae, 0x6f, 0x16,
+ 0x7a, 0x46, 0xcb, 0x94, 0xb8, 0x4f, 0x3a, 0x50, 0xa4, 0xd2, 0xb2, 0x8c, 0xe7, 0xfa, 0xc8, 0xa1,
+ 0xac, 0x00, 0x26, 0xd7, 0x0b, 0xee, 0xac, 0xfa, 0xc7, 0x60, 0x98, 0x53, 0x9f, 0xfe, 0x84, 0x03,
+ 0x90, 0x56, 0xba, 0x57, 0x22, 0xb0, 0xfb, 0xed, 0x02, 0x9c, 0xca, 0x5d, 0x46, 0xe8, 0xd3, 0xca,
+ 0x22, 0xe7, 0xd8, 0x8e, 0x56, 0x34, 0x08, 0xe9, 0x86, 0xb9, 0x09, 0xc3, 0x30, 0x27, 0xec, 0x71,
+ 0xf7, 0x4a, 0x81, 0x11, 0x6c, 0x5a, 0x9b, 0xac, 0x1f, 0x39, 0x69, 0x00, 0xac, 0xca, 0x6b, 0xf4,
+ 0x17, 0xf0, 0x12, 0x8f, 0xfb, 0x63, 0xed, 0x86, 0x83, 0x1c, 0xe8, 0x11, 0xf0, 0x8a, 0xeb, 0x26,
+ 0xaf, 0xc0, 0xf6, 0xfd, 0xc8, 0x7d, 0x98, 0xc5, 0x2b, 0x90, 0xe7, 0x58, 0x1e, 0x2c, 0x09, 0xa4,
+ 0x71, 0x1d, 0xb6, 0x30, 0xf0, 0x75, 0xd8, 0x09, 0x28, 0xbf, 0xe8, 0xab, 0xec, 0xa1, 0xf3, 0xb3,
+ 0xdf, 0xf9, 0xe1, 0xd9, 0xfb, 0xbe, 0xfb, 0xc3, 0xb3, 0xf7, 0xfd, 0xe0, 0x87, 0x67, 0xef, 0xfb,
+ 0xf8, 0xcd, 0xb3, 0xce, 0x77, 0x6e, 0x9e, 0x75, 0xbe, 0x7b, 0xf3, 0xac, 0xf3, 0x83, 0x9b, 0x67,
+ 0x9d, 0x7f, 0x77, 0xf3, 0xac, 0xf3, 0x77, 0xfe, 0xfd, 0xd9, 0xfb, 0x5e, 0x1c, 0x93, 0x03, 0xfb,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x1f, 0x04, 0xde, 0xd2, 0xd7, 0x00, 0x00,
}
func (m *Amount) Marshal() (dAtA []byte, err error) {
@@ -11323,6 +11325,34 @@ func (m *Synchronization) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.Mutexes) > 0 {
+ for iNdEx := len(m.Mutexes) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Mutexes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x22
+ }
+ }
+ if len(m.Semaphores) > 0 {
+ for iNdEx := len(m.Semaphores) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Semaphores[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
if m.Mutex != nil {
{
size, err := m.Mutex.MarshalToSizedBuffer(dAtA[:i])
@@ -16404,6 +16434,18 @@ func (m *Synchronization) Size() (n int) {
l = m.Mutex.Size()
n += 1 + l + sovGenerated(uint64(l))
}
+ if len(m.Semaphores) > 0 {
+ for _, e := range m.Semaphores {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ if len(m.Mutexes) > 0 {
+ for _, e := range m.Mutexes {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
return n
}
@@ -19013,9 +19055,21 @@ func (this *Synchronization) String() string {
if this == nil {
return "nil"
}
+ repeatedStringForSemaphores := "[]*SemaphoreRef{"
+ for _, f := range this.Semaphores {
+ repeatedStringForSemaphores += strings.Replace(f.String(), "SemaphoreRef", "SemaphoreRef", 1) + ","
+ }
+ repeatedStringForSemaphores += "}"
+ repeatedStringForMutexes := "[]*Mutex{"
+ for _, f := range this.Mutexes {
+ repeatedStringForMutexes += strings.Replace(f.String(), "Mutex", "Mutex", 1) + ","
+ }
+ repeatedStringForMutexes += "}"
s := strings.Join([]string{`&Synchronization{`,
`Semaphore:` + strings.Replace(this.Semaphore.String(), "SemaphoreRef", "SemaphoreRef", 1) + `,`,
`Mutex:` + strings.Replace(this.Mutex.String(), "Mutex", "Mutex", 1) + `,`,
+ `Semaphores:` + repeatedStringForSemaphores + `,`,
+ `Mutexes:` + repeatedStringForMutexes + `,`,
`}`,
}, "")
return s
@@ -38997,6 +39051,74 @@ func (m *Synchronization) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Semaphores", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Semaphores = append(m.Semaphores, &SemaphoreRef{})
+ if err := m.Semaphores[len(m.Semaphores)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Mutexes", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Mutexes = append(m.Mutexes, &Mutex{})
+ if err := m.Mutexes[len(m.Mutexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto
index 75daf99022cb..67cf02491ae7 100644
--- a/pkg/apis/workflow/v1alpha1/generated.proto
+++ b/pkg/apis/workflow/v1alpha1/generated.proto
@@ -1551,11 +1551,17 @@ message SuspendTemplate {
// Synchronization holds synchronization lock configuration
message Synchronization {
- // Semaphore holds the Semaphore configuration
+ // Semaphore holds the Semaphore configuration - deprecated, use semaphores instead
optional SemaphoreRef semaphore = 1;
- // Mutex holds the Mutex lock details
+ // Mutex holds the Mutex lock details - deprecated, use mutexes instead
optional Mutex mutex = 2;
+
+ // Semaphores holds the list of Semaphores configuration
+ repeated SemaphoreRef semaphores = 3;
+
+ // Mutexes holds the list of Mutex lock details
+ repeated Mutex mutexes = 4;
}
// SynchronizationStatus stores the status of semaphore and mutex.
diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go
index 56d15884603e..830664678343 100644
--- a/pkg/apis/workflow/v1alpha1/openapi_generated.go
+++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go
@@ -6019,16 +6019,42 @@ func schema_pkg_apis_workflow_v1alpha1_Synchronization(ref common.ReferenceCallb
Properties: map[string]spec.Schema{
"semaphore": {
SchemaProps: spec.SchemaProps{
- Description: "Semaphore holds the Semaphore configuration",
+ Description: "Semaphore holds the Semaphore configuration - deprecated, use semaphores instead",
Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SemaphoreRef"),
},
},
"mutex": {
SchemaProps: spec.SchemaProps{
- Description: "Mutex holds the Mutex lock details",
+ Description: "Mutex holds the Mutex lock details - deprecated, use mutexes instead",
Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Mutex"),
},
},
+ "semaphores": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Semaphores holds the list of Semaphores configuration",
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.SemaphoreRef"),
+ },
+ },
+ },
+ },
+ },
+ "mutexes": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Mutexes holds the list of Mutex lock details",
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Mutex"),
+ },
+ },
+ },
+ },
+ },
},
},
},
diff --git a/pkg/apis/workflow/v1alpha1/workflow_types.go b/pkg/apis/workflow/v1alpha1/workflow_types.go
index c7ac0c2e4f27..94bd3685d98a 100644
--- a/pkg/apis/workflow/v1alpha1/workflow_types.go
+++ b/pkg/apis/workflow/v1alpha1/workflow_types.go
@@ -1628,10 +1628,14 @@ type TemplateRef struct {
// Synchronization holds synchronization lock configuration
type Synchronization struct {
- // Semaphore holds the Semaphore configuration
+ // Semaphore holds the Semaphore configuration - deprecated, use semaphores instead
Semaphore *SemaphoreRef `json:"semaphore,omitempty" protobuf:"bytes,1,opt,name=semaphore"`
- // Mutex holds the Mutex lock details
+ // Mutex holds the Mutex lock details - deprecated, use mutexes instead
Mutex *Mutex `json:"mutex,omitempty" protobuf:"bytes,2,opt,name=mutex"`
+ // Semaphores holds the list of Semaphores configuration
+ Semaphores []*SemaphoreRef `json:"semaphores,omitempty" protobuf:"bytes,3,opt,name=semaphores"`
+ // Mutexes holds the list of Mutex lock details
+ Mutexes []*Mutex `json:"mutexes,omitempty" protobuf:"bytes,4,opt,name=mutexes"`
}
func (s *Synchronization) getSemaphoreConfigMapRef() *apiv1.ConfigMapKeySelector {
@@ -1641,23 +1645,6 @@ func (s *Synchronization) getSemaphoreConfigMapRef() *apiv1.ConfigMapKeySelector
return nil
}
-type SynchronizationType string
-
-const (
- SynchronizationTypeSemaphore SynchronizationType = "Semaphore"
- SynchronizationTypeMutex SynchronizationType = "Mutex"
- SynchronizationTypeUnknown SynchronizationType = "Unknown"
-)
-
-func (s *Synchronization) GetType() SynchronizationType {
- if s.Semaphore != nil {
- return SynchronizationTypeSemaphore
- } else if s.Mutex != nil {
- return SynchronizationTypeMutex
- }
- return SynchronizationTypeUnknown
-}
-
// SemaphoreRef is a reference of Semaphore
type SemaphoreRef struct {
// ConfigMapKeyRef is configmap selector for Semaphore configuration
@@ -3880,6 +3867,14 @@ type SynchronizationStatus struct {
Mutex *MutexStatus `json:"mutex,omitempty" protobuf:"bytes,2,opt,name=mutex"`
}
+type SynchronizationType string
+
+const (
+ SynchronizationTypeSemaphore SynchronizationType = "Semaphore"
+ SynchronizationTypeMutex SynchronizationType = "Mutex"
+ SynchronizationTypeUnknown SynchronizationType = "Unknown"
+)
+
func (ss *SynchronizationStatus) GetStatus(syncType SynchronizationType) SynchronizationAction {
switch syncType {
case SynchronizationTypeSemaphore:
diff --git a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go
index f71aca040c98..fea752614a6f 100644
--- a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go
@@ -3055,6 +3055,28 @@ func (in *Synchronization) DeepCopyInto(out *Synchronization) {
*out = new(Mutex)
**out = **in
}
+ if in.Semaphores != nil {
+ in, out := &in.Semaphores, &out.Semaphores
+ *out = make([]*SemaphoreRef, len(*in))
+ for i := range *in {
+ if (*in)[i] != nil {
+ in, out := &(*in)[i], &(*out)[i]
+ *out = new(SemaphoreRef)
+ (*in).DeepCopyInto(*out)
+ }
+ }
+ }
+ if in.Mutexes != nil {
+ in, out := &in.Mutexes, &out.Mutexes
+ *out = make([]*Mutex, len(*in))
+ for i := range *in {
+ if (*in)[i] != nil {
+ in, out := &(*in)[i], &(*out)[i]
+ *out = new(Mutex)
+ **out = **in
+ }
+ }
+ }
return
}
diff --git a/pkg/plugins/executor/swagger.yml b/pkg/plugins/executor/swagger.yml
index a503bffe916b..dbb877f5fc99 100644
--- a/pkg/plugins/executor/swagger.yml
+++ b/pkg/plugins/executor/swagger.yml
@@ -3933,8 +3933,18 @@ definitions:
properties:
mutex:
$ref: '#/definitions/Mutex'
+ mutexes:
+ description: Mutexes holds the list of Mutex lock details
+ items:
+ $ref: '#/definitions/Mutex'
+ type: array
semaphore:
$ref: '#/definitions/SemaphoreRef'
+ semaphores:
+ description: Semaphores holds the list of Semaphores configuration
+ items:
+ $ref: '#/definitions/SemaphoreRef'
+ type: array
type: object
Sysctl:
description: Sysctl defines a kernel parameter to be set
diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md
index ac9b866bb953..310e05a2f1d6 100644
--- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md
+++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md
@@ -9,7 +9,9 @@ Synchronization holds synchronization lock configuration
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**mutex** | [**IoArgoprojWorkflowV1alpha1Mutex**](IoArgoprojWorkflowV1alpha1Mutex.md) | | [optional]
+**mutexes** | [**List<IoArgoprojWorkflowV1alpha1Mutex>**](IoArgoprojWorkflowV1alpha1Mutex.md) | Mutexes holds the list of Mutex lock details | [optional]
**semaphore** | [**IoArgoprojWorkflowV1alpha1SemaphoreRef**](IoArgoprojWorkflowV1alpha1SemaphoreRef.md) | | [optional]
+**semaphores** | [**List<IoArgoprojWorkflowV1alpha1SemaphoreRef>**](IoArgoprojWorkflowV1alpha1SemaphoreRef.md) | Semaphores holds the list of Semaphores configuration | [optional]
diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_synchronization.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_synchronization.py
index 3c3a131cbb58..95fa013e6b89 100644
--- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_synchronization.py
+++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_synchronization.py
@@ -90,7 +90,9 @@ def openapi_types():
lazy_import()
return {
'mutex': (IoArgoprojWorkflowV1alpha1Mutex,), # noqa: E501
+ 'mutexes': ([IoArgoprojWorkflowV1alpha1Mutex],), # noqa: E501
'semaphore': (IoArgoprojWorkflowV1alpha1SemaphoreRef,), # noqa: E501
+ 'semaphores': ([IoArgoprojWorkflowV1alpha1SemaphoreRef],), # noqa: E501
}
@cached_property
@@ -100,7 +102,9 @@ def discriminator():
attribute_map = {
'mutex': 'mutex', # noqa: E501
+ 'mutexes': 'mutexes', # noqa: E501
'semaphore': 'semaphore', # noqa: E501
+ 'semaphores': 'semaphores', # noqa: E501
}
read_only_vars = {
@@ -145,7 +149,9 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501
through its discriminator because we passed in
_visited_composed_classes = (Animal,)
mutex (IoArgoprojWorkflowV1alpha1Mutex): [optional] # noqa: E501
+ mutexes ([IoArgoprojWorkflowV1alpha1Mutex]): Mutexes holds the list of Mutex lock details. [optional] # noqa: E501
semaphore (IoArgoprojWorkflowV1alpha1SemaphoreRef): [optional] # noqa: E501
+ semaphores ([IoArgoprojWorkflowV1alpha1SemaphoreRef]): Semaphores holds the list of Semaphores configuration. [optional] # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)
@@ -228,7 +234,9 @@ def __init__(self, *args, **kwargs): # noqa: E501
through its discriminator because we passed in
_visited_composed_classes = (Animal,)
mutex (IoArgoprojWorkflowV1alpha1Mutex): [optional] # noqa: E501
+ mutexes ([IoArgoprojWorkflowV1alpha1Mutex]): Mutexes holds the list of Mutex lock details. [optional] # noqa: E501
semaphore (IoArgoprojWorkflowV1alpha1SemaphoreRef): [optional] # noqa: E501
+ semaphores ([IoArgoprojWorkflowV1alpha1SemaphoreRef]): Semaphores holds the list of Semaphores configuration. [optional] # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)
diff --git a/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md b/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md
index 5f2d50121d95..9899b6feb953 100644
--- a/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md
+++ b/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md
@@ -1059,6 +1059,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -1067,6 +1073,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -5243,6 +5259,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -5251,6 +5273,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -9810,6 +9842,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -9818,6 +9856,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -11993,6 +12041,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -12001,6 +12055,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -16177,6 +16241,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -16185,6 +16255,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -20744,6 +20824,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -20752,6 +20838,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -22831,6 +22927,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -22839,6 +22941,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -27015,6 +27127,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -27023,6 +27141,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -31582,6 +31710,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -31590,6 +31724,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
diff --git a/sdks/python/client/docs/CronWorkflowServiceApi.md b/sdks/python/client/docs/CronWorkflowServiceApi.md
index 455b2749c5cd..66c1fda4f708 100644
--- a/sdks/python/client/docs/CronWorkflowServiceApi.md
+++ b/sdks/python/client/docs/CronWorkflowServiceApi.md
@@ -1119,6 +1119,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -1127,6 +1133,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -5303,6 +5319,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -5311,6 +5333,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -9870,6 +9902,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -9878,6 +9916,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -12135,6 +12183,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -12143,6 +12197,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -16319,6 +16383,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -16327,6 +16397,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -20886,6 +20966,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -20894,6 +20980,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -23236,6 +23332,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -23244,6 +23346,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -27420,6 +27532,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -27428,6 +27546,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -31987,6 +32115,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -31995,6 +32129,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md
index fc8ba3f2e9c5..829ce269c1fc 100644
--- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md
+++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Synchronization.md
@@ -6,7 +6,9 @@ Synchronization holds synchronization lock configuration
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**mutex** | [**IoArgoprojWorkflowV1alpha1Mutex**](IoArgoprojWorkflowV1alpha1Mutex.md) | | [optional]
+**mutexes** | [**[IoArgoprojWorkflowV1alpha1Mutex]**](IoArgoprojWorkflowV1alpha1Mutex.md) | Mutexes holds the list of Mutex lock details | [optional]
**semaphore** | [**IoArgoprojWorkflowV1alpha1SemaphoreRef**](IoArgoprojWorkflowV1alpha1SemaphoreRef.md) | | [optional]
+**semaphores** | [**[IoArgoprojWorkflowV1alpha1SemaphoreRef]**](IoArgoprojWorkflowV1alpha1SemaphoreRef.md) | Semaphores holds the list of Semaphores configuration | [optional]
**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 4296e4211333..e146a7826221 100644
--- a/sdks/python/client/docs/WorkflowServiceApi.md
+++ b/sdks/python/client/docs/WorkflowServiceApi.md
@@ -1074,6 +1074,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -1082,6 +1088,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -5258,6 +5274,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -5266,6 +5288,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -9825,6 +9857,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -9833,6 +9871,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -16305,6 +16353,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -16313,6 +16367,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -17652,6 +17716,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -17660,6 +17730,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -21836,6 +21916,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -21844,6 +21930,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -26403,6 +26499,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -26411,6 +26513,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -28628,6 +28740,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -28636,6 +28754,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -32812,6 +32940,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -32820,6 +32954,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -37379,6 +37523,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -37387,6 +37537,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -43859,6 +44019,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -43867,6 +44033,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -45206,6 +45382,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -45214,6 +45396,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -49390,6 +49582,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -49398,6 +49596,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -53957,6 +54165,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -53965,6 +54179,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
diff --git a/sdks/python/client/docs/WorkflowTemplateServiceApi.md b/sdks/python/client/docs/WorkflowTemplateServiceApi.md
index 8f9032d97d57..9db55c5dfdc2 100644
--- a/sdks/python/client/docs/WorkflowTemplateServiceApi.md
+++ b/sdks/python/client/docs/WorkflowTemplateServiceApi.md
@@ -1061,6 +1061,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -1069,6 +1075,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -5245,6 +5261,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -5253,6 +5275,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -9812,6 +9844,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -9820,6 +9858,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -12002,6 +12050,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -12010,6 +12064,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -16186,6 +16250,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -16194,6 +16264,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -20753,6 +20833,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -20761,6 +20847,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -22854,6 +22950,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -22862,6 +22964,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
template_defaults=IoArgoprojWorkflowV1alpha1Template(
active_deadline_seconds="active_deadline_seconds_example",
@@ -27038,6 +27150,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -27046,6 +27164,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
@@ -31605,6 +31733,12 @@ with argo_workflows.ApiClient(configuration) as api_client:
name="name_example",
namespace="namespace_example",
),
+ mutexes=[
+ IoArgoprojWorkflowV1alpha1Mutex(
+ name="name_example",
+ namespace="namespace_example",
+ ),
+ ],
semaphore=IoArgoprojWorkflowV1alpha1SemaphoreRef(
config_map_key_ref=ConfigMapKeySelector(
key="key_example",
@@ -31613,6 +31747,16 @@ with argo_workflows.ApiClient(configuration) as api_client:
),
namespace="namespace_example",
),
+ semaphores=[
+ IoArgoprojWorkflowV1alpha1SemaphoreRef(
+ config_map_key_ref=ConfigMapKeySelector(
+ key="key_example",
+ name="name_example",
+ optional=True,
+ ),
+ namespace="namespace_example",
+ ),
+ ],
),
timeout="timeout_example",
tolerations=[
diff --git a/test/e2e/functional/synchronization-legacy-mutex-semaphore.yaml b/test/e2e/functional/synchronization-legacy-mutex-semaphore.yaml
new file mode 100644
index 000000000000..e74226cf818a
--- /dev/null
+++ b/test/e2e/functional/synchronization-legacy-mutex-semaphore.yaml
@@ -0,0 +1,31 @@
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ generateName: synchronization-legacy-
+spec:
+ entrypoint: main
+ templates:
+ - name: main
+ steps:
+ - - name: task-1
+ template: django-command
+ - name: task-2
+ template: load-command
+
+ - name: load-command
+ synchronization:
+ mutex:
+ name: task-1
+ container:
+ image: argoproj/argosay:v2
+ args: ["sleep", "2s"]
+
+ - name: django-command
+ synchronization:
+ semaphore:
+ configMapKeyRef:
+ name: my-config
+ key: workflow
+ container:
+ image: argoproj/argosay:v2
+ args: ["sleep", "2s"]
diff --git a/test/e2e/functional/synchronization-multiple.yaml b/test/e2e/functional/synchronization-multiple.yaml
new file mode 100644
index 000000000000..5293a2a5bb2d
--- /dev/null
+++ b/test/e2e/functional/synchronization-multiple.yaml
@@ -0,0 +1,39 @@
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ generateName: synchronization-multiple-
+spec:
+ entrypoint: main
+ templates:
+ - name: main
+ steps:
+ - - name: task-1
+ template: django-command
+ - name: task-2
+ template: load-command
+
+ - name: load-command
+ synchronization:
+ mutexes:
+ - name: load-1
+ - name: load-2
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
+ container:
+ image: argoproj/argosay:v2
+ args: ["sleep", "2s"]
+
+ - name: django-command
+ synchronization:
+ mutexes:
+ - name: django-1
+ - name: django-2
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
+ container:
+ image: argoproj/argosay:v2
+ args: ["sleep", "2s"]
diff --git a/test/e2e/functional/synchronization-mutex-tmpl-level.yaml b/test/e2e/functional/synchronization-mutex-tmpl-level.yaml
index dd6e011941e1..b59836cc0bb2 100644
--- a/test/e2e/functional/synchronization-mutex-tmpl-level.yaml
+++ b/test/e2e/functional/synchronization-mutex-tmpl-level.yaml
@@ -25,16 +25,16 @@ spec:
- name: acquire-lock
synchronization:
- mutex:
- name: welcome
+ mutexes:
+ - name: welcome
container:
image: argoproj/argosay:v2
args: ["sleep", "2s"]
- name: acquire-lock-1
synchronization:
- mutex:
- name: test
+ mutexes:
+ - name: test
container:
image: argoproj/argosay:v2
args: ["sleep", "2s"]
\ No newline at end of file
diff --git a/test/e2e/functional/synchronization-mutex-wf-level-1.yaml b/test/e2e/functional/synchronization-mutex-wf-level-1.yaml
index e55b50f99ab8..84618ec9686a 100644
--- a/test/e2e/functional/synchronization-mutex-wf-level-1.yaml
+++ b/test/e2e/functional/synchronization-mutex-wf-level-1.yaml
@@ -5,8 +5,8 @@ metadata:
spec:
entrypoint: main
synchronization:
- mutex:
- name: test
+ mutexes:
+ - name: test
templates:
- name: main
container:
diff --git a/test/e2e/functional/synchronization-mutex-wf-level.yaml b/test/e2e/functional/synchronization-mutex-wf-level.yaml
index 94a0deeaac90..b52dc7771d9c 100644
--- a/test/e2e/functional/synchronization-mutex-wf-level.yaml
+++ b/test/e2e/functional/synchronization-mutex-wf-level.yaml
@@ -5,8 +5,8 @@ metadata:
spec:
entrypoint: main
synchronization:
- mutex:
- name: test
+ mutexes:
+ - name: test
templates:
- name: main
container:
diff --git a/test/e2e/functional/synchronization-tmpl-level-mutex-semaphore.yaml b/test/e2e/functional/synchronization-tmpl-level-mutex-semaphore.yaml
index 824a6501bcb3..e4831352b82b 100644
--- a/test/e2e/functional/synchronization-tmpl-level-mutex-semaphore.yaml
+++ b/test/e2e/functional/synchronization-tmpl-level-mutex-semaphore.yaml
@@ -11,22 +11,24 @@ spec:
template: django-command
- name: task-2
template: load-command
-
+
- name: load-command
synchronization:
- mutex:
- name: task-1
+ mutexes:
+ - name: task-1
container:
image: argoproj/argosay:v2
args: ["sleep", "2s"]
-
+
- name: django-command
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: workflow
+ mutexes:
+ - name: task-1
+ - name: task-2
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
container:
image: argoproj/argosay:v2
args: ["sleep", "2s"]
-
diff --git a/test/e2e/hooks_test.go b/test/e2e/hooks_test.go
index db5e49419b00..47eb29265ada 100644
--- a/test/e2e/hooks_test.go
+++ b/test/e2e/hooks_test.go
@@ -536,8 +536,8 @@ spec:
template: sleep
- name: sleep
synchronization:
- mutex:
- name: job
+ mutexes:
+ - name: job
script:
image: alpine:latest
command: [/bin/sh]
diff --git a/test/e2e/semaphore_test.go b/test/e2e/semaphore_test.go
index 670a31936582..d2d4d3125a3e 100644
--- a/test/e2e/semaphore_test.go
+++ b/test/e2e/semaphore_test.go
@@ -82,6 +82,25 @@ func (s *SemaphoreSuite) TestSynchronizationTmplLevelMutexAndSemaphore() {
WaitForWorkflow(fixtures.ToBeSucceeded, 90*time.Second)
}
+func (s *SemaphoreSuite) TestSynchronizationMultiple() {
+ s.Given().
+ Workflow("@functional/synchronization-multiple.yaml").
+ When().
+ CreateConfigMap("my-config", map[string]string{"workflow": "2"}, map[string]string{}).
+ SubmitWorkflow().
+ WaitForWorkflow(fixtures.ToBeSucceeded, 90*time.Second)
+}
+
+// Legacy CRD entries: mutex and semaphore
+func (s *SemaphoreSuite) TestSynchronizationLegacyMutexAndSemaphore() {
+ s.Given().
+ Workflow("@functional/synchronization-legacy-mutex-semaphore.yaml").
+ When().
+ CreateConfigMap("my-config", map[string]string{"workflow": "1"}, map[string]string{}).
+ SubmitWorkflow().
+ WaitForWorkflow(fixtures.ToBeSucceeded, 90*time.Second)
+}
+
func TestSemaphoreSuite(t *testing.T) {
suite.Run(t, new(SemaphoreSuite))
}
diff --git a/test/e2e/testdata/semaphore-tmpl-level.yaml b/test/e2e/testdata/semaphore-tmpl-level.yaml
index 049c531a1d1a..d4eee390b26f 100644
--- a/test/e2e/testdata/semaphore-tmpl-level.yaml
+++ b/test/e2e/testdata/semaphore-tmpl-level.yaml
@@ -22,9 +22,9 @@ spec:
parameters:
- name: seconds
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: template
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: template
container:
image: argoproj/argosay:v2
diff --git a/test/e2e/testdata/semaphore-wf-level-1.yaml b/test/e2e/testdata/semaphore-wf-level-1.yaml
index 16bb45c5069a..9f8c1bd88b80 100644
--- a/test/e2e/testdata/semaphore-wf-level-1.yaml
+++ b/test/e2e/testdata/semaphore-wf-level-1.yaml
@@ -5,10 +5,10 @@ metadata:
spec:
entrypoint: whalesay
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: workflow
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
templates:
- name: whalesay
container:
diff --git a/test/e2e/testdata/semaphore-wf-level.yaml b/test/e2e/testdata/semaphore-wf-level.yaml
index 09d99bfd5d7a..765daae2fe52 100644
--- a/test/e2e/testdata/semaphore-wf-level.yaml
+++ b/test/e2e/testdata/semaphore-wf-level.yaml
@@ -5,10 +5,10 @@ metadata:
spec:
entrypoint: whalesay
synchronization:
- semaphore:
- configMapKeyRef:
- name: my-config
- key: workflow
+ semaphores:
+ - configMapKeyRef:
+ name: my-config
+ key: workflow
templates:
- name: whalesay
container:
diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go
index df300d9959b8..aca294f71562 100644
--- a/workflow/controller/operator.go
+++ b/workflow/controller/operator.go
@@ -60,7 +60,6 @@ import (
"github.com/argoproj/argo-workflows/v3/workflow/controller/indexes"
"github.com/argoproj/argo-workflows/v3/workflow/metrics"
"github.com/argoproj/argo-workflows/v3/workflow/progress"
- argosync "github.com/argoproj/argo-workflows/v3/workflow/sync"
"github.com/argoproj/argo-workflows/v3/workflow/templateresolution"
wfutil "github.com/argoproj/argo-workflows/v3/workflow/util"
"github.com/argoproj/argo-workflows/v3/workflow/validate"
@@ -252,9 +251,9 @@ func (woc *wfOperationCtx) operate(ctx context.Context) {
// Workflow Level Synchronization lock
if woc.execWf.Spec.Synchronization != nil {
- acquired, wfUpdate, msg, err := woc.controller.syncManager.TryAcquire(woc.wf, "", woc.execWf.Spec.Synchronization)
+ acquired, wfUpdate, msg, failedLockName, err := woc.controller.syncManager.TryAcquire(woc.wf, "", woc.execWf.Spec.Synchronization)
if err != nil {
- woc.log.Warn("Failed to acquire the lock")
+ woc.log.Warnf("Failed to acquire the lock %s", failedLockName)
woc.markWorkflowFailed(ctx, fmt.Sprintf("Failed to acquire the synchronization lock. %s", err.Error()))
return
}
@@ -1965,7 +1964,7 @@ func (woc *wfOperationCtx) executeTemplate(ctx context.Context, nodeName string,
unlockedNode := false
if processedTmpl.Synchronization != nil {
- lockAcquired, wfUpdated, msg, err := woc.controller.syncManager.TryAcquire(woc.wf, woc.wf.NodeID(nodeName), processedTmpl.Synchronization)
+ lockAcquired, wfUpdated, msg, failedLockName, err := woc.controller.syncManager.TryAcquire(woc.wf, woc.wf.NodeID(nodeName), processedTmpl.Synchronization)
if err != nil {
return woc.initializeNodeOrMarkError(node, nodeName, templateScope, orgTmpl, opts.boundaryID, opts.nodeFlag, err), err
}
@@ -1973,14 +1972,8 @@ func (woc *wfOperationCtx) executeTemplate(ctx context.Context, nodeName string,
if node == nil {
node = woc.initializeExecutableNode(nodeName, wfutil.GetNodeType(processedTmpl), templateScope, processedTmpl, orgTmpl, opts.boundaryID, wfv1.NodePending, opts.nodeFlag, msg)
}
- lockName, err := argosync.GetLockName(processedTmpl.Synchronization, woc.wf.Namespace)
- if err != nil {
- // If an error were to be returned here, it would have been caught by TryAcquire. If it didn't, then it is
- // unexpected behavior and is a bug.
- panic("bug: GetLockName should not return an error after a call to TryAcquire")
- }
- woc.log.Infof("Could not acquire lock named: %s", lockName)
- return woc.markNodeWaitingForLock(node.Name, lockName.EncodeName())
+ woc.log.Infof("Could not acquire lock named: %s", failedLockName)
+ return woc.markNodeWaitingForLock(node.Name, failedLockName)
} else {
woc.log.Infof("Node %s acquired synchronization lock", nodeName)
if node != nil {
diff --git a/workflow/controller/operator_test.go b/workflow/controller/operator_test.go
index 3cbc7b1990ce..740a1e3a3c70 100644
--- a/workflow/controller/operator_test.go
+++ b/workflow/controller/operator_test.go
@@ -8564,7 +8564,7 @@ func TestMutexWfPendingWithNoPod(t *testing.T) {
ctx := context.Background()
controller.syncManager = sync.NewLockManager(GetSyncLimitFunc(ctx, controller.kubeclientset), func(key string) {
}, workflowExistenceFunc)
- _, _, _, err := controller.syncManager.TryAcquire(wf, "test", &wfv1.Synchronization{Mutex: &wfv1.Mutex{Name: "welcome"}})
+ _, _, _, _, err := controller.syncManager.TryAcquire(wf, "test", &wfv1.Synchronization{Mutex: &wfv1.Mutex{Name: "welcome"}})
assert.NoError(t, err)
woc := newWorkflowOperationCtx(wf, controller)
@@ -8573,7 +8573,7 @@ func TestMutexWfPendingWithNoPod(t *testing.T) {
assert.Equal(t, wfv1.NodePending, woc.wf.Status.Nodes.FindByDisplayName("hello-world-mpdht").Phase)
}
-var wfGlopalArtifactNil = `apiVersion: argoproj.io/v1alpha1
+var wfGlobalArtifactNil = `apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: global-outputs-ttsfq
@@ -8643,7 +8643,7 @@ spec:
`
func TestWFGlobalArtifactNil(t *testing.T) {
- wf := wfv1.MustUnmarshalWorkflow(wfGlopalArtifactNil)
+ wf := wfv1.MustUnmarshalWorkflow(wfGlobalArtifactNil)
cancel, controller := newController(wf)
defer cancel()
diff --git a/workflow/sync/common.go b/workflow/sync/common.go
index b4a19e9c5c84..182bf2ca07b7 100644
--- a/workflow/sync/common.go
+++ b/workflow/sync/common.go
@@ -2,8 +2,9 @@ package sync
import "time"
-type Semaphore interface {
+type semaphore interface {
acquire(holderKey string) bool
+ checkAcquire(holderKey string) (bool, bool, string)
tryAcquire(holderKey string) (bool, string)
release(key string) bool
addToQueue(holderKey string, priority int32, creationTime time.Time)
diff --git a/workflow/sync/lock_name.go b/workflow/sync/lock_name.go
index 248d7e41b8d3..41d9902af8e1 100644
--- a/workflow/sync/lock_name.go
+++ b/workflow/sync/lock_name.go
@@ -8,22 +8,22 @@ import (
"github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
)
-type LockKind string
+type lockKind string
const (
- LockKindConfigMap LockKind = "ConfigMap"
- LockKindMutex LockKind = "Mutex"
+ lockKindConfigMap lockKind = "ConfigMap"
+ lockKindMutex lockKind = "Mutex"
)
-type LockName struct {
+type lockName struct {
Namespace string
ResourceName string
Key string
- Kind LockKind
+ Kind lockKind
}
-func NewLockName(namespace, resourceName, lockKey string, kind LockKind) *LockName {
- return &LockName{
+func newLockName(namespace, resourceName, lockKey string, kind lockKind) *lockName {
+ return &lockName{
Namespace: namespace,
ResourceName: resourceName,
Key: lockKey,
@@ -31,68 +31,76 @@ func NewLockName(namespace, resourceName, lockKey string, kind LockKind) *LockNa
}
}
-func GetLockName(sync *v1alpha1.Synchronization, wfNamespace string) (*LockName, error) {
- switch sync.GetType() {
- case v1alpha1.SynchronizationTypeSemaphore:
- if sync.Semaphore.ConfigMapKeyRef != nil {
- namespace := sync.Semaphore.Namespace
- if namespace == "" {
- namespace = wfNamespace
- }
- return NewLockName(namespace, sync.Semaphore.ConfigMapKeyRef.Name, sync.Semaphore.ConfigMapKeyRef.Key, LockKindConfigMap), nil
- }
- return nil, fmt.Errorf("cannot get LockName for a Semaphore without a ConfigMapRef")
- case v1alpha1.SynchronizationTypeMutex:
- namespace := sync.Mutex.Namespace
+func getSemaphoreLockName(sem *v1alpha1.SemaphoreRef, wfNamespace string) (*lockName, error) {
+ if sem.ConfigMapKeyRef != nil {
+ namespace := sem.Namespace
if namespace == "" {
namespace = wfNamespace
}
- return NewLockName(namespace, sync.Mutex.Name, "", LockKindMutex), nil
+ return newLockName(namespace, sem.ConfigMapKeyRef.Name, sem.ConfigMapKeyRef.Key, lockKindConfigMap), nil
+ }
+ return nil, fmt.Errorf("cannot get LockName for a Semaphore without a ConfigMapRef")
+}
+
+func getMutexLockName(mtx *v1alpha1.Mutex, wfNamespace string) *lockName {
+ namespace := mtx.Namespace
+ if namespace == "" {
+ namespace = wfNamespace
+ }
+ return newLockName(namespace, mtx.Name, "", lockKindMutex)
+}
+
+func getLockName(item *syncItem, wfNamespace string) (*lockName, error) {
+ switch {
+ case item.semaphore != nil:
+ return getSemaphoreLockName(item.semaphore, wfNamespace)
+ case item.mutex != nil:
+ return getMutexLockName(item.mutex, wfNamespace), nil
default:
- return nil, fmt.Errorf("cannot get LockName for a Sync of Unknown type")
+ return nil, fmt.Errorf("cannot getLockName if not semaphore or mutex")
}
}
-func DecodeLockName(lockName string) (*LockName, error) {
- items := strings.SplitN(lockName, "/", 3)
+func DecodeLockName(name string) (*lockName, error) {
+ items := strings.SplitN(name, "/", 3)
if len(items) < 3 {
return nil, errors.New(errors.CodeBadRequest, "Invalid lock key: unknown format")
}
- var lock LockName
- lockKind := LockKind(items[1])
+ var lock lockName
+ lockKind := lockKind(items[1])
namespace := items[0]
switch lockKind {
- case LockKindMutex:
- lock = LockName{Namespace: namespace, Kind: lockKind, ResourceName: items[2]}
- case LockKindConfigMap:
+ case lockKindMutex:
+ lock = lockName{Namespace: namespace, Kind: lockKind, ResourceName: items[2]}
+ case lockKindConfigMap:
components := strings.Split(items[2], "/")
if len(components) != 2 {
return nil, errors.New(errors.CodeBadRequest, "Invalid ConfigMap lock key: unknown format")
}
- lock = LockName{Namespace: namespace, Kind: lockKind, ResourceName: components[0], Key: components[1]}
+ lock = lockName{Namespace: namespace, Kind: lockKind, ResourceName: components[0], Key: components[1]}
default:
return nil, errors.New(errors.CodeBadRequest, fmt.Sprintf("Invalid lock key, unexpected kind: %s", lockKind))
}
- err := lock.Validate()
+ err := lock.validate()
if err != nil {
return nil, err
}
return &lock, nil
}
-func (ln *LockName) EncodeName() string {
- if ln.Kind == LockKindMutex {
- return ln.ValidateEncoding(fmt.Sprintf("%s/%s/%s", ln.Namespace, ln.Kind, ln.ResourceName))
+func (ln *lockName) encodeName() string {
+ if ln.Kind == lockKindMutex {
+ return ln.validateEncoding(fmt.Sprintf("%s/%s/%s", ln.Namespace, ln.Kind, ln.ResourceName))
}
- return ln.ValidateEncoding(fmt.Sprintf("%s/%s/%s/%s", ln.Namespace, ln.Kind, ln.ResourceName, ln.Key))
+ return ln.validateEncoding(fmt.Sprintf("%s/%s/%s/%s", ln.Namespace, ln.Kind, ln.ResourceName, ln.Key))
}
-func (ln *LockName) Validate() error {
+func (ln *lockName) validate() error {
if ln.Namespace == "" {
return errors.New(errors.CodeBadRequest, "Invalid lock key: Namespace is missing")
}
@@ -102,13 +110,13 @@ func (ln *LockName) Validate() error {
if ln.ResourceName == "" {
return errors.New(errors.CodeBadRequest, "Invalid lock key: ResourceName is missing")
}
- if ln.Kind == LockKindConfigMap && ln.Key == "" {
+ if ln.Kind == lockKindConfigMap && ln.Key == "" {
return errors.New(errors.CodeBadRequest, "Invalid lock key: Key is missing for ConfigMap lock")
}
return nil
}
-func (ln *LockName) ValidateEncoding(encoding string) string {
+func (ln *lockName) validateEncoding(encoding string) string {
decoded, err := DecodeLockName(encoding)
if err != nil {
panic(fmt.Sprintf("bug: unable to decode lock that was just encoded: %s", err))
diff --git a/workflow/sync/lock_name_test.go b/workflow/sync/lock_name_test.go
index 7eef8d03189b..559c2becdefb 100644
--- a/workflow/sync/lock_name_test.go
+++ b/workflow/sync/lock_name_test.go
@@ -14,17 +14,17 @@ func TestDecodeLockName(t *testing.T) {
tests := []struct {
name string
args args
- want *LockName
+ want *lockName
wantErr assert.ErrorAssertionFunc
}{
{
"TestMutexLockNameValidation",
args{"default/Mutex/test"},
- &LockName{
+ &lockName{
Namespace: "default",
ResourceName: "test",
Key: "",
- Kind: LockKindMutex,
+ Kind: lockKindMutex,
},
func(t assert.TestingT, err error, i ...interface{}) bool {
return true
@@ -33,11 +33,11 @@ func TestDecodeLockName(t *testing.T) {
{
"TestMutexLocksCanContainSlashes",
args{"default/Mutex/test/foo/bar/baz"},
- &LockName{
+ &lockName{
Namespace: "default",
ResourceName: "test/foo/bar/baz",
Key: "",
- Kind: LockKindMutex,
+ Kind: lockKindMutex,
},
func(t assert.TestingT, err error, i ...interface{}) bool {
return true
@@ -46,11 +46,11 @@ func TestDecodeLockName(t *testing.T) {
{
"TestConfigMapLockNamesWork",
args{"default/ConfigMap/foo/bar"},
- &LockName{
+ &lockName{
Namespace: "default",
ResourceName: "foo",
Key: "bar",
- Kind: LockKindConfigMap,
+ Kind: lockKindConfigMap,
},
func(t assert.TestingT, err error, i ...interface{}) bool {
return true
@@ -68,11 +68,11 @@ func TestDecodeLockName(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := DecodeLockName(tt.args.lockName)
- if !tt.wantErr(t, err, fmt.Sprintf("DecodeLockName(%v)", tt.args.lockName)) {
+ if !tt.wantErr(t, err, fmt.Sprintf("decodeLockName(%v)", tt.args.lockName)) {
return
}
- assert.Equalf(t, tt.want, got, "DecodeLockName(%v)", tt.args.lockName)
- got.ValidateEncoding(tt.args.lockName)
+ assert.Equalf(t, tt.want, got, "decodeLockName(%v)", tt.args.lockName)
+ got.validateEncoding(tt.args.lockName)
})
}
}
diff --git a/workflow/sync/multiple_test.go b/workflow/sync/multiple_test.go
new file mode 100644
index 000000000000..cfe33e3514ee
--- /dev/null
+++ b/workflow/sync/multiple_test.go
@@ -0,0 +1,424 @@
+package sync
+
+import (
+ "context"
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/kubernetes/fake"
+ "k8s.io/utils/pointer"
+
+ wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
+)
+
+var wfTmpl = `
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ name: %s
+ namespace: default
+spec:
+ entrypoint: whalesay
+ synchronization:
+%s
+ templates:
+ - name: whalesay
+ container:
+ image: docker/whalesay:latest
+ command: [cowsay]
+ args: ["hello world"]
+`
+
+func templatedWorkflow(name string, syncBlock string) *wfv1.Workflow {
+ return wfv1.MustUnmarshalWorkflow(fmt.Sprintf(wfTmpl, name, syncBlock))
+}
+
+func TestMultipleMutexLock(t *testing.T) {
+ kube := fake.NewSimpleClientset()
+ syncLimitFunc := GetSyncLimitFunc(kube)
+ t.Run("MultipleMutex", func(t *testing.T) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {},
+ WorkflowExistenceFunc)
+ wfall := templatedWorkflow("all",
+ ` mutexes:
+ - name: one
+ - name: two
+ - name: three
+`)
+ wf1 := templatedWorkflow("one",
+ ` mutexes:
+ - name: one
+`)
+ wf2 := templatedWorkflow("two",
+ ` mutexes:
+ - name: two
+`)
+ wf3 := templatedWorkflow("three",
+ ` mutexes:
+ - name: three
+`)
+ // Acquire 1
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Acquire 2
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Acquire 3
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf3, "", wf3.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Fail to acquire because one locked
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/one", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ syncManager.ReleaseAll(wf1)
+ // Fail to acquire because two locked
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.False(t, wfUpdate)
+
+ syncManager.ReleaseAll(wf2)
+ // Fail to acquire because three locked
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/three", failedLockName)
+ assert.False(t, status)
+ assert.False(t, wfUpdate)
+
+ syncManager.ReleaseAll(wf3)
+ // Now lock
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+ })
+ t.Run("MultipleMutexOrdering", func(t *testing.T) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {},
+ WorkflowExistenceFunc)
+ wfall := templatedWorkflow("all",
+ ` mutexes:
+ - name: one
+ - name: two
+ - name: three
+`)
+ // Old style single mutex
+ wf1 := templatedWorkflow("one",
+ ` mutex:
+ name: one
+`)
+ wf2 := templatedWorkflow("two",
+ ` mutexes:
+ - name: two
+`)
+ // Acquire 1
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Fail to acquire because one locked
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/one", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Attempt 2, but blocked by all
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.False(t, wfUpdate)
+
+ // Fail to acquire because one locked
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/one", failedLockName)
+ assert.False(t, status)
+ assert.False(t, wfUpdate)
+
+ syncManager.ReleaseAll(wf1)
+ syncManager.ReleaseAll(wf2)
+
+ // Now lock
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfall, "", wfall.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+ })
+}
+
+const multipleConfigMap = `
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: my-config
+data:
+ double: "2"
+`
+
+func TestMutexAndSemaphore(t *testing.T) {
+ kube := fake.NewSimpleClientset()
+ var cm v1.ConfigMap
+ wfv1.MustUnmarshal([]byte(multipleConfigMap), &cm)
+
+ ctx := context.Background()
+ _, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
+ require.NoError(t, err)
+
+ syncLimitFunc := GetSyncLimitFunc(kube)
+ t.Run("MutexSemaphore", func(t *testing.T) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {},
+ WorkflowExistenceFunc)
+ wfmands1 := templatedWorkflow("mands1",
+ ` mutexes:
+ - name: one
+ semaphores:
+ - configMapKeyRef:
+ key: double
+ name: my-config
+`)
+ wfmands1copy := wfmands1.DeepCopy()
+ wfmands2 := templatedWorkflow("mands2",
+ ` mutex:
+ name: two
+ semaphore:
+ configMapKeyRef:
+ key: double
+ name: my-config
+`)
+ wf1 := templatedWorkflow("one",
+ ` mutexes:
+ - name: one
+`)
+ wf2 := templatedWorkflow("two",
+ ` mutexes:
+ - name: two
+`)
+ wfsem := templatedWorkflow("three",
+ ` semaphores:
+ - configMapKeyRef:
+ key: double
+ name: my-config
+`)
+ // Acquire sem + 1
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wfmands1, "", wfmands1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Acquire sem + 2
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfmands2, "", wfmands2.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Fail 1
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/one", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Fail 2
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Fail sem
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfsem, "", wfsem.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/double", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Release 1 and sem
+ syncManager.ReleaseAll(wfmands1)
+
+ // Succeed 1
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Fail 2
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.False(t, wfUpdate)
+
+ // Succeed sem
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfsem, "", wfsem.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ syncManager.ReleaseAll(wf1)
+ syncManager.ReleaseAll(wfsem)
+
+ // And reacquire in a sem+mutex wf
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfmands1copy, "", wfmands1copy.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ })
+}
+func TestPriority(t *testing.T) {
+ kube := fake.NewSimpleClientset()
+ syncLimitFunc := GetSyncLimitFunc(kube)
+ t.Run("Priority", func(t *testing.T) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {},
+ WorkflowExistenceFunc)
+ wflow := templatedWorkflow("prioritylow",
+ ` mutexes:
+ - name: one
+ - name: two
+`)
+ wfhigh := wflow.DeepCopy()
+ wfhigh.Name = "priorityhigh"
+ wfhigh.Spec.Priority = pointer.Int32(5)
+ wf1 := templatedWorkflow("one",
+ ` mutexes:
+ - name: two
+`)
+ // wf2 takes mutex two
+ wf2 := templatedWorkflow("two",
+ ` mutexes:
+ - name: two
+`)
+ // Acquire 1 + 2 as low
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wflow, "", wflow.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+
+ // Attempt to acquire 2, fail
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Attempt get 1 + 2 as high but fail
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfhigh, "", wfhigh.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/one", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Attempt to acquire 2 again as two, fail
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.True(t, wfUpdate)
+
+ // Release locks
+ syncManager.ReleaseAll(wflow)
+
+ // Attempt to acquire 2 again, but priority blocks
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/two", failedLockName)
+ assert.False(t, status)
+ assert.False(t, wfUpdate)
+
+ // Attempt get 1 + 2 as high and priority succeeds
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wfhigh, "", wfhigh.Spec.Synchronization)
+ require.NoError(t, err)
+ assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
+ assert.True(t, status)
+ assert.True(t, wfUpdate)
+ })
+}
+
+func TestDuplicates(t *testing.T) {
+ kube := fake.NewSimpleClientset()
+ syncLimitFunc := GetSyncLimitFunc(kube)
+ t.Run("Mutex", func(t *testing.T) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {},
+ WorkflowExistenceFunc)
+ wfdupmutex := templatedWorkflow("mutex",
+ ` mutexes:
+ - name: one
+ - name: one
+`)
+ _, _, _, _, err := syncManager.TryAcquire(wfdupmutex, "", wfdupmutex.Spec.Synchronization)
+ assert.Error(t, err)
+ })
+ t.Run("Semaphore", func(t *testing.T) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {},
+ WorkflowExistenceFunc)
+ wfdupsemaphore := templatedWorkflow("semaphore",
+ ` semaphores:
+ - configMapKeyRef:
+ key: double
+ name: my-config
+ - configMapKeyRef:
+ key: double
+ name: my-config
+`)
+ _, _, _, _, err := syncManager.TryAcquire(wfdupsemaphore, "", wfdupsemaphore.Spec.Synchronization)
+ assert.Error(t, err)
+ })
+}
diff --git a/workflow/sync/mutex.go b/workflow/sync/mutex.go
index ab90d305088d..c2c86fdc1ff1 100644
--- a/workflow/sync/mutex.go
+++ b/workflow/sync/mutex.go
@@ -1,6 +1,6 @@
package sync
// NewMutex creates a size 1 semaphore
-func NewMutex(name string, nextWorkflow NextWorkflow) *PrioritySemaphore {
+func NewMutex(name string, nextWorkflow NextWorkflow) *prioritySemaphore {
return NewSemaphore(name, 1, nextWorkflow, "mutex")
}
diff --git a/workflow/sync/mutex_test.go b/workflow/sync/mutex_test.go
index 330ad4ae71fa..e4053235009a 100644
--- a/workflow/sync/mutex_test.go
+++ b/workflow/sync/mutex_test.go
@@ -5,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/utils/pointer"
@@ -72,8 +73,7 @@ spec:
mutex:
name: test
templates:
- -
- container:
+ - container:
args:
- hello world
command:
@@ -113,122 +113,132 @@ func TestMutexLock(t *testing.T) {
kube := fake.NewSimpleClientset()
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("InitializeSynchronization", func(t *testing.T) {
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(mutexwfstatus)
wfclientset := fakewfclientset.NewSimpleClientset(wf)
ctx := context.Background()
wfList, err := wfclientset.ArgoprojV1alpha1().Workflows("default").List(ctx, metav1.ListOptions{})
- assert.NoError(t, err)
- concurrenyMgr.Initialize(wfList.Items)
- assert.Equal(t, 1, len(concurrenyMgr.syncLockMap))
+ require.NoError(t, err)
+ syncManager.Initialize(wfList.Items)
+ assert.Equal(t, 1, len(syncManager.syncLockMap))
})
t.Run("WfLevelMutexAcquireAndRelease", func(t *testing.T) {
var nextWorkflow string
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
nextWorkflow = key
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(mutexWf)
wf1 := wf.DeepCopy()
wf2 := wf.DeepCopy()
wf3 := wf.DeepCopy()
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
- assert.NotNil(t, wf.Status.Synchronization.Mutex.Holding)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
+ require.NotNil(t, wf.Status.Synchronization.Mutex.Holding)
assert.Equal(t, wf.Name, wf.Status.Synchronization.Mutex.Holding[0].Holder)
// Try to acquire again
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.True(t, status)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.False(t, wfUpdate)
wf1.Name = "two"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/test", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf2.Name = "three"
wf2.Spec.Priority = pointer.Int32(5)
holderKey2 := getHolderKey(wf2, "")
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/test", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf3.Name = "four"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf3, "", wf3.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf3, "", wf3.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/test", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
- concurrenyMgr.Release(wf, "", wf.Spec.Synchronization)
+ syncManager.Release(wf, "", wf.Spec.Synchronization)
assert.Equal(t, holderKey2, nextWorkflow)
- assert.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
assert.Equal(t, 0, len(wf.Status.Synchronization.Mutex.Holding))
// Low priority workflow try to acquire the lock
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/test", failedLockName)
assert.False(t, status)
assert.False(t, wfUpdate)
// High Priority workflow acquires the lock
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf2.Status.Synchronization)
- assert.NotNil(t, wf2.Status.Synchronization.Mutex)
+ require.NotNil(t, wf2.Status.Synchronization)
+ require.NotNil(t, wf2.Status.Synchronization.Mutex)
assert.Equal(t, wf2.Name, wf2.Status.Synchronization.Mutex.Holding[0].Holder)
- concurrenyMgr.ReleaseAll(wf2)
+ syncManager.ReleaseAll(wf2)
assert.Nil(t, wf2.Status.Synchronization)
})
t.Run("WfLevelMutexOthernamespace", func(t *testing.T) {
var nextWorkflow string
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ concurrencyManager := NewLockManager(syncLimitFunc, func(key string) {
nextWorkflow = key
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(mutexWfNamespaced)
wf1 := wf.DeepCopy()
wf2 := wf.DeepCopy()
wf3 := wf.DeepCopy()
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := concurrencyManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
- assert.NotNil(t, wf.Status.Synchronization.Mutex.Holding)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
+ require.NotNil(t, wf.Status.Synchronization.Mutex.Holding)
assert.Equal(t, wf.Name, wf.Status.Synchronization.Mutex.Holding[0].Holder)
// Try to acquire again
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = concurrencyManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.True(t, status)
+ assert.Empty(t, failedLockName)
assert.Empty(t, msg)
assert.False(t, wfUpdate)
wf1.Name = "two"
wf1.Namespace = "two"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = concurrencyManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "other/Mutex/test", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
@@ -236,42 +246,46 @@ func TestMutexLock(t *testing.T) {
wf2.Namespace = "three"
wf2.Spec.Priority = pointer.Int32(5)
holderKey2 := getHolderKey(wf2, "")
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = concurrencyManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "other/Mutex/test", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf3.Name = "four"
wf3.Namespace = "four"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf3, "", wf3.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = concurrencyManager.TryAcquire(wf3, "", wf3.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "other/Mutex/test", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
- concurrenyMgr.Release(wf, "", wf.Spec.Synchronization)
+ concurrencyManager.Release(wf, "", wf.Spec.Synchronization)
assert.Equal(t, holderKey2, nextWorkflow)
- assert.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
assert.Equal(t, 0, len(wf.Status.Synchronization.Mutex.Holding))
// Low priority workflow try to acquire the lock
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = concurrencyManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "other/Mutex/test", failedLockName)
assert.False(t, status)
assert.False(t, wfUpdate)
// High Priority workflow acquires the lock
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = concurrencyManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf2.Status.Synchronization)
- assert.NotNil(t, wf2.Status.Synchronization.Mutex)
+ require.NotNil(t, wf2.Status.Synchronization)
+ require.NotNil(t, wf2.Status.Synchronization.Mutex)
assert.Equal(t, wf2.Name, wf2.Status.Synchronization.Mutex.Holding[0].Holder)
- concurrenyMgr.ReleaseAll(wf2)
+ concurrencyManager.ReleaseAll(wf2)
assert.Nil(t, wf2.Status.Synchronization)
})
}
@@ -381,53 +395,57 @@ func TestMutexTmplLevel(t *testing.T) {
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("TemplateLevelAcquireAndRelease", func(t *testing.T) {
// var nextKey string
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
// nextKey = key
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(mutexWfWithTmplLevel)
tmpl := wf.Spec.Templates[1]
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", tmpl.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
assert.Equal(t, "synchronization-tmpl-level-mutex-vjcdk-3941195474", wf.Status.Synchronization.Mutex.Holding[0].Holder)
// Try to acquire again
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-2216915482", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-2216915482", tmpl.Synchronization)
+ require.NoError(t, err)
assert.True(t, wfUpdate)
+ assert.Equal(t, "default/Mutex/welcome", failedLockName)
assert.False(t, status)
assert.NotEmpty(t, msg)
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-1432992664", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-1432992664", tmpl.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/welcome", failedLockName)
assert.False(t, wfUpdate)
assert.False(t, status)
assert.Equal(t, "synchronization-tmpl-level-mutex-vjcdk-3941195474", wf.Status.Synchronization.Mutex.Holding[0].Holder)
- concurrenyMgr.Release(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", tmpl.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
+ syncManager.Release(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", tmpl.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
assert.Empty(t, wf.Status.Synchronization.Mutex.Holding)
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-2216915482", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-2216915482", tmpl.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
assert.Equal(t, "synchronization-tmpl-level-mutex-vjcdk-2216915482", wf.Status.Synchronization.Mutex.Holding[0].Holder)
assert.NotEqual(t, "synchronization-tmpl-level-mutex-vjcdk-3941195474", wf.Status.Synchronization.Mutex.Holding[0].Holder)
- concurrenyMgr.Release(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", tmpl.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
+ syncManager.Release(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", tmpl.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
assert.NotEmpty(t, wf.Status.Synchronization.Mutex.Holding)
})
}
diff --git a/workflow/sync/semaphore.go b/workflow/sync/semaphore.go
index 63be7239ddeb..fe97e6d29538 100644
--- a/workflow/sync/semaphore.go
+++ b/workflow/sync/semaphore.go
@@ -3,34 +3,31 @@ package sync
import (
"fmt"
"strings"
- "sync"
"time"
log "github.com/sirupsen/logrus"
sema "golang.org/x/sync/semaphore"
)
-type PrioritySemaphore struct {
+type prioritySemaphore struct {
name string
limit int
pending *priorityQueue
semaphore *sema.Weighted
lockHolder map[string]bool
- lock *sync.Mutex
nextWorkflow NextWorkflow
log *log.Entry
}
-var _ Semaphore = &PrioritySemaphore{}
+var _ semaphore = &prioritySemaphore{}
-func NewSemaphore(name string, limit int, nextWorkflow NextWorkflow, lockType string) *PrioritySemaphore {
- return &PrioritySemaphore{
+func NewSemaphore(name string, limit int, nextWorkflow NextWorkflow, lockType string) *prioritySemaphore {
+ return &prioritySemaphore{
name: name,
limit: limit,
pending: &priorityQueue{itemByKey: make(map[string]*item)},
semaphore: sema.NewWeighted(int64(limit)),
lockHolder: make(map[string]bool),
- lock: &sync.Mutex{},
nextWorkflow: nextWorkflow,
log: log.WithFields(log.Fields{
lockType: name,
@@ -38,15 +35,15 @@ func NewSemaphore(name string, limit int, nextWorkflow NextWorkflow, lockType st
}
}
-func (s *PrioritySemaphore) getName() string {
+func (s *prioritySemaphore) getName() string {
return s.name
}
-func (s *PrioritySemaphore) getLimit() int {
+func (s *prioritySemaphore) getLimit() int {
return s.limit
}
-func (s *PrioritySemaphore) getCurrentPending() []string {
+func (s *prioritySemaphore) getCurrentPending() []string {
var keys []string
for _, item := range s.pending.items {
keys = append(keys, item.key)
@@ -54,7 +51,7 @@ func (s *PrioritySemaphore) getCurrentPending() []string {
return keys
}
-func (s *PrioritySemaphore) getCurrentHolders() []string {
+func (s *prioritySemaphore) getCurrentHolders() []string {
var keys []string
for k := range s.lockHolder {
keys = append(keys, k)
@@ -62,10 +59,7 @@ func (s *PrioritySemaphore) getCurrentHolders() []string {
return keys
}
-func (s *PrioritySemaphore) resize(n int) bool {
- s.lock.Lock()
- defer s.lock.Unlock()
-
+func (s *prioritySemaphore) resize(n int) bool {
cur := len(s.lockHolder)
// downward case, acquired n locks
if cur > n {
@@ -82,9 +76,7 @@ func (s *PrioritySemaphore) resize(n int) bool {
return status
}
-func (s *PrioritySemaphore) release(key string) bool {
- s.lock.Lock()
- defer s.lock.Unlock()
+func (s *prioritySemaphore) release(key string) bool {
if _, ok := s.lockHolder[key]; ok {
delete(s.lockHolder, key)
// When semaphore resized downward
@@ -105,7 +97,7 @@ func (s *PrioritySemaphore) release(key string) bool {
// notifyWaiters enqueues the next N workflows who are waiting for the semaphore to the workqueue,
// where N is the availability of the semaphore. If semaphore is out of capacity, this does nothing.
-func (s *PrioritySemaphore) notifyWaiters() {
+func (s *prioritySemaphore) notifyWaiters() {
triggerCount := s.limit - len(s.lockHolder)
if s.pending.Len() < triggerCount {
triggerCount = s.pending.Len()
@@ -130,10 +122,7 @@ func workflowKey(i *item) string {
}
// addToQueue adds the holderkey into priority queue that maintains the priority order to acquire the lock.
-func (s *PrioritySemaphore) addToQueue(holderKey string, priority int32, creationTime time.Time) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
+func (s *prioritySemaphore) addToQueue(holderKey string, priority int32, creationTime time.Time) {
if _, ok := s.lockHolder[holderKey]; ok {
s.log.Debugf("Lock is already acquired by %s", holderKey)
return
@@ -143,15 +132,12 @@ func (s *PrioritySemaphore) addToQueue(holderKey string, priority int32, creatio
s.log.Debugf("Added into queue: %s", holderKey)
}
-func (s *PrioritySemaphore) removeFromQueue(holderKey string) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
+func (s *prioritySemaphore) removeFromQueue(holderKey string) {
s.pending.remove(holderKey)
s.log.Debugf("Removed from queue: %s", holderKey)
}
-func (s *PrioritySemaphore) acquire(holderKey string) bool {
+func (s *prioritySemaphore) acquire(holderKey string) bool {
if s.semaphore.TryAcquire(1) {
s.lockHolder[holderKey] = true
return true
@@ -170,15 +156,22 @@ func isSameWorkflowNodeKeys(firstKey, secondKey string) bool {
return firstItems[1] == secondItems[1]
}
-func (s *PrioritySemaphore) tryAcquire(holderKey string) (bool, string) {
- s.lock.Lock()
- defer s.lock.Unlock()
+// checkAcquire examines if tryAcquire would succeed
+// returns
+//
+// true, false if we would be able to take the lock
+// false, true if we already have the lock
+// false, false if the lock is not acquirable
+// string return is a user facing message when not acquirable
+func (s *prioritySemaphore) checkAcquire(holderKey string) (bool, bool, string) {
+ if holderKey == "" {
+ return false, false, "bug: attempt to check semaphore with empty holder key"
+ }
if _, ok := s.lockHolder[holderKey]; ok {
s.log.Debugf("%s is already holding a lock", holderKey)
- return true, ""
+ return false, true, ""
}
- var nextKey string
waitingMsg := fmt.Sprintf("Waiting for %s lock. Lock status: %d/%d", s.name, s.limit-len(s.lockHolder), s.limit)
@@ -187,15 +180,32 @@ func (s *PrioritySemaphore) tryAcquire(holderKey string) (bool, string) {
// If it is not a front key, it needs to wait for its turn.
if s.pending.Len() > 0 {
item := s.pending.peek()
- if holderKey != nextKey && !isSameWorkflowNodeKeys(holderKey, item.key) {
+ if !isSameWorkflowNodeKeys(holderKey, item.key) {
// Enqueue the front workflow if lock is available
if len(s.lockHolder) < s.limit {
s.nextWorkflow(workflowKey(item))
}
- return false, waitingMsg
+ s.log.Infof("%s isn't at the front", holderKey)
+ return false, false, waitingMsg
}
}
+ if s.semaphore.TryAcquire(1) {
+ s.semaphore.Release(1)
+ return true, false, ""
+ }
+
+ s.log.Debugf("Current semaphore Holders. %v", s.lockHolder)
+ return false, false, waitingMsg
+}
+func (s *prioritySemaphore) tryAcquire(holderKey string) (bool, string) {
+ acq, already, msg := s.checkAcquire(holderKey)
+ if already {
+ return true, msg
+ }
+ if !acq {
+ return false, msg
+ }
if s.acquire(holderKey) {
s.pending.pop()
s.log.Infof("%s acquired by %s. Lock availability: %d/%d", s.name, holderKey, s.limit-len(s.lockHolder), s.limit)
@@ -203,5 +213,5 @@ func (s *PrioritySemaphore) tryAcquire(holderKey string) (bool, string) {
return true, ""
}
s.log.Debugf("Current semaphore Holders. %v", s.lockHolder)
- return false, waitingMsg
+ return false, msg
}
diff --git a/workflow/sync/sync_manager.go b/workflow/sync/sync_manager.go
index 6f4c92b87aac..6a1f94cd5ca8 100644
--- a/workflow/sync/sync_manager.go
+++ b/workflow/sync/sync_manager.go
@@ -18,7 +18,7 @@ type (
)
type Manager struct {
- syncLockMap map[string]Semaphore
+ syncLockMap map[string]semaphore
lock *sync.Mutex
nextWorkflow NextWorkflow
getSyncLimit GetSyncLimit
@@ -27,7 +27,7 @@ type Manager struct {
func NewLockManager(getSyncLimit GetSyncLimit, nextWorkflow NextWorkflow, isWFDeleted IsWorkflowDeleted) *Manager {
return &Manager{
- syncLockMap: make(map[string]Semaphore),
+ syncLockMap: make(map[string]semaphore),
lock: &sync.Mutex{},
nextWorkflow: nextWorkflow,
getSyncLimit: getSyncLimit,
@@ -35,7 +35,7 @@ func NewLockManager(getSyncLimit GetSyncLimit, nextWorkflow NextWorkflow, isWFDe
}
}
-func (cm *Manager) getWorkflowKey(key string) (string, error) {
+func (sm *Manager) getWorkflowKey(key string) (string, error) {
if key == "" {
return "", fmt.Errorf("holderkey is empty")
}
@@ -46,19 +46,19 @@ func (cm *Manager) getWorkflowKey(key string) (string, error) {
return fmt.Sprintf("%s/%s", items[0], items[1]), nil
}
-func (cm *Manager) CheckWorkflowExistence() {
+func (sm *Manager) CheckWorkflowExistence() {
defer runtimeutil.HandleCrash(runtimeutil.PanicHandlers...)
log.Debug("Check the workflow existence")
- for _, lock := range cm.syncLockMap {
+ for _, lock := range sm.syncLockMap {
keys := lock.getCurrentHolders()
keys = append(keys, lock.getCurrentPending()...)
for _, holderKeys := range keys {
- wfKey, err := cm.getWorkflowKey(holderKeys)
+ wfKey, err := sm.getWorkflowKey(holderKeys)
if err != nil {
continue
}
- if !cm.isWFDeleted(wfKey) {
+ if !sm.isWFDeleted(wfKey) {
lock.release(holderKeys)
lock.removeFromQueue(holderKeys)
}
@@ -66,7 +66,7 @@ func (cm *Manager) CheckWorkflowExistence() {
}
}
-func (cm *Manager) Initialize(wfs []wfv1.Workflow) {
+func (sm *Manager) Initialize(wfs []wfv1.Workflow) {
for _, wf := range wfs {
if wf.Status.Synchronization == nil {
continue
@@ -74,15 +74,14 @@ func (cm *Manager) Initialize(wfs []wfv1.Workflow) {
if wf.Status.Synchronization.Semaphore != nil {
for _, holding := range wf.Status.Synchronization.Semaphore.Holding {
-
- semaphore := cm.syncLockMap[holding.Semaphore]
+ semaphore := sm.syncLockMap[holding.Semaphore]
if semaphore == nil {
- semaphore, err := cm.initializeSemaphore(holding.Semaphore)
+ semaphore, err := sm.initializeSemaphore(holding.Semaphore)
if err != nil {
log.Warnf("cannot initialize semaphore '%s': %v", holding.Semaphore, err)
continue
}
- cm.syncLockMap[holding.Semaphore] = semaphore
+ sm.syncLockMap[holding.Semaphore] = semaphore
}
for _, holders := range holding.Holders {
@@ -96,15 +95,14 @@ func (cm *Manager) Initialize(wfs []wfv1.Workflow) {
if wf.Status.Synchronization.Mutex != nil {
for _, holding := range wf.Status.Synchronization.Mutex.Holding {
-
- mutex := cm.syncLockMap[holding.Mutex]
+ mutex := sm.syncLockMap[holding.Mutex]
if mutex == nil {
- mutex := cm.initializeMutex(holding.Mutex)
+ mutex := sm.initializeMutex(holding.Mutex)
if holding.Holder != "" {
resourceKey := getResourceKey(wf.Namespace, wf.Name, holding.Holder)
mutex.acquire(resourceKey)
}
- cm.syncLockMap[holding.Mutex] = mutex
+ sm.syncLockMap[holding.Mutex] = mutex
}
}
}
@@ -113,94 +111,138 @@ func (cm *Manager) Initialize(wfs []wfv1.Workflow) {
}
// TryAcquire tries to acquire the lock from semaphore.
-// It returns status of acquiring a lock , status of Workflow status updated, waiting message if lock is not available and any error encountered
-func (cm *Manager) TryAcquire(wf *wfv1.Workflow, nodeName string, syncLockRef *wfv1.Synchronization) (bool, bool, string, error) {
- cm.lock.Lock()
- defer cm.lock.Unlock()
+// It returns status of acquiring a lock , status of Workflow status updated, waiting message if lock is not available, the failed lock, and any error encountered
+func (sm *Manager) TryAcquire(wf *wfv1.Workflow, nodeName string, syncLockRef *wfv1.Synchronization) (bool, bool, string, string, error) {
+ sm.lock.Lock()
+ defer sm.lock.Unlock()
if syncLockRef == nil {
- return false, false, "", fmt.Errorf("cannot acquire lock from nil Synchronization")
+ return false, false, "", "", fmt.Errorf("cannot acquire lock from nil Synchronization")
}
- syncLockName, err := GetLockName(syncLockRef, wf.Namespace)
+ failedLockName := ""
+ syncItems, err := allSyncItems(syncLockRef)
if err != nil {
- return false, false, "", fmt.Errorf("requested configuration is invalid: %w", err)
+ return false, false, "", failedLockName, fmt.Errorf("requested configuration is invalid: %w", err)
}
+ holderKey := getHolderKey(wf, nodeName)
- lockKey := syncLockName.EncodeName()
- lock, found := cm.syncLockMap[lockKey]
- if !found {
- switch syncLockRef.GetType() {
- case wfv1.SynchronizationTypeSemaphore:
- lock, err = cm.initializeSemaphore(lockKey)
- case wfv1.SynchronizationTypeMutex:
- lock = cm.initializeMutex(lockKey)
- default:
- return false, false, "", fmt.Errorf("unknown Synchronization Type")
- }
+ var msg string
+ lockKeys := make([]string, len(syncItems))
+ allAcquirable := true
+ for i, syncItem := range syncItems {
+ syncLockName, err := getLockName(syncItem, wf.Namespace)
if err != nil {
- return false, false, "", err
+ return false, false, "", failedLockName, fmt.Errorf("requested configuration is invalid: %w", err)
}
- cm.syncLockMap[lockKey] = lock
+ lockKeys[i] = syncLockName.encodeName()
}
+ for i, lockKey := range lockKeys {
+ lock, found := sm.syncLockMap[lockKey]
+ if !found {
+ var err error
+ switch syncItems[i].getType() {
+ case wfv1.SynchronizationTypeSemaphore:
+ lock, err = sm.initializeSemaphore(lockKey)
+ case wfv1.SynchronizationTypeMutex:
+ lock = sm.initializeMutex(lockKey)
+ default:
+ return false, false, "", failedLockName, fmt.Errorf("unknown Synchronization Type")
+ }
+ if err != nil {
+ return false, false, "", failedLockName, err
+ }
+ sm.syncLockMap[lockKey] = lock
+ }
- if syncLockRef.GetType() == wfv1.SynchronizationTypeSemaphore {
- err := cm.checkAndUpdateSemaphoreSize(lock)
- if err != nil {
- return false, false, "", err
+ if syncItems[i].getType() == wfv1.SynchronizationTypeSemaphore {
+ err := sm.checkAndUpdateSemaphoreSize(lock)
+ if err != nil {
+ return false, false, "", "", err
+ }
}
- }
- holderKey := getHolderKey(wf, nodeName)
- var priority int32
- if wf.Spec.Priority != nil {
- priority = *wf.Spec.Priority
- } else {
- priority = 0
- }
- creationTime := wf.CreationTimestamp
- lock.addToQueue(holderKey, priority, creationTime.Time)
-
- ensureInit(wf, syncLockRef.GetType())
- currentHolders := cm.getCurrentLockHolders(lockKey)
- acquired, msg := lock.tryAcquire(holderKey)
- if acquired {
- updated := wf.Status.Synchronization.GetStatus(syncLockRef.GetType()).LockAcquired(holderKey, lockKey, currentHolders)
- return true, updated, "", nil
+ var priority int32
+ if wf.Spec.Priority != nil {
+ priority = *wf.Spec.Priority
+ } else {
+ priority = 0
+ }
+ creationTime := wf.CreationTimestamp
+ lock.addToQueue(holderKey, priority, creationTime.Time)
+
+ ensureInit(wf, syncItems[i].getType())
+ acquired, already, newMsg := lock.checkAcquire(holderKey)
+ if !acquired && !already {
+ allAcquirable = false
+ if msg == "" {
+ msg = newMsg
+ }
+ if failedLockName == "" {
+ failedLockName = lockKey
+ }
+ }
}
- updated := wf.Status.Synchronization.GetStatus(syncLockRef.GetType()).LockWaiting(holderKey, lockKey, currentHolders)
- return false, updated, msg, nil
+ switch {
+ case allAcquirable:
+ updated := false
+ for i, lockKey := range lockKeys {
+ lock := sm.syncLockMap[lockKey]
+ acquired, msg := lock.tryAcquire(holderKey)
+ if !acquired {
+ return false, false, "", failedLockName, fmt.Errorf("bug: failed to acquire something that should have been checked: %s", msg)
+ }
+ currentHolders := sm.getCurrentLockHolders(lockKey)
+ if wf.Status.Synchronization.GetStatus(syncItems[i].getType()).LockAcquired(holderKey, lockKey, currentHolders) {
+ updated = true
+ }
+ }
+ return true, updated, msg, failedLockName, nil
+ default: // Not all acquirable
+ updated := false
+ for i, lockKey := range lockKeys {
+ currentHolders := sm.getCurrentLockHolders(lockKey)
+ if wf.Status.Synchronization.GetStatus(syncItems[i].getType()).LockWaiting(holderKey, lockKey, currentHolders) {
+ updated = true
+ }
+ }
+ return false, updated, msg, failedLockName, nil
+ }
}
-func (cm *Manager) Release(wf *wfv1.Workflow, nodeName string, syncRef *wfv1.Synchronization) {
+func (sm *Manager) Release(wf *wfv1.Workflow, nodeName string, syncRef *wfv1.Synchronization) {
if syncRef == nil {
return
}
- cm.lock.Lock()
- defer cm.lock.Unlock()
+ sm.lock.Lock()
+ defer sm.lock.Unlock()
holderKey := getHolderKey(wf, nodeName)
- lockName, err := GetLockName(syncRef, wf.Namespace)
- if err != nil {
- return
- }
+ // Ignoring error here is as good as it's going to be, we shouldn't get here as we should
+ // should never have acquired anything if this errored
+ syncItems, _ := allSyncItems(syncRef)
- if syncLockHolder, ok := cm.syncLockMap[lockName.EncodeName()]; ok {
- syncLockHolder.release(holderKey)
- syncLockHolder.removeFromQueue(holderKey)
- log.Debugf("%s sync lock is released by %s", lockName.EncodeName(), holderKey)
- lockKey := lockName.EncodeName()
- if wf.Status.Synchronization != nil {
- wf.Status.Synchronization.GetStatus(syncRef.GetType()).LockReleased(holderKey, lockKey)
+ for _, syncItem := range syncItems {
+ lockName, err := getLockName(syncItem, wf.Namespace)
+ if err != nil {
+ return
+ }
+ if syncLockHolder, ok := sm.syncLockMap[lockName.encodeName()]; ok {
+ syncLockHolder.release(holderKey)
+ syncLockHolder.removeFromQueue(holderKey)
+ lockKey := lockName.encodeName()
+ if wf.Status.Synchronization != nil {
+ wf.Status.Synchronization.GetStatus(syncItem.getType()).LockReleased(holderKey, lockKey)
+ }
}
}
}
-func (cm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
- cm.lock.Lock()
- defer cm.lock.Unlock()
+func (sm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
+ sm.lock.Lock()
+ defer sm.lock.Unlock()
if wf.Status.Synchronization == nil {
return true
@@ -208,7 +250,7 @@ func (cm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
if wf.Status.Synchronization.Semaphore != nil {
for _, holding := range wf.Status.Synchronization.Semaphore.Holding {
- syncLockHolder := cm.syncLockMap[holding.Semaphore]
+ syncLockHolder := sm.syncLockMap[holding.Semaphore]
if syncLockHolder == nil {
continue
}
@@ -223,7 +265,7 @@ func (cm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
// Remove the pending Workflow level semaphore keys
for _, waiting := range wf.Status.Synchronization.Semaphore.Waiting {
- syncLockHolder := cm.syncLockMap[waiting.Semaphore]
+ syncLockHolder := sm.syncLockMap[waiting.Semaphore]
if syncLockHolder == nil {
continue
}
@@ -235,7 +277,7 @@ func (cm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
if wf.Status.Synchronization.Mutex != nil {
for _, holding := range wf.Status.Synchronization.Mutex.Holding {
- syncLockHolder := cm.syncLockMap[holding.Mutex]
+ syncLockHolder := sm.syncLockMap[holding.Mutex]
if syncLockHolder == nil {
continue
}
@@ -248,7 +290,7 @@ func (cm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
// Remove the pending Workflow level mutex keys
for _, waiting := range wf.Status.Synchronization.Mutex.Waiting {
- syncLockHolder := cm.syncLockMap[waiting.Mutex]
+ syncLockHolder := sm.syncLockMap[waiting.Mutex]
if syncLockHolder == nil {
continue
}
@@ -260,7 +302,7 @@ func (cm *Manager) ReleaseAll(wf *wfv1.Workflow) bool {
for _, node := range wf.Status.Nodes {
if node.SynchronizationStatus != nil && node.SynchronizationStatus.Waiting != "" {
- lock, ok := cm.syncLockMap[node.SynchronizationStatus.Waiting]
+ lock, ok := sm.syncLockMap[node.SynchronizationStatus.Waiting]
if ok {
lock.removeFromQueue(getHolderKey(wf, node.ID))
}
@@ -304,35 +346,35 @@ func getResourceKey(namespace, wfName, resourceName string) string {
return resourceKey
}
-func (cm *Manager) getCurrentLockHolders(lockName string) []string {
- if concurrency, ok := cm.syncLockMap[lockName]; ok {
+func (sm *Manager) getCurrentLockHolders(lockName string) []string {
+ if concurrency, ok := sm.syncLockMap[lockName]; ok {
return concurrency.getCurrentHolders()
}
return nil
}
-func (cm *Manager) initializeSemaphore(semaphoreName string) (Semaphore, error) {
- limit, err := cm.getSyncLimit(semaphoreName)
+func (sm *Manager) initializeSemaphore(semaphoreName string) (semaphore, error) {
+ limit, err := sm.getSyncLimit(semaphoreName)
if err != nil {
return nil, err
}
- return NewSemaphore(semaphoreName, limit, cm.nextWorkflow, "semaphore"), nil
+ return NewSemaphore(semaphoreName, limit, sm.nextWorkflow, "semaphore"), nil
}
-func (cm *Manager) initializeMutex(mutexName string) Semaphore {
- return NewMutex(mutexName, cm.nextWorkflow)
+func (sm *Manager) initializeMutex(mutexName string) semaphore {
+ return NewMutex(mutexName, sm.nextWorkflow)
}
-func (cm *Manager) isSemaphoreSizeChanged(semaphore Semaphore) (bool, int, error) {
- limit, err := cm.getSyncLimit(semaphore.getName())
+func (sm *Manager) isSemaphoreSizeChanged(semaphore semaphore) (bool, int, error) {
+ limit, err := sm.getSyncLimit(semaphore.getName())
if err != nil {
return false, semaphore.getLimit(), err
}
return semaphore.getLimit() != limit, limit, nil
}
-func (cm *Manager) checkAndUpdateSemaphoreSize(semaphore Semaphore) error {
- changed, newLimit, err := cm.isSemaphoreSizeChanged(semaphore)
+func (sm *Manager) checkAndUpdateSemaphoreSize(semaphore semaphore) error {
+ changed, newLimit, err := sm.isSemaphoreSizeChanged(semaphore)
if err != nil {
return err
}
diff --git a/workflow/sync/sync_manager_test.go b/workflow/sync/sync_manager_test.go
index 69194467c65c..91975b9089f1 100644
--- a/workflow/sync/sync_manager_test.go
+++ b/workflow/sync/sync_manager_test.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
@@ -304,7 +305,7 @@ var WorkflowExistenceFunc = func(s string) bool {
}
func GetSyncLimitFunc(kube *fake.Clientset) func(string) (int, error) {
- syncLimitConfig := func(lockName string) (int, error) {
+ return func(lockName string) (int, error) {
items := strings.Split(lockName, "/")
if len(items) < 4 {
return 0, argoErr.New(argoErr.CodeBadRequest, "Invalid Config Map Key")
@@ -323,7 +324,6 @@ func GetSyncLimitFunc(kube *fake.Clientset) func(string) (int, error) {
}
return strconv.Atoi(value)
}
- return syncLimitConfig
}
func TestSemaphoreWfLevel(t *testing.T) {
@@ -333,113 +333,120 @@ func TestSemaphoreWfLevel(t *testing.T) {
ctx := context.Background()
_, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("InitializeSynchronization", func(t *testing.T) {
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(wfWithStatus)
wfclientset := fakewfclientset.NewSimpleClientset(wf)
wfList, err := wfclientset.ArgoprojV1alpha1().Workflows("default").List(ctx, metav1.ListOptions{})
- assert.NoError(t, err)
- concurrenyMgr.Initialize(wfList.Items)
- assert.Equal(t, 1, len(concurrenyMgr.syncLockMap))
+ require.NoError(t, err)
+ syncManager.Initialize(wfList.Items)
+ assert.Equal(t, 1, len(syncManager.syncLockMap))
})
t.Run("InitializeSynchronizationWithInvalid", func(t *testing.T) {
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(wfWithStatus)
invalidSync := []wfv1.SemaphoreHolding{{Semaphore: "default/configmap/my-config1/workflow", Holders: []string{"hello-world-vcrg5"}}}
wf.Status.Synchronization.Semaphore.Holding = invalidSync
wfclientset := fakewfclientset.NewSimpleClientset(wf)
wfList, err := wfclientset.ArgoprojV1alpha1().Workflows("default").List(ctx, metav1.ListOptions{})
- assert.NoError(t, err)
- concurrenyMgr.Initialize(wfList.Items)
- assert.Equal(t, 0, len(concurrenyMgr.syncLockMap))
+ require.NoError(t, err)
+ syncManager.Initialize(wfList.Items)
+ assert.Equal(t, 0, len(syncManager.syncLockMap))
})
t.Run("WfLevelAcquireAndRelease", func(t *testing.T) {
var nextKey string
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
nextKey = key
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(wfWithSemaphore)
wf1 := wf.DeepCopy()
wf2 := wf.DeepCopy()
wf3 := wf.DeepCopy()
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Semaphore)
- assert.NotNil(t, wf.Status.Synchronization.Semaphore.Holding)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf.Status.Synchronization.Semaphore.Holding)
assert.Equal(t, wf.Name, wf.Status.Synchronization.Semaphore.Holding[0].Holders[0])
// Try to acquire again
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.True(t, status)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.False(t, wfUpdate)
wf1.Name = "two"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/workflow", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf2.Name = "three"
wf2.Spec.Priority = pointer.Int32(5)
holderKey2 := getHolderKey(wf2, "")
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/workflow", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf3.Name = "four"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf3, "", wf3.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf3, "", wf3.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/workflow", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
- concurrenyMgr.Release(wf, "", wf.Spec.Synchronization)
+ syncManager.Release(wf, "", wf.Spec.Synchronization)
assert.Equal(t, holderKey2, nextKey)
- assert.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
assert.Equal(t, 0, len(wf.Status.Synchronization.Semaphore.Holding[0].Holders))
// Low priority workflow try to acquire the lock
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/workflow", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
// High Priority workflow acquires the lock
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf2.Status.Synchronization)
- assert.NotNil(t, wf2.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf2.Status.Synchronization)
+ require.NotNil(t, wf2.Status.Synchronization.Semaphore)
assert.Equal(t, wf2.Name, wf2.Status.Synchronization.Semaphore.Holding[0].Holders[0])
- concurrenyMgr.ReleaseAll(wf2)
+ syncManager.ReleaseAll(wf2)
assert.Nil(t, wf2.Status.Synchronization)
- sema := concurrenyMgr.syncLockMap["default/ConfigMap/my-config/workflow"].(*PrioritySemaphore)
- assert.NotNil(t, sema)
+ sema := syncManager.syncLockMap["default/ConfigMap/my-config/workflow"].(*prioritySemaphore)
+ require.NotNil(t, sema)
assert.Len(t, sema.pending.items, 2)
- concurrenyMgr.ReleaseAll(wf1)
+ syncManager.ReleaseAll(wf1)
assert.Len(t, sema.pending.items, 1)
- concurrenyMgr.ReleaseAll(wf3)
+ syncManager.ReleaseAll(wf3)
assert.Len(t, sema.pending.items, 0)
})
}
@@ -451,62 +458,67 @@ func TestResizeSemaphoreSize(t *testing.T) {
ctx := context.Background()
_, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("WfLevelAcquireAndRelease", func(t *testing.T) {
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(wfWithSemaphore)
wf.CreationTimestamp = metav1.Time{Time: time.Now()}
wf1 := wf.DeepCopy()
wf2 := wf.DeepCopy()
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Semaphore)
assert.Equal(t, wf.Name, wf.Status.Synchronization.Semaphore.Holding[0].Holders[0])
wf1.Name = "two"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/workflow", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf2.Name = "three"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/workflow", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
// Increase the semaphore Size
cm, err := kube.CoreV1().ConfigMaps("default").Get(ctx, "my-config", metav1.GetOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
cm.Data["workflow"] = "3"
_, err = kube.CoreV1().ConfigMaps("default").Update(ctx, cm, metav1.UpdateOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.True(t, status)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf1.Status.Synchronization)
- assert.NotNil(t, wf1.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf1.Status.Synchronization)
+ require.NotNil(t, wf1.Status.Synchronization.Semaphore)
assert.Equal(t, wf1.Name, wf1.Status.Synchronization.Semaphore.Holding[0].Holders[0])
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf2.Status.Synchronization)
- assert.NotNil(t, wf2.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf2.Status.Synchronization)
+ require.NotNil(t, wf2.Status.Synchronization.Semaphore)
assert.Equal(t, wf2.Name, wf2.Status.Synchronization.Semaphore.Holding[0].Holders[0])
})
}
@@ -518,51 +530,55 @@ func TestSemaphoreTmplLevel(t *testing.T) {
ctx := context.Background()
_, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("TemplateLevelAcquireAndRelease", func(t *testing.T) {
// var nextKey string
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
// nextKey = key
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(wfWithTmplSemaphore)
tmpl := wf.Spec.Templates[2]
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "semaphore-tmpl-level-xjvln-3448864205", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "semaphore-tmpl-level-xjvln-3448864205", tmpl.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Semaphore)
assert.Equal(t, "semaphore-tmpl-level-xjvln-3448864205", wf.Status.Synchronization.Semaphore.Holding[0].Holders[0])
// Try to acquire again
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "semaphore-tmpl-level-xjvln-3448864205", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "semaphore-tmpl-level-xjvln-3448864205", tmpl.Synchronization)
+ require.NoError(t, err)
assert.True(t, status)
+ assert.Empty(t, failedLockName)
assert.False(t, wfUpdate)
assert.Empty(t, msg)
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "semaphore-tmpl-level-xjvln-1607747183", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "semaphore-tmpl-level-xjvln-1607747183", tmpl.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/ConfigMap/my-config/template", failedLockName)
assert.True(t, wfUpdate)
assert.False(t, status)
- concurrenyMgr.Release(wf, "semaphore-tmpl-level-xjvln-3448864205", tmpl.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Semaphore)
+ syncManager.Release(wf, "semaphore-tmpl-level-xjvln-3448864205", tmpl.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Semaphore)
assert.Empty(t, wf.Status.Synchronization.Semaphore.Holding[0].Holders)
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "semaphore-tmpl-level-xjvln-1607747183", tmpl.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf, "semaphore-tmpl-level-xjvln-1607747183", tmpl.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Semaphore)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Semaphore)
assert.Equal(t, "semaphore-tmpl-level-xjvln-1607747183", wf.Status.Synchronization.Semaphore.Holding[0].Holders[0])
})
}
@@ -576,21 +592,22 @@ func TestTriggerWFWithAvailableLock(t *testing.T) {
ctx := context.Background()
_, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
- assert.NoError(err)
+ require.NoError(t, err)
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("TriggerWfsWithAvailableLocks", func(t *testing.T) {
triggerCount := 0
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
triggerCount++
}, WorkflowExistenceFunc)
var wfs []wfv1.Workflow
for i := 0; i < 3; i++ {
wf := wfv1.MustUnmarshalWorkflow(wfWithSemaphore)
wf.Name = fmt.Sprintf("%s-%d", "acquired", i)
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(msg)
+ assert.Empty(failedLockName)
assert.True(status)
assert.True(wfUpdate)
wfs = append(wfs, *wf)
@@ -599,15 +616,16 @@ func TestTriggerWFWithAvailableLock(t *testing.T) {
for i := 0; i < 3; i++ {
wf := wfv1.MustUnmarshalWorkflow(wfWithSemaphore)
wf.Name = fmt.Sprintf("%s-%d", "wait", i)
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(msg)
+ assert.Equal("default/ConfigMap/my-config/workflow", failedLockName)
assert.False(status)
assert.True(wfUpdate)
}
- concurrenyMgr.Release(&wfs[0], "", wfs[0].Spec.Synchronization)
+ syncManager.Release(&wfs[0], "", wfs[0].Spec.Synchronization)
triggerCount = 0
- concurrenyMgr.Release(&wfs[1], "", wfs[1].Spec.Synchronization)
+ syncManager.Release(&wfs[1], "", wfs[1].Spec.Synchronization)
assert.Equal(2, triggerCount)
})
}
@@ -617,42 +635,45 @@ func TestMutexWfLevel(t *testing.T) {
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("WorkflowLevelMutexAcquireAndRelease", func(t *testing.T) {
// var nextKey string
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
// nextKey = key
}, WorkflowExistenceFunc)
wf := wfv1.MustUnmarshalWorkflow(wfWithMutex)
wf1 := wf.DeepCopy()
wf2 := wf.DeepCopy()
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", wf.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "", wf.Spec.Synchronization)
+ require.NoError(t, err)
assert.Empty(t, msg)
+ assert.Empty(t, failedLockName)
assert.True(t, status)
assert.True(t, wfUpdate)
- assert.NotNil(t, wf.Status.Synchronization)
- assert.NotNil(t, wf.Status.Synchronization.Mutex)
- assert.NotNil(t, wf.Status.Synchronization.Mutex.Holding)
+ require.NotNil(t, wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization.Mutex)
+ require.NotNil(t, wf.Status.Synchronization.Mutex.Holding)
wf1.Name = "two"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", wf1.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf1, "", wf1.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/my-mutex", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
wf2.Name = "three"
- status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", wf2.Spec.Synchronization)
- assert.NoError(t, err)
+ status, wfUpdate, msg, failedLockName, err = syncManager.TryAcquire(wf2, "", wf2.Spec.Synchronization)
+ require.NoError(t, err)
assert.NotEmpty(t, msg)
+ assert.Equal(t, "default/Mutex/my-mutex", failedLockName)
assert.False(t, status)
assert.True(t, wfUpdate)
- mutex := concurrenyMgr.syncLockMap["default/Mutex/my-mutex"].(*PrioritySemaphore)
- assert.NotNil(t, mutex)
+ mutex := syncManager.syncLockMap["default/Mutex/my-mutex"].(*prioritySemaphore)
+ require.NotNil(t, mutex)
assert.Len(t, mutex.pending.items, 2)
- concurrenyMgr.ReleaseAll(wf1)
+ syncManager.ReleaseAll(wf1)
assert.Len(t, mutex.pending.items, 1)
- concurrenyMgr.ReleaseAll(wf2)
+ syncManager.ReleaseAll(wf2)
assert.Len(t, mutex.pending.items, 0)
})
}
@@ -666,11 +687,11 @@ func TestCheckWorkflowExistence(t *testing.T) {
ctx := context.Background()
_, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
- assert.NoError(err)
+ require.NoError(t, err)
syncLimitFunc := GetSyncLimitFunc(kube)
t.Run("WorkflowDeleted", func(t *testing.T) {
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
// nextKey = key
}, func(s string) bool {
return strings.Contains(s, "test1")
@@ -681,18 +702,18 @@ func TestCheckWorkflowExistence(t *testing.T) {
wfSema := wfv1.MustUnmarshalWorkflow(wfWithSemaphore)
wfSema1 := wfSema.DeepCopy()
wfSema1.Name = "test2"
- _, _, _, _ = concurrenyMgr.TryAcquire(wfMutex, "", wfMutex.Spec.Synchronization)
- _, _, _, _ = concurrenyMgr.TryAcquire(wfMutex1, "", wfMutex.Spec.Synchronization)
- _, _, _, _ = concurrenyMgr.TryAcquire(wfSema, "", wfSema.Spec.Synchronization)
- _, _, _, _ = concurrenyMgr.TryAcquire(wfSema1, "", wfSema.Spec.Synchronization)
- mutex := concurrenyMgr.syncLockMap["default/Mutex/my-mutex"].(*PrioritySemaphore)
- semaphore := concurrenyMgr.syncLockMap["default/ConfigMap/my-config/workflow"]
+ _, _, _, _, _ = syncManager.TryAcquire(wfMutex, "", wfMutex.Spec.Synchronization)
+ _, _, _, _, _ = syncManager.TryAcquire(wfMutex1, "", wfMutex.Spec.Synchronization)
+ _, _, _, _, _ = syncManager.TryAcquire(wfSema, "", wfSema.Spec.Synchronization)
+ _, _, _, _, _ = syncManager.TryAcquire(wfSema1, "", wfSema.Spec.Synchronization)
+ mutex := syncManager.syncLockMap["default/Mutex/my-mutex"].(*prioritySemaphore)
+ semaphore := syncManager.syncLockMap["default/ConfigMap/my-config/workflow"]
assert.Len(mutex.getCurrentHolders(), 1)
assert.Len(mutex.getCurrentPending(), 1)
assert.Len(semaphore.getCurrentHolders(), 1)
assert.Len(semaphore.getCurrentPending(), 1)
- concurrenyMgr.CheckWorkflowExistence()
+ syncManager.CheckWorkflowExistence()
assert.Len(mutex.getCurrentHolders(), 0)
assert.Len(mutex.getCurrentPending(), 1)
assert.Len(semaphore.getCurrentHolders(), 0)
@@ -709,7 +730,7 @@ func TestTriggerWFWithSemaphoreAndMutex(t *testing.T) {
ctx := context.Background()
_, err := kube.CoreV1().ConfigMaps("default").Create(ctx, &cm, metav1.CreateOptions{})
- assert.NoError(err)
+ require.NoError(t, err)
wf := wfv1.MustUnmarshalWorkflow(`apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
@@ -839,27 +860,29 @@ status:
`)
syncLimitFunc := GetSyncLimitFunc(kube)
- concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) {
+ syncManager := NewLockManager(syncLimitFunc, func(key string) {
// nextKey = key
}, WorkflowExistenceFunc)
t.Run("InitializeMutex", func(t *testing.T) {
tmpl := wf.Spec.Templates[1]
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-sgg6t-1949670081", tmpl.Synchronization)
- assert.NoError(err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "synchronization-tmpl-level-sgg6t-1949670081", tmpl.Synchronization)
+ require.NoError(t, err)
assert.Empty(msg)
+ assert.Empty(failedLockName)
assert.True(status)
assert.True(wfUpdate)
- assert.NotNil(wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
assert.NotNil(wf.Status.Synchronization.Mutex)
})
t.Run("InitializeSemaphore", func(t *testing.T) {
tmpl := wf.Spec.Templates[2]
- status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-sgg6t-1899337224", tmpl.Synchronization)
- assert.NoError(err)
+ status, wfUpdate, msg, failedLockName, err := syncManager.TryAcquire(wf, "synchronization-tmpl-level-sgg6t-1899337224", tmpl.Synchronization)
+ require.NoError(t, err)
assert.Empty(msg)
+ assert.Empty(failedLockName)
assert.True(status)
assert.True(wfUpdate)
- assert.NotNil(wf.Status.Synchronization)
+ require.NotNil(t, wf.Status.Synchronization)
assert.NotNil(wf.Status.Synchronization.Semaphore)
})
diff --git a/workflow/sync/syncitems.go b/workflow/sync/syncitems.go
new file mode 100644
index 000000000000..8e8cd79a3860
--- /dev/null
+++ b/workflow/sync/syncitems.go
@@ -0,0 +1,52 @@
+package sync
+
+import (
+ "errors"
+ "reflect"
+
+ "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
+)
+
+type syncItem struct {
+ semaphore *v1alpha1.SemaphoreRef
+ mutex *v1alpha1.Mutex
+}
+
+func allSyncItems(sync *v1alpha1.Synchronization) ([]*syncItem, error) {
+ var syncItems []*syncItem
+ if sync.Semaphore != nil {
+ syncItems = append(syncItems, &syncItem{semaphore: sync.Semaphore})
+ }
+ if sync.Mutex != nil {
+ syncItems = append(syncItems, &syncItem{mutex: sync.Mutex})
+ }
+ for _, semaphore := range sync.Semaphores {
+ syncItems = append(syncItems, &syncItem{semaphore: semaphore})
+ }
+ for _, mtx := range sync.Mutexes {
+ syncItems = append(syncItems, &syncItem{mutex: mtx})
+ }
+ return syncItems, checkDuplicates(syncItems)
+}
+
+func checkDuplicates(items []*syncItem) error {
+ for i, item := range items {
+ for j := i + 1; j < len(items); j++ {
+ if reflect.DeepEqual(*item, *items[j]) {
+ return errors.New("Duplicate synchronization item found")
+ }
+ }
+ }
+ return nil
+}
+
+func (i *syncItem) getType() v1alpha1.SynchronizationType {
+ switch {
+ case i.semaphore != nil:
+ return v1alpha1.SynchronizationTypeSemaphore
+ case i.mutex != nil:
+ return v1alpha1.SynchronizationTypeMutex
+ default:
+ return v1alpha1.SynchronizationTypeUnknown
+ }
+}
diff --git a/workflow/sync/syncitems_test.go b/workflow/sync/syncitems_test.go
new file mode 100644
index 000000000000..f7fe5974d195
--- /dev/null
+++ b/workflow/sync/syncitems_test.go
@@ -0,0 +1,142 @@
+package sync
+
+import (
+ "testing"
+
+ apiv1 "k8s.io/api/core/v1"
+
+ "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
+
+ "github.com/stretchr/testify/assert"
+ // "github.com/stretchr/testify/require"
+)
+
+func TestNoDuplicates(t *testing.T) {
+ tests := []struct {
+ name string
+ items []*syncItem
+ }{
+ {
+ name: "single",
+ items: []*syncItem{
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ },
+ },
+ },
+ },
+ {
+ name: "two",
+ items: []*syncItem{
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ },
+ },
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "beta",
+ },
+ },
+ },
+ },
+ {
+ name: "different namespace mutex",
+ items: []*syncItem{
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ Namespace: "foo",
+ },
+ },
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ Namespace: "bar",
+ },
+ },
+ },
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ err := checkDuplicates(test.items)
+ assert.NoError(t, err)
+ })
+ }
+}
+
+func TestExpectDuplicates(t *testing.T) {
+ tests := []struct {
+ name string
+ items []*syncItem
+ }{
+ {
+ name: "simple duplicate mutex",
+ items: []*syncItem{
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ },
+ },
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ },
+ },
+ },
+ },
+ {
+ name: "simple duplicate semaphore",
+ items: []*syncItem{
+ &syncItem{
+ semaphore: &v1alpha1.SemaphoreRef{
+ ConfigMapKeyRef: &apiv1.ConfigMapKeySelector{
+ LocalObjectReference: apiv1.LocalObjectReference{
+ Name: "foo",
+ },
+ Key: "alpha",
+ },
+ },
+ },
+ &syncItem{
+ semaphore: &v1alpha1.SemaphoreRef{
+ ConfigMapKeyRef: &apiv1.ConfigMapKeySelector{
+ LocalObjectReference: apiv1.LocalObjectReference{
+ Name: "foo",
+ },
+ Key: "alpha",
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "another duplicate mutex",
+ items: []*syncItem{
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ },
+ },
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "beta",
+ },
+ },
+ &syncItem{
+ mutex: &v1alpha1.Mutex{
+ Name: "alpha",
+ },
+ },
+ },
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ err := checkDuplicates(test.items)
+ assert.Error(t, err)
+ })
+ }
+}