diff --git a/docs/api-reference/apidocs.swagger.json b/docs/api-reference/apidocs.swagger.json index 0d520d3df..c5e27ad60 100644 --- a/docs/api-reference/apidocs.swagger.json +++ b/docs/api-reference/apidocs.swagger.json @@ -765,6 +765,124 @@ ] } }, + "/v1/tenants/{tenant_id}/permissions/lookup-entities": { + "post": { + "summary": "lookup entities", + "operationId": "permissions.lookupEntities", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/PermissionsLookupEntityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Status" + } + } + }, + "parameters": [ + { + "name": "tenant_id", + "description": "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant \u003ccode\u003et1\u003c/code\u003e for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LookupEntitiesBody" + } + } + ], + "tags": [ + "Permission" + ], + "x-codeSamples": [ + { + "label": "go", + "lang": "go", + "source": "cr, err := client.Permission.LookupEntities(context.Background(), \u0026v1.PermissionsLookupEntityRequest{\n TenantId: \"t1\",\n Metadata: \u0026v1.PermissionLookupEntityRequestMetadata{\n SnapToken: \"\",\n SchemaVersion: \"\",\n Depth: 20,\n },\n EntityType: \"document\",\n Permissions: [\"edit\"],\n Subject: \u0026v1.Subject{\n Type: \"user\",\n Id: \"1\",\n }\n PageSize: 20,\n ContinuousToken: \"\",\n})" + }, + { + "label": "node", + "lang": "javascript", + "source": "client.permission.lookupEntities({\n tenantId: \"t1\",\n metadata: {\n snapToken: \"\",\n schemaVersion: \"\",\n depth: 20\n },\n entity_type: \"document\",\n permissions: [\"edit\"],\n subject: {\n type: \"user\",\n id: \"1\"\n },\n page_size: 20,\n continuous_token: \"\"\n}).then((response) =\u003e {\n console.log(response.entity_ids)\n})" + }, + { + "label": "cURL", + "lang": "curl", + "source": "curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/permissions/lookup-entities' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n \"metadata\":{\n \"snap_token\": \"\",\n \"schema_version\": \"\",\n \"depth\": 20\n },\n \"entity_type\": \"document\",\n \"permissions\": [\"edit\"],\n \"subject\": {\n \"type\":\"user\",\n \"id\":\"1\"\n },\n \"page_size\": 20,\n \"continuous_token\": \"\",\n}'" + } + ] + } + }, + "/v1/tenants/{tenant_id}/permissions/lookup-entities-stream": { + "post": { + "summary": "lookup entities stream", + "operationId": "permissions.lookupEntitiesStream", + "responses": { + "200": { + "description": "A successful response.(streaming responses)", + "schema": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/PermissionsLookupEntityStreamResponse" + }, + "error": { + "$ref": "#/definitions/Status" + } + }, + "title": "Stream result of PermissionsLookupEntityStreamResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Status" + } + } + }, + "parameters": [ + { + "name": "tenant_id", + "description": "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant \u003ccode\u003et1\u003c/code\u003e for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LookupEntitiesStreamBody" + } + } + ], + "tags": [ + "Permission" + ], + "x-codeSamples": [ + { + "label": "go", + "lang": "go", + "source": "str, err := client.Permission.LookupEntitiesStream(context.Background(), \u0026v1.PermissionsLookupEntityRequest{\n Metadata: \u0026v1.PermissionsLookupEntityRequestMetadata{\n SnapToken: \"\",\n SchemaVersion: \"\",\n Depth: 50,\n },\n EntityType: \"document\",\n Permissions: [\"view\"],\n Subject: \u0026v1.Subject{\n Type: \"user\",\n Id: \"1\",\n },\n PageSize: 20,\n ContinuousToken: \"\",\n})\n\n// handle stream response\nfor {\n res, err := str.Recv()\n\n if err == io.EOF {\n break\n }\n\n // res.EntityId, res.Permission\n}" + }, + { + "label": "node", + "lang": "javascript", + "source": "const permify = require(\"@permify/permify-node\");\nconst {PermissionsLookupEntityStreamResponse} = require(\"@permify/permify-node/dist/src/grpc/generated/base/v1/service\");\n\nfunction main() {\n const client = new permify.grpc.newClient({\n endpoint: \"localhost:3478\",\n });\n\n let res = client.permission.lookupEntitiesStream({\n metadata: {\n snapToken: \"\",\n schemaVersion: \"\",\n depth: 20\n },\n entityType: \"document\",\n permissions: [\"view\"],\n subject: {\n type: \"user\",\n id: \"1\"\n },\n page_size: 20,\n continuous_token: \"\"\n });\n\n handle(res);\n}\n\nasync function handle(res: AsyncIterable\u003cPermissionsLookupEntityStreamResponse\u003e) {\n for await (const response of res) {\n // response.entityId, response.permission\n }\n}" + } + ] + } + }, "/v1/tenants/{tenant_id}/permissions/lookup-entity": { "post": { "summary": "lookup entity", @@ -2036,6 +2154,18 @@ }, "description": "EntityFilter is used to filter entities based on the type and ids." }, + "EntityIds": { + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string" + }, + "title": "entitiy Ids" + } + } + }, "Entry": { "type": "object", "properties": { @@ -2231,6 +2361,96 @@ }, "description": "List type with typed elements, e.g. `list\u003cexample.proto.MyMessage\u003e`." }, + "LookupEntitiesBody": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/PermissionLookupEntityRequestMetadata", + "description": "Metadata associated with this request, required." + }, + "entity_type": { + "type": "string", + "description": "Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "subject": { + "$ref": "#/definitions/Subject", + "description": "Subject for which to check the permission, required." + }, + "context": { + "$ref": "#/definitions/Context", + "description": "Context associated with this request." + }, + "scope": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/StringArrayValue" + }, + "description": "Scope: A map that associates entity types with lists of identifiers. Each entry\nhelps filter requests by specifying which entities are relevant to the operation." + }, + "page_size": { + "type": "integer", + "format": "int64", + "description": "page_size is the number of entities to be returned in the response.\nThe value should be between 1 and 100." + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is an optional parameter used for pagination.\nIt should be the value received in the previous response." + } + }, + "description": "PermissionsLookupEntityRequest is the request message for the LookupEntities method in the Permission service." + }, + "LookupEntitiesStreamBody": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/PermissionLookupEntityRequestMetadata", + "description": "Metadata associated with this request, required." + }, + "entity_type": { + "type": "string", + "description": "Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "subject": { + "$ref": "#/definitions/Subject", + "description": "Subject for which to check the permission, required." + }, + "context": { + "$ref": "#/definitions/Context", + "description": "Context associated with this request." + }, + "scope": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/StringArrayValue" + }, + "description": "Scope: A map that associates entity types with lists of identifiers. Each entry\nhelps filter requests by specifying which entities are relevant to the operation." + }, + "page_size": { + "type": "integer", + "format": "int64", + "description": "page_size is the number of entities to be returned in the response.\nThe value should be between 1 and 100." + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is an optional parameter used for pagination.\nIt should be the value received in the previous response." + } + }, + "description": "PermissionsLookupEntityRequest is the request message for the LookupEntities method in the Permission service." + }, "LookupEntityBody": { "type": "object", "properties": { @@ -2647,6 +2867,40 @@ }, "description": "PermissionSubjectPermissionResponse is the response message for the SubjectPermission method in the Permission service." }, + "PermissionsLookupEntityResponse": { + "type": "object", + "properties": { + "entity_ids": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/EntityIds" + }, + "description": "List of identifiers for entities that match the lookup." + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is a string that can be used to paginate and retrieve the next set of results." + } + }, + "description": "PermissionLookupEntityResponse is the response message for the LookupEntity method in the Permission service." + }, + "PermissionsLookupEntityStreamResponse": { + "type": "object", + "properties": { + "entity_id": { + "type": "string", + "description": "Identifier for an entity that matches the lookup." + }, + "permission": { + "type": "string", + "title": "The name of the permission for which the specified entity_id has access" + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is a string that can be used to paginate and retrieve the next set of results." + } + } + }, "PrimitiveType": { "type": "string", "enum": [ diff --git a/docs/api-reference/openapiv2/apidocs.swagger.json b/docs/api-reference/openapiv2/apidocs.swagger.json index 88e7475e0..32ce436d1 100644 --- a/docs/api-reference/openapiv2/apidocs.swagger.json +++ b/docs/api-reference/openapiv2/apidocs.swagger.json @@ -765,6 +765,124 @@ ] } }, + "/v1/tenants/{tenant_id}/permissions/lookup-entities": { + "post": { + "summary": "lookup entities", + "operationId": "permissions.lookupEntities", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/PermissionsLookupEntityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Status" + } + } + }, + "parameters": [ + { + "name": "tenant_id", + "description": "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant \u003ccode\u003et1\u003c/code\u003e for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LookupEntitiesBody" + } + } + ], + "tags": [ + "Permission" + ], + "x-codeSamples": [ + { + "label": "go", + "lang": "go", + "source": "cr, err := client.Permission.LookupEntities(context.Background(), \u0026v1.PermissionsLookupEntityRequest{\n TenantId: \"t1\",\n Metadata: \u0026v1.PermissionLookupEntityRequestMetadata{\n SnapToken: \"\",\n SchemaVersion: \"\",\n Depth: 20,\n },\n EntityType: \"document\",\n Permissions: [\"edit\"],\n Subject: \u0026v1.Subject{\n Type: \"user\",\n Id: \"1\",\n }\n PageSize: 20,\n ContinuousToken: \"\",\n})" + }, + { + "label": "node", + "lang": "javascript", + "source": "client.permission.lookupEntities({\n tenantId: \"t1\",\n metadata: {\n snapToken: \"\",\n schemaVersion: \"\",\n depth: 20\n },\n entity_type: \"document\",\n permissions: [\"edit\"],\n subject: {\n type: \"user\",\n id: \"1\"\n },\n page_size: 20,\n continuous_token: \"\"\n}).then((response) =\u003e {\n console.log(response.entity_ids)\n})" + }, + { + "label": "cURL", + "lang": "curl", + "source": "curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/permissions/lookup-entities' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n \"metadata\":{\n \"snap_token\": \"\",\n \"schema_version\": \"\",\n \"depth\": 20\n },\n \"entity_type\": \"document\",\n \"permissions\": [\"edit\"],\n \"subject\": {\n \"type\":\"user\",\n \"id\":\"1\"\n },\n \"page_size\": 20,\n \"continuous_token\": \"\",\n}'" + } + ] + } + }, + "/v1/tenants/{tenant_id}/permissions/lookup-entities-stream": { + "post": { + "summary": "lookup entities stream", + "operationId": "permissions.lookupEntitiesStream", + "responses": { + "200": { + "description": "A successful response.(streaming responses)", + "schema": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/PermissionsLookupEntityStreamResponse" + }, + "error": { + "$ref": "#/definitions/Status" + } + }, + "title": "Stream result of PermissionsLookupEntityStreamResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Status" + } + } + }, + "parameters": [ + { + "name": "tenant_id", + "description": "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant \u003ccode\u003et1\u003c/code\u003e for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LookupEntitiesStreamBody" + } + } + ], + "tags": [ + "Permission" + ], + "x-codeSamples": [ + { + "label": "go", + "lang": "go", + "source": "str, err := client.Permission.LookupEntitiesStream(context.Background(), \u0026v1.PermissionsLookupEntityRequest{\n Metadata: \u0026v1.PermissionsLookupEntityRequestMetadata{\n SnapToken: \"\",\n SchemaVersion: \"\",\n Depth: 50,\n },\n EntityType: \"document\",\n Permissions: [\"view\"],\n Subject: \u0026v1.Subject{\n Type: \"user\",\n Id: \"1\",\n },\n PageSize: 20,\n ContinuousToken: \"\",\n})\n\n// handle stream response\nfor {\n res, err := str.Recv()\n\n if err == io.EOF {\n break\n }\n\n // res.EntityId, res.Permission\n}" + }, + { + "label": "node", + "lang": "javascript", + "source": "const permify = require(\"@permify/permify-node\");\nconst {PermissionsLookupEntityStreamResponse} = require(\"@permify/permify-node/dist/src/grpc/generated/base/v1/service\");\n\nfunction main() {\n const client = new permify.grpc.newClient({\n endpoint: \"localhost:3478\",\n });\n\n let res = client.permission.lookupEntitiesStream({\n metadata: {\n snapToken: \"\",\n schemaVersion: \"\",\n depth: 20\n },\n entityType: \"document\",\n permissions: [\"view\"],\n subject: {\n type: \"user\",\n id: \"1\"\n },\n page_size: 20,\n continuous_token: \"\"\n });\n\n handle(res);\n}\n\nasync function handle(res: AsyncIterable\u003cPermissionsLookupEntityStreamResponse\u003e) {\n for await (const response of res) {\n // response.entityId, response.permission\n }\n}" + } + ] + } + }, "/v1/tenants/{tenant_id}/permissions/lookup-entity": { "post": { "summary": "lookup entity", @@ -2028,6 +2146,18 @@ }, "description": "EntityFilter is used to filter entities based on the type and ids." }, + "EntityIds": { + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string" + }, + "title": "entitiy Ids" + } + } + }, "Entry": { "type": "object", "properties": { @@ -2221,6 +2351,96 @@ }, "description": "List type with typed elements, e.g. `list\u003cexample.proto.MyMessage\u003e`." }, + "LookupEntitiesBody": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/PermissionLookupEntityRequestMetadata", + "description": "Metadata associated with this request, required." + }, + "entity_type": { + "type": "string", + "description": "Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "subject": { + "$ref": "#/definitions/Subject", + "description": "Subject for which to check the permission, required." + }, + "context": { + "$ref": "#/definitions/Context", + "description": "Context associated with this request." + }, + "scope": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/StringArrayValue" + }, + "description": "Scope: A map that associates entity types with lists of identifiers. Each entry\nhelps filter requests by specifying which entities are relevant to the operation." + }, + "page_size": { + "type": "integer", + "format": "int64", + "description": "page_size is the number of entities to be returned in the response.\nThe value should be between 1 and 100." + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is an optional parameter used for pagination.\nIt should be the value received in the previous response." + } + }, + "description": "PermissionsLookupEntityRequest is the request message for the LookupEntities method in the Permission service." + }, + "LookupEntitiesStreamBody": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/PermissionLookupEntityRequestMetadata", + "description": "Metadata associated with this request, required." + }, + "entity_type": { + "type": "string", + "description": "Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes." + }, + "subject": { + "$ref": "#/definitions/Subject", + "description": "Subject for which to check the permission, required." + }, + "context": { + "$ref": "#/definitions/Context", + "description": "Context associated with this request." + }, + "scope": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/StringArrayValue" + }, + "description": "Scope: A map that associates entity types with lists of identifiers. Each entry\nhelps filter requests by specifying which entities are relevant to the operation." + }, + "page_size": { + "type": "integer", + "format": "int64", + "description": "page_size is the number of entities to be returned in the response.\nThe value should be between 1 and 100." + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is an optional parameter used for pagination.\nIt should be the value received in the previous response." + } + }, + "description": "PermissionsLookupEntityRequest is the request message for the LookupEntities method in the Permission service." + }, "LookupEntityBody": { "type": "object", "properties": { @@ -2633,6 +2853,40 @@ }, "description": "PermissionSubjectPermissionResponse is the response message for the SubjectPermission method in the Permission service." }, + "PermissionsLookupEntityResponse": { + "type": "object", + "properties": { + "entity_ids": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/EntityIds" + }, + "description": "List of identifiers for entities that match the lookup." + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is a string that can be used to paginate and retrieve the next set of results." + } + }, + "description": "PermissionLookupEntityResponse is the response message for the LookupEntity method in the Permission service." + }, + "PermissionsLookupEntityStreamResponse": { + "type": "object", + "properties": { + "entity_id": { + "type": "string", + "description": "Identifier for an entity that matches the lookup." + }, + "permission": { + "type": "string", + "title": "The name of the permission for which the specified entity_id has access" + }, + "continuous_token": { + "type": "string", + "description": "continuous_token is a string that can be used to paginate and retrieve the next set of results." + } + } + }, "PrimitiveType": { "type": "string", "enum": [ diff --git a/integration-test/usecases/facebook_groups_test.go b/integration-test/usecases/facebook_groups_test.go index 5991eaec5..3016054f7 100644 --- a/integration-test/usecases/facebook_groups_test.go +++ b/integration-test/usecases/facebook_groups_test.go @@ -111,13 +111,17 @@ var _ = Describe("facebook-groups-test", func() { Context: &base.Context{ Tuples: contextTuples, }, - EntityType: filter.EntityType, - Permission: permission, - Subject: subject, + EntityType: filter.EntityType, + Permissions: []string{permission}, + Subject: subject, }) Expect(err).ShouldNot(HaveOccurred()) - Expect(IsSameArray(res.GetEntityIds(), expected)).Should(Equal(true)) + var responseIdsForPermission []string + if res, ok := res.GetEntityIds()[permission]; ok { + responseIdsForPermission = res.Ids + } + Expect(IsSameArray(responseIdsForPermission, expected)).Should(Equal(true)) } } } diff --git a/integration-test/usecases/google_docs_test.go b/integration-test/usecases/google_docs_test.go index 949eee71e..888daea14 100644 --- a/integration-test/usecases/google_docs_test.go +++ b/integration-test/usecases/google_docs_test.go @@ -111,13 +111,17 @@ var _ = Describe("google-docs-test", func() { Context: &base.Context{ Tuples: contextTuples, }, - EntityType: filter.EntityType, - Permission: permission, - Subject: subject, + EntityType: filter.EntityType, + Permissions: []string{permission}, + Subject: subject, }) Expect(err).ShouldNot(HaveOccurred()) - Expect(IsSameArray(res.GetEntityIds(), expected)).Should(Equal(true)) + var responseIdsForPermission []string + if res, ok := res.GetEntityIds()[permission]; ok { + responseIdsForPermission = res.Ids + } + Expect(IsSameArray(responseIdsForPermission, expected)).Should(Equal(true)) } } } diff --git a/integration-test/usecases/notion_test.go b/integration-test/usecases/notion_test.go index 192df8b5a..587d3b5af 100644 --- a/integration-test/usecases/notion_test.go +++ b/integration-test/usecases/notion_test.go @@ -111,13 +111,17 @@ var _ = Describe("notion-test", func() { Context: &base.Context{ Tuples: contextTuples, }, - EntityType: filter.EntityType, - Permission: permission, - Subject: subject, + EntityType: filter.EntityType, + Permissions: []string{permission}, + Subject: subject, }) Expect(err).ShouldNot(HaveOccurred()) - Expect(IsSameArray(res.GetEntityIds(), expected)).Should(Equal(true)) + var responseIdsForPermission []string + if res, ok := res.GetEntityIds()[permission]; ok { + responseIdsForPermission = res.Ids + } + Expect(IsSameArray(responseIdsForPermission, expected)).Should(Equal(true)) } } } diff --git a/internal/engines/bulk.go b/internal/engines/bulk.go index 13db0226f..a2d20ab30 100644 --- a/internal/engines/bulk.go +++ b/internal/engines/bulk.go @@ -54,7 +54,7 @@ type BulkChecker struct { // callback is a function that handles the result of each permission check. // It is called with the entity ID and the result of the permission check (e.g., allowed or denied). - callback func(entityID, ct string) + callback func(entityID, permission, ct string) // sortedList is a slice that stores BulkCheckerRequest objects. // This list is maintained in a sorted order based on some criteria, such as the entity ID. @@ -76,7 +76,7 @@ type BulkChecker struct { // engine: the CheckEngine to use for permission checks // callback: a callback function that handles the result of each permission check // concurrencyLimit: the maximum number of concurrent permission checks -func NewBulkChecker(ctx context.Context, checker invoke.Check, typ BulkCheckerType, callback func(entityID, ct string), concurrencyLimit int) *BulkChecker { +func NewBulkChecker(ctx context.Context, checker invoke.Check, typ BulkCheckerType, callback func(entityID, permission, ct string), concurrencyLimit int) *BulkChecker { bc := &BulkChecker{ RequestChan: make(chan BulkCheckerRequest), checker: checker, @@ -208,6 +208,7 @@ func (bc *BulkChecker) ExecuteRequests(size uint32) error { for processedIndex < len(listCopy) && results[processedIndex] != base.CheckResult_CHECK_RESULT_UNSPECIFIED { // If the result at the processed index is allowed, call the callback function if results[processedIndex] == base.CheckResult_CHECK_RESULT_ALLOWED { + if atomic.AddInt64(&successCount, 1) <= int64(size) { ct := "" if processedIndex+1 < len(listCopy) { @@ -218,11 +219,14 @@ func (bc *BulkChecker) ExecuteRequests(size uint32) error { ct = utils.NewContinuousToken(listCopy[processedIndex+1].Request.GetSubject().GetId()).Encode().String() } } + // Depending on the type of check (entity or subject), call the appropriate callback if bc.typ == BULK_ENTITY { - bc.callback(listCopy[processedIndex].Request.GetEntity().GetId(), ct) + bc.callback(listCopy[processedIndex].Request.GetEntity().GetId(), listCopy[processedIndex].Request.GetPermission(), ct) + } else if bc.typ == BULK_SUBJECT { - bc.callback(listCopy[processedIndex].Request.GetSubject().GetId(), ct) + bc.callback(listCopy[processedIndex].Request.GetSubject().GetId(), listCopy[processedIndex].Request.GetPermission(), ct) + } } } @@ -246,13 +250,13 @@ func (bc *BulkChecker) ExecuteRequests(size uint32) error { type BulkEntityPublisher struct { bulkChecker *BulkChecker - request *base.PermissionLookupEntityRequest + request *base.PermissionsLookupEntityRequest // context to manage goroutines and cancellation ctx context.Context } // NewBulkEntityPublisher creates a new BulkStreamer instance. -func NewBulkEntityPublisher(ctx context.Context, request *base.PermissionLookupEntityRequest, bulkChecker *BulkChecker) *BulkEntityPublisher { +func NewBulkEntityPublisher(ctx context.Context, request *base.PermissionsLookupEntityRequest, bulkChecker *BulkChecker) *BulkEntityPublisher { return &BulkEntityPublisher{ bulkChecker: bulkChecker, request: request, @@ -261,17 +265,22 @@ func NewBulkEntityPublisher(ctx context.Context, request *base.PermissionLookupE } // Publish publishes a permission check request to the BulkChecker. -func (s *BulkEntityPublisher) Publish(entity *base.Entity, metadata *base.PermissionCheckRequestMetadata, context *base.Context, result base.CheckResult) { - s.bulkChecker.RequestChan <- BulkCheckerRequest{ - Request: &base.PermissionCheckRequest{ - TenantId: s.request.GetTenantId(), - Metadata: metadata, - Entity: entity, - Permission: s.request.GetPermission(), - Subject: s.request.GetSubject(), - Context: context, - }, - Result: result, +func (s *BulkEntityPublisher) Publish(entity *base.Entity, metadata *base.PermissionCheckRequestMetadata, context *base.Context, result base.CheckResult, permissionChecks *VisitsMap) { + for _, permission := range s.request.GetPermissions() { + if !permissionChecks.AddER(entity, permission) { + continue + } + s.bulkChecker.RequestChan <- BulkCheckerRequest{ + Request: &base.PermissionCheckRequest{ + TenantId: s.request.GetTenantId(), + Metadata: metadata, + Entity: entity, + Permission: permission, + Subject: s.request.GetSubject(), + Context: context, + }, + Result: result, + } } } diff --git a/internal/engines/entityFilter.go b/internal/engines/entityFilter.go index 20a586dfc..bd2b083a6 100644 --- a/internal/engines/entityFilter.go +++ b/internal/engines/entityFilter.go @@ -3,7 +3,6 @@ package engines import ( "context" "errors" - "golang.org/x/sync/errgroup" "github.com/Permify/permify/internal/schema" @@ -35,31 +34,36 @@ func (engine *EntityFilter) EntityFilter( request *base.PermissionEntityFilterRequest, // A permission request for linked entities. visits *VisitsMap, // A map that keeps track of visited entities to avoid infinite loops. publisher *BulkEntityPublisher, // A custom publisher that publishes results in bulk. + permissionChecks *VisitsMap, // A thread safe map to check if for a entity same permission already checked or not ) (err error) { // Returns an error if one occurs during execution. // Check if direct result - if request.GetEntrance().GetType() == request.GetSubject().GetType() && request.GetEntrance().GetValue() == request.GetSubject().GetRelation() { - found := &base.Entity{ - Type: request.GetSubject().GetType(), - Id: request.GetSubject().GetId(), - } + for _, entrance := range request.Entrances { + if entrance.GetType() == request.GetSubject().GetType() && entrance.GetValue() == request.GetSubject().GetRelation() { + found := &base.Entity{ + Type: request.GetSubject().GetType(), + Id: request.GetSubject().GetId(), + } - if !visits.AddPublished(found) { // If the entity and relation has already been visited. - return nil - } + if !visits.AddPublished(found) { // If the entity and relation has already been visited. + return nil + } - // If the entity reference is the same as the subject, publish the result directly and return. - publisher.Publish(found, &base.PermissionCheckRequestMetadata{ - SnapToken: request.GetMetadata().GetSnapToken(), - SchemaVersion: request.GetMetadata().GetSchemaVersion(), - Depth: request.GetMetadata().GetDepth(), - }, request.GetContext(), base.CheckResult_CHECK_RESULT_UNSPECIFIED) + // If the entity reference is the same as the subject, publish the result directly and return. + publisher.Publish(found, &base.PermissionCheckRequestMetadata{ + SnapToken: request.GetMetadata().GetSnapToken(), + SchemaVersion: request.GetMetadata().GetSchemaVersion(), + Depth: request.GetMetadata().GetDepth(), + }, request.GetContext(), base.CheckResult_CHECK_RESULT_UNSPECIFIED, permissionChecks) + // Breaking loop here as publisher would make sure now to check for all permissions + break + } } // Retrieve linked entrances cn := schema.NewLinkedGraph(engine.schema) // Create a new linked graph from the schema definition. var entrances []*schema.LinkedEntrance entrances, err = cn.LinkedEntrances( - request.GetEntrance(), + request.GetEntrances(), &base.Entrance{ Type: request.GetSubject().GetType(), Value: request.GetSubject().GetRelation(), @@ -82,7 +86,7 @@ func (engine *EntityFilter) EntityFilter( // Switch on the kind of linked entrance. switch entrance.LinkedEntranceKind() { case schema.RelationLinkedEntrance: // If the linked entrance is a relation entrance. - err = engine.relationEntrance(cont, request, entrance, visits, g, publisher) // Call the relation entrance method. + err = engine.relationEntrance(cont, request, entrance, visits, g, publisher, permissionChecks) // Call the relation entrance method. if err != nil { return err } @@ -93,17 +97,17 @@ func (engine *EntityFilter) EntityFilter( Id: request.GetSubject().GetId(), }, Relation: entrance.TargetEntrance.GetValue(), - }, visits, g, publisher) + }, visits, g, publisher, permissionChecks) if err != nil { return err } case schema.AttributeLinkedEntrance: // If the linked entrance is a computed user set entrance. - err = engine.attributeEntrance(cont, request, entrance, visits, g, publisher) // Call the tuple to user set entrance method. + err = engine.attributeEntrance(cont, request, entrance, visits, g, publisher, permissionChecks) // Call the tuple to user set entrance method. if err != nil { return err } case schema.TupleToUserSetLinkedEntrance: // If the linked entrance is a tuple to user set entrance. - err = engine.tupleToUserSetEntrance(cont, request, entrance, visits, g, publisher) // Call the tuple to user set entrance method. + err = engine.tupleToUserSetEntrance(cont, request, entrance, visits, g, publisher, permissionChecks) // Call the tuple to user set entrance method. if err != nil { return err } @@ -123,6 +127,7 @@ func (engine *EntityFilter) attributeEntrance( visits *VisitsMap, // A map that keeps track of visited entities to avoid infinite loops. g *errgroup.Group, // An errgroup used for executing goroutines. publisher *BulkEntityPublisher, // A custom publisher that publishes results in bulk. + entityChecks *VisitsMap, // A map that keeps track of visited entities to avoid infinite loops. ) error { // Returns an error if one occurs during execution. // Retrieve the scope associated with the target entrance type. @@ -156,10 +161,12 @@ func (engine *EntityFilter) attributeEntrance( // Determine the pagination settings based on the entity type in the request. // If the entity type matches the target entrance, use cursor pagination with sorting by "entity_id". // Otherwise, use the default pagination settings. - if request.GetEntrance().GetType() == entrance.TargetEntrance.GetType() { - pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id")) - } else { - pagination = database.NewCursorPagination() + pagination = database.NewCursorPagination() + for _, reqEntrance := range request.GetEntrances() { + if reqEntrance.GetType() == entrance.TargetEntrance.GetType() { + pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id")) + break + } } // Query the relationships using the specified pagination settings. @@ -193,7 +200,7 @@ func (engine *EntityFilter) attributeEntrance( &base.Entity{ Type: entrance.TargetEntrance.GetType(), Id: current.GetEntity().GetId(), - }, visits, g, publisher) + }, visits, g, publisher, entityChecks) }) } @@ -208,6 +215,7 @@ func (engine *EntityFilter) relationEntrance( visits *VisitsMap, // A map that keeps track of visited entities to avoid infinite loops. g *errgroup.Group, // An errgroup used for executing goroutines. publisher *BulkEntityPublisher, // A custom publisher that publishes results in bulk. + permissionChecks *VisitsMap, // A thread safe map to check if for a entity same permission already checked or not ) error { // Returns an error if one occurs during execution. // Retrieve the scope associated with the target entrance type. // Check if it exists to avoid accessing a nil map entry. @@ -245,10 +253,12 @@ func (engine *EntityFilter) relationEntrance( // Determine the pagination settings based on the entity type in the request. // If the entity type matches the target entrance, use cursor pagination with sorting by "entity_id". // Otherwise, use the default pagination settings. - if request.GetEntrance().GetType() == entrance.TargetEntrance.GetType() { - pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id")) - } else { - pagination = database.NewCursorPagination() + pagination = database.NewCursorPagination() + for _, reqEntrance := range request.GetEntrances() { + if reqEntrance.GetType() == entrance.TargetEntrance.GetType() { + pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id")) + break + } } // Query the relationships using the specified pagination settings. @@ -282,7 +292,7 @@ func (engine *EntityFilter) relationEntrance( Id: current.GetEntity().GetId(), }, Relation: current.GetRelation(), - }, visits, g, publisher) + }, visits, g, publisher, permissionChecks) }) } return nil @@ -302,6 +312,8 @@ func (engine *EntityFilter) tupleToUserSetEntrance( g *errgroup.Group, // A custom publisher that publishes results in bulk. publisher *BulkEntityPublisher, + // A thread safe map to check if for a entity same permission already checked or not + permissionChecks *VisitsMap, ) error { // Returns an error if one occurs during execution. // Retrieve the scope associated with the target entrance type. // Check if it exists to avoid accessing a nil map entry. @@ -339,10 +351,12 @@ func (engine *EntityFilter) tupleToUserSetEntrance( // Determine the pagination settings based on the entity type in the request. // If the entity type matches the target entrance, use cursor pagination with sorting by "entity_id". // Otherwise, use the default pagination settings. - if request.GetEntrance().GetType() == entrance.TargetEntrance.GetType() { - pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id")) - } else { - pagination = database.NewCursorPagination() + pagination = database.NewCursorPagination() + for _, reqEntrance := range request.GetEntrances() { + if reqEntrance.GetType() == entrance.TargetEntrance.GetType() { + pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id")) + break + } } // Query the relationships using the specified pagination settings. @@ -376,7 +390,7 @@ func (engine *EntityFilter) tupleToUserSetEntrance( Id: current.GetEntity().GetId(), }, Relation: entrance.TargetEntrance.GetValue(), - }, visits, g, publisher) + }, visits, g, publisher, permissionChecks) }) } return nil @@ -390,6 +404,7 @@ func (engine *EntityFilter) lt( visits *VisitsMap, // A map that keeps track of visited entities to avoid infinite loops. g *errgroup.Group, // An errgroup used for executing goroutines. publisher *BulkEntityPublisher, // A custom publisher that publishes results in bulk. + permissionChecks *VisitsMap, // A thread safe map to check if for a entity same permission already checked or not ) error { // Returns an error if one occurs during execution. if !visits.AddER(found.GetEntity(), found.GetRelation()) { // If the entity and relation has already been visited. return nil @@ -401,7 +416,7 @@ func (engine *EntityFilter) lt( cn := schema.NewLinkedGraph(engine.schema) var entrances []*schema.LinkedEntrance entrances, err = cn.LinkedEntrances( - request.GetEntrance(), + request.GetEntrances(), &base.Entrance{ Type: request.GetSubject().GetType(), Value: request.GetSubject().GetRelation(), @@ -412,24 +427,26 @@ func (engine *EntityFilter) lt( } if entrances == nil { // If there are no linked entrances for the request. - if found.GetEntity().GetType() == request.GetEntrance().GetType() && found.GetRelation() == request.GetEntrance().GetValue() { // Check if the found entity matches the requested entity reference. - if !visits.AddPublished(found.GetEntity()) { // If the entity and relation has already been visited. + for _, entrance := range request.GetEntrances() { + if found.GetEntity().GetType() == entrance.GetType() && found.GetRelation() == entrance.GetValue() { // Check if the found entity matches the requested entity reference. + if !visits.AddPublished(found.GetEntity()) { // If the entity and relation has already been visited. + return nil + } + publisher.Publish(found.GetEntity(), &base.PermissionCheckRequestMetadata{ // Publish the found entity with the permission check metadata. + SnapToken: request.GetMetadata().GetSnapToken(), + SchemaVersion: request.GetMetadata().GetSchemaVersion(), + Depth: request.GetMetadata().GetDepth(), + }, request.GetContext(), base.CheckResult_CHECK_RESULT_UNSPECIFIED, permissionChecks) return nil } - publisher.Publish(found.GetEntity(), &base.PermissionCheckRequestMetadata{ // Publish the found entity with the permission check metadata. - SnapToken: request.GetMetadata().GetSnapToken(), - SchemaVersion: request.GetMetadata().GetSchemaVersion(), - Depth: request.GetMetadata().GetDepth(), - }, request.GetContext(), base.CheckResult_CHECK_RESULT_UNSPECIFIED) - return nil } return nil // Otherwise, return without publishing any results. } g.Go(func() error { return engine.EntityFilter(ctx, &base.PermissionEntityFilterRequest{ // Call the Run method recursively with a new permission request. - TenantId: request.GetTenantId(), - Entrance: request.GetEntrance(), + TenantId: request.GetTenantId(), + Entrances: request.GetEntrances(), Subject: &base.Subject{ Type: found.GetEntity().GetType(), Id: found.GetEntity().GetId(), @@ -439,7 +456,7 @@ func (engine *EntityFilter) lt( Metadata: request.GetMetadata(), Context: request.GetContext(), Cursor: request.GetCursor(), - }, visits, publisher) + }, visits, publisher, permissionChecks) }) return nil } @@ -451,6 +468,7 @@ func (engine *EntityFilter) la( visits *VisitsMap, // A map that keeps track of visited entities to avoid infinite loops. g *errgroup.Group, // An errgroup used for executing goroutines. publisher *BulkEntityPublisher, // A custom publisher that publishes results in bulk. + entityChecks *VisitsMap, // A thread safe map to check if for a entity same permission already checked or not ) error { // Returns an error if one occurs during execution. if !visits.AddPublished(found) { // If the entity and relation has already been visited. return nil @@ -460,6 +478,6 @@ func (engine *EntityFilter) la( SnapToken: request.GetMetadata().GetSnapToken(), SchemaVersion: request.GetMetadata().GetSchemaVersion(), Depth: request.GetMetadata().GetDepth(), - }, request.GetContext(), base.CheckResult_CHECK_RESULT_UNSPECIFIED) + }, request.GetContext(), base.CheckResult_CHECK_RESULT_UNSPECIFIED, entityChecks) return nil } diff --git a/internal/engines/lookup.go b/internal/engines/lookup.go index 0c2464f03..0b6005b91 100644 --- a/internal/engines/lookup.go +++ b/internal/engines/lookup.go @@ -3,12 +3,11 @@ package engines import ( "context" "errors" - "sync" - "github.com/Permify/permify/internal/invoke" "github.com/Permify/permify/internal/schema" "github.com/Permify/permify/internal/storage" base "github.com/Permify/permify/pkg/pb/base/v1" + "sync" ) type LookupEngine struct { @@ -61,7 +60,7 @@ func (engine *LookupEngine) LookupEntity(ctx context.Context, request *base.Perm // Callback function which is called for each entity. If the entity passes the permission check, // the entity ID is appended to the entityIDs slice. - callback := func(entityID, token string) { + callback := func(entityID, permission, token string) { mu.Lock() // Safeguard access to the shared slice with a mutex defer mu.Unlock() // Ensure the lock is released after appending the ID entityIDs = append(entityIDs, entityID) @@ -72,7 +71,7 @@ func (engine *LookupEngine) LookupEntity(ctx context.Context, request *base.Perm checker := NewBulkChecker(ctx, engine.checkEngine, BULK_ENTITY, callback, engine.concurrencyLimit) // Create and start BulkPublisher. It receives entities and passes them to BulkChecker. - publisher := NewBulkEntityPublisher(ctx, request, checker) + publisher := NewBulkEntityPublisher(ctx, ConvertToPermissionsLookupEntityRequest(request), checker) // Retrieve the schema of the entity based on the tenantId and schema version var sc *base.SchemaDefinition @@ -84,6 +83,8 @@ func (engine *LookupEngine) LookupEntity(ctx context.Context, request *base.Perm // Create a map to keep track of visited entities visits := &VisitsMap{} + permissionChecks := &VisitsMap{} + // Perform an entity filter operation based on the permission request err = NewEntityFilter(engine.dataReader, sc).EntityFilter(ctx, &base.PermissionEntityFilterRequest{ TenantId: request.GetTenantId(), @@ -92,15 +93,17 @@ func (engine *LookupEngine) LookupEntity(ctx context.Context, request *base.Perm SchemaVersion: request.GetMetadata().GetSchemaVersion(), Depth: request.GetMetadata().GetDepth(), }, - Entrance: &base.Entrance{ - Type: request.GetEntityType(), - Value: request.GetPermission(), + Entrances: []*base.Entrance{ + { + Type: request.GetEntityType(), + Value: request.GetPermission(), + }, }, Subject: request.GetSubject(), Context: request.GetContext(), Scope: request.GetScope(), Cursor: request.GetContinuousToken(), - }, visits, publisher) + }, visits, publisher, permissionChecks) if err != nil { return nil, err } @@ -118,6 +121,89 @@ func (engine *LookupEngine) LookupEntity(ctx context.Context, request *base.Perm }, nil } +// LookupEntities performs a permission check on a set of entities and returns a response +// containing the IDs of the entities that have the requested permissions. +func (engine *LookupEngine) LookupEntities(ctx context.Context, request *base.PermissionsLookupEntityRequest) (response *base.PermissionsLookupEntityResponse, err error) { + // A mutex and slice are declared to safely store entity IDs from concurrent callbacks + var mu sync.Mutex + entityIDsByPermission := make(map[string]*base.EntityIds) + var ct string + + size := request.GetPageSize() + if size == 0 { + size = 1000 + } + + // Callback function which is called for each entity. If the entity passes the permission check, + // the entity ID is appended to the entityIDs slice. + callback := func(entityID, permission, token string) { + mu.Lock() // Safeguard access to the shared slice with a mutex + defer mu.Unlock() // Ensure the lock is released after appending the ID + if _, exists := entityIDsByPermission[permission]; !exists { + // If not, initialize it with an empty EntityIds struct + entityIDsByPermission[permission] = &base.EntityIds{Ids: []string{}} + } + entityIDsByPermission[permission].Ids = append(entityIDsByPermission[permission].Ids, entityID) + ct = token + } + + // Create and start BulkChecker. It performs permission checks in parallel. + checker := NewBulkChecker(ctx, engine.checkEngine, BULK_ENTITY, callback, engine.concurrencyLimit) + + // Create and start BulkPublisher. It receives entities and passes them to BulkChecker. + publisher := NewBulkEntityPublisher(ctx, request, checker) + + // Retrieve the schema of the entity based on the tenantId and schema version + var sc *base.SchemaDefinition + sc, err = engine.readSchema(ctx, request.GetTenantId(), request.GetMetadata().GetSchemaVersion()) + if err != nil { + return nil, err + } + + // Create a map to keep track of visited entities + visits := &VisitsMap{} + permissionChecks := &VisitsMap{} + + entrances := make([]*base.Entrance, 0) + + for _, permission := range request.GetPermissions() { + entrances = append(entrances, &base.Entrance{ + Type: request.GetEntityType(), + Value: permission, + }) + } + + // Perform an entity filter operation based on the permissions request + err = NewEntityFilter(engine.dataReader, sc).EntityFilter(ctx, &base.PermissionEntityFilterRequest{ + TenantId: request.GetTenantId(), + Metadata: &base.PermissionEntityFilterRequestMetadata{ + SnapToken: request.GetMetadata().GetSnapToken(), + SchemaVersion: request.GetMetadata().GetSchemaVersion(), + Depth: request.GetMetadata().GetDepth(), + }, + Entrances: entrances, + Subject: request.GetSubject(), + Context: request.GetContext(), + Scope: request.GetScope(), + Cursor: request.GetContinuousToken(), + }, visits, publisher, permissionChecks) + if err != nil { + return nil, err + } + + // At this point, the BulkChecker has collected and sorted requests + err = checker.ExecuteRequests(size) // Execute the collected requests in parallel + if err != nil { + return nil, err + } + + // Return response containing allowed entity IDs + return &base.PermissionsLookupEntityResponse{ + EntityIds: entityIDsByPermission, + ContinuousToken: ct, + }, nil +} + // LookupEntityStream performs a permission check on a set of entities and streams the results // containing the IDs of the entities that have the requested permission. func (engine *LookupEngine) LookupEntityStream(ctx context.Context, request *base.PermissionLookupEntityRequest, server base.Permission_LookupEntityStreamServer) (err error) { @@ -128,7 +214,7 @@ func (engine *LookupEngine) LookupEntityStream(ctx context.Context, request *bas // Define a callback function that will be called for each entity that passes the permission check. // If the check result is allowed, it sends the entity ID to the server stream. - callback := func(entityID, token string) { + callback := func(entityID, permission, token string) { err := server.Send(&base.PermissionLookupEntityStreamResponse{ EntityId: entityID, ContinuousToken: token, @@ -143,7 +229,7 @@ func (engine *LookupEngine) LookupEntityStream(ctx context.Context, request *bas checker := NewBulkChecker(ctx, engine.checkEngine, BULK_ENTITY, callback, engine.concurrencyLimit) // Create and start BulkPublisher. It receives entities and passes them to BulkChecker. - publisher := NewBulkEntityPublisher(ctx, request, checker) + publisher := NewBulkEntityPublisher(ctx, ConvertToPermissionsLookupEntityRequest(request), checker) // Retrieve the entity definition schema based on the tenantId and schema version var sc *base.SchemaDefinition @@ -153,6 +239,7 @@ func (engine *LookupEngine) LookupEntityStream(ctx context.Context, request *bas } visits := &VisitsMap{} + permissionChecks := &VisitsMap{} // Perform an entity filter operation based on the permission request err = NewEntityFilter(engine.dataReader, sc).EntityFilter(ctx, &base.PermissionEntityFilterRequest{ @@ -162,14 +249,88 @@ func (engine *LookupEngine) LookupEntityStream(ctx context.Context, request *bas SchemaVersion: request.GetMetadata().GetSchemaVersion(), Depth: request.GetMetadata().GetDepth(), }, - Entrance: &base.Entrance{ - Type: request.GetEntityType(), - Value: request.GetPermission(), + Entrances: []*base.Entrance{ + { + Type: request.GetEntityType(), + Value: request.GetPermission(), + }, }, Subject: request.GetSubject(), Context: request.GetContext(), Cursor: request.GetContinuousToken(), - }, visits, publisher) + }, visits, publisher, permissionChecks) + if err != nil { + return err + } + + err = checker.ExecuteRequests(size) + if err != nil { + return err + } + + return nil +} + +// LookupEntitiesStream performs a permission check on a set of entities and streams the results +// containing the IDs of the entities that have the requested permissions. +func (engine *LookupEngine) LookupEntitiesStream(ctx context.Context, request *base.PermissionsLookupEntityRequest, server base.Permission_LookupEntitiesStreamServer) (err error) { + size := request.GetPageSize() + if size == 0 { + size = 1000 + } + + // Define a callback function that will be called for each entity that passes the permission check. + // If the check result is allowed, it sends the entity ID to the server stream. + callback := func(entityID, permission, token string) { + err := server.Send(&base.PermissionsLookupEntityStreamResponse{ + EntityId: entityID, + Permission: permission, + ContinuousToken: token, + }) + // If there is an error in sending the response, the function will return + if err != nil { + return + } + } + + // Create and start BulkChecker. It performs permission checks concurrently. + checker := NewBulkChecker(ctx, engine.checkEngine, BULK_ENTITY, callback, engine.concurrencyLimit) + + // Create and start BulkPublisher. It receives entities and passes them to BulkChecker. + publisher := NewBulkEntityPublisher(ctx, request, checker) + + // Retrieve the entity definition schema based on the tenantId and schema version + var sc *base.SchemaDefinition + sc, err = engine.readSchema(ctx, request.GetTenantId(), request.GetMetadata().GetSchemaVersion()) + if err != nil { + return err + } + + visits := &VisitsMap{} + permissionChecks := &VisitsMap{} + + entrances := make([]*base.Entrance, 0) + + for _, permission := range request.GetPermissions() { + entrances = append(entrances, &base.Entrance{ + Type: request.GetEntityType(), + Value: permission, + }) + } + + // Perform an entity filter operation based on the permission request + err = NewEntityFilter(engine.dataReader, sc).EntityFilter(ctx, &base.PermissionEntityFilterRequest{ + TenantId: request.GetTenantId(), + Metadata: &base.PermissionEntityFilterRequestMetadata{ + SnapToken: request.GetMetadata().GetSnapToken(), + SchemaVersion: request.GetMetadata().GetSchemaVersion(), + Depth: request.GetMetadata().GetDepth(), + }, + Entrances: entrances, + Subject: request.GetSubject(), + Context: request.GetContext(), + Cursor: request.GetContinuousToken(), + }, visits, publisher, permissionChecks) if err != nil { return err } @@ -197,7 +358,7 @@ func (engine *LookupEngine) LookupSubject(ctx context.Context, request *base.Per // Callback function to handle the results of permission checks. // If an entity passes the permission check, its ID is stored in the subjectIDs slice. - callback := func(subjectID, token string) { + callback := func(subjectID, permission, token string) { mu.Lock() // Lock to prevent concurrent modification of the slice. defer mu.Unlock() // Unlock after the ID is appended. subjectIDs = append(subjectIDs, subjectID) diff --git a/internal/engines/lookup_test.go b/internal/engines/lookup_test.go index 74efb2338..9d7bb166b 100644 --- a/internal/engines/lookup_test.go +++ b/internal/engines/lookup_test.go @@ -3,7 +3,6 @@ package engines import ( "context" "fmt" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -1163,121 +1162,8 @@ var _ = Describe("lookup-entity-engine", func() { }) }) - facebookGroupsSchemaEntityFilter := ` - entity user {} - - entity group { - - // Relation to represent the members of the group - relation member @user - // Relation to represent the admins of the group - relation admin @user - // Relation to represent the moderators of the group - relation moderator @user - - // Permissions for the group entity - action create = member - action join = member - action leave = member - action invite_to_group = admin - action remove_from_group = admin or moderator - action edit_settings = admin or moderator - action post_to_group = member - action comment_on_post = member - action view_group_insights = admin or moderator - } - - entity post { - - // Relation to represent the owner of the post - relation owner @user - // Relation to represent the group that the post belongs to - relation group @group - - // Permissions for the post entity - action view_post = owner or group.member - action edit_post = owner or group.admin - action delete_post = owner or group.admin - - permission group_member = group.member - } - - entity comment { - - // Relation to represent the owner of the comment - relation owner @user - - // Relation to represent the post that the comment belongs to - relation post @post - - // Permissions for the comment entity - action view_comment = owner or post.group_member - action edit_comment = owner - action delete_comment = owner - - action remove = post.delete_post - } - - entity like { - - // Relation to represent the owner of the like - relation owner @user - - // Relation to represent the post that the like belongs to - relation post @post - - // Permissions for the like entity - action like_post = owner or post.group_member - action unlike_post = owner or post.group_member - } - - entity poll { - - // Relation to represent the owner of the poll - relation owner @user - - // Relation to represent the group that the poll belongs to - relation group @group - - // Permissions for the poll entity - action create_poll = owner or group.admin - action view_poll = owner or group.member - action edit_poll = owner or group.admin - action delete_poll = owner or group.admin - } - - entity file { - - // Relation to represent the owner of the file - relation owner @user - - // Relation to represent the group that the file belongs to - relation group @group - - // Permissions for the file entity - action upload_file = owner or group.member - action view_file = owner or group.member - action delete_file = owner or group.admin - } - - entity event { - - // Relation to represent the owner of the event - relation owner @user - // Relation to represent the group that the event belongs to - relation group @group - - // Permissions for the event entity - action create_event = owner or group.admin - action view_event = owner or group.member - action edit_event = owner or group.admin - action delete_event = owner or group.admin - action RSVP_to_event = owner or group.member - } - ` - - Context("Facebook Group Sample: Entity Filter", func() { - It("Facebook Group Sample: Case 1", func() { + Context("Drive Sample: Entity Filters", func() { + It("Drive Sample: Case 1", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -1286,7 +1172,7 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) - conf, err := newSchema(facebookGroupsSchemaEntityFilter) + conf, err := newSchema(driveSchemaEntityFilter) Expect(err).ShouldNot(HaveOccurred()) schemaWriter := factories.SchemaWriterFactory(db) @@ -1295,93 +1181,34 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { relationships []string + contextual []string filters []filter }{ relationships: []string{ - "group:1#member@user:1", - "group:1#admin@user:2", - "group:1#moderator@user:3", - "post:1#owner@user:1", - "post:1#group@group:1#...", - "comment:1#owner@user:1", - "comment:1#post@post:1#...", - "like:1#owner@user:1", - "like:1#post@post:1#...", - "poll:1#owner@user:2", - "poll:1#group@group:1#...", - "file:1#owner@user:3", - "file:1#group@group:1#...", - "event:1#owner@user:2", - "event:1#group@group:1#...", + "doc:1#owner@user:2", + "doc:1#folder@user:3", + "folder:1#collaborator@user:1", + }, + contextual: []string{ + "folder:1#collaborator@user:3", + "organization:1#admin@user:1", + "doc:1#org@organization:1#...", }, filters: []filter{ { - entityType: "group", - subject: "user:1", - assertions: map[string][]string{ - "create": {"1"}, - "join": {"1"}, - "leave": {"1"}, - "post_to_group": {"1"}, - "comment_on_post": {"1"}, - }, - }, - { - entityType: "post", - subject: "user:1", - assertions: map[string][]string{ - "view_post": {"1"}, - "edit_post": {"1"}, - }, - }, - { - entityType: "comment", - subject: "user:1", - assertions: map[string][]string{ - "view_comment": {"1"}, - "edit_comment": {"1"}, - }, - }, - { - entityType: "like", - subject: "user:1", - assertions: map[string][]string{ - "like_post": {"1"}, - "unlike_post": {"1"}, - }, - }, - { - entityType: "poll", - subject: "user:2", - assertions: map[string][]string{ - "create_poll": {"1"}, - "view_poll": {"1"}, - "edit_poll": {"1"}, - }, - }, - { - entityType: "file", - subject: "user:3", - assertions: map[string][]string{ - "upload_file": {"1"}, - "view_file": {"1"}, - }, - }, - { - entityType: "event", - subject: "user:2", + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, assertions: map[string][]string{ - "create_event": {"1"}, - "view_event": {"1"}, - "edit_event": {"1"}, - "RSVP_to_event": {"1"}, + "read": {"1"}, }, }, }, @@ -1421,6 +1248,17 @@ var _ = Describe("lookup-entity-engine", func() { _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) Expect(err).ShouldNot(HaveOccurred()) + reqContext := &base.Context{ + Tuples: []*base.Tuple{}, + Attributes: []*base.Attribute{}, + } + + for _, relationship := range tests.contextual { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + reqContext.Tuples = append(reqContext.Tuples, t) + } + for _, filter := range tests.filters { ear, err := tuple.EAR(filter.subject) Expect(err).ShouldNot(HaveOccurred()) @@ -1431,26 +1269,31 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } - for permission, res := range filter.assertions { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - }) + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + Context: reqContext, + }) - Expect(err).ShouldNot(HaveOccurred()) - Expect(response.GetEntityIds()).Should(Equal(res)) + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds() != nil && response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) } } }) - It("Facebook Group Sample: Case 2", func() { + It("Drive Sample: Case 2", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -1459,7 +1302,7 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) - conf, err := newSchema(facebookGroupsSchemaEntityFilter) + conf, err := newSchema(driveSchemaEntityFilter) Expect(err).ShouldNot(HaveOccurred()) schemaWriter := factories.SchemaWriterFactory(db) @@ -1468,135 +1311,44 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { relationships []string - contextual []string filters []filter }{ relationships: []string{ - "group:1#member@user:1", - "group:1#member@user:2", - "group:1#member@user:3", - "group:1#admin@user:4", - "group:1#admin@user:5", - "group:1#moderator@user:6", - "group:1#moderator@user:7", - "post:1#owner@user:1", - "post:2#owner@user:2", - "post:3#owner@user:3", - "post:1#group@group:1#...", - "post:2#group@group:1#...", - "post:3#group@group:1#...", - "comment:1#owner@user:1", - "comment:2#owner@user:2", - "comment:3#owner@user:3", - "comment:1#post@post:1#...", - "comment:2#post@post:2#...", - "comment:3#post@post:3#...", - "like:1#owner@user:1", - "like:2#owner@user:2", - "like:3#owner@user:3", - "like:1#post@post:1#...", - "like:2#post@post:2#...", - "like:3#post@post:3#...", - "poll:1#owner@user:4", - "poll:2#owner@user:5", - "poll:3#owner@user:6", - "poll:1#group@group:1#...", - "poll:2#group@group:1#...", - "poll:3#group@group:1#...", - "file:1#owner@user:7", - "file:2#owner@user:8", - "file:3#owner@user:9", - "file:1#group@group:1#...", - "file:2#group@group:1#...", - "file:3#group@group:1#...", - "event:1#owner@user:10", - "event:2#owner@user:11", - "event:3#owner@user:12", - "event:1#group@group:1#...", - "event:2#group@group:1#...", - "event:3#group@group:1#...", - }, - contextual: []string{ - "file:1#group@group:1#...", - "file:2#group@group:1#...", - "file:3#group@group:1#...", - "event:1#owner@user:10", - "event:2#owner@user:11", - "event:3#owner@user:12", - "event:1#group@group:1#...", - "event:2#group@group:1#...", - "event:3#group@group:1#...", + "doc:2#owner@user:2", + "doc:2#parent@folder:2#...", + "folder:2#collaborator@user:3", + "folder:2#creator@user:2", + "organization:2#admin@user:2", + "doc:2#org@organization:2#...", }, filters: []filter{ { - entityType: "group", - subject: "user:1", - assertions: map[string][]string{ - "create": {"1"}, - "join": {"1"}, - "leave": {"1"}, - "post_to_group": {"1"}, - "comment_on_post": {"1"}, - }, - }, - { - entityType: "post", - subject: "user:1", + entityType: "doc", + subject: "user:2", + permissions: []string{"read", "update", "delete", "share"}, assertions: map[string][]string{ - "view_post": {"1", "2", "3"}, - "edit_post": {"1"}, + "read": {"2"}, + "update": {"2"}, + "delete": {"2"}, + "share": {"2"}, }, }, { - entityType: "comment", + entityType: "doc", subject: "user:2", + // permissions: []string{"read"}, + permissions: []string{"read", "update"}, assertions: map[string][]string{ - "view_comment": {"1", "2", "3"}, - "edit_comment": {"2"}, - }, - }, - { - entityType: "like", - subject: "user:3", - assertions: map[string][]string{ - "like_post": {"1", "2", "3"}, - "unlike_post": {"1", "2", "3"}, - }, - }, - { - entityType: "poll", - subject: "user:4", - assertions: map[string][]string{ - "create_poll": {"1", "2", "3"}, - "view_poll": {"1"}, - "edit_poll": {"1", "2", "3"}, - }, - }, - { - entityType: "file", - subject: "user:5", - assertions: map[string][]string{ - "upload_file": nil, - "view_file": nil, - "delete_file": {"1", "2", "3"}, - }, - }, - { - entityType: "event", - subject: "user:6", - assertions: map[string][]string{ - "create_event": nil, - "view_event": nil, - "edit_event": nil, - "delete_event": nil, - "RSVP_to_event": nil, + "read": {"2"}, + "update": {"2"}, }, }, }, @@ -1636,17 +1388,6 @@ var _ = Describe("lookup-entity-engine", func() { _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) Expect(err).ShouldNot(HaveOccurred()) - reqContext := &base.Context{ - Tuples: []*base.Tuple{}, - Attributes: []*base.Attribute{}, - } - - for _, relationship := range tests.contextual { - t, err := tuple.Tuple(relationship) - Expect(err).ShouldNot(HaveOccurred()) - reqContext.Tuples = append(reqContext.Tuples, t) - } - for _, filter := range tests.filters { ear, err := tuple.EAR(filter.subject) Expect(err).ShouldNot(HaveOccurred()) @@ -1657,27 +1398,29 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + Expect(err).ShouldNot(HaveOccurred()) for permission, res := range filter.assertions { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - Context: reqContext, - }) - - Expect(err).ShouldNot(HaveOccurred()) - Expect(response.GetEntityIds()).Should(Equal(res)) + var permissions []string + if response.GetEntityIds() != nil && response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) } } }) - It("Facebook Group Sample: Case 3 pagination", func() { + It("Drive Sample: Case 3", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -1686,7 +1429,7 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) - conf, err := newSchema(facebookGroupsSchemaEntityFilter) + conf, err := newSchema(driveSchemaEntityFilter) Expect(err).ShouldNot(HaveOccurred()) schemaWriter := factories.SchemaWriterFactory(db) @@ -1695,9 +1438,10 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { @@ -1705,27 +1449,29 @@ var _ = Describe("lookup-entity-engine", func() { filters []filter }{ relationships: []string{ - "group:1#member@user:1", - "group:2#member@user:1", - "group:3#member@user:1", - "group:4#member@user:1", - - "post:99#group@group:1#...", - "post:98#group@group:2#...", - "post:97#group@group:3#...", - "post:96#group@group:4#...", - "post:96#group@group:4#...", - "post:95#group@group:4#...", - "post:94#group@group:4#...", - "post:93#group@group:4#...", - "post:92#group@group:4#...", + "doc:1#owner@user:2", + "doc:1#parent@folder:1#...", + "folder:1#collaborator@user:1", + "folder:1#collaborator@user:3", + "folder:1#creator@user:2", + "organization:1#admin@user:1", + "doc:1#org@organization:1#...", }, filters: []filter{ { - entityType: "post", - subject: "user:1", + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, assertions: map[string][]string{ - "view_post": {"92", "93", "94", "95", "96", "97", "98", "99"}, + "read": {"1"}, + }, + }, + { + entityType: "folder", + subject: "user:2", + permissions: []string{"delete"}, + assertions: map[string][]string{ + "delete": {"1"}, }, }, }, @@ -1775,43 +1521,30 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } - for permission, res := range filter.assertions { - - ct := "" - - var ids []string - - for { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - PageSize: 5, - ContinuousToken: ct, - }) - Expect(err).ShouldNot(HaveOccurred()) - - ids = append(ids, response.GetEntityIds()...) - - ct = response.GetContinuousToken() + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) - if ct == "" { - break - } + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds() != nil && response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids } - - Expect(ids).Should(Equal(res)) + Expect(permissions).Should(Equal(res)) } } }) - It("Facebook Group Sample: Case 4 pagination", func() { + It("Drive Sample: Case 4", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -1820,7 +1553,7 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) - conf, err := newSchema(facebookGroupsSchemaEntityFilter) + conf, err := newSchema(driveSchemaEntityFilter) Expect(err).ShouldNot(HaveOccurred()) schemaWriter := factories.SchemaWriterFactory(db) @@ -1829,9 +1562,10 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { @@ -1839,40 +1573,29 @@ var _ = Describe("lookup-entity-engine", func() { filters []filter }{ relationships: []string{ - "group:1#admin@user:1", - "group:2#admin@user:1", - "group:3#admin@user:1", - "group:4#admin@user:1", - - "post:59#group@group:1#...", - "post:58#group@group:2#...", - "post:57#group@group:3#...", - "post:56#group@group:4#...", - "post:55#group@group:4#...", - "post:54#group@group:4#...", - "post:53#group@group:4#...", - "post:52#group@group:4#...", - - "comment:99#post@post:58#...", - "comment:98#post@post:58#...", - "comment:97#post@post:54#...", - "comment:96#post@post:4#...", - "comment:96#post@post:57#...", - "comment:95#post@post:54#...", - "comment:94#post@post:54#...", - "comment:93#post@post:54#...", - "comment:92#post@post:53#...", - "comment:91#post@post:53#...", - "comment:90#post@post:53#...", - "comment:45#post@post:53#...", - "comment:1#post@post:53#...", + "doc:1#owner@user:2", + "doc:1#parent@folder:1#...", + "folder:1#collaborator@user:1", + "folder:1#collaborator@user:3", + "folder:1#creator@user:2", + "organization:1#admin@user:1", + "doc:1#org@organization:1#...", }, filters: []filter{ { - entityType: "comment", - subject: "user:1", + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, assertions: map[string][]string{ - "remove": {"1", "45", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + "read": {"1"}, + }, + }, + { + entityType: "folder", + subject: "user:2", + permissions: []string{"delete"}, + assertions: map[string][]string{ + "delete": {"1"}, }, }, }, @@ -1922,72 +1645,26 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } - for permission, res := range filter.assertions { - - ct := "" - - var ids []string - - for { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - PageSize: 5, - ContinuousToken: ct, - }) - Expect(err).ShouldNot(HaveOccurred()) - - ids = append(ids, response.GetEntityIds()...) - - ct = response.GetContinuousToken() - - if ct == "" { - break - } - } + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) - Expect(ids).Should(Equal(res)) + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + Expect(response.GetEntityIds()[permission].Ids).Should(Equal(res)) } } }) - }) - googleDocsSchemaEntityFilter := ` - entity user {} - - entity resource { - relation viewer @user @group#member @group#manager - relation manager @user @group#member @group#manager - - action edit = manager - action view = viewer or manager - } - - entity group { - relation manager @user @group#member @group#manager - relation member @user @group#member @group#manager - } - - entity organization { - relation group @group - relation resource @resource - - relation administrator @user @group#member @group#manager - relation direct_member @user - - permission admin = administrator - permission member = direct_member or administrator or group.member - }` - - Context("Google Docs Sample: Entity Filter", func() { - It("Google Docs Sample: Case 1", func() { + It("Drive Sample: Case 5", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -1996,7 +1673,7 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) - conf, err := newSchema(googleDocsSchemaEntityFilter) + conf, err := newSchema(driveSchemaEntityFilter) Expect(err).ShouldNot(HaveOccurred()) schemaWriter := factories.SchemaWriterFactory(db) @@ -2005,9 +1682,10 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { @@ -2015,36 +1693,2225 @@ var _ = Describe("lookup-entity-engine", func() { filters []filter }{ relationships: []string{ - "resource:1#viewer@user:1", - "resource:1#viewer@group:1#member", - "resource:1#manager@user:2", - "resource:1#manager@group:1#manager", - "group:1#manager@user:3", - "group:1#manager@group:1#member", - "group:1#member@user:4", - "group:1#member@group:1#manager", - "organization:1#group@group:1#...", - "organization:1#resource@resource:1#...", - "organization:1#administrator@user:5", - "organization:1#administrator@group:1#manager", - "organization:1#direct_member@user:6", + "doc:1#owner@user:2", + "doc:2#owner@user:3", + "doc:1#parent@folder:1#...", + "doc:2#parent@folder:1#...", + "folder:1#collaborator@user:1", + "folder:1#collaborator@user:3", + "folder:1#creator@user:2", + "organization:1#admin@user:1", + "doc:1#org@organization:1#...", + "doc:2#org@organization:1#...", }, filters: []filter{ { - entityType: "resource", - subject: "user:1", + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, assertions: map[string][]string{ - "view": {"1"}, + "read": {"1", "2"}, }, }, { - entityType: "resource", - subject: "group:1#member", + entityType: "folder", + subject: "user:2", + permissions: []string{"delete"}, assertions: map[string][]string{ - "view": {"1"}, + "delete": {"1"}, }, }, - { + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + Expect(response.GetEntityIds()[permission].Ids).Should(Equal(res)) + } + } + }) + + It("Drive Sample: Case 6", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(driveSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + assertions map[string][]string + } + + tests := struct { + relationships []string + contextual []string + filters []filter + }{ + relationships: []string{ + "doc:1#owner@user:2", + "doc:2#owner@user:3", + "doc:3#owner@user:3", + "doc:4#owner@user:2", + "doc:5#owner@user:3", + "doc:6#owner@user:2", + "doc:1#parent@folder:1#...", + "doc:2#parent@folder:1#...", + "doc:3#parent@folder:1#...", + }, + contextual: []string{ + "doc:4#parent@folder:1#...", + "doc:5#parent@folder:1#...", + "doc:6#parent@folder:1#...", + "folder:1#collaborator@user:1", + "folder:1#collaborator@user:3", + "folder:1#creator@user:2", + "organization:1#admin@user:1", + }, + filters: []filter{ + { + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, + assertions: map[string][]string{ + "read": {"1", "2", "3", "4", "5", "6"}, + }, + }, + { + entityType: "folder", + subject: "user:2", + permissions: []string{"delete"}, + assertions: map[string][]string{ + "delete": {"1"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + reqContext := &base.Context{ + Tuples: []*base.Tuple{}, + Attributes: []*base.Attribute{}, + } + + for _, relationship := range tests.contextual { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + reqContext.Tuples = append(reqContext.Tuples, t) + } + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + Context: reqContext, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + Expect(response.GetEntityIds()[permission].Ids).Should(Equal(res)) + } + } + }) + + It("Drive Sample: Case 7", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(driveSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "doc:1#owner@user:2", + "doc:2#owner@user:3", + "doc:3#owner@user:3", + "doc:4#owner@user:2", + "doc:5#owner@user:3", + "doc:6#owner@user:2", + "doc:7#owner@user:4", + "doc:8#owner@user:4", + "doc:9#owner@user:5", + "doc:10#owner@user:5", + "doc:1#parent@folder:1#...", + "doc:2#parent@folder:1#...", + "doc:3#parent@folder:2#...", + "doc:4#parent@folder:2#...", + "doc:5#parent@folder:3#...", + "doc:6#parent@folder:3#...", + "doc:7#parent@folder:4#...", + "doc:8#parent@folder:4#...", + "doc:9#parent@folder:5#...", + "doc:10#parent@folder:5#...", + "folder:1#collaborator@user:1", + "folder:2#collaborator@user:1", + "folder:3#collaborator@user:2", + "folder:4#collaborator@user:2", + "folder:5#collaborator@user:3", + "folder:1#creator@user:2", + "folder:2#creator@user:3", + "folder:3#creator@user:4", + "folder:4#creator@user:4", + "folder:5#creator@user:5", + "organization:1#admin@user:1", + "organization:2#admin@user:2", + "organization:3#admin@user:3", + "doc:1#org@organization:1#...", + "doc:2#org@organization:1#...", + "doc:3#org@organization:2#...", + "doc:4#org@organization:2#...", + "doc:5#org@organization:3#...", + "doc:6#org@organization:3#...", + "doc:7#org@organization:1#...", + "doc:8#org@organization:2#...", + "doc:9#org@organization:3#...", + "doc:10#org@organization:1#...", + }, + filters: []filter{ + { + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, + assertions: map[string][]string{ + "read": {"1", "10", "2", "3", "4", "7"}, + }, + }, + { + entityType: "doc", + subject: "user:2", + permissions: []string{"read", "delete"}, + assertions: map[string][]string{ + "read": {"1", "3", "4", "5", "6", "7", "8"}, + "delete": {"1", "3", "4", "6", "8"}, + }, + }, + { + entityType: "doc", + subject: "user:3", + permissions: []string{"read", "update"}, + assertions: map[string][]string{ + "read": {"10", "2", "3", "5", "6", "9"}, + "update": {"5"}, + }, + }, + { + entityType: "doc", + subject: "user:4", + permissions: []string{"read", "delete", "share"}, + assertions: map[string][]string{ + "read": {"7", "8"}, + "delete": {"7", "8"}, + "share": nil, + }, + }, + { + entityType: "doc", + subject: "user:5", + permissions: []string{"read", "delete"}, + assertions: map[string][]string{ + "read": {"10", "9"}, + "delete": {"10", "9"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) + } + } + }) + + It("Drive Sample: Case 8 scope", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(driveSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + scope map[string]*base.StringArrayValue + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "doc:1#owner@user:2", + "doc:2#owner@user:3", + "doc:3#owner@user:3", + "doc:4#owner@user:2", + "doc:5#owner@user:3", + "doc:6#owner@user:2", + "doc:7#owner@user:4", + "doc:8#owner@user:4", + "doc:9#owner@user:5", + "doc:10#owner@user:5", + "doc:1#parent@folder:1#...", + "doc:2#parent@folder:1#...", + "doc:3#parent@folder:2#...", + "doc:4#parent@folder:2#...", + "doc:5#parent@folder:3#...", + "doc:6#parent@folder:3#...", + "doc:7#parent@folder:4#...", + "doc:8#parent@folder:4#...", + "doc:9#parent@folder:5#...", + "doc:10#parent@folder:5#...", + "folder:1#collaborator@user:1", + "folder:2#collaborator@user:1", + "folder:3#collaborator@user:2", + "folder:4#collaborator@user:2", + "folder:5#collaborator@user:3", + "folder:1#creator@user:2", + "folder:2#creator@user:3", + "folder:3#creator@user:4", + "folder:4#creator@user:4", + "folder:5#creator@user:5", + "organization:1#admin@user:1", + "organization:2#admin@user:2", + "organization:3#admin@user:3", + "doc:1#org@organization:1#...", + "doc:2#org@organization:1#...", + "doc:3#org@organization:2#...", + "doc:4#org@organization:2#...", + "doc:5#org@organization:3#...", + "doc:6#org@organization:3#...", + "doc:7#org@organization:1#...", + "doc:8#org@organization:2#...", + "doc:9#org@organization:3#...", + "doc:10#org@organization:1#...", + }, + filters: []filter{ + { + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, + scope: map[string]*base.StringArrayValue{ + "organization": { + Data: []string{"2"}, + }, + }, + assertions: map[string][]string{ + "read": {"1", "2", "3", "4"}, + }, + }, + { + entityType: "doc", + subject: "user:1", + permissions: []string{"read"}, + scope: map[string]*base.StringArrayValue{ + "organization": { + Data: []string{"2"}, + }, + "folder": { + Data: []string{"2"}, + }, + }, + assertions: map[string][]string{ + "read": {"3", "4"}, + }, + }, + { + entityType: "doc", + subject: "user:2", + permissions: []string{"read", "delete"}, + scope: map[string]*base.StringArrayValue{ + "organization": { + Data: []string{"1"}, + }, + }, + assertions: map[string][]string{ + "read": {"1", "4", "5", "6", "7", "8"}, + "delete": {"1", "4", "6"}, + }, + }, + { + entityType: "doc", + subject: "user:3", + permissions: []string{"read", "update"}, + scope: map[string]*base.StringArrayValue{ + "organization": { + Data: []string{"1", "2", "3"}, + }, + }, + assertions: map[string][]string{ + "read": {"10", "2", "3", "5", "6", "9"}, + "update": {"5"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Scope: filter.scope, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + Expect(response.GetEntityIds()[permission].Ids).Should(Equal(res)) + } + } + }) + }) + + facebookGroupsSchemaEntityFilter := ` + entity user {} + + entity group { + + // Relation to represent the members of the group + relation member @user + // Relation to represent the admins of the group + relation admin @user + // Relation to represent the moderators of the group + relation moderator @user + + // Permissions for the group entity + action create = member + action join = member + action leave = member + action invite_to_group = admin + action remove_from_group = admin or moderator + action edit_settings = admin or moderator + action post_to_group = member + action comment_on_post = member + action view_group_insights = admin or moderator + } + + entity post { + + // Relation to represent the owner of the post + relation owner @user + // Relation to represent the group that the post belongs to + relation group @group + + // Permissions for the post entity + action view_post = owner or group.member + action edit_post = owner or group.admin + action delete_post = owner or group.admin + + permission group_member = group.member + } + + entity comment { + + // Relation to represent the owner of the comment + relation owner @user + + // Relation to represent the post that the comment belongs to + relation post @post + + // Permissions for the comment entity + action view_comment = owner or post.group_member + action edit_comment = owner + action delete_comment = owner + + action remove = post.delete_post + } + + entity like { + + // Relation to represent the owner of the like + relation owner @user + + // Relation to represent the post that the like belongs to + relation post @post + + // Permissions for the like entity + action like_post = owner or post.group_member + action unlike_post = owner or post.group_member + } + + entity poll { + + // Relation to represent the owner of the poll + relation owner @user + + // Relation to represent the group that the poll belongs to + relation group @group + + // Permissions for the poll entity + action create_poll = owner or group.admin + action view_poll = owner or group.member + action edit_poll = owner or group.admin + action delete_poll = owner or group.admin + } + + entity file { + + // Relation to represent the owner of the file + relation owner @user + + // Relation to represent the group that the file belongs to + relation group @group + + // Permissions for the file entity + action upload_file = owner or group.member + action view_file = owner or group.member + action delete_file = owner or group.admin + } + + entity event { + + // Relation to represent the owner of the event + relation owner @user + // Relation to represent the group that the event belongs to + relation group @group + + // Permissions for the event entity + action create_event = owner or group.admin + action view_event = owner or group.member + action edit_event = owner or group.admin + action delete_event = owner or group.admin + action RSVP_to_event = owner or group.member + } + ` + + Context("Facebook Group Sample: Entity Filter", func() { + It("Facebook Group Sample: Case 1", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "group:1#member@user:1", + "group:1#admin@user:2", + "group:1#moderator@user:3", + "post:1#owner@user:1", + "post:1#group@group:1#...", + "comment:1#owner@user:1", + "comment:1#post@post:1#...", + "like:1#owner@user:1", + "like:1#post@post:1#...", + "poll:1#owner@user:2", + "poll:1#group@group:1#...", + "file:1#owner@user:3", + "file:1#group@group:1#...", + "event:1#owner@user:2", + "event:1#group@group:1#...", + }, + filters: []filter{ + { + entityType: "group", + subject: "user:1", + assertions: map[string][]string{ + "create": {"1"}, + "join": {"1"}, + "leave": {"1"}, + "post_to_group": {"1"}, + "comment_on_post": {"1"}, + }, + }, + { + entityType: "post", + subject: "user:1", + assertions: map[string][]string{ + "view_post": {"1"}, + "edit_post": {"1"}, + }, + }, + { + entityType: "comment", + subject: "user:1", + assertions: map[string][]string{ + "view_comment": {"1"}, + "edit_comment": {"1"}, + }, + }, + { + entityType: "like", + subject: "user:1", + assertions: map[string][]string{ + "like_post": {"1"}, + "unlike_post": {"1"}, + }, + }, + { + entityType: "poll", + subject: "user:2", + assertions: map[string][]string{ + "create_poll": {"1"}, + "view_poll": {"1"}, + "edit_poll": {"1"}, + }, + }, + { + entityType: "file", + subject: "user:3", + assertions: map[string][]string{ + "upload_file": {"1"}, + "view_file": {"1"}, + }, + }, + { + entityType: "event", + subject: "user:2", + assertions: map[string][]string{ + "create_event": {"1"}, + "view_event": {"1"}, + "edit_event": {"1"}, + "RSVP_to_event": {"1"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + Expect(response.GetEntityIds()).Should(Equal(res)) + } + } + }) + + It("Facebook Group Sample: Case 2", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + contextual []string + filters []filter + }{ + relationships: []string{ + "group:1#member@user:1", + "group:1#member@user:2", + "group:1#member@user:3", + "group:1#admin@user:4", + "group:1#admin@user:5", + "group:1#moderator@user:6", + "group:1#moderator@user:7", + "post:1#owner@user:1", + "post:2#owner@user:2", + "post:3#owner@user:3", + "post:1#group@group:1#...", + "post:2#group@group:1#...", + "post:3#group@group:1#...", + "comment:1#owner@user:1", + "comment:2#owner@user:2", + "comment:3#owner@user:3", + "comment:1#post@post:1#...", + "comment:2#post@post:2#...", + "comment:3#post@post:3#...", + "like:1#owner@user:1", + "like:2#owner@user:2", + "like:3#owner@user:3", + "like:1#post@post:1#...", + "like:2#post@post:2#...", + "like:3#post@post:3#...", + "poll:1#owner@user:4", + "poll:2#owner@user:5", + "poll:3#owner@user:6", + "poll:1#group@group:1#...", + "poll:2#group@group:1#...", + "poll:3#group@group:1#...", + "file:1#owner@user:7", + "file:2#owner@user:8", + "file:3#owner@user:9", + "file:1#group@group:1#...", + "file:2#group@group:1#...", + "file:3#group@group:1#...", + "event:1#owner@user:10", + "event:2#owner@user:11", + "event:3#owner@user:12", + "event:1#group@group:1#...", + "event:2#group@group:1#...", + "event:3#group@group:1#...", + }, + contextual: []string{ + "file:1#group@group:1#...", + "file:2#group@group:1#...", + "file:3#group@group:1#...", + "event:1#owner@user:10", + "event:2#owner@user:11", + "event:3#owner@user:12", + "event:1#group@group:1#...", + "event:2#group@group:1#...", + "event:3#group@group:1#...", + }, + filters: []filter{ + { + entityType: "group", + subject: "user:1", + assertions: map[string][]string{ + "create": {"1"}, + "join": {"1"}, + "leave": {"1"}, + "post_to_group": {"1"}, + "comment_on_post": {"1"}, + }, + }, + { + entityType: "post", + subject: "user:1", + assertions: map[string][]string{ + "view_post": {"1", "2", "3"}, + "edit_post": {"1"}, + }, + }, + { + entityType: "comment", + subject: "user:2", + assertions: map[string][]string{ + "view_comment": {"1", "2", "3"}, + "edit_comment": {"2"}, + }, + }, + { + entityType: "like", + subject: "user:3", + assertions: map[string][]string{ + "like_post": {"1", "2", "3"}, + "unlike_post": {"1", "2", "3"}, + }, + }, + { + entityType: "poll", + subject: "user:4", + assertions: map[string][]string{ + "create_poll": {"1", "2", "3"}, + "view_poll": {"1"}, + "edit_poll": {"1", "2", "3"}, + }, + }, + { + entityType: "file", + subject: "user:5", + assertions: map[string][]string{ + "upload_file": nil, + "view_file": nil, + "delete_file": {"1", "2", "3"}, + }, + }, + { + entityType: "event", + subject: "user:6", + assertions: map[string][]string{ + "create_event": nil, + "view_event": nil, + "edit_event": nil, + "delete_event": nil, + "RSVP_to_event": nil, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + reqContext := &base.Context{ + Tuples: []*base.Tuple{}, + Attributes: []*base.Attribute{}, + } + + for _, relationship := range tests.contextual { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + reqContext.Tuples = append(reqContext.Tuples, t) + } + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + Context: reqContext, + }) + + Expect(err).ShouldNot(HaveOccurred()) + Expect(response.GetEntityIds()).Should(Equal(res)) + } + } + }) + + It("Facebook Group Sample: Case 3 pagination", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "group:1#member@user:1", + "group:2#member@user:1", + "group:3#member@user:1", + "group:4#member@user:1", + + "post:99#group@group:1#...", + "post:98#group@group:2#...", + "post:97#group@group:3#...", + "post:96#group@group:4#...", + "post:96#group@group:4#...", + "post:95#group@group:4#...", + "post:94#group@group:4#...", + "post:93#group@group:4#...", + "post:92#group@group:4#...", + }, + filters: []filter{ + { + entityType: "post", + subject: "user:1", + assertions: map[string][]string{ + "view_post": {"92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + + ct := "" + + var ids []string + + for { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + PageSize: 5, + ContinuousToken: ct, + }) + Expect(err).ShouldNot(HaveOccurred()) + + ids = append(ids, response.GetEntityIds()...) + + ct = response.GetContinuousToken() + + if ct == "" { + break + } + } + + Expect(ids).Should(Equal(res)) + } + } + }) + + It("Facebook Group Sample: Case 4 pagination", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "group:1#admin@user:1", + "group:2#admin@user:1", + "group:3#admin@user:1", + "group:4#admin@user:1", + + "post:59#group@group:1#...", + "post:58#group@group:2#...", + "post:57#group@group:3#...", + "post:56#group@group:4#...", + "post:55#group@group:4#...", + "post:54#group@group:4#...", + "post:53#group@group:4#...", + "post:52#group@group:4#...", + + "comment:99#post@post:58#...", + "comment:98#post@post:58#...", + "comment:97#post@post:54#...", + "comment:96#post@post:4#...", + "comment:96#post@post:57#...", + "comment:95#post@post:54#...", + "comment:94#post@post:54#...", + "comment:93#post@post:54#...", + "comment:92#post@post:53#...", + "comment:91#post@post:53#...", + "comment:90#post@post:53#...", + "comment:45#post@post:53#...", + "comment:1#post@post:53#...", + }, + filters: []filter{ + { + entityType: "comment", + subject: "user:1", + assertions: map[string][]string{ + "remove": {"1", "45", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + + ct := "" + + var ids []string + + for { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + PageSize: 5, + ContinuousToken: ct, + }) + Expect(err).ShouldNot(HaveOccurred()) + + ids = append(ids, response.GetEntityIds()...) + + ct = response.GetContinuousToken() + + if ct == "" { + break + } + } + + Expect(ids).Should(Equal(res)) + } + } + }) + }) + + Context("Facebook Group Sample: Entities Filter", func() { + It("Facebook Group Sample: Case 1", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + permissions []string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "group:1#member@user:1", + "group:1#admin@user:2", + "group:1#moderator@user:3", + "post:1#owner@user:1", + "post:1#group@group:1#...", + "comment:1#owner@user:1", + "comment:1#post@post:1#...", + "like:1#owner@user:1", + "like:1#post@post:1#...", + "poll:1#owner@user:2", + "poll:1#group@group:1#...", + "file:1#owner@user:3", + "file:1#group@group:1#...", + "event:1#owner@user:2", + "event:1#group@group:1#...", + }, + filters: []filter{ + { + entityType: "group", + subject: "user:1", + permissions: []string{"create", "join", "leave", "post_to_group", "comment_on_post"}, + assertions: map[string][]string{ + "create": {"1"}, + "join": {"1"}, + "leave": {"1"}, + "post_to_group": {"1"}, + "comment_on_post": {"1"}, + }, + }, + { + entityType: "post", + subject: "user:1", + permissions: []string{"view_post", "edit_post"}, + assertions: map[string][]string{ + "view_post": {"1"}, + "edit_post": {"1"}, + }, + }, + { + entityType: "comment", + subject: "user:1", + permissions: []string{"view_comment", "edit_comment"}, + assertions: map[string][]string{ + "view_comment": {"1"}, + "edit_comment": {"1"}, + }, + }, + { + entityType: "like", + subject: "user:1", + permissions: []string{"like_post", "unlike_post"}, + assertions: map[string][]string{ + "like_post": {"1"}, + "unlike_post": {"1"}, + }, + }, + { + entityType: "poll", + subject: "user:2", + permissions: []string{"create_poll", "view_poll", "edit_poll"}, + assertions: map[string][]string{ + "create_poll": {"1"}, + "view_poll": {"1"}, + "edit_poll": {"1"}, + }, + }, + { + entityType: "file", + subject: "user:3", + permissions: []string{"upload_file", "view_file"}, + assertions: map[string][]string{ + "upload_file": {"1"}, + "view_file": {"1"}, + }, + }, + { + entityType: "event", + subject: "user:2", + permissions: []string{"create_event", "view_event", "edit_event", "RSVP_to_event"}, + assertions: map[string][]string{ + "create_event": {"1"}, + "view_event": {"1"}, + "edit_event": {"1"}, + "RSVP_to_event": {"1"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) + } + } + }) + + It("Facebook Group Sample: Case 2", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + assertions map[string][]string + } + + tests := struct { + relationships []string + contextual []string + filters []filter + }{ + relationships: []string{ + "group:1#member@user:1", + "group:1#member@user:2", + "group:1#member@user:3", + "group:1#admin@user:4", + "group:1#admin@user:5", + "group:1#moderator@user:6", + "group:1#moderator@user:7", + "post:1#owner@user:1", + "post:2#owner@user:2", + "post:3#owner@user:3", + "post:1#group@group:1#...", + "post:2#group@group:1#...", + "post:3#group@group:1#...", + "comment:1#owner@user:1", + "comment:2#owner@user:2", + "comment:3#owner@user:3", + "comment:1#post@post:1#...", + "comment:2#post@post:2#...", + "comment:3#post@post:3#...", + "like:1#owner@user:1", + "like:2#owner@user:2", + "like:3#owner@user:3", + "like:1#post@post:1#...", + "like:2#post@post:2#...", + "like:3#post@post:3#...", + "poll:1#owner@user:4", + "poll:2#owner@user:5", + "poll:3#owner@user:6", + "poll:1#group@group:1#...", + "poll:2#group@group:1#...", + "poll:3#group@group:1#...", + "file:1#owner@user:7", + "file:2#owner@user:8", + "file:3#owner@user:9", + "file:1#group@group:1#...", + "file:2#group@group:1#...", + "file:3#group@group:1#...", + "event:1#owner@user:10", + "event:2#owner@user:11", + "event:3#owner@user:12", + "event:1#group@group:1#...", + "event:2#group@group:1#...", + "event:3#group@group:1#...", + }, + contextual: []string{ + "file:1#group@group:1#...", + "file:2#group@group:1#...", + "file:3#group@group:1#...", + "event:1#owner@user:10", + "event:2#owner@user:11", + "event:3#owner@user:12", + "event:1#group@group:1#...", + "event:2#group@group:1#...", + "event:3#group@group:1#...", + }, + filters: []filter{ + { + entityType: "group", + subject: "user:1", + permissions: []string{"create", "join", "leave", "post_to_group", "comment_on_post"}, + assertions: map[string][]string{ + "create": {"1"}, + "join": {"1"}, + "leave": {"1"}, + "post_to_group": {"1"}, + "comment_on_post": {"1"}, + }, + }, + { + entityType: "post", + subject: "user:1", + permissions: []string{"view_post", "edit_post"}, + assertions: map[string][]string{ + "view_post": {"1", "2", "3"}, + "edit_post": {"1"}, + }, + }, + { + entityType: "comment", + subject: "user:2", + permissions: []string{"view_comment", "edit_comment"}, + assertions: map[string][]string{ + "view_comment": {"1", "2", "3"}, + "edit_comment": {"2"}, + }, + }, + { + entityType: "like", + subject: "user:3", + permissions: []string{"like_post", "unlike_post"}, + assertions: map[string][]string{ + "like_post": {"1", "2", "3"}, + "unlike_post": {"1", "2", "3"}, + }, + }, + { + entityType: "poll", + subject: "user:4", + permissions: []string{"create_poll", "view_poll", "edit_poll"}, + assertions: map[string][]string{ + "create_poll": {"1", "2", "3"}, + "view_poll": {"1"}, + "edit_poll": {"1", "2", "3"}, + }, + }, + { + entityType: "file", + subject: "user:5", + permissions: []string{"upload_file", "view_file", "delete_file"}, + assertions: map[string][]string{ + "upload_file": nil, + "view_file": nil, + "delete_file": {"1", "2", "3"}, + }, + }, + { + entityType: "event", + subject: "user:6", + permissions: []string{"create_event", "view_event", "edit_event", "delete_event", "RSVP_to_event"}, + assertions: map[string][]string{ + "create_event": nil, + "view_event": nil, + "edit_event": nil, + "delete_event": nil, + "RSVP_to_event": nil, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + reqContext := &base.Context{ + Tuples: []*base.Tuple{}, + Attributes: []*base.Attribute{}, + } + + for _, relationship := range tests.contextual { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + reqContext.Tuples = append(reqContext.Tuples, t) + } + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) + } + } + }) + + It("Facebook Group Sample: Case 3 pagination", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + permissions []string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "group:1#member@user:1", + "group:2#member@user:1", + "group:3#member@user:1", + "group:4#member@user:1", + + "post:99#group@group:1#...", + "post:98#group@group:2#...", + "post:97#group@group:3#...", + "post:96#group@group:4#...", + "post:96#group@group:4#...", + "post:95#group@group:4#...", + "post:94#group@group:4#...", + "post:93#group@group:4#...", + "post:92#group@group:4#...", + }, + filters: []filter{ + { + entityType: "post", + subject: "user:1", + permissions: []string{"view_post"}, + assertions: map[string][]string{ + "view_post": {"92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + + ct := "" + + var ids []string + + for { + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: []string{permission}, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + PageSize: 5, + ContinuousToken: ct, + }) + Expect(err).ShouldNot(HaveOccurred()) + + ids = append(ids, response.GetEntityIds()[permission].Ids...) + + ct = response.GetContinuousToken() + + if ct == "" { + break + } + } + + Expect(ids).Should(Equal(res)) + } + } + }) + + It("Facebook Group Sample: Case 4 pagination", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(facebookGroupsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + permissions []string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "group:1#admin@user:1", + "group:2#admin@user:1", + "group:3#admin@user:1", + "group:4#admin@user:1", + + "post:59#group@group:1#...", + "post:58#group@group:2#...", + "post:57#group@group:3#...", + "post:56#group@group:4#...", + "post:55#group@group:4#...", + "post:54#group@group:4#...", + "post:53#group@group:4#...", + "post:52#group@group:4#...", + + "comment:99#post@post:58#...", + "comment:98#post@post:58#...", + "comment:97#post@post:54#...", + "comment:96#post@post:4#...", + "comment:96#post@post:57#...", + "comment:95#post@post:54#...", + "comment:94#post@post:54#...", + "comment:93#post@post:54#...", + "comment:92#post@post:53#...", + "comment:91#post@post:53#...", + "comment:90#post@post:53#...", + "comment:45#post@post:53#...", + "comment:1#post@post:53#...", + }, + filters: []filter{ + { + entityType: "comment", + subject: "user:1", + permissions: []string{"remove"}, + assertions: map[string][]string{ + "remove": {"1", "45", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + + ct := "" + + var ids []string + + for { + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: []string{permission}, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + PageSize: 5, + ContinuousToken: ct, + }) + Expect(err).ShouldNot(HaveOccurred()) + + ids = append(ids, response.GetEntityIds()[permission].Ids...) + + ct = response.GetContinuousToken() + + if ct == "" { + break + } + } + + Expect(ids).Should(Equal(res)) + } + } + }) + }) + + googleDocsSchemaEntityFilter := ` + entity user {} + + entity resource { + relation viewer @user @group#member @group#manager + relation manager @user @group#member @group#manager + + action edit = manager + action view = viewer or manager + } + + entity group { + relation manager @user @group#member @group#manager + relation member @user @group#member @group#manager + } + + entity organization { + relation group @group + relation resource @resource + + relation administrator @user @group#member @group#manager + relation direct_member @user + + permission admin = administrator + permission member = direct_member or administrator or group.member + }` + + Context("Google Docs Sample: Entity Filter", func() { + It("Google Docs Sample: Case 1", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(googleDocsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "resource:1#viewer@user:1", + "resource:1#viewer@group:1#member", + "resource:1#manager@user:2", + "resource:1#manager@group:1#manager", + "group:1#manager@user:3", + "group:1#manager@group:1#member", + "group:1#member@user:4", + "group:1#member@group:1#manager", + "organization:1#group@group:1#...", + "organization:1#resource@resource:1#...", + "organization:1#administrator@user:5", + "organization:1#administrator@group:1#manager", + "organization:1#direct_member@user:6", + }, + filters: []filter{ + { + entityType: "resource", + subject: "user:1", + assertions: map[string][]string{ + "view": {"1"}, + }, + }, + { + entityType: "resource", + subject: "group:1#member", + assertions: map[string][]string{ + "view": {"1"}, + }, + }, + { entityType: "resource", subject: "user:2", assertions: map[string][]string{ @@ -2053,24 +3920,611 @@ var _ = Describe("lookup-entity-engine", func() { }, }, { - entityType: "organization", - subject: "user:5", + entityType: "organization", + subject: "user:5", + assertions: map[string][]string{ + "admin": {"1"}, + "member": {"1"}, + }, + }, + { + entityType: "organization", + subject: "group:1#manager", + assertions: map[string][]string{ + "admin": {"1"}, + "member": {"1"}, + }, + }, + { + entityType: "organization", + subject: "user:6", + assertions: map[string][]string{ + "member": {"1"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + Expect(response.GetEntityIds()).Should(Equal(res)) + } + } + }) + + It("Google Docs Sample: Case 2", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(googleDocsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "resource:1#viewer@user:1", + "resource:1#viewer@group:1#member", + "resource:1#viewer@group:2#manager", + "resource:1#manager@user:2", + "resource:1#manager@group:1#manager", + "resource:1#manager@group:2#member", + "resource:2#viewer@user:3", + "resource:2#viewer@group:2#manager", + "resource:2#manager@user:4", + "resource:2#manager@group:1#manager", + "group:1#manager@user:5", + "group:1#manager@group:2#member", + "group:1#member@user:6", + "group:1#member@group:2#manager", + "group:2#manager@user:7", + "group:2#manager@group:1#member", + "group:2#member@user:8", + "group:2#member@group:1#manager", + "organization:1#group@group:1#...", + "organization:1#group@group:2#...", + "organization:1#resource@resource:1#...", + "organization:1#resource@resource:2#...", + "organization:1#administrator@user:9", + "organization:1#administrator@group:1#manager", + "organization:1#administrator@group:2#member", + "organization:1#direct_member@user:10", + }, + filters: []filter{ + { + entityType: "resource", + subject: "user:1", + assertions: map[string][]string{ + "view": {"1"}, + }, + }, + { + entityType: "resource", + subject: "group:2#manager", + assertions: map[string][]string{ + "view": {"1", "2"}, + }, + }, + { + entityType: "resource", + subject: "user:4", + assertions: map[string][]string{ + "edit": {"2"}, + "view": {"2"}, + }, + }, + { + entityType: "group", + subject: "user:5", + assertions: map[string][]string{ + "member": {"2"}, + }, + }, + { + entityType: "group", + subject: "group:1#manager", + assertions: map[string][]string{ + "member": {"2"}, + }, + }, + { + entityType: "organization", + subject: "user:9", + assertions: map[string][]string{ + "admin": {"1"}, + "member": {"1"}, + }, + }, + { + entityType: "organization", + subject: "group:2#member", + assertions: map[string][]string{ + "admin": {"1"}, + "member": {"1"}, + }, + }, + { + entityType: "organization", + subject: "user:10", + assertions: map[string][]string{ + "member": {"1"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + Expect(response.GetEntityIds()).Should(Equal(res)) + } + } + }) + + It("Google Docs Sample: Case 3", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(googleDocsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{} + + for i := 1; i <= 50; i++ { + relationship := fmt.Sprintf("resource:%d#viewer@user:1", i) + tests.relationships = append(tests.relationships, relationship) + } + + // Generate 50 manager relationships. + for i := 51; i <= 100; i++ { + relationship := fmt.Sprintf("resource:%d#manager@user:1", i) + tests.relationships = append(tests.relationships, relationship) + } + + tests.filters = []filter{ + { + entityType: "resource", + subject: "user:1", + assertions: map[string][]string{ + "view": {"1", "10", "100", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "3", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "4", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "5", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "6", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "7", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "8", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "9", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + "edit": {"100", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + Expect(response.GetEntityIds()).Should(Equal(res)) + } + } + }) + + It("Google Docs Sample: Case 4 pagination", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(googleDocsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{} + + for i := 1; i <= 50; i++ { + relationship := fmt.Sprintf("resource:%d#viewer@user:1", i) + tests.relationships = append(tests.relationships, relationship) + } + + // Generate 50 manager relationships. + for i := 51; i <= 100; i++ { + relationship := fmt.Sprintf("resource:%d#manager@user:1", i) + tests.relationships = append(tests.relationships, relationship) + } + + tests.filters = []filter{ + { + entityType: "resource", + subject: "user:1", + assertions: map[string][]string{ + "view": {"1", "10", "100", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "3", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "4", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "5", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "6", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "7", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "8", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "9", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + "edit": {"100", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + + ct := "" + + var ids []string + + for { + response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permission: permission, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + PageSize: 10, + ContinuousToken: ct, + }) + Expect(err).ShouldNot(HaveOccurred()) + + ids = append(ids, response.GetEntityIds()...) + + ct = response.GetContinuousToken() + + if ct == "" { + break + } + } + + Expect(ids).Should(Equal(res)) + } + } + }) + }) + + Context("Google Docs Sample: Entities Filter", func() { + It("Google Docs Sample: Case 1", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(googleDocsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{ + relationships: []string{ + "resource:1#viewer@user:1", + "resource:1#viewer@group:1#member", + "resource:1#manager@user:2", + "resource:1#manager@group:1#manager", + "group:1#manager@user:3", + "group:1#manager@group:1#member", + "group:1#member@user:4", + "group:1#member@group:1#manager", + "organization:1#group@group:1#...", + "organization:1#resource@resource:1#...", + "organization:1#administrator@user:5", + "organization:1#administrator@group:1#manager", + "organization:1#direct_member@user:6", + }, + filters: []filter{ + { + entityType: "resource", + subject: "user:1", + permissions: []string{"view"}, + assertions: map[string][]string{ + "view": {"1"}, + }, + }, + { + entityType: "resource", + subject: "group:1#member", + permissions: []string{"view"}, + assertions: map[string][]string{ + "view": {"1"}, + }, + }, + { + entityType: "resource", + subject: "user:2", + permissions: []string{"edit", "view"}, + assertions: map[string][]string{ + "edit": {"1"}, + "view": {"1"}, + }, + }, + { + entityType: "organization", + subject: "user:5", + permissions: []string{"admin", "member"}, assertions: map[string][]string{ "admin": {"1"}, "member": {"1"}, }, }, { - entityType: "organization", - subject: "group:1#manager", + entityType: "organization", + subject: "group:1#manager", + permissions: []string{"admin", "member"}, assertions: map[string][]string{ "admin": {"1"}, "member": {"1"}, }, }, { - entityType: "organization", - subject: "user:6", + entityType: "organization", + subject: "user:6", + permissions: []string{"member"}, assertions: map[string][]string{ "member": {"1"}, }, @@ -2122,21 +4576,25 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } - for permission, res := range filter.assertions { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - }) + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) - Expect(err).ShouldNot(HaveOccurred()) - Expect(response.GetEntityIds()).Should(Equal(res)) + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds() != nil && response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) } } }) @@ -2159,9 +4617,10 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { @@ -2198,60 +4657,68 @@ var _ = Describe("lookup-entity-engine", func() { }, filters: []filter{ { - entityType: "resource", - subject: "user:1", + entityType: "resource", + subject: "user:1", + permissions: []string{"view"}, assertions: map[string][]string{ "view": {"1"}, }, }, { - entityType: "resource", - subject: "group:2#manager", + entityType: "resource", + subject: "group:2#manager", + permissions: []string{"view"}, assertions: map[string][]string{ "view": {"1", "2"}, }, }, { - entityType: "resource", - subject: "user:4", + entityType: "resource", + subject: "user:4", + permissions: []string{"edit", "view"}, assertions: map[string][]string{ "edit": {"2"}, "view": {"2"}, }, }, { - entityType: "group", - subject: "user:5", + entityType: "group", + subject: "user:5", + permissions: []string{"member"}, assertions: map[string][]string{ "member": {"2"}, }, }, { - entityType: "group", - subject: "group:1#manager", + entityType: "group", + subject: "group:1#manager", + permissions: []string{"member"}, assertions: map[string][]string{ "member": {"2"}, }, }, { - entityType: "organization", - subject: "user:9", + entityType: "organization", + subject: "user:9", + permissions: []string{"admin", "member"}, assertions: map[string][]string{ "admin": {"1"}, "member": {"1"}, }, }, { - entityType: "organization", - subject: "group:2#member", + entityType: "organization", + subject: "group:2#member", + permissions: []string{"admin", "member"}, assertions: map[string][]string{ "admin": {"1"}, "member": {"1"}, }, }, { - entityType: "organization", - subject: "user:10", + entityType: "organization", + subject: "user:10", + permissions: []string{"member"}, assertions: map[string][]string{ "member": {"1"}, }, @@ -2303,26 +4770,145 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } - for permission, res := range filter.assertions { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - }) + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds() != nil && response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) + } + } + }) + + It("Google Docs Sample: Case 3", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(googleDocsSchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + assertions map[string][]string + } + + tests := struct { + relationships []string + filters []filter + }{} + + for i := 1; i <= 50; i++ { + relationship := fmt.Sprintf("resource:%d#viewer@user:1", i) + tests.relationships = append(tests.relationships, relationship) + } + + // Generate 50 manager relationships. + for i := 51; i <= 100; i++ { + relationship := fmt.Sprintf("resource:%d#manager@user:1", i) + tests.relationships = append(tests.relationships, relationship) + } + + tests.filters = []filter{ + { + entityType: "resource", + subject: "user:1", + permissions: []string{"view", "edit"}, + assertions: map[string][]string{ + "view": {"1", "10", "100", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "3", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "4", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "5", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "6", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "7", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "8", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "9", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + "edit": {"100", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) - Expect(err).ShouldNot(HaveOccurred()) - Expect(response.GetEntityIds()).Should(Equal(res)) + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + Expect(response.GetEntityIds()[permission].Ids).Should(Equal(res)) } } }) - It("Google Docs Sample: Case 3", func() { + It("Google Docs Sample: Case 4 pagination", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -2340,9 +4926,10 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + permissions []string + assertions map[string][]string } tests := struct { @@ -2363,8 +4950,9 @@ var _ = Describe("lookup-entity-engine", func() { tests.filters = []filter{ { - entityType: "resource", - subject: "user:1", + entityType: "resource", + subject: "user:1", + permissions: []string{"view", "edit"}, assertions: map[string][]string{ "view": {"1", "10", "100", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "3", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "4", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "5", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "6", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "7", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "8", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "9", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, "edit": {"100", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, @@ -2406,6 +4994,202 @@ var _ = Describe("lookup-entity-engine", func() { _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) Expect(err).ShouldNot(HaveOccurred()) + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + for permission, res := range filter.assertions { + + ct := "" + + var ids []string + + for { + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + PageSize: 10, + ContinuousToken: ct, + }) + Expect(err).ShouldNot(HaveOccurred()) + + ids = append(ids, response.GetEntityIds()[permission].Ids...) + + ct = response.GetContinuousToken() + + if ct == "" { + break + } + } + + Expect(ids).Should(Equal(res)) + } + } + }) + }) + + workdaySchemaEntityFilter := ` + entity user {} + + entity organization { + + relation member @user + + attribute balance integer + + permission view = check_balance(balance) and member + } + + entity repository { + + relation organization @organization + + attribute is_public boolean + + permission view = is_public + permission edit = organization.view + permission delete = is_workday(is_public) + } + + rule check_balance(balance integer) { + balance > 5000 + } + + rule is_workday(is_public boolean) { + is_public && (context.data.day_of_week != 'saturday' && context.data.day_of_week != 'sunday') + } + ` + + Context("Weekday Sample: Entity Filter", func() { + It("Weekday Sample: Case 1", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(workdaySchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + assertions map[string][]string + } + + tests := struct { + relationships []string + attributes []string + filters []filter + }{ + relationships: []string{ + "organization:1#member@user:1", + "organization:2#member@user:1", + "organization:4#member@user:1", + "organization:8#member@user:1", + "organization:917#member@user:1", + "organization:20#member@user:1", + "organization:45#member@user:1", + "repository:4#organization@organization:1", + + "organization:2#member@user:1", + }, + attributes: []string{ + "repository:1$is_public|boolean:true", + "repository:2$is_public|boolean:false", + "repository:3$is_public|boolean:true", + "repository:4$is_public|boolean:true", + "repository:5$is_public|boolean:true", + "repository:6$is_public|boolean:false", + + "organization:1$balance|integer:4000", + "organization:2$balance|integer:6000", + "organization:4$balance|integer:6000", + "organization:8$balance|integer:6000", + "organization:917$balance|integer:6000", + "organization:20$balance|integer:6000", + "organization:45$balance|integer:6000", + }, + filters: []filter{ + { + entityType: "repository", + subject: "user:1", + assertions: map[string][]string{ + "view": {"1", "3", "4", "5"}, + }, + }, + { + entityType: "organization", + subject: "user:1", + assertions: map[string][]string{ + "view": {"2", "20", "4", "45", "8", "917"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + var attributes []*base.Attribute + + for _, attr := range tests.attributes { + a, err := attribute.Attribute(attr) + Expect(err).ShouldNot(HaveOccurred()) + attributes = append(attributes, a) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection(attributes...)) + Expect(err).ShouldNot(HaveOccurred()) + for _, filter := range tests.filters { ear, err := tuple.EAR(filter.subject) Expect(err).ShouldNot(HaveOccurred()) @@ -2435,7 +5219,7 @@ var _ = Describe("lookup-entity-engine", func() { } }) - It("Google Docs Sample: Case 4 pagination", func() { + It("Weekday Sample: Case 2 pagination", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -2444,7 +5228,7 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) - conf, err := newSchema(googleDocsSchemaEntityFilter) + conf, err := newSchema(workdaySchemaEntityFilter) Expect(err).ShouldNot(HaveOccurred()) schemaWriter := factories.SchemaWriterFactory(db) @@ -2460,27 +5244,57 @@ var _ = Describe("lookup-entity-engine", func() { tests := struct { relationships []string + attributes []string filters []filter - }{} - - for i := 1; i <= 50; i++ { - relationship := fmt.Sprintf("resource:%d#viewer@user:1", i) - tests.relationships = append(tests.relationships, relationship) - } + }{ + relationships: []string{ + "organization:1#member@user:1", + "organization:2#member@user:1", + "organization:4#member@user:1", + "organization:8#member@user:1", + "organization:917#member@user:1", + "organization:20#member@user:1", + "organization:45#member@user:1", + "organization:22#member@user:1", + "organization:43#member@user:1", + "organization:84#member@user:1", + "organization:9157#member@user:1", + "organization:260#member@user:1", + "organization:475#member@user:1", + "repository:4#organization@organization:1", - // Generate 50 manager relationships. - for i := 51; i <= 100; i++ { - relationship := fmt.Sprintf("resource:%d#manager@user:1", i) - tests.relationships = append(tests.relationships, relationship) - } + "organization:2#member@user:1", + }, + attributes: []string{ + "repository:1$is_public|boolean:true", + "repository:2$is_public|boolean:false", + "repository:3$is_public|boolean:true", + "repository:4$is_public|boolean:true", + "repository:5$is_public|boolean:true", + "repository:6$is_public|boolean:false", - tests.filters = []filter{ - { - entityType: "resource", - subject: "user:1", - assertions: map[string][]string{ - "view": {"1", "10", "100", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "3", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "4", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "5", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "6", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "7", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "8", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "9", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, - "edit": {"100", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}, + "organization:1$balance|integer:4000", + "organization:2$balance|integer:6000", + "organization:4$balance|integer:6000", + "organization:8$balance|integer:6000", + "organization:917$balance|integer:6000", + "organization:20$balance|integer:6000", + "organization:45$balance|integer:6000", + + "organization:22$balance|integer:6000", + "organization:43$balance|integer:6000", + "organization:84$balance|integer:6000", + "organization:9157$balance|integer:6000", + "organization:260$balance|integer:6000", + "organization:475$balance|integer:6000", + }, + filters: []filter{ + { + entityType: "organization", + subject: "user:1", + assertions: map[string][]string{ + "view": {"2", "20", "22", "260", "4", "43", "45", "475", "8", "84", "9157", "917"}, + }, }, }, } @@ -2516,7 +5330,15 @@ var _ = Describe("lookup-entity-engine", func() { tuples = append(tuples, t) } - _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection()) + var attributes []*base.Attribute + + for _, attr := range tests.attributes { + a, err := attribute.Attribute(attr) + Expect(err).ShouldNot(HaveOccurred()) + attributes = append(attributes, a) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection(attributes...)) Expect(err).ShouldNot(HaveOccurred()) for _, filter := range tests.filters { @@ -2564,42 +5386,8 @@ var _ = Describe("lookup-entity-engine", func() { } } }) - }) - - workdaySchemaEntityFilter := ` - entity user {} - - entity organization { - - relation member @user - - attribute balance integer - - permission view = check_balance(balance) and member - } - - entity repository { - - relation organization @organization - - attribute is_public boolean - - permission view = is_public - permission edit = organization.view - permission delete = is_workday(is_public) - } - - rule check_balance(balance integer) { - balance > 5000 - } - - rule is_workday(is_public boolean) { - is_public && (context.data.day_of_week != 'saturday' && context.data.day_of_week != 'sunday') - } - ` - Context("Weekday Sample: Entity Filter", func() { - It("Weekday Sample: Case 1", func() { + It("Weekday Sample: Case 3 scope", func() { db, err := factories.DatabaseFactory( config.Database{ Engine: "memory", @@ -2619,6 +5407,7 @@ var _ = Describe("lookup-entity-engine", func() { type filter struct { entityType string subject string + scope map[string]*base.StringArrayValue assertions map[string][]string } @@ -2731,6 +5520,7 @@ var _ = Describe("lookup-entity-engine", func() { EntityType: filter.entityType, Subject: subject, Permission: permission, + Scope: filter.scope, Metadata: &base.PermissionLookupEntityRequestMetadata{ SnapToken: token.NewNoopToken().Encode().String(), SchemaVersion: "", @@ -2743,6 +5533,161 @@ var _ = Describe("lookup-entity-engine", func() { } } }) + }) + + Context("Weekday Sample: Entities Filter", func() { + It("Weekday Sample: Case 1", func() { + db, err := factories.DatabaseFactory( + config.Database{ + Engine: "memory", + }, + ) + + Expect(err).ShouldNot(HaveOccurred()) + + conf, err := newSchema(workdaySchemaEntityFilter) + Expect(err).ShouldNot(HaveOccurred()) + + schemaWriter := factories.SchemaWriterFactory(db) + err = schemaWriter.WriteSchema(context.Background(), conf) + + Expect(err).ShouldNot(HaveOccurred()) + + type filter struct { + entityType string + subject string + permissions []string + assertions map[string][]string + } + + tests := struct { + relationships []string + attributes []string + filters []filter + }{ + relationships: []string{ + "organization:1#member@user:1", + "organization:2#member@user:1", + "organization:4#member@user:1", + "organization:8#member@user:1", + "organization:917#member@user:1", + "organization:20#member@user:1", + "organization:45#member@user:1", + "repository:4#organization@organization:1", + + "organization:2#member@user:1", + }, + attributes: []string{ + "repository:1$is_public|boolean:true", + "repository:2$is_public|boolean:false", + "repository:3$is_public|boolean:true", + "repository:4$is_public|boolean:true", + "repository:5$is_public|boolean:true", + "repository:6$is_public|boolean:false", + + "organization:1$balance|integer:4000", + "organization:2$balance|integer:6000", + "organization:4$balance|integer:6000", + "organization:8$balance|integer:6000", + "organization:917$balance|integer:6000", + "organization:20$balance|integer:6000", + "organization:45$balance|integer:6000", + }, + filters: []filter{ + { + entityType: "repository", + subject: "user:1", + permissions: []string{"view"}, + assertions: map[string][]string{ + "view": {"1", "3", "4", "5"}, + }, + }, + { + entityType: "organization", + subject: "user:1", + permissions: []string{"view"}, + assertions: map[string][]string{ + "view": {"2", "20", "4", "45", "8", "917"}, + }, + }, + }, + } + + schemaReader := factories.SchemaReaderFactory(db) + dataReader := factories.DataReaderFactory(db) + dataWriter := factories.DataWriterFactory(db) + + checkEngine := NewCheckEngine(schemaReader, dataReader) + + lookupEngine := NewLookupEngine( + checkEngine, + schemaReader, + dataReader, + ) + + invoker := invoke.NewDirectInvoker( + schemaReader, + dataReader, + checkEngine, + nil, + lookupEngine, + nil, + ) + + checkEngine.SetInvoker(invoker) + + var tuples []*base.Tuple + + for _, relationship := range tests.relationships { + t, err := tuple.Tuple(relationship) + Expect(err).ShouldNot(HaveOccurred()) + tuples = append(tuples, t) + } + + var attributes []*base.Attribute + + for _, attr := range tests.attributes { + a, err := attribute.Attribute(attr) + Expect(err).ShouldNot(HaveOccurred()) + attributes = append(attributes, a) + } + + _, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection(attributes...)) + Expect(err).ShouldNot(HaveOccurred()) + + for _, filter := range tests.filters { + ear, err := tuple.EAR(filter.subject) + Expect(err).ShouldNot(HaveOccurred()) + + subject := &base.Subject{ + Type: ear.GetEntity().GetType(), + Id: ear.GetEntity().GetId(), + Relation: ear.GetRelation(), + } + + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) + + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + var permissions []string + if response.GetEntityIds()[permission] != nil { + permissions = response.GetEntityIds()[permission].Ids + } + Expect(permissions).Should(Equal(res)) + } + + } + }) It("Weekday Sample: Case 2 pagination", func() { db, err := factories.DatabaseFactory( @@ -2762,9 +5707,10 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - assertions map[string][]string + entityType string + subject string + assertions map[string][]string + permissions []string } tests := struct { @@ -2815,8 +5761,9 @@ var _ = Describe("lookup-entity-engine", func() { }, filters: []filter{ { - entityType: "organization", - subject: "user:1", + entityType: "organization", + subject: "user:1", + permissions: []string{"view"}, assertions: map[string][]string{ "view": {"2", "20", "22", "260", "4", "43", "45", "475", "8", "84", "9157", "917"}, }, @@ -2883,11 +5830,11 @@ var _ = Describe("lookup-entity-engine", func() { var ids []string for { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: []string{permission}, Metadata: &base.PermissionLookupEntityRequestMetadata{ SnapToken: token.NewNoopToken().Encode().String(), SchemaVersion: "", @@ -2898,7 +5845,7 @@ var _ = Describe("lookup-entity-engine", func() { }) Expect(err).ShouldNot(HaveOccurred()) - ids = append(ids, response.GetEntityIds()...) + ids = append(ids, response.GetEntityIds()[permission].Ids...) ct = response.GetContinuousToken() @@ -2930,10 +5877,11 @@ var _ = Describe("lookup-entity-engine", func() { Expect(err).ShouldNot(HaveOccurred()) type filter struct { - entityType string - subject string - scope map[string]*base.StringArrayValue - assertions map[string][]string + entityType string + subject string + permissions []string + scope map[string]*base.StringArrayValue + assertions map[string][]string } tests := struct { @@ -2971,15 +5919,17 @@ var _ = Describe("lookup-entity-engine", func() { }, filters: []filter{ { - entityType: "repository", - subject: "user:1", + entityType: "repository", + subject: "user:1", + permissions: []string{"view"}, assertions: map[string][]string{ "view": {"1", "3", "4", "5"}, }, }, { - entityType: "organization", - subject: "user:1", + entityType: "organization", + subject: "user:1", + permissions: []string{"view"}, assertions: map[string][]string{ "view": {"2", "20", "4", "45", "8", "917"}, }, @@ -3039,58 +5989,58 @@ var _ = Describe("lookup-entity-engine", func() { Relation: ear.GetRelation(), } - for permission, res := range filter.assertions { - response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{ - TenantId: "t1", - EntityType: filter.entityType, - Subject: subject, - Permission: permission, - Scope: filter.scope, - Metadata: &base.PermissionLookupEntityRequestMetadata{ - SnapToken: token.NewNoopToken().Encode().String(), - SchemaVersion: "", - Depth: 100, - }, - }) + response, err := invoker.LookupEntities(context.Background(), &base.PermissionsLookupEntityRequest{ + TenantId: "t1", + EntityType: filter.entityType, + Subject: subject, + Permissions: filter.permissions, + Scope: filter.scope, + Metadata: &base.PermissionLookupEntityRequestMetadata{ + SnapToken: token.NewNoopToken().Encode().String(), + SchemaVersion: "", + Depth: 100, + }, + }) - Expect(err).ShouldNot(HaveOccurred()) - Expect(response.GetEntityIds()).Should(Equal(res)) + Expect(err).ShouldNot(HaveOccurred()) + for permission, res := range filter.assertions { + Expect(response.GetEntityIds()[permission].Ids).Should(Equal(res)) } } }) }) driveSchemaSubjectFilter := ` - entity user {} + entity user {} - entity organization { - relation admin @user - } + entity organization { + relation admin @user + } - entity folder { - relation org @organization - relation creator @user - relation collaborator @user + entity folder { + relation org @organization + relation creator @user + relation collaborator @user - permission read = collaborator - permission update = collaborator - permission delete = creator or org.admin - permission share = update - } + permission read = collaborator + permission update = collaborator + permission delete = creator or org.admin + permission share = update + } - entity doc { - relation org @organization - relation parent @folder + entity doc { + relation org @organization + relation parent @folder - relation owner @user @organization#admin - relation member @user + relation owner @user @organization#admin + relation member @user - permission read = owner or member - permission update = owner and org.admin - permission delete = owner or org.admin - permission share = update and (member not parent.update) - permission remove = owner or parent.delete - }` + permission read = owner or member + permission update = owner and org.admin + permission delete = owner or org.admin + permission share = update and (member not parent.update) + permission remove = owner or parent.delete + }` Context("Drive Sample: Subject Filter", func() { It("Drive Sample: Case 1", func() { @@ -4069,36 +7019,36 @@ var _ = Describe("lookup-entity-engine", func() { }) workdaySchemaSubjectFilter := ` - entity user {} + entity user {} - entity organization { + entity organization { - relation member @user + relation member @user - attribute balance integer + attribute balance integer - permission view = check_balance(balance) and member - } + permission view = check_balance(balance) and member + } - entity repository { + entity repository { - relation organization @organization + relation organization @organization - attribute is_public boolean + attribute is_public boolean - permission view = is_public - permission edit = organization.view - permission delete = is_workday(is_public) - } + permission view = is_public + permission edit = organization.view + permission delete = is_workday(is_public) + } - rule check_balance(balance integer) { - balance > 5000 - } + rule check_balance(balance integer) { + balance > 5000 + } - rule is_workday(is_public boolean) { - is_public == true && (context.data.day_of_week != 'saturday' && context.data.day_of_week != 'sunday') - } - ` + rule is_workday(is_public boolean) { + is_public == true && (context.data.day_of_week != 'saturday' && context.data.day_of_week != 'sunday') + } + ` Context("Weekday Sample: Subject Filter", func() { It("Weekday Sample: Case 1", func() { diff --git a/internal/engines/utils.go b/internal/engines/utils.go index d22e10865..88890829a 100644 --- a/internal/engines/utils.go +++ b/internal/engines/utils.go @@ -393,3 +393,17 @@ func IsRelational(en *base.EntityDefinition, permission string) bool { return isRelational } + +func ConvertToPermissionsLookupEntityRequest(req *base.PermissionLookupEntityRequest) *base.PermissionsLookupEntityRequest { + return &base.PermissionsLookupEntityRequest{ + TenantId: req.TenantId, + Metadata: req.Metadata, + EntityType: req.EntityType, + Permissions: []string{req.Permission}, + Subject: req.Subject, + Context: req.Context, + Scope: req.Scope, + PageSize: req.PageSize, + ContinuousToken: req.ContinuousToken, + } +} diff --git a/internal/invoke/invoke.go b/internal/invoke/invoke.go index d4a7f2a22..422ae0b52 100644 --- a/internal/invoke/invoke.go +++ b/internal/invoke/invoke.go @@ -49,6 +49,8 @@ type Lookup interface { LookupEntity(ctx context.Context, request *base.PermissionLookupEntityRequest) (response *base.PermissionLookupEntityResponse, err error) LookupEntityStream(ctx context.Context, request *base.PermissionLookupEntityRequest, server base.Permission_LookupEntityStreamServer) (err error) LookupSubject(ctx context.Context, request *base.PermissionLookupSubjectRequest) (response *base.PermissionLookupSubjectResponse, err error) + LookupEntities(ctx context.Context, request *base.PermissionsLookupEntityRequest) (response *base.PermissionsLookupEntityResponse, err error) + LookupEntitiesStream(ctx context.Context, request *base.PermissionsLookupEntityRequest, server base.Permission_LookupEntitiesStreamServer) (err error) } // SubjectPermission - @@ -245,7 +247,7 @@ func (invoker *DirectInvoker) LookupEntity(ctx context.Context, request *base.Pe ctx, span := tracer.Start(ctx, "lookup-entity", trace.WithAttributes( attribute.KeyValue{Key: "tenant_id", Value: attribute.StringValue(request.GetTenantId())}, attribute.KeyValue{Key: "entity_type", Value: attribute.StringValue(request.GetEntityType())}, - attribute.KeyValue{Key: "permission", Value: attribute.StringValue(request.GetPermission())}, + attribute.KeyValue{Key: "permissions", Value: attribute.StringValue(request.GetPermission())}, attribute.KeyValue{Key: "subject", Value: attribute.StringValue(tuple.SubjectToString(request.GetSubject()))}, )) defer span.End() @@ -292,7 +294,7 @@ func (invoker *DirectInvoker) LookupEntityStream(ctx context.Context, request *b ctx, span := tracer.Start(ctx, "lookup-entity-stream", trace.WithAttributes( attribute.KeyValue{Key: "tenant_id", Value: attribute.StringValue(request.GetTenantId())}, attribute.KeyValue{Key: "entity_type", Value: attribute.StringValue(request.GetEntityType())}, - attribute.KeyValue{Key: "permission", Value: attribute.StringValue(request.GetPermission())}, + attribute.KeyValue{Key: "permissions", Value: attribute.StringValue(request.GetPermission())}, attribute.KeyValue{Key: "subject", Value: attribute.StringValue(tuple.SubjectToString(request.GetSubject()))}, )) defer span.End() @@ -332,6 +334,100 @@ func (invoker *DirectInvoker) LookupEntityStream(ctx context.Context, request *b return resp } +// LookupEntities is a method that implements the LookupEntities interface. +// It calls the Run method of the LookupEntitiesEngine with the provided context and PermissionsLookupEntityRequest, +// and returns a PermissionsLookupEntityResponse and an error if any. +func (invoker *DirectInvoker) LookupEntities(ctx context.Context, request *base.PermissionsLookupEntityRequest) (response *base.PermissionsLookupEntityResponse, err error) { + ctx, span := tracer.Start(ctx, "lookup-entities", trace.WithAttributes( + attribute.KeyValue{Key: "tenant_id", Value: attribute.StringValue(request.GetTenantId())}, + attribute.KeyValue{Key: "entity_type", Value: attribute.StringValue(request.GetEntityType())}, + attribute.KeyValue{Key: "permissions", Value: attribute.StringSliceValue(request.GetPermissions())}, + attribute.KeyValue{Key: "subject", Value: attribute.StringValue(tuple.SubjectToString(request.GetSubject()))}, + )) + defer span.End() + + start := time.Now() + + // Set SnapToken if not provided + if request.GetMetadata().GetSnapToken() == "" { // Check if the request has a SnapToken. + var st token.SnapToken + st, err = invoker.dataReader.HeadSnapshot(ctx, request.GetTenantId()) // Retrieve the head snapshot from the relationship reader. + if err != nil { + span.RecordError(err) + span.SetStatus(otelCodes.Error, err.Error()) + return response, err + } + request.Metadata.SnapToken = st.Encode().String() // Set the SnapToken in the request metadata. + } + + // Set SchemaVersion if not provided + if request.GetMetadata().GetSchemaVersion() == "" { // Check if the request has a SchemaVersion. + request.Metadata.SchemaVersion, err = invoker.schemaReader.HeadVersion(ctx, request.GetTenantId()) // Retrieve the head schema version from the schema reader. + if err != nil { + span.RecordError(err) + span.SetStatus(otelCodes.Error, err.Error()) + return response, err + } + } + + resp, err := invoker.lo.LookupEntities(ctx, request) + + duration := time.Since(start) + invoker.lookupEntityDurationHistogram.Record(ctx, duration.Microseconds()) + + // Increase the lookup entity count in the metrics. + invoker.lookupEntityCounter.Add(ctx, 1) + + return resp, err +} + +// LookupEntitiesStream is a method that implements the LookupEntitiesStream interface. +// It calls the Stream method of the LookupEntitiesEngine with the provided context, PermissionsLookupEntityRequest, and Permission_LookupEntitiesStreamServer, +// and returns an error if any. +func (invoker *DirectInvoker) LookupEntitiesStream(ctx context.Context, request *base.PermissionsLookupEntityRequest, server base.Permission_LookupEntitiesStreamServer) (err error) { + ctx, span := tracer.Start(ctx, "lookup-entities-stream", trace.WithAttributes( + attribute.KeyValue{Key: "tenant_id", Value: attribute.StringValue(request.GetTenantId())}, + attribute.KeyValue{Key: "entity_type", Value: attribute.StringValue(request.GetEntityType())}, + attribute.KeyValue{Key: "permissions", Value: attribute.StringSliceValue(request.GetPermissions())}, + attribute.KeyValue{Key: "subject", Value: attribute.StringValue(tuple.SubjectToString(request.GetSubject()))}, + )) + defer span.End() + + start := time.Now() + + // Set SnapToken if not provided + if request.GetMetadata().GetSnapToken() == "" { // Check if the request has a SnapToken. + var st token.SnapToken + st, err = invoker.dataReader.HeadSnapshot(ctx, request.GetTenantId()) // Retrieve the head snapshot from the relationship reader. + if err != nil { + span.RecordError(err) + span.SetStatus(otelCodes.Error, err.Error()) + return err + } + request.Metadata.SnapToken = st.Encode().String() // Set the SnapToken in the request metadata. + } + + // Set SchemaVersion if not provided + if request.GetMetadata().GetSchemaVersion() == "" { // Check if the request has a SchemaVersion. + request.Metadata.SchemaVersion, err = invoker.schemaReader.HeadVersion(ctx, request.GetTenantId()) // Retrieve the head schema version from the schema reader. + if err != nil { + span.RecordError(err) + span.SetStatus(otelCodes.Error, err.Error()) + return err + } + } + + resp := invoker.lo.LookupEntitiesStream(ctx, request, server) + + duration := time.Since(start) + invoker.lookupEntityDurationHistogram.Record(ctx, duration.Microseconds()) + + // Increase the lookup entity count in the metrics. + invoker.lookupEntityCounter.Add(ctx, 1) + + return resp +} + // LookupSubject is a method of the DirectInvoker structure. It handles the task of looking up subjects // and returning the results in a response. func (invoker *DirectInvoker) LookupSubject(ctx context.Context, request *base.PermissionLookupSubjectRequest) (response *base.PermissionLookupSubjectResponse, err error) { diff --git a/internal/schema/linkedSchema.go b/internal/schema/linkedSchema.go index 12b91645b..892cc9d7d 100644 --- a/internal/schema/linkedSchema.go +++ b/internal/schema/linkedSchema.go @@ -2,9 +2,9 @@ package schema import ( "errors" - "github.com/Permify/permify/pkg/dsl/utils" base "github.com/Permify/permify/pkg/pb/base/v1" + "sync" ) // LinkedSchemaGraph represents a graph of linked schema objects. The schema object contains definitions for entities, @@ -87,13 +87,40 @@ func (re LinkedEntrance) LinkedEntranceKind() LinkedEntranceKind { // Returns: // - slice of LinkedEntrance objects that represent entry points into the LinkedSchemaGraph, or an error if the target or // source relation does not exist in the schema graph -func (g *LinkedSchemaGraph) LinkedEntrances(target, source *base.Entrance) ([]*LinkedEntrance, error) { - entries, err := g.findEntrance(target, source, map[string]struct{}{}) - if err != nil { - return nil, err +func (g *LinkedSchemaGraph) LinkedEntrances(targets []*base.Entrance, source *base.Entrance) ([]*LinkedEntrance, error) { + visited := map[string]struct{}{} + var mu sync.Mutex + var wg sync.WaitGroup + errChan := make(chan error, len(targets)) + done := make(chan struct{}) + totalEntries := make([]*LinkedEntrance, 0) + for _, target := range targets { + wg.Add(1) + go func(target *base.Entrance) { + defer wg.Done() + entries, err := g.findEntrance(target, source, visited, &mu) + if err != nil { + errChan <- err + } + mu.Lock() + defer mu.Unlock() + totalEntries = append(totalEntries, entries...) + }(target) } - return entries, nil + go func() { + wg.Wait() + close(done) + }() + + select { + case <-done: + // All goroutines finished + return totalEntries, nil + case err := <-errChan: + // Return on the first error encountered + return nil, err + } } // findEntrance is a recursive helper function that searches the LinkedSchemaGraph for all entry points that can be reached @@ -111,12 +138,16 @@ func (g *LinkedSchemaGraph) LinkedEntrances(target, source *base.Entrance) ([]*L // Returns: // - slice of LinkedEntrance objects that represent entry points into the LinkedSchemaGraph, or an error if the target or // source relation does not exist in the schema graph -func (g *LinkedSchemaGraph) findEntrance(target, source *base.Entrance, visited map[string]struct{}) ([]*LinkedEntrance, error) { +func (g *LinkedSchemaGraph) findEntrance(target, source *base.Entrance, visited map[string]struct{}, mu *sync.Mutex) ([]*LinkedEntrance, error) { key := utils.Key(target.GetType(), target.GetValue()) + mu.Lock() + if _, ok := visited[key]; ok { + mu.Unlock() return nil, nil } visited[key] = struct{}{} + mu.Unlock() def, ok := g.schema.EntityDefinitions[target.GetType()] if !ok { @@ -131,9 +162,9 @@ func (g *LinkedSchemaGraph) findEntrance(target, source *base.Entrance, visited } child := permission.GetChild() if child.GetRewrite() != nil { - return g.findEntranceRewrite(target, source, child.GetRewrite(), visited) + return g.findEntranceRewrite(target, source, child.GetRewrite(), visited, mu) } - return g.findEntranceLeaf(target, source, child.GetLeaf(), visited) + return g.findEntranceLeaf(target, source, child.GetLeaf(), visited, mu) case base.EntityDefinition_REFERENCE_ATTRIBUTE: attribute, ok := def.Attributes[target.GetValue()] if !ok { @@ -149,7 +180,7 @@ func (g *LinkedSchemaGraph) findEntrance(target, source *base.Entrance, visited }, }, nil case base.EntityDefinition_REFERENCE_RELATION: - return g.findRelationEntrance(target, source, visited) + return g.findRelationEntrance(target, source, visited, mu) default: return nil, ErrUnimplemented } @@ -169,7 +200,7 @@ func (g *LinkedSchemaGraph) findEntrance(target, source *base.Entrance, visited // Returns: // - slice of LinkedEntrance objects that represent entry points into the LinkedSchemaGraph, or an error if the target or // source relation does not exist in the schema graph -func (g *LinkedSchemaGraph) findRelationEntrance(target, source *base.Entrance, visited map[string]struct{}) ([]*LinkedEntrance, error) { +func (g *LinkedSchemaGraph) findRelationEntrance(target, source *base.Entrance, visited map[string]struct{}, mu *sync.Mutex) ([]*LinkedEntrance, error) { var res []*LinkedEntrance entity, ok := g.schema.EntityDefinitions[target.GetType()] @@ -197,7 +228,7 @@ func (g *LinkedSchemaGraph) findRelationEntrance(target, source *base.Entrance, entrances, err := g.findEntrance(&base.Entrance{ Type: rel.GetType(), Value: rel.GetRelation(), - }, source, visited) + }, source, visited, mu) if err != nil { return nil, err } @@ -226,7 +257,7 @@ func (g *LinkedSchemaGraph) findRelationEntrance(target, source *base.Entrance, // Returns: // - slice of LinkedEntrance objects that represent entry points into the LinkedSchemaGraph, or an error if the target or // source relation does not exist in the schema graph -func (g *LinkedSchemaGraph) findEntranceLeaf(target, source *base.Entrance, leaf *base.Leaf, visited map[string]struct{}) ([]*LinkedEntrance, error) { +func (g *LinkedSchemaGraph) findEntranceLeaf(target, source *base.Entrance, leaf *base.Leaf, visited map[string]struct{}, mu *sync.Mutex) ([]*LinkedEntrance, error) { switch t := leaf.GetType().(type) { case *base.Leaf_TupleToUserSet: tupleSet := t.TupleToUserSet.GetTupleSet().GetRelation() @@ -259,6 +290,7 @@ func (g *LinkedSchemaGraph) findEntranceLeaf(target, source *base.Entrance, leaf }, source, visited, + mu, ) if err != nil { return nil, err @@ -283,6 +315,7 @@ func (g *LinkedSchemaGraph) findEntranceLeaf(target, source *base.Entrance, leaf }, source, visited, + mu, ) if err != nil { return nil, err @@ -338,17 +371,17 @@ func (g *LinkedSchemaGraph) findEntranceLeaf(target, source *base.Entrance, leaf // Returns: // - slice of LinkedEntrance objects that represent entry points into the LinkedSchemaGraph, or an error if the target or // source relation does not exist in the schema graph -func (g *LinkedSchemaGraph) findEntranceRewrite(target, source *base.Entrance, rewrite *base.Rewrite, visited map[string]struct{}) (results []*LinkedEntrance, err error) { +func (g *LinkedSchemaGraph) findEntranceRewrite(target, source *base.Entrance, rewrite *base.Rewrite, visited map[string]struct{}, mu *sync.Mutex) (results []*LinkedEntrance, err error) { var res []*LinkedEntrance for _, child := range rewrite.GetChildren() { switch child.GetType().(type) { case *base.Child_Rewrite: - results, err = g.findEntranceRewrite(target, source, child.GetRewrite(), visited) + results, err = g.findEntranceRewrite(target, source, child.GetRewrite(), visited, mu) if err != nil { return nil, err } case *base.Child_Leaf: - results, err = g.findEntranceLeaf(target, source, child.GetLeaf(), visited) + results, err = g.findEntranceLeaf(target, source, child.GetLeaf(), visited, mu) if err != nil { return nil, err } diff --git a/internal/servers/permissionServer.go b/internal/servers/permissionServer.go index dd41fac2d..9fb9e918c 100644 --- a/internal/servers/permissionServer.go +++ b/internal/servers/permissionServer.go @@ -109,6 +109,48 @@ func (r *PermissionServer) LookupEntityStream(request *v1.PermissionLookupEntity return nil } +// LookupEntities - +func (r *PermissionServer) LookupEntities(ctx context.Context, request *v1.PermissionsLookupEntityRequest) (*v1.PermissionsLookupEntityResponse, error) { + ctx, span := tracer.Start(ctx, "permissions.lookup-entities") + defer span.End() + + v := request.Validate() + if v != nil { + return nil, status.Error(GetStatus(v), v.Error()) + } + + response, err := r.invoker.LookupEntities(ctx, request) + if err != nil { + span.RecordError(err) + span.SetStatus(otelCodes.Error, err.Error()) + slog.ErrorContext(ctx, err.Error()) + return nil, status.Error(GetStatus(err), err.Error()) + } + + return response, nil +} + +// LookupEntitiesStream - +func (r *PermissionServer) LookupEntitiesStream(request *v1.PermissionsLookupEntityRequest, server v1.Permission_LookupEntitiesStreamServer) error { + ctx, span := tracer.Start(server.Context(), "permissions.lookup-entities-stream") + defer span.End() + + v := request.Validate() + if v != nil { + return v + } + + err := r.invoker.LookupEntitiesStream(ctx, request, server) + if err != nil { + span.RecordError(err) + span.SetStatus(otelCodes.Error, err.Error()) + slog.ErrorContext(ctx, err.Error()) + return status.Error(GetStatus(err), err.Error()) + } + + return nil +} + // LookupSubject - func (r *PermissionServer) LookupSubject(ctx context.Context, request *v1.PermissionLookupSubjectRequest) (*v1.PermissionLookupSubjectResponse, error) { ctx, span := tracer.Start(ctx, "permissions.lookup-subject") diff --git a/pkg/cmd/validate.go b/pkg/cmd/validate.go index b74060c7a..c4aeddb57 100644 --- a/pkg/cmd/validate.go +++ b/pkg/cmd/validate.go @@ -364,8 +364,11 @@ func validate() func(cmd *cobra.Command, args []string) error { // Format the subject, permission, and entity type as a string for logging. query := tuple.SubjectToString(subject) + " " + permission + " " + filter.EntityType - // Check if the actual result matches the expected result. - if isSameArray(res.GetEntityIds(), expected) { + if res.GetEntityIds() == nil && len(expected) == 0 { + // If the results match, log a success message. + color.Success.Print(" success:") + fmt.Printf(" %v\n", query) + } else if res.GetEntityIds() != nil && isSameArray(res.GetEntityIds(), expected) { // If the results match, log a success message. color.Success.Print(" success:") fmt.Printf(" %v\n", query) diff --git a/pkg/pb/base/v1/health.pb.go b/pkg/pb/base/v1/health.pb.go new file mode 100644 index 000000000..a8a45cea0 --- /dev/null +++ b/pkg/pb/base/v1/health.pb.go @@ -0,0 +1,314 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: base/v1/health.proto + +package basev1 + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HealthCheckResponse_ServingStatus int32 + +const ( + HealthCheckResponse_UNKNOWN HealthCheckResponse_ServingStatus = 0 + HealthCheckResponse_SERVING HealthCheckResponse_ServingStatus = 1 + HealthCheckResponse_NOT_SERVING HealthCheckResponse_ServingStatus = 2 + HealthCheckResponse_SERVICE_UNKNOWN HealthCheckResponse_ServingStatus = 3 // Used only by the Watch method. +) + +// Enum value maps for HealthCheckResponse_ServingStatus. +var ( + HealthCheckResponse_ServingStatus_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SERVING", + 2: "NOT_SERVING", + 3: "SERVICE_UNKNOWN", + } + HealthCheckResponse_ServingStatus_value = map[string]int32{ + "UNKNOWN": 0, + "SERVING": 1, + "NOT_SERVING": 2, + "SERVICE_UNKNOWN": 3, + } +) + +func (x HealthCheckResponse_ServingStatus) Enum() *HealthCheckResponse_ServingStatus { + p := new(HealthCheckResponse_ServingStatus) + *p = x + return p +} + +func (x HealthCheckResponse_ServingStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HealthCheckResponse_ServingStatus) Descriptor() protoreflect.EnumDescriptor { + return file_base_v1_health_proto_enumTypes[0].Descriptor() +} + +func (HealthCheckResponse_ServingStatus) Type() protoreflect.EnumType { + return &file_base_v1_health_proto_enumTypes[0] +} + +func (x HealthCheckResponse_ServingStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use HealthCheckResponse_ServingStatus.Descriptor instead. +func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) { + return file_base_v1_health_proto_rawDescGZIP(), []int{1, 0} +} + +type HealthCheckRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` +} + +func (x *HealthCheckRequest) Reset() { + *x = HealthCheckRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_base_v1_health_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckRequest) ProtoMessage() {} + +func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_health_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckRequest.ProtoReflect.Descriptor instead. +func (*HealthCheckRequest) Descriptor() ([]byte, []int) { + return file_base_v1_health_proto_rawDescGZIP(), []int{0} +} + +func (x *HealthCheckRequest) GetService() string { + if x != nil { + return x.Service + } + return "" +} + +type HealthCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=base.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"` +} + +func (x *HealthCheckResponse) Reset() { + *x = HealthCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_base_v1_health_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckResponse) ProtoMessage() {} + +func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_health_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckResponse.ProtoReflect.Descriptor instead. +func (*HealthCheckResponse) Descriptor() ([]byte, []int) { + return file_base_v1_health_proto_rawDescGZIP(), []int{1} +} + +func (x *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus { + if x != nil { + return x.Status + } + return HealthCheckResponse_UNKNOWN +} + +var File_base_v1_health_proto protoreflect.FileDescriptor + +var file_base_v1_health_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x1a, + 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, + 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2e, 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x4f, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0f, 0x0a, + 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, + 0x0a, 0x0f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x03, 0x32, 0xe5, 0x02, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x94, + 0x02, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xcf, 0x01, 0x92, 0x41, 0xbb, 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x12, 0x0a, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x61, 0x70, 0x69, 0x2a, 0x0c, + 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6a, 0x96, 0x01, 0x0a, + 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x84, + 0x01, 0x32, 0x81, 0x01, 0x0a, 0x29, 0x2a, 0x27, 0x0a, 0x0b, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x02, 0x1a, 0x00, 0x0a, 0x0a, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x02, 0x1a, + 0x00, 0x0a, 0x0c, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x02, 0x1a, 0x00, 0x0a, + 0x29, 0x2a, 0x27, 0x0a, 0x0b, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x02, 0x1a, 0x00, + 0x0a, 0x0a, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x02, 0x1a, 0x00, 0x0a, 0x0c, 0x0a, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x02, 0x1a, 0x00, 0x0a, 0x29, 0x2a, 0x27, 0x0a, 0x0b, + 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x02, 0x1a, 0x00, 0x0a, 0x0a, 0x0a, 0x04, 0x6c, + 0x61, 0x6e, 0x67, 0x12, 0x02, 0x1a, 0x00, 0x0a, 0x0c, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x02, 0x1a, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x7a, 0x12, 0x44, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1b, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x89, 0x01, 0x0a, 0x0b, + 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x62, 0x61, + 0x73, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, + 0x58, 0x58, 0xaa, 0x02, 0x07, 0x42, 0x61, 0x73, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x42, + 0x61, 0x73, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x42, 0x61, 0x73, 0x65, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x42, + 0x61, 0x73, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_base_v1_health_proto_rawDescOnce sync.Once + file_base_v1_health_proto_rawDescData = file_base_v1_health_proto_rawDesc +) + +func file_base_v1_health_proto_rawDescGZIP() []byte { + file_base_v1_health_proto_rawDescOnce.Do(func() { + file_base_v1_health_proto_rawDescData = protoimpl.X.CompressGZIP(file_base_v1_health_proto_rawDescData) + }) + return file_base_v1_health_proto_rawDescData +} + +var file_base_v1_health_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_base_v1_health_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_base_v1_health_proto_goTypes = []any{ + (HealthCheckResponse_ServingStatus)(0), // 0: base.v1.HealthCheckResponse.ServingStatus + (*HealthCheckRequest)(nil), // 1: base.v1.HealthCheckRequest + (*HealthCheckResponse)(nil), // 2: base.v1.HealthCheckResponse +} +var file_base_v1_health_proto_depIdxs = []int32{ + 0, // 0: base.v1.HealthCheckResponse.status:type_name -> base.v1.HealthCheckResponse.ServingStatus + 1, // 1: base.v1.Health.Check:input_type -> base.v1.HealthCheckRequest + 1, // 2: base.v1.Health.Watch:input_type -> base.v1.HealthCheckRequest + 2, // 3: base.v1.Health.Check:output_type -> base.v1.HealthCheckResponse + 2, // 4: base.v1.Health.Watch:output_type -> base.v1.HealthCheckResponse + 3, // [3:5] is the sub-list for method output_type + 1, // [1:3] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_base_v1_health_proto_init() } +func file_base_v1_health_proto_init() { + if File_base_v1_health_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_base_v1_health_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*HealthCheckRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_base_v1_health_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*HealthCheckResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_base_v1_health_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_base_v1_health_proto_goTypes, + DependencyIndexes: file_base_v1_health_proto_depIdxs, + EnumInfos: file_base_v1_health_proto_enumTypes, + MessageInfos: file_base_v1_health_proto_msgTypes, + }.Build() + File_base_v1_health_proto = out.File + file_base_v1_health_proto_rawDesc = nil + file_base_v1_health_proto_goTypes = nil + file_base_v1_health_proto_depIdxs = nil +} + diff --git a/pkg/pb/base/v1/health.pb.validate.go b/pkg/pb/base/v1/health.pb.validate.go new file mode 100644 index 000000000..60cb10b39 --- /dev/null +++ b/pkg/pb/base/v1/health.pb.validate.go @@ -0,0 +1,245 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: base/v1/health.proto + +package basev1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on HealthCheckRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *HealthCheckRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on HealthCheckRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// HealthCheckRequestMultiError, or nil if none found. +func (m *HealthCheckRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *HealthCheckRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Service + + if len(errors) > 0 { + return HealthCheckRequestMultiError(errors) + } + + return nil +} + +// HealthCheckRequestMultiError is an error wrapping multiple validation errors +// returned by HealthCheckRequest.ValidateAll() if the designated constraints +// aren't met. +type HealthCheckRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m HealthCheckRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m HealthCheckRequestMultiError) AllErrors() []error { return m } + +// HealthCheckRequestValidationError is the validation error returned by +// HealthCheckRequest.Validate if the designated constraints aren't met. +type HealthCheckRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e HealthCheckRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e HealthCheckRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e HealthCheckRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e HealthCheckRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e HealthCheckRequestValidationError) ErrorName() string { + return "HealthCheckRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e HealthCheckRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sHealthCheckRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = HealthCheckRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = HealthCheckRequestValidationError{} + +// Validate checks the field values on HealthCheckResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *HealthCheckResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on HealthCheckResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// HealthCheckResponseMultiError, or nil if none found. +func (m *HealthCheckResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *HealthCheckResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Status + + if len(errors) > 0 { + return HealthCheckResponseMultiError(errors) + } + + return nil +} + +// HealthCheckResponseMultiError is an error wrapping multiple validation +// errors returned by HealthCheckResponse.ValidateAll() if the designated +// constraints aren't met. +type HealthCheckResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m HealthCheckResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m HealthCheckResponseMultiError) AllErrors() []error { return m } + +// HealthCheckResponseValidationError is the validation error returned by +// HealthCheckResponse.Validate if the designated constraints aren't met. +type HealthCheckResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e HealthCheckResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e HealthCheckResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e HealthCheckResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e HealthCheckResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e HealthCheckResponseValidationError) ErrorName() string { + return "HealthCheckResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e HealthCheckResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sHealthCheckResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = HealthCheckResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = HealthCheckResponseValidationError{} + diff --git a/pkg/pb/base/v1/health_grpc.pb.go b/pkg/pb/base/v1/health_grpc.pb.go new file mode 100644 index 000000000..8df5e98ec --- /dev/null +++ b/pkg/pb/base/v1/health_grpc.pb.go @@ -0,0 +1,181 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.4.0 +// - protoc (unknown) +// source: base/v1/health.proto + +package basev1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +const ( + Health_Check_FullMethodName = "/base.v1.Health/Check" + Health_Watch_FullMethodName = "/base.v1.Health/Watch" +) + +// HealthClient is the client API for Health service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HealthClient interface { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) + Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) +} + +type healthClient struct { + cc grpc.ClientConnInterface +} + +func NewHealthClient(cc grpc.ClientConnInterface) HealthClient { + return &healthClient{cc} +} + +func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(HealthCheckResponse) + err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &healthWatchClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Health_WatchClient interface { + Recv() (*HealthCheckResponse, error) + grpc.ClientStream +} + +type healthWatchClient struct { + grpc.ClientStream +} + +func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) { + m := new(HealthCheckResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// HealthServer is the server API for Health service. +// All implementations must embed UnimplementedHealthServer +// for forward compatibility +type HealthServer interface { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) + Watch(*HealthCheckRequest, Health_WatchServer) error + mustEmbedUnimplementedHealthServer() +} + +// UnimplementedHealthServer must be embedded to have forward compatible implementations. +type UnimplementedHealthServer struct { +} + +func (UnimplementedHealthServer) Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") +} +func (UnimplementedHealthServer) Watch(*HealthCheckRequest, Health_WatchServer) error { + return status.Errorf(codes.Unimplemented, "method Watch not implemented") +} +func (UnimplementedHealthServer) mustEmbedUnimplementedHealthServer() {} + +// UnsafeHealthServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HealthServer will +// result in compilation errors. +type UnsafeHealthServer interface { + mustEmbedUnimplementedHealthServer() +} + +func RegisterHealthServer(s grpc.ServiceRegistrar, srv HealthServer) { + s.RegisterService(&Health_ServiceDesc, srv) +} + +func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HealthServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Health_Check_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Health_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(HealthCheckRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(HealthServer).Watch(m, &healthWatchServer{ServerStream: stream}) +} + +type Health_WatchServer interface { + Send(*HealthCheckResponse) error + grpc.ServerStream +} + +type healthWatchServer struct { + grpc.ServerStream +} + +func (x *healthWatchServer) Send(m *HealthCheckResponse) error { + return x.ServerStream.SendMsg(m) +} + +// Health_ServiceDesc is the grpc.ServiceDesc for Health service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Health_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "base.v1.Health", + HandlerType: (*HealthServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Check", + Handler: _Health_Check_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Watch", + Handler: _Health_Watch_Handler, + ServerStreams: true, + }, + }, + Metadata: "base/v1/health.proto", +} + diff --git a/pkg/pb/base/v1/service.pb.go b/pkg/pb/base/v1/service.pb.go index aa38d9b6b..248750131 100644 --- a/pkg/pb/base/v1/service.pb.go +++ b/pkg/pb/base/v1/service.pb.go @@ -625,6 +625,130 @@ func (x *PermissionLookupEntityRequest) GetContinuousToken() string { return "" } +// PermissionsLookupEntityRequest is the request message for the LookupEntities method in the Permission service. +type PermissionsLookupEntityRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,proto3" json:"tenant_id,omitempty"` + // Metadata associated with this request, required. + Metadata *PermissionLookupEntityRequestMetadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` + // Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. + EntityType string `protobuf:"bytes,3,opt,name=entity_type,proto3" json:"entity_type,omitempty"` + // Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. + Permissions []string `protobuf:"bytes,4,rep,name=permissions,proto3" json:"permissions,omitempty"` + // Subject for which to check the permission, required. + Subject *Subject `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` + // Context associated with this request. + Context *Context `protobuf:"bytes,6,opt,name=context,proto3" json:"context,omitempty"` + // Scope: A map that associates entity types with lists of identifiers. Each entry + // helps filter requests by specifying which entities are relevant to the operation. + Scope map[string]*StringArrayValue `protobuf:"bytes,7,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // page_size is the number of entities to be returned in the response. + // The value should be between 1 and 100. + PageSize uint32 `protobuf:"varint,8,opt,name=page_size,proto3" json:"page_size,omitempty"` + // continuous_token is an optional parameter used for pagination. + // It should be the value received in the previous response. + ContinuousToken string `protobuf:"bytes,9,opt,name=continuous_token,proto3" json:"continuous_token,omitempty"` +} + +func (x *PermissionsLookupEntityRequest) Reset() { + *x = PermissionsLookupEntityRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_base_v1_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PermissionsLookupEntityRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionsLookupEntityRequest) ProtoMessage() {} + +func (x *PermissionsLookupEntityRequest) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionsLookupEntityRequest.ProtoReflect.Descriptor instead. +func (*PermissionsLookupEntityRequest) Descriptor() ([]byte, []int) { + return file_base_v1_service_proto_rawDescGZIP(), []int{8} +} + +func (x *PermissionsLookupEntityRequest) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *PermissionsLookupEntityRequest) GetMetadata() *PermissionLookupEntityRequestMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *PermissionsLookupEntityRequest) GetEntityType() string { + if x != nil { + return x.EntityType + } + return "" +} + +func (x *PermissionsLookupEntityRequest) GetPermissions() []string { + if x != nil { + return x.Permissions + } + return nil +} + +func (x *PermissionsLookupEntityRequest) GetSubject() *Subject { + if x != nil { + return x.Subject + } + return nil +} + +func (x *PermissionsLookupEntityRequest) GetContext() *Context { + if x != nil { + return x.Context + } + return nil +} + +func (x *PermissionsLookupEntityRequest) GetScope() map[string]*StringArrayValue { + if x != nil { + return x.Scope + } + return nil +} + +func (x *PermissionsLookupEntityRequest) GetPageSize() uint32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *PermissionsLookupEntityRequest) GetContinuousToken() string { + if x != nil { + return x.ContinuousToken + } + return "" +} + // PermissionLookupEntityRequestMetadata metadata for the PermissionLookupEntityRequest. type PermissionLookupEntityRequestMetadata struct { state protoimpl.MessageState @@ -642,7 +766,7 @@ type PermissionLookupEntityRequestMetadata struct { func (x *PermissionLookupEntityRequestMetadata) Reset() { *x = PermissionLookupEntityRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[8] + mi := &file_base_v1_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -655,7 +779,7 @@ func (x *PermissionLookupEntityRequestMetadata) String() string { func (*PermissionLookupEntityRequestMetadata) ProtoMessage() {} func (x *PermissionLookupEntityRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[8] + mi := &file_base_v1_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -668,7 +792,7 @@ func (x *PermissionLookupEntityRequestMetadata) ProtoReflect() protoreflect.Mess // Deprecated: Use PermissionLookupEntityRequestMetadata.ProtoReflect.Descriptor instead. func (*PermissionLookupEntityRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{8} + return file_base_v1_service_proto_rawDescGZIP(), []int{9} } func (x *PermissionLookupEntityRequestMetadata) GetSchemaVersion() string { @@ -707,7 +831,7 @@ type PermissionLookupEntityResponse struct { func (x *PermissionLookupEntityResponse) Reset() { *x = PermissionLookupEntityResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[9] + mi := &file_base_v1_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -720,7 +844,7 @@ func (x *PermissionLookupEntityResponse) String() string { func (*PermissionLookupEntityResponse) ProtoMessage() {} func (x *PermissionLookupEntityResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[9] + mi := &file_base_v1_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -733,7 +857,7 @@ func (x *PermissionLookupEntityResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PermissionLookupEntityResponse.ProtoReflect.Descriptor instead. func (*PermissionLookupEntityResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{9} + return file_base_v1_service_proto_rawDescGZIP(), []int{10} } func (x *PermissionLookupEntityResponse) GetEntityIds() []string { @@ -750,35 +874,35 @@ func (x *PermissionLookupEntityResponse) GetContinuousToken() string { return "" } -// PermissionLookupEntityStreamResponse is the response message for the LookupEntityStream method in the Permission service. -type PermissionLookupEntityStreamResponse struct { +// PermissionLookupEntityResponse is the response message for the LookupEntity method in the Permission service. +type PermissionsLookupEntityResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Identifier for an entity that matches the lookup. - EntityId string `protobuf:"bytes,1,opt,name=entity_id,proto3" json:"entity_id,omitempty"` + // List of identifiers for entities that match the lookup. + EntityIds map[string]*EntityIds `protobuf:"bytes,1,rep,name=entity_ids,proto3" json:"entity_ids,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // continuous_token is a string that can be used to paginate and retrieve the next set of results. ContinuousToken string `protobuf:"bytes,2,opt,name=continuous_token,proto3" json:"continuous_token,omitempty"` } -func (x *PermissionLookupEntityStreamResponse) Reset() { - *x = PermissionLookupEntityStreamResponse{} +func (x *PermissionsLookupEntityResponse) Reset() { + *x = PermissionsLookupEntityResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[10] + mi := &file_base_v1_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PermissionLookupEntityStreamResponse) String() string { +func (x *PermissionsLookupEntityResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PermissionLookupEntityStreamResponse) ProtoMessage() {} +func (*PermissionsLookupEntityResponse) ProtoMessage() {} -func (x *PermissionLookupEntityStreamResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[10] +func (x *PermissionsLookupEntityResponse) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -789,66 +913,51 @@ func (x *PermissionLookupEntityStreamResponse) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use PermissionLookupEntityStreamResponse.ProtoReflect.Descriptor instead. -func (*PermissionLookupEntityStreamResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{10} +// Deprecated: Use PermissionsLookupEntityResponse.ProtoReflect.Descriptor instead. +func (*PermissionsLookupEntityResponse) Descriptor() ([]byte, []int) { + return file_base_v1_service_proto_rawDescGZIP(), []int{11} } -func (x *PermissionLookupEntityStreamResponse) GetEntityId() string { +func (x *PermissionsLookupEntityResponse) GetEntityIds() map[string]*EntityIds { if x != nil { - return x.EntityId + return x.EntityIds } - return "" + return nil } -func (x *PermissionLookupEntityStreamResponse) GetContinuousToken() string { +func (x *PermissionsLookupEntityResponse) GetContinuousToken() string { if x != nil { return x.ContinuousToken } return "" } -// PermissionEntityFilterRequest is the request message for the LookupEntityStream method in the Permission service. -type PermissionEntityFilterRequest struct { +type EntityIds struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. - TenantId string `protobuf:"bytes,1,opt,name=tenant_id,proto3" json:"tenant_id,omitempty"` - // Metadata associated with this request, required. - Metadata *PermissionEntityFilterRequestMetadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` - // Reference to the entity to filter. - Entrance *Entrance `protobuf:"bytes,3,opt,name=entrance,proto3" json:"entrance,omitempty"` - // Subject for which to check the permission. - Subject *Subject `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - // Context associated with this request. - Context *Context `protobuf:"bytes,5,opt,name=context,proto3" json:"context,omitempty"` - // Scope: A map that associates entity types with lists of identifiers. Each entry - // helps filter requests by specifying which entities are relevant to the operation. - Scope map[string]*StringArrayValue `protobuf:"bytes,6,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // cursor is an optional parameter used for pagination. - // It should be the value received in the previous response. - Cursor string `protobuf:"bytes,7,opt,name=cursor,proto3" json:"cursor,omitempty"` + // entitiy Ids + Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` } -func (x *PermissionEntityFilterRequest) Reset() { - *x = PermissionEntityFilterRequest{} +func (x *EntityIds) Reset() { + *x = EntityIds{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[11] + mi := &file_base_v1_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PermissionEntityFilterRequest) String() string { +func (x *EntityIds) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PermissionEntityFilterRequest) ProtoMessage() {} +func (*EntityIds) ProtoMessage() {} -func (x *PermissionEntityFilterRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[11] +func (x *EntityIds) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -859,91 +968,278 @@ func (x *PermissionEntityFilterRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PermissionEntityFilterRequest.ProtoReflect.Descriptor instead. -func (*PermissionEntityFilterRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{11} +// Deprecated: Use EntityIds.ProtoReflect.Descriptor instead. +func (*EntityIds) Descriptor() ([]byte, []int) { + return file_base_v1_service_proto_rawDescGZIP(), []int{12} } -func (x *PermissionEntityFilterRequest) GetTenantId() string { +func (x *EntityIds) GetIds() []string { if x != nil { - return x.TenantId + return x.Ids } - return "" + return nil } -func (x *PermissionEntityFilterRequest) GetMetadata() *PermissionEntityFilterRequestMetadata { - if x != nil { - return x.Metadata - } - return nil +// PermissionLookupEntityStreamResponse is the response message for the LookupEntityStream method in the Permission service. +type PermissionLookupEntityStreamResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Identifier for an entity that matches the lookup. + EntityId string `protobuf:"bytes,1,opt,name=entity_id,proto3" json:"entity_id,omitempty"` + // continuous_token is a string that can be used to paginate and retrieve the next set of results. + ContinuousToken string `protobuf:"bytes,2,opt,name=continuous_token,proto3" json:"continuous_token,omitempty"` } -func (x *PermissionEntityFilterRequest) GetEntrance() *Entrance { - if x != nil { - return x.Entrance +func (x *PermissionLookupEntityStreamResponse) Reset() { + *x = PermissionLookupEntityStreamResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_base_v1_service_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -func (x *PermissionEntityFilterRequest) GetSubject() *Subject { - if x != nil { - return x.Subject - } - return nil +func (x *PermissionLookupEntityStreamResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *PermissionEntityFilterRequest) GetContext() *Context { - if x != nil { - return x.Context +func (*PermissionLookupEntityStreamResponse) ProtoMessage() {} + +func (x *PermissionLookupEntityStreamResponse) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *PermissionEntityFilterRequest) GetScope() map[string]*StringArrayValue { +// Deprecated: Use PermissionLookupEntityStreamResponse.ProtoReflect.Descriptor instead. +func (*PermissionLookupEntityStreamResponse) Descriptor() ([]byte, []int) { + return file_base_v1_service_proto_rawDescGZIP(), []int{13} +} + +func (x *PermissionLookupEntityStreamResponse) GetEntityId() string { if x != nil { - return x.Scope + return x.EntityId } - return nil + return "" } -func (x *PermissionEntityFilterRequest) GetCursor() string { +func (x *PermissionLookupEntityStreamResponse) GetContinuousToken() string { if x != nil { - return x.Cursor + return x.ContinuousToken } return "" } -// PermissionEntityFilterRequestMetadata metadata for the PermissionEntityFilterRequest. -type PermissionEntityFilterRequestMetadata struct { +type PermissionsLookupEntityStreamResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Version of the schema. - SchemaVersion string `protobuf:"bytes,1,opt,name=schema_version,proto3" json:"schema_version,omitempty"` - // Token associated with the snap. - SnapToken string `protobuf:"bytes,2,opt,name=snap_token,proto3" json:"snap_token,omitempty"` - // Depth of lookup, required, must be greater or equal to 3. - Depth int32 `protobuf:"varint,3,opt,name=depth,proto3" json:"depth,omitempty"` + // Identifier for an entity that matches the lookup. + EntityId string `protobuf:"bytes,1,opt,name=entity_id,proto3" json:"entity_id,omitempty"` + // The name of the permission for which the specified entity_id has access + Permission string `protobuf:"bytes,2,opt,name=permission,proto3" json:"permission,omitempty"` + // continuous_token is a string that can be used to paginate and retrieve the next set of results. + ContinuousToken string `protobuf:"bytes,3,opt,name=continuous_token,proto3" json:"continuous_token,omitempty"` } -func (x *PermissionEntityFilterRequestMetadata) Reset() { - *x = PermissionEntityFilterRequestMetadata{} +func (x *PermissionsLookupEntityStreamResponse) Reset() { + *x = PermissionsLookupEntityStreamResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[12] + mi := &file_base_v1_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PermissionEntityFilterRequestMetadata) String() string { +func (x *PermissionsLookupEntityStreamResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PermissionEntityFilterRequestMetadata) ProtoMessage() {} +func (*PermissionsLookupEntityStreamResponse) ProtoMessage() {} -func (x *PermissionEntityFilterRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[12] +func (x *PermissionsLookupEntityStreamResponse) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionsLookupEntityStreamResponse.ProtoReflect.Descriptor instead. +func (*PermissionsLookupEntityStreamResponse) Descriptor() ([]byte, []int) { + return file_base_v1_service_proto_rawDescGZIP(), []int{14} +} + +func (x *PermissionsLookupEntityStreamResponse) GetEntityId() string { + if x != nil { + return x.EntityId + } + return "" +} + +func (x *PermissionsLookupEntityStreamResponse) GetPermission() string { + if x != nil { + return x.Permission + } + return "" +} + +func (x *PermissionsLookupEntityStreamResponse) GetContinuousToken() string { + if x != nil { + return x.ContinuousToken + } + return "" +} + +// PermissionEntityFilterRequest is the request message for the LookupEntityStream method in the Permission service. +type PermissionEntityFilterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,proto3" json:"tenant_id,omitempty"` + // Metadata associated with this request, required. + Metadata *PermissionEntityFilterRequestMetadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` + // Reference to the entity to filter. + Entrances []*Entrance `protobuf:"bytes,3,rep,name=entrances,proto3" json:"entrances,omitempty"` + // Subject for which to check the permission. + Subject *Subject `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` + // Context associated with this request. + Context *Context `protobuf:"bytes,5,opt,name=context,proto3" json:"context,omitempty"` + // Scope: A map that associates entity types with lists of identifiers. Each entry + // helps filter requests by specifying which entities are relevant to the operation. + Scope map[string]*StringArrayValue `protobuf:"bytes,6,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // cursor is an optional parameter used for pagination. + // It should be the value received in the previous response. + Cursor string `protobuf:"bytes,7,opt,name=cursor,proto3" json:"cursor,omitempty"` +} + +func (x *PermissionEntityFilterRequest) Reset() { + *x = PermissionEntityFilterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_base_v1_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PermissionEntityFilterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionEntityFilterRequest) ProtoMessage() {} + +func (x *PermissionEntityFilterRequest) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionEntityFilterRequest.ProtoReflect.Descriptor instead. +func (*PermissionEntityFilterRequest) Descriptor() ([]byte, []int) { + return file_base_v1_service_proto_rawDescGZIP(), []int{15} +} + +func (x *PermissionEntityFilterRequest) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *PermissionEntityFilterRequest) GetMetadata() *PermissionEntityFilterRequestMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *PermissionEntityFilterRequest) GetEntrances() []*Entrance { + if x != nil { + return x.Entrances + } + return nil +} + +func (x *PermissionEntityFilterRequest) GetSubject() *Subject { + if x != nil { + return x.Subject + } + return nil +} + +func (x *PermissionEntityFilterRequest) GetContext() *Context { + if x != nil { + return x.Context + } + return nil +} + +func (x *PermissionEntityFilterRequest) GetScope() map[string]*StringArrayValue { + if x != nil { + return x.Scope + } + return nil +} + +func (x *PermissionEntityFilterRequest) GetCursor() string { + if x != nil { + return x.Cursor + } + return "" +} + +// PermissionEntityFilterRequestMetadata metadata for the PermissionEntityFilterRequest. +type PermissionEntityFilterRequestMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Version of the schema. + SchemaVersion string `protobuf:"bytes,1,opt,name=schema_version,proto3" json:"schema_version,omitempty"` + // Token associated with the snap. + SnapToken string `protobuf:"bytes,2,opt,name=snap_token,proto3" json:"snap_token,omitempty"` + // Depth of lookup, required, must be greater or equal to 3. + Depth int32 `protobuf:"varint,3,opt,name=depth,proto3" json:"depth,omitempty"` +} + +func (x *PermissionEntityFilterRequestMetadata) Reset() { + *x = PermissionEntityFilterRequestMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_base_v1_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PermissionEntityFilterRequestMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionEntityFilterRequestMetadata) ProtoMessage() {} + +func (x *PermissionEntityFilterRequestMetadata) ProtoReflect() protoreflect.Message { + mi := &file_base_v1_service_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -956,7 +1252,7 @@ func (x *PermissionEntityFilterRequestMetadata) ProtoReflect() protoreflect.Mess // Deprecated: Use PermissionEntityFilterRequestMetadata.ProtoReflect.Descriptor instead. func (*PermissionEntityFilterRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{12} + return file_base_v1_service_proto_rawDescGZIP(), []int{16} } func (x *PermissionEntityFilterRequestMetadata) GetSchemaVersion() string { @@ -1009,7 +1305,7 @@ type PermissionLookupSubjectRequest struct { func (x *PermissionLookupSubjectRequest) Reset() { *x = PermissionLookupSubjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[13] + mi := &file_base_v1_service_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1022,7 +1318,7 @@ func (x *PermissionLookupSubjectRequest) String() string { func (*PermissionLookupSubjectRequest) ProtoMessage() {} func (x *PermissionLookupSubjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[13] + mi := &file_base_v1_service_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1035,7 +1331,7 @@ func (x *PermissionLookupSubjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PermissionLookupSubjectRequest.ProtoReflect.Descriptor instead. func (*PermissionLookupSubjectRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{13} + return file_base_v1_service_proto_rawDescGZIP(), []int{17} } func (x *PermissionLookupSubjectRequest) GetTenantId() string { @@ -1111,7 +1407,7 @@ type PermissionLookupSubjectRequestMetadata struct { func (x *PermissionLookupSubjectRequestMetadata) Reset() { *x = PermissionLookupSubjectRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[14] + mi := &file_base_v1_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1124,7 +1420,7 @@ func (x *PermissionLookupSubjectRequestMetadata) String() string { func (*PermissionLookupSubjectRequestMetadata) ProtoMessage() {} func (x *PermissionLookupSubjectRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[14] + mi := &file_base_v1_service_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1137,7 +1433,7 @@ func (x *PermissionLookupSubjectRequestMetadata) ProtoReflect() protoreflect.Mes // Deprecated: Use PermissionLookupSubjectRequestMetadata.ProtoReflect.Descriptor instead. func (*PermissionLookupSubjectRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{14} + return file_base_v1_service_proto_rawDescGZIP(), []int{18} } func (x *PermissionLookupSubjectRequestMetadata) GetSchemaVersion() string { @@ -1176,7 +1472,7 @@ type PermissionLookupSubjectResponse struct { func (x *PermissionLookupSubjectResponse) Reset() { *x = PermissionLookupSubjectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[15] + mi := &file_base_v1_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1189,7 +1485,7 @@ func (x *PermissionLookupSubjectResponse) String() string { func (*PermissionLookupSubjectResponse) ProtoMessage() {} func (x *PermissionLookupSubjectResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[15] + mi := &file_base_v1_service_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1202,7 +1498,7 @@ func (x *PermissionLookupSubjectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PermissionLookupSubjectResponse.ProtoReflect.Descriptor instead. func (*PermissionLookupSubjectResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{15} + return file_base_v1_service_proto_rawDescGZIP(), []int{19} } func (x *PermissionLookupSubjectResponse) GetSubjectIds() []string { @@ -1240,7 +1536,7 @@ type PermissionSubjectPermissionRequest struct { func (x *PermissionSubjectPermissionRequest) Reset() { *x = PermissionSubjectPermissionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[16] + mi := &file_base_v1_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1253,7 +1549,7 @@ func (x *PermissionSubjectPermissionRequest) String() string { func (*PermissionSubjectPermissionRequest) ProtoMessage() {} func (x *PermissionSubjectPermissionRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[16] + mi := &file_base_v1_service_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1266,7 +1562,7 @@ func (x *PermissionSubjectPermissionRequest) ProtoReflect() protoreflect.Message // Deprecated: Use PermissionSubjectPermissionRequest.ProtoReflect.Descriptor instead. func (*PermissionSubjectPermissionRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{16} + return file_base_v1_service_proto_rawDescGZIP(), []int{20} } func (x *PermissionSubjectPermissionRequest) GetTenantId() string { @@ -1323,7 +1619,7 @@ type PermissionSubjectPermissionRequestMetadata struct { func (x *PermissionSubjectPermissionRequestMetadata) Reset() { *x = PermissionSubjectPermissionRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[17] + mi := &file_base_v1_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1336,7 +1632,7 @@ func (x *PermissionSubjectPermissionRequestMetadata) String() string { func (*PermissionSubjectPermissionRequestMetadata) ProtoMessage() {} func (x *PermissionSubjectPermissionRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[17] + mi := &file_base_v1_service_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1349,7 +1645,7 @@ func (x *PermissionSubjectPermissionRequestMetadata) ProtoReflect() protoreflect // Deprecated: Use PermissionSubjectPermissionRequestMetadata.ProtoReflect.Descriptor instead. func (*PermissionSubjectPermissionRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{17} + return file_base_v1_service_proto_rawDescGZIP(), []int{21} } func (x *PermissionSubjectPermissionRequestMetadata) GetSchemaVersion() string { @@ -1393,7 +1689,7 @@ type PermissionSubjectPermissionResponse struct { func (x *PermissionSubjectPermissionResponse) Reset() { *x = PermissionSubjectPermissionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[18] + mi := &file_base_v1_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1406,7 +1702,7 @@ func (x *PermissionSubjectPermissionResponse) String() string { func (*PermissionSubjectPermissionResponse) ProtoMessage() {} func (x *PermissionSubjectPermissionResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[18] + mi := &file_base_v1_service_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1419,7 +1715,7 @@ func (x *PermissionSubjectPermissionResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use PermissionSubjectPermissionResponse.ProtoReflect.Descriptor instead. func (*PermissionSubjectPermissionResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{18} + return file_base_v1_service_proto_rawDescGZIP(), []int{22} } func (x *PermissionSubjectPermissionResponse) GetResults() map[string]CheckResult { @@ -1445,7 +1741,7 @@ type WatchRequest struct { func (x *WatchRequest) Reset() { *x = WatchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[19] + mi := &file_base_v1_service_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1458,7 +1754,7 @@ func (x *WatchRequest) String() string { func (*WatchRequest) ProtoMessage() {} func (x *WatchRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[19] + mi := &file_base_v1_service_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1471,7 +1767,7 @@ func (x *WatchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchRequest.ProtoReflect.Descriptor instead. func (*WatchRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{19} + return file_base_v1_service_proto_rawDescGZIP(), []int{23} } func (x *WatchRequest) GetTenantId() string { @@ -1502,7 +1798,7 @@ type WatchResponse struct { func (x *WatchResponse) Reset() { *x = WatchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[20] + mi := &file_base_v1_service_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1515,7 +1811,7 @@ func (x *WatchResponse) String() string { func (*WatchResponse) ProtoMessage() {} func (x *WatchResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[20] + mi := &file_base_v1_service_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1528,7 +1824,7 @@ func (x *WatchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchResponse.ProtoReflect.Descriptor instead. func (*WatchResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{20} + return file_base_v1_service_proto_rawDescGZIP(), []int{24} } func (x *WatchResponse) GetChanges() *DataChanges { @@ -1555,7 +1851,7 @@ type SchemaWriteRequest struct { func (x *SchemaWriteRequest) Reset() { *x = SchemaWriteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[21] + mi := &file_base_v1_service_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1568,7 +1864,7 @@ func (x *SchemaWriteRequest) String() string { func (*SchemaWriteRequest) ProtoMessage() {} func (x *SchemaWriteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[21] + mi := &file_base_v1_service_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1581,7 +1877,7 @@ func (x *SchemaWriteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaWriteRequest.ProtoReflect.Descriptor instead. func (*SchemaWriteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{21} + return file_base_v1_service_proto_rawDescGZIP(), []int{25} } func (x *SchemaWriteRequest) GetTenantId() string { @@ -1612,7 +1908,7 @@ type SchemaWriteResponse struct { func (x *SchemaWriteResponse) Reset() { *x = SchemaWriteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[22] + mi := &file_base_v1_service_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1625,7 +1921,7 @@ func (x *SchemaWriteResponse) String() string { func (*SchemaWriteResponse) ProtoMessage() {} func (x *SchemaWriteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[22] + mi := &file_base_v1_service_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1638,7 +1934,7 @@ func (x *SchemaWriteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaWriteResponse.ProtoReflect.Descriptor instead. func (*SchemaWriteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{22} + return file_base_v1_service_proto_rawDescGZIP(), []int{26} } func (x *SchemaWriteResponse) GetSchemaVersion() string { @@ -1667,7 +1963,7 @@ type SchemaPartialWriteRequest struct { func (x *SchemaPartialWriteRequest) Reset() { *x = SchemaPartialWriteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[23] + mi := &file_base_v1_service_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1680,7 +1976,7 @@ func (x *SchemaPartialWriteRequest) String() string { func (*SchemaPartialWriteRequest) ProtoMessage() {} func (x *SchemaPartialWriteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[23] + mi := &file_base_v1_service_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1693,7 +1989,7 @@ func (x *SchemaPartialWriteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaPartialWriteRequest.ProtoReflect.Descriptor instead. func (*SchemaPartialWriteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{23} + return file_base_v1_service_proto_rawDescGZIP(), []int{27} } func (x *SchemaPartialWriteRequest) GetTenantId() string { @@ -1731,7 +2027,7 @@ type SchemaPartialWriteRequestMetadata struct { func (x *SchemaPartialWriteRequestMetadata) Reset() { *x = SchemaPartialWriteRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[24] + mi := &file_base_v1_service_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1744,7 +2040,7 @@ func (x *SchemaPartialWriteRequestMetadata) String() string { func (*SchemaPartialWriteRequestMetadata) ProtoMessage() {} func (x *SchemaPartialWriteRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[24] + mi := &file_base_v1_service_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1757,7 +2053,7 @@ func (x *SchemaPartialWriteRequestMetadata) ProtoReflect() protoreflect.Message // Deprecated: Use SchemaPartialWriteRequestMetadata.ProtoReflect.Descriptor instead. func (*SchemaPartialWriteRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{24} + return file_base_v1_service_proto_rawDescGZIP(), []int{28} } func (x *SchemaPartialWriteRequestMetadata) GetSchemaVersion() string { @@ -1781,7 +2077,7 @@ type SchemaPartialWriteResponse struct { func (x *SchemaPartialWriteResponse) Reset() { *x = SchemaPartialWriteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[25] + mi := &file_base_v1_service_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1794,7 +2090,7 @@ func (x *SchemaPartialWriteResponse) String() string { func (*SchemaPartialWriteResponse) ProtoMessage() {} func (x *SchemaPartialWriteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[25] + mi := &file_base_v1_service_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1807,7 +2103,7 @@ func (x *SchemaPartialWriteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaPartialWriteResponse.ProtoReflect.Descriptor instead. func (*SchemaPartialWriteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{25} + return file_base_v1_service_proto_rawDescGZIP(), []int{29} } func (x *SchemaPartialWriteResponse) GetSchemaVersion() string { @@ -1834,7 +2130,7 @@ type SchemaReadRequest struct { func (x *SchemaReadRequest) Reset() { *x = SchemaReadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[26] + mi := &file_base_v1_service_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1847,7 +2143,7 @@ func (x *SchemaReadRequest) String() string { func (*SchemaReadRequest) ProtoMessage() {} func (x *SchemaReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[26] + mi := &file_base_v1_service_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1860,7 +2156,7 @@ func (x *SchemaReadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaReadRequest.ProtoReflect.Descriptor instead. func (*SchemaReadRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{26} + return file_base_v1_service_proto_rawDescGZIP(), []int{30} } func (x *SchemaReadRequest) GetTenantId() string { @@ -1891,7 +2187,7 @@ type SchemaReadRequestMetadata struct { func (x *SchemaReadRequestMetadata) Reset() { *x = SchemaReadRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[27] + mi := &file_base_v1_service_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1904,7 +2200,7 @@ func (x *SchemaReadRequestMetadata) String() string { func (*SchemaReadRequestMetadata) ProtoMessage() {} func (x *SchemaReadRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[27] + mi := &file_base_v1_service_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1917,7 +2213,7 @@ func (x *SchemaReadRequestMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaReadRequestMetadata.ProtoReflect.Descriptor instead. func (*SchemaReadRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{27} + return file_base_v1_service_proto_rawDescGZIP(), []int{31} } func (x *SchemaReadRequestMetadata) GetSchemaVersion() string { @@ -1941,7 +2237,7 @@ type SchemaReadResponse struct { func (x *SchemaReadResponse) Reset() { *x = SchemaReadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[28] + mi := &file_base_v1_service_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1954,7 +2250,7 @@ func (x *SchemaReadResponse) String() string { func (*SchemaReadResponse) ProtoMessage() {} func (x *SchemaReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[28] + mi := &file_base_v1_service_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1967,7 +2263,7 @@ func (x *SchemaReadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaReadResponse.ProtoReflect.Descriptor instead. func (*SchemaReadResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{28} + return file_base_v1_service_proto_rawDescGZIP(), []int{32} } func (x *SchemaReadResponse) GetSchema() *SchemaDefinition { @@ -1998,7 +2294,7 @@ type SchemaListRequest struct { func (x *SchemaListRequest) Reset() { *x = SchemaListRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[29] + mi := &file_base_v1_service_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2011,7 +2307,7 @@ func (x *SchemaListRequest) String() string { func (*SchemaListRequest) ProtoMessage() {} func (x *SchemaListRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[29] + mi := &file_base_v1_service_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2024,7 +2320,7 @@ func (x *SchemaListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaListRequest.ProtoReflect.Descriptor instead. func (*SchemaListRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{29} + return file_base_v1_service_proto_rawDescGZIP(), []int{33} } func (x *SchemaListRequest) GetTenantId() string { @@ -2066,7 +2362,7 @@ type SchemaListResponse struct { func (x *SchemaListResponse) Reset() { *x = SchemaListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[30] + mi := &file_base_v1_service_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2079,7 +2375,7 @@ func (x *SchemaListResponse) String() string { func (*SchemaListResponse) ProtoMessage() {} func (x *SchemaListResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[30] + mi := &file_base_v1_service_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2092,7 +2388,7 @@ func (x *SchemaListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaListResponse.ProtoReflect.Descriptor instead. func (*SchemaListResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{30} + return file_base_v1_service_proto_rawDescGZIP(), []int{34} } func (x *SchemaListResponse) GetHead() string { @@ -2129,7 +2425,7 @@ type SchemaList struct { func (x *SchemaList) Reset() { *x = SchemaList{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[31] + mi := &file_base_v1_service_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2142,7 +2438,7 @@ func (x *SchemaList) String() string { func (*SchemaList) ProtoMessage() {} func (x *SchemaList) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[31] + mi := &file_base_v1_service_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2155,7 +2451,7 @@ func (x *SchemaList) ProtoReflect() protoreflect.Message { // Deprecated: Use SchemaList.ProtoReflect.Descriptor instead. func (*SchemaList) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{31} + return file_base_v1_service_proto_rawDescGZIP(), []int{35} } func (x *SchemaList) GetVersion() string { @@ -2193,7 +2489,7 @@ type DataWriteRequest struct { func (x *DataWriteRequest) Reset() { *x = DataWriteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[32] + mi := &file_base_v1_service_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2206,7 +2502,7 @@ func (x *DataWriteRequest) String() string { func (*DataWriteRequest) ProtoMessage() {} func (x *DataWriteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[32] + mi := &file_base_v1_service_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2219,7 +2515,7 @@ func (x *DataWriteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DataWriteRequest.ProtoReflect.Descriptor instead. func (*DataWriteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{32} + return file_base_v1_service_proto_rawDescGZIP(), []int{36} } func (x *DataWriteRequest) GetTenantId() string { @@ -2264,7 +2560,7 @@ type DataWriteRequestMetadata struct { func (x *DataWriteRequestMetadata) Reset() { *x = DataWriteRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[33] + mi := &file_base_v1_service_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2277,7 +2573,7 @@ func (x *DataWriteRequestMetadata) String() string { func (*DataWriteRequestMetadata) ProtoMessage() {} func (x *DataWriteRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[33] + mi := &file_base_v1_service_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2290,7 +2586,7 @@ func (x *DataWriteRequestMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use DataWriteRequestMetadata.ProtoReflect.Descriptor instead. func (*DataWriteRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{33} + return file_base_v1_service_proto_rawDescGZIP(), []int{37} } func (x *DataWriteRequestMetadata) GetSchemaVersion() string { @@ -2314,7 +2610,7 @@ type DataWriteResponse struct { func (x *DataWriteResponse) Reset() { *x = DataWriteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[34] + mi := &file_base_v1_service_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2327,7 +2623,7 @@ func (x *DataWriteResponse) String() string { func (*DataWriteResponse) ProtoMessage() {} func (x *DataWriteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[34] + mi := &file_base_v1_service_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2340,7 +2636,7 @@ func (x *DataWriteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DataWriteResponse.ProtoReflect.Descriptor instead. func (*DataWriteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{34} + return file_base_v1_service_proto_rawDescGZIP(), []int{38} } func (x *DataWriteResponse) GetSnapToken() string { @@ -2367,7 +2663,7 @@ type RelationshipWriteRequest struct { func (x *RelationshipWriteRequest) Reset() { *x = RelationshipWriteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[35] + mi := &file_base_v1_service_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2380,7 +2676,7 @@ func (x *RelationshipWriteRequest) String() string { func (*RelationshipWriteRequest) ProtoMessage() {} func (x *RelationshipWriteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[35] + mi := &file_base_v1_service_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2393,7 +2689,7 @@ func (x *RelationshipWriteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipWriteRequest.ProtoReflect.Descriptor instead. func (*RelationshipWriteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{35} + return file_base_v1_service_proto_rawDescGZIP(), []int{39} } func (x *RelationshipWriteRequest) GetTenantId() string { @@ -2429,7 +2725,7 @@ type RelationshipWriteRequestMetadata struct { func (x *RelationshipWriteRequestMetadata) Reset() { *x = RelationshipWriteRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[36] + mi := &file_base_v1_service_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2442,7 +2738,7 @@ func (x *RelationshipWriteRequestMetadata) String() string { func (*RelationshipWriteRequestMetadata) ProtoMessage() {} func (x *RelationshipWriteRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[36] + mi := &file_base_v1_service_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2455,7 +2751,7 @@ func (x *RelationshipWriteRequestMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipWriteRequestMetadata.ProtoReflect.Descriptor instead. func (*RelationshipWriteRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{36} + return file_base_v1_service_proto_rawDescGZIP(), []int{40} } func (x *RelationshipWriteRequestMetadata) GetSchemaVersion() string { @@ -2477,7 +2773,7 @@ type RelationshipWriteResponse struct { func (x *RelationshipWriteResponse) Reset() { *x = RelationshipWriteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[37] + mi := &file_base_v1_service_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2490,7 +2786,7 @@ func (x *RelationshipWriteResponse) String() string { func (*RelationshipWriteResponse) ProtoMessage() {} func (x *RelationshipWriteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[37] + mi := &file_base_v1_service_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2503,7 +2799,7 @@ func (x *RelationshipWriteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipWriteResponse.ProtoReflect.Descriptor instead. func (*RelationshipWriteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{37} + return file_base_v1_service_proto_rawDescGZIP(), []int{41} } func (x *RelationshipWriteResponse) GetSnapToken() string { @@ -2536,7 +2832,7 @@ type RelationshipReadRequest struct { func (x *RelationshipReadRequest) Reset() { *x = RelationshipReadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[38] + mi := &file_base_v1_service_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2549,7 +2845,7 @@ func (x *RelationshipReadRequest) String() string { func (*RelationshipReadRequest) ProtoMessage() {} func (x *RelationshipReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[38] + mi := &file_base_v1_service_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2562,7 +2858,7 @@ func (x *RelationshipReadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipReadRequest.ProtoReflect.Descriptor instead. func (*RelationshipReadRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{38} + return file_base_v1_service_proto_rawDescGZIP(), []int{42} } func (x *RelationshipReadRequest) GetTenantId() string { @@ -2614,7 +2910,7 @@ type RelationshipReadRequestMetadata struct { func (x *RelationshipReadRequestMetadata) Reset() { *x = RelationshipReadRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[39] + mi := &file_base_v1_service_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2627,7 +2923,7 @@ func (x *RelationshipReadRequestMetadata) String() string { func (*RelationshipReadRequestMetadata) ProtoMessage() {} func (x *RelationshipReadRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[39] + mi := &file_base_v1_service_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2640,7 +2936,7 @@ func (x *RelationshipReadRequestMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipReadRequestMetadata.ProtoReflect.Descriptor instead. func (*RelationshipReadRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{39} + return file_base_v1_service_proto_rawDescGZIP(), []int{43} } func (x *RelationshipReadRequestMetadata) GetSnapToken() string { @@ -2666,7 +2962,7 @@ type RelationshipReadResponse struct { func (x *RelationshipReadResponse) Reset() { *x = RelationshipReadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[40] + mi := &file_base_v1_service_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2679,7 +2975,7 @@ func (x *RelationshipReadResponse) String() string { func (*RelationshipReadResponse) ProtoMessage() {} func (x *RelationshipReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[40] + mi := &file_base_v1_service_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2692,7 +2988,7 @@ func (x *RelationshipReadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipReadResponse.ProtoReflect.Descriptor instead. func (*RelationshipReadResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{40} + return file_base_v1_service_proto_rawDescGZIP(), []int{44} } func (x *RelationshipReadResponse) GetTuples() []*Tuple { @@ -2732,7 +3028,7 @@ type AttributeReadRequest struct { func (x *AttributeReadRequest) Reset() { *x = AttributeReadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[41] + mi := &file_base_v1_service_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2745,7 +3041,7 @@ func (x *AttributeReadRequest) String() string { func (*AttributeReadRequest) ProtoMessage() {} func (x *AttributeReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[41] + mi := &file_base_v1_service_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2758,7 +3054,7 @@ func (x *AttributeReadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeReadRequest.ProtoReflect.Descriptor instead. func (*AttributeReadRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{41} + return file_base_v1_service_proto_rawDescGZIP(), []int{45} } func (x *AttributeReadRequest) GetTenantId() string { @@ -2810,7 +3106,7 @@ type AttributeReadRequestMetadata struct { func (x *AttributeReadRequestMetadata) Reset() { *x = AttributeReadRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[42] + mi := &file_base_v1_service_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2823,7 +3119,7 @@ func (x *AttributeReadRequestMetadata) String() string { func (*AttributeReadRequestMetadata) ProtoMessage() {} func (x *AttributeReadRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[42] + mi := &file_base_v1_service_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2836,7 +3132,7 @@ func (x *AttributeReadRequestMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeReadRequestMetadata.ProtoReflect.Descriptor instead. func (*AttributeReadRequestMetadata) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{42} + return file_base_v1_service_proto_rawDescGZIP(), []int{46} } func (x *AttributeReadRequestMetadata) GetSnapToken() string { @@ -2862,7 +3158,7 @@ type AttributeReadResponse struct { func (x *AttributeReadResponse) Reset() { *x = AttributeReadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[43] + mi := &file_base_v1_service_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2875,7 +3171,7 @@ func (x *AttributeReadResponse) String() string { func (*AttributeReadResponse) ProtoMessage() {} func (x *AttributeReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[43] + mi := &file_base_v1_service_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2888,7 +3184,7 @@ func (x *AttributeReadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeReadResponse.ProtoReflect.Descriptor instead. func (*AttributeReadResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{43} + return file_base_v1_service_proto_rawDescGZIP(), []int{47} } func (x *AttributeReadResponse) GetAttributes() []*Attribute { @@ -2923,7 +3219,7 @@ type DataDeleteRequest struct { func (x *DataDeleteRequest) Reset() { *x = DataDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[44] + mi := &file_base_v1_service_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2936,7 +3232,7 @@ func (x *DataDeleteRequest) String() string { func (*DataDeleteRequest) ProtoMessage() {} func (x *DataDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[44] + mi := &file_base_v1_service_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2949,7 +3245,7 @@ func (x *DataDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DataDeleteRequest.ProtoReflect.Descriptor instead. func (*DataDeleteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{44} + return file_base_v1_service_proto_rawDescGZIP(), []int{48} } func (x *DataDeleteRequest) GetTenantId() string { @@ -2987,7 +3283,7 @@ type DataDeleteResponse struct { func (x *DataDeleteResponse) Reset() { *x = DataDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[45] + mi := &file_base_v1_service_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3000,7 +3296,7 @@ func (x *DataDeleteResponse) String() string { func (*DataDeleteResponse) ProtoMessage() {} func (x *DataDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[45] + mi := &file_base_v1_service_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3013,7 +3309,7 @@ func (x *DataDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DataDeleteResponse.ProtoReflect.Descriptor instead. func (*DataDeleteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{45} + return file_base_v1_service_proto_rawDescGZIP(), []int{49} } func (x *DataDeleteResponse) GetSnapToken() string { @@ -3036,7 +3332,7 @@ type RelationshipDeleteRequest struct { func (x *RelationshipDeleteRequest) Reset() { *x = RelationshipDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[46] + mi := &file_base_v1_service_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3049,7 +3345,7 @@ func (x *RelationshipDeleteRequest) String() string { func (*RelationshipDeleteRequest) ProtoMessage() {} func (x *RelationshipDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[46] + mi := &file_base_v1_service_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3062,7 +3358,7 @@ func (x *RelationshipDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipDeleteRequest.ProtoReflect.Descriptor instead. func (*RelationshipDeleteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{46} + return file_base_v1_service_proto_rawDescGZIP(), []int{50} } func (x *RelationshipDeleteRequest) GetTenantId() string { @@ -3091,7 +3387,7 @@ type RelationshipDeleteResponse struct { func (x *RelationshipDeleteResponse) Reset() { *x = RelationshipDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[47] + mi := &file_base_v1_service_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3104,7 +3400,7 @@ func (x *RelationshipDeleteResponse) String() string { func (*RelationshipDeleteResponse) ProtoMessage() {} func (x *RelationshipDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[47] + mi := &file_base_v1_service_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3117,7 +3413,7 @@ func (x *RelationshipDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RelationshipDeleteResponse.ProtoReflect.Descriptor instead. func (*RelationshipDeleteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{47} + return file_base_v1_service_proto_rawDescGZIP(), []int{51} } func (x *RelationshipDeleteResponse) GetSnapToken() string { @@ -3144,7 +3440,7 @@ type BundleRunRequest struct { func (x *BundleRunRequest) Reset() { *x = BundleRunRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[48] + mi := &file_base_v1_service_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3157,7 +3453,7 @@ func (x *BundleRunRequest) String() string { func (*BundleRunRequest) ProtoMessage() {} func (x *BundleRunRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[48] + mi := &file_base_v1_service_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3170,7 +3466,7 @@ func (x *BundleRunRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleRunRequest.ProtoReflect.Descriptor instead. func (*BundleRunRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{48} + return file_base_v1_service_proto_rawDescGZIP(), []int{52} } func (x *BundleRunRequest) GetTenantId() string { @@ -3207,7 +3503,7 @@ type BundleRunResponse struct { func (x *BundleRunResponse) Reset() { *x = BundleRunResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[49] + mi := &file_base_v1_service_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3220,7 +3516,7 @@ func (x *BundleRunResponse) String() string { func (*BundleRunResponse) ProtoMessage() {} func (x *BundleRunResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[49] + mi := &file_base_v1_service_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3233,7 +3529,7 @@ func (x *BundleRunResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleRunResponse.ProtoReflect.Descriptor instead. func (*BundleRunResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{49} + return file_base_v1_service_proto_rawDescGZIP(), []int{53} } func (x *BundleRunResponse) GetSnapToken() string { @@ -3257,7 +3553,7 @@ type BundleWriteRequest struct { func (x *BundleWriteRequest) Reset() { *x = BundleWriteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[50] + mi := &file_base_v1_service_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3270,7 +3566,7 @@ func (x *BundleWriteRequest) String() string { func (*BundleWriteRequest) ProtoMessage() {} func (x *BundleWriteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[50] + mi := &file_base_v1_service_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3283,7 +3579,7 @@ func (x *BundleWriteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleWriteRequest.ProtoReflect.Descriptor instead. func (*BundleWriteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{50} + return file_base_v1_service_proto_rawDescGZIP(), []int{54} } func (x *BundleWriteRequest) GetTenantId() string { @@ -3313,7 +3609,7 @@ type BundleWriteResponse struct { func (x *BundleWriteResponse) Reset() { *x = BundleWriteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[51] + mi := &file_base_v1_service_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3326,7 +3622,7 @@ func (x *BundleWriteResponse) String() string { func (*BundleWriteResponse) ProtoMessage() {} func (x *BundleWriteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[51] + mi := &file_base_v1_service_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3339,7 +3635,7 @@ func (x *BundleWriteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleWriteResponse.ProtoReflect.Descriptor instead. func (*BundleWriteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{51} + return file_base_v1_service_proto_rawDescGZIP(), []int{55} } func (x *BundleWriteResponse) GetNames() []string { @@ -3361,7 +3657,7 @@ type BundleReadRequest struct { func (x *BundleReadRequest) Reset() { *x = BundleReadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[52] + mi := &file_base_v1_service_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3374,7 +3670,7 @@ func (x *BundleReadRequest) String() string { func (*BundleReadRequest) ProtoMessage() {} func (x *BundleReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[52] + mi := &file_base_v1_service_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3387,7 +3683,7 @@ func (x *BundleReadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleReadRequest.ProtoReflect.Descriptor instead. func (*BundleReadRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{52} + return file_base_v1_service_proto_rawDescGZIP(), []int{56} } func (x *BundleReadRequest) GetTenantId() string { @@ -3415,7 +3711,7 @@ type BundleReadResponse struct { func (x *BundleReadResponse) Reset() { *x = BundleReadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[53] + mi := &file_base_v1_service_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3428,7 +3724,7 @@ func (x *BundleReadResponse) String() string { func (*BundleReadResponse) ProtoMessage() {} func (x *BundleReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[53] + mi := &file_base_v1_service_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3441,7 +3737,7 @@ func (x *BundleReadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleReadResponse.ProtoReflect.Descriptor instead. func (*BundleReadResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{53} + return file_base_v1_service_proto_rawDescGZIP(), []int{57} } func (x *BundleReadResponse) GetBundle() *DataBundle { @@ -3465,7 +3761,7 @@ type BundleDeleteRequest struct { func (x *BundleDeleteRequest) Reset() { *x = BundleDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[54] + mi := &file_base_v1_service_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3478,7 +3774,7 @@ func (x *BundleDeleteRequest) String() string { func (*BundleDeleteRequest) ProtoMessage() {} func (x *BundleDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[54] + mi := &file_base_v1_service_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3491,7 +3787,7 @@ func (x *BundleDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleDeleteRequest.ProtoReflect.Descriptor instead. func (*BundleDeleteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{54} + return file_base_v1_service_proto_rawDescGZIP(), []int{58} } func (x *BundleDeleteRequest) GetTenantId() string { @@ -3519,7 +3815,7 @@ type BundleDeleteResponse struct { func (x *BundleDeleteResponse) Reset() { *x = BundleDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[55] + mi := &file_base_v1_service_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3532,7 +3828,7 @@ func (x *BundleDeleteResponse) String() string { func (*BundleDeleteResponse) ProtoMessage() {} func (x *BundleDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[55] + mi := &file_base_v1_service_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3545,7 +3841,7 @@ func (x *BundleDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BundleDeleteResponse.ProtoReflect.Descriptor instead. func (*BundleDeleteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{55} + return file_base_v1_service_proto_rawDescGZIP(), []int{59} } func (x *BundleDeleteResponse) GetName() string { @@ -3570,7 +3866,7 @@ type TenantCreateRequest struct { func (x *TenantCreateRequest) Reset() { *x = TenantCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[56] + mi := &file_base_v1_service_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3583,7 +3879,7 @@ func (x *TenantCreateRequest) String() string { func (*TenantCreateRequest) ProtoMessage() {} func (x *TenantCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[56] + mi := &file_base_v1_service_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3596,7 +3892,7 @@ func (x *TenantCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TenantCreateRequest.ProtoReflect.Descriptor instead. func (*TenantCreateRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{56} + return file_base_v1_service_proto_rawDescGZIP(), []int{60} } func (x *TenantCreateRequest) GetId() string { @@ -3626,7 +3922,7 @@ type TenantCreateResponse struct { func (x *TenantCreateResponse) Reset() { *x = TenantCreateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[57] + mi := &file_base_v1_service_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3639,7 +3935,7 @@ func (x *TenantCreateResponse) String() string { func (*TenantCreateResponse) ProtoMessage() {} func (x *TenantCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[57] + mi := &file_base_v1_service_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3652,7 +3948,7 @@ func (x *TenantCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TenantCreateResponse.ProtoReflect.Descriptor instead. func (*TenantCreateResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{57} + return file_base_v1_service_proto_rawDescGZIP(), []int{61} } func (x *TenantCreateResponse) GetTenant() *Tenant { @@ -3675,7 +3971,7 @@ type TenantDeleteRequest struct { func (x *TenantDeleteRequest) Reset() { *x = TenantDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[58] + mi := &file_base_v1_service_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3688,7 +3984,7 @@ func (x *TenantDeleteRequest) String() string { func (*TenantDeleteRequest) ProtoMessage() {} func (x *TenantDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[58] + mi := &file_base_v1_service_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3701,7 +3997,7 @@ func (x *TenantDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TenantDeleteRequest.ProtoReflect.Descriptor instead. func (*TenantDeleteRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{58} + return file_base_v1_service_proto_rawDescGZIP(), []int{62} } func (x *TenantDeleteRequest) GetId() string { @@ -3724,7 +4020,7 @@ type TenantDeleteResponse struct { func (x *TenantDeleteResponse) Reset() { *x = TenantDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[59] + mi := &file_base_v1_service_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3737,7 +4033,7 @@ func (x *TenantDeleteResponse) String() string { func (*TenantDeleteResponse) ProtoMessage() {} func (x *TenantDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[59] + mi := &file_base_v1_service_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3750,7 +4046,7 @@ func (x *TenantDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TenantDeleteResponse.ProtoReflect.Descriptor instead. func (*TenantDeleteResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{59} + return file_base_v1_service_proto_rawDescGZIP(), []int{63} } func (x *TenantDeleteResponse) GetTenant() *Tenant { @@ -3777,7 +4073,7 @@ type TenantListRequest struct { func (x *TenantListRequest) Reset() { *x = TenantListRequest{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[60] + mi := &file_base_v1_service_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3790,7 +4086,7 @@ func (x *TenantListRequest) String() string { func (*TenantListRequest) ProtoMessage() {} func (x *TenantListRequest) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[60] + mi := &file_base_v1_service_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3803,7 +4099,7 @@ func (x *TenantListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TenantListRequest.ProtoReflect.Descriptor instead. func (*TenantListRequest) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{60} + return file_base_v1_service_proto_rawDescGZIP(), []int{64} } func (x *TenantListRequest) GetPageSize() uint32 { @@ -3835,7 +4131,7 @@ type TenantListResponse struct { func (x *TenantListResponse) Reset() { *x = TenantListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_base_v1_service_proto_msgTypes[61] + mi := &file_base_v1_service_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3848,7 +4144,7 @@ func (x *TenantListResponse) String() string { func (*TenantListResponse) ProtoMessage() {} func (x *TenantListResponse) ProtoReflect() protoreflect.Message { - mi := &file_base_v1_service_proto_msgTypes[61] + mi := &file_base_v1_service_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3861,7 +4157,7 @@ func (x *TenantListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TenantListResponse.ProtoReflect.Descriptor instead. func (*TenantListResponse) Descriptor() ([]byte, []int) { - return file_base_v1_service_proto_rawDescGZIP(), []int{61} + return file_base_v1_service_proto_rawDescGZIP(), []int{65} } func (x *TenantListResponse) GetTenants() []*Tenant { @@ -4091,288 +4387,194 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbb, 0x02, 0x0a, 0x25, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, - 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, - 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, - 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, - 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, - 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, - 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, - 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x66, - 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, 0x74, 0x20, - 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x03, 0x52, - 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x6c, 0x0a, 0x1e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, - 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x70, 0x0a, 0x24, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, - 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xe9, 0x05, 0x0a, 0x1d, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, - 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, - 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, - 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, - 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, - 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, - 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, - 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, - 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, - 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, - 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x54, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, - 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x08, 0x65, - 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x63, 0x65, - 0x52, 0x08, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x07, 0x0a, 0x1e, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, + 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, + 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, + 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, + 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, + 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x54, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, + 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, + 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x1d, 0xfa, 0x42, 0x1a, 0x72, 0x18, 0x28, 0x40, 0x32, 0x11, 0x5e, 0x5b, + 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x5f, 0x5d, 0x7b, 0x31, 0x2c, 0x36, 0x34, 0x7d, 0x24, 0xd0, + 0x01, 0x00, 0x52, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x4f, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x42, 0x2d, 0xfa, 0x42, 0x2a, 0x92, 0x01, 0x27, 0x08, 0x01, 0x10, 0x64, + 0x22, 0x21, 0x72, 0x1f, 0x28, 0x40, 0x32, 0x18, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x5f, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5d, 0x2a, 0x24, + 0xd0, 0x01, 0x00, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x34, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x31, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x06, 0x63, - 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, - 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x1a, 0x53, 0x0a, - 0x0a, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, - 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0xbb, 0x02, 0x0a, 0x25, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, - 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, - 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, - 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, - 0x42, 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, - 0x73, 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, - 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, - 0x70, 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, - 0x22, 0xf5, 0x05, 0x0a, 0x1e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, - 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, - 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, - 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, - 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, - 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, - 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, - 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, - 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, - 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, - 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, - 0x10, 0x01, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, - 0xfa, 0x42, 0x1a, 0x72, 0x18, 0x28, 0x40, 0x32, 0x11, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, - 0x5a, 0x5f, 0x5d, 0x7b, 0x31, 0x2c, 0x36, 0x34, 0x7d, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x0a, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x11, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, - 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, - 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, - 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, - 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xbc, 0x02, 0x0a, 0x26, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, - 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, - 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, - 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, - 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, - 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, - 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, - 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, - 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, - 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, 0x74, - 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x03, - 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x6f, 0x0a, 0x1f, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, + 0x78, 0x74, 0x12, 0x48, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x32, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x27, 0x0a, 0x09, + 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x42, + 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x53, 0x0a, 0x0a, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xbb, 0x02, 0x0a, 0x25, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, + 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, + 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x47, + 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, + 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, + 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, + 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x6c, + 0x0a, 0x1e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, + 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf8, 0x01, 0x0a, + 0x1f, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x57, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x50, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, + 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1d, 0x0a, 0x09, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x64, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x70, 0x0a, 0x24, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, - 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc1, 0x04, 0x0a, 0x22, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, - 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, - 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, - 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, - 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, - 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, - 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, - 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, - 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, - 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x59, 0x0a, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, - 0x10, 0x01, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x12, 0x2a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xea, 0x02, 0x0a, - 0x2a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, - 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, - 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, - 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x12, 0x28, 0x0a, 0x0f, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, - 0x70, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42, 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, - 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, - 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, - 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0xcc, 0x01, 0x0a, 0x23, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x53, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc8, 0x03, 0x0a, 0x0c, 0x57, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, - 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, - 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, - 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, - 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, - 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, - 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, - 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, - 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, - 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, - 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, - 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, - 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0x3f, 0x0a, 0x0d, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x61, 0x74, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x22, 0xd9, 0x02, 0x0a, 0x12, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, + 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x91, 0x01, 0x0a, 0x25, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, + 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xeb, 0x05, 0x0a, + 0x1d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, + 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, + 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, + 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, + 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, + 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, + 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, + 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, + 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x54, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x2f, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2a, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x06, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x1a, 0x53, 0x0a, 0x0a, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbb, 0x02, 0x0a, 0x25, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, + 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, + 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, + 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, + 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, + 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, + 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, + 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, + 0x69, 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, + 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, + 0x03, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0xf5, 0x05, 0x0a, 0x1e, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, @@ -4391,262 +4593,343 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x22, 0x3d, 0x0a, 0x13, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0xd9, 0x02, 0x0a, 0x19, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, - 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, - 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, - 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, - 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, - 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x50, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, - 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, - 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c, 0x0a, - 0x08, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x30, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x08, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x1a, 0x4e, 0x0a, 0x0d, 0x50, - 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x21, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x44, 0x0a, 0x1a, 0x53, 0x63, 0x68, 0x65, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, + 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x31, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, 0xfa, 0x42, 0x1a, 0x72, 0x18, 0x28, 0x40, 0x32, + 0x11, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x5f, 0x5d, 0x7b, 0x31, 0x2c, 0x36, 0x34, + 0x7d, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x52, 0x0a, 0x11, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x11, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0xbc, 0x02, 0x0a, 0x26, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, + 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, + 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, + 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, + 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, + 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, + 0x6f, 0x0a, 0x1f, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, + 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0xc1, 0x04, 0x0a, 0x22, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, + 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, + 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, + 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, + 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, + 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, + 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, + 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, + 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, + 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x12, 0x59, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, + 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x31, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, + 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x22, 0xea, 0x02, 0x0a, 0x2a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01, 0x0a, 0x0a, + 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, + 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, + 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, + 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, + 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, + 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, + 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x6f, 0x6e, 0x6c, 0x79, + 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0f, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x5d, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x05, 0x42, 0x47, 0x92, 0x41, 0x3d, 0x32, 0x3b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x63, 0x75, + 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x20, 0x71, + 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, + 0x6f, 0x70, 0x2e, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x22, 0xcc, 0x01, 0x0a, 0x23, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x50, + 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x14, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xc8, 0x03, 0x0a, 0x0c, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, + 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, + 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, + 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, + 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, + 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, + 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, + 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, + 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x8a, + 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, + 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, + 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, + 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, + 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, + 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, + 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3f, 0x0a, 0x0d, 0x57, + 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0xd9, 0x02, 0x0a, + 0x12, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, + 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, + 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, + 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, + 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, + 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, + 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, + 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x3d, 0x0a, 0x13, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd9, 0x02, 0x0a, 0x19, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8a, - 0x03, 0x0a, 0x11, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, - 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, - 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, - 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, - 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, - 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, - 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, - 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, - 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, - 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, - 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, - 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, - 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, - 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, - 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x43, 0x0a, 0x19, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, + 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, + 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x12, 0x50, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x61, 0x6c, 0x73, 0x1a, 0x4e, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x21, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x47, 0x0a, 0x12, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, - 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, - 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, - 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, - 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, - 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, - 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, - 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, - 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, - 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x09, - 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, - 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, - 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x12, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x07, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x22, 0x44, 0x0a, 0x1a, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, + 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, + 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8a, 0x03, 0x0a, 0x11, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, + 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, + 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, + 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, + 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, + 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, + 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, + 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, + 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, + 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x43, 0x0a, 0x19, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0x0a, 0x12, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, + 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x44, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, + 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, + 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, + 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, + 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, + 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, + 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, + 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, + 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, + 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, + 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0x46, 0x0a, 0x0a, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x22, 0x8a, 0x04, 0x0a, 0x10, 0x44, 0x61, - 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, - 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, - 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, - 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, - 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, - 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, - 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, - 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, - 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, - 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, - 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x47, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, - 0x75, 0x70, 0x6c, 0x65, 0x42, 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, 0x0b, 0x08, 0x00, 0x10, 0x64, - 0x22, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x12, - 0x45, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x42, 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, 0x0b, 0x08, - 0x00, 0x10, 0x64, 0x22, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x42, 0x0a, 0x18, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, - 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa0, 0x01, 0x0a, 0x11, 0x44, - 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, - 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, - 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, - 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd3, 0x03, - 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, - 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, - 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, - 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, - 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, - 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, - 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, - 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, - 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, - 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, - 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x4f, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x06, 0x74, 0x75, 0x70, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x42, 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, 0x0b, - 0x08, 0x01, 0x10, 0x64, 0x22, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x74, 0x75, 0x70, - 0x6c, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0xa7, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, - 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, - 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, - 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, - 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, - 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, - 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, - 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xad, 0x04, 0x0a, 0x17, 0x52, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, - 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, - 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, - 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, - 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, - 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, - 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, - 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, - 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, - 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, - 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, - 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, - 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x36, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, - 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, - 0x10, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, - 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x1f, 0x52, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x89, 0x01, - 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, - 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, - 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, - 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, - 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, - 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, - 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x6e, 0x0a, 0x18, 0x52, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x75, 0x70, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, + 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x12, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, + 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x2d, + 0x0a, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xab, 0x04, 0x0a, 0x14, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x46, 0x0a, 0x0a, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x22, 0x8a, 0x04, 0x0a, 0x10, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, + 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, + 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, + 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, + 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, + 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, + 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, + 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, + 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x06, + 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x42, 0x11, 0xfa, 0x42, + 0x0e, 0x92, 0x01, 0x0b, 0x08, 0x00, 0x10, 0x64, 0x22, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, + 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x42, + 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, 0x0b, 0x08, 0x00, 0x10, 0x64, 0x22, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x42, + 0x0a, 0x18, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x22, 0xa0, 0x01, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, + 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x6a, 0x92, + 0x41, 0x67, 0x32, 0x65, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, + 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, + 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, + 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, + 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, + 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x2e, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd3, 0x03, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, @@ -4666,504 +4949,702 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, - 0x4b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, - 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3a, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, - 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, - 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, - 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xaa, 0x01, 0x0a, 0x1c, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, - 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, - 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, - 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, - 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, - 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, - 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, - 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x77, 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, - 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, - 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd4, 0x03, - 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, - 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, - 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, - 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, - 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, - 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, - 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, - 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, - 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, - 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, - 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x12, 0x42, 0x0a, 0x0c, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, - 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, - 0x10, 0x01, 0x52, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x22, 0xa0, 0x01, 0x0a, 0x12, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x0a, - 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, - 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, - 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, - 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, - 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, - 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, - 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf6, 0x02, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, - 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, - 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, - 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, - 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, - 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, - 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, - 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, - 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, - 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, - 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, - 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, - 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x22, 0xa8, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, - 0x70, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, - 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, - 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, - 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, - 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd9, 0x03, 0x0a, 0x10, - 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, - 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, - 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, - 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, - 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, - 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, - 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, - 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, - 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x46, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, - 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x01, 0x0a, 0x11, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, - 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, - 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, - 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, - 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, - 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, - 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, - 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf0, 0x02, 0x0a, 0x12, 0x42, 0x75, - 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, - 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, - 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, - 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, - 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, - 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, - 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, - 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, - 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x2d, 0x0a, - 0x07, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x42, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x52, 0x07, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x2b, 0x0a, 0x13, - 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xd4, 0x02, 0x0a, 0x11, 0x42, 0x75, - 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, - 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, - 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, - 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, - 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, - 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, - 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, - 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, - 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, - 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x41, 0x0a, 0x12, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x61, 0x74, 0x61, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x06, 0x62, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x22, 0xd6, 0x02, 0x0a, 0x13, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, - 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, - 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, - 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, + 0x4f, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x29, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, + 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x39, 0x0a, 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, + 0x42, 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, 0x0b, 0x08, 0x01, 0x10, 0x64, 0x22, 0x05, 0x8a, 0x01, + 0x02, 0x10, 0x01, 0x52, 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x20, 0x52, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, + 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0xad, 0x04, 0x0a, 0x17, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, + 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, + 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, + 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, + 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, + 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, + 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, + 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, + 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, + 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, + 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x1f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, + 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, + 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0x6e, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, + 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, + 0x06, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x52, 0x06, 0x74, + 0x75, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0xab, 0x04, 0x0a, 0x14, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, + 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, + 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, + 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, + 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, + 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, + 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, + 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, + 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x4b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, + 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, + 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, + 0xaa, 0x01, 0x0a, 0x1c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, + 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, + 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, + 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, + 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x77, 0x0a, 0x15, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd4, 0x03, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, + 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2a, 0x0a, 0x14, - 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x61, 0x0a, 0x13, 0x54, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0xfa, 0x42, 0x17, - 0x72, 0x15, 0x28, 0x40, 0x32, 0x0e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x2d, 0x2c, 0x5d, 0x2b, 0xd0, 0x01, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x72, 0x05, - 0x28, 0x40, 0xd0, 0x01, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3f, 0x0a, 0x14, 0x54, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x22, 0x2f, 0x0a, 0x13, - 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x00, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3f, 0x0a, - 0x14, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x22, 0x72, - 0x0a, 0x11, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, - 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, - 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, - 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x22, 0x6b, 0x0a, 0x12, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x52, 0x07, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, - 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, - 0x93, 0x4c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0xe8, - 0x0d, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x0d, 0x92, 0x41, - 0xe3, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x09, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x61, 0x70, 0x69, 0x2a, 0x11, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6a, 0xb6, 0x0c, 0x0a, - 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xa4, - 0x0c, 0x32, 0xa1, 0x0c, 0x0a, 0xc0, 0x04, 0x2a, 0xbd, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, - 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x9d, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x92, 0x04, 0x1a, 0x8f, 0x04, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, - 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, - 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, - 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, - 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, - 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, - 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, - 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, - 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, - 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, - 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, - 0x29, 0x0a, 0x69, 0x66, 0x20, 0x63, 0x72, 0x2e, 0x43, 0x61, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x76, - 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, - 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x0a, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, - 0x45, 0x4e, 0x49, 0x45, 0x44, 0x0a, 0x7d, 0x0a, 0x9b, 0x04, 0x2a, 0x98, 0x04, 0x0a, 0x0f, 0x0a, - 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, - 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x0a, 0xee, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0xe3, 0x03, 0x1a, 0xe0, 0x03, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x28, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, - 0x22, 0x2c, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, - 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, - 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, - 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x63, 0x61, 0x6e, 0x20, - 0x3d, 0x3d, 0x3d, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x2e, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, - 0x44, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, - 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, - 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x52, 0x45, 0x53, - 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x0a, 0xbd, 0x03, 0x2a, 0xba, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, - 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x96, 0x03, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x8b, 0x03, 0x1a, 0x88, 0x03, 0x63, 0x75, 0x72, - 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, - 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, - 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, - 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, - 0x30, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, - 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, - 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0xb4, 0x09, 0x0a, 0x06, 0x45, 0x78, - 0x70, 0x61, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe4, 0x08, 0x92, 0x41, 0xab, 0x08, - 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x65, 0x78, - 0x70, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x69, 0x2a, 0x12, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x6a, 0xfc, 0x07, 0x0a, - 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xea, - 0x07, 0x32, 0xe7, 0x07, 0x0a, 0xee, 0x02, 0x2a, 0xeb, 0x02, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, - 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xcb, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0xc0, 0x02, 0x1a, 0xbd, 0x02, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, - 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x28, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x0c, 0x74, 0x75, 0x70, 0x6c, + 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, + 0x74, 0x75, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x10, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0xa0, 0x01, 0x0a, + 0x12, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, 0x64, 0x54, + 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x63, + 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, + 0xf6, 0x02, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, + 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, + 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, + 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, + 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, + 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, + 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, + 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0xa8, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, + 0x66, 0x32, 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, + 0x20, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, + 0x70, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0xd9, 0x03, 0x0a, 0x10, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, + 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, + 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, + 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, + 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, + 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, + 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, + 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, + 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, + 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, + 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x9f, 0x01, 0x0a, 0x11, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0x92, 0x41, 0x66, 0x32, + 0x64, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x20, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x5b, 0x53, 0x6e, 0x61, 0x70, 0x20, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5d, 0x28, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2d, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x29, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0xf0, 0x02, 0x0a, 0x12, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, + 0x41, 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, + 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x63, 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, + 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, + 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, + 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x2e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, + 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, + 0x61, 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, + 0x29, 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, + 0x2d, 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, + 0x38, 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x07, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x73, 0x22, 0x2b, 0x0a, 0x13, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x22, 0xd4, 0x02, 0x0a, 0x11, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, + 0xd9, 0x01, 0x32, 0xd6, 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, + 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x79, 0x20, 0x28, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, + 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, + 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x20, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, + 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, + 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, + 0x78, 0x20, 0x36, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, + 0x28, 0x80, 0x01, 0x32, 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5f, 0x5c, 0x2d, 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, + 0x7d, 0x7c, 0x5c, 0x2a, 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x41, 0x0a, 0x12, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, + 0x0a, 0x06, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x52, 0x06, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x22, 0xd6, 0x02, 0x0a, 0x13, + 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0xaa, 0x02, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02, 0x92, 0x41, 0xd9, 0x01, 0x32, 0xd6, + 0x01, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x2d, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x68, + 0x61, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x29, 0x20, 0x75, 0x73, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x20, 0x3c, 0x63, 0x6f, + 0x64, 0x65, 0x3e, 0x74, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x20, 0x5c, 0xe2, 0x80, 0x9c, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x2d, 0x2c, 0x5d, 0x2b, 0x5c, 0xe2, 0x80, 0x9c, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x36, 0x34, + 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0xfa, 0x42, 0x2b, 0x72, 0x29, 0x28, 0x80, 0x01, 0x32, + 0x21, 0x5e, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x5c, 0x2d, + 0x40, 0x5c, 0x2e, 0x3a, 0x2b, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x32, 0x38, 0x7d, 0x7c, 0x5c, 0x2a, + 0x29, 0x24, 0xd0, 0x01, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x61, 0x0a, 0x13, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x1a, 0xfa, 0x42, 0x17, 0x72, 0x15, 0x28, 0x40, 0x32, 0x0e, 0x5b, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x2c, 0x5d, 0x2b, 0xd0, 0x01, 0x00, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x72, 0x05, 0x28, 0x40, 0xd0, 0x01, 0x00, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x3f, 0x0a, 0x14, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x22, 0x2f, 0x0a, 0x13, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, + 0x00, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3f, 0x0a, 0x14, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, + 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x52, 0x06, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x22, 0x72, 0x0a, 0x11, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x09, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, + 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x01, 0x40, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, + 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, + 0xfa, 0x42, 0x05, 0x72, 0x03, 0xd0, 0x01, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, + 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x6b, 0x0a, 0x12, 0x54, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x29, 0x0a, 0x07, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x52, 0x07, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, + 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xf2, 0x66, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0xe8, 0x0d, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x1f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x0d, 0x92, 0x41, 0xe3, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x61, 0x70, + 0x69, 0x2a, 0x11, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x6a, 0xb6, 0x0c, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xa4, 0x0c, 0x32, 0xa1, 0x0c, 0x0a, 0xc0, 0x04, 0x2a, + 0xbd, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, + 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, + 0x9d, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x92, 0x04, 0x1a, 0x8f, 0x04, + 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, + 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x69, 0x66, 0x20, 0x63, 0x72, 0x2e, + 0x43, 0x61, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x5f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, + 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, + 0x20, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x0a, + 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x0a, 0x7d, 0x0a, + 0x9b, 0x04, 0x2a, 0x98, 0x04, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, + 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, + 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xee, 0x03, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xe3, 0x03, 0x1a, 0xe0, 0x03, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, + 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, + 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x63, 0x61, 0x6e, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x52, 0x45, 0x53, 0x55, 0x4c, + 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, + 0x28, 0x22, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, + 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, + 0x45, 0x44, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x0a, 0xbd, 0x03, + 0x2a, 0xba, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, + 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, + 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x96, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x8b, 0x03, 0x1a, 0x88, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, + 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, + 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x27, 0x20, 0x5c, 0x0a, + 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, + 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, + 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, + 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x12, 0xb4, 0x09, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xe4, 0x08, 0x92, 0x41, 0xab, 0x08, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x69, + 0x2a, 0x12, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x78, + 0x70, 0x61, 0x6e, 0x64, 0x6a, 0xfc, 0x07, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xea, 0x07, 0x32, 0xe7, 0x07, 0x0a, 0xee, 0x02, 0x2a, + 0xeb, 0x02, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, + 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, + 0xcb, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc0, 0x02, 0x1a, 0xbd, 0x02, + 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x78, 0x70, + 0x61, 0x6e, 0x64, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x8d, 0x02, + 0x2a, 0x8a, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, + 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xe0, 0x01, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xd5, 0x01, 0x1a, 0xd2, 0x01, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x65, 0x78, 0x70, + 0x61, 0x6e, 0x64, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xe3, 0x02, + 0x2a, 0xe0, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, + 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, + 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xbc, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0xb1, 0x02, 0x1a, 0xae, 0x02, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, + 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, + 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x27, 0x20, 0x5c, + 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, + 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, + 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x12, 0xb2, 0x0c, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x26, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, + 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x0b, 0x92, 0x41, 0x90, + 0x0b, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x6c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2a, 0x18, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x6a, 0xd8, 0x0a, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, + 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc6, 0x0a, 0x32, 0xc3, 0x0a, 0x0a, 0xd5, + 0x03, 0x2a, 0xd2, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, + 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, + 0x6f, 0x0a, 0xb2, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xa7, 0x03, 0x1a, + 0xa4, 0x03, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, - 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, - 0x78, 0x70, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, - 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, - 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, - 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x70, 0x75, 0x73, 0x68, - 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x8d, 0x02, 0x2a, 0x8a, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, - 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x0a, 0xe0, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xd5, 0x01, - 0x1a, 0xd2, 0x01, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x28, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, + 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, - 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, - 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x70, 0x75, 0x73, 0x68, - 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xe3, 0x02, 0x2a, 0xe0, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, - 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xbc, 0x02, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb1, 0x02, 0x1a, 0xae, 0x02, 0x63, 0x75, 0x72, - 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, - 0x78, 0x70, 0x61, 0x6e, 0x64, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, - 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, - 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, - 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, - 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0x3a, 0x20, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, + 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, + 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xa7, 0x03, 0x2a, 0xa4, 0x03, 0x0a, 0x0f, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, + 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x0a, 0xfa, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xef, + 0x02, 0x1a, 0xec, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, + 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, + 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, + 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x29, 0x0a, 0x7d, 0x29, + 0x0a, 0xbe, 0x03, 0x2a, 0xbb, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, + 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, + 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x97, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x8c, 0x03, 0x1a, 0x89, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, + 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, - 0x12, 0xb2, 0x0c, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x12, 0x26, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xd0, 0x0b, 0x92, 0x41, 0x90, 0x0b, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x2a, 0x18, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x6a, 0xd8, - 0x0a, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, - 0x12, 0xc6, 0x0a, 0x32, 0xc3, 0x0a, 0x0a, 0xd5, 0x03, 0x2a, 0xd2, 0x03, 0x0a, 0x0d, 0x0a, 0x05, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, - 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xb2, 0x03, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0xa7, 0x03, 0x1a, 0xa4, 0x03, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, - 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, - 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, - 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, - 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, - 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xa7, - 0x03, 0x2a, 0xa4, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, - 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, - 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xfa, 0x02, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xef, 0x02, 0x1a, 0xec, 0x02, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, - 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, + 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, + 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x3a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, + 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, + 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, + 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, + 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x01, 0x2a, 0x22, 0x31, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0xcc, 0x0c, + 0x0a, 0x0e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x27, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xe6, 0x0b, 0x92, 0x41, 0xa4, 0x0b, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2a, 0x1a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x6a, 0xe8, 0x0a, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xd6, 0x0a, 0x32, 0xd3, 0x0a, 0x0a, 0xdb, 0x03, 0x2a, 0xd8, + 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, + 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xb8, + 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xad, 0x03, 0x1a, 0xaa, 0x03, 0x63, + 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, + 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, + 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, + 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x22, 0x65, 0x64, 0x69, + 0x74, 0x22, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, + 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xac, 0x03, 0x2a, 0xa9, 0x03, 0x0a, + 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xff, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0xf4, 0x02, 0x1a, 0xf1, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, + 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, + 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, @@ -5174,827 +5655,923 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x5f, 0x69, 0x64, 0x73, 0x29, 0x0a, 0x7d, 0x29, 0x0a, 0xbe, 0x03, 0x2a, 0xbb, 0x03, 0x0a, 0x0f, + 0x5f, 0x69, 0x64, 0x73, 0x29, 0x0a, 0x7d, 0x29, 0x0a, 0xc3, 0x03, 0x2a, 0xc0, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, - 0x97, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x8c, 0x03, 0x1a, 0x89, 0x03, + 0x9c, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x91, 0x03, 0x1a, 0x8e, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x27, - 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, - 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x7d, 0x2c, - 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x65, - 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, - 0x3a, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x61, 0x67, - 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x22, - 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, - 0x01, 0x2a, 0x22, 0x31, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, - 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0xd0, 0x0d, 0x0a, 0x12, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, - 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x26, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xe0, 0x0c, 0x92, 0x41, 0x99, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, 0x1e, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, - 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x6a, 0xd4, 0x0b, 0x0a, - 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc2, - 0x0b, 0x32, 0xbf, 0x0b, 0x0a, 0xc8, 0x04, 0x2a, 0xc5, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, - 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xa5, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x9a, 0x04, 0x1a, 0x97, 0x04, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, - 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, - 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, - 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x35, 0x30, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3a, 0x20, 0x22, 0x76, 0x69, 0x65, 0x77, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, - 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, - 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, - 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x66, 0x6f, 0x72, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x2e, 0x52, 0x65, 0x63, 0x76, 0x28, 0x29, 0x0a, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x45, - 0x4f, 0x46, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, - 0x61, 0x6b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, - 0x20, 0x72, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x0a, 0x7d, 0x0a, - 0xf1, 0x06, 0x2a, 0xee, 0x06, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, - 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, - 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xc4, 0x06, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb9, 0x06, 0x1a, 0xb6, 0x06, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x7d, 0x20, 0x3d, 0x20, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x64, 0x69, 0x73, - 0x74, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x64, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x65, - 0x77, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6e, - 0x65, 0x77, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x38, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, - 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, - 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, - 0x22, 0x76, 0x69, 0x65, 0x77, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, - 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x29, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x3a, 0x20, - 0x41, 0x73, 0x79, 0x6e, 0x63, 0x49, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x3e, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, - 0x77, 0x61, 0x69, 0x74, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x0a, 0x7d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x3a, 0x01, 0x2a, 0x22, 0x38, 0x2f, 0x76, - 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2d, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0xe3, 0x0d, 0x0a, 0x0d, 0x4c, 0x6f, 0x6f, - 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x27, 0x2e, 0x62, 0x61, 0x73, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x0c, - 0x92, 0x41, 0xbd, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x0e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x2a, 0x19, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6a, 0x83, 0x0c, 0x0a, 0x0d, - 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xf1, 0x0b, - 0x32, 0xee, 0x0b, 0x0a, 0x9f, 0x04, 0x2a, 0x9c, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, + 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, + 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, + 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, + 0x20, 0x5b, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, 0x20, 0x32, 0x30, + 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x27, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x38, 0x3a, 0x01, 0x2a, 0x22, 0x33, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x8d, 0x0e, 0x0a, + 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x27, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x99, + 0x0d, 0x92, 0x41, 0xd0, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x16, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x6a, 0x87, 0x0c, 0x0a, 0x0d, + 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xf5, 0x0b, + 0x32, 0xf2, 0x0b, 0x0a, 0xdf, 0x04, 0x2a, 0xdc, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, - 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xfc, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0xf1, 0x03, 0x1a, 0xee, 0x03, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, - 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, - 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, - 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, - 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x26, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, - 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, 0x65, - 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, - 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, - 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xdc, 0x03, 0x2a, 0xd9, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, + 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xbc, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0xb1, 0x04, 0x1a, 0xae, 0x04, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, + 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, + 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x35, + 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x22, 0x76, 0x69, 0x65, 0x77, 0x22, 0x5d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x0a, 0x66, 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x2c, + 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x2e, 0x52, 0x65, 0x63, 0x76, + 0x28, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x45, 0x4f, 0x46, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x0a, 0x7d, 0x0a, 0x8d, 0x07, 0x2a, 0x8a, 0x07, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x0a, 0xaf, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xa4, 0x03, - 0x1a, 0xa1, 0x03, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, - 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, - 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x70, 0x74, 0x0a, 0xe0, 0x06, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xd5, 0x06, + 0x1a, 0xd2, 0x06, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, + 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, + 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7b, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x7d, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, + 0x6f, 0x64, 0x65, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x67, 0x72, 0x70, + 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x62, 0x61, 0x73, 0x65, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6e, 0x65, 0x77, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x28, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, + 0x34, 0x37, 0x38, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x22, 0x76, 0x69, 0x65, 0x77, + 0x22, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, - 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, - 0x29, 0x0a, 0x7d, 0x29, 0x0a, 0xea, 0x03, 0x2a, 0xe7, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, - 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xc3, 0x03, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb8, 0x03, 0x1a, 0xb5, 0x03, 0x63, 0x75, 0x72, 0x6c, - 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x27, 0x20, 0x5c, 0x0a, - 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, - 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x6e, - 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, - 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, - 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, - 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, - 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, - 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, - 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x3a, 0x01, 0x2a, 0x22, 0x32, 0x2f, 0x76, 0x31, 0x2f, - 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0xf4, - 0x0c, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x83, 0x0c, 0x92, 0x41, 0xbe, 0x0b, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x1d, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6a, 0xfc, 0x0a, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, - 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xea, 0x0a, 0x32, 0xe7, 0x0a, 0x0a, 0xf1, 0x03, - 0x2a, 0xee, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, - 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, - 0x0a, 0xce, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc3, 0x03, 0x1a, 0xc0, - 0x03, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, + 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, + 0x0a, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x41, 0x73, 0x79, 0x6e, + 0x63, 0x49, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3e, + 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x77, 0x61, 0x69, + 0x74, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3f, 0x3a, 0x01, 0x2a, 0x22, 0x3a, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0xd0, 0x0d, 0x0a, + 0x12, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x26, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe0, 0x0c, 0x92, 0x41, 0x99, + 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x6c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x2a, 0x1e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x6a, 0xd4, 0x0b, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc2, 0x0b, 0x32, 0xbf, 0x0b, 0x0a, 0xc8, 0x04, 0x2a, 0xc5, + 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, + 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xa5, + 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x9a, 0x04, 0x1a, 0x97, 0x04, 0x73, + 0x74, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, - 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, + 0x68, 0x3a, 0x20, 0x35, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x76, 0x69, 0x65, 0x77, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, + 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x0a, 0x66, 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, + 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x2e, 0x52, 0x65, 0x63, + 0x76, 0x28, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, + 0x3d, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x45, 0x4f, 0x46, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x49, 0x64, 0x0a, 0x7d, 0x0a, 0xf1, 0x06, 0x2a, 0xee, 0x06, 0x0a, 0x0f, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, + 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x0a, 0xc4, 0x06, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb9, + 0x06, 0x1a, 0xb6, 0x06, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, + 0x79, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, + 0x64, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7b, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x7d, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, + 0x6f, 0x64, 0x65, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x67, 0x72, 0x70, + 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x62, 0x61, 0x73, 0x65, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6e, 0x65, 0x77, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x28, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, + 0x34, 0x37, 0x38, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, - 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, - 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, - 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, - 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, - 0x29, 0x0a, 0x9f, 0x03, 0x2a, 0x9c, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, - 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xf2, - 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xe7, 0x02, 0x1a, 0xe4, 0x02, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, - 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, - 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, - 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, - 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, - 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x3b, - 0x0a, 0x7d, 0x29, 0x0a, 0xce, 0x03, 0x2a, 0xcb, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, - 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xa7, 0x03, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x9c, 0x03, 0x1a, 0x99, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, - 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x27, - 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, - 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, - 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, - 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, - 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, - 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, - 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x3a, 0x01, 0x2a, 0x22, 0x36, 0x2f, - 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x84, 0x08, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, - 0xfa, 0x07, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x15, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbf, 0x07, 0x92, 0x41, 0x93, 0x07, 0x0a, - 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x0d, 0x77, 0x61, 0x74, 0x63, 0x68, 0x20, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2a, 0x0b, 0x77, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x77, 0x61, 0x74, - 0x63, 0x68, 0x6a, 0xed, 0x06, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x73, 0x12, 0xdb, 0x06, 0x32, 0xd8, 0x06, 0x0a, 0x9e, 0x02, 0x2a, 0x9b, 0x02, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, + 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x76, 0x69, 0x65, 0x77, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, + 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x61, 0x73, 0x79, 0x6e, + 0x63, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x28, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x49, 0x74, 0x65, 0x72, + 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3e, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x28, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x72, + 0x65, 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x49, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, + 0x3a, 0x01, 0x2a, 0x22, 0x38, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, + 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, + 0xe3, 0x0d, 0x0a, 0x0d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x27, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x0c, 0x92, 0x41, 0xbd, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2a, 0x19, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x6a, 0x83, 0x0c, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x73, 0x12, 0xf1, 0x0b, 0x32, 0xee, 0x0b, 0x0a, 0x9f, 0x04, 0x2a, 0x9c, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, - 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xfb, 0x01, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xf0, 0x01, 0x1a, 0xed, 0x01, 0x63, 0x72, + 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xfc, 0x03, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xf1, 0x03, 0x1a, 0xee, 0x03, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x57, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x28, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, - 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, - 0x3a, 0x20, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, - 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x2f, - 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x66, 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, - 0x72, 0x2e, 0x52, 0x65, 0x63, 0x76, 0x28, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x45, 0x4f, 0x46, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, - 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x0a, 0x7d, 0x0a, 0x0a, 0xb4, 0x04, 0x2a, 0xb1, - 0x04, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, - 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, - 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x87, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0xfc, 0x03, 0x1a, 0xf9, 0x03, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, - 0x20, 0x7b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x7d, - 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, - 0x65, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, - 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x0a, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2e, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x6e, 0x65, 0x77, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x28, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x3a, 0x20, 0x22, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, - 0x38, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x28, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, - 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, - 0x65, 0x28, 0x72, 0x65, 0x73, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x61, 0x73, 0x79, 0x6e, 0x63, - 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x28, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x49, 0x74, 0x65, 0x72, 0x61, - 0x62, 0x6c, 0x65, 0x3c, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x3e, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x77, - 0x61, 0x69, 0x74, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, - 0x7d, 0x0a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, - 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x32, 0xac, 0x1f, 0x0a, - 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0xd3, 0x10, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x12, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8e, 0x10, 0x92, - 0x41, 0xda, 0x0f, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x0c, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x73, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6a, 0xb2, 0x0f, 0x0a, 0x0d, 0x78, 0x2d, 0x63, - 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xa0, 0x0f, 0x32, 0x9d, 0x0f, - 0x0a, 0xf2, 0x04, 0x2a, 0xef, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, - 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, - 0x02, 0x67, 0x6f, 0x0a, 0xcf, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc4, - 0x04, 0x1a, 0xc1, 0x04, 0x73, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, - 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, - 0x20, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x75, 0x73, - 0x65, 0x72, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, - 0x28, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x20, 0x40, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, - 0x61, 0x64, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x60, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xf3, 0x04, 0x2a, 0xf0, 0x04, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, - 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x0a, 0xc6, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xbb, 0x04, - 0x1a, 0xb8, 0x04, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x20, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, - 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x40, 0x75, - 0x73, 0x65, 0x72, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, - 0x72, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, - 0x3d, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x40, 0x75, - 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x40, 0x6f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, - 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, - 0x3d, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, - 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xaf, 0x05, 0x2a, 0xac, - 0x05, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, + 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, + 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, + 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xdc, 0x03, 0x2a, + 0xd9, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, + 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, + 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xaf, 0x03, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0xa4, 0x03, 0x1a, 0xa1, 0x03, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, + 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, + 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, + 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, 0x30, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, + 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, + 0x6f, 0x67, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x29, 0x0a, 0x7d, 0x29, 0x0a, 0xea, 0x03, 0x2a, 0xe7, + 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, - 0x72, 0x6c, 0x0a, 0x88, 0x05, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xfd, 0x04, - 0x1a, 0xfa, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x72, 0x6c, 0x0a, 0xc3, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb8, 0x03, + 0x1a, 0xb5, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, + 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, + 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, + 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, + 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, + 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x2c, + 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, + 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, + 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x22, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, + 0x65, 0x64, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, + 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x3a, 0x01, + 0x2a, 0x22, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0xf4, 0x0c, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x0c, 0x92, 0x41, 0xbe, 0x0b, 0x0a, 0x0a, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x1d, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6a, 0xfc, 0x0a, 0x0a, + 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xea, + 0x0a, 0x32, 0xe7, 0x0a, 0x0a, 0xf1, 0x03, 0x2a, 0xee, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xce, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0xc3, 0x03, 0x1a, 0xc0, 0x03, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, + 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, + 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, + 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x44, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, + 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, + 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x9f, 0x03, 0x2a, 0x9c, 0x03, 0x0a, 0x0f, + 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, + 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xf2, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0xe7, 0x02, 0x1a, 0xe4, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3a, 0x20, 0x32, + 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, + 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x7d, 0x29, 0x0a, 0xce, 0x03, 0x2a, 0xcb, 0x03, + 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, + 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, + 0x6c, 0x0a, 0xa7, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x9c, 0x03, 0x1a, + 0x99, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, + 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, - 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, - 0x3a, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x7b, - 0x7d, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, - 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x5c, 0x6e, - 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x5c, 0x6e, + 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x3a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x0a, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x3b, 0x3a, 0x01, 0x2a, 0x22, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x2d, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x84, 0x08, 0x0a, + 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0xfa, 0x07, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x12, 0x15, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xbf, 0x07, 0x92, 0x41, 0x93, 0x07, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x0d, 0x77, + 0x61, 0x74, 0x63, 0x68, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2a, 0x0b, 0x77, 0x61, + 0x74, 0x63, 0x68, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x6a, 0xed, 0x06, 0x0a, 0x0d, 0x78, 0x2d, + 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xdb, 0x06, 0x32, 0xd8, + 0x06, 0x0a, 0x9e, 0x02, 0x2a, 0x9b, 0x02, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, + 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xfb, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0xf0, 0x01, 0x1a, 0xed, 0x01, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, + 0x66, 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x65, + 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x72, 0x2e, 0x52, 0x65, 0x63, 0x76, 0x28, 0x29, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x69, + 0x6f, 0x2e, 0x45, 0x4f, 0x46, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x0a, + 0x7d, 0x0a, 0x0a, 0xb4, 0x04, 0x2a, 0xb1, 0x04, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, + 0x87, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xfc, 0x03, 0x1a, 0xf9, 0x03, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x20, 0x3d, 0x20, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, + 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x29, + 0x3b, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x7d, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x28, 0x22, 0x40, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x66, 0x79, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x2f, 0x73, 0x72, + 0x63, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x22, 0x29, 0x3b, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, + 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6e, 0x65, 0x77, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x38, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, + 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x77, + 0x61, 0x74, 0x63, 0x68, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x29, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x41, 0x73, 0x79, + 0x6e, 0x63, 0x49, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3e, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, + 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, + 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, + 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x77, 0x61, 0x74, 0x63, + 0x68, 0x30, 0x01, 0x32, 0xac, 0x1f, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0xd3, + 0x10, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x8e, 0x10, 0x92, 0x41, 0xda, 0x0f, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x12, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x2a, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6a, + 0xb2, 0x0f, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x73, 0x12, 0xa0, 0x0f, 0x32, 0x9d, 0x0f, 0x0a, 0xf2, 0x04, 0x2a, 0xef, 0x04, 0x0a, 0x0d, 0x0a, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, + 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xcf, 0x04, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc4, 0x04, 0x1a, 0xc1, 0x04, 0x73, 0x72, 0x2c, 0x20, 0x65, + 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, + 0x26, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x20, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x40, + 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, + 0x65, 0x72, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, + 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, + 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, + 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x40, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, + 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, + 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xf3, 0x04, 0x2a, + 0xf0, 0x04, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, + 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, + 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xc6, 0x04, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0xbb, 0x04, 0x1a, 0xb8, 0x04, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, + 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x20, + 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x75, 0x73, 0x65, + 0x72, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x5c, 0x6e, 0x5c, - 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x20, 0x7b, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, - 0x40, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x6e, 0x5c, - 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5c, 0x6e, 0x20, 0x20, + 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x28, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x40, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x29, - 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x29, 0x29, 0x5c, 0x6e, 0x20, 0x7d, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, + 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, + 0x7d, 0x29, 0x0a, 0xaf, 0x05, 0x2a, 0xac, 0x05, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x88, 0x05, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0xfd, 0x04, 0x1a, 0xfa, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, + 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0xdf, 0x01, - 0x0a, 0x0c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x22, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, - 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, 0x01, 0x92, 0x41, 0x4a, 0x0a, 0x06, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x29, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, - 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x2a, 0x15, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, - 0x6c, 0x2d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, - 0x32, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x2d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, - 0xf4, 0x06, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xb2, 0x06, 0x92, 0x41, 0xff, 0x05, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x12, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x0c, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x6a, 0xd9, 0x05, 0x0a, 0x0d, - 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc7, 0x05, - 0x32, 0xc4, 0x05, 0x0a, 0xf5, 0x01, 0x2a, 0xf2, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, - 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xd2, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0xc7, 0x01, 0x1a, 0xc4, 0x01, 0x73, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, - 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, - 0x52, 0x65, 0x61, 0x64, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, - 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, - 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x63, 0x6e, 0x62, 0x65, 0x36, - 0x73, 0x65, 0x35, 0x66, 0x6d, 0x61, 0x6c, 0x31, 0x38, 0x67, 0x70, 0x63, 0x36, 0x36, 0x67, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xb6, 0x01, 0x2a, 0xb3, - 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, - 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, - 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x89, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x7f, 0x1a, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, - 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x72, - 0x65, 0x61, 0x64, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, - 0x20, 0x73, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x90, 0x02, 0x2a, 0x8d, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, - 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xe9, 0x01, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xde, 0x01, 0x1a, 0xdb, 0x01, 0x63, 0x75, 0x72, 0x6c, - 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x27, 0x20, - 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, - 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x63, 0x6e, 0x62, 0x65, 0x36, 0x73, 0x65, - 0x35, 0x66, 0x6d, 0x61, 0x6c, 0x31, 0x38, 0x67, 0x70, 0x63, 0x36, 0x36, 0x67, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, - 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x12, 0xf2, 0x05, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x27, 0x20, 0x5c, + 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x7b, 0x7d, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, + 0x40, 0x75, 0x73, 0x65, 0x72, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x40, + 0x75, 0x73, 0x65, 0x72, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x7b, 0x5c, 0x6e, 0x5c, + 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x40, 0x75, 0x73, 0x65, 0x72, 0x5c, 0x6e, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x40, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x6e, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x77, 0x6e, 0x65, + 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, + 0x6d, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x29, 0x5c, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, + 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x29, 0x29, 0x5c, 0x6e, 0x20, 0x7d, + 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, + 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x12, 0xdf, 0x01, 0x0a, 0x0c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, + 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, + 0x01, 0x92, 0x41, 0x4a, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x29, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x79, + 0x6f, 0x75, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2a, 0x15, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, + 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x2d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x32, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x2d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0xf4, 0x06, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb0, 0x05, 0x92, 0x41, 0xfd, 0x04, 0x0a, - 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2e, 0x6c, 0x69, - 0x73, 0x74, 0x6a, 0xd7, 0x04, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc5, 0x04, 0x32, 0xc2, 0x04, 0x0a, 0xbd, 0x01, 0x2a, 0xba, 0x01, + 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb2, 0x06, 0x92, 0x41, 0xff, 0x05, 0x0a, + 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x20, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2e, 0x72, 0x65, + 0x61, 0x64, 0x6a, 0xd9, 0x05, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc7, 0x05, 0x32, 0xc4, 0x05, 0x0a, 0xf5, 0x01, 0x2a, 0xf2, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, - 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x9a, 0x01, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x8f, 0x01, 0x1a, 0x8c, 0x01, 0x73, 0x72, + 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xd2, 0x01, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc7, 0x01, 0x1a, 0xc4, 0x01, 0x73, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x74, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, - 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, + 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x85, 0x01, 0x2a, 0x82, 0x01, - 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, - 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, - 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x59, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x4f, 0x1a, 0x4d, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x6c, 0x69, 0x73, - 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, - 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, - 0x7d, 0x29, 0x0a, 0xf7, 0x01, 0x2a, 0xf4, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, - 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xd0, 0x01, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0xc5, 0x01, 0x1a, 0xc2, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, - 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, - 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x27, 0x20, 0x5c, 0x0a, - 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, - 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, - 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x32, 0xe5, 0x44, 0x0a, 0x04, - 0x44, 0x61, 0x74, 0x61, 0x12, 0xb6, 0x15, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x19, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf5, 0x14, 0x92, 0x41, 0xc4, 0x14, 0x0a, 0x04, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x0a, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6a, 0xa3, 0x14, 0x0a, 0x0d, 0x78, - 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x91, 0x14, 0x32, - 0x8e, 0x14, 0x0a, 0xb6, 0x07, 0x2a, 0xb3, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, - 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x93, 0x07, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x88, 0x07, 0x1a, 0x85, 0x07, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x74, - 0x6f, 0x20, 0x41, 0x6e, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, - 0x3d, 0x20, 0x61, 0x6e, 0x79, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x77, 0x28, 0x26, 0x76, 0x31, 0x2e, - 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x7d, 0x29, - 0x0a, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x7d, 0x0a, 0x0a, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, - 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, - 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, - 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x5b, - 0x5d, 0x2a, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x20, 0x22, 0x31, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2a, - 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, - 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x20, - 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x3a, 0x20, 0x22, 0x69, 0x73, 0x5f, 0x70, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x80, 0x06, 0x2a, 0xfd, - 0x05, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, - 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, - 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xd3, 0x05, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0xc8, 0x05, 0x1a, 0xc5, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x62, - 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x42, 0x6f, - 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x4a, - 0x53, 0x4f, 0x4e, 0x28, 0x7b, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, - 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x20, 0x3d, 0x20, 0x41, 0x6e, 0x79, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x4a, 0x53, 0x4f, 0x4e, - 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c, 0x3a, 0x20, - 0x27, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x6f, - 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x62, 0x6f, 0x6f, 0x6c, 0x65, - 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x2e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x28, - 0x29, 0x0a, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x22, 0x63, 0x6e, 0x62, 0x65, 0x36, 0x73, 0x65, 0x35, 0x66, 0x6d, 0x61, 0x6c, 0x31, 0x38, + 0x67, 0x70, 0x63, 0x36, 0x36, 0x67, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x7d, 0x29, 0x0a, 0xb6, 0x01, 0x2a, 0xb3, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, + 0x89, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x7f, 0x1a, 0x7d, 0x6c, 0x65, + 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x90, 0x02, 0x2a, 0x8d, + 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, + 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, + 0x72, 0x6c, 0x0a, 0xe9, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xde, 0x01, + 0x1a, 0xdb, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, + 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, + 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, + 0x2f, 0x72, 0x65, 0x61, 0x64, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, + 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, + 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, + 0x63, 0x6e, 0x62, 0x65, 0x36, 0x73, 0x65, 0x35, 0x66, 0x6d, 0x61, 0x6c, 0x31, 0x38, 0x67, 0x70, + 0x63, 0x36, 0x36, 0x67, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x12, 0xf2, 0x05, + 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xb0, 0x05, 0x92, 0x41, 0xfd, 0x04, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x0b, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x0c, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x73, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x6a, 0xd7, 0x04, 0x0a, 0x0d, 0x78, 0x2d, + 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xc5, 0x04, 0x32, 0xc2, + 0x04, 0x0a, 0xbd, 0x01, 0x2a, 0xba, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, + 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x9a, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x8f, 0x01, 0x1a, 0x8c, 0x01, 0x73, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, + 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, + 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, + 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, + 0x29, 0x0a, 0x85, 0x01, 0x2a, 0x82, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, + 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x59, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4f, 0x1a, 0x4d, 0x6c, 0x65, 0x74, 0x20, + 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, + 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x0a, 0xf7, 0x01, 0x2a, 0xf4, 0x01, 0x0a, + 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, + 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, + 0x0a, 0xd0, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc5, 0x01, 0x1a, 0xc2, + 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, + 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, + 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x6c, + 0x69, 0x73, 0x74, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, + 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, + 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, + 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, + 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, + 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x2f, 0x6c, 0x69, + 0x73, 0x74, 0x32, 0xe5, 0x44, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0xb6, 0x15, 0x0a, 0x05, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf5, 0x14, 0x92, + 0x41, 0xc4, 0x14, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x6a, 0xa3, 0x14, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x73, 0x12, 0x91, 0x14, 0x32, 0x8e, 0x14, 0x0a, 0xb6, 0x07, 0x2a, 0xb3, 0x07, 0x0a, + 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, + 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x93, 0x07, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x88, 0x07, 0x1a, 0x85, 0x07, 0x2f, 0x2f, 0x20, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x41, 0x6e, 0x79, 0x20, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x61, 0x6e, 0x79, 0x70, 0x62, 0x2e, 0x4e, + 0x65, 0x77, 0x28, 0x26, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, + 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x7d, 0x0a, 0x0a, 0x63, + 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, + 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x75, + 0x70, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2a, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, + 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, + 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, - 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, - 0x22, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, - 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, - 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x3a, 0x20, 0x22, 0x69, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x5d, 0x0a, 0x7d, 0x29, 0x2e, - 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, - 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xcf, - 0x06, 0x2a, 0xcc, 0x06, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, - 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, - 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xa8, 0x06, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x9d, 0x06, 0x1a, 0x9a, 0x06, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, - 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, - 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, - 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, - 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, - 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, - 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, - 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, - 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, - 0x75, 0x70, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, + 0x64, 0x3a, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, + 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x20, 0x26, + 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x20, + 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2a, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x3a, 0x20, 0x22, 0x69, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x7d, 0x29, 0x0a, 0x80, 0x06, 0x2a, 0xfd, 0x05, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, + 0xd3, 0x05, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xc8, 0x05, 0x1a, 0xc5, 0x05, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x3d, 0x20, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x4a, 0x53, 0x4f, 0x4e, 0x28, 0x7b, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x41, 0x6e, 0x79, 0x2e, 0x66, + 0x72, 0x6f, 0x6d, 0x4a, 0x53, 0x4f, 0x4e, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x55, 0x72, 0x6c, 0x3a, 0x20, 0x27, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x42, 0x6f, + 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, + 0x65, 0x28, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x2e, + 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x28, 0x29, 0x0a, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, + 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, + 0x73, 0x3a, 0x20, 0x5b, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, - 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, + 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x3a, 0x20, 0x22, 0x69, 0x73, 0x5f, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x5d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xcf, 0x06, 0x2a, 0xcc, 0x06, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, + 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xa8, 0x06, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x9d, 0x06, 0x1a, 0x9a, 0x06, 0x63, 0x75, 0x72, + 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x27, 0x20, 0x5c, + 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, @@ -6002,179 +6579,134 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x69, 0x73, 0x5f, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x40, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x7d, 0x27, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0xc6, 0x01, - 0x0a, 0x12, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x68, 0x69, 0x70, 0x73, 0x12, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, - 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x92, 0x41, 0x30, - 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x13, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2a, 0x13, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x3a, 0x01, 0x2a, 0x22, 0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, - 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0xd1, 0x0c, 0x0a, 0x11, 0x52, 0x65, 0x61, 0x64, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x12, 0x20, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, + 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3a, 0x20, + 0x22, 0x69, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x40, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, + 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, + 0x22, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x12, 0xc6, 0x01, 0x0a, 0x12, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x12, 0x21, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, + 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xf6, 0x0b, 0x92, 0x41, 0xb8, 0x0b, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, - 0x72, 0x65, 0x61, 0x64, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, - 0x70, 0x73, 0x2a, 0x17, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x82, 0x0b, 0x0a, 0x0d, - 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xf0, 0x0a, - 0x32, 0xed, 0x0a, 0x0a, 0xa6, 0x04, 0x2a, 0xa3, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, - 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x83, 0x04, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0xf8, 0x03, 0x1a, 0xf5, 0x03, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, - 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x28, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, - 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x26, 0x76, 0x31, - 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, - 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, - 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, - 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, - 0x64, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x22, 0x7d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x0a, 0x84, 0x03, 0x2a, - 0x81, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, - 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, - 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xd7, 0x02, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0xcc, 0x02, 0x1a, 0xc9, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, - 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, - 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, - 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, - 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, - 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x2f, 0x2f, - 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x0a, 0x7d, 0x29, 0x0a, 0xba, 0x03, 0x2a, 0xb7, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, - 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x93, 0x03, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x88, 0x03, 0x1a, 0x85, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, - 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, - 0x69, 0x70, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, - 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x22, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x3a, 0x01, 0x2a, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x68, 0x69, 0x70, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x12, 0xdc, 0x0a, 0x0a, 0x0e, 0x52, - 0x65, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a, 0x0a, 0x92, - 0x41, 0xcf, 0x09, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x20, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2a, 0x14, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x6a, 0x9f, 0x09, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x73, 0x12, 0x8d, 0x09, 0x32, 0x8a, 0x09, 0x0a, 0xb5, 0x03, 0x2a, 0xb2, 0x03, 0x0a, 0x0d, - 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, - 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x92, 0x03, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x87, 0x03, 0x1a, 0x84, 0x03, 0x72, 0x72, 0x2c, 0x20, - 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, - 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, - 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, - 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, - 0x0a, 0xcb, 0x02, 0x2a, 0xc8, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, - 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, - 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x9e, 0x02, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x93, 0x02, 0x1a, 0x90, 0x02, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x6d, + 0x6e, 0x73, 0x68, 0x69, 0x70, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x69, 0x92, 0x41, 0x30, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x13, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, + 0x70, 0x73, 0x2a, 0x13, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, + 0x73, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x3a, 0x01, 0x2a, + 0x22, 0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0xd1, 0x0c, + 0x0a, 0x11, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, + 0x69, 0x70, 0x73, 0x12, 0x20, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf6, 0x0b, 0x92, 0x41, 0xb8, 0x0b, 0x0a, + 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x72, 0x65, 0x61, 0x64, 0x20, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2a, 0x17, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2e, 0x72, 0x65, + 0x61, 0x64, 0x6a, 0x82, 0x0b, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x73, 0x12, 0xf0, 0x0a, 0x32, 0xed, 0x0a, 0x0a, 0xa6, 0x04, 0x2a, 0xa3, 0x04, + 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, + 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x83, 0x04, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xf8, 0x03, 0x1a, 0xf5, 0x03, 0x72, 0x72, + 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, + 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, + 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, + 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x7b, 0x22, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x0a, 0x7d, 0x29, 0x0a, 0x84, 0x03, 0x2a, 0x81, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, + 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x0a, 0xd7, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xcc, 0x02, 0x1a, 0xc9, + 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x28, 0x7b, + 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, + 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, + 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xba, 0x03, 0x2a, 0xb7, 0x03, + 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, + 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, + 0x6c, 0x0a, 0x93, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x88, 0x03, 0x1a, + 0x85, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, + 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x27, + 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, + 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, @@ -6183,360 +6715,366 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, - 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0x81, - 0x03, 0x2a, 0xfe, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, - 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, - 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xda, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0xcf, 0x02, 0x1a, 0xcc, 0x02, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, - 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, - 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, - 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, - 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, - 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, - 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x0a, - 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x3a, 0x01, 0x2a, 0x22, 0x2c, 0x2f, 0x76, 0x31, - 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x12, 0xa9, 0x0c, 0x0a, 0x06, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe5, 0x0b, - 0x92, 0x41, 0xb3, 0x0b, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0b, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x6a, 0x90, 0x0b, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xfe, 0x0a, 0x32, 0xfb, 0x0a, 0x0a, 0x8f, 0x04, 0x2a, - 0x8c, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, - 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, - 0xec, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xe1, 0x03, 0x1a, 0xde, 0x03, - 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, - 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, - 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, - 0x2e, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x75, - 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, - 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, - 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, - 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x73, 0x3a, - 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, - 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x49, 0x64, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x0a, 0x94, - 0x03, 0x2a, 0x91, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, - 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, - 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xe7, 0x02, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xdc, 0x02, 0x1a, 0xd9, 0x02, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x7b, - 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, - 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x74, 0x75, 0x70, 0x6c, - 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, - 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, - 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, - 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, - 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x3a, 0x01, 0x2a, + 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2f, 0x72, 0x65, 0x61, + 0x64, 0x12, 0xdc, 0x0a, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x8a, 0x0a, 0x92, 0x41, 0xcf, 0x09, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, + 0x12, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2a, 0x14, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x9f, 0x09, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, + 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x8d, 0x09, 0x32, 0x8a, 0x09, 0x0a, + 0xb5, 0x03, 0x2a, 0xb2, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, + 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, + 0x67, 0x6f, 0x0a, 0x92, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x87, 0x03, + 0x1a, 0x84, 0x03, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, + 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, + 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x6e, 0x61, 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, + 0x20, 0x26, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x7b, 0x22, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xcb, 0x02, 0x2a, 0xc8, 0x02, 0x0a, 0x0f, 0x0a, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, + 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x0a, 0x9e, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x93, 0x02, 0x1a, 0x90, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x72, 0x65, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x28, + 0x7b, 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, + 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, + 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, + 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xcf, 0x03, 0x2a, 0xcc, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, + 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0x81, 0x03, 0x2a, 0xfe, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, - 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xa8, 0x03, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x9d, 0x03, 0x1a, 0x9a, 0x03, 0x63, 0x75, 0x72, + 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xda, 0x02, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xcf, 0x02, 0x1a, 0xcc, 0x02, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, - 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, - 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x74, - 0x75, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, - 0x64, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, - 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, - 0x3a, 0x20, 0x7b, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, - 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, + 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, + 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, + 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x3a, + 0x01, 0x2a, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, + 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, + 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, + 0x12, 0xa9, 0x0c, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe5, 0x0b, 0x92, 0x41, 0xb3, 0x0b, 0x0a, 0x04, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x0b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x0b, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x6a, 0x90, 0x0b, 0x0a, 0x0d, + 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xfe, 0x0a, + 0x32, 0xfb, 0x0a, 0x0a, 0x8f, 0x04, 0x2a, 0x8c, 0x04, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, + 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xec, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0xe1, 0x03, 0x1a, 0xde, 0x03, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, + 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, + 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, + 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6e, 0x61, 0x70, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x3a, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x49, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x7b, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x22, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x26, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x7b, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x0a, 0x94, 0x03, 0x2a, 0x91, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, + 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x0a, 0xe7, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xdc, 0x02, + 0x1a, 0xd9, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6e, 0x61, 0x70, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x20, 0x22, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, + 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, + 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xcf, 0x03, 0x2a, + 0xcc, 0x03, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, + 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, + 0x75, 0x72, 0x6c, 0x0a, 0xa8, 0x03, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x9d, + 0x03, 0x1a, 0x9a, 0x03, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, + 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, + 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0xcc, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x12, 0x22, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x68, 0x69, 0x70, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6c, 0x92, 0x41, 0x32, 0x0a, 0x04, 0x44, 0x61, 0x74, - 0x61, 0x12, 0x14, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2a, 0x14, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x31, 0x3a, 0x01, 0x2a, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, + 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, + 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x73, 0x22, + 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0xcc, 0x01, 0x0a, + 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x68, 0x69, 0x70, 0x73, 0x12, 0x22, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6c, 0x92, + 0x41, 0x32, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2a, 0x14, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2e, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x3a, 0x01, 0x2a, 0x22, 0x2c, 0x2f, + 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x68, 0x69, 0x70, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0xac, 0x08, 0x0a, 0x09, + 0x52, 0x75, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x62, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xe7, 0x07, 0x92, 0x41, 0xb1, 0x07, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0a, 0x72, + 0x75, 0x6e, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2a, 0x0a, 0x62, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6a, 0x90, 0x07, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xfe, 0x06, 0x32, 0xfb, 0x06, 0x0a, 0xa5, 0x02, + 0x2a, 0xa2, 0x02, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, + 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, + 0x0a, 0x82, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xf7, 0x01, 0x1a, 0xf4, + 0x01, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x3a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x35, 0x36, 0x34, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x44, 0x22, 0x3a, 0x20, 0x22, 0x37, 0x38, 0x39, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x8a, 0x02, 0x2a, 0x87, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, + 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x0a, 0xdd, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xd2, 0x01, + 0x1a, 0xcf, 0x01, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, + 0x75, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x44, 0x3a, 0x20, 0x22, 0x35, 0x36, 0x34, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x44, 0x3a, 0x20, 0x22, 0x37, 0x38, 0x39, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, + 0x7d, 0x29, 0x0a, 0xc3, 0x02, 0x2a, 0xc0, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, + 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x9c, 0x02, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x91, 0x02, 0x1a, 0x8e, 0x02, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, + 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2f, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0xac, 0x08, 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe7, 0x07, 0x92, 0x41, 0xb1, 0x07, - 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0a, 0x72, 0x75, 0x6e, 0x20, 0x62, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x2a, 0x0a, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6a, 0x90, - 0x07, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, - 0x12, 0xfe, 0x06, 0x32, 0xfb, 0x06, 0x0a, 0xa5, 0x02, 0x2a, 0xa2, 0x02, 0x0a, 0x0d, 0x0a, 0x05, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, - 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x82, 0x02, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0xf7, 0x01, 0x1a, 0xf4, 0x01, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, - 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x2e, 0x52, 0x75, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, - 0x20, 0x26, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x75, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, - 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x75, 0x6e, 0x2d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x27, + 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, + 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, - 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x35, 0x36, - 0x34, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22, 0x3a, 0x20, 0x22, 0x37, - 0x38, 0x39, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x8a, - 0x02, 0x2a, 0x87, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, - 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, - 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xdd, 0x01, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xd2, 0x01, 0x1a, 0xcf, 0x01, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x75, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, - 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, - 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, - 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x72, - 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x3a, 0x20, 0x22, 0x35, - 0x36, 0x34, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x3a, 0x20, 0x22, 0x37, 0x38, - 0x39, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, - 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xc3, 0x02, 0x2a, 0xc0, - 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, - 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, - 0x72, 0x6c, 0x0a, 0x9c, 0x02, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x91, 0x02, - 0x1a, 0x8e, 0x02, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, - 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, - 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x75, - 0x6e, 0x2d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, - 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, - 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, - 0x3a, 0x20, 0x22, 0x35, 0x36, 0x34, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, - 0x22, 0x3a, 0x20, 0x22, 0x37, 0x38, 0x39, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, - 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, - 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x75, 0x6e, 0x2d, 0x62, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x32, 0xc0, 0x21, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x80, - 0x15, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xbb, 0x14, 0x92, 0x41, 0x88, 0x14, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x12, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x2a, 0x0c, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6a, 0xe1, - 0x13, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, - 0x12, 0xcf, 0x13, 0x32, 0xcc, 0x13, 0x0a, 0xd3, 0x06, 0x2a, 0xd0, 0x06, 0x0a, 0x0d, 0x0a, 0x05, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, - 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0xb0, 0x06, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0xa5, 0x06, 0x1a, 0xa2, 0x06, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, - 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, - 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2a, 0x76, 0x31, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2a, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, - 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x44, 0x7d, 0x7d, 0x23, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, - 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, + 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x3a, 0x20, 0x22, 0x35, 0x36, 0x34, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, - 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x24, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x7c, 0x62, - 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x9b, 0x06, 0x2a, - 0x98, 0x06, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, - 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, - 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0xee, 0x05, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0xe3, 0x05, 0x1a, 0xe0, 0x05, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, - 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x3a, - 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, - 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x5b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x5f, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x23, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x44, 0x7d, 0x7d, 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x40, 0x75, 0x73, 0x65, - 0x72, 0x3a, 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, - 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x24, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x7c, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, - 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xd5, 0x06, 0x2a, 0xd2, 0x06, - 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, - 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, - 0x6c, 0x0a, 0xae, 0x06, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xa3, 0x06, 0x1a, - 0xa0, 0x06, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, - 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, - 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x77, - 0x72, 0x69, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, - 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, - 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x3a, - 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, - 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, - 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22, 0x3a, 0x20, 0x22, 0x37, 0x38, 0x39, 0x22, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, + 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, + 0x72, 0x75, 0x6e, 0x2d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x32, 0xc0, 0x21, 0x0a, 0x06, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x80, 0x15, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, + 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbb, 0x14, 0x92, 0x41, 0x88, + 0x14, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2a, 0x0c, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x6a, 0xe1, 0x13, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xcf, 0x13, 0x32, 0xcc, 0x13, 0x0a, 0xd3, 0x06, + 0x2a, 0xd0, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, + 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, + 0x0a, 0xb0, 0x06, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xa5, 0x06, 0x1a, 0xa2, + 0x06, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x5b, + 0x5d, 0x2a, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x5d, 0x2a, 0x76, + 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, - 0x73, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x23, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, + 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, + 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, 0x7b, + 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x24, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x7c, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x7d, 0x29, 0x0a, 0x9b, 0x06, 0x2a, 0x98, 0x06, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, + 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x0a, 0xee, 0x05, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xe3, 0x05, 0x1a, 0xe0, + 0x05, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, + 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x5b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, + 0x70, 0x73, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, @@ -6547,256 +7085,313 @@ var file_base_v1_service_proto_rawDesc = []byte{ 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x44, 0x7d, 0x7d, 0x24, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x7c, 0x62, 0x6f, 0x6f, 0x6c, 0x65, - 0x61, 0x6e, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, + 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, + 0x7d, 0x7d, 0x24, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x7c, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, + 0x6e, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, - 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, - 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x12, 0x8d, 0x06, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x05, 0x92, 0x41, 0x99, 0x05, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x12, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2a, - 0x0b, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x6a, 0xf4, 0x04, 0x0a, - 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xe2, - 0x04, 0x32, 0xdf, 0x04, 0x0a, 0xb8, 0x01, 0x2a, 0xb5, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, - 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x95, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x8a, 0x01, 0x1a, 0x87, 0x01, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, - 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x2e, 0x52, 0x65, 0x61, 0x64, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, - 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, - 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, - 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, - 0xb5, 0x01, 0x2a, 0xb2, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, - 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, - 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x88, 0x01, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x7e, 0x1a, 0x7c, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x28, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, - 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xe9, 0x01, 0x2a, 0xe6, 0x01, 0x0a, 0x0f, 0x0a, - 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, - 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xc2, - 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb7, 0x01, 0x1a, 0xb4, 0x01, 0x63, - 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, - 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, - 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x72, 0x65, 0x61, 0x64, - 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, - 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, - 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, 0x2f, 0x76, - 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x72, 0x65, 0x61, - 0x64, 0x12, 0xa2, 0x06, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x61, 0x73, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xda, 0x05, 0x92, 0x41, 0xa6, 0x05, - 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2a, 0x0d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x6a, 0xfd, 0x04, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, - 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xeb, 0x04, 0x32, 0xe8, 0x04, 0x0a, 0xbc, - 0x01, 0x2a, 0xb9, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, - 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, - 0x6f, 0x0a, 0x99, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x1a, - 0x8b, 0x01, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, - 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xb8, 0x01, - 0x2a, 0xb5, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, - 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, - 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x8b, 0x01, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x80, 0x01, 0x1a, 0x7e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, - 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, - 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xeb, 0x01, 0x2a, 0xe8, 0x01, 0x0a, 0x0f, - 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, - 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, - 0xc4, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb9, 0x01, 0x1a, 0xb6, 0x01, - 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, - 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, - 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, - 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, - 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, - 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x32, 0xc1, 0x0f, 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, - 0x63, 0x79, 0x12, 0xbe, 0x05, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf6, 0x04, 0x92, 0x41, 0xd5, - 0x04, 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x12, 0x0d, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2a, 0x0e, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x6a, 0xaa, 0x04, 0x0a, 0x0d, 0x78, 0x2d, - 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x98, 0x04, 0x32, 0x95, - 0x04, 0x0a, 0x9b, 0x01, 0x2a, 0x98, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, - 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x79, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x6f, - 0x1a, 0x6d, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x20, 0x20, 0x22, 0x22, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x0a, - 0x98, 0x01, 0x2a, 0x95, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, - 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, - 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x6c, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x62, 0x1a, 0x60, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, - 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xd9, 0x01, 0x2a, 0xd6, 0x01, - 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, - 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, - 0x6c, 0x0a, 0xb2, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xa7, 0x01, 0x1a, - 0xa4, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, - 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, + 0x29, 0x0a, 0xd5, 0x06, 0x2a, 0xd2, 0x06, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, + 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xae, 0x06, 0x0a, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0xa3, 0x06, 0x1a, 0xa0, 0x06, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, - 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, - 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, - 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, - 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0xba, 0x04, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1c, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf2, 0x03, 0x92, 0x41, - 0xd6, 0x03, 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x12, 0x0d, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x2a, 0x0e, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x73, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x6a, 0xab, 0x03, 0x0a, 0x0d, 0x78, - 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x99, 0x03, 0x32, - 0x96, 0x03, 0x0a, 0x8b, 0x01, 0x2a, 0x88, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, - 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x69, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x5f, 0x1a, 0x5d, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, - 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, - 0x0a, 0x8c, 0x01, 0x2a, 0x89, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, - 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, - 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x60, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x56, 0x1a, 0x54, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, + 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, + 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x6f, 0x72, 0x49, 0x44, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x3a, + 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x23, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, + 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, + 0x7d, 0x7d, 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x40, 0x75, 0x73, 0x65, 0x72, 0x3a, + 0x7b, 0x7b, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x44, 0x7d, 0x7d, 0x22, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x3a, 0x20, 0x5b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7b, 0x7b, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x7d, 0x7d, 0x24, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x7c, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, + 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, + 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x2f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0x8d, 0x06, 0x0a, 0x04, 0x52, 0x65, 0x61, + 0x64, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, + 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x05, 0x92, 0x41, 0x99, + 0x05, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x20, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2a, 0x0b, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x6a, 0xf4, 0x04, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0xe2, 0x04, 0x32, 0xdf, 0x04, 0x0a, 0xb8, 0x01, 0x2a, 0xb5, + 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, + 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x95, + 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x8a, 0x01, 0x1a, 0x87, 0x01, 0x72, + 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x28, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, + 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xb5, 0x01, 0x2a, 0xb2, 0x01, 0x0a, 0x0f, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, + 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x0a, 0x88, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x7e, + 0x1a, 0x7c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, + 0x72, 0x65, 0x61, 0x64, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x2e, + 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, + 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0xe9, + 0x01, 0x2a, 0xe6, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, + 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, + 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xc2, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0xb7, 0x01, 0x1a, 0xb4, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, + 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, + 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, + 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, + 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, + 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, + 0x3a, 0x01, 0x2a, 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, + 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x12, 0xa2, 0x06, 0x0a, 0x06, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xda, 0x05, 0x92, 0x41, 0xa6, 0x05, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, + 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2a, 0x0d, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x6a, 0xfd, 0x04, + 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, + 0xeb, 0x04, 0x32, 0xe8, 0x04, 0x0a, 0xbc, 0x01, 0x2a, 0xb9, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, + 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x99, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x1a, 0x8b, 0x01, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, + 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, + 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, + 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xb8, 0x01, 0x2a, 0xb5, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, + 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x0a, 0x8b, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x80, 0x01, 0x1a, + 0x7e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x49, 0x64, 0x3a, 0x20, 0x22, 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, - 0x77, 0x2a, 0x75, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, - 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, - 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x52, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x48, - 0x1a, 0x46, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x74, 0x31, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, - 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xb7, 0x05, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xf5, 0x04, 0x92, 0x41, 0xd6, 0x04, 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, - 0x63, 0x79, 0x12, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, - 0x2a, 0x0c, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x6a, 0xae, - 0x04, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, - 0x12, 0x9c, 0x04, 0x32, 0x99, 0x04, 0x0a, 0xa8, 0x01, 0x2a, 0xa5, 0x01, 0x0a, 0x0d, 0x0a, 0x05, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, - 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x85, 0x01, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x7b, 0x1a, 0x79, 0x63, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, - 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, - 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, - 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, - 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, - 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, - 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, - 0x29, 0x0a, 0x85, 0x01, 0x2a, 0x82, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, - 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x59, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4f, 0x1a, 0x4d, 0x6c, 0x65, 0x74, 0x20, - 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0xe3, 0x01, 0x2a, 0xe0, 0x01, 0x0a, - 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, - 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, - 0x0a, 0xbc, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xb1, 0x01, 0x1a, 0xae, - 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, - 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, - 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x27, - 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, - 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, 0x20, 0x32, 0x30, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x27, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x8a, 0x01, 0x0a, 0x0b, 0x63, - 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x62, 0x61, - 0x73, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, - 0x58, 0x58, 0xaa, 0x02, 0x07, 0x42, 0x61, 0x73, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x42, - 0x61, 0x73, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x42, 0x61, 0x73, 0x65, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x42, - 0x61, 0x73, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0xeb, 0x01, 0x2a, 0xe8, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, + 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x06, + 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xc4, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0xb9, 0x01, 0x1a, 0xb6, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, + 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, + 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, + 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x32, 0xc1, 0x0f, + 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x12, 0xbe, 0x05, 0x0a, 0x06, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xf6, 0x04, 0x92, 0x41, 0xd5, 0x04, 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x79, 0x12, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x2a, 0x0e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x6a, 0xaa, 0x04, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x73, 0x12, 0x98, 0x04, 0x32, 0x95, 0x04, 0x0a, 0x9b, 0x01, 0x2a, 0x98, 0x01, 0x0a, 0x0d, + 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, 0x0a, + 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x79, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x6f, 0x1a, 0x6d, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, + 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, + 0x63, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x20, + 0x26, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, 0x3a, + 0x20, 0x20, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x0a, 0x98, 0x01, 0x2a, 0x95, 0x01, 0x0a, 0x0f, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, 0x0a, + 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x0a, 0x6c, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x62, 0x1a, + 0x60, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, 0x20, + 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x22, 0x0a, + 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0a, 0x7d, + 0x29, 0x0a, 0xd9, 0x01, 0x2a, 0xd6, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, + 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xb2, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0xa7, 0x01, 0x1a, 0xa4, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, + 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, + 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0xba, 0x04, 0x0a, 0x06, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xf2, 0x03, 0x92, 0x41, 0xd6, 0x03, 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, + 0x63, 0x79, 0x12, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x2a, 0x0e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x6a, 0xab, 0x03, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x73, 0x12, 0x99, 0x03, 0x32, 0x96, 0x03, 0x0a, 0x8b, 0x01, 0x2a, 0x88, 0x01, 0x0a, + 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x0c, + 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, 0x0a, 0x69, 0x0a, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x5f, 0x1a, 0x5d, 0x72, 0x72, 0x2c, 0x20, 0x65, 0x72, + 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x61, + 0x6e, 0x63, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x29, 0x2c, + 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x64, + 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x29, 0x0a, 0x8c, 0x01, 0x2a, 0x89, 0x01, 0x0a, 0x0f, 0x0a, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x14, + 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x0a, 0x60, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x56, + 0x1a, 0x54, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, + 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x64, 0x3a, + 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x0a, 0x7d, 0x29, 0x0a, 0x77, 0x2a, 0x75, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, + 0x61, 0x6e, 0x67, 0x12, 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0x52, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x48, 0x1a, 0x46, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x20, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x74, 0x31, 0x27, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb7, 0x05, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x1a, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf5, 0x04, 0x92, 0x41, 0xd6, 0x04, + 0x0a, 0x07, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x12, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x20, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2a, 0x0c, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x6a, 0xae, 0x04, 0x0a, 0x0d, 0x78, 0x2d, 0x63, 0x6f, 0x64, 0x65, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x9c, 0x04, 0x32, 0x99, 0x04, 0x0a, 0xa8, 0x01, + 0x2a, 0xa5, 0x01, 0x0a, 0x0d, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x04, 0x1a, 0x02, + 0x67, 0x6f, 0x0a, 0x0c, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x04, 0x1a, 0x02, 0x67, 0x6f, + 0x0a, 0x85, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x7b, 0x1a, 0x79, 0x63, + 0x72, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x28, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x28, 0x29, 0x2c, 0x20, 0x26, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, + 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, 0x0a, 0x85, 0x01, 0x2a, 0x82, 0x01, 0x0a, 0x0f, + 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x06, 0x1a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x0a, + 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x0c, 0x1a, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a, 0x59, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x4f, 0x1a, 0x4d, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x6c, 0x69, 0x73, 0x74, + 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, + 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x6f, 0x75, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x22, 0x22, 0x2c, 0x0a, 0x7d, 0x29, + 0x0a, 0xe3, 0x01, 0x2a, 0xe0, 0x01, 0x0a, 0x0f, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, + 0x06, 0x1a, 0x04, 0x63, 0x55, 0x52, 0x4c, 0x0a, 0x0e, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, + 0x06, 0x1a, 0x04, 0x63, 0x75, 0x72, 0x6c, 0x0a, 0xbc, 0x01, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0xb1, 0x01, 0x1a, 0xae, 0x01, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x2d, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x27, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, + 0x74, 0x3a, 0x33, 0x34, 0x37, 0x36, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, + 0x6f, 0x6e, 0x27, 0x20, 0x5c, 0x0a, 0x2d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x61, 0x77, + 0x20, 0x27, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x22, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, + 0x20, 0x22, 0x22, 0x0a, 0x7d, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, + 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, + 0x74, 0x42, 0x8a, 0x01, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, + 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x6b, + 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x62, 0x61, 0x73, + 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x42, 0x61, 0x73, 0x65, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x42, 0x61, 0x73, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, + 0x42, 0x61, 0x73, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x42, 0x61, 0x73, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -6811,7 +7406,7 @@ func file_base_v1_service_proto_rawDescGZIP() []byte { return file_base_v1_service_proto_rawDescData } -var file_base_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 67) +var file_base_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 73) var file_base_v1_service_proto_goTypes = []any{ (*PermissionCheckRequest)(nil), // 0: base.v1.PermissionCheckRequest (*PermissionCheckRequestMetadata)(nil), // 1: base.v1.PermissionCheckRequestMetadata @@ -6821,198 +7416,215 @@ var file_base_v1_service_proto_goTypes = []any{ (*PermissionExpandRequestMetadata)(nil), // 5: base.v1.PermissionExpandRequestMetadata (*PermissionExpandResponse)(nil), // 6: base.v1.PermissionExpandResponse (*PermissionLookupEntityRequest)(nil), // 7: base.v1.PermissionLookupEntityRequest - (*PermissionLookupEntityRequestMetadata)(nil), // 8: base.v1.PermissionLookupEntityRequestMetadata - (*PermissionLookupEntityResponse)(nil), // 9: base.v1.PermissionLookupEntityResponse - (*PermissionLookupEntityStreamResponse)(nil), // 10: base.v1.PermissionLookupEntityStreamResponse - (*PermissionEntityFilterRequest)(nil), // 11: base.v1.PermissionEntityFilterRequest - (*PermissionEntityFilterRequestMetadata)(nil), // 12: base.v1.PermissionEntityFilterRequestMetadata - (*PermissionLookupSubjectRequest)(nil), // 13: base.v1.PermissionLookupSubjectRequest - (*PermissionLookupSubjectRequestMetadata)(nil), // 14: base.v1.PermissionLookupSubjectRequestMetadata - (*PermissionLookupSubjectResponse)(nil), // 15: base.v1.PermissionLookupSubjectResponse - (*PermissionSubjectPermissionRequest)(nil), // 16: base.v1.PermissionSubjectPermissionRequest - (*PermissionSubjectPermissionRequestMetadata)(nil), // 17: base.v1.PermissionSubjectPermissionRequestMetadata - (*PermissionSubjectPermissionResponse)(nil), // 18: base.v1.PermissionSubjectPermissionResponse - (*WatchRequest)(nil), // 19: base.v1.WatchRequest - (*WatchResponse)(nil), // 20: base.v1.WatchResponse - (*SchemaWriteRequest)(nil), // 21: base.v1.SchemaWriteRequest - (*SchemaWriteResponse)(nil), // 22: base.v1.SchemaWriteResponse - (*SchemaPartialWriteRequest)(nil), // 23: base.v1.SchemaPartialWriteRequest - (*SchemaPartialWriteRequestMetadata)(nil), // 24: base.v1.SchemaPartialWriteRequestMetadata - (*SchemaPartialWriteResponse)(nil), // 25: base.v1.SchemaPartialWriteResponse - (*SchemaReadRequest)(nil), // 26: base.v1.SchemaReadRequest - (*SchemaReadRequestMetadata)(nil), // 27: base.v1.SchemaReadRequestMetadata - (*SchemaReadResponse)(nil), // 28: base.v1.SchemaReadResponse - (*SchemaListRequest)(nil), // 29: base.v1.SchemaListRequest - (*SchemaListResponse)(nil), // 30: base.v1.SchemaListResponse - (*SchemaList)(nil), // 31: base.v1.SchemaList - (*DataWriteRequest)(nil), // 32: base.v1.DataWriteRequest - (*DataWriteRequestMetadata)(nil), // 33: base.v1.DataWriteRequestMetadata - (*DataWriteResponse)(nil), // 34: base.v1.DataWriteResponse - (*RelationshipWriteRequest)(nil), // 35: base.v1.RelationshipWriteRequest - (*RelationshipWriteRequestMetadata)(nil), // 36: base.v1.RelationshipWriteRequestMetadata - (*RelationshipWriteResponse)(nil), // 37: base.v1.RelationshipWriteResponse - (*RelationshipReadRequest)(nil), // 38: base.v1.RelationshipReadRequest - (*RelationshipReadRequestMetadata)(nil), // 39: base.v1.RelationshipReadRequestMetadata - (*RelationshipReadResponse)(nil), // 40: base.v1.RelationshipReadResponse - (*AttributeReadRequest)(nil), // 41: base.v1.AttributeReadRequest - (*AttributeReadRequestMetadata)(nil), // 42: base.v1.AttributeReadRequestMetadata - (*AttributeReadResponse)(nil), // 43: base.v1.AttributeReadResponse - (*DataDeleteRequest)(nil), // 44: base.v1.DataDeleteRequest - (*DataDeleteResponse)(nil), // 45: base.v1.DataDeleteResponse - (*RelationshipDeleteRequest)(nil), // 46: base.v1.RelationshipDeleteRequest - (*RelationshipDeleteResponse)(nil), // 47: base.v1.RelationshipDeleteResponse - (*BundleRunRequest)(nil), // 48: base.v1.BundleRunRequest - (*BundleRunResponse)(nil), // 49: base.v1.BundleRunResponse - (*BundleWriteRequest)(nil), // 50: base.v1.BundleWriteRequest - (*BundleWriteResponse)(nil), // 51: base.v1.BundleWriteResponse - (*BundleReadRequest)(nil), // 52: base.v1.BundleReadRequest - (*BundleReadResponse)(nil), // 53: base.v1.BundleReadResponse - (*BundleDeleteRequest)(nil), // 54: base.v1.BundleDeleteRequest - (*BundleDeleteResponse)(nil), // 55: base.v1.BundleDeleteResponse - (*TenantCreateRequest)(nil), // 56: base.v1.TenantCreateRequest - (*TenantCreateResponse)(nil), // 57: base.v1.TenantCreateResponse - (*TenantDeleteRequest)(nil), // 58: base.v1.TenantDeleteRequest - (*TenantDeleteResponse)(nil), // 59: base.v1.TenantDeleteResponse - (*TenantListRequest)(nil), // 60: base.v1.TenantListRequest - (*TenantListResponse)(nil), // 61: base.v1.TenantListResponse - nil, // 62: base.v1.PermissionLookupEntityRequest.ScopeEntry - nil, // 63: base.v1.PermissionEntityFilterRequest.ScopeEntry - nil, // 64: base.v1.PermissionSubjectPermissionResponse.ResultsEntry - nil, // 65: base.v1.SchemaPartialWriteRequest.PartialsEntry - nil, // 66: base.v1.BundleRunRequest.ArgumentsEntry - (*Entity)(nil), // 67: base.v1.Entity - (*Subject)(nil), // 68: base.v1.Subject - (*Context)(nil), // 69: base.v1.Context - (*Argument)(nil), // 70: base.v1.Argument - (CheckResult)(0), // 71: base.v1.CheckResult - (*Expand)(nil), // 72: base.v1.Expand - (*Entrance)(nil), // 73: base.v1.Entrance - (*RelationReference)(nil), // 74: base.v1.RelationReference - (*DataChanges)(nil), // 75: base.v1.DataChanges - (*SchemaDefinition)(nil), // 76: base.v1.SchemaDefinition - (*Tuple)(nil), // 77: base.v1.Tuple - (*Attribute)(nil), // 78: base.v1.Attribute - (*TupleFilter)(nil), // 79: base.v1.TupleFilter - (*AttributeFilter)(nil), // 80: base.v1.AttributeFilter - (*DataBundle)(nil), // 81: base.v1.DataBundle - (*Tenant)(nil), // 82: base.v1.Tenant - (*StringArrayValue)(nil), // 83: base.v1.StringArrayValue - (*Partials)(nil), // 84: base.v1.Partials + (*PermissionsLookupEntityRequest)(nil), // 8: base.v1.PermissionsLookupEntityRequest + (*PermissionLookupEntityRequestMetadata)(nil), // 9: base.v1.PermissionLookupEntityRequestMetadata + (*PermissionLookupEntityResponse)(nil), // 10: base.v1.PermissionLookupEntityResponse + (*PermissionsLookupEntityResponse)(nil), // 11: base.v1.PermissionsLookupEntityResponse + (*EntityIds)(nil), // 12: base.v1.EntityIds + (*PermissionLookupEntityStreamResponse)(nil), // 13: base.v1.PermissionLookupEntityStreamResponse + (*PermissionsLookupEntityStreamResponse)(nil), // 14: base.v1.PermissionsLookupEntityStreamResponse + (*PermissionEntityFilterRequest)(nil), // 15: base.v1.PermissionEntityFilterRequest + (*PermissionEntityFilterRequestMetadata)(nil), // 16: base.v1.PermissionEntityFilterRequestMetadata + (*PermissionLookupSubjectRequest)(nil), // 17: base.v1.PermissionLookupSubjectRequest + (*PermissionLookupSubjectRequestMetadata)(nil), // 18: base.v1.PermissionLookupSubjectRequestMetadata + (*PermissionLookupSubjectResponse)(nil), // 19: base.v1.PermissionLookupSubjectResponse + (*PermissionSubjectPermissionRequest)(nil), // 20: base.v1.PermissionSubjectPermissionRequest + (*PermissionSubjectPermissionRequestMetadata)(nil), // 21: base.v1.PermissionSubjectPermissionRequestMetadata + (*PermissionSubjectPermissionResponse)(nil), // 22: base.v1.PermissionSubjectPermissionResponse + (*WatchRequest)(nil), // 23: base.v1.WatchRequest + (*WatchResponse)(nil), // 24: base.v1.WatchResponse + (*SchemaWriteRequest)(nil), // 25: base.v1.SchemaWriteRequest + (*SchemaWriteResponse)(nil), // 26: base.v1.SchemaWriteResponse + (*SchemaPartialWriteRequest)(nil), // 27: base.v1.SchemaPartialWriteRequest + (*SchemaPartialWriteRequestMetadata)(nil), // 28: base.v1.SchemaPartialWriteRequestMetadata + (*SchemaPartialWriteResponse)(nil), // 29: base.v1.SchemaPartialWriteResponse + (*SchemaReadRequest)(nil), // 30: base.v1.SchemaReadRequest + (*SchemaReadRequestMetadata)(nil), // 31: base.v1.SchemaReadRequestMetadata + (*SchemaReadResponse)(nil), // 32: base.v1.SchemaReadResponse + (*SchemaListRequest)(nil), // 33: base.v1.SchemaListRequest + (*SchemaListResponse)(nil), // 34: base.v1.SchemaListResponse + (*SchemaList)(nil), // 35: base.v1.SchemaList + (*DataWriteRequest)(nil), // 36: base.v1.DataWriteRequest + (*DataWriteRequestMetadata)(nil), // 37: base.v1.DataWriteRequestMetadata + (*DataWriteResponse)(nil), // 38: base.v1.DataWriteResponse + (*RelationshipWriteRequest)(nil), // 39: base.v1.RelationshipWriteRequest + (*RelationshipWriteRequestMetadata)(nil), // 40: base.v1.RelationshipWriteRequestMetadata + (*RelationshipWriteResponse)(nil), // 41: base.v1.RelationshipWriteResponse + (*RelationshipReadRequest)(nil), // 42: base.v1.RelationshipReadRequest + (*RelationshipReadRequestMetadata)(nil), // 43: base.v1.RelationshipReadRequestMetadata + (*RelationshipReadResponse)(nil), // 44: base.v1.RelationshipReadResponse + (*AttributeReadRequest)(nil), // 45: base.v1.AttributeReadRequest + (*AttributeReadRequestMetadata)(nil), // 46: base.v1.AttributeReadRequestMetadata + (*AttributeReadResponse)(nil), // 47: base.v1.AttributeReadResponse + (*DataDeleteRequest)(nil), // 48: base.v1.DataDeleteRequest + (*DataDeleteResponse)(nil), // 49: base.v1.DataDeleteResponse + (*RelationshipDeleteRequest)(nil), // 50: base.v1.RelationshipDeleteRequest + (*RelationshipDeleteResponse)(nil), // 51: base.v1.RelationshipDeleteResponse + (*BundleRunRequest)(nil), // 52: base.v1.BundleRunRequest + (*BundleRunResponse)(nil), // 53: base.v1.BundleRunResponse + (*BundleWriteRequest)(nil), // 54: base.v1.BundleWriteRequest + (*BundleWriteResponse)(nil), // 55: base.v1.BundleWriteResponse + (*BundleReadRequest)(nil), // 56: base.v1.BundleReadRequest + (*BundleReadResponse)(nil), // 57: base.v1.BundleReadResponse + (*BundleDeleteRequest)(nil), // 58: base.v1.BundleDeleteRequest + (*BundleDeleteResponse)(nil), // 59: base.v1.BundleDeleteResponse + (*TenantCreateRequest)(nil), // 60: base.v1.TenantCreateRequest + (*TenantCreateResponse)(nil), // 61: base.v1.TenantCreateResponse + (*TenantDeleteRequest)(nil), // 62: base.v1.TenantDeleteRequest + (*TenantDeleteResponse)(nil), // 63: base.v1.TenantDeleteResponse + (*TenantListRequest)(nil), // 64: base.v1.TenantListRequest + (*TenantListResponse)(nil), // 65: base.v1.TenantListResponse + nil, // 66: base.v1.PermissionLookupEntityRequest.ScopeEntry + nil, // 67: base.v1.PermissionsLookupEntityRequest.ScopeEntry + nil, // 68: base.v1.PermissionsLookupEntityResponse.EntityIdsEntry + nil, // 69: base.v1.PermissionEntityFilterRequest.ScopeEntry + nil, // 70: base.v1.PermissionSubjectPermissionResponse.ResultsEntry + nil, // 71: base.v1.SchemaPartialWriteRequest.PartialsEntry + nil, // 72: base.v1.BundleRunRequest.ArgumentsEntry + (*Entity)(nil), // 73: base.v1.Entity + (*Subject)(nil), // 74: base.v1.Subject + (*Context)(nil), // 75: base.v1.Context + (*Argument)(nil), // 76: base.v1.Argument + (CheckResult)(0), // 77: base.v1.CheckResult + (*Expand)(nil), // 78: base.v1.Expand + (*Entrance)(nil), // 79: base.v1.Entrance + (*RelationReference)(nil), // 80: base.v1.RelationReference + (*DataChanges)(nil), // 81: base.v1.DataChanges + (*SchemaDefinition)(nil), // 82: base.v1.SchemaDefinition + (*Tuple)(nil), // 83: base.v1.Tuple + (*Attribute)(nil), // 84: base.v1.Attribute + (*TupleFilter)(nil), // 85: base.v1.TupleFilter + (*AttributeFilter)(nil), // 86: base.v1.AttributeFilter + (*DataBundle)(nil), // 87: base.v1.DataBundle + (*Tenant)(nil), // 88: base.v1.Tenant + (*StringArrayValue)(nil), // 89: base.v1.StringArrayValue + (*Partials)(nil), // 90: base.v1.Partials } var file_base_v1_service_proto_depIdxs = []int32{ 1, // 0: base.v1.PermissionCheckRequest.metadata:type_name -> base.v1.PermissionCheckRequestMetadata - 67, // 1: base.v1.PermissionCheckRequest.entity:type_name -> base.v1.Entity - 68, // 2: base.v1.PermissionCheckRequest.subject:type_name -> base.v1.Subject - 69, // 3: base.v1.PermissionCheckRequest.context:type_name -> base.v1.Context - 70, // 4: base.v1.PermissionCheckRequest.arguments:type_name -> base.v1.Argument - 71, // 5: base.v1.PermissionCheckResponse.can:type_name -> base.v1.CheckResult + 73, // 1: base.v1.PermissionCheckRequest.entity:type_name -> base.v1.Entity + 74, // 2: base.v1.PermissionCheckRequest.subject:type_name -> base.v1.Subject + 75, // 3: base.v1.PermissionCheckRequest.context:type_name -> base.v1.Context + 76, // 4: base.v1.PermissionCheckRequest.arguments:type_name -> base.v1.Argument + 77, // 5: base.v1.PermissionCheckResponse.can:type_name -> base.v1.CheckResult 3, // 6: base.v1.PermissionCheckResponse.metadata:type_name -> base.v1.PermissionCheckResponseMetadata 5, // 7: base.v1.PermissionExpandRequest.metadata:type_name -> base.v1.PermissionExpandRequestMetadata - 67, // 8: base.v1.PermissionExpandRequest.entity:type_name -> base.v1.Entity - 69, // 9: base.v1.PermissionExpandRequest.context:type_name -> base.v1.Context - 70, // 10: base.v1.PermissionExpandRequest.arguments:type_name -> base.v1.Argument - 72, // 11: base.v1.PermissionExpandResponse.tree:type_name -> base.v1.Expand - 8, // 12: base.v1.PermissionLookupEntityRequest.metadata:type_name -> base.v1.PermissionLookupEntityRequestMetadata - 68, // 13: base.v1.PermissionLookupEntityRequest.subject:type_name -> base.v1.Subject - 69, // 14: base.v1.PermissionLookupEntityRequest.context:type_name -> base.v1.Context - 62, // 15: base.v1.PermissionLookupEntityRequest.scope:type_name -> base.v1.PermissionLookupEntityRequest.ScopeEntry - 12, // 16: base.v1.PermissionEntityFilterRequest.metadata:type_name -> base.v1.PermissionEntityFilterRequestMetadata - 73, // 17: base.v1.PermissionEntityFilterRequest.entrance:type_name -> base.v1.Entrance - 68, // 18: base.v1.PermissionEntityFilterRequest.subject:type_name -> base.v1.Subject - 69, // 19: base.v1.PermissionEntityFilterRequest.context:type_name -> base.v1.Context - 63, // 20: base.v1.PermissionEntityFilterRequest.scope:type_name -> base.v1.PermissionEntityFilterRequest.ScopeEntry - 14, // 21: base.v1.PermissionLookupSubjectRequest.metadata:type_name -> base.v1.PermissionLookupSubjectRequestMetadata - 67, // 22: base.v1.PermissionLookupSubjectRequest.entity:type_name -> base.v1.Entity - 74, // 23: base.v1.PermissionLookupSubjectRequest.subject_reference:type_name -> base.v1.RelationReference - 69, // 24: base.v1.PermissionLookupSubjectRequest.context:type_name -> base.v1.Context - 17, // 25: base.v1.PermissionSubjectPermissionRequest.metadata:type_name -> base.v1.PermissionSubjectPermissionRequestMetadata - 67, // 26: base.v1.PermissionSubjectPermissionRequest.entity:type_name -> base.v1.Entity - 68, // 27: base.v1.PermissionSubjectPermissionRequest.subject:type_name -> base.v1.Subject - 69, // 28: base.v1.PermissionSubjectPermissionRequest.context:type_name -> base.v1.Context - 64, // 29: base.v1.PermissionSubjectPermissionResponse.results:type_name -> base.v1.PermissionSubjectPermissionResponse.ResultsEntry - 75, // 30: base.v1.WatchResponse.changes:type_name -> base.v1.DataChanges - 24, // 31: base.v1.SchemaPartialWriteRequest.metadata:type_name -> base.v1.SchemaPartialWriteRequestMetadata - 65, // 32: base.v1.SchemaPartialWriteRequest.partials:type_name -> base.v1.SchemaPartialWriteRequest.PartialsEntry - 27, // 33: base.v1.SchemaReadRequest.metadata:type_name -> base.v1.SchemaReadRequestMetadata - 76, // 34: base.v1.SchemaReadResponse.schema:type_name -> base.v1.SchemaDefinition - 31, // 35: base.v1.SchemaListResponse.schemas:type_name -> base.v1.SchemaList - 33, // 36: base.v1.DataWriteRequest.metadata:type_name -> base.v1.DataWriteRequestMetadata - 77, // 37: base.v1.DataWriteRequest.tuples:type_name -> base.v1.Tuple - 78, // 38: base.v1.DataWriteRequest.attributes:type_name -> base.v1.Attribute - 36, // 39: base.v1.RelationshipWriteRequest.metadata:type_name -> base.v1.RelationshipWriteRequestMetadata - 77, // 40: base.v1.RelationshipWriteRequest.tuples:type_name -> base.v1.Tuple - 39, // 41: base.v1.RelationshipReadRequest.metadata:type_name -> base.v1.RelationshipReadRequestMetadata - 79, // 42: base.v1.RelationshipReadRequest.filter:type_name -> base.v1.TupleFilter - 77, // 43: base.v1.RelationshipReadResponse.tuples:type_name -> base.v1.Tuple - 42, // 44: base.v1.AttributeReadRequest.metadata:type_name -> base.v1.AttributeReadRequestMetadata - 80, // 45: base.v1.AttributeReadRequest.filter:type_name -> base.v1.AttributeFilter - 78, // 46: base.v1.AttributeReadResponse.attributes:type_name -> base.v1.Attribute - 79, // 47: base.v1.DataDeleteRequest.tuple_filter:type_name -> base.v1.TupleFilter - 80, // 48: base.v1.DataDeleteRequest.attribute_filter:type_name -> base.v1.AttributeFilter - 79, // 49: base.v1.RelationshipDeleteRequest.filter:type_name -> base.v1.TupleFilter - 66, // 50: base.v1.BundleRunRequest.arguments:type_name -> base.v1.BundleRunRequest.ArgumentsEntry - 81, // 51: base.v1.BundleWriteRequest.bundles:type_name -> base.v1.DataBundle - 81, // 52: base.v1.BundleReadResponse.bundle:type_name -> base.v1.DataBundle - 82, // 53: base.v1.TenantCreateResponse.tenant:type_name -> base.v1.Tenant - 82, // 54: base.v1.TenantDeleteResponse.tenant:type_name -> base.v1.Tenant - 82, // 55: base.v1.TenantListResponse.tenants:type_name -> base.v1.Tenant - 83, // 56: base.v1.PermissionLookupEntityRequest.ScopeEntry.value:type_name -> base.v1.StringArrayValue - 83, // 57: base.v1.PermissionEntityFilterRequest.ScopeEntry.value:type_name -> base.v1.StringArrayValue - 71, // 58: base.v1.PermissionSubjectPermissionResponse.ResultsEntry.value:type_name -> base.v1.CheckResult - 84, // 59: base.v1.SchemaPartialWriteRequest.PartialsEntry.value:type_name -> base.v1.Partials - 0, // 60: base.v1.Permission.Check:input_type -> base.v1.PermissionCheckRequest - 4, // 61: base.v1.Permission.Expand:input_type -> base.v1.PermissionExpandRequest - 7, // 62: base.v1.Permission.LookupEntity:input_type -> base.v1.PermissionLookupEntityRequest - 7, // 63: base.v1.Permission.LookupEntityStream:input_type -> base.v1.PermissionLookupEntityRequest - 13, // 64: base.v1.Permission.LookupSubject:input_type -> base.v1.PermissionLookupSubjectRequest - 16, // 65: base.v1.Permission.SubjectPermission:input_type -> base.v1.PermissionSubjectPermissionRequest - 19, // 66: base.v1.Watch.Watch:input_type -> base.v1.WatchRequest - 21, // 67: base.v1.Schema.Write:input_type -> base.v1.SchemaWriteRequest - 23, // 68: base.v1.Schema.PartialWrite:input_type -> base.v1.SchemaPartialWriteRequest - 26, // 69: base.v1.Schema.Read:input_type -> base.v1.SchemaReadRequest - 29, // 70: base.v1.Schema.List:input_type -> base.v1.SchemaListRequest - 32, // 71: base.v1.Data.Write:input_type -> base.v1.DataWriteRequest - 35, // 72: base.v1.Data.WriteRelationships:input_type -> base.v1.RelationshipWriteRequest - 38, // 73: base.v1.Data.ReadRelationships:input_type -> base.v1.RelationshipReadRequest - 41, // 74: base.v1.Data.ReadAttributes:input_type -> base.v1.AttributeReadRequest - 44, // 75: base.v1.Data.Delete:input_type -> base.v1.DataDeleteRequest - 46, // 76: base.v1.Data.DeleteRelationships:input_type -> base.v1.RelationshipDeleteRequest - 48, // 77: base.v1.Data.RunBundle:input_type -> base.v1.BundleRunRequest - 50, // 78: base.v1.Bundle.Write:input_type -> base.v1.BundleWriteRequest - 52, // 79: base.v1.Bundle.Read:input_type -> base.v1.BundleReadRequest - 54, // 80: base.v1.Bundle.Delete:input_type -> base.v1.BundleDeleteRequest - 56, // 81: base.v1.Tenancy.Create:input_type -> base.v1.TenantCreateRequest - 58, // 82: base.v1.Tenancy.Delete:input_type -> base.v1.TenantDeleteRequest - 60, // 83: base.v1.Tenancy.List:input_type -> base.v1.TenantListRequest - 2, // 84: base.v1.Permission.Check:output_type -> base.v1.PermissionCheckResponse - 6, // 85: base.v1.Permission.Expand:output_type -> base.v1.PermissionExpandResponse - 9, // 86: base.v1.Permission.LookupEntity:output_type -> base.v1.PermissionLookupEntityResponse - 10, // 87: base.v1.Permission.LookupEntityStream:output_type -> base.v1.PermissionLookupEntityStreamResponse - 15, // 88: base.v1.Permission.LookupSubject:output_type -> base.v1.PermissionLookupSubjectResponse - 18, // 89: base.v1.Permission.SubjectPermission:output_type -> base.v1.PermissionSubjectPermissionResponse - 20, // 90: base.v1.Watch.Watch:output_type -> base.v1.WatchResponse - 22, // 91: base.v1.Schema.Write:output_type -> base.v1.SchemaWriteResponse - 25, // 92: base.v1.Schema.PartialWrite:output_type -> base.v1.SchemaPartialWriteResponse - 28, // 93: base.v1.Schema.Read:output_type -> base.v1.SchemaReadResponse - 30, // 94: base.v1.Schema.List:output_type -> base.v1.SchemaListResponse - 34, // 95: base.v1.Data.Write:output_type -> base.v1.DataWriteResponse - 37, // 96: base.v1.Data.WriteRelationships:output_type -> base.v1.RelationshipWriteResponse - 40, // 97: base.v1.Data.ReadRelationships:output_type -> base.v1.RelationshipReadResponse - 43, // 98: base.v1.Data.ReadAttributes:output_type -> base.v1.AttributeReadResponse - 45, // 99: base.v1.Data.Delete:output_type -> base.v1.DataDeleteResponse - 47, // 100: base.v1.Data.DeleteRelationships:output_type -> base.v1.RelationshipDeleteResponse - 49, // 101: base.v1.Data.RunBundle:output_type -> base.v1.BundleRunResponse - 51, // 102: base.v1.Bundle.Write:output_type -> base.v1.BundleWriteResponse - 53, // 103: base.v1.Bundle.Read:output_type -> base.v1.BundleReadResponse - 55, // 104: base.v1.Bundle.Delete:output_type -> base.v1.BundleDeleteResponse - 57, // 105: base.v1.Tenancy.Create:output_type -> base.v1.TenantCreateResponse - 59, // 106: base.v1.Tenancy.Delete:output_type -> base.v1.TenantDeleteResponse - 61, // 107: base.v1.Tenancy.List:output_type -> base.v1.TenantListResponse - 84, // [84:108] is the sub-list for method output_type - 60, // [60:84] is the sub-list for method input_type - 60, // [60:60] is the sub-list for extension type_name - 60, // [60:60] is the sub-list for extension extendee - 0, // [0:60] is the sub-list for field type_name + 73, // 8: base.v1.PermissionExpandRequest.entity:type_name -> base.v1.Entity + 75, // 9: base.v1.PermissionExpandRequest.context:type_name -> base.v1.Context + 76, // 10: base.v1.PermissionExpandRequest.arguments:type_name -> base.v1.Argument + 78, // 11: base.v1.PermissionExpandResponse.tree:type_name -> base.v1.Expand + 9, // 12: base.v1.PermissionLookupEntityRequest.metadata:type_name -> base.v1.PermissionLookupEntityRequestMetadata + 74, // 13: base.v1.PermissionLookupEntityRequest.subject:type_name -> base.v1.Subject + 75, // 14: base.v1.PermissionLookupEntityRequest.context:type_name -> base.v1.Context + 66, // 15: base.v1.PermissionLookupEntityRequest.scope:type_name -> base.v1.PermissionLookupEntityRequest.ScopeEntry + 9, // 16: base.v1.PermissionsLookupEntityRequest.metadata:type_name -> base.v1.PermissionLookupEntityRequestMetadata + 74, // 17: base.v1.PermissionsLookupEntityRequest.subject:type_name -> base.v1.Subject + 75, // 18: base.v1.PermissionsLookupEntityRequest.context:type_name -> base.v1.Context + 67, // 19: base.v1.PermissionsLookupEntityRequest.scope:type_name -> base.v1.PermissionsLookupEntityRequest.ScopeEntry + 68, // 20: base.v1.PermissionsLookupEntityResponse.entity_ids:type_name -> base.v1.PermissionsLookupEntityResponse.EntityIdsEntry + 16, // 21: base.v1.PermissionEntityFilterRequest.metadata:type_name -> base.v1.PermissionEntityFilterRequestMetadata + 79, // 22: base.v1.PermissionEntityFilterRequest.entrances:type_name -> base.v1.Entrance + 74, // 23: base.v1.PermissionEntityFilterRequest.subject:type_name -> base.v1.Subject + 75, // 24: base.v1.PermissionEntityFilterRequest.context:type_name -> base.v1.Context + 69, // 25: base.v1.PermissionEntityFilterRequest.scope:type_name -> base.v1.PermissionEntityFilterRequest.ScopeEntry + 18, // 26: base.v1.PermissionLookupSubjectRequest.metadata:type_name -> base.v1.PermissionLookupSubjectRequestMetadata + 73, // 27: base.v1.PermissionLookupSubjectRequest.entity:type_name -> base.v1.Entity + 80, // 28: base.v1.PermissionLookupSubjectRequest.subject_reference:type_name -> base.v1.RelationReference + 75, // 29: base.v1.PermissionLookupSubjectRequest.context:type_name -> base.v1.Context + 21, // 30: base.v1.PermissionSubjectPermissionRequest.metadata:type_name -> base.v1.PermissionSubjectPermissionRequestMetadata + 73, // 31: base.v1.PermissionSubjectPermissionRequest.entity:type_name -> base.v1.Entity + 74, // 32: base.v1.PermissionSubjectPermissionRequest.subject:type_name -> base.v1.Subject + 75, // 33: base.v1.PermissionSubjectPermissionRequest.context:type_name -> base.v1.Context + 70, // 34: base.v1.PermissionSubjectPermissionResponse.results:type_name -> base.v1.PermissionSubjectPermissionResponse.ResultsEntry + 81, // 35: base.v1.WatchResponse.changes:type_name -> base.v1.DataChanges + 28, // 36: base.v1.SchemaPartialWriteRequest.metadata:type_name -> base.v1.SchemaPartialWriteRequestMetadata + 71, // 37: base.v1.SchemaPartialWriteRequest.partials:type_name -> base.v1.SchemaPartialWriteRequest.PartialsEntry + 31, // 38: base.v1.SchemaReadRequest.metadata:type_name -> base.v1.SchemaReadRequestMetadata + 82, // 39: base.v1.SchemaReadResponse.schema:type_name -> base.v1.SchemaDefinition + 35, // 40: base.v1.SchemaListResponse.schemas:type_name -> base.v1.SchemaList + 37, // 41: base.v1.DataWriteRequest.metadata:type_name -> base.v1.DataWriteRequestMetadata + 83, // 42: base.v1.DataWriteRequest.tuples:type_name -> base.v1.Tuple + 84, // 43: base.v1.DataWriteRequest.attributes:type_name -> base.v1.Attribute + 40, // 44: base.v1.RelationshipWriteRequest.metadata:type_name -> base.v1.RelationshipWriteRequestMetadata + 83, // 45: base.v1.RelationshipWriteRequest.tuples:type_name -> base.v1.Tuple + 43, // 46: base.v1.RelationshipReadRequest.metadata:type_name -> base.v1.RelationshipReadRequestMetadata + 85, // 47: base.v1.RelationshipReadRequest.filter:type_name -> base.v1.TupleFilter + 83, // 48: base.v1.RelationshipReadResponse.tuples:type_name -> base.v1.Tuple + 46, // 49: base.v1.AttributeReadRequest.metadata:type_name -> base.v1.AttributeReadRequestMetadata + 86, // 50: base.v1.AttributeReadRequest.filter:type_name -> base.v1.AttributeFilter + 84, // 51: base.v1.AttributeReadResponse.attributes:type_name -> base.v1.Attribute + 85, // 52: base.v1.DataDeleteRequest.tuple_filter:type_name -> base.v1.TupleFilter + 86, // 53: base.v1.DataDeleteRequest.attribute_filter:type_name -> base.v1.AttributeFilter + 85, // 54: base.v1.RelationshipDeleteRequest.filter:type_name -> base.v1.TupleFilter + 72, // 55: base.v1.BundleRunRequest.arguments:type_name -> base.v1.BundleRunRequest.ArgumentsEntry + 87, // 56: base.v1.BundleWriteRequest.bundles:type_name -> base.v1.DataBundle + 87, // 57: base.v1.BundleReadResponse.bundle:type_name -> base.v1.DataBundle + 88, // 58: base.v1.TenantCreateResponse.tenant:type_name -> base.v1.Tenant + 88, // 59: base.v1.TenantDeleteResponse.tenant:type_name -> base.v1.Tenant + 88, // 60: base.v1.TenantListResponse.tenants:type_name -> base.v1.Tenant + 89, // 61: base.v1.PermissionLookupEntityRequest.ScopeEntry.value:type_name -> base.v1.StringArrayValue + 89, // 62: base.v1.PermissionsLookupEntityRequest.ScopeEntry.value:type_name -> base.v1.StringArrayValue + 12, // 63: base.v1.PermissionsLookupEntityResponse.EntityIdsEntry.value:type_name -> base.v1.EntityIds + 89, // 64: base.v1.PermissionEntityFilterRequest.ScopeEntry.value:type_name -> base.v1.StringArrayValue + 77, // 65: base.v1.PermissionSubjectPermissionResponse.ResultsEntry.value:type_name -> base.v1.CheckResult + 90, // 66: base.v1.SchemaPartialWriteRequest.PartialsEntry.value:type_name -> base.v1.Partials + 0, // 67: base.v1.Permission.Check:input_type -> base.v1.PermissionCheckRequest + 4, // 68: base.v1.Permission.Expand:input_type -> base.v1.PermissionExpandRequest + 7, // 69: base.v1.Permission.LookupEntity:input_type -> base.v1.PermissionLookupEntityRequest + 8, // 70: base.v1.Permission.LookupEntities:input_type -> base.v1.PermissionsLookupEntityRequest + 8, // 71: base.v1.Permission.LookupEntitiesStream:input_type -> base.v1.PermissionsLookupEntityRequest + 7, // 72: base.v1.Permission.LookupEntityStream:input_type -> base.v1.PermissionLookupEntityRequest + 17, // 73: base.v1.Permission.LookupSubject:input_type -> base.v1.PermissionLookupSubjectRequest + 20, // 74: base.v1.Permission.SubjectPermission:input_type -> base.v1.PermissionSubjectPermissionRequest + 23, // 75: base.v1.Watch.Watch:input_type -> base.v1.WatchRequest + 25, // 76: base.v1.Schema.Write:input_type -> base.v1.SchemaWriteRequest + 27, // 77: base.v1.Schema.PartialWrite:input_type -> base.v1.SchemaPartialWriteRequest + 30, // 78: base.v1.Schema.Read:input_type -> base.v1.SchemaReadRequest + 33, // 79: base.v1.Schema.List:input_type -> base.v1.SchemaListRequest + 36, // 80: base.v1.Data.Write:input_type -> base.v1.DataWriteRequest + 39, // 81: base.v1.Data.WriteRelationships:input_type -> base.v1.RelationshipWriteRequest + 42, // 82: base.v1.Data.ReadRelationships:input_type -> base.v1.RelationshipReadRequest + 45, // 83: base.v1.Data.ReadAttributes:input_type -> base.v1.AttributeReadRequest + 48, // 84: base.v1.Data.Delete:input_type -> base.v1.DataDeleteRequest + 50, // 85: base.v1.Data.DeleteRelationships:input_type -> base.v1.RelationshipDeleteRequest + 52, // 86: base.v1.Data.RunBundle:input_type -> base.v1.BundleRunRequest + 54, // 87: base.v1.Bundle.Write:input_type -> base.v1.BundleWriteRequest + 56, // 88: base.v1.Bundle.Read:input_type -> base.v1.BundleReadRequest + 58, // 89: base.v1.Bundle.Delete:input_type -> base.v1.BundleDeleteRequest + 60, // 90: base.v1.Tenancy.Create:input_type -> base.v1.TenantCreateRequest + 62, // 91: base.v1.Tenancy.Delete:input_type -> base.v1.TenantDeleteRequest + 64, // 92: base.v1.Tenancy.List:input_type -> base.v1.TenantListRequest + 2, // 93: base.v1.Permission.Check:output_type -> base.v1.PermissionCheckResponse + 6, // 94: base.v1.Permission.Expand:output_type -> base.v1.PermissionExpandResponse + 10, // 95: base.v1.Permission.LookupEntity:output_type -> base.v1.PermissionLookupEntityResponse + 11, // 96: base.v1.Permission.LookupEntities:output_type -> base.v1.PermissionsLookupEntityResponse + 14, // 97: base.v1.Permission.LookupEntitiesStream:output_type -> base.v1.PermissionsLookupEntityStreamResponse + 13, // 98: base.v1.Permission.LookupEntityStream:output_type -> base.v1.PermissionLookupEntityStreamResponse + 19, // 99: base.v1.Permission.LookupSubject:output_type -> base.v1.PermissionLookupSubjectResponse + 22, // 100: base.v1.Permission.SubjectPermission:output_type -> base.v1.PermissionSubjectPermissionResponse + 24, // 101: base.v1.Watch.Watch:output_type -> base.v1.WatchResponse + 26, // 102: base.v1.Schema.Write:output_type -> base.v1.SchemaWriteResponse + 29, // 103: base.v1.Schema.PartialWrite:output_type -> base.v1.SchemaPartialWriteResponse + 32, // 104: base.v1.Schema.Read:output_type -> base.v1.SchemaReadResponse + 34, // 105: base.v1.Schema.List:output_type -> base.v1.SchemaListResponse + 38, // 106: base.v1.Data.Write:output_type -> base.v1.DataWriteResponse + 41, // 107: base.v1.Data.WriteRelationships:output_type -> base.v1.RelationshipWriteResponse + 44, // 108: base.v1.Data.ReadRelationships:output_type -> base.v1.RelationshipReadResponse + 47, // 109: base.v1.Data.ReadAttributes:output_type -> base.v1.AttributeReadResponse + 49, // 110: base.v1.Data.Delete:output_type -> base.v1.DataDeleteResponse + 51, // 111: base.v1.Data.DeleteRelationships:output_type -> base.v1.RelationshipDeleteResponse + 53, // 112: base.v1.Data.RunBundle:output_type -> base.v1.BundleRunResponse + 55, // 113: base.v1.Bundle.Write:output_type -> base.v1.BundleWriteResponse + 57, // 114: base.v1.Bundle.Read:output_type -> base.v1.BundleReadResponse + 59, // 115: base.v1.Bundle.Delete:output_type -> base.v1.BundleDeleteResponse + 61, // 116: base.v1.Tenancy.Create:output_type -> base.v1.TenantCreateResponse + 63, // 117: base.v1.Tenancy.Delete:output_type -> base.v1.TenantDeleteResponse + 65, // 118: base.v1.Tenancy.List:output_type -> base.v1.TenantListResponse + 93, // [93:119] is the sub-list for method output_type + 67, // [67:93] is the sub-list for method input_type + 67, // [67:67] is the sub-list for extension type_name + 67, // [67:67] is the sub-list for extension extendee + 0, // [0:67] is the sub-list for field type_name } func init() { file_base_v1_service_proto_init() } @@ -7119,7 +7731,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*PermissionLookupEntityRequestMetadata); i { + switch v := v.(*PermissionsLookupEntityRequest); i { case 0: return &v.state case 1: @@ -7131,7 +7743,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*PermissionLookupEntityResponse); i { + switch v := v.(*PermissionLookupEntityRequestMetadata); i { case 0: return &v.state case 1: @@ -7143,7 +7755,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*PermissionLookupEntityStreamResponse); i { + switch v := v.(*PermissionLookupEntityResponse); i { case 0: return &v.state case 1: @@ -7155,7 +7767,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*PermissionEntityFilterRequest); i { + switch v := v.(*PermissionsLookupEntityResponse); i { case 0: return &v.state case 1: @@ -7167,7 +7779,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*PermissionEntityFilterRequestMetadata); i { + switch v := v.(*EntityIds); i { case 0: return &v.state case 1: @@ -7179,7 +7791,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*PermissionLookupSubjectRequest); i { + switch v := v.(*PermissionLookupEntityStreamResponse); i { case 0: return &v.state case 1: @@ -7191,7 +7803,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*PermissionLookupSubjectRequestMetadata); i { + switch v := v.(*PermissionsLookupEntityStreamResponse); i { case 0: return &v.state case 1: @@ -7203,7 +7815,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*PermissionLookupSubjectResponse); i { + switch v := v.(*PermissionEntityFilterRequest); i { case 0: return &v.state case 1: @@ -7215,7 +7827,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*PermissionSubjectPermissionRequest); i { + switch v := v.(*PermissionEntityFilterRequestMetadata); i { case 0: return &v.state case 1: @@ -7227,7 +7839,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*PermissionSubjectPermissionRequestMetadata); i { + switch v := v.(*PermissionLookupSubjectRequest); i { case 0: return &v.state case 1: @@ -7239,7 +7851,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*PermissionSubjectPermissionResponse); i { + switch v := v.(*PermissionLookupSubjectRequestMetadata); i { case 0: return &v.state case 1: @@ -7251,7 +7863,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*WatchRequest); i { + switch v := v.(*PermissionLookupSubjectResponse); i { case 0: return &v.state case 1: @@ -7263,7 +7875,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[20].Exporter = func(v any, i int) any { - switch v := v.(*WatchResponse); i { + switch v := v.(*PermissionSubjectPermissionRequest); i { case 0: return &v.state case 1: @@ -7275,7 +7887,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*SchemaWriteRequest); i { + switch v := v.(*PermissionSubjectPermissionRequestMetadata); i { case 0: return &v.state case 1: @@ -7287,7 +7899,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*SchemaWriteResponse); i { + switch v := v.(*PermissionSubjectPermissionResponse); i { case 0: return &v.state case 1: @@ -7299,7 +7911,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[23].Exporter = func(v any, i int) any { - switch v := v.(*SchemaPartialWriteRequest); i { + switch v := v.(*WatchRequest); i { case 0: return &v.state case 1: @@ -7311,7 +7923,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[24].Exporter = func(v any, i int) any { - switch v := v.(*SchemaPartialWriteRequestMetadata); i { + switch v := v.(*WatchResponse); i { case 0: return &v.state case 1: @@ -7323,7 +7935,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[25].Exporter = func(v any, i int) any { - switch v := v.(*SchemaPartialWriteResponse); i { + switch v := v.(*SchemaWriteRequest); i { case 0: return &v.state case 1: @@ -7335,7 +7947,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[26].Exporter = func(v any, i int) any { - switch v := v.(*SchemaReadRequest); i { + switch v := v.(*SchemaWriteResponse); i { case 0: return &v.state case 1: @@ -7347,7 +7959,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[27].Exporter = func(v any, i int) any { - switch v := v.(*SchemaReadRequestMetadata); i { + switch v := v.(*SchemaPartialWriteRequest); i { case 0: return &v.state case 1: @@ -7359,7 +7971,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[28].Exporter = func(v any, i int) any { - switch v := v.(*SchemaReadResponse); i { + switch v := v.(*SchemaPartialWriteRequestMetadata); i { case 0: return &v.state case 1: @@ -7371,7 +7983,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[29].Exporter = func(v any, i int) any { - switch v := v.(*SchemaListRequest); i { + switch v := v.(*SchemaPartialWriteResponse); i { case 0: return &v.state case 1: @@ -7383,7 +7995,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[30].Exporter = func(v any, i int) any { - switch v := v.(*SchemaListResponse); i { + switch v := v.(*SchemaReadRequest); i { case 0: return &v.state case 1: @@ -7395,7 +8007,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[31].Exporter = func(v any, i int) any { - switch v := v.(*SchemaList); i { + switch v := v.(*SchemaReadRequestMetadata); i { case 0: return &v.state case 1: @@ -7407,7 +8019,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[32].Exporter = func(v any, i int) any { - switch v := v.(*DataWriteRequest); i { + switch v := v.(*SchemaReadResponse); i { case 0: return &v.state case 1: @@ -7419,7 +8031,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[33].Exporter = func(v any, i int) any { - switch v := v.(*DataWriteRequestMetadata); i { + switch v := v.(*SchemaListRequest); i { case 0: return &v.state case 1: @@ -7431,7 +8043,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[34].Exporter = func(v any, i int) any { - switch v := v.(*DataWriteResponse); i { + switch v := v.(*SchemaListResponse); i { case 0: return &v.state case 1: @@ -7443,7 +8055,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[35].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipWriteRequest); i { + switch v := v.(*SchemaList); i { case 0: return &v.state case 1: @@ -7455,7 +8067,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[36].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipWriteRequestMetadata); i { + switch v := v.(*DataWriteRequest); i { case 0: return &v.state case 1: @@ -7467,7 +8079,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[37].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipWriteResponse); i { + switch v := v.(*DataWriteRequestMetadata); i { case 0: return &v.state case 1: @@ -7479,7 +8091,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[38].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipReadRequest); i { + switch v := v.(*DataWriteResponse); i { case 0: return &v.state case 1: @@ -7491,7 +8103,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[39].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipReadRequestMetadata); i { + switch v := v.(*RelationshipWriteRequest); i { case 0: return &v.state case 1: @@ -7503,7 +8115,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[40].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipReadResponse); i { + switch v := v.(*RelationshipWriteRequestMetadata); i { case 0: return &v.state case 1: @@ -7515,7 +8127,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[41].Exporter = func(v any, i int) any { - switch v := v.(*AttributeReadRequest); i { + switch v := v.(*RelationshipWriteResponse); i { case 0: return &v.state case 1: @@ -7527,7 +8139,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[42].Exporter = func(v any, i int) any { - switch v := v.(*AttributeReadRequestMetadata); i { + switch v := v.(*RelationshipReadRequest); i { case 0: return &v.state case 1: @@ -7539,7 +8151,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[43].Exporter = func(v any, i int) any { - switch v := v.(*AttributeReadResponse); i { + switch v := v.(*RelationshipReadRequestMetadata); i { case 0: return &v.state case 1: @@ -7551,7 +8163,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[44].Exporter = func(v any, i int) any { - switch v := v.(*DataDeleteRequest); i { + switch v := v.(*RelationshipReadResponse); i { case 0: return &v.state case 1: @@ -7563,7 +8175,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[45].Exporter = func(v any, i int) any { - switch v := v.(*DataDeleteResponse); i { + switch v := v.(*AttributeReadRequest); i { case 0: return &v.state case 1: @@ -7575,7 +8187,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[46].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipDeleteRequest); i { + switch v := v.(*AttributeReadRequestMetadata); i { case 0: return &v.state case 1: @@ -7587,7 +8199,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[47].Exporter = func(v any, i int) any { - switch v := v.(*RelationshipDeleteResponse); i { + switch v := v.(*AttributeReadResponse); i { case 0: return &v.state case 1: @@ -7599,7 +8211,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[48].Exporter = func(v any, i int) any { - switch v := v.(*BundleRunRequest); i { + switch v := v.(*DataDeleteRequest); i { case 0: return &v.state case 1: @@ -7611,7 +8223,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[49].Exporter = func(v any, i int) any { - switch v := v.(*BundleRunResponse); i { + switch v := v.(*DataDeleteResponse); i { case 0: return &v.state case 1: @@ -7623,7 +8235,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[50].Exporter = func(v any, i int) any { - switch v := v.(*BundleWriteRequest); i { + switch v := v.(*RelationshipDeleteRequest); i { case 0: return &v.state case 1: @@ -7635,7 +8247,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[51].Exporter = func(v any, i int) any { - switch v := v.(*BundleWriteResponse); i { + switch v := v.(*RelationshipDeleteResponse); i { case 0: return &v.state case 1: @@ -7647,7 +8259,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[52].Exporter = func(v any, i int) any { - switch v := v.(*BundleReadRequest); i { + switch v := v.(*BundleRunRequest); i { case 0: return &v.state case 1: @@ -7659,7 +8271,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[53].Exporter = func(v any, i int) any { - switch v := v.(*BundleReadResponse); i { + switch v := v.(*BundleRunResponse); i { case 0: return &v.state case 1: @@ -7671,7 +8283,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[54].Exporter = func(v any, i int) any { - switch v := v.(*BundleDeleteRequest); i { + switch v := v.(*BundleWriteRequest); i { case 0: return &v.state case 1: @@ -7683,7 +8295,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[55].Exporter = func(v any, i int) any { - switch v := v.(*BundleDeleteResponse); i { + switch v := v.(*BundleWriteResponse); i { case 0: return &v.state case 1: @@ -7695,7 +8307,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[56].Exporter = func(v any, i int) any { - switch v := v.(*TenantCreateRequest); i { + switch v := v.(*BundleReadRequest); i { case 0: return &v.state case 1: @@ -7707,7 +8319,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[57].Exporter = func(v any, i int) any { - switch v := v.(*TenantCreateResponse); i { + switch v := v.(*BundleReadResponse); i { case 0: return &v.state case 1: @@ -7719,7 +8331,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[58].Exporter = func(v any, i int) any { - switch v := v.(*TenantDeleteRequest); i { + switch v := v.(*BundleDeleteRequest); i { case 0: return &v.state case 1: @@ -7731,7 +8343,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[59].Exporter = func(v any, i int) any { - switch v := v.(*TenantDeleteResponse); i { + switch v := v.(*BundleDeleteResponse); i { case 0: return &v.state case 1: @@ -7743,7 +8355,7 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[60].Exporter = func(v any, i int) any { - switch v := v.(*TenantListRequest); i { + switch v := v.(*TenantCreateRequest); i { case 0: return &v.state case 1: @@ -7755,6 +8367,54 @@ func file_base_v1_service_proto_init() { } } file_base_v1_service_proto_msgTypes[61].Exporter = func(v any, i int) any { + switch v := v.(*TenantCreateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_base_v1_service_proto_msgTypes[62].Exporter = func(v any, i int) any { + switch v := v.(*TenantDeleteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_base_v1_service_proto_msgTypes[63].Exporter = func(v any, i int) any { + switch v := v.(*TenantDeleteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_base_v1_service_proto_msgTypes[64].Exporter = func(v any, i int) any { + switch v := v.(*TenantListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_base_v1_service_proto_msgTypes[65].Exporter = func(v any, i int) any { switch v := v.(*TenantListResponse); i { case 0: return &v.state @@ -7773,7 +8433,7 @@ func file_base_v1_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_base_v1_service_proto_rawDesc, NumEnums: 0, - NumMessages: 67, + NumMessages: 73, NumExtensions: 0, NumServices: 6, }, diff --git a/pkg/pb/base/v1/service.pb.gw.go b/pkg/pb/base/v1/service.pb.gw.go index 1e270a916..d86420ca2 100644 --- a/pkg/pb/base/v1/service.pb.gw.go +++ b/pkg/pb/base/v1/service.pb.gw.go @@ -211,6 +211,104 @@ func local_request_Permission_LookupEntity_0(ctx context.Context, marshaler runt } +func request_Permission_LookupEntities_0(ctx context.Context, marshaler runtime.Marshaler, client PermissionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PermissionsLookupEntityRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["tenant_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "tenant_id") + } + + protoReq.TenantId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "tenant_id", err) + } + + msg, err := client.LookupEntities(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Permission_LookupEntities_0(ctx context.Context, marshaler runtime.Marshaler, server PermissionServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PermissionsLookupEntityRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["tenant_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "tenant_id") + } + + protoReq.TenantId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "tenant_id", err) + } + + msg, err := server.LookupEntities(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Permission_LookupEntitiesStream_0(ctx context.Context, marshaler runtime.Marshaler, client PermissionClient, req *http.Request, pathParams map[string]string) (Permission_LookupEntitiesStreamClient, runtime.ServerMetadata, error) { + var protoReq PermissionsLookupEntityRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["tenant_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "tenant_id") + } + + protoReq.TenantId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "tenant_id", err) + } + + stream, err := client.LookupEntitiesStream(ctx, &protoReq) + if err != nil { + return nil, metadata, err + } + header, err := stream.Header() + if err != nil { + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil + +} + func request_Permission_LookupEntityStream_0(ctx context.Context, marshaler runtime.Marshaler, client PermissionClient, req *http.Request, pathParams map[string]string) (Permission_LookupEntityStreamClient, runtime.ServerMetadata, error) { var protoReq PermissionLookupEntityRequest var metadata runtime.ServerMetadata @@ -1432,6 +1530,38 @@ func RegisterPermissionHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_Permission_LookupEntities_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/base.v1.Permission/LookupEntities", runtime.WithHTTPPathPattern("/v1/tenants/{tenant_id}/permissions/lookup-entities")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Permission_LookupEntities_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Permission_LookupEntities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Permission_LookupEntitiesStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport") + _, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + }) + mux.Handle("POST", pattern_Permission_LookupEntityStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport") _, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -2073,6 +2203,50 @@ func RegisterPermissionHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_Permission_LookupEntities_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/base.v1.Permission/LookupEntities", runtime.WithHTTPPathPattern("/v1/tenants/{tenant_id}/permissions/lookup-entities")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Permission_LookupEntities_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Permission_LookupEntities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Permission_LookupEntitiesStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/base.v1.Permission/LookupEntitiesStream", runtime.WithHTTPPathPattern("/v1/tenants/{tenant_id}/permissions/lookup-entities-stream")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Permission_LookupEntitiesStream_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Permission_LookupEntitiesStream_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_Permission_LookupEntityStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -2149,6 +2323,10 @@ var ( pattern_Permission_LookupEntity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "tenants", "tenant_id", "permissions", "lookup-entity"}, "")) + pattern_Permission_LookupEntities_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "tenants", "tenant_id", "permissions", "lookup-entities"}, "")) + + pattern_Permission_LookupEntitiesStream_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "tenants", "tenant_id", "permissions", "lookup-entities-stream"}, "")) + pattern_Permission_LookupEntityStream_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "tenants", "tenant_id", "permissions", "lookup-entity-stream"}, "")) pattern_Permission_LookupSubject_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "tenants", "tenant_id", "permissions", "lookup-subject"}, "")) @@ -2163,6 +2341,10 @@ var ( forward_Permission_LookupEntity_0 = runtime.ForwardResponseMessage + forward_Permission_LookupEntities_0 = runtime.ForwardResponseMessage + + forward_Permission_LookupEntitiesStream_0 = runtime.ForwardResponseStream + forward_Permission_LookupEntityStream_0 = runtime.ForwardResponseStream forward_Permission_LookupSubject_0 = runtime.ForwardResponseMessage diff --git a/pkg/pb/base/v1/service.pb.validate.go b/pkg/pb/base/v1/service.pb.validate.go index 3e970e5bb..8ef3c0fd8 100644 --- a/pkg/pb/base/v1/service.pb.validate.go +++ b/pkg/pb/base/v1/service.pb.validate.go @@ -1608,6 +1608,371 @@ var _PermissionLookupEntityRequest_EntityType_Pattern = regexp.MustCompile("^[a- var _PermissionLookupEntityRequest_Permission_Pattern = regexp.MustCompile("^[a-zA-Z_]{1,64}$") +// Validate checks the field values on PermissionsLookupEntityRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *PermissionsLookupEntityRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on PermissionsLookupEntityRequest with +// the rules defined in the proto definition for this message. If any rules +// are violated, the result is a list of violation errors wrapped in +// PermissionsLookupEntityRequestMultiError, or nil if none found. +func (m *PermissionsLookupEntityRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *PermissionsLookupEntityRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(m.GetTenantId()) > 128 { + err := PermissionsLookupEntityRequestValidationError{ + field: "TenantId", + reason: "value length must be at most 128 bytes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if !_PermissionsLookupEntityRequest_TenantId_Pattern.MatchString(m.GetTenantId()) { + err := PermissionsLookupEntityRequestValidationError{ + field: "TenantId", + reason: "value does not match regex pattern \"^([a-zA-Z0-9_\\\\-@\\\\.:+]{1,128}|\\\\*)$\"", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetMetadata() == nil { + err := PermissionsLookupEntityRequestValidationError{ + field: "Metadata", + reason: "value is required", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return PermissionsLookupEntityRequestValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(m.GetEntityType()) > 64 { + err := PermissionsLookupEntityRequestValidationError{ + field: "EntityType", + reason: "value length must be at most 64 bytes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if !_PermissionsLookupEntityRequest_EntityType_Pattern.MatchString(m.GetEntityType()) { + err := PermissionsLookupEntityRequestValidationError{ + field: "EntityType", + reason: "value does not match regex pattern \"^[a-zA-Z_]{1,64}$\"", + } + if !all { + return err + } + errors = append(errors, err) + } + + if l := len(m.GetPermissions()); l < 1 || l > 100 { + err := PermissionsLookupEntityRequestValidationError{ + field: "Permissions", + reason: "value must contain between 1 and 100 items, inclusive", + } + if !all { + return err + } + errors = append(errors, err) + } + + for idx, item := range m.GetPermissions() { + _, _ = idx, item + + if len(item) > 64 { + err := PermissionsLookupEntityRequestValidationError{ + field: fmt.Sprintf("Permissions[%v]", idx), + reason: "value length must be at most 64 bytes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if !_PermissionsLookupEntityRequest_Permissions_Pattern.MatchString(item) { + err := PermissionsLookupEntityRequestValidationError{ + field: fmt.Sprintf("Permissions[%v]", idx), + reason: "value does not match regex pattern \"^[a-zA-Z_][a-zA-Z0-9_]*$\"", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.GetSubject() == nil { + err := PermissionsLookupEntityRequestValidationError{ + field: "Subject", + reason: "value is required", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetSubject()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: "Subject", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: "Subject", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetSubject()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return PermissionsLookupEntityRequestValidationError{ + field: "Subject", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetContext()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: "Context", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: "Context", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetContext()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return PermissionsLookupEntityRequestValidationError{ + field: "Context", + reason: "embedded message failed validation", + cause: err, + } + } + } + + { + sorted_keys := make([]string, len(m.GetScope())) + i := 0 + for key := range m.GetScope() { + sorted_keys[i] = key + i++ + } + sort.Slice(sorted_keys, func(i, j int) bool { return sorted_keys[i] < sorted_keys[j] }) + for _, key := range sorted_keys { + val := m.GetScope()[key] + _ = val + + // no validation rules for Scope[key] + + if all { + switch v := interface{}(val).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: fmt.Sprintf("Scope[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, PermissionsLookupEntityRequestValidationError{ + field: fmt.Sprintf("Scope[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(val).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return PermissionsLookupEntityRequestValidationError{ + field: fmt.Sprintf("Scope[%v]", key), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + } + + if m.GetPageSize() != 0 { + + if m.GetPageSize() < 1 { + err := PermissionsLookupEntityRequestValidationError{ + field: "PageSize", + reason: "value must be greater than or equal to 1", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.GetContinuousToken() != "" { + + } + + if len(errors) > 0 { + return PermissionsLookupEntityRequestMultiError(errors) + } + + return nil +} + +// PermissionsLookupEntityRequestMultiError is an error wrapping multiple +// validation errors returned by PermissionsLookupEntityRequest.ValidateAll() +// if the designated constraints aren't met. +type PermissionsLookupEntityRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m PermissionsLookupEntityRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m PermissionsLookupEntityRequestMultiError) AllErrors() []error { return m } + +// PermissionsLookupEntityRequestValidationError is the validation error +// returned by PermissionsLookupEntityRequest.Validate if the designated +// constraints aren't met. +type PermissionsLookupEntityRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e PermissionsLookupEntityRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e PermissionsLookupEntityRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e PermissionsLookupEntityRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e PermissionsLookupEntityRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e PermissionsLookupEntityRequestValidationError) ErrorName() string { + return "PermissionsLookupEntityRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e PermissionsLookupEntityRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sPermissionsLookupEntityRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = PermissionsLookupEntityRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = PermissionsLookupEntityRequestValidationError{} + +var _PermissionsLookupEntityRequest_TenantId_Pattern = regexp.MustCompile("^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$") + +var _PermissionsLookupEntityRequest_EntityType_Pattern = regexp.MustCompile("^[a-zA-Z_]{1,64}$") + +var _PermissionsLookupEntityRequest_Permissions_Pattern = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") + // Validate checks the field values on PermissionLookupEntityRequestMetadata // with the rules defined in the proto definition for this message. If any // rules are violated, the first error encountered is returned, or nil if @@ -1616,51 +1981,307 @@ func (m *PermissionLookupEntityRequestMetadata) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on PermissionLookupEntityRequestMetadata -// with the rules defined in the proto definition for this message. If any -// rules are violated, the result is a list of violation errors wrapped in -// PermissionLookupEntityRequestMetadataMultiError, or nil if none found. -func (m *PermissionLookupEntityRequestMetadata) ValidateAll() error { +// ValidateAll checks the field values on PermissionLookupEntityRequestMetadata +// with the rules defined in the proto definition for this message. If any +// rules are violated, the result is a list of violation errors wrapped in +// PermissionLookupEntityRequestMetadataMultiError, or nil if none found. +func (m *PermissionLookupEntityRequestMetadata) ValidateAll() error { + return m.validate(true) +} + +func (m *PermissionLookupEntityRequestMetadata) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for SchemaVersion + + // no validation rules for SnapToken + + if m.GetDepth() < 3 { + err := PermissionLookupEntityRequestMetadataValidationError{ + field: "Depth", + reason: "value must be greater than or equal to 3", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return PermissionLookupEntityRequestMetadataMultiError(errors) + } + + return nil +} + +// PermissionLookupEntityRequestMetadataMultiError is an error wrapping +// multiple validation errors returned by +// PermissionLookupEntityRequestMetadata.ValidateAll() if the designated +// constraints aren't met. +type PermissionLookupEntityRequestMetadataMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m PermissionLookupEntityRequestMetadataMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m PermissionLookupEntityRequestMetadataMultiError) AllErrors() []error { return m } + +// PermissionLookupEntityRequestMetadataValidationError is the validation error +// returned by PermissionLookupEntityRequestMetadata.Validate if the +// designated constraints aren't met. +type PermissionLookupEntityRequestMetadataValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e PermissionLookupEntityRequestMetadataValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e PermissionLookupEntityRequestMetadataValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e PermissionLookupEntityRequestMetadataValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e PermissionLookupEntityRequestMetadataValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e PermissionLookupEntityRequestMetadataValidationError) ErrorName() string { + return "PermissionLookupEntityRequestMetadataValidationError" +} + +// Error satisfies the builtin error interface +func (e PermissionLookupEntityRequestMetadataValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sPermissionLookupEntityRequestMetadata.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = PermissionLookupEntityRequestMetadataValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = PermissionLookupEntityRequestMetadataValidationError{} + +// Validate checks the field values on PermissionLookupEntityResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *PermissionLookupEntityResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on PermissionLookupEntityResponse with +// the rules defined in the proto definition for this message. If any rules +// are violated, the result is a list of violation errors wrapped in +// PermissionLookupEntityResponseMultiError, or nil if none found. +func (m *PermissionLookupEntityResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *PermissionLookupEntityResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for ContinuousToken + + if len(errors) > 0 { + return PermissionLookupEntityResponseMultiError(errors) + } + + return nil +} + +// PermissionLookupEntityResponseMultiError is an error wrapping multiple +// validation errors returned by PermissionLookupEntityResponse.ValidateAll() +// if the designated constraints aren't met. +type PermissionLookupEntityResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m PermissionLookupEntityResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m PermissionLookupEntityResponseMultiError) AllErrors() []error { return m } + +// PermissionLookupEntityResponseValidationError is the validation error +// returned by PermissionLookupEntityResponse.Validate if the designated +// constraints aren't met. +type PermissionLookupEntityResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e PermissionLookupEntityResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e PermissionLookupEntityResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e PermissionLookupEntityResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e PermissionLookupEntityResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e PermissionLookupEntityResponseValidationError) ErrorName() string { + return "PermissionLookupEntityResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e PermissionLookupEntityResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sPermissionLookupEntityResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = PermissionLookupEntityResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = PermissionLookupEntityResponseValidationError{} + +// Validate checks the field values on PermissionsLookupEntityResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *PermissionsLookupEntityResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on PermissionsLookupEntityResponse with +// the rules defined in the proto definition for this message. If any rules +// are violated, the result is a list of violation errors wrapped in +// PermissionsLookupEntityResponseMultiError, or nil if none found. +func (m *PermissionsLookupEntityResponse) ValidateAll() error { return m.validate(true) } -func (m *PermissionLookupEntityRequestMetadata) validate(all bool) error { +func (m *PermissionsLookupEntityResponse) validate(all bool) error { if m == nil { return nil } var errors []error - // no validation rules for SchemaVersion + { + sorted_keys := make([]string, len(m.GetEntityIds())) + i := 0 + for key := range m.GetEntityIds() { + sorted_keys[i] = key + i++ + } + sort.Slice(sorted_keys, func(i, j int) bool { return sorted_keys[i] < sorted_keys[j] }) + for _, key := range sorted_keys { + val := m.GetEntityIds()[key] + _ = val - // no validation rules for SnapToken + // no validation rules for EntityIds[key] + + if all { + switch v := interface{}(val).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, PermissionsLookupEntityResponseValidationError{ + field: fmt.Sprintf("EntityIds[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, PermissionsLookupEntityResponseValidationError{ + field: fmt.Sprintf("EntityIds[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(val).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return PermissionsLookupEntityResponseValidationError{ + field: fmt.Sprintf("EntityIds[%v]", key), + reason: "embedded message failed validation", + cause: err, + } + } + } - if m.GetDepth() < 3 { - err := PermissionLookupEntityRequestMetadataValidationError{ - field: "Depth", - reason: "value must be greater than or equal to 3", - } - if !all { - return err } - errors = append(errors, err) } + // no validation rules for ContinuousToken + if len(errors) > 0 { - return PermissionLookupEntityRequestMetadataMultiError(errors) + return PermissionsLookupEntityResponseMultiError(errors) } return nil } -// PermissionLookupEntityRequestMetadataMultiError is an error wrapping -// multiple validation errors returned by -// PermissionLookupEntityRequestMetadata.ValidateAll() if the designated -// constraints aren't met. -type PermissionLookupEntityRequestMetadataMultiError []error +// PermissionsLookupEntityResponseMultiError is an error wrapping multiple +// validation errors returned by PermissionsLookupEntityResponse.ValidateAll() +// if the designated constraints aren't met. +type PermissionsLookupEntityResponseMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m PermissionLookupEntityRequestMetadataMultiError) Error() string { +func (m PermissionsLookupEntityResponseMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -1669,12 +2290,12 @@ func (m PermissionLookupEntityRequestMetadataMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m PermissionLookupEntityRequestMetadataMultiError) AllErrors() []error { return m } +func (m PermissionsLookupEntityResponseMultiError) AllErrors() []error { return m } -// PermissionLookupEntityRequestMetadataValidationError is the validation error -// returned by PermissionLookupEntityRequestMetadata.Validate if the -// designated constraints aren't met. -type PermissionLookupEntityRequestMetadataValidationError struct { +// PermissionsLookupEntityResponseValidationError is the validation error +// returned by PermissionsLookupEntityResponse.Validate if the designated +// constraints aren't met. +type PermissionsLookupEntityResponseValidationError struct { field string reason string cause error @@ -1682,24 +2303,24 @@ type PermissionLookupEntityRequestMetadataValidationError struct { } // Field function returns field value. -func (e PermissionLookupEntityRequestMetadataValidationError) Field() string { return e.field } +func (e PermissionsLookupEntityResponseValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e PermissionLookupEntityRequestMetadataValidationError) Reason() string { return e.reason } +func (e PermissionsLookupEntityResponseValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e PermissionLookupEntityRequestMetadataValidationError) Cause() error { return e.cause } +func (e PermissionsLookupEntityResponseValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e PermissionLookupEntityRequestMetadataValidationError) Key() bool { return e.key } +func (e PermissionsLookupEntityResponseValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e PermissionLookupEntityRequestMetadataValidationError) ErrorName() string { - return "PermissionLookupEntityRequestMetadataValidationError" +func (e PermissionsLookupEntityResponseValidationError) ErrorName() string { + return "PermissionsLookupEntityResponseValidationError" } // Error satisfies the builtin error interface -func (e PermissionLookupEntityRequestMetadataValidationError) Error() string { +func (e PermissionsLookupEntityResponseValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -1711,14 +2332,14 @@ func (e PermissionLookupEntityRequestMetadataValidationError) Error() string { } return fmt.Sprintf( - "invalid %sPermissionLookupEntityRequestMetadata.%s: %s%s", + "invalid %sPermissionsLookupEntityResponse.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = PermissionLookupEntityRequestMetadataValidationError{} +var _ error = PermissionsLookupEntityResponseValidationError{} var _ interface { Field() string @@ -1726,46 +2347,43 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = PermissionLookupEntityRequestMetadataValidationError{} +} = PermissionsLookupEntityResponseValidationError{} -// Validate checks the field values on PermissionLookupEntityResponse with the -// rules defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *PermissionLookupEntityResponse) Validate() error { +// Validate checks the field values on EntityIds with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *EntityIds) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on PermissionLookupEntityResponse with -// the rules defined in the proto definition for this message. If any rules -// are violated, the result is a list of violation errors wrapped in -// PermissionLookupEntityResponseMultiError, or nil if none found. -func (m *PermissionLookupEntityResponse) ValidateAll() error { +// ValidateAll checks the field values on EntityIds with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in EntityIdsMultiError, or nil +// if none found. +func (m *EntityIds) ValidateAll() error { return m.validate(true) } -func (m *PermissionLookupEntityResponse) validate(all bool) error { +func (m *EntityIds) validate(all bool) error { if m == nil { return nil } var errors []error - // no validation rules for ContinuousToken - if len(errors) > 0 { - return PermissionLookupEntityResponseMultiError(errors) + return EntityIdsMultiError(errors) } return nil } -// PermissionLookupEntityResponseMultiError is an error wrapping multiple -// validation errors returned by PermissionLookupEntityResponse.ValidateAll() -// if the designated constraints aren't met. -type PermissionLookupEntityResponseMultiError []error +// EntityIdsMultiError is an error wrapping multiple validation errors returned +// by EntityIds.ValidateAll() if the designated constraints aren't met. +type EntityIdsMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m PermissionLookupEntityResponseMultiError) Error() string { +func (m EntityIdsMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -1774,12 +2392,11 @@ func (m PermissionLookupEntityResponseMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m PermissionLookupEntityResponseMultiError) AllErrors() []error { return m } +func (m EntityIdsMultiError) AllErrors() []error { return m } -// PermissionLookupEntityResponseValidationError is the validation error -// returned by PermissionLookupEntityResponse.Validate if the designated -// constraints aren't met. -type PermissionLookupEntityResponseValidationError struct { +// EntityIdsValidationError is the validation error returned by +// EntityIds.Validate if the designated constraints aren't met. +type EntityIdsValidationError struct { field string reason string cause error @@ -1787,24 +2404,22 @@ type PermissionLookupEntityResponseValidationError struct { } // Field function returns field value. -func (e PermissionLookupEntityResponseValidationError) Field() string { return e.field } +func (e EntityIdsValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e PermissionLookupEntityResponseValidationError) Reason() string { return e.reason } +func (e EntityIdsValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e PermissionLookupEntityResponseValidationError) Cause() error { return e.cause } +func (e EntityIdsValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e PermissionLookupEntityResponseValidationError) Key() bool { return e.key } +func (e EntityIdsValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e PermissionLookupEntityResponseValidationError) ErrorName() string { - return "PermissionLookupEntityResponseValidationError" -} +func (e EntityIdsValidationError) ErrorName() string { return "EntityIdsValidationError" } // Error satisfies the builtin error interface -func (e PermissionLookupEntityResponseValidationError) Error() string { +func (e EntityIdsValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -1816,14 +2431,14 @@ func (e PermissionLookupEntityResponseValidationError) Error() string { } return fmt.Sprintf( - "invalid %sPermissionLookupEntityResponse.%s: %s%s", + "invalid %sEntityIds.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = PermissionLookupEntityResponseValidationError{} +var _ error = EntityIdsValidationError{} var _ interface { Field() string @@ -1831,7 +2446,7 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = PermissionLookupEntityResponseValidationError{} +} = EntityIdsValidationError{} // Validate checks the field values on PermissionLookupEntityStreamResponse // with the rules defined in the proto definition for this message. If any @@ -1942,6 +2557,117 @@ var _ interface { ErrorName() string } = PermissionLookupEntityStreamResponseValidationError{} +// Validate checks the field values on PermissionsLookupEntityStreamResponse +// with the rules defined in the proto definition for this message. If any +// rules are violated, the first error encountered is returned, or nil if +// there are no violations. +func (m *PermissionsLookupEntityStreamResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on PermissionsLookupEntityStreamResponse +// with the rules defined in the proto definition for this message. If any +// rules are violated, the result is a list of violation errors wrapped in +// PermissionsLookupEntityStreamResponseMultiError, or nil if none found. +func (m *PermissionsLookupEntityStreamResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *PermissionsLookupEntityStreamResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for EntityId + + // no validation rules for Permission + + // no validation rules for ContinuousToken + + if len(errors) > 0 { + return PermissionsLookupEntityStreamResponseMultiError(errors) + } + + return nil +} + +// PermissionsLookupEntityStreamResponseMultiError is an error wrapping +// multiple validation errors returned by +// PermissionsLookupEntityStreamResponse.ValidateAll() if the designated +// constraints aren't met. +type PermissionsLookupEntityStreamResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m PermissionsLookupEntityStreamResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m PermissionsLookupEntityStreamResponseMultiError) AllErrors() []error { return m } + +// PermissionsLookupEntityStreamResponseValidationError is the validation error +// returned by PermissionsLookupEntityStreamResponse.Validate if the +// designated constraints aren't met. +type PermissionsLookupEntityStreamResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e PermissionsLookupEntityStreamResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e PermissionsLookupEntityStreamResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e PermissionsLookupEntityStreamResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e PermissionsLookupEntityStreamResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e PermissionsLookupEntityStreamResponseValidationError) ErrorName() string { + return "PermissionsLookupEntityStreamResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e PermissionsLookupEntityStreamResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sPermissionsLookupEntityStreamResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = PermissionsLookupEntityStreamResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = PermissionsLookupEntityStreamResponseValidationError{} + // Validate checks the field values on PermissionEntityFilterRequest with the // rules defined in the proto definition for this message. If any rules are // violated, the first error encountered is returned, or nil if there are no violations. @@ -2026,33 +2752,38 @@ func (m *PermissionEntityFilterRequest) validate(all bool) error { } } - if all { - switch v := interface{}(m.GetEntrance()).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, PermissionEntityFilterRequestValidationError{ - field: "Entrance", - reason: "embedded message failed validation", - cause: err, - }) + for idx, item := range m.GetEntrances() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, PermissionEntityFilterRequestValidationError{ + field: fmt.Sprintf("Entrances[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, PermissionEntityFilterRequestValidationError{ + field: fmt.Sprintf("Entrances[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } } - case interface{ Validate() error }: + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { if err := v.Validate(); err != nil { - errors = append(errors, PermissionEntityFilterRequestValidationError{ - field: "Entrance", + return PermissionEntityFilterRequestValidationError{ + field: fmt.Sprintf("Entrances[%v]", idx), reason: "embedded message failed validation", cause: err, - }) - } - } - } else if v, ok := interface{}(m.GetEntrance()).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return PermissionEntityFilterRequestValidationError{ - field: "Entrance", - reason: "embedded message failed validation", - cause: err, + } } } + } if all { diff --git a/pkg/pb/base/v1/service_grpc.pb.go b/pkg/pb/base/v1/service_grpc.pb.go index 7ec7108e6..02fe958a0 100644 --- a/pkg/pb/base/v1/service_grpc.pb.go +++ b/pkg/pb/base/v1/service_grpc.pb.go @@ -19,12 +19,14 @@ import ( const _ = grpc.SupportPackageIsVersion8 const ( - Permission_Check_FullMethodName = "/base.v1.Permission/Check" - Permission_Expand_FullMethodName = "/base.v1.Permission/Expand" - Permission_LookupEntity_FullMethodName = "/base.v1.Permission/LookupEntity" - Permission_LookupEntityStream_FullMethodName = "/base.v1.Permission/LookupEntityStream" - Permission_LookupSubject_FullMethodName = "/base.v1.Permission/LookupSubject" - Permission_SubjectPermission_FullMethodName = "/base.v1.Permission/SubjectPermission" + Permission_Check_FullMethodName = "/base.v1.Permission/Check" + Permission_Expand_FullMethodName = "/base.v1.Permission/Expand" + Permission_LookupEntity_FullMethodName = "/base.v1.Permission/LookupEntity" + Permission_LookupEntities_FullMethodName = "/base.v1.Permission/LookupEntities" + Permission_LookupEntitiesStream_FullMethodName = "/base.v1.Permission/LookupEntitiesStream" + Permission_LookupEntityStream_FullMethodName = "/base.v1.Permission/LookupEntityStream" + Permission_LookupSubject_FullMethodName = "/base.v1.Permission/LookupSubject" + Permission_SubjectPermission_FullMethodName = "/base.v1.Permission/SubjectPermission" ) // PermissionClient is the client API for Permission service. @@ -43,6 +45,12 @@ type PermissionClient interface { // LookupEntity method receives a PermissionLookupEntityRequest and returns a PermissionLookupEntityResponse. // It is used to retrieve an entity by its identifier. LookupEntity(ctx context.Context, in *PermissionLookupEntityRequest, opts ...grpc.CallOption) (*PermissionLookupEntityResponse, error) + // LookupEntity method receives a PermissionsLookupEntityRequest and returns a PermissionsLookupEntityResponse. + // It is used to retrieve entities by its identifier. + LookupEntities(ctx context.Context, in *PermissionsLookupEntityRequest, opts ...grpc.CallOption) (*PermissionsLookupEntityResponse, error) + // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. + // It is used to retrieve entities by their identifiers in a streaming fashion. + LookupEntitiesStream(ctx context.Context, in *PermissionsLookupEntityRequest, opts ...grpc.CallOption) (Permission_LookupEntitiesStreamClient, error) // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. // It is used to retrieve entities by their identifiers in a streaming fashion. LookupEntityStream(ctx context.Context, in *PermissionLookupEntityRequest, opts ...grpc.CallOption) (Permission_LookupEntityStreamClient, error) @@ -92,9 +100,52 @@ func (c *permissionClient) LookupEntity(ctx context.Context, in *PermissionLooku return out, nil } +func (c *permissionClient) LookupEntities(ctx context.Context, in *PermissionsLookupEntityRequest, opts ...grpc.CallOption) (*PermissionsLookupEntityResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PermissionsLookupEntityResponse) + err := c.cc.Invoke(ctx, Permission_LookupEntities_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *permissionClient) LookupEntitiesStream(ctx context.Context, in *PermissionsLookupEntityRequest, opts ...grpc.CallOption) (Permission_LookupEntitiesStreamClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Permission_ServiceDesc.Streams[0], Permission_LookupEntitiesStream_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &permissionLookupEntitiesStreamClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Permission_LookupEntitiesStreamClient interface { + Recv() (*PermissionsLookupEntityStreamResponse, error) + grpc.ClientStream +} + +type permissionLookupEntitiesStreamClient struct { + grpc.ClientStream +} + +func (x *permissionLookupEntitiesStreamClient) Recv() (*PermissionsLookupEntityStreamResponse, error) { + m := new(PermissionsLookupEntityStreamResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *permissionClient) LookupEntityStream(ctx context.Context, in *PermissionLookupEntityRequest, opts ...grpc.CallOption) (Permission_LookupEntityStreamClient, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &Permission_ServiceDesc.Streams[0], Permission_LookupEntityStream_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &Permission_ServiceDesc.Streams[1], Permission_LookupEntityStream_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -161,6 +212,12 @@ type PermissionServer interface { // LookupEntity method receives a PermissionLookupEntityRequest and returns a PermissionLookupEntityResponse. // It is used to retrieve an entity by its identifier. LookupEntity(context.Context, *PermissionLookupEntityRequest) (*PermissionLookupEntityResponse, error) + // LookupEntity method receives a PermissionsLookupEntityRequest and returns a PermissionsLookupEntityResponse. + // It is used to retrieve entities by its identifier. + LookupEntities(context.Context, *PermissionsLookupEntityRequest) (*PermissionsLookupEntityResponse, error) + // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. + // It is used to retrieve entities by their identifiers in a streaming fashion. + LookupEntitiesStream(*PermissionsLookupEntityRequest, Permission_LookupEntitiesStreamServer) error // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. // It is used to retrieve entities by their identifiers in a streaming fashion. LookupEntityStream(*PermissionLookupEntityRequest, Permission_LookupEntityStreamServer) error @@ -186,6 +243,12 @@ func (UnimplementedPermissionServer) Expand(context.Context, *PermissionExpandRe func (UnimplementedPermissionServer) LookupEntity(context.Context, *PermissionLookupEntityRequest) (*PermissionLookupEntityResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LookupEntity not implemented") } +func (UnimplementedPermissionServer) LookupEntities(context.Context, *PermissionsLookupEntityRequest) (*PermissionsLookupEntityResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LookupEntities not implemented") +} +func (UnimplementedPermissionServer) LookupEntitiesStream(*PermissionsLookupEntityRequest, Permission_LookupEntitiesStreamServer) error { + return status.Errorf(codes.Unimplemented, "method LookupEntitiesStream not implemented") +} func (UnimplementedPermissionServer) LookupEntityStream(*PermissionLookupEntityRequest, Permission_LookupEntityStreamServer) error { return status.Errorf(codes.Unimplemented, "method LookupEntityStream not implemented") } @@ -262,6 +325,45 @@ func _Permission_LookupEntity_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Permission_LookupEntities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PermissionsLookupEntityRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServer).LookupEntities(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Permission_LookupEntities_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServer).LookupEntities(ctx, req.(*PermissionsLookupEntityRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Permission_LookupEntitiesStream_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(PermissionsLookupEntityRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(PermissionServer).LookupEntitiesStream(m, &permissionLookupEntitiesStreamServer{ServerStream: stream}) +} + +type Permission_LookupEntitiesStreamServer interface { + Send(*PermissionsLookupEntityStreamResponse) error + grpc.ServerStream +} + +type permissionLookupEntitiesStreamServer struct { + grpc.ServerStream +} + +func (x *permissionLookupEntitiesStreamServer) Send(m *PermissionsLookupEntityStreamResponse) error { + return x.ServerStream.SendMsg(m) +} + func _Permission_LookupEntityStream_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(PermissionLookupEntityRequest) if err := stream.RecvMsg(m); err != nil { @@ -338,6 +440,10 @@ var Permission_ServiceDesc = grpc.ServiceDesc{ MethodName: "LookupEntity", Handler: _Permission_LookupEntity_Handler, }, + { + MethodName: "LookupEntities", + Handler: _Permission_LookupEntities_Handler, + }, { MethodName: "LookupSubject", Handler: _Permission_LookupSubject_Handler, @@ -348,6 +454,11 @@ var Permission_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{ + { + StreamName: "LookupEntitiesStream", + Handler: _Permission_LookupEntitiesStream_Handler, + ServerStreams: true, + }, { StreamName: "LookupEntityStream", Handler: _Permission_LookupEntityStream_Handler, diff --git a/proto/base/v1/service.proto b/proto/base/v1/service.proto index bf2cf97cf..380f67a3e 100644 --- a/proto/base/v1/service.proto +++ b/proto/base/v1/service.proto @@ -390,6 +390,244 @@ service Permission { }; } + + // LookupEntity method receives a PermissionsLookupEntityRequest and returns a PermissionsLookupEntityResponse. + // It is used to retrieve entities by its identifier. + rpc LookupEntities(PermissionsLookupEntityRequest) returns (PermissionsLookupEntityResponse) { + // HTTP mapping for this method + option (google.api.http) = { + post: "/v1/tenants/{tenant_id}/permissions/lookup-entities" + body: "*" + }; + // OpenAPI annotations for this method + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "lookup entities" + tags: ["Permission"] + operation_id: "permissions.lookupEntities" + description: "" + extensions: { + key: "x-codeSamples" + value: { + list_value: { + values: { + struct_value: { + fields: { + key: "lang" + value: {string_value: "go"} + } + fields: { + key: "label" + value: {string_value: "go"} + } + fields: { + key: "source" + value: {string_value: + "cr, err := client.Permission.LookupEntities(context.Background(), &v1.PermissionsLookupEntityRequest{\n" + " TenantId: \"t1\",\n" + " Metadata: &v1.PermissionLookupEntityRequestMetadata{\n" + " SnapToken: \"\",\n" + " SchemaVersion: \"\",\n" + " Depth: 20,\n" + " },\n" + " EntityType: \"document\",\n" + " Permissions: [\"edit\"],\n" + " Subject: &v1.Subject{\n" + " Type: \"user\",\n" + " Id: \"1\",\n" + " }\n" + " PageSize: 20,\n" + " ContinuousToken: \"\",\n" + "})" +} + } + } + } + values: { + struct_value: { + fields: { + key: "lang" + value: {string_value: "javascript"} + } + fields: { + key: "label" + value: {string_value: "node"} + } + fields: { + key: "source" + value: {string_value: + "client.permission.lookupEntities({\n" + " tenantId: \"t1\",\n" + " metadata: {\n" + " snapToken: \"\",\n" + " schemaVersion: \"\",\n" + " depth: 20\n" + " },\n" + " entity_type: \"document\",\n" + " permissions: [\"edit\"],\n" + " subject: {\n" + " type: \"user\",\n" + " id: \"1\"\n" + " },\n" + " page_size: 20,\n" + " continuous_token: \"\"\n" + "}).then((response) => {\n" + " console.log(response.entity_ids)\n" + "})" +} + } + } + } + values: { + struct_value: { + fields: { + key: "lang" + value: {string_value: "curl"} + } + fields: { + key: "label" + value: {string_value: "cURL"} + } + fields: { + key: "source" + value: {string_value: + "curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/permissions/lookup-entities' \\\n" + "--header 'Content-Type: application/json' \\\n" + "--data-raw '{\n" + " \"metadata\":{\n" + " \"snap_token\": \"\",\n" + " \"schema_version\": \"\",\n" + " \"depth\": 20\n" + " },\n" + " \"entity_type\": \"document\",\n" + " \"permissions\": [\"edit\"],\n" + " \"subject\": {\n" + " \"type\":\"user\",\n" + " \"id\":\"1\"\n" + " },\n" + " \"page_size\": 20,\n" + " \"continuous_token\": \"\",\n" + "}'" +} + } + } + } + } + } + } + }; + } + + // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. + // It is used to retrieve entities by their identifiers in a streaming fashion. + rpc LookupEntitiesStream(PermissionsLookupEntityRequest) returns (stream PermissionsLookupEntityStreamResponse) { + // HTTP mapping for this method + option (google.api.http) = { + post: "/v1/tenants/{tenant_id}/permissions/lookup-entities-stream" + body: "*" + }; + // OpenAPI annotations for this method + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "lookup entities stream" + tags: ["Permission"] + operation_id: "permissions.lookupEntitiesStream" + description: "" + extensions: { + key: "x-codeSamples" + value: { + list_value: { + values: { + struct_value: { + fields: { + key: "lang" + value: {string_value: "go"} + } + fields: { + key: "label" + value: {string_value: "go"} + } + fields: { + key: "source" + value: {string_value: + "str, err := client.Permission.LookupEntitiesStream(context.Background(), &v1.PermissionsLookupEntityRequest{\n" + " Metadata: &v1.PermissionsLookupEntityRequestMetadata{\n" + " SnapToken: \"\",\n" + " SchemaVersion: \"\",\n" + " Depth: 50,\n" + " },\n" + " EntityType: \"document\",\n" + " Permissions: [\"view\"],\n" + " Subject: &v1.Subject{\n" + " Type: \"user\",\n" + " Id: \"1\",\n" + " },\n" + " PageSize: 20,\n" + " ContinuousToken: \"\",\n" + "})\n\n" + "// handle stream response\n" + "for {\n" + " res, err := str.Recv()\n\n" + " if err == io.EOF {\n" + " break\n" + " }\n\n" + " // res.EntityId, res.Permission\n" + "}" +} + } + } + } + values: { + struct_value: { + fields: { + key: "lang" + value: {string_value: "javascript"} + } + fields: { + key: "label" + value: {string_value: "node"} + } + fields: { + key: "source" + value: {string_value: + "const permify = require(\"@permify/permify-node\");\n" + "const {PermissionsLookupEntityStreamResponse} = require(\"@permify/permify-node/dist/src/grpc/generated/base/v1/service\");\n\n" + "function main() {\n" + " const client = new permify.grpc.newClient({\n" + " endpoint: \"localhost:3478\",\n" + " });\n\n" + " let res = client.permission.lookupEntitiesStream({\n" + " metadata: {\n" + " snapToken: \"\",\n" + " schemaVersion: \"\",\n" + " depth: 20\n" + " },\n" + " entityType: \"document\",\n" + " permissions: [\"view\"],\n" + " subject: {\n" + " type: \"user\",\n" + " id: \"1\"\n" + " },\n" + " page_size: 20,\n" + " continuous_token: \"\"\n" + " });\n\n" + " handle(res);\n" + "}\n\n" + "async function handle(res: AsyncIterable) {\n" + " for await (const response of res) {\n" + " // response.entityId, response.permission\n" + " }\n" + "}" +} + } + } + } + } + } + } + }; + } + + + // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. // It is used to retrieve entities by their identifiers in a streaming fashion. rpc LookupEntityStream(PermissionLookupEntityRequest) returns (stream PermissionLookupEntityStreamResponse) { @@ -988,6 +1226,81 @@ message PermissionLookupEntityRequest { ]; } +// PermissionsLookupEntityRequest is the request message for the LookupEntities method in the Permission service. +message PermissionsLookupEntityRequest { + // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. + string tenant_id = 1 [ + json_name = "tenant_id", + (validate.rules).string = { + pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" + max_bytes: 128 + ignore_empty: false + }, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} + ]; + + // Metadata associated with this request, required. + PermissionLookupEntityRequestMetadata metadata = 2 [ + json_name = "metadata", + (validate.rules).message.required = true + ]; + + // Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. + string entity_type = 3 [ + json_name = "entity_type", + (validate.rules).string = { + pattern: "^[a-zA-Z_]{1,64}$" + max_bytes: 64 + ignore_empty: false + } + ]; + + // Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. + repeated string permissions = 4 [json_name = "permissions", (validate.rules).repeated = { + min_items : 1, + max_items : 100, + items: { + string: { + pattern: "^[a-zA-Z_][a-zA-Z0-9_]*$", + max_bytes: 64, + ignore_empty: false + } + } + } + ]; + + // Subject for which to check the permission, required. + Subject subject = 5 [ + json_name = "subject", + (validate.rules).message.required = true + ]; + + // Context associated with this request. + Context context = 6 [json_name = "context"]; + + // Scope: A map that associates entity types with lists of identifiers. Each entry + // helps filter requests by specifying which entities are relevant to the operation. + map scope = 7 [json_name = "scope"]; + + // page_size is the number of entities to be returned in the response. + // The value should be between 1 and 100. + uint32 page_size = 8 [ + json_name = "page_size", + (validate.rules).uint32 = { + gte: 1 + ignore_empty: true + } + ]; + + // continuous_token is an optional parameter used for pagination. + // It should be the value received in the previous response. + string continuous_token = 9 [ + json_name = "continuous_token", + (validate.rules).string = {ignore_empty: true} + ]; +} + + // PermissionLookupEntityRequestMetadata metadata for the PermissionLookupEntityRequest. message PermissionLookupEntityRequestMetadata { // Version of the schema. @@ -1016,6 +1329,22 @@ message PermissionLookupEntityResponse { string continuous_token = 2 [json_name = "continuous_token"]; } + +// PermissionLookupEntityResponse is the response message for the LookupEntity method in the Permission service. +message PermissionsLookupEntityResponse { + // List of identifiers for entities that match the lookup. + map entity_ids = 1 [json_name = "entity_ids"]; + + // continuous_token is a string that can be used to paginate and retrieve the next set of results. + string continuous_token = 2 [json_name = "continuous_token"]; +} + +message EntityIds { + // entitiy Ids + repeated string ids = 1; +} + + // LOOKUP STREAM // PermissionLookupEntityStreamResponse is the response message for the LookupEntityStream method in the Permission service. @@ -1027,6 +1356,17 @@ message PermissionLookupEntityStreamResponse { string continuous_token = 2 [json_name = "continuous_token"]; } +message PermissionsLookupEntityStreamResponse { + // Identifier for an entity that matches the lookup. + string entity_id = 1 [json_name = "entity_id"]; + + // The name of the permission for which the specified entity_id has access + string permission = 2 [json_name = "permission"]; + + // continuous_token is a string that can be used to paginate and retrieve the next set of results. + string continuous_token = 3 [json_name = "continuous_token"]; +} + // PermissionEntityFilterRequest is the request message for the LookupEntityStream method in the Permission service. message PermissionEntityFilterRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. @@ -1047,7 +1387,7 @@ message PermissionEntityFilterRequest { ]; // Reference to the entity to filter. - Entrance entrance = 3 [json_name = "entrance"]; + repeated Entrance entrances = 3 [json_name = "entrances"]; // Subject for which to check the permission. Subject subject = 4 [json_name = "subject"];