Initial commit

This commit is contained in:
kdusek
2025-12-09 12:13:01 +01:00
commit 8e654ed209
13332 changed files with 2695056 additions and 0 deletions

View File

@@ -0,0 +1,283 @@
Metadata-Version: 2.4
Name: humanize
Version: 4.14.0
Summary: Python humanize utilities
Project-URL: Documentation, https://humanize.readthedocs.io/
Project-URL: Funding, https://tidelift.com/subscription/pkg/pypi-humanize?utm_source=pypi-humanize&utm_medium=pypi
Project-URL: Homepage, https://github.com/python-humanize/humanize
Project-URL: Issue tracker, https://github.com/python-humanize/humanize/issues
Project-URL: Release notes, https://github.com/python-humanize/humanize/releases
Project-URL: Source, https://github.com/python-humanize/humanize
Author-email: Jason Moiron <jmoiron@jmoiron.net>
Maintainer: Hugo van Kemenade
License-Expression: MIT
License-File: LICENCE
Keywords: humanize time size
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Text Processing
Classifier: Topic :: Text Processing :: General
Requires-Python: >=3.10
Provides-Extra: tests
Requires-Dist: freezegun; extra == 'tests'
Requires-Dist: pytest; extra == 'tests'
Requires-Dist: pytest-cov; extra == 'tests'
Description-Content-Type: text/markdown
# humanize
[![PyPI version](https://img.shields.io/pypi/v/humanize.svg?logo=pypi&logoColor=FFE873)](https://pypi.org/project/humanize/)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/humanize.svg?logo=python&logoColor=FFE873)](https://pypi.org/project/humanize/)
[![Documentation Status](https://readthedocs.org/projects/python-humanize/badge/?version=latest)](https://humanize.readthedocs.io/en/latest/?badge=latest)
[![PyPI downloads](https://img.shields.io/pypi/dm/humanize.svg)](https://pypistats.org/packages/humanize)
[![GitHub Actions status](https://github.com/python-humanize/humanize/workflows/Test/badge.svg)](https://github.com/python-humanize/humanize/actions)
[![codecov](https://codecov.io/gh/python-humanize/humanize/branch/main/graph/badge.svg)](https://codecov.io/gh/python-humanize/humanize)
[![MIT License](https://img.shields.io/github/license/python-humanize/humanize.svg)](LICENCE)
[![Tidelift](https://tidelift.com/badges/package/pypi/humanize)](https://tidelift.com/subscription/pkg/pypi-humanize?utm_source=pypi-humanize&utm_medium=badge)
This modest package contains various common humanization utilities, like turning a
number into a fuzzy human-readable duration ("3 minutes ago") or into a human-readable
size or throughput. It is localized to:
- Arabic
- Basque
- Bengali
- Brazilian Portuguese
- Catalan
- Danish
- Dutch
- Esperanto
- European Portuguese
- Finnish
- French
- German
- Greek
- Hebrew
- Indonesian
- Italian
- Japanese
- Klingon
- Korean
- Norwegian
- Persian
- Polish
- Russian
- Simplified Chinese
- Slovak
- Slovenian
- Spanish
- Swedish
- Turkish
- Ukrainian
- Uzbek
- Vietnamese
## API reference
[https://humanize.readthedocs.io](https://humanize.readthedocs.io/)
<!-- usage-start -->
## Installation
### From PyPI
```bash
python3 -m pip install --upgrade humanize
```
### From source
```bash
git clone https://github.com/python-humanize/humanize
cd humanize
python3 -m pip install -e .
```
## Usage
### Integer humanization
```pycon
>>> import humanize
>>> humanize.intcomma(12345)
'12,345'
>>> humanize.intword(123455913)
'123.5 million'
>>> humanize.intword(12345591313)
'12.3 billion'
>>> humanize.apnumber(4)
'four'
>>> humanize.apnumber(41)
'41'
```
### Date & time humanization
```pycon
>>> import humanize
>>> import datetime as dt
>>> humanize.naturalday(dt.datetime.now())
'today'
>>> humanize.naturaldelta(dt.timedelta(seconds=1001))
'16 minutes'
>>> humanize.naturalday(dt.datetime.now() - dt.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(dt.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(dt.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(dt.datetime.now() - dt.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(dt.datetime.now() - dt.timedelta(seconds=3600))
'an hour ago'
```
### Precise time delta
```pycon
>>> import humanize
>>> import datetime as dt
>>> delta = dt.timedelta(seconds=3633, days=2, microseconds=123000)
>>> humanize.precisedelta(delta)
'2 days, 1 hour and 33.12 seconds'
>>> humanize.precisedelta(delta, minimum_unit="microseconds")
'2 days, 1 hour, 33 seconds and 123 milliseconds'
>>> humanize.precisedelta(delta, suppress=["days"], format="%0.4f")
'49 hours and 33.1230 seconds'
```
#### Smaller units
If seconds are too large, set `minimum_unit` to milliseconds or microseconds:
```pycon
>>> import humanize
>>> import datetime as dt
>>> humanize.naturaldelta(dt.timedelta(seconds=2))
'2 seconds'
```
```pycon
>>> delta = dt.timedelta(milliseconds=4)
>>> humanize.naturaldelta(delta)
'a moment'
>>> humanize.naturaldelta(delta, minimum_unit="milliseconds")
'4 milliseconds'
>>> humanize.naturaldelta(delta, minimum_unit="microseconds")
'4 milliseconds'
```
```pycon
>>> humanize.naturaltime(delta)
'now'
>>> humanize.naturaltime(delta, minimum_unit="milliseconds")
'4 milliseconds ago'
>>> humanize.naturaltime(delta, minimum_unit="microseconds")
'4 milliseconds ago'
```
### File size humanization
```pycon
>>> import humanize
>>> humanize.naturalsize(1_000_000)
'1.0 MB'
>>> humanize.naturalsize(1_000_000, binary=True)
'976.6 KiB'
>>> humanize.naturalsize(1_000_000, gnu=True)
'976.6K'
```
### Human-readable floating point numbers
```pycon
>>> import humanize
>>> humanize.fractional(1/3)
'1/3'
>>> humanize.fractional(1.5)
'1 1/2'
>>> humanize.fractional(0.3)
'3/10'
>>> humanize.fractional(0.333)
'333/1000'
>>> humanize.fractional(1)
'1'
```
### Scientific notation
```pycon
>>> import humanize
>>> humanize.scientific(0.3)
'3.00 x 10⁻¹'
>>> humanize.scientific(500)
'5.00 x 10²'
>>> humanize.scientific("20000")
'2.00 x 10⁴'
>>> humanize.scientific(1**10)
'1.00 x 10⁰'
>>> humanize.scientific(1**10, precision=1)
'1.0 x 10⁰'
>>> humanize.scientific(1**10, precision=0)
'1 x 10⁰'
```
## Localization
How to change locale at runtime:
```pycon
>>> import humanize
>>> import datetime as dt
>>> humanize.naturaltime(dt.timedelta(seconds=3))
'3 seconds ago'
>>> _t = humanize.i18n.activate("ru_RU")
>>> humanize.naturaltime(dt.timedelta(seconds=3))
'3 секунды назад'
>>> humanize.i18n.deactivate()
>>> humanize.naturaltime(dt.timedelta(seconds=3))
'3 seconds ago'
```
You can pass additional parameter `path` to `activate` to specify a path to search
locales in.
```pycon
>>> import humanize
>>> humanize.i18n.activate("xx_XX")
<...>
FileNotFoundError: [Errno 2] No translation file found for domain: 'humanize'
>>> humanize.i18n.activate("pt_BR", path="path/to/my/own/translation/")
<gettext.GNUTranslations instance ...>
```
<!-- usage-end -->
How to add new phrases to existing locale files:
```sh
xgettext --from-code=UTF-8 -o humanize.pot -k'_' -k'N_' -k'P_:1c,2' -k'NS_:1,2' -k'_ngettext:1,2' -l python src/humanize/*.py # extract new phrases
msgmerge -U src/humanize/locale/ru_RU/LC_MESSAGES/humanize.po humanize.pot # add them to locale files
```
How to add a new locale:
```sh
msginit -i humanize.pot -o humanize/locale/<locale name>/LC_MESSAGES/humanize.po --locale <locale name>
```
Where `<locale name>` is a locale abbreviation, eg. `en_GB`, `pt_BR` or just `ru`, `fr`
etc.
List the language at the top of this README.

View File

@@ -0,0 +1,88 @@
humanize-4.14.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
humanize-4.14.0.dist-info/METADATA,sha256=mppVSc9pFHBGigPdD1wv6X_XfagXISk7QSILYQ2kPZ0,7799
humanize-4.14.0.dist-info/RECORD,,
humanize-4.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
humanize-4.14.0.dist-info/licenses/LICENCE,sha256=i6bBgRKkMUAK08dD9wZwB5swJUXZiIT8LyipHDg6A4A,1078
humanize/__init__.py,sha256=0A0xgaWdltqMG8T6jhVmGJXwb-z2brONy2ReflJwI0k,911
humanize/__pycache__/__init__.cpython-310.pyc,,
humanize/__pycache__/_version.cpython-310.pyc,,
humanize/__pycache__/filesize.cpython-310.pyc,,
humanize/__pycache__/i18n.cpython-310.pyc,,
humanize/__pycache__/lists.cpython-310.pyc,,
humanize/__pycache__/number.cpython-310.pyc,,
humanize/__pycache__/time.cpython-310.pyc,,
humanize/_version.py,sha256=HK99J01s1g57btZFIWMu5zC8IUJbQB-DbpgMyQ_kkgE,706
humanize/filesize.py,sha256=LotRWEZURx-Rq1I0ygj9w1KwsdQbjHUd5daNMs-TK9o,2343
humanize/i18n.py,sha256=_RoZOYC9LJntrsDMgnBCRTAKRVSlmwFRZFRNBogoPqs,5158
humanize/lists.py,sha256=reyztCSCUXvwWMydHC7rordYiJDVQYOajxgb66Hnl5E,889
humanize/locale/ar/LC_MESSAGES/humanize.mo,sha256=7Q_UyKGoG-2tSGLtIcNGow2DZEX4eALVpDvX1Khfd5w,3986
humanize/locale/ar/LC_MESSAGES/humanize.po,sha256=TKnzks-uLwtaiS5k7qG-A6kKwYDnV7OuKpZRrWJ21EE,7117
humanize/locale/bn_BD/LC_MESSAGES/humanize.mo,sha256=LUrDF4ZVZkYw1Heh6Y1QvDXVS0m8KyO6zMPlwsqFGhs,4089
humanize/locale/bn_BD/LC_MESSAGES/humanize.po,sha256=ZyKh0iahFUuSbF1xpfsOtLqggK_NfAdU4R6pPyicAlE,7498
humanize/locale/ca_ES/LC_MESSAGES/humanize.mo,sha256=veqJwGHEzymT-ott8nPopAm2SZ4wto3yJRzU8JGXIG8,3345
humanize/locale/ca_ES/LC_MESSAGES/humanize.po,sha256=A4hVDpUEoImXUbmEMMjyk8W-P6xuwyZNAr-Zb0sVwaw,6496
humanize/locale/da_DK/LC_MESSAGES/humanize.mo,sha256=MS04fnP0NwUPe55v2yM3DEQAWe7A5R8A8P5kiLRStDY,3474
humanize/locale/da_DK/LC_MESSAGES/humanize.po,sha256=xS0gZXDJxP3NI329XpbpBHeY_HiwWB2oEeVu3wBqCw0,6576
humanize/locale/de_DE/LC_MESSAGES/humanize.mo,sha256=vjS7oDPGDGrNNdr7Z5NcznpZnbpLY6KKrcjiFIA1epY,3356
humanize/locale/de_DE/LC_MESSAGES/humanize.po,sha256=HIUjysys7zzNJTQdnyn9ag0gXYn9icxi9ytRdG7AEDM,6683
humanize/locale/el_GR/LC_MESSAGES/humanize.mo,sha256=5TEIw0jhD39CTpUIc-4JBg6_U_NGBcsD9e_J0vR2J8s,3559
humanize/locale/el_GR/LC_MESSAGES/humanize.po,sha256=gj-TkzEaSXa25NsSIaoXX4cBRmCZ-j2JOnIEZnhLPAc,8843
humanize/locale/eo/LC_MESSAGES/humanize.mo,sha256=QiudCU8bTdewpjXZcx1nVfOMtgSflFW_VI2HMjf5bl8,3345
humanize/locale/eo/LC_MESSAGES/humanize.po,sha256=UpnnPZHGbUQA-xHtDaushO3WndBtQtLF2J_1ySBYJjk,6548
humanize/locale/es_ES/LC_MESSAGES/humanize.mo,sha256=WRam8vl8OU2O76EkwQmhMVeliuZKO3W2_6zP9yp63W0,3466
humanize/locale/es_ES/LC_MESSAGES/humanize.po,sha256=Mav01u47b4t9QYtsLfsuLKe3GUMLSoNRo-ypt79ryU0,6601
humanize/locale/eu/LC_MESSAGES/humanize.mo,sha256=QbE_-2pncT26m_QDn1HP2mKDKq3OSz6NQq-NGaYTPhY,3098
humanize/locale/eu/LC_MESSAGES/humanize.po,sha256=9VB8-lTfzj41q4EVRya1kR5lhmYkB503WqBhaytlhTk,6522
humanize/locale/fa_IR/LC_MESSAGES/humanize.mo,sha256=42B1yDpYHdrnMVev01aEr_BaLlq-gMvh17CfjTM1HBI,4010
humanize/locale/fa_IR/LC_MESSAGES/humanize.po,sha256=cK6dwRRicaGNFGFRP6LWu0Z6Sx6IcjW54jtkaBUgoJM,7131
humanize/locale/fi_FI/LC_MESSAGES/humanize.mo,sha256=5lleMFhHuP2dkg01BewxrLcPWBE-W8CdCNWSme1E1kI,3369
humanize/locale/fi_FI/LC_MESSAGES/humanize.po,sha256=RHRfvBDhBkuIQmQUPUc-bVaFD9b3DoDx2ixip0TKSD0,6704
humanize/locale/fr_FR/LC_MESSAGES/humanize.mo,sha256=ntVm4cjej6K3gKyRGmi7ZR9_fJISSaBA_Q0RlIRp6Ow,3521
humanize/locale/fr_FR/LC_MESSAGES/humanize.po,sha256=1nOpuDIdxdhpmbfKPf6UoMi-L2ATN2oxAwJ74TBlRig,6628
humanize/locale/he_IL/LC_MESSAGES/humanize.mo,sha256=uWyjbTR6aee_ByHfsdshQCOi6oWF8x3PUtoL6pemP4U,3868
humanize/locale/he_IL/LC_MESSAGES/humanize.po,sha256=JJZwKddnhMQGb0t8rw6B5F6cUGj55Mqbj9Hsq7_h0bA,6961
humanize/locale/hu_HU/LC_MESSAGES/humanize.mo,sha256=NyDNyv_oiGfw-S1wNji1CIcJOrU3o0rpkhyTBy4aVZQ,3342
humanize/locale/hu_HU/LC_MESSAGES/humanize.po,sha256=deX1icCsNCRTHv7n36eKmFM2MKp3Jzzif3X06ypRi1g,6662
humanize/locale/id_ID/LC_MESSAGES/humanize.mo,sha256=6kl6Wh4ROJODFTkIbhV6UQ2JKT1inQn9lDxUeEepUTw,3005
humanize/locale/id_ID/LC_MESSAGES/humanize.po,sha256=kmOOMkkDALQNHAc9qUW1v_K_XoPsWXpbyvzX23JwCPY,6064
humanize/locale/it_IT/LC_MESSAGES/humanize.mo,sha256=22Ef6Z-FcbcrN5I8bVVNxHiix6-rvXYiU-iNbYwfxCw,3274
humanize/locale/it_IT/LC_MESSAGES/humanize.po,sha256=LdqSpE5JMaNiEiDShNBmeW9X1GqaETRp-LG9rH2wX5Q,6595
humanize/locale/ja_JP/LC_MESSAGES/humanize.mo,sha256=QaWCy6xeudjHEhJZmrStFghg-Lax9KC55JbhiG8AFE8,2457
humanize/locale/ja_JP/LC_MESSAGES/humanize.po,sha256=nIwxUswG2rbw_gCObxHoYb2RlV-DPhevdhDKGCbkKoU,6114
humanize/locale/ko_KR/LC_MESSAGES/humanize.mo,sha256=yDaJCpAY79DonnPJQcx0E8nqjuHJvmlv523Zgw-pjpg,2016
humanize/locale/ko_KR/LC_MESSAGES/humanize.po,sha256=xZXalYw9Fm6Fn38x1rZEHUFQem8HRMX46Xszce3CaZI,7026
humanize/locale/nb/LC_MESSAGES/humanize.mo,sha256=PD9dlULsr6X8Gw3CCICCfMk-W2YWNyHhfCFk8diJP4k,3521
humanize/locale/nb/LC_MESSAGES/humanize.po,sha256=HZg97E-53Yr1Kj0T3CdSXgl1xEHm-1O_Nhwo3DsvecI,6652
humanize/locale/nl_NL/LC_MESSAGES/humanize.mo,sha256=pUzwmGiXcgEgepNqS4KrRLbJnCG2uNdZdfzCu_HFSJw,3258
humanize/locale/nl_NL/LC_MESSAGES/humanize.po,sha256=Z5ZZQ_dz6GgM5XExjau12YzLzWj3g0eQGMBL60vGG20,6611
humanize/locale/pl_PL/LC_MESSAGES/humanize.mo,sha256=TaNbuHF10C4JjLFTS9qIFJqdLAt1g_jLPzfPTJXoTKI,3753
humanize/locale/pl_PL/LC_MESSAGES/humanize.po,sha256=FHSM2vxyr7-in-O4BQ0XgJ0Pdzg61EXGutyyRc1P9QI,7298
humanize/locale/pt_BR/LC_MESSAGES/humanize.mo,sha256=TOo5-USJuHa7faNF82eUcrKbFy75iC1t9KNnNYWee3E,3452
humanize/locale/pt_BR/LC_MESSAGES/humanize.po,sha256=qcupezKKHUWpSEKmRQ5humbJif6PL0JOnjQyeRCOSVE,6555
humanize/locale/pt_PT/LC_MESSAGES/humanize.mo,sha256=AFoTysVc89o2EMopIngkO7vdvYmQE5BmczaWN1sjQI0,3403
humanize/locale/pt_PT/LC_MESSAGES/humanize.po,sha256=i2p5MTjqcV5LM88R-akfN94G7cPDpND6u73NHkpX8SQ,6574
humanize/locale/ru_RU/LC_MESSAGES/humanize.mo,sha256=i-go1a1XjSR-PpWHBlpOst7DhoY-XlLTDP-paFJ68yY,4538
humanize/locale/ru_RU/LC_MESSAGES/humanize.po,sha256=SnvkM-3IyS6cfj3bg-Oy42SrTA36XxG8djhuhu0zwxE,7913
humanize/locale/sk_SK/LC_MESSAGES/humanize.mo,sha256=0_mdWYPZhFsPpx5hWEUweV5_MCuIgXJIhE0gBI7qw1Y,3540
humanize/locale/sk_SK/LC_MESSAGES/humanize.po,sha256=FctCrO9wiKmZG8UWoq3VGSrAf9fPeLrAVdixvoxejds,7187
humanize/locale/sl_SI/LC_MESSAGES/humanize.mo,sha256=scf8JQb2OCHRuZLDjaaX4Sta1E1p7ff4XGqXE5GuJP8,3979
humanize/locale/sl_SI/LC_MESSAGES/humanize.po,sha256=iSsMDQJe6lBZvsoT1H_in6aNgrdkngRVHJHUvL-v2z0,7625
humanize/locale/sv_SE/LC_MESSAGES/humanize.mo,sha256=Kc9KozjWca9D3PEX5Ao6tNvote5iaHGbjqWAm4_hQHs,3448
humanize/locale/sv_SE/LC_MESSAGES/humanize.po,sha256=elUV6pcN9exHEXV4yaKGUZ1NXpVAMY8xEQCLri1flPg,6553
humanize/locale/tlh/LC_MESSAGES/humanize.mo,sha256=wZ5uePT1Rb5xKDPU0MNwWSbLu6PqCxbLwFH5c74ye_E,2923
humanize/locale/tlh/LC_MESSAGES/humanize.po,sha256=MNKPaMahkZnisxVapCFS4lSL4BGbPRD0EDpFm4tO6UU,6426
humanize/locale/tr_TR/LC_MESSAGES/humanize.mo,sha256=mVyn5lJkS6GVZgJL7cglSDknfa3AM8hg7Uju0pIARZY,3457
humanize/locale/tr_TR/LC_MESSAGES/humanize.po,sha256=jtV7qjveteRvpxmST_FMCuVfbMg_uEr5ilJkeD0zzCA,6815
humanize/locale/uk_UA/LC_MESSAGES/humanize.mo,sha256=1Dgq35RkIlF_fUFvV9kayXEZZoD7ceRsViCweUsrZSM,4188
humanize/locale/uk_UA/LC_MESSAGES/humanize.po,sha256=WQ-9W3ipySDoIGtYghIHJG4EjonfWMklBtfqMiInuog,7668
humanize/locale/uz/LC_MESSAGES/humanize.mo,sha256=MWjb8_EhPDsJUPLGl2avkC2ifP119SmJ2H5iGP7ipaQ,3506
humanize/locale/uz/LC_MESSAGES/humanize.po,sha256=RCmFagdobCOANX72Jyup8UDgNu6zXbYZOX2cwxX3ZT0,6644
humanize/locale/vi_VN/LC_MESSAGES/humanize.mo,sha256=qN3hRa5kdPw49HwB4W8aonaiuUDrjyj-CbLswcEUbFQ,3164
humanize/locale/vi_VN/LC_MESSAGES/humanize.po,sha256=i1KLFBZG_pi_8p6X_4vRzk5LG0wPGB_91ELr3Y3lkfw,6927
humanize/locale/zh_CN/LC_MESSAGES/humanize.mo,sha256=_m1AucUNQhGvlREWbIcGILLGrO5E6ib76GvyQaUwTdQ,3067
humanize/locale/zh_CN/LC_MESSAGES/humanize.po,sha256=4Mc_IJ-l1f8clZLSQByrbfVQYrs8iGaT6_3GSIGo4HY,6386
humanize/locale/zh_HK/LC_MESSAGES/humanize.mo,sha256=ebOHit8EH6n0gd6H70MjQNhe_ojz9S1z0PgN2ZVI0fM,3341
humanize/locale/zh_HK/LC_MESSAGES/humanize.po,sha256=i9pU7fNa-omsQprUoO9Lz81pItM6Azcl5mjn-nUdyJ8,6520
humanize/number.py,sha256=LYpXChu-vrfE2TMxX7p4kmiLOoa2YhCEGZC9-zEcqCs,16277
humanize/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
humanize/time.py,sha256=wKZLYWFsyltdCCKgKsxxpQsxPeltSsOf3tV70DbIJdY,20036

View File

@@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: hatchling 1.27.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,20 @@
Copyright (c) 2010-2020 Jason Moiron and Contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.