Billing
- class jelastic.api.billing.Billing(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
ClientAbstract
The Billing service provides methods for managing user accounts and their billing information.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing
Ref: https://docs.jelastic.com/api/#!/billing
- property Account: _Account
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Account
- property GroupQuota: _GroupQuota
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.GroupQuota
Ref: https://docs.jelastic.com/api/#!/api/billing.GroupQuota
- property Integration: _Integration
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Integration
Ref: https://docs.jelastic.com/api/#!/api/billing.Integration
- property Invoice: _Invoice
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Invoice
- property Order: _Order
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Order
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Order
- property PayMethod: _PayMethod
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.PayMethod
Ref: https://docs.jelastic.com/api/private/#!/api/billing.PayMethod
- property Pricing: _Pricing
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Pricing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Pricing
- property Reseller: _Reseller
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Reseller
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Reseller
- property ServicePlan: _ServicePlan
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.ServicePlan
Ref: https://docs.jelastic.com/api/private/#!/api/billing.ServicePlan
- property Subscription: _Subscription
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Subscription
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Subscription
- property System: _System
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.System
- property Utils: _Utils
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
>>> from jelastic import Jelastic >>> jelastic = Jelastic('https://app.xapp.cloudmydc.com', token='d6f4e314a5b5fefd164995169f28ae32d987704f') >>> jelastic.billing.Utils
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Utils
- class jelastic.api.billing._Account(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
The methods of this service provide billing information about a user account (such as UID, balance, billing history, quotas, etc.) and allow managing it.
Ref: https://docs.jelastic.com/api/#!/api/billing.Account
- ChangeGroup(group_name: str, uids: list[str] | None = None, send_email: bool = False, template: str | None = None, ruk: str | None = None)[source]
Change account group for selected users
- ChangePhoneNumber(login: str, number: str, ruk: str | None = None)[source]
Changes user’s phone number.
- ChargeAccountByUid(uid: int, amount: float, description: str, env_name: str | None = None, ruk: str | None = None)[source]
Charge account by uid.
- ConvertToCommercial(customer: dict, ruk: str | None = None)[source]
Make trial account commercial one. This method register Jbilling account into extern billing system. Commercial client can create auto payment, just pay service plans.
externBillingSystemId need if hoster has multiple billing systems. And its user belongs to one specific system. This is one place where it’s needed to point it obviously.
- ConvertToCommercialAndPay(customer: dict, pay_method_type: str, service_plan_id: int, auto_service_plan_id: int | None = None, auto_refill_main_balance: int | None = None, auto_refill_period: str | None = None, ruk: str | None = None)[source]
Make trial account commercial one. This method register Jbilling account into extern billing system. Commercial client can create auto payment, just pay service plans.
- ConvertToTrial(template: str, uids: list[str] | None = None, start_time: datetime | None = None, end_time: datetime | None = None, start: int | None = None, count: int | None = None, bonus: float | None = None, ruk: str | None = None)[source]
Converts non-trial and billing accounts to trial.
- ExportAccountBillingHistoryByPeriod(start_time: datetime, end_time: datetime, period: Literal['AGE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR'] = 'DAY', time_offset: int | None = None, group_nodes: bool = False, target_app_id: str | None = None, ruk: str | None = None)[source]
Generates a link for downloading the specified account’s billing history for the specific period.
- ExportEnvBillingHistoryByPeriod(start_time: datetime, end_time: datetime, time_offset: int, period: Literal['AGE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR'] = 'DAY', group_nodes: bool = False, ruk: str | None = None)[source]
Generates a link for downloading the specified environment’s billing history for the specific period.
- FundAccount(uid: int, amount: float, is_bonus: bool = False, note: str | None = None, ruk: str | None = None)[source]
Fund account by uid.
- Parameters:
uid – unique identifier of the target user whose balance will be changed
amount – positive value of money
is_bonus – false change bonus balance otherwise change main balance
note – note for transaction
- FundAndActivateAccount(uid: int, amount: float, note: str | None = None, ruk: str | None = None)[source]
Fund account by uid, activate it and set billing group.
- Parameters:
uid – unique identifier of the target user whose balance will be changed
amount – positive value of money
note – note for transaction
- GetAccountBillingByEngineTypeAndPeriod(start_time: datetime, end_time: datetime, owner_uid: str | None = None, engine_types: list[str] | None = None, period: Literal['AGE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR'] = 'DAY', time_offset: int | None = None, ruk: str | None = None)[source]
Returns account billing information for the specified period.
- Parameters:
owner_uid – owner uid
engine_types – list of engine types
start_time – start time of the period
end_time – end time of the period
period – period of the billing
time_offset – time offset
- GetAccountBillingHistoryByPeriod(start_time: datetime, end_time: datetime, period: Literal['AGE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR'] = 'DAY', time_offset: int | None = None, group_nodes: bool = False, target_app_id: str | None = None, ruk: str | None = None)[source]
Gets account billing history.
- GetAccounts(lebalance: str | None = None, order_field: str | None = None, order_direction: str | None = None, filter_field: str | None = None, filter_value: str | None = None, start_row: int | None = None, result_count: int | None = None, ruk: str | None = None)[source]
Gets accounts.
- GetAccountsByLimits(uidslimits: list[str], ruk: str | None = None)[source]
Gets accounts by limits.
- GetAccountsByPersonalThreshold(ruk: str | None = None)[source]
Get accounts for remind which balance less then setted by user.
- GetAccountsByUids(uids: list[str], lebalance: str | None = None, ruk: str | None = None)[source]
Gets accounts by user ids.
- GetAccountsForDeactivation(ruk: str | None = None)[source]
Get accounts for deactivation. Such as bonus is zero or trial period ended for trial accounts and balance less then allowed for billing accounts.
- GetAccountsForDestroying(ruk: str | None = None)[source]
Get accounts for destroying which in status inactive more then allowed.
- GetAggClusterBillingHistory(start_time: datetime, end_time: datetime, interval: int, sum_fields: list[str], is_paid: bool = False, ruk: str | None = None)[source]
Gets account billing history.
- GetAggExtraBillingHistory(start_time: datetime, end_time: datetime, interval: int, is_paid: bool = False, type: str | None = None, names: list[str] | None = None, ruk: str | None = None)[source]
- GetClusterBillingHistory(start_time: datetime, end_time: datetime, interval: int | None = None, ruk: str | None = None)[source]
Gets account billing history.
- GetCollaborationQuotas(collaboration_id: int | None = None, owner_uid: int | None = None, quota_names: list[str] | None = None, ruk: str | None = None)[source]
Gets list of quotas of the payer user.
- Parameters:
collaboration_id – unique identifier of the collaboration.
owner_uid – owner uid
quota_names – list of quota names to get values for
- GetCountries(ruk: str | None = None)[source]
Returns associative list of country names, regex patterns for VAT (tax payer id) and postal code, phone prefix and its two letter codes. Each extern billing could have its own representation so Jbilling settle this.
- GetCountryStates(country_code: str, ruk: str | None = None)[source]
Returns lists of states (provinces) for the specified country. If conversion to commercial group doesn’t requires to point client’s state then this method returns empty list.
- GetEnvBillingHistoryByPeriod(start_time: datetime, end_time: datetime, period: Literal['AGE', 'YEAR', 'MONTH', 'WEEK', 'DAY', 'HOUR'] = 'DAY', time_offset: int | None = None, group_nodes: bool = False, ruk: str | None = None)[source]
Gets environment billing history.
- GetExtendedAccountBillingHistoryByPeriod(start_time: datetime, end_time: datetime, target_app_id: str | None = None, ruk: str | None = None)[source]
Returns user’s billing history information for the specified period.
- Parameters:
start_time – start time of the period
end_time – end time of the period
target_app_id – target environment name
- GetExternBillingSystemSession(ruk: str | None = None)[source]
Session (some information) to interact with extern billing system as its client. It created automatically and garbaged. JBilling cache it and check. If you code fails try to recall this method.
- GetExternBillingSystems(ruk: str | None = None)[source]
The platform can work with multiple external billing systems. But each user can only be bound with one. Possible values: NullExternBilling, PbasExternBilling, PbaExternBilling.
- GetFundAccountHistory(start_time: datetime, end_time: datetime, uid: int, ruk: str | None = None)[source]
Getting Fund history account by uid.
- GetQuotas(quota_names: list[str] | None = None, ruk: str | None = None)[source]
Returns the values of the specified quotas for the user.
- Parameters:
quota_names – list of quota names to get values for
- GetSum(uid: int, start_time: datetime, end_time: datetime, ruk: str | None = None)[source]
Gets account summary debit and balance for period.
- GetSumAccountBillingHistory(uid: int, start_time: datetime, end_time: datetime, bonus: int | None = None, ruk: str | None = None)[source]
Gets account billing history.
- ResetTestAccounts(ruk: str | None = None)[source]
Resets a list of testing accounts on the platform.
- SetAccountStatus(uid: int, status: int, ruk: str | None = None)[source]
Sets account status. If new status is inactive then active environments are remembered and non stopped environments are shutdown. At activation all active environments are woken up.
- SetBillingInfo(customer: dict, ruk: str | None = None)[source]
Replaces existing account billing information with the provided value.
- Parameters:
customer – JSON object with the client’s billing information.
- SetGroup(uid: int, group_name: str, reset_balance: bool = False, reset_bonus: bool = False, ruk: str | None = None)[source]
Sets group to account.
- SetQuota(uid: int, name: str, value: str, reference_id: int | None = None, ruk: str | None = None)[source]
Changes quota value for the target account.
- Parameters:
uid – unique ID of the target user account.
name – a name of the quota to be adjusted.
value – custom value for the quota.
reference_id – reference ID of the quota.
- SurchargeAccounts(start_date: date, end_date: date, ruk: str | None = None)[source]
Surcharge accounts.
- SuspendUser(uid: int, ruk: str | None = None)[source]
Suspend account. This status deny signin for user.
- UnfundAccount(uid: int, amount: float, is_bonus: bool = False, note: str | None = None, ruk: str | None = None)[source]
Unfund account by uid.
- Parameters:
uid – unique identifier of the target user whose balance will be changed
amount – positive value of money
is_bonus – false change bonus balance otherwise change main balance
note – note for transaction
- class jelastic.api.billing._Invoice(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Invoice
- Event(extern_id: str, event_type: str, ruk: str | None = None)[source]
- Parameters:
extern_id – unique identifier of the document that was returned by external billing system
event_type – invoice event type (EXPIRED or PAID)
- GetExternalInvoices(limit: int | None = None, owner_uid: int | None = None, ruk: str | None = None)[source]
- Parameters:
limit – the maximum number of invoices returned in the response.
owner_uid – unique identifier of the invoice owner.
- GetInvoices(id: int | None = None, unique_name: str | None = None, type: str | None = None, status: str | None = None, subscription_id: int | None = None, subscription_status: str | None = None, order_fields: str | None = None, order_direction: str | None = None, start_row: int | None = None, result_count: int | None = None, expand_fields: str | None = None, ruk: str | None = None)[source]
- Parameters:
id – unique identifier of the target invoice.
unique_name – a name of the target invoice that is provided to the end-user.
type – invoice type (POST_PAYMENT or SUBSCRIPTION).
status – a semicolon-separated list of invoice statuses.
subscription_id – unique identifier of the target subscription.
subscription_status – a semicolon-separated list of the subscription statuses.
order_fields – sorts results by the specified field.
order_direction – sorts results in the ascending (ASC) or descending (DESC) order.
start_row – returns information starting from the specified row in the response (starts with 0, by default).
result_count – returns the specified number of rows from the response (0 – unlimited – by default).
expand_fields – there are fields that are not included in responses by default. You can request these fields as an expanded response by listing required object paths in this parameter (e.g. account.group
- MakeInvoice(uid: str, skip_pay: bool | None = None, ruk: str | None = None)[source]
- Parameters:
uid – a comma-separated list of target POST-paid users’ unique identifiers (all, if not set).
skip_pay – a flag that disables (true) or enables (false) auto-pay with a default payment method
- MarkAsPaid(id: int | None = None, ebs_invoice_id: str | None = None, ruk: str | None = None)[source]
- Parameters:
id – unique identifier of the target invoice.
ebs_invoice_id – unique identifier of the target invoice in the external billing system.
- MarkAsVoid(id: int | None = None, ebs_invoice_id: str | None = None, ruk: str | None = None)[source]
- Parameters:
id – unique identifier of the target invoice.
ebs_invoice_id – unique identifier of the target invoice in the external billing system.
- Pay(id: int, payment_method_id: str | None = None, payment_method_type: str | None = None, ruk: str | None = None)[source]
- Parameters:
id – unique identifier of the target invoice.
payment_method_id – unique identifier of the payment method type.
payment_method_type – type of the payment method.
- SearchInvoices(search: str, expand_fields: str | None = None, reseller_id: int | None = None, ruk: str | None = None)[source]
- Parameters:
search – a search string in the JSON format. For example: {“startDate”:”2023-01-23 00:00:00”,”endDate”:”2023-01-30 23:59:59”,”orderField”:”id”,”orderDirection”:”DESC”,”startRow”:0,”resultCount”:10}
expand_fields – there are fields that are not included in responses by default. You can request these fields as an expanded response by listing required object paths in this parameter (e.g. account.group).
reseller_id – unique identifier of the target reseller platform.
- class jelastic.api.billing._GroupQuota(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/#!/api/billing.GroupQuota
- AddGroup(type: str, name: str, description: str | None = None, source_group_name: str | None = None, domain: str | None = None, conversion_group: str | None = None, ruk: str | None = None)[source]
- Parameters:
type – quota group type.
name – unique name of the target quota group.
description – custom description for the quota group.
source_group_name – name of the quota group to be used as a source for the new group.
domain – domain name of the target platform.
conversion_group – name of the quota group to be used after conversion.
- AddQuota(name: str, description: str | None = None, reference_id: str | None = None, default_value: int | None = None, assign_to_group: bool | None = None, ruk: str | None = None)[source]
- Parameters:
name – a name of the quota to be created.
description – custom quota description.
reference_id – reference ID of the quota.
default_value – quota’s default value.
assign_to_group – a flag that indicates if this quota could (true) or not (false) be assigned to groups.
- EditGroup(name: str, new_name: str | None = None, description: str | None = None, conversion_group: str | None = None, ruk: str | None = None)[source]
- Parameters:
name – unique name of the target quota group.
new_name – a new name for the quota group.
description – custom description for the quota group.
conversion_group – name of the quota group to be used after conversion.
- EditQuota(name: str, reference_id: str | None = None, new_reference_id: str | None = None, description: str | None = None, ruk: str | None = None)[source]
param name: unique a name of the quota to be adjusted. param reference_id: reference ID of the quota. param description: custom quota description.
- RemoveQuota(name: str, force: bool | None = None, reference_id: str | None = None, ruk: str | None = None)[source]
- Parameters:
name – a name of the quota to be removed.
force – proceeds (true) or interrupts (false) the operation in case of errors.
reference_id – reference ID of the quota.
- SetGroupQuota(group_name: str, quota_name: str, value: int, reference_id: str | None = None, ruk: str | None = None)[source]
- Parameters:
group_name – unique name of the target group.
quota_name – a name of the quota to be adjusted.
value – custom value for the quota.
reference_id – reference ID of the quota.
- class jelastic.api.billing._Integration(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/administration.Integration
- class jelastic.api.billing._PayMethod(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.PayMethod
- EnablePayMethod(pay_method_id: str, enable: int, ruk: str | None = None)[source]
- Parameters:
pay_method_id – payment method ID to be set as default one (see the GetPayMethodList method)
enable – enables (1) or disables (0) the provided payment method
- RegisterBankCard(first_name: str, last_name: str, card_number: str, card_code: str, expire_month: int, expire_year: int, service_plan_id: int, ruk: str | None = None)[source]
- Parameters:
first_name – exactly as on the card
last_name – exactly as on the card
card_number – very big number
card_code – 4 digits.
expire_month – exactly as on the card. from 1 to 12
expire_year – year in format yyyy
service_plan_id – service plan id to buy for check card or 0 then min test pay is used.
- RegisterPayMethodAndPay(pay_method_type: str, service_plan_id: int, auto_service_plan_id: int | None = None, auto_refill_min_balance: int | None = None, auto_refill_period: str | None = None, ruk: str | None = None)[source]
- Parameters:
pay_method_type – take value from item of GetValidPayTypes response
auto_service_plan_id – service plan id for auto refill, should 0 or -1 if none
auto_refill_min_balance – min balance threshold when by new service plan
auto_refill_period – accepted string literals “WEEK” and “MONTH”
- class jelastic.api.billing._Pricing(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Pricing
- AddPricing(pricing: dict, tariff_ids: str, tariff_grid_names: str | None = None, ruk: str | None = None)[source]
- CheckHostGroupsAllowed(owner_uid: int | None = None, hardware_node_groups: str | None = None, ruk: str | None = None)[source]
- Parameters:
owner_uid – unique identifier of the target user.
hardware_node_groups – a comma-separated list of the host groups to be checked.
- GetPricingInner(reseller_id: int | None = None, ruk: str | None = None)[source]
- Parameters:
reseller_id – unique ID of the target reseller platform
- GetTariffsInner(pricing_id: str | None = None, type: str | None = None, reseller_id: int | None = None, ruk: str | None = None)[source]
- Parameters:
pricing_id – pricing model unique ID.
type – a semicolon-separated list of tariff types.
reseller_id – unique ID of the target reseller platform.
- SetTariffs(pricing_id: str, tariff_ids: str, tariff_grid_names: str | None = None, ruk: str | None = None)[source]
- ValidateEnvironment(hardware_node_group: str, owner_uid: int | None = None, ruk: str | None = None)[source]
- class jelastic.api.billing._Reseller(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Reseller
- class jelastic.api.billing._ServicePlan(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.ServicePlan
- class jelastic.api.billing._Subscription(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Subscription
- class jelastic.api.billing._Order(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Order
- class jelastic.api.billing._Utils(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.Utils
- ClearBillingHistory(env_name: str, uid: int, start_date: datetime, end_date: datetime, checksum: str, ruk: str | None = None)[source]
- GetUidUsageByPeriod(uid: int, start_date: datetime, end_date: datetime, checksum: str, ruk: str | None = None)[source]
- SetAccountDate(uid: int, date_type: str, date_value: str, checksum: str, ruk: str | None = None)[source]
- class jelastic.api.billing._System(session: Session, token: str, debug: bool = False, ruk: str | None = None)[source]
Bases:
Billing
Ref: https://docs.jelastic.com/api/private/#!/api/billing.System
- CleanCheckRequestCache(uid: int | None = None, local_only: bool | None = None, ruk: str | None = None)[source]
- GetAPIDescriptions(is_public_only: bool | None = None, is_token: bool | None = None, ruk: str | None = None)[source]
- ReloadConfiguration(reseller_id: int | None = None, changed_placeholders: str | None = None, ruk: str | None = None)[source]