From a1cda2ec3e29319e0bcda2dc472119c51ae3c653 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Fri, 28 Aug 2026 21:01:36 +0000 Subject: [PATCH] Regenerate client from commit c38672d of spec repo --- .generator/schemas/v2/openapi.yaml | 44 +++ ...vabilityPipelineConfigDestinationItem.java | 89 +++++ ...pelineOpentelemetryMetricsDestination.java | 322 ++++++++++++++++++ ...neOpentelemetryMetricsDestinationType.java | 63 ++++ 4 files changed, 518 insertions(+) create mode 100644 src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestination.java create mode 100644 src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestinationType.java diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index c441901f41d..b6a3ce30c87 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -72524,6 +72524,7 @@ components: - $ref: "#/components/schemas/ObservabilityPipelineSyslogNgDestination" - $ref: "#/components/schemas/ObservabilityPipelineDatabricksZerobusDestination" - $ref: "#/components/schemas/ObservabilityPipelineDatadogMetricsDestination" + - $ref: "#/components/schemas/ObservabilityPipelineOpentelemetryMetricsDestination" - $ref: "#/components/schemas/ObservabilityPipelineSplunkHecMetricsDestination" ObservabilityPipelineConfigPipelineType: default: logs @@ -75170,6 +75171,49 @@ components: type: string x-enum-varnames: - OPENSEARCH + ObservabilityPipelineOpentelemetryMetricsDestination: + description: |- + The `opentelemetry` destination forwards metrics using the OpenTelemetry Protocol (OTLP) over HTTP. + + **Supported pipeline types:** metrics + properties: + buffer: + $ref: "#/components/schemas/ObservabilityPipelineBufferOptions" + http_client_uri_key: + default: DESTINATION_OTEL_HTTP_CLIENT_URI + description: Environment variable name containing the URI of the OTLP HTTP endpoint to send metrics to. + example: DESTINATION_OTEL_HTTP_CLIENT_URI + type: string + id: + description: The unique identifier for this component. Used in other parts of the pipeline to reference this component (for example, as the `input` to downstream components). + example: opentelemetry-metrics-destination + type: string + inputs: + description: A list of component IDs whose output is used as the `input` for this component. + example: ["metrics-filter-processor"] + items: + description: The ID of a component whose output is used as input for this destination. + type: string + type: array + tls: + $ref: "#/components/schemas/ObservabilityPipelineTls" + type: + $ref: "#/components/schemas/ObservabilityPipelineOpentelemetryMetricsDestinationType" + required: + - id + - type + - inputs + type: object + x-pipeline-types: [metrics] + ObservabilityPipelineOpentelemetryMetricsDestinationType: + default: opentelemetry + description: The destination type. Always `opentelemetry`. + enum: + - opentelemetry + example: opentelemetry + type: string + x-enum-varnames: + - OPENTELEMETRY ObservabilityPipelineOpentelemetrySource: description: |- The `opentelemetry` source receives telemetry data using the OpenTelemetry Protocol (OTLP) over gRPC and HTTP. diff --git a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineConfigDestinationItem.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineConfigDestinationItem.java index fb68db07218..285c5c013c3 100644 --- a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineConfigDestinationItem.java +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineConfigDestinationItem.java @@ -1431,6 +1431,61 @@ public ObservabilityPipelineConfigDestinationItem deserialize( e); } + // deserialize ObservabilityPipelineOpentelemetryMetricsDestination + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Integer.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Long.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Float.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Double.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Boolean.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Integer.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals( + Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Float.class) + || ObservabilityPipelineOpentelemetryMetricsDestination.class.equals( + Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (ObservabilityPipelineOpentelemetryMetricsDestination.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = + tree.traverse(jp.getCodec()) + .readValueAs(ObservabilityPipelineOpentelemetryMetricsDestination.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + if (!((ObservabilityPipelineOpentelemetryMetricsDestination) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log( + Level.FINER, + "Input data matches schema 'ObservabilityPipelineOpentelemetryMetricsDestination'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log( + Level.FINER, + "Input data does not match schema" + + " 'ObservabilityPipelineOpentelemetryMetricsDestination'", + e); + } + // deserialize ObservabilityPipelineSplunkHecMetricsDestination try { boolean attemptParsing = true; @@ -1656,6 +1711,12 @@ public ObservabilityPipelineConfigDestinationItem( setActualInstance(o); } + public ObservabilityPipelineConfigDestinationItem( + ObservabilityPipelineOpentelemetryMetricsDestination o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + public ObservabilityPipelineConfigDestinationItem( ObservabilityPipelineSplunkHecMetricsDestination o) { super("oneOf", Boolean.FALSE); @@ -1737,6 +1798,9 @@ public ObservabilityPipelineConfigDestinationItem( schemas.put( "ObservabilityPipelineDatadogMetricsDestination", new GenericType() {}); + schemas.put( + "ObservabilityPipelineOpentelemetryMetricsDestination", + new GenericType() {}); schemas.put( "ObservabilityPipelineSplunkHecMetricsDestination", new GenericType() {}); @@ -1766,6 +1830,7 @@ public Map getSchemas() { * ObservabilityPipelineSplunkHecDestination, ObservabilityPipelineSumoLogicDestination, * ObservabilityPipelineSyslogNgDestination, ObservabilityPipelineDatabricksZerobusDestination, * ObservabilityPipelineDatadogMetricsDestination, + * ObservabilityPipelineOpentelemetryMetricsDestination, * ObservabilityPipelineSplunkHecMetricsDestination * *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a @@ -1911,6 +1976,13 @@ public void setActualInstance(Object instance) { super.setActualInstance(instance); return; } + if (JSON.isInstanceOf( + ObservabilityPipelineOpentelemetryMetricsDestination.class, + instance, + new HashSet>())) { + super.setActualInstance(instance); + return; + } if (JSON.isInstanceOf( ObservabilityPipelineSplunkHecMetricsDestination.class, instance, @@ -1947,6 +2019,7 @@ public void setActualInstance(Object instance) { + " ObservabilityPipelineSyslogNgDestination," + " ObservabilityPipelineDatabricksZerobusDestination," + " ObservabilityPipelineDatadogMetricsDestination," + + " ObservabilityPipelineOpentelemetryMetricsDestination," + " ObservabilityPipelineSplunkHecMetricsDestination"); } @@ -1967,6 +2040,7 @@ public void setActualInstance(Object instance) { * ObservabilityPipelineSplunkHecDestination, ObservabilityPipelineSumoLogicDestination, * ObservabilityPipelineSyslogNgDestination, ObservabilityPipelineDatabricksZerobusDestination, * ObservabilityPipelineDatadogMetricsDestination, + * ObservabilityPipelineOpentelemetryMetricsDestination, * ObservabilityPipelineSplunkHecMetricsDestination * * @return The actual instance (ObservabilityPipelineElasticsearchDestination, @@ -1987,6 +2061,7 @@ public void setActualInstance(Object instance) { * ObservabilityPipelineSyslogNgDestination, * ObservabilityPipelineDatabricksZerobusDestination, * ObservabilityPipelineDatadogMetricsDestination, + * ObservabilityPipelineOpentelemetryMetricsDestination, * ObservabilityPipelineSplunkHecMetricsDestination) */ @Override @@ -2326,6 +2401,20 @@ public ObservabilityPipelineSyslogNgDestination getObservabilityPipelineSyslogNg return (ObservabilityPipelineDatadogMetricsDestination) super.getActualInstance(); } + /** + * Get the actual instance of `ObservabilityPipelineOpentelemetryMetricsDestination`. If the + * actual instance is not `ObservabilityPipelineOpentelemetryMetricsDestination`, the + * ClassCastException will be thrown. + * + * @return The actual instance of `ObservabilityPipelineOpentelemetryMetricsDestination` + * @throws ClassCastException if the instance is not + * `ObservabilityPipelineOpentelemetryMetricsDestination` + */ + public ObservabilityPipelineOpentelemetryMetricsDestination + getObservabilityPipelineOpentelemetryMetricsDestination() throws ClassCastException { + return (ObservabilityPipelineOpentelemetryMetricsDestination) super.getActualInstance(); + } + /** * Get the actual instance of `ObservabilityPipelineSplunkHecMetricsDestination`. If the actual * instance is not `ObservabilityPipelineSplunkHecMetricsDestination`, the ClassCastException will diff --git a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestination.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestination.java new file mode 100644 index 00000000000..da9abe202d8 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestination.java @@ -0,0 +1,322 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v2.model; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * The opentelemetry destination forwards metrics using the OpenTelemetry Protocol + * (OTLP) over HTTP. + * + *

Supported pipeline types: metrics + */ +@JsonPropertyOrder({ + ObservabilityPipelineOpentelemetryMetricsDestination.JSON_PROPERTY_BUFFER, + ObservabilityPipelineOpentelemetryMetricsDestination.JSON_PROPERTY_HTTP_CLIENT_URI_KEY, + ObservabilityPipelineOpentelemetryMetricsDestination.JSON_PROPERTY_ID, + ObservabilityPipelineOpentelemetryMetricsDestination.JSON_PROPERTY_INPUTS, + ObservabilityPipelineOpentelemetryMetricsDestination.JSON_PROPERTY_TLS, + ObservabilityPipelineOpentelemetryMetricsDestination.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class ObservabilityPipelineOpentelemetryMetricsDestination { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_BUFFER = "buffer"; + private ObservabilityPipelineBufferOptions buffer; + + public static final String JSON_PROPERTY_HTTP_CLIENT_URI_KEY = "http_client_uri_key"; + private String httpClientUriKey = "DESTINATION_OTEL_HTTP_CLIENT_URI"; + + public static final String JSON_PROPERTY_ID = "id"; + private String id; + + public static final String JSON_PROPERTY_INPUTS = "inputs"; + private List inputs = new ArrayList<>(); + + public static final String JSON_PROPERTY_TLS = "tls"; + private ObservabilityPipelineTls tls; + + public static final String JSON_PROPERTY_TYPE = "type"; + private ObservabilityPipelineOpentelemetryMetricsDestinationType type = + ObservabilityPipelineOpentelemetryMetricsDestinationType.OPENTELEMETRY; + + public ObservabilityPipelineOpentelemetryMetricsDestination() {} + + @JsonCreator + public ObservabilityPipelineOpentelemetryMetricsDestination( + @JsonProperty(required = true, value = JSON_PROPERTY_ID) String id, + @JsonProperty(required = true, value = JSON_PROPERTY_INPUTS) List inputs, + @JsonProperty(required = true, value = JSON_PROPERTY_TYPE) + ObservabilityPipelineOpentelemetryMetricsDestinationType type) { + this.id = id; + this.inputs = inputs; + this.type = type; + this.unparsed |= !type.isValid(); + } + + public ObservabilityPipelineOpentelemetryMetricsDestination buffer( + ObservabilityPipelineBufferOptions buffer) { + this.buffer = buffer; + this.unparsed |= buffer.unparsed; + return this; + } + + /** + * Configuration for buffer settings on destination components. + * + * @return buffer + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_BUFFER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ObservabilityPipelineBufferOptions getBuffer() { + return buffer; + } + + public void setBuffer(ObservabilityPipelineBufferOptions buffer) { + this.buffer = buffer; + if (buffer != null) { + this.unparsed |= buffer.unparsed; + } + } + + public ObservabilityPipelineOpentelemetryMetricsDestination httpClientUriKey( + String httpClientUriKey) { + this.httpClientUriKey = httpClientUriKey; + return this; + } + + /** + * Environment variable name containing the URI of the OTLP HTTP endpoint to send metrics to. + * + * @return httpClientUriKey + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_HTTP_CLIENT_URI_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getHttpClientUriKey() { + return httpClientUriKey; + } + + public void setHttpClientUriKey(String httpClientUriKey) { + this.httpClientUriKey = httpClientUriKey; + } + + public ObservabilityPipelineOpentelemetryMetricsDestination id(String id) { + this.id = id; + return this; + } + + /** + * The unique identifier for this component. Used in other parts of the pipeline to reference this + * component (for example, as the input to downstream components). + * + * @return id + */ + @JsonProperty(JSON_PROPERTY_ID) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ObservabilityPipelineOpentelemetryMetricsDestination inputs(List inputs) { + this.inputs = inputs; + return this; + } + + public ObservabilityPipelineOpentelemetryMetricsDestination addInputsItem(String inputsItem) { + this.inputs.add(inputsItem); + return this; + } + + /** + * A list of component IDs whose output is used as the input for this component. + * + * @return inputs + */ + @JsonProperty(JSON_PROPERTY_INPUTS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getInputs() { + return inputs; + } + + public void setInputs(List inputs) { + this.inputs = inputs; + } + + public ObservabilityPipelineOpentelemetryMetricsDestination tls(ObservabilityPipelineTls tls) { + this.tls = tls; + this.unparsed |= tls.unparsed; + return this; + } + + /** + * Configuration for enabling TLS encryption between the pipeline component and external services. + * + * @return tls + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_TLS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ObservabilityPipelineTls getTls() { + return tls; + } + + public void setTls(ObservabilityPipelineTls tls) { + this.tls = tls; + if (tls != null) { + this.unparsed |= tls.unparsed; + } + } + + public ObservabilityPipelineOpentelemetryMetricsDestination type( + ObservabilityPipelineOpentelemetryMetricsDestinationType type) { + this.type = type; + this.unparsed |= !type.isValid(); + return this; + } + + /** + * The destination type. Always opentelemetry. + * + * @return type + */ + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public ObservabilityPipelineOpentelemetryMetricsDestinationType getType() { + return type; + } + + public void setType(ObservabilityPipelineOpentelemetryMetricsDestinationType type) { + if (!type.isValid()) { + this.unparsed = true; + } + this.type = type; + } + + /** + * A container for additional, undeclared properties. This is a holder for any undeclared + * properties as specified with the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. If the property + * does not already exist, create it otherwise replace it. + * + * @param key The arbitrary key to set + * @param value The associated value + * @return ObservabilityPipelineOpentelemetryMetricsDestination + */ + @JsonAnySetter + public ObservabilityPipelineOpentelemetryMetricsDestination putAdditionalProperty( + String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + * + * @return The additional properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * + * @param key The arbitrary key to get + * @return The specific additional property for the given key + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** + * Return true if this ObservabilityPipelineOpentelemetryMetricsDestination object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ObservabilityPipelineOpentelemetryMetricsDestination + observabilityPipelineOpentelemetryMetricsDestination = + (ObservabilityPipelineOpentelemetryMetricsDestination) o; + return Objects.equals(this.buffer, observabilityPipelineOpentelemetryMetricsDestination.buffer) + && Objects.equals( + this.httpClientUriKey, + observabilityPipelineOpentelemetryMetricsDestination.httpClientUriKey) + && Objects.equals(this.id, observabilityPipelineOpentelemetryMetricsDestination.id) + && Objects.equals(this.inputs, observabilityPipelineOpentelemetryMetricsDestination.inputs) + && Objects.equals(this.tls, observabilityPipelineOpentelemetryMetricsDestination.tls) + && Objects.equals(this.type, observabilityPipelineOpentelemetryMetricsDestination.type) + && Objects.equals( + this.additionalProperties, + observabilityPipelineOpentelemetryMetricsDestination.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(buffer, httpClientUriKey, id, inputs, tls, type, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ObservabilityPipelineOpentelemetryMetricsDestination {\n"); + sb.append(" buffer: ").append(toIndentedString(buffer)).append("\n"); + sb.append(" httpClientUriKey: ").append(toIndentedString(httpClientUriKey)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" inputs: ").append(toIndentedString(inputs)).append("\n"); + sb.append(" tls: ").append(toIndentedString(tls)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" additionalProperties: ") + .append(toIndentedString(additionalProperties)) + .append("\n"); + sb.append('}'); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestinationType.java b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestinationType.java new file mode 100644 index 00000000000..37df44085ba --- /dev/null +++ b/src/main/java/com/datadog/api/client/v2/model/ObservabilityPipelineOpentelemetryMetricsDestinationType.java @@ -0,0 +1,63 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v2.model; + +import com.datadog.api.client.ModelEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** The destination type. Always opentelemetry. */ +@JsonSerialize( + using = + ObservabilityPipelineOpentelemetryMetricsDestinationType + .ObservabilityPipelineOpentelemetryMetricsDestinationTypeSerializer.class) +public class ObservabilityPipelineOpentelemetryMetricsDestinationType extends ModelEnum { + + private static final Set allowedValues = + new HashSet(Arrays.asList("opentelemetry")); + + public static final ObservabilityPipelineOpentelemetryMetricsDestinationType OPENTELEMETRY = + new ObservabilityPipelineOpentelemetryMetricsDestinationType("opentelemetry"); + + ObservabilityPipelineOpentelemetryMetricsDestinationType(String value) { + super(value, allowedValues); + } + + public static class ObservabilityPipelineOpentelemetryMetricsDestinationTypeSerializer + extends StdSerializer { + public ObservabilityPipelineOpentelemetryMetricsDestinationTypeSerializer( + Class t) { + super(t); + } + + public ObservabilityPipelineOpentelemetryMetricsDestinationTypeSerializer() { + this(null); + } + + @Override + public void serialize( + ObservabilityPipelineOpentelemetryMetricsDestinationType value, + JsonGenerator jgen, + SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonCreator + public static ObservabilityPipelineOpentelemetryMetricsDestinationType fromValue(String value) { + return new ObservabilityPipelineOpentelemetryMetricsDestinationType(value); + } +}