Skip to content

API Reference#

Packages#

finops.stakater.com/v1alpha1#

Package v1alpha1 contains API Schema definitions for the finops v1alpha1 API group.

Resource Types#

AWSOptions#

AWSOptions defines AWS-specific options.

Appears in: - FinOpsProviderSpec

Field Description Default Validation
cloudIntegrationSecret string CloudIntegrationSecret is the Azure Subscription ID. Optional: {}
pricingModelSource string PricingModelSource indicates how the pricing model is provided to OpenCost.
e.g., "Pricebook" if derived from PriceBook CRs.
Optional: {}

AzureOptions#

AzureOptions defines Azure-specific options.

Appears in: - FinOpsProviderSpec

Field Description Default Validation
cloudIntegrationSecret string CloudIntegrationSecret is the Azure Subscription ID. Optional: {}
pricingModelSource string PricingModelSource indicates how the pricing model is provided to OpenCost.
e.g., "Pricebook" if derived from PriceBook CRs.
Optional: {}

Compatibility#

Compatibility defines compatibility requirements for subscriptions bound to this offering

Appears in: - OfferingSpec

Field Description Default Validation
requiredOfferings ObjectReference array RequiredOfferings lists offerings that must be covered by an active subscription in
the same family (the connected tree sharing a root ancestor) for a subscription to
this offering to activate. Coverage spans the whole family EXCEPT the subscription's
own subtree: ancestors, siblings, uncles, and cousins all count; the subscription's
own children and descendants do not. A root subscription's subtree is the entire
family, so a requirement-bearing root can never be covered.
Optional: {}

CostBucket#

Appears in: - SubscriptionStatus

Field Description Default Validation
granularity string Granularity is the time granularity of this bucket (e.g., hour, day, month). Enum: [hour day month]
start Time Start is the start time of the bucket (inclusive).
endExclusive Time EndExclusive is the end time of the bucket (exclusive).
current integer Current is the current accumulated spend for the period in micro-currency units. Optional: {}
projected integer Projected is the projected spend for the full period cycle in micro-currency units. Optional: {}
breakdown CostMetric array Breakdown contains the cost breakdown by component. Optional: {}

CostJob#

CostJob is the Schema for the costjobs API.

Field Description Default Validation
apiVersion string finops.stakater.com/v1alpha1
kind string CostJob
metadata ObjectMeta Refer to Kubernetes API documentation for fields of metadata.
spec CostJobSpec
status CostJobStatus

CostJobSpec#

CostJobSpec defines the desired state of CostJob.

Appears in: - CostJob

Field Description Default Validation
type CostJobType Type of the cost collection job, e.g., "ResourceCostCollection" ResourceCostCollection Enum: [ResourceCostCollection SubscriptionChargeCollection]
Optional: {}
databaseInitTimeout Duration DatabaseInitTimeout is the timeout for database initialization 2m Optional: {}
kubernetesOperationTimeout Duration KubernetesOperationTimeout is the timeout for Kubernetes API operations 1m Optional: {}
openCostFetchTimeout Duration OpenCostFetchTimeout is the timeout for fetching data from OpenCost 2m Optional: {}
databaseInsertTimeout Duration DatabaseInsertTimeout is the timeout for database insert operations 3m Optional: {}
databaseViewsRefreshTimeout Duration DatabaseViewsRefreshTimeout is retained for API compatibility and has no
effect. The cost ingestion job no longer refreshes any database view: the
mv_provider_allocations_summary materialized view it used to rebuild on
every run had no readers and was dropped in migration 14.
Deprecated: no-op. Setting this value changes nothing.
Optional: {}
statusUpdateTimeout Duration StatusUpdateTimeout is the timeout for status update operations 1m Optional: {}
httpClientTimeout Duration HTTPClientTimeout is the timeout for HTTP client requests 90s Optional: {}
interval Duration 24h
resources ResourceRequirements Resources overrides compute resources for the generated CronJob's loader container.
Setting this replaces the whole block, so a partial value does not inherit the
template defaults for the keys it omits. Unset means the operator defaults apply.
Optional: {}

CostJobStatus#

CostJobStatus defines the observed state of CostJob

Appears in: - CostJob

Field Description Default Validation
lastExecutionTime Time Last execution time
lastSuccessfulExecutionTime Time Last successful execution time
lastExecutionStatus string Status of the last execution Enum: [Success Failed Error Pending]
executionHistory ExecutionRecord array History of the last 10 executions

CostJobType#

Underlying type: string

Validation: - Enum: [ResourceCostCollection SubscriptionChargeCollection]

Appears in: - CostJobSpec

Field Description
ResourceCostCollection
SubscriptionChargeCollection

CostMetric#

Appears in: - CostBucket

Field Description Default Validation
name MeterName Name is the name of the cost metric (e.g., "cpuHour", "pvGbHour"). Enum: [subscription cpuHour gpuHour ramGbHour pvGbHour networkGb]
Required: {}
current integer Current is the current accumulated value in micro-currency units. Optional: {}
projected integer Projected is the projected value in micro-currency units. Optional: {}

ExecutionRecord#

ExecutionRecord represents a single execution attempt

Appears in: - CostJobStatus

Field Description Default Validation
executionTime Time The time when this execution started
status string Status of the execution (Success, Failed, Error) Enum: [Success Failed Error]
duration string Duration of the execution
error string Error message if the execution failed

FinOpsProvider#

FinOpsProvider is the Schema for the finopsproviders API.

Field Description Default Validation
apiVersion string finops.stakater.com/v1alpha1
kind string FinOpsProvider
metadata ObjectMeta Refer to Kubernetes API documentation for fields of metadata.
spec FinOpsProviderSpec
status FinOpsProviderStatus

FinOpsProviderSpec#

ProviderOptions holds provider-specific configuration options. Exactly one of AWS, GCP, Azure, or OnPrem must be set. These validations operate on the Go field names (AWS, GCP, Azure, OnPrem). Se https://opencost.io/docs/configuration/ for possible options todo: +kubebuilder:validation:XValidation:rule="has(self.Aws) || has(self.Gcp) || has(self.Azure) || has(self.OnPrem)", message="At least one provider option (awsoptions, gcpoptions, azureoptions, onpremoptions) must be set" todo: +kubebuilder:validation:XValidation:rule="(has(self.Aws) ? 1 : 0) + (has(self.Gcp) ? 1 : 0) + (has(self.Azure) ? 1 : 0) + (has(self.OnPrem) ? 1 : 0) == 1", message="Exactly one provider option (awsoptions, gcpoptions, azureoptions, onpremoptions) must be set"

Appears in: - FinOpsProvider

Field Description Default Validation
awsoptions AWSOptions AWS specific options. Optional: {}
gcpoptions GCPOptions GCP specific options. Optional: {}
azureoptions AzureOptions Azure specific options. Optional: {}
onpremoptions OnPremOptions OnPrem specific options. Optional: {}

FinOpsProviderStatus#

FinOpsProviderStatus defines the observed state of FinOpsProvider.

Appears in: - FinOpsProvider

Field Description Default Validation
observedGeneration integer ObservedGeneration reflects the generation of the most recently observed spec. Optional: {}
conditions Condition array Conditions represent the latest available observations of the FinOpsProvider's state. Optional: {}
lastSyncTime Time LastSyncTime is the timestamp of the last successful sync of OpenCost configuration. Optional: {}

GCPOptions#

GCPOptions defines GCP-specific options.

Appears in: - FinOpsProviderSpec

Field Description Default Validation
cloudIntegrationSecret string CloudIntegrationSecret is the Azure Subscription ID. Optional: {}
pricingModelSource string PricingModelSource indicates how the pricing model is provided to OpenCost.
e.g., "Pricebook" if derived from PriceBook CRs.
Optional: {}

Lifecycle#

Lifecycle defines lifecycle behavior for subscriptions

Appears in: - OfferingSpec

Field Description Default Validation
onParentDeactivate ParentDeactivateAction OnParentDeactivate toggles whether subscriptions to this offering should be deactivated when their parent subscription is deactivated
- Deactivate: this subscription also deactivates.
- Orphan: this subscription stays active independently, while retaining the parent reference for traceability.
Deactivate Enum: [Deactivate Orphan]
allowOverride boolean AllowOverride allows the subscription to override the lifecycle settings Optional: {}

Margins#

Margins defines pricing adjustments. AbsoluteMicros and FactorMilli are mutually exclusive — pick one mode per meter. Both must be non-negative: a negative margin would drive the per-unit price (and thus the usage charge) below zero, which usage meters don't support. Express a discount with a factorMilli below 1000 (e.g. 980 = 0.98x), not a negative absoluteMicros.

Appears in: - Meter

Field Description Default Validation
absoluteMicros integer AbsoluteMicros is an additive margin in micro-currency units (10^-6 of the currency)
1,000,000 micros = 1.00 currency unit
Example: 0.02 cents = 0.0002 currency units = 200 micros
Optional: {}
factorMilli integer FactorMilli is a multiplicative factor in milli-units
1000 = 1.000x, 1020 = 1.020x (adds 2%), 980 = 0.980x (discount 2%)
Optional: {}

Meter#

Meter defines pricing adjustments for a specific meter

Appears in: - Pricing

Field Description Default Validation
name MeterName Name is the name of the meter along with unit (e.g., "cpuHour", "ramGbHour"). Enum: [subscription cpuHour gpuHour ramGbHour pvGbHour networkGb]
Required: {}
margins Margins Margins adjusts the price derived from raw usage for this meter.
You can specify either:
- absoluteMicros: an additive margin in micro-currency units (10^-6 of the currency), or
- factorMilli: a multiplicative factor in milli-units (1000 = 1.000x, 1020 = 1.020x).
Optional: {}

MeterName#

Underlying type: string

MeterName defines the name of a usage meter for pricing adjustments

Validation: - Enum: [subscription cpuHour gpuHour ramGbHour pvGbHour networkGb]

Appears in: - CostMetric - Meter - ResolvedMeter

Field Description
subscription
cpuHour
gpuHour
ramGbHour
pvGbHour
networkGb MeterNetworkGB bills total data transferred (transfer + receive) per GiB.
No time dimension — the rate is per-GB, not per-GB-hour — hence no "Hour".

ObjectReference#

Appears in: - Compatibility - SubscriptionParent - SubscriptionSpec

Field Description Default Validation
name string Required: {}
namespace string Namespace of the referenced object. Must be set explicitly — references are
never resolved against the referrer's namespace, so the same reference always
means the same object no matter where it is authored. MinLength guards against
an empty string, which +required alone would accept.
MinLength: 1
Required: {}

Offering#

Offering describes a cost driving entity It owns the rules for how the base cost for that entity is collected and calculated

Field Description Default Validation
apiVersion string finops.stakater.com/v1alpha1
kind string Offering
metadata ObjectMeta Refer to Kubernetes API documentation for fields of metadata.
spec OfferingSpec
status OfferingStatus

OfferingSpec#

OfferingSpec defines the desired state of Offering.

Appears in: - Offering

Field Description Default Validation
pricing Pricing Pricing specifies how the price for this offering is calculated Required: {}
compatibility Compatibility Compatibility can be used for ensuring that any subscription created for this offering
has the required offerings in its parents or siblings
Optional: {}
lifecycle Lifecycle Lifecycle defines how subscriptions to this offering behave during certain lifecycle events Optional: {}

OfferingStatus#

OfferingStatus defines the observed state of Offering.

Appears in: - Offering

Field Description Default Validation
resolvedPricing ResolvedPricing ResolvedPricing contains the effective pricing derived from the offering spec Optional: {}
conditions Condition array Conditions represent the latest available observations of the Offering's state Optional: {}
ready ConditionStatus Ready indicates whether the offering is ready to be subscribed to (i.e., all required offerings are present and no circular dependencies detected)

OnPremOptions#

OnPremOptions defines On-Premise specific options.

Appears in: - FinOpsProviderSpec

Field Description Default Validation
pricingModelSource string PricingModelSource indicates how the pricing model is provided to OpenCost.
e.g., "Pricebook" if derived from PriceBook CRs.
Optional: {}

ParentDeactivateAction#

Underlying type: string

ParentDeactivateAction defines the behavior when a parent subscription is deactivated.

Validation: - Enum: [Deactivate Orphan]

Appears in: - Lifecycle - SubscriptionLifecycle

Field Description
Deactivate
Orphan

PriceBook#

PriceBook is the Schema for the pricebooks API

Field Description Default Validation
apiVersion string finops.stakater.com/v1alpha1
kind string PriceBook
metadata ObjectMeta Refer to Kubernetes API documentation for fields of metadata.
spec PriceBookSpec
status PriceBookStatus

PriceBookSpec#

PriceBookSpec defines the desired state of PriceBook

Appears in: - PriceBook

Field Description Default Validation
currency string The base currency for financial reporting and calculations (e.g., EUR, USD). Pattern: ^[A-Z]\{3\}$
Required: {}
valuationMode string The mode of valuation - either 'currency' for direct monetary rates or 'percent' for weighted scoring. Enum: [currency percent]
Required: {}
rates PriceRates Rates used for valuation in 'currency' mode. Defines cost per unit of resource. Required if valuationMode is 'currency'. Optional: {}

PriceBookStatus#

PriceBookStatus defines the observed state of PriceBook

Appears in: - PriceBook

Field Description Default Validation
active boolean Active indicates whether this PriceBook instance is currently designated as the active one
used for pricing calculations. This field is managed by the operator.
Optional: {}
ready ConditionStatus Ready indicates whether this PriceBook's rates are valid and it is usable
for pricing resolution. Managed by the operator.
Optional: {}
observedGeneration integer ObservedGeneration reflects the generation of the most recently observed spec. Optional: {}
conditions Condition array Conditions represent the latest available observations of the PriceBook's state. Optional: {}
activePricing object (keys:string, values:string) ActivePricing mirrors the OpenCost custom-pricing document (default.json)
this PriceBook has applied to OpenCost. Populated only on the active, ready
PriceBook (the one driving OpenCost); nil on every other PriceBook.
Managed by the operator.
Optional: {}

PriceRates#

PriceRates defines the cost rates for different resources. Each rate is a non-negative decimal string (e.g. "0.031"); empty means "unset". The pattern ^([0-9]+(\.[0-9]+)?)?$ rejects malformed values at admission while allowing empty.

Appears in: - PriceBookSpec

Field Description Default Validation
cpuHour string Cost per vCPU-hour (e.g., 0.031). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}
spotCPUHour string Cost per vCPU-hour (e.g., 0.031). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}
ramGbHour string Cost per GB-hour of RAM (e.g., 0.004). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}
spotRAMGbHour string Cost per GB-hour of spotRAM (e.g., 0.004). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}
pvGbHour string Cost per GB-hour of Persistent Volume (e.g., 0.00012). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}
gpuHour string Cost per GPU-hour (e.g., 1.8). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}
networkGiB string Cost per GiB of network data transferred (e.g., 0.09). Pattern: ^([0-9]+(\.[0-9]+)?)?$
Optional: {}

Pricing#

Pricing defines pricing rules for the offering

Appears in: - OfferingSpec

Field Description Default Validation
resourcePricing Meter array ResourcePricing defines per-meter pricing adjustments applied to raw usage.
Each meter can optionally define:
- includedUsage: an amount of usage included for free per subscription (same unit as the meter)
- margins: either an absolute add-on (in micro-currency) or a multiplicative factor (in milli-units)
Optional: {}
subscriptionFee SubscriptionFee SubscriptionFee defines the recurring fee charged for the subscription being active,
independent of resource usage
Optional: {}

ResolvedIncludedUsage#

ResolvedIncludedUsage contains the resolved included usage with its unit of measurement

Appears in: - ResolvedMeter

Field Description Default Validation
value integer Value is the amount of free usage included per subscription
unit string Unit is the unit of measurement (e.g., "GbHour", "CoreHour")

ResolvedMeter#

ResolvedMeter contains the effective per-unit price for a specific meter

Appears in: - ResolvedPricing

Field Description Default Validation
name MeterName Name is the meter name (e.g., "cpuHour", "ramGbHour") Enum: [subscription cpuHour gpuHour ramGbHour pvGbHour networkGb]
Required: {}
unitPriceMicros integer UnitPriceMicros is the effective per-unit price in micro-currency units (10^-6)
includedUsage ResolvedIncludedUsage IncludedUsage is the free usage included per subscription for this meter Optional: {}

ResolvedPricing#

ResolvedPricing contains the effective pricing that consumers see. It is derived from the offering spec and stamped on status during reconciliation.

Appears in: - OfferingStatus

Field Description Default Validation
resolvedAt Time ResolvedAt is the timestamp when pricing was last resolved
meters ResolvedMeter array Meters contains per-meter resolved unit prices after margins are applied.
Empty when no resource pricing is configured.
subscriptionFee SubscriptionFee SubscriptionFee contains the resolved subscription fee, if configured Optional: {}

Subscription#

Subscription is the Schema for the subscriptions API.

Field Description Default Validation
apiVersion string finops.stakater.com/v1alpha1
kind string Subscription
metadata ObjectMeta Refer to Kubernetes API documentation for fields of metadata.
spec SubscriptionSpec
status SubscriptionStatus

SubscriptionFee#

SubscriptionFee defines the recurring fee charged for the subscription being active, independent of resource usage.

Billing model: - The fee accrues over time in discrete "ticks" of length period. - Each tick contributes priceMicros to the total. - Ticks are aligned according to tickAlignment.

Tick alignment: - ActivatedAt: ticks start at status.activatedAt (tick boundaries are: activatedAt + N*period). Best for per-subscription billing cycles (common for add-ons). - HourBoundary / DayBoundary / MonthBoundary: ticks align to wall-clock boundaries. Best for synchronized billing windows across subscriptions (common for reporting).

Charging rule (deterministic per time window): For a time bucket [start, endExclusive), the subscription fee charged in that bucket is:

ticks(t) = number of full tick boundaries strictly before time t
feeInBucket = priceMicros * (ticks(endExclusive) - ticks(start))

This ensures exports are idempotent: the same [start, endExclusive) always yields the same fee.

Minimum commitment (minPeriods): - minPeriods defines the minimum number of periods to bill once the subscription becomes active. - If the subscription deactivates before minPeriods have elapsed, the remaining periods are billed as an adjustment at deactivation time, so the total billed periods is at least minPeriods.

All monetary values are expressed in micro-currency units (10^-6 of the currency).

Appears in: - Pricing - ResolvedPricing

Field Description Default Validation
period string Period is the tick interval. Its interpretation depends on tickAlignment:
- ActivatedAt: a Go duration string (e.g., "1h", "30m", "24h").
- HourBoundary: an integer number of hours (e.g., "1", "2").
- DayBoundary: an integer number of days (e.g., "1", "7").
- MonthBoundary: an integer number of months (e.g., "1", "3", "12").
tickAlignment TickAlignment TickAlignment defines where tick boundaries occur.
ActivatedAt: ticks start at status.activatedAt (tick boundaries are: activatedAt + N*period).
Best for per-subscription billing cycles (common for add-ons).
HourBoundary / DayBoundary / MonthBoundary: ticks align to wall-clock boundaries.
Best for synchronized billing windows across subscriptions (common for reporting).
For boundary-aligned modes, the first tick after activation covers a partial period
and is prorated: charge = priceMicros * actualDuration / periodDuration.
For MonthBoundary, the period duration denominator is a fixed 365.25/12 days (30.4375 days).
Enum: [ActivatedAt HourBoundary DayBoundary MonthBoundary]
minPeriods integer MinPeriods is the minimum number of full tick periods before deletion is allowed.
The collection job keeps the subscription finalizer until at least minPeriods ticks
have elapsed since activation. The subscription continues accruing charges normally
until the finalizer is removed.
Minimum: 1
Optional: {}
priceMicros integer PriceMicros is the price per tick, in micro-currency units Minimum: 1
Required: {}

SubscriptionLifecycle#

Appears in: - SubscriptionSpec

Field Description Default Validation
onParentDeactivate ParentDeactivateAction OnParentDeactivate controls what happens when the parent subscription deactivates:
- Deactivate: this subscription also deactivates.
- Orphan: this subscription stays active independently, while retaining the parent reference for traceability.
Orphan only detaches the parent lifecycle link; compatibility requirements are still enforced.
An orphan whose required offering was covered only by the now-deactivated parent (and by no
active sibling) is still deactivated, because keeping it active would violate the requirement.
Deactivate Enum: [Deactivate Orphan]
targetRef TargetReference TargetRef ties the lifecycle of the subscription to a target resource.
The subscription will not activate until the target status is Ready.
When the target is deleted, the subscription will be deactivated.
Optional: {}

SubscriptionParent#

Appears in: - SubscriptionSpec

Field Description Default Validation
subscriptionRef ObjectReference SubscriptionRef is a reference to the parent subscription. Required: {}

SubscriptionSpec#

SubscriptionSpec defines the desired state of Subscription. A Subscription creates a binding to an Offering, starting the clock and instantiating the offering. Effectively it starts consuming the cost-driving entity from a billing perspective.

offeringRef and parent are immutable: both determine what the subscription is billed for and which subscriptions provide its compatibility coverage, and a subscription's activation is a billing epoch that cannot be re-pointed.

Appears in: - Subscription

Field Description Default Validation
offeringRef ObjectReference OfferingRef is the reference to the Offering which is being subscribed to. Required: {}
parent SubscriptionParent Parent is an optional reference to a parent subscription for traceability.
For example, a storage subscription attached to a VM would reference the VM subscription.
Optional: {}
usageSources UsageSource array UsageSources defines from where the data for the resource usage of this subscription comes. Optional: {}
lifecycle SubscriptionLifecycle Lifecycle allows overriding lifecycle behavior if the Offering permits it.
If both parent and targetRef are set:
- activation requires BOTH (parent active AND target Ready)
- deactivation happens if EITHER stops applying, except parent deactivation is ignored when onParentDeactivate=Orphan
Note: onParentDeactivate=Orphan only governs the parent lifecycle link. It does not
exempt the subscription from its offering's compatibility requirements: if the deactivating
parent was the only active provider of a required offering, the subscription is still
deactivated for the coverage gap.
Optional: {}

SubscriptionStatus#

SubscriptionStatus defines the observed state of Subscription. Non-active subscriptions are ignored by scrape jobs. A subscription becomes active when: - parent.SubscriptionRef is set and the parent is active, and/or - targetRef is set and the target is Ready. Unset references are ignored. If neither reference is set, the subscription activates after spec validation.

Appears in: - Subscription

Field Description Default Validation
ready ConditionStatus Ready indicates whether the subscription is active and ready.
activatedAt Time ActivatedAt is the time when the subscription became active. Optional: {}
deactivatedAt Time DeactivatedAt is the time when the subscription was deactivated. Optional: {}
compatibilityRoot string CompatibilityRoot is the metadata.uid of this subscription's root ancestor,
resolved once by the controller. It identifies the connected family used
for compatibility coverage.
Optional: {}
costs CostBucket array Costs contains rolling cost summaries for the current hour, day, and month.
When populated, contains exactly 3 entries — one per granularity. // +optional
conditions Condition array Conditions represent the latest available observations of the Subscription's state. Optional: {}

TargetReference#

Appears in: - SubscriptionLifecycle

Field Description Default Validation
apiVersion string APIVersion is the API version of the target resource.
kind string Kind is the kind of the target resource.
namespace string Namespace is the namespace of the target resource. Optional: {}
name string Name is the name of the target resource.

TickAlignment#

Underlying type: string

TickAlignment defines where tick boundaries occur for subscription fee billing.

Validation: - Enum: [ActivatedAt HourBoundary DayBoundary MonthBoundary]

Appears in: - SubscriptionFee

Field Description
ActivatedAt ActivatedAt: ticks start at status.activatedAt (tick boundaries are: activatedAt + N*period).
Best for per-subscription billing cycles (common for add-ons).
HourBoundary HourBoundary ticks align to wall-clock hour boundaries (e.g., 1:00, 2:00, etc.).
DayBoundary DayBoundary ticks align to wall-clock day boundaries (e.g., 1 calender day).
MonthBoundary MonthBoundary ticks align to wall-clock month boundaries (e.g., 1st of each month).

UsageSource#

Appears in: - SubscriptionSpec

Field Description Default Validation
resourceType string ResourceType is the type of resource to track (e.g., Deployment, StatefulSet, Pod). Enum: [Deployment StatefulSet Pod DaemonSet Job CronJob ReplicaSet]
name string Name is the name of the specific resource instance. Optional: {}
namespace string Namespace is the namespace of the resource. Optional: {}