Coder Social home page Coder Social logo

jonahsnider / convert Goto Github PK

View Code? Open in Web Editor NEW
112.0 3.0 18.0 23.36 MB

The smallest & fastest library for really easy, totally type-safe unit conversions in TypeScript & JavaScript.

Home Page: https://convert.js.org

License: MIT License

TypeScript 97.58% JavaScript 1.05% Just 1.37%
typescript uom convert-units convert javascript si-units unit-conversions conversions hacktoberfest metric

convert's Introduction

Convert

The smallest & fastest library for really easy, totally type-safe unit conversions in TypeScript & JavaScript.

bundle size npm monthly downloads

npm install convert
# or
yarn add convert

More installation examples below.

convert(5, "miles").to("km");
convertMany("4d 16h").to("minutes");

Features

  • Full build time and runtime validation of conversions
  • Web frameworks like Next.js and Vite know that Convert is side-effect free, so conversions will be precalculated at build-time, absolutely zero conversion code is sent to clients
  • Runs anywhere (browsers, Node, Bun, etc), full ES3 backwards-compatibility
  • Tiny bundle size and 0 dependencies
  • Supports bigints

Usage

Generated API documentation for the latest version is available online.

View docs.

// ESM:
import convert from "convert";
// CJS:
const { convert } = require("convert");

// 360 seconds into minutes
convert(360, "seconds").to("minutes");
// -> 6

// BigInt support
convert(20n, "hours").to("minutes");
// -> 1200n

// Format to the best unit automatically
convert(5500, "meters").to("best");
// -> { quantity: 5.5, unit: 'km', toString: () => '5.5km' }

// You can also do length, data, volume, mass, temperature, and more
convert(5, "kilometers").to("nautical miles");
convert(12, "pounds").to("ounces");
convert(8192, "bytes").to("KiB");
convert(10, "atmospheres").to("kPa");
convert(451, "fahrenheit").to("celsius");

Converting many units

import { convertMany } from "convert";
const { convertMany } = require("convert");

// Convert 1 day and 8 hours into ms
convertMany("1d8h").to("ms");

Converting to best unit

import convert from "convert";
const { convert } = require("convert");

// Convert into the best unit
const duration = convert(36, "h").to("best");
// -> { quantity: 1.5, unit: 'd', toString: () => '1.5d' }

// The toString() method means you can automatically cast the object to a string without any issues
"duration is " + duration;
// -> duration is 1.5d

// You can also specify to use a specific kind of units (metric or imperial, metric is default)
convert(3.5, "km").to("best"); // -> { quantity: 3.5, unit: 'km', toString: () => '3.5km' }
convert(3.5, "km").to("best", "metric"); // -> { quantity: 3.5, unit: 'km', toString: () => '3.5km' }
convert(3.5, "km").to("best", "imperial"); // -> { quantity: 2.17, unit: 'mi', toString: () => '3.5mi' }

ms shorthand

import { ms } from "convert";
const { ms } = require("convert");

// Convert a duration into milliseconds
ms("1d 2h 30min");
// -> 95400000

// Convert milliseconds to a string
ms(86400000);
// -> '1d'

Installation

Package manager

Convert is published as convert on npm.

npm install convert
# or
yarn add convert

And then import it in your code like this:

// CommonJS
const { convert } = require("convert");

// ESM
import convert from "convert";

Browsers

Pick your favorite CDN:

ES Modules via CDN

<script type="module">
	import convert from "https://cdn.skypack.dev/convert@5";
	import convert from "https://esm.run/convert@5";
	import convert from "https://cdn.jsdelivr.net/npm/convert@5";
	import convert from "https://unpkg.com/convert@5";
</script>

UMD (global)

<script src="https://cdn.jsdelivr.net/npm/convert@5/dist/index.js"></script>
<script src="https://unpkg.com/convert@5/dist/index.js"></script>

Alternatives

Convert is better than other unit conversion libraries because it's faster and smaller than them, while having the same features. Benchmarks of popular unit conversion libraries, including Convert are available here.

Convert is the fastest, taking less than a microsecond for all functions. That's a little over 3 million convert() calls per second.

Bundle size comparison

npm bundle size of convert

npm bundle size of safe-units

npm bundle size of convert-units

npm bundle size of js-quantities

npm bundle size of uom + npm bundle size of uom-units

convert's People

Contributors

cyruseuros avatar dependabot[bot] avatar filipef101 avatar furrycatherder avatar github-actions[bot] avatar jonahsnider avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

convert's Issues

meters to feet ratio is wrong

I'm using two different conversion utilities. meters to feet conversion isn't matching. I realized the ratio used here is rounded and not right.

{ names: ['foot', 'feet'], symbols: ['ft', "'"], ratio: 0.3048 },

1 m = 3.28084 ft
or
1 ft = 0.3047999902464003 m

Meters to kilometers and rounding

Hi, I couldn't find any information about doing a round operation automatically or even triggering it with some param.

So while the examples in readme seems to be accurate, the example of convert(1930536, 'meters').to('best').toString() returns me an ugly result of 1930.5359999999998km. I expected to maybe get 1930.54km as a result when using a "best" param.

Export is not a function in UMD build

          This issue still persists as of v4.13.2. It shows "Uncaught TypeError: convert is not a function" error

Originally posted by @mahony0 in #560 (comment)


Moving discussion here, as the bug you are describing is not the one in the issue originally commented in

Energy units

It seems that there are no energy units included (joule, kcal, watt, kWhm btu, etc.), I think it would be a great addition.

Using convert with vanilla JS doesn't work

I tried the unpkg link for this repo and it did not work. I hacked the script to extract the convert, convertMany, and ms functions out (if you're looking to do this just set e to an external variable where e.convert is being set.)

Maybe I did something wrong but I had to hack it to extract the convert function at all. It doesn't set on the window.

Cannot get KB, MB, etc. units when using "best" for data conversion

When using the "best" parameter for data conversion it always returns the binary unit (KiB, MiB, etc.) for both the "imperial" or "metric" parameter. I think when using the "metric" param, it should be returning MB, GB, etc.

This seems to be a simple change in your bestUnits type for the "metric" kind, was hoping this could be updated.

Thanks!

[Q] Can i convert from squared millimeters to meters with this library?

Hiya,

I'm trying to convert from squared millimetres (mm2) to squared meters (m2) or 'best' since the values can get quite large.
I'm not finding any options for squared values with intellisense in vscode, but i do see some cubic (m3) conversions.

Am i blind or can someone point me in the right direction?

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Pending Branch Automerge

These updates await pending status checks before automerging. Click on a checkbox to abort the branch automerge, and create a PR instead.

  • build(deps): update vitest monorepo to v1.6.0 (@vitest/coverage-v8, @vitest/ui, vitest)

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v4
  • actions/setup-node v4
  • oven-sh/setup-bun v1
  • actions/checkout v4
  • actions/setup-node v4
  • oven-sh/setup-bun v1
.github/workflows/release-please.yml
  • google-github-actions/release-please-action v4
  • actions/checkout v4
  • actions/setup-node v4
  • oven-sh/setup-bun v1
  • actions/setup-node v4
nodenv
.node-version
  • node 20
npm
package.json
  • @babel/core 7.24.5
  • @babel/preset-env 7.24.5
  • @biomejs/biome 1.7.3
  • @jonahsnider/util 11.0.0
  • @microsoft/api-extractor 7.43.4
  • @rollup/plugin-babel 6.0.4
  • @rollup/plugin-node-resolve 15.2.3
  • @rollup/plugin-swc 0.3.0
  • @rollup/plugin-terser 0.4.4
  • @size-limit/preset-small-lib 11.1.3
  • @swc/core 1.5.5
  • @tsconfig/node20 20.1.4
  • @tsconfig/strictest 2.0.5
  • @types/node 20.12.11
  • @vitest/coverage-v8 1.3.1
  • @vitest/ui ^1.2.2
  • bignumber.js 9.1.2
  • just-install 2.0.1
  • rollup 4.17.2
  • size-limit 11.1.3
  • typedoc 0.25.13
  • typescript 5.4.5
  • vitest 1.3.1
  • yarn 4.2.2

  • Check this box to trigger a request for Renovate to run again on this repository

please double check square

please double check square because these are not working correctly

square kilometers
square centimeters
square millimeters
square micrometers

BTU support

Is there any support for BTU? sorry if this is the wrong channel.

Ability to convert speed

Looking through the docs I dont see any conversion types for speed. I often work in inches per second, but threejs uses meters so I have to convert. Would be great to get this built in or the ability to define custom units. If possible, I think a generic solution for this would be best where you can use any already defined length unit over any defined time unit instead of adding in specifically in/s, m/s, miles/h, etc...

With this, the dividend I guess could also be an angle... degrees/s, radians/m, etc.

use 'm' for minutes

Is there a way to use m for minutes with the ms shorthand utility? I see m is used for meters currently but its also commonly used for minutes. (even in the ms package)

Library can't handle ASCII char for "micro" (Β΅)

Hey!

The "Β΅" char in this library has the char code 956 (unicode). Our backend responses with a unit string "Β΅m" where the "Β΅" has the char code 181 (ASCII).

The library can't handle this char and throws an RangeError.

image

Duplicated code and Failure to expand tonnes in mass.ts

Issue: Duplicated code and Failure to expand tonnes in mass.ts

Description:
There is a duplication of code in the mass.ts file, specifically in the conversions array. The expandMacro method is called twice with the same parameters, resulting in the duplication of conversions and a potential oversight. Additionally, this duplication prevents the proper expansion of units for ton (tonne) measurements.

Steps to Reproduce:

  1. Go to the mass.ts file.
  2. Locate the conversions array.
  3. Notice that the expandMacro method is called twice with the same parameters.

Expected Behavior:
The expandMacro method should be called only once with the appropriate parameters to avoid duplicated conversions. Furthermore, the expansion of units for ton (tonne) measurements should be included.

Actual Behavior:
The expandMacro method is called twice with the same parameters, leading to duplicate conversions. As a result, the expansion of units for ton (tonne) measurements is not present in the conversions.

Code Snippet:

const poundInGrams = new BigNumber(4.535_923_7e2);

export const mass: ReadonlyDeep<Family> = {
	// ...
	conversions: [
		{names: ['gram', 'grams'], symbols: ['g'], ratio: 1},
		...expandMacro(Macros.si, {names: ['gram', 'grams'], symbols: ['g'], ratio: 1}),

		{names: ['tonne', 'tonnes', 'metric ton', 'metric tons'], symbols: ['t'], ratio: 1e6},
		...expandMacro(Macros.si, {names: ['gram', 'grams'], symbols: ['g'], ratio: 1}),

		// ... other conversions ...
	],
};

Proposed Solution:
Remove the duplicated expandMacro method call at line 20, as it duplicates the conversions already added at line 17. Additionally, modify the second expandMacro call to properly expand the units for ton (tonne) measurements.

Replace method call at line 20

...expandMacro(Macros.si, {names: ['gram', 'grams'], symbols: ['g'], ratio: 1}),

with

...expandMacro(Macros.si, {names: ['tonne', 'tonnes', 'metric ton', 'metric tons'], symbols: ['t'], ratio: 1e6}),

to continue with convert error

to continue, in this case if we convert 3 Grams to Petagrams we get 3.0000000000000002e-15 and rounding this number leads to errors

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

How to Use this library with Ember

I have tried to install and trying to import but it is giving me error like ' Could not find module convert imported from'. Though I am able to see this in node_modules. Please suggest me how to procceed.

Version used: 5.0.0

Conversion ratio for US dry quart and US dry pint incorrect

When doing conversions with US dry quart and US dry pint to litres the values are incorrect (i.e. convert(1, 'US dry quart').to('l'))

The correct ratio values for dry measures are listed here (https://en.wikipedia.org/wiki/United_States_customary_units#Dry_volume and https://en.wikipedia.org/wiki/Dry_measure#US_units_of_dry_measure) as mentioned in the comments in src/dev/conversions/volume.ts.

Expected behaviour:
1 US dry quart = 1.101221 L
1 US dry pint = 0.550610 L

Actual behaviour:
1 US dry quart = 0.946352946 L
1 US dry pint = 33600.3125 L

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Cannot push to the Git repository.

semantic-release cannot push the version tag to the branch master on the remote Git repository with URL http://x-access-token:[secure]@github.com/jonahsnider/convert.git.

This can be caused by:


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Add rounding?

Hi. I found your package today and it's excellent. Thanks so much for putting it together.

One thing I'm always having to do is rounding for display purposes. I'm curious if you'd be interested in adding round and/or toFixed with decimal places to your package.

My thinking is that everyone doing these conversions needs to also round for display purposes.

About 6 months ago I tested many solutions and settled on this for speed and accuracy.

// Modified version of Solution #2 from https://stackoverflow.com/a/48764436/25197.
// Fast and accurate.
const DecimalMath = (() => {
  const decimalAdjust = (type, num, decimalPlaces) => {
    const precision = 10 ** decimalPlaces;
    const n = num * precision * (1 + Number.EPSILON);
    return Math[type](n) / precision;
  };

  return {
    round(num: number, decimalPlaces = 0) {
      return decimalAdjust('round', num, decimalPlaces);
    },

    // Format using fixed-point notation.
    toFixed(num: number, decimalPlaces = 0) {
      return decimalAdjust('round', num, decimalPlaces).toFixed(decimalPlaces);
    },

    ceil(num: number, decimalPlaces = 0) {
      return decimalAdjust('ceil', num, decimalPlaces);
    },

    floor(num: number, decimalPlaces = 0) {
      return decimalAdjust('floor', num, decimalPlaces);
    },

    trunc(num: number, decimalPlaces = 0) {
      return decimalAdjust('trunc', num, decimalPlaces);
    },
  };
})();

export default DecimalMath;

To see the round and toFixed functions in action click the Run Code Snippet button on this stackoverflow answer. There are 30 answers on that page and I went through the comments in each one to find the places where each answer broke and made sure my version worked correctly.

I imagine a version of convert that can do this.

convert(150).from('pound').to('kilogram').round(2)

If any of this seems reasonable and you want me to take a stab at a PR I can do that as well.

problem with rounding by all measures

Hello, a problem with rounding by all measures was found.
for example, if we take 10 square meters and translate them into square kilometers, we get 0.000009999999999999999, while if we take 11 we get the correct answer 0.000011, and so on for all metrics

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Ability to convert Pa to psi

Looking through the pressure conversions available I do not see one for psi, would it be possible to add it?
{names: ['psi'], symbols:['psi'], ratio: new BigNumber(6_894_75729).div(1e5)},
Would be all that was required, no?

Convert Fahrenheit to Celsius on Version 3.1.0

Converting from F to C results in incorrect value.

const tempC = convert(68.0, "fahrenheit").to("celsius");

the output is: 5.777777777777779 while it should be 20

Converting from C to F works as expected and K to C does, too.

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Converting from 1 ft to inches

Hi, there seems to be a floating point problem when converting from 1 foot into inches.

convert(1, 'ft').to('in')  // Results in 12.000000000000002

I know there can be floating point problems in javascript, but I would expect this basic conversion to work properly.

Thanks!
Raymond

Return falsy when conversion is not supported

Would it be possible to make the function return null or false when a conversion fails?

For example calling:

convert(360, 'sec').to('min')

will output the whole library code.

Would be nice in it's place to get a falsy value to evaluate against.

Custom units

Feature request: Ability to define custom units
If this is already possible, some documentation on how to do so would be super.

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Cannot push to the Git repository.

semantic-release cannot push the version tag to the branch master on the remote Git repository with URL http://x-access-token:[secure]@github.com/jonahsnider/convert.git.

This can be caused by:


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

US Legal Cup conversion error

convert(1, 'US legal cup').to('cup')

should return 1.01442 but instead it's 1

Screenshot 2023-03-31 at 23 54 34

By trying other conversions is US legal cup that does not convert any measure properly, it converts them as a normal cup, so that's the data that needs correction.

Add support to restrict to('best') to input measurement system

Thanks for your consideration...

Currently

convert(16, 'tablespoon').to('best')

results in 236.5882365 mL, which is accurate but perhaps not the best option as 16 tablespoons = 1 cup.

It would great if the best option could be restricted to the measurement system of the input.

Or perhaps I have missed how to do that today?

Inaccurate conversion from meters to ft.

convert(2000, 'ft').to('meters') returns 609.6 which is correct
but
convert(609.6, 'meter').to('ft') returns 1999.9999999999998 which should be 2000 ft and is incorrect ?

Data `bigint` conversion error due to ratio is not an integer

All data conversions fail if using bigint due to Conversion for [UNIT] to [UNIT] cannot be calculated as a BigInt because the conversion ratio is not an integer error.Β 
Even a simple operation like this fails:

convert(1024n, 'B').to('KiB');

Unexpected result using your example of converting 36 hours to "best" units

console.log(convert(36, 'h').to('days').toString());
'1.5'

console.log(convert(36, 'h').to('days'));
1.5

console.log(convert(36, 'h').to('best').toString());  // your example of using 'best'
'1.4999999999999998d'

console.log(convert(36, 'h').to('best'));
{
  quantity: 1.4999999999999998,
  unit: 'd',
  toString: Ζ’ ()
}

Adding pixels, point to length type

First off want to say love this package. Very clean and easy to use.

Feature request:
Thoughts on adding pixels and points to the length type?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.