diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..39906eb7 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,60 @@ +--- + +name: Test + +on: + push: + pull_request: + schedule: + - cron: '9 0 * * 1' + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: [3.8, 3.9, '3.10', 3.11, 3.12, 3.13, 3.14, pypy3.9] + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: python -m pip install --upgrade pip tox + - name: Run tox + run: tox -e "$(echo py${{ matrix.python-version }} | sed -e 's/[.]//g;s/pypypy/pypy/')" --skip-missing-interpreters false + tox_job: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + tox_job: [docs, flake8, mypy, headers] + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.13 + - name: Install dependencies + run: python -m pip install --upgrade pip tox + - name: Run tox ${{ matrix.tox_job }} + run: tox -e ${{ matrix.tox_job }} --skip-missing-interpreters false + CodeQL: + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: python + - name: Build + uses: github/codeql-action/autobuild@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.gitignore b/.gitignore index bc90af02..77e8d2c6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,10 @@ __pycache__ # / /.coverage +/.mypy_cache +/.ruff_cache /.tox +/.venv /build /coverage /dist diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fb26bd79..00000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: python -cache: pip -sudo: false -python: - - 2.7 - - 3.4 - - 3.5 - - 3.6 - - 3.7 - - 3.8 - - pypy -matrix: - include: - - python: 2.6 - dist: trusty - - python: pypy3 - dist: trusty - - python: 3.6 - env: TOXENV=flake8 - - python: 3.6 - env: TOXENV=docs -install: pip install tox -script: tox -e "${TOXENV:-$(echo py$TRAVIS_PYTHON_VERSION | tr -d . | sed -e 's/pypypy/pypy/')}" --skip-missing-interpreters false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..f6ba7a3f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,160 @@ +Contributing to python-stdnum +============================= + +This document describes general guidelines for contributing new formats or +other enhancement to python-stdnum. + + +Adding number formats +--------------------- + +Basically any number or code that has some validation mechanism available or +some common formatting is eligible for inclusion into this library. If the +only specification of the number is "it consists of 6 digits" implementing +validation may not be that useful. + +Contributions of new formats or requests to implement validation for a format +should include the following: + +* The format name and short description. +* References to (official) sources that describe the format. +* A one or two paragraph description containing more details of the number + (e.g. purpose and issuer and possibly format information that might be + useful to end users). +* If available, a link to an (official) validation service for the number, + reference implementations or similar sources that allow validating the + correctness of the implementation. +* A set of around 20 to 100 "real" valid numbers for testing (more is better + during development but only around 100 will be retained for regression + testing). +* If the validation depends on some (online) list of formats, structures or + parts of the identifier (e.g. a list of region codes that are part of the + number) a way to easily update the registry information should be + available. + + +Code contributions +------------------ + +Improvements to python-stdnum are most welcome. Integrating contributions +will be done on a best-effort basis and can be made easier if the following +are considered: + +* Ideally contributions are made as GitHub pull requests, but contributions + by email (privately or through the python-stdnum-users mailing list) can + also be considered. +* Submitted contributions will often be reformatted and sometimes + restructured for consistency with other parts. +* Contributions will be acknowledged in the release notes. +* Contributions should add or update a copyright statement if you feel the + contribution is significant. +* All contribution should be made with compatible applicable copyright. +* It is not needed to modify the NEWS, README.md or files under docs for new + formats; these files will be updated on release. +* Marking valid numbers as invalid should be avoided and are much worse than + marking invalid numbers as valid. Since the primary use case for + python-stdnum is to validate entered data having an implementation that + results in "computer says no" should be avoided. +* Number format implementations should include links to sources of + information: generally useful links (e.g. more details about the number + itself) should be in the module docstring, if it relates more to the + implementation (e.g. pointer to reference implementation, online API + documentation or similar) a comment in the code is better +* Country-specific numbers and codes go in a country or region package (e.g. + stdnum.eu.vat or stdnum.nl.bsn) while global numbers go in the toplevel + name space (e.g. stdnum.isbn). +* All code should be well tested and achieve 100% code coverage. +* Existing code structure conventions (e.g. see README for interface) should + be followed. +* Git commit messages should follow the usual 7 rules. +* Declarative or functional constructs are preferred over an iterative + approach, e.g.:: + + s = sum(int(c) for c in number) + + over:: + + s = 0 + for c in number: + s += int(c) + + +Testing +------- + +Tests can be run with `tox`. Some basic code style tests can be run with `tox +-e flake8` and most other targets run the test suite with various supported +Python interpreters. + +Module implementations have a couple of smaller test cases that also serve as +basic documentation of the happy flow. + +More extensive tests are available, per module, in the tests directory. These +tests (also doctests) cover more corner cases and should include a set of +valid numbers that demonstrate that the module works correctly for real +numbers. + +The normal tests should never require online sources for execution. All +functions that deal with online lookups (e.g. the EU VIES service for VAT +validation) should only be tested using conditional unittests. + + +Finding test numbers +-------------------- + +Some company numbers are commonly published on a company's website contact +page (e.g. VAT or other registration numbers, bank account numbers). Doing a +web search limited to a country and some key words generally turn up a lot of +pages with this information. + +Another approach is to search for spreadsheet-type documents with some +keywords that match the number. This sometimes turns up lists of companies +(also occasionally works for personal identifiers). + +For information that is displayed on ID cards or passports it is sometimes +useful to do an image search. + +For dealing with numbers that point to individuals it is important to: + +* Only keep the data that is needed to test the implementation. +* Ensure that no actual other data relation to a person or other personal + information is kept or can be inferred from the kept data. +* The presence of a number in the test set should not provide any information + about the person (other than that there is a person with the number or + information that is present in the number itself). + +Sometimes numbers are part of a data leak. If this data is used to pick a few +sample numbers from the selection should be random and the leak should not be +identifiable from the picked numbers. For example, if the leaked numbers +pertain only to people with a certain medical condition, membership of some +organisation or other specific property the leaked data should not be used. + + +Reverse engineering +------------------- + +Sometimes a number format clearly has a check digit but the algorithm is not +publicly documented. It is sometimes possible to reverse engineer the used +check digit algorithm from a large set of numbers. + +For example, given numbers that, apart from the check digit, only differ in +one digit will often expose the weights used. This works reasonably well if +the algorithm uses modulo 11 is over a weighted sums over the digits. + +See https://github.com/arthurdejong/python-stdnum/pull/203#issuecomment-623188812 + + +Registries +---------- + +Some numbers or parts of numbers use validation base on a registry of known +good prefixes, ranges or formats. It is only useful to fully base validation +on these registries if the update frequency to these registries is very low. + +If there is a registry that is used (a list of known values, ranges or +otherwise) the downloaded information should be stored in a data file (see +the stdnum.numdb module). Only the minimal amount of data should be kept (for +validation or identification). + +The data files should be able to be created and updated using a script in the +`update` directory. diff --git a/COPYING b/COPYING index 5ab7695a..f6683e74 100644 --- a/COPYING +++ b/COPYING @@ -1,8 +1,8 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -10,7 +10,7 @@ as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a former contains code derived from the library, whereas the latter must be combined with the library in order to run. - GNU LESSER GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other @@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. - + 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an @@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. @@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries @@ -484,8 +484,7 @@ convey the exclusion of warranty; and each file should have at least the Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + License along with this library; if not, see . Also add information on how to contact you by electronic and paper mail. @@ -496,9 +495,7 @@ necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. - , 1 April 1990 - Ty Coon, President of Vice + , 1 April 1990 + Moe Ghoul, President of Vice That's all there is to it! - - diff --git a/ChangeLog b/ChangeLog index 9b3cef46..a546b744 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,2746 @@ +2026-01-04 Arthur de Jong + + * [e7e900a] .github/workflows/test.yml, setup.py, tox.ini: Add + support for Python 3.14 + +2026-01-04 Arthur de Jong + + * [97d8cae] stdnum/sn/ninea.py: URL escape the underscore because + it confuses Sphinx + +2026-01-04 Arthur de Jong + + * [6070c60] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/cz/banks.dat, stdnum/gs1_ai.dat, + stdnum/iban.dat, stdnum/imsi.dat, stdnum/isbn.dat, stdnum/isil.dat, + stdnum/nz/banks.dat, stdnum/oui.dat: Update database files + +2026-01-04 Arthur de Jong + + * [a7fd300] update/at_postleitzahl.py, update/be_banks.py, + update/cfi.py, update/cn_loc.py, update/cz_banks.py, + update/do_whitelists.py, update/gs1_ai.py, update/iban.py, + update/imsi.py, update/isbn.py, update/isil.py, update/nz_banks.py: + Consistently pass a user agent for update scripts + + The scourge of AI bots is forcing more and more sites to block + bots that don't set particular user agents. + +2026-01-04 Arthur de Jong + + * [e7afc61] update/be_banks.py: Update download URL of Belgian + bank numbers + + This also changes the handling to prefer the English name over + other names and handles another variant of not-applicable values. + +2026-01-04 Arthur de Jong + + * [d332ee1] stdnum/sn/ninea.py, tests/test_sn_ninea.doctest: + Add check digit validation to Senegal NINEA + +2023-02-12 Leandro Regueiro + + * [dd22123] stdnum/sn/__init__.py, stdnum/sn/ninea.py, + tests/test_sn_ninea.doctest: Add support for Senegal TIN + + Closes https://github.com/arthurdejong/python-stdnum/pull/395 + Closes https://github.com/arthurdejong/python-stdnum/issues/357 + +2026-01-03 Arthur de Jong + + * [d3ec3bd] stdnum/br/cnpj.py: Support new format for Brazilian CNPJ + + The new format allows letters as well as numbers to identify + companies. + + Closes https://github.com/arthurdejong/python-stdnum/issues/484 + +2025-02-27 dotbit1 <68584562+dotbit1@users.noreply.github.com> + + * [cd94bf1] stdnum/ro/onrc.py, tests/test_ro_onrc.doctest: Support + the new Romanian ONRC format + + Closes https://github.com/arthurdejong/python-stdnum/pull/465 + +2026-01-03 Arthur de Jong + + * [293136b] stdnum/lv/pvn.py: Support Latvian personal codes issued + after 2017 + + These numbers no longer embed a birth date in the format. + + Closes https://github.com/arthurdejong/python-stdnum/issues/486 + +2023-12-08 Cédric Krier + + * [a906a1e] stdnum/eu/excise.py, stdnum/fr/__init__.py, + stdnum/fr/accise.py, tests/test_fr_accise.doctest: Add accise - + the French number for excise + + Closes https://github.com/arthurdejong/python-stdnum/pull/424 + +2023-12-08 Cédric Krier + + * [1a254d9] stdnum/eu/excise.py, tests/test_eu_excise.doctest: + Add European Excise Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/424 + +2025-09-28 Cédric Krier + + * [d534b3c] stdnum/be/ogm_vcs.py: Add Belgian OGM-VCS + + Closes https://github.com/arthurdejong/python-stdnum/pull/487 + +2025-10-14 KathrinM + + * [2cf475c] stdnum/eu/nace.py, stdnum/eu/nace20.dat, + stdnum/eu/nace21.dat, tests/test_eu_nace.doctest: Add support + for nace revision 2.1 + + This makes revision 2.1 the default but still allows validating + against version 2.0 using the revision argument. + + Closes https://github.com/arthurdejong/python-stdnum/pull/490 + +2025-12-19 Tuukka Tolvanen + + * [acda255] stdnum/de/leitweg.py, tests/test_de_leitweg.doctest: + Add DE Leitweg-ID + + Closes https://github.com/arthurdejong/python-stdnum/pull/491 + +2025-12-16 Arthur de Jong + + * [c7a7fd1] .github/workflows/test.yml: Run flake8 with Python 3.13 + + Python version 3.14 no longer works. + +2025-10-26 Arthur de Jong + + * [7a9b852] stdnum/ro/cnp.py: Mark more Romanian CNP county codes + as valid + + According to + https://ro.wikipedia.org/wiki/Carte_de_identitate_rom%C3%A2neasc%C4%83#Seriile_c%C4%83r%C8%9Bilor_de_identitate_(%C3%AEn_modelele_emise_%C3%AEnainte_de_2021) + 70 is used to represent any registration, regardless of county + but while multiple documents claim 80-83 are also valid it is + unclear what they represent. + + Closes https://github.com/arthurdejong/python-stdnum/issues/489 + +2025-10-26 Arthur de Jong + + * [7ca9b6c] stdnum/be/vat.py, tests/test_be_vat.doctest: Validate + first digit of Belgian VAT number + + Thanks to antonio-ginestar find pointing this out. + + Closes https://github.com/arthurdejong/python-stdnum/issues/488 + +2022-09-17 Leandro Regueiro + + * [a1fdd5d] stdnum/az/__init__.py, stdnum/az/voen.py, + tests/test_az_voen.doctest: Add support for Azerbaijan TIN + + Thanks to Adam Handke for finding the weights for the check + digit algorithm. + + Closes https://github.com/arthurdejong/python-stdnum/issues/200 + CLoses https://github.com/arthurdejong/python-stdnum/pull/329 + +2025-08-08 Fabien MICHEL + + * [e741318] stdnum/fr/rcs.py, tests/test_fr_rcs.doctest: Add French + RCS number + + Closes https://github.com/arthurdejong/python-stdnum/pull/481 + +2025-08-08 Fabien MICHEL + + * [ca80cc4] stdnum/fr/siren.py: Add fr.siren.format() function + +2025-08-08 Fabien MICHEL + + * [b3a42a1] stdnum/fr/tva.py, tests/test_fr_tva.doctest: Add + fr.tva.to_siren() function + + The function can convert a French VAT number to a SIREN. + + Closes https://github.com/arthurdejong/python-stdnum/pull/480 + +2025-08-14 Arthur de Jong + + * [843bbec] stdnum/bic.py, tests/test_bic.doctest: Add validation + of country code in BIC + + Closes https://github.com/arthurdejong/python-stdnum/issues/482 + +2025-06-05 Joni Saarinen + + * [deb0db1] stdnum/ee/__init__.py: Add personal id and business + id alias for Estonia + + Closes https://github.com/arthurdejong/python-stdnum/pull/476 + +2025-05-10 Luca + + * [1773a91] stdnum/mz/__init__.py, stdnum/mz/nuit.py, + tests/test_mz_nuit.doctest: Add support for Mozambique TIN + + Closes https://github.com/arthurdejong/python-stdnum/issues/360 + Closes https://github.com/arthurdejong/python-stdnum/pull/392 + Closes https://github.com/arthurdejong/python-stdnum/pull/473 + +2025-06-01 Arthur de Jong + + * [5ef6ade] stdnum/numdb.py: Use broader type ignore for + pkg_resources import + + Apparently mypy changed for classifying the problem from + import-untyped to import-not-found. + +2025-05-25 Arthur de Jong + + * [0e64cf6] stdnum/cn/loc.dat, stdnum/cn/ric.py, + tests/test_cn_ric.doctest, update/cn_loc.py: Download Chinise + location codes from Wikipedia + + The list on GitHub is missing historical information and also + appears to no longer be updated. This changes the birth place + lookup to take the birth year into account to determine whether + a county was assigned at the time. + + Closes https://github.com/arthurdejong/python-stdnum/issues/442 + +2025-05-18 Arthur de Jong + + * [210b9ce] stdnum/gs1_128.py, stdnum/gs1_ai.dat, + tests/test_gs1_128.doctest, update/gs1_ai.py: Fix handling of + decimals in Application Identifiers + + This fixes the handling of GS1-128 Application Identifiers with + decimal types. Previously, with some 4 digit decimal application + identifiers the number of decimals were incorrectly considered + part of the value instead of the application identifier. + + For example (310)5033333 is not correct but it should be evaluated + as (3105)033333 (application identifier 3105 and value 0.33333). + + Closes https://github.com/arthurdejong/python-stdnum/issues/471 + +2025-05-17 Arthur de Jong + + * [d66998e] ChangeLog, NEWS, stdnum/__init__.py: Get files ready + for 2.1 release + +2025-05-17 Arthur de Jong + + * [a753ebf] stdnum/at/postleitzahl.dat, stdnum/cn/loc.dat, + stdnum/gs1_ai.dat, stdnum/imsi.dat, stdnum/isbn.dat, + stdnum/my/bp.dat, stdnum/nz/banks.dat, stdnum/oui.dat, + update/my_bp.py: Update database files + + This also updates the URLs for the National Registration Department + of Malaysia. + +2025-05-14 Cédric Krier + + * [972b42d] setup.py: Define minimal Python version in setup.py + + Closes https://github.com/arthurdejong/python-stdnum/issues/474 + Closes https://github.com/arthurdejong/python-stdnum/pull/475 + Fixes 3542c06 + +2025-05-05 Luca + + * [8b78f78] stdnum/jp/in_.py: Remove superfluous modulus operation + + Closes https://github.com/arthurdejong/python-stdnum/pull/470 + +2025-05-05 Arthur de Jong + + * [ad4af91] ChangeLog, NEWS, README.md, docs/conf.py, + docs/index.rst, docs/stdnum.be.eid.rst, docs/stdnum.be.ssn.rst, + docs/stdnum.es.cae.rst, docs/stdnum.id.nik.rst, + docs/stdnum.isni.rst, docs/stdnum.jp.in_.rst, + docs/stdnum.nl.identiteitskaartnummer.rst, docs/stdnum.ru.ogrn.rst, + stdnum/__init__.py: Get files ready for 2.0 release + +2025-05-05 Arthur de Jong + + * [f2967d3] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cfi.dat, stdnum/cn/loc.dat, stdnum/cz/banks.dat, + stdnum/gs1_ai.dat, stdnum/iban.dat, stdnum/imsi.dat, + stdnum/isbn.dat, stdnum/isil.dat, stdnum/my/bp.dat, + stdnum/nz/banks.dat, stdnum/oui.dat, tests/test_gs1_128.doctest, + tox.ini: Update database files + + This also updates the GS1-128 tests because a previously unused + AI is now in use. This also adds the updating of the Czech bank + numbers to tox. + +2025-05-05 Arthur de Jong + + * [c118723] update/at_postleitzahl.py: Remove duplicate Austrian + post offices + +2025-05-05 Arthur de Jong + + * [1a87baf] update/my_bp.crt, update/my_bp.py: Drop custom + certificates for www.jpn.gov.my + + The certificate chain for www.jpn.gov.my seems to have been fixed. + +2025-05-05 Arthur de Jong + + * [44575a1] update/iban.py: Allow reading IBAN registry from the + command line + + It seems that the Swift website currently uses TLS fingerprinting + to block downloads of the IBAN registry except in certain browsers. + + It also fixes an idiosyncrasy in the IBAN registry iteself where + the Norwegian BBAN format string was not correct. + +2025-05-05 Arthur de Jong + + * [44c2355] update/gs1_ai.py: Fix the downloading of GS1 application + identifiers + + The URL changed and the embedded JSON also slightly changed. + +2025-05-05 Arthur de Jong + + * [01e87f9] update/cn_loc.py, update/gs1_ai.py: Fix datetime + related deprecation warnings in update scripts + +2025-05-05 Arthur de Jong + + * [37320ea] update/be_banks.py, update/requirements.txt: Fix the + downloading of Belgian bank identifiers + + The site switched from XLS to XLSX files. + +2025-05-05 Arthur de Jong + + * [98b4fa0] stdnum/util.py, update/cfi.py, update/isil.py, + update/my_bp.py: Always pass regex flags as keyword argument + + In particular with re.sub() it got confused with the count + positional argument. + + Fixes a9039c1 + +2025-05-05 Arthur de Jong + + * [6e8c783] stdnum/cr/cpj.py, stdnum/fr/nir.py, stdnum/si/maticna.py: + Switch some URLs to HTTPS + +2022-09-04 Leandro Regueiro + + * [497bb11] stdnum/th/__init__.py: Add VAT alias for Thailand + TIN number + + Based on + https://github.com/arthurdejong/python-stdnum/issues/118#issuecomment-920521305 + Closes https://github.com/arthurdejong/python-stdnum/pull/314 + +2025-05-05 Arthur de Jong + + * [bfac07b] stdnum/ua/edrpou.py: Fix typo + + Fixes b7b2af8 + +2025-04-04 Luca Sicurello + + * [fca47b0] stdnum/jp/in_.py: Add Japanese Individual Number + +2025-03-13 David Salvisberg + + * [0e857fb] .github/workflows/test.yml, .gitignore, docs/index.rst, + setup.cfg, setup.py, stdnum/__init__.py, stdnum/ad/__init__.py, + stdnum/ad/nrt.py, stdnum/al/__init__.py, stdnum/al/nipt.py, + stdnum/ar/__init__.py, stdnum/ar/cbu.py, stdnum/ar/cuit.py, + stdnum/ar/dni.py, stdnum/at/__init__.py, stdnum/at/businessid.py, + stdnum/at/postleitzahl.py, stdnum/at/tin.py, stdnum/at/uid.py, + stdnum/at/vnr.py, stdnum/au/__init__.py, stdnum/au/abn.py, + stdnum/au/acn.py, stdnum/au/tfn.py, stdnum/be/__init__.py, + stdnum/be/bis.py, stdnum/be/eid.py, stdnum/be/iban.py, + stdnum/be/nn.py, stdnum/be/ssn.py, stdnum/be/vat.py, + stdnum/bg/egn.py, stdnum/bg/pnf.py, stdnum/bg/vat.py, + stdnum/bic.py, stdnum/bitcoin.py, stdnum/br/__init__.py, + stdnum/br/cnpj.py, stdnum/br/cpf.py, stdnum/by/__init__.py, + stdnum/by/unp.py, stdnum/ca/__init__.py, stdnum/ca/bc_phn.py, + stdnum/ca/bn.py, stdnum/ca/sin.py, stdnum/casrn.py, stdnum/cfi.py, + stdnum/ch/esr.py, stdnum/ch/ssn.py, stdnum/ch/uid.py, + stdnum/ch/vat.py, stdnum/cl/__init__.py, stdnum/cl/rut.py, + stdnum/cn/__init__.py, stdnum/cn/ric.py, stdnum/cn/uscc.py, + stdnum/co/__init__.py, stdnum/co/nit.py, stdnum/cr/__init__.py, + stdnum/cr/cpf.py, stdnum/cr/cpj.py, stdnum/cr/cr.py, + stdnum/cu/ni.py, stdnum/cusip.py, stdnum/cy/vat.py, + stdnum/cz/__init__.py, stdnum/cz/bankaccount.py, + stdnum/cz/dic.py, stdnum/cz/rc.py, stdnum/damm.py, + stdnum/de/__init__.py, stdnum/de/handelsregisternummer.py, + stdnum/de/idnr.py, stdnum/de/stnr.py, stdnum/de/vat.py, + stdnum/de/wkn.py, stdnum/dk/__init__.py, stdnum/dk/cpr.py, + stdnum/dk/cvr.py, stdnum/do/__init__.py, stdnum/do/cedula.py, + stdnum/do/ncf.py, stdnum/do/rnc.py, stdnum/dz/__init__.py, + stdnum/dz/nif.py, stdnum/ean.py, stdnum/ec/__init__.py, + stdnum/ec/ci.py, stdnum/ec/ruc.py, stdnum/ee/__init__.py, + stdnum/ee/ik.py, stdnum/ee/kmkr.py, stdnum/ee/registrikood.py, + stdnum/eg/__init__.py, stdnum/eg/tn.py, stdnum/es/__init__.py, + stdnum/es/cae.py, stdnum/es/ccc.py, stdnum/es/cif.py, + stdnum/es/cups.py, stdnum/es/dni.py, stdnum/es/iban.py, + stdnum/es/nie.py, stdnum/es/nif.py, stdnum/es/postal_code.py, + stdnum/es/referenciacatastral.py, stdnum/eu/at_02.py, + stdnum/eu/banknote.py, stdnum/eu/ecnumber.py, stdnum/eu/eic.py, + stdnum/eu/nace.py, stdnum/eu/oss.py, stdnum/eu/vat.py, + stdnum/exceptions.py, stdnum/fi/__init__.py, stdnum/fi/alv.py, + stdnum/fi/associationid.py, stdnum/fi/hetu.py, + stdnum/fi/veronumero.py, stdnum/fi/ytunnus.py, + stdnum/figi.py, stdnum/fo/__init__.py, stdnum/fo/vn.py, + stdnum/fr/__init__.py, stdnum/fr/nif.py, stdnum/fr/nir.py, + stdnum/fr/siren.py, stdnum/fr/siret.py, stdnum/fr/tva.py, + stdnum/gb/nhs.py, stdnum/gb/sedol.py, stdnum/gb/upn.py, + stdnum/gb/utr.py, stdnum/gb/vat.py, stdnum/gh/__init__.py, + stdnum/gh/tin.py, stdnum/gn/__init__.py, stdnum/gn/nifp.py, + stdnum/gr/amka.py, stdnum/gr/vat.py, stdnum/grid.py, + stdnum/gs1_128.py, stdnum/gt/__init__.py, stdnum/gt/nit.py, + stdnum/hr/__init__.py, stdnum/hr/oib.py, stdnum/hu/__init__.py, + stdnum/hu/anum.py, stdnum/iban.py, stdnum/id/__init__.py, + stdnum/id/nik.py, stdnum/id/npwp.py, stdnum/ie/pps.py, + stdnum/ie/vat.py, stdnum/il/__init__.py, stdnum/il/hp.py, + stdnum/il/idnr.py, stdnum/imei.py, stdnum/imo.py, stdnum/imsi.py, + stdnum/in_/__init__.py, stdnum/in_/aadhaar.py, stdnum/in_/epic.py, + stdnum/in_/gstin.py, stdnum/in_/pan.py, stdnum/in_/vid.py, + stdnum/is_/__init__.py, stdnum/is_/kennitala.py, stdnum/is_/vsk.py, + stdnum/isan.py, stdnum/isbn.py, stdnum/isil.py, stdnum/isin.py, + stdnum/ismn.py, stdnum/isni.py, stdnum/iso11649.py, + stdnum/iso6346.py, stdnum/iso7064/mod_11_10.py, + stdnum/iso7064/mod_11_2.py, stdnum/iso7064/mod_37_2.py, + stdnum/iso7064/mod_37_36.py, stdnum/iso7064/mod_97_10.py, + stdnum/isrc.py, stdnum/issn.py, stdnum/it/__init__.py, + stdnum/it/aic.py, stdnum/it/codicefiscale.py, stdnum/it/iva.py, + stdnum/jp/__init__.py, stdnum/jp/cn.py, stdnum/ke/__init__.py, + stdnum/ke/pin.py, stdnum/kr/__init__.py, stdnum/kr/brn.py, + stdnum/kr/rrn.py, stdnum/lei.py, stdnum/li/peid.py, + stdnum/lt/__init__.py, stdnum/lt/asmens.py, + stdnum/lt/pvm.py, stdnum/lu/__init__.py, stdnum/lu/tva.py, + stdnum/luhn.py, stdnum/lv/__init__.py, stdnum/lv/pvn.py, + stdnum/ma/__init__.py, stdnum/ma/ice.py, stdnum/mac.py, + stdnum/mc/__init__.py, stdnum/mc/tva.py, stdnum/md/idno.py, + stdnum/me/__init__.py, stdnum/me/iban.py, stdnum/me/pib.py, + stdnum/meid.py, stdnum/mk/__init__.py, stdnum/mk/edb.py, + stdnum/mt/vat.py, stdnum/mu/nid.py, stdnum/mx/__init__.py, + stdnum/mx/curp.py, stdnum/mx/rfc.py, stdnum/my/nric.py, + stdnum/nl/__init__.py, stdnum/nl/brin.py, stdnum/nl/bsn.py, + stdnum/nl/btw.py, stdnum/nl/identiteitskaartnummer.py, + stdnum/nl/onderwijsnummer.py, stdnum/nl/postcode.py, + stdnum/no/__init__.py, stdnum/no/fodselsnummer.py, + stdnum/no/iban.py, stdnum/no/kontonr.py, stdnum/no/mva.py, + stdnum/no/orgnr.py, stdnum/numdb.py, stdnum/nz/__init__.py, + stdnum/nz/bankaccount.py, stdnum/nz/ird.py, stdnum/pe/__init__.py, + stdnum/pe/cui.py, stdnum/pe/ruc.py, stdnum/pk/cnic.py, + stdnum/pl/__init__.py, stdnum/pl/nip.py, stdnum/pl/pesel.py, + stdnum/pl/regon.py, stdnum/pt/__init__.py, stdnum/pt/cc.py, + stdnum/pt/nif.py, stdnum/py.typed, stdnum/py/__init__.py, + stdnum/py/ruc.py, stdnum/ro/__init__.py, stdnum/ro/cf.py, + stdnum/ro/cnp.py, stdnum/ro/cui.py, stdnum/ro/onrc.py, + stdnum/rs/__init__.py, stdnum/rs/pib.py, stdnum/ru/__init__.py, + stdnum/ru/inn.py, stdnum/ru/ogrn.py, stdnum/se/__init__.py, + stdnum/se/orgnr.py, stdnum/se/personnummer.py, + stdnum/se/postnummer.py, stdnum/se/vat.py, + stdnum/sg/__init__.py, stdnum/sg/uen.py, stdnum/si/__init__.py, + stdnum/si/ddv.py, stdnum/si/emso.py, stdnum/si/maticna.py, + stdnum/sk/__init__.py, stdnum/sk/dph.py, stdnum/sk/rc.py, + stdnum/sm/__init__.py, stdnum/sm/coe.py, stdnum/sv/__init__.py, + stdnum/sv/nit.py, stdnum/th/moa.py, stdnum/th/pin.py, + stdnum/th/tin.py, stdnum/tn/__init__.py, stdnum/tn/mf.py, + stdnum/tr/__init__.py, stdnum/tr/tckimlik.py, stdnum/tr/vkn.py, + stdnum/tw/__init__.py, stdnum/tw/ubn.py, stdnum/ua/edrpou.py, + stdnum/ua/rntrc.py, stdnum/us/atin.py, stdnum/us/ein.py, + stdnum/us/itin.py, stdnum/us/ptin.py, stdnum/us/rtn.py, + stdnum/us/ssn.py, stdnum/us/tin.py, stdnum/util.py, + stdnum/uy/__init__.py, stdnum/uy/rut.py, stdnum/vatin.py, + stdnum/ve/__init__.py, stdnum/ve/rif.py, stdnum/verhoeff.py, + stdnum/vn/__init__.py, stdnum/vn/mst.py, stdnum/za/idnr.py, + stdnum/za/tin.py, tests/test_by_unp.py, tests/test_ch_uid.py, + tests/test_de_handelsregisternummer.py, tests/test_do_cedula.py, + tests/test_do_ncf.py, tests/test_do_rnc.py, tests/test_eu_vat.py, + tox.ini: Add type hints + + Closes https://github.com/arthurdejong/python-stdnum/pull/467 + Closes https://github.com/arthurdejong/python-stdnum/issues/433 + +2025-04-21 Arthur de Jong + + * [bc689fd] stdnum/do/cedula.py: Add missing verify argument to + Cedula check_dgii() + +2025-03-13 David Salvisberg + + * [8283dbb] stdnum/be/bis.py, stdnum/be/nn.py, stdnum/be/ssn.py, + stdnum/de/handelsregisternummer.py, stdnum/do/ncf.py, + stdnum/do/rnc.py, stdnum/eu/vat.py, stdnum/pk/cnic.py, + stdnum/util.py: Explicity return None + + As per PEP 8. + + See https://peps.python.org/pep-0008/ + +2025-03-13 David Salvisberg + + * [6b9bbe2] stdnum/be/iban.py, stdnum/be/nn.py, + stdnum/cz/bankaccount.py, stdnum/es/cups.py, stdnum/gs1_128.py, + stdnum/pk/cnic.py, stdnum/vatin.py, stdnum/verhoeff.py, + tests/test_be_iban.doctest: Small code cleanups + +2025-04-21 Arthur de Jong + + * [3542c06] .github/workflows/test.yml, setup.py, tox.ini: Drop + support for Python 3.6 and 3.7 + + Sadly GitHub has dropped the ability to run tests with these + versions of Python. + +2025-03-27 Arthur de Jong + + * [ae0d86c] tests/test_do_cedula.py, tests/test_do_rnc.py: Ignore + test failures from www.dgii.gov.do + + There was a change in the SOAP service and there is a new + URL. However, the API has changed and seems to require + authentication. + + We ignore test failures for now but unless a solution is found + the DGII validation will be removed. + + See: https://github.com/arthurdejong/python-stdnum/pull/462 See: + https://github.com/arthurdejong/python-stdnum/issues/461 + +2025-03-27 Arthur de Jong + + * [dcd7fa6] tests/test_do_rnc.py: Drop more Python 2.7 compatibility + code + +2025-03-27 Arthur de Jong + + * [852515c] stdnum/cz/rc.py, tests/test_cz_rc.doctest: Fix Czech + Rodné číslo check digit validation + + It seems that a small minority of numbers assigned + with a checksum of 10 are still valid and expected + to have a check digit value of 0. According to + https://www.domzo13.cz/sw/evok/help/born_numbers.html this + practice even happended (but less frequently) after 1985. + + Closes https://github.com/arthurdejong/python-stdnum/issues/468 + +2025-02-16 Arthur de Jong + + * [fc766bc] .github/workflows/test.yml, setup.py, tox.ini: Add + support for Python 3.13 + +2024-12-10 nvmbrasserie + + * [1386f67] stdnum/ru/ogrn.py, tests/test_ru_ogrn.doctest: Add + Russian ОГРН + + Closes https://github.com/arthurdejong/python-stdnum/pull/459 + +2024-07-04 Quique Porta + + * [8519221] stdnum/es/cae.py, tests/test_es_cae.doctest: Add + Spanish CAE Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/446 + +2025-02-15 Arthur de Jong + + * [0f94ca6] stdnum/ec/ruc.py, tests/test_ec_ruc.doctest: Support + Ecuador public RUC with juridical format + + It seems that numbers with a format used for juridical RUCs have + been issued to companies. + + Closes https://github.com/arthurdejong/python-stdnum/issues/457 + +2025-02-15 Arthur de Jong + + * [928a09d] stdnum/isni.py: Add International Standard Name + Identifier + + Closes https://github.com/arthurdejong/python-stdnum/issues/463 + +2025-01-11 Arthur de Jong + + * [2b92075] .github/workflows/test.yml, README.md, + online_check/stdnum.wsgi, setup.cfg, setup.py, stdnum/by/unp.py, + stdnum/de/handelsregisternummer.py, stdnum/do/ncf.py, + stdnum/eg/tn.py, stdnum/es/referenciacatastral.py, + stdnum/eu/nace.py, stdnum/imsi.py, + stdnum/mac.py, stdnum/meid.py, stdnum/mk/edb.py, + stdnum/mx/curp.py, stdnum/mx/rfc.py, stdnum/util.py, + tests/test_by_unp.doctest, tests/test_cn_ric.doctest, + tests/test_de_handelsregisternummer.doctest, + tests/test_de_stnr.doctest, tests/test_eg_tn.doctest, + tests/test_es_referenciacatastral.doctest, tests/test_isan.doctest, + tests/test_mac.doctest, tests/test_mk_edb.doctest, + tests/test_my_nric.doctest, tests/test_robustness.doctest, + tests/test_util.doctest, tox.ini: Drop Python 2 support + + This deprecates the stdnum.util.to_unicode() function because + we no longer have to deal with bytestrings. + +2024-11-17 Arthur de Jong + + * [0218601] stdnum/uy/rut.py, tests/test_uy_rut.doctest: Allow + Uruguay RUT number starting with 22 + +2024-09-30 Victor Sordoillet + + * [bcd5018] stdnum/isrc.py, tests/test_isrc.doctest: Add missing + music industry ISRC country codes + + Closes https://github.com/arthurdejong/python-stdnum/pull/455 + Closes https://github.com/arthurdejong/python-stdnum/issues/454 + +2024-10-11 Arthur de Jong + + * [020f1df] .github/workflows/test.yml: Use older Github runner + for Python 3.7 tests + +2024-10-11 Arthur de Jong + + * [051e63f] tests/test_verhoeff.doctest: Add more tests for + Verhoeff implementation + + See https://github.com/arthurdejong/python-stdnum/issues/456 + +2024-09-21 Arthur de Jong + + * [dc850d6] tox.ini: Ignore deprecation warnings in flake8 target + + This silences a ton of ast deprecation warnings that we can't + fix in python-stdnum anyway. + +2024-09-15 Arthur de Jong + + * [0ceb2b9] stdnum/util.py: Ensure get_soap_client() caches + with verify + + This fixes the get_soap_client() function to cache SOAP clients + taking the verify argument into account. + + Fixes 3fcebb2 + +2024-07-25 Jeff Horemans + + * [6c2873c] stdnum/be/eid.py: Add Belgian eID card number + + Closes https://github.com/arthurdejong/python-stdnum/pull/448 + +2024-07-25 Jeff Horemans + + * [56036d0] stdnum/nl/identiteitskaartnummer.py: Add Dutch + identiteitskaartnummer + + Closes https://github.com/arthurdejong/python-stdnum/pull/449 + +2024-09-14 Arthur de Jong + + * [3fcebb2] setup.py, stdnum/by/unp.py, stdnum/ch/uid.py, + stdnum/de/handelsregisternummer.py, stdnum/do/ncf.py, + stdnum/do/rnc.py, stdnum/eu/vat.py, stdnum/tr/tckimlik.py, + stdnum/util.py: Customise certificate validation for web services + + This adds a `verify` argument to all functions that use network + services for lookups. The option is used to configure how + certificate validation works, the same as in the requests library. + + For SOAP requests this is implemented properly when using the + Zeep library. The implementations using Suds and PySimpleSOAP + have been updated on a best-effort basis but their use has been + deprecated because they do not seem to work in practice in a + lot of cases already. + + Related to https://github.com/arthurdejong/python-stdnum/issues/452 + Related to https://github.com/arthurdejong/python-stdnum/pull/453 + +2024-07-04 Joris Makauskis + + * [6cbb9bc] stdnum/util.py: Fix zeep client timeout parameter + + The timeout parameter of the zeep transport class is not + responsable for POST/GET timeouts. The operational_timeout + parameter should be used for that. + + See https://github.com/mvantellingen/python-zeep/issues/140 + + Closes https://github.com/arthurdejong/python-stdnum/issues/444 + Closes https://github.com/arthurdejong/python-stdnum/pull/445 + +2023-07-04 Jeff Horemans + + * [af3a728] stdnum/be/ssn.py, tests/test_be_ssn.doctest: Add + Belgian SSN number + + Closes https://github.com/arthurdejong/python-stdnum/pull/438 + +2024-07-15 Arthur de Jong + + * [0da257c] online_check/stdnum.wsgi: Replace use of deprecated + inspect.getargspec() + + Use the inspect.signature() function instead. The + inspect.getargspec() function was removed in Python 3.11. + +2024-06-23 Arthur de Jong + + * [e951dac] stdnum/id/npwp.py, tests/test_id_npwp.doctest: Support + 16 digit Indonesian NPWP numbers + + The Indonesian NPWP is being switched from 15 to 16 digits. The + number is now the NIK for Indonesian citizens and the old format + with a leading 0 for others (organisations and non-citizens). + + See + https://www.grantthornton.co.id/insights/global-insights1/updates-regarding-the-format-of-indonesian-tax-id-numbers/ + + Closes https://github.com/arthurdejong/python-stdnum/issues/432 + +2024-05-17 Jeff Horemans + + * [1da003f] stdnum/ch/uid.py: Adjust Swiss uid module to accept + numbers without CHE prefix + + Closes https://github.com/arthurdejong/python-stdnum/pull/437 + Closes https://github.com/arthurdejong/python-stdnum/issues/423 + +2024-05-21 petr.prikryl + + * [91959bd] stdnum/cz/banks.dat: Update Czech database files + + Closes https://github.com/arthurdejong/python-stdnum/pull/439 + Closes https://github.com/arthurdejong/python-stdnum/pull/435 + +2024-05-31 Olly Middleton + + * [58ecb03] stdnum/ie/pps.py, tests/test_ie_pps.doctest: Update + Irish PPS validator to support new numbers + + See https://www.charteredaccountants.ie/News/b-range-pps-numbers + + Closes https://github.com/arthurdejong/python-stdnum/issues/440 + Closes https://github.com/arthurdejong/python-stdnum/pull/441 + +2024-06-13 vanderkoort + + * [fb4d792] NEWS: Fix a typo + + Closes https://github.com/arthurdejong/python-stdnum/pull/443 + +2024-05-19 Arthur de Jong + + * [5aeaeff] stdnum/id/loc.dat, stdnum/id/nik.py: Add support for + Indonesian NIK + +2024-05-19 Arthur de Jong + + * [0690996] .github/workflows/test.yml, setup.py, tox.ini: Drop + support for Python 3.5 + + We don't have an easy way to test with Python 3.5 any more. + +2024-03-17 Arthur de Jong + + * [201d4d1] ChangeLog, NEWS, README.md, docs/conf.py, docs/index.rst, + docs/stdnum.ca.bc_phn.rst, docs/stdnum.eu.ecnumber.rst, + docs/stdnum.in_.vid.rst, stdnum/__init__.py: Get files ready + for 1.20 release + +2024-03-17 Arthur de Jong + + * [b454d3a] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/gs1_128.py, stdnum/gs1_ai.dat, + stdnum/iban.dat, stdnum/imsi.dat, stdnum/isbn.dat, stdnum/isil.dat, + stdnum/nz/banks.dat, stdnum/oui.dat, tests/test_be_iban.doctest, + update/gs1_ai.py: Update database files + + The Belgian bpost bank no longer has a registration and a few + bank account numbers in the tests that used that bank were removed. + + Also updates the update/gs1_ai.py script to handle the new format + of the data published by GS1. Also update the GS1-128 module to + handle some different date formats. + + The Pakistan entry was kept in the stdnum/iban.dat file because + the PDF version of the IBAN Registry still contains the country. + + fix db + +2024-03-17 Arthur de Jong + + * [97dbced] tox.ini: Add update-dat tox target for convenient data + file updating + +2024-03-17 Arthur de Jong + + * [26fd25b] setup.cfg, update/cfi.py, update/nz_banks.py, + update/requirements.txt: Switch to using openpyxl for parsing + XLSX files + + The xlrd has dropped support for parsing XLSX files. We still + use xlrd for update/be_banks.py because they use the classic + XLS format and openpyxl does not support that format. + +2024-03-17 Arthur de Jong + + * [9230604] stdnum/za/idnr.py: Use HTTPS in URLs where possible + +2024-02-27 Atul Deolekar + + * [7cba469] stdnum/in_/vid.py: Add Indian virtual identity number + + Closes https://github.com/arthurdejong/python-stdnum/pull/428 + +2024-03-17 Arthur de Jong + + * [bb20121] stdnum/ua/edrpou.py, tests/test_ua_edrpou.doctest: + Fix Ukrainian EDRPOU check digit calculation + + This fixes the case where the weighted sum woud be 10 which + should result in a check digit of 0. + + Closes https://github.com/arthurdejong/python-stdnum/issues/429 + +2023-12-15 Kevin Dagostino + + * [9c7c669] stdnum/fr/nif.py: Imporve French NIF validation + (checksum) + + The last 3 digits are a checksum. % 511 + https://ec.europa.eu/taxation_customs/tin/specs/FS-TIN%20Algorithms-Public.docx + + Closes https://github.com/arthurdejong/python-stdnum/pull/426 + +2024-02-03 Arthur de Jong + + * [1e412ee] stdnum/vatin.py, tests/test_vatin.doctest: Fix vatin + number compacting for "EU" VAT numbers + + Thanks Davide Walder for finding this. + + Closes https://github.com/arthurdejong/python-stdnum/issues/427 + +2023-11-19 Daniel Weber + + * [2535bbf] stdnum/eu/ecnumber.py, tests/test_eu_ecnumber.doctest: + Add European Community (EC) Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/422 + +2023-10-20 Ömer Boratav + + * [2478483] stdnum/ca/bc_phn.py: Add British Columbia PHN + + Closes https://github.com/arthurdejong/python-stdnum/pull/421 + +2023-11-12 Arthur de Jong + + * [58d6283] stdnum/ro/cf.py, tests/test_eu_vat.doctest: Ensure EU + VAT numbers don't accept duplicate country codes + +2023-11-12 Arthur de Jong + + * [1a5db1f] stdnum/de/vat.py: Fix typo (thanks Александр + Кизеев) + +2023-10-02 Arthur de Jong + + * [352bbcb] .github/workflows/test.yml, setup.py, tox.ini: Add + support for Python 3.12 + +2023-08-20 Arthur de Jong + + * [fa455fc] ChangeLog, NEWS, README.md, docs/index.rst, + docs/stdnum.be.bis.rst, docs/stdnum.eg.tn.rst, + docs/stdnum.es.postal_code.rst, docs/stdnum.eu.oss.rst, + docs/stdnum.gn.nifp.rst, docs/stdnum.si.maticna.rst, + stdnum/__init__.py: Get files ready for 1.19 release + +2023-08-20 Arthur de Jong + + * [3191b4c] MANIFEST.in: Ensure all files are included in source + archive + + Fixes b1dc313 Fixes 90044e2 + +2023-08-20 Arthur de Jong + + * [3947a54] stdnum/by/portal.nalog.gov.by.crt, stdnum/by/unp.py: + Remove obsolete intermediate certificate + + The portal.nalog.gov.by web no longer has an incomplete + certificate chain. + +2023-08-20 Arthur de Jong + + * [7761e42] stdnum/numdb.py: Use importlib.resource in place of + deprecated pkg_resources + + Closes https://github.com/arthurdejong/python-stdnum/issues/412 + Closes https://github.com/arthurdejong/python-stdnum/pull/413 + +2023-08-20 Arthur de Jong + + * [f6edcc5] tests/test_do_rnc.py: Avoid the deprecated + assertRegexpMatches function + +2023-08-20 Arthur de Jong + + * [895f092] setup.cfg: Rename license_file option in setup.cfg + + It seems the old option wasn't working with all versions of + setuptools anyway. + + See + https://setuptools.pypa.io/en/latest/userguide/declarative_config.html + +2023-08-20 Arthur de Jong + + * [3126f96] stdnum/by/unp.py, tests/test_by_unp.py: Update Belarusian + UNP online check + + The API for the online check for Belarusian UNP numbers at + https://www.portal.nalog.gov.by/grp/getData has changed some + small details of the API. + +2023-08-20 Arthur de Jong + + * [88d1dca] tests/test_de_handelsregisternummer.py: Replace test + number for German company registry + + The number seems to be no longer valid breaking the online tests. + +2023-08-20 Arthur de Jong + + * [6e56f3c] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/gs1_ai.dat, stdnum/iban.dat, + stdnum/imsi.dat, stdnum/isbn.dat, stdnum/isil.dat, + stdnum/nz/banks.dat, stdnum/oui.dat, tests/test_be_iban.doctest, + update/oui.py: Update database files + + This also modifies the OUI update script because the website + has changed to HTTPS and is sometimes very slow. + + The Belgian Commerzbank no longer has a registration and a bank + account number in the tests used that bank. + +2023-08-20 Arthur de Jong + + * [0aa0b85] update/eu_nace.py: Remove EU NACE update script + + The website that publishes the NACE catalogue has changed and + a complete re-write of the script would be necessary. The data + file hasn't changed since 2017 so is also unlikely to change + until it is going to be replaced by NACE rev. 2.1 in 2025. + + See https://ec.europa.eu/eurostat/web/nace + + The NACE rev 2 specification can now be found here: + https://showvoc.op.europa.eu/#/datasets/ESTAT_Statistical_Classification_of_Economic_Activities_in_the_European_Community_Rev._2/data + + The NACE rev 2.1 specification can now be found here: + https://showvoc.op.europa.eu/#/datasets/ESTAT_Statistical_Classification_of_Economic_Activities_in_the_European_Community_Rev._2.1._%28NACE_2.1%29/data + + In both cases a ZIP file with RDF metadata can be downloaded + (but the web applciation also exposes some simpler JSON APIs). + +2023-08-13 Arthur de Jong + + * [f58e08d] stdnum/eu/oss.py, stdnum/eu/vat.py, + tests/test_eu_oss.doctest, tests/test_eu_vat.doctest: Validate + European VAT numbers with EU or IM prefix + + Closes https://github.com/arthurdejong/python-stdnum/pull/417 + +2023-06-30 Blaž Bregar + + * [d0f4c1a] stdnum/si/__init__.py, stdnum/si/maticna.py, + tests/test_si_maticna.doctest: Add Slovenian Corporate Registration + Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/414 + +2023-08-06 Arthur de Jong + + * [b8ee830] .github/workflows/test.yml, scripts/check_headers.py, + tox.ini: Extend license check to file header check + + This also checks that the file name referenced in the file header + is correct. + +2023-08-06 Arthur de Jong + + * [ef49f49] stdnum/be/bis.py, stdnum/be/nn.py, + stdnum/de/stnr.py, stdnum/dz/nif.py, stdnum/fi/alv.py, + stdnum/gb/utr.py, stdnum/hr/oib.py, stdnum/md/idno.py, + stdnum/pl/regon.py, stdnum/py/ruc.py, stdnum/sk/dph.py, + stdnum/tn/mf.py, stdnum/ua/edrpou.py, stdnum/ua/rntrc.py, + stdnum/vn/mst.py, stdnum/za/idnr.py, tests/test_al_nipt.doctest, + tests/test_gb_sedol.doctest, tests/test_iso6346.doctest, + tests/test_iso7064.doctest, tests/test_th_moa.doctest, + tests/test_tn_mf.doctest, tests/test_ve_rif.doctest: Fix file + headers + + This improves consistency across files and fixes some files that + had an incorrect file name reference. + +2023-07-30 Arthur de Jong + + * [3848318] stdnum/ca/sin.py: Validate first digit of Canadian SIN + + See + http://www.straightlineinternational.com/docs/vaildating_canadian_sin.pdf + See + https://lists.arthurdejong.org/python-stdnum-users/2023/msg00000.html + +2023-06-20 Jeff Horemans + + * [be33a80] stdnum/be/bis.py, stdnum/be/nn.py, + tests/test_be_bis.doctest, tests/test_be_nn.doctest: Add Belgian + BIS Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/418 + +2023-06-19 Arthur de Jong + + * [8ce4a47] .github/workflows/test.yml: Run Python 2.7 tests in + a container for GitHub Actions + + See https://github.com/actions/setup-python/issues/672 + +2023-06-13 Jeff Horemans + + * [311fd56] stdnum/be/nn.py, tests/test_be_nn.doctest: Handle + (partially) unknown birthdate of Belgian National Number + + This adds documentation for the special cases regarding birth + dates embedded in the number, allows for date parts to be unknown + and adds functions for getting the year and month. + + Closes https://github.com/arthurdejong/python-stdnum/pull/416 + +2023-06-01 Chales Horn + + * [7d3ddab] stdnum/isbn.py, stdnum/issn.py: Minor ISSN and ISBN + documentation fixes + + Fix a comment that claimed incorrect ISSN length and use slightly + more consistent terminology around check digits in ISSN and ISBN. + + Closes https://github.com/arthurdejong/python-stdnum/pull/415 + +2023-05-12 Arthur de Jong + + * [90044e2] .github/workflows/test.yml, + scripts/check_license_headers.py, tox.ini: Add automated checking + for correct license header + +2023-01-28 Leandro Regueiro + + * [62d15e9] stdnum/gn/__init__.py, stdnum/gn/nifp.py, + tests/test_gn_nifp.doctest: Add support for Guinea TIN + + Closes https://github.com/arthurdejong/python-stdnum/issues/384 + Closes https://github.com/arthurdejong/python-stdnum/pull/386 + +2023-02-24 Victor + + * [96abcfe] stdnum/es/postal_code.py: Add Spanish postcode validator + + Closes https://github.com/arthurdejong/python-stdnum/pull/401 + +2023-02-13 mjturt + + * [36858cc] stdnum/fi/hetu.py, tests/test_fi_hetu.doctest: Add + support for Finland HETU new century indicating signs + + More information at + https://dvv.fi/en/reform-of-personal-identity-code + + Cloess https://github.com/arthurdejong/python-stdnum/pull/396 + +2023-01-05 Jeff Horemans + + * [42d2792] stdnum/be/nn.py, tests/test_be_nn.doctest: Add + functionality to get gender from Belgian National Number + + This also extends the documentation for the number. + + Closes https://github.com/arthurdejong/python-stdnum/pull/347/files + +2023-03-06 RaduBorzea <101399404+RaduBorzea@users.noreply.github.com> + + * [cf14a9f] stdnum/ro/cnp.py: Add get_county() function to + Romanian CNP + + This also validates the county part of the number. + + Closes https://github.com/arthurdejong/python-stdnum/pull/407 + +2023-03-19 Arthur de Jong + + * [a8b6573] docs/conf.py, setup.cfg, tox.ini: Ensure flake8 is + run on all Python files + + This also fixes code style fixes in the Sphinx configuration file. + +2023-03-18 Arthur de Jong + + * [7af50b7] .github/workflows/test.yml, setup.py, tox.ini: Add + support for Python 3.11 + +2023-03-18 Arthur de Jong + + * [8498b37] stdnum/gs1_128.py: Fix date formatting on PyPy 2.7 + + The original way of calling strftime was likely an artifact of + Python 2.6 support. + + Fixes 7e84c05 + +2023-03-18 Arthur de Jong + + * [7e84c05] stdnum/gs1_128.py, stdnum/gs1_ai.dat, + tests/test_gs1_128.doctest, update/gs1_ai.py: Extend date parsing + in GS1-128 + + Some new AIs have new date formats or have changed the way + optional components of formats are defined. + +2023-03-09 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [bf1bdfe] stdnum/iban.dat: Update IBAN database file + + Closes https://github.com/arthurdejong/python-stdnum/pull/409 + +2023-03-18 Arthur de Jong + + * [a09a7ce] stdnum/al/nipt.py, tests/test_al_nipt.doctest: Fix + Albanian tax number validation + + This extends the description of the Albanian NIPT (NUIS) number + with information on the structure of the number. The first + character was previously limited between J and L but this letter + indicates a decade and the number is also used for individuals + to where it indicates a birth date. + + Thanks Julien Launois for pointing this out. + + Source: + https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Albania-TIN.pdf + + Fixes 3db826c Closes + https://github.com/arthurdejong/python-stdnum/pull/402 + +2023-03-13 Ali-Akber Saifee + + * [031a249] stdnum/sg/uen.py: Fix typo in UEN docstring + +2023-01-02 Arthur de Jong + + * [cf22705] online_check/stdnum.wsgi, tox.ini: Extend number + properties to show in online check + + This also ensures that flake8 is run on the WSGI script. + +2022-10-09 Leandro Regueiro + + * [6d366e3] stdnum/eg/__init__.py, stdnum/eg/tn.py, + tests/test_eg_tn.doctest: Add support for Egypt TIN + + This also convertis Arabic digits to ASCII digits. + + Closes https://github.com/arthurdejong/python-stdnum/issues/225 + Closes https://github.com/arthurdejong/python-stdnum/pull/334 + +2022-12-30 Arthur de Jong + + * [b1dc313] CONTRIBUTING.md, docs/contributing.rst, docs/index.rst: + Add initial CONTRIBUTING.md file + + Initial description of the information needed for adding new + number formats and some coding and testing guidelines. + +2022-12-05 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [df894c3] stdnum/ch/uid.py, stdnum/gh/tin.py: Fix typos found + by codespell + + Closes https://github.com/arthurdejong/python-stdnum/pull/344 + +2022-12-12 Arthur de Jong + + * [4f8155c] .github/workflows/test.yml: Run Python 3.5 and 3.6 + GitHub tests on older Ubuntu + + The ubuntu-latest now points to ubuntu-22.04 instead of + ubuntu-20.04 before. + + This also switches the PyPy version to test with to 3.9. + +2022-11-29 valeriko + + * [74d854f] stdnum/ee/ik.py: Fix a typo + + Clocses https://github.com/arthurdejong/python-stdnum/pull/341 + +2022-11-28 Arthur de Jong + + * [7a91a98] tox.ini: Avoid newer flake8 + + The new 6.0.0 contains a number of backwards incompatible changes + for which plugins need to be updated and configuration needs to + be updated. + + Sadly the maintainer no longer accepts contributions or discussion + See https://github.com/PyCQA/flake8/issues/1760 + +2022-11-13 Arthur de Jong + + * [60a90ed] ChangeLog, NEWS, README.md, docs/index.rst, + docs/stdnum.be.nn.rst, docs/stdnum.cfi.rst, + docs/stdnum.cz.bankaccount.rst, docs/stdnum.dz.nif.rst, + docs/stdnum.fo.vn.rst, docs/stdnum.gh.tin.rst, + docs/stdnum.ke.pin.rst, docs/stdnum.ma.ice.rst, + docs/stdnum.me.pib.rst, docs/stdnum.mk.edb.rst, + docs/stdnum.pk.cnic.rst, docs/stdnum.si.emso.rst, + docs/stdnum.tn.mf.rst, stdnum/__init__.py, stdnum/gh/tin.py, + tox.ini: Get files ready for 1.18 release + +2022-11-13 Arthur de Jong + + * [31b2694] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/eu/nace.dat, stdnum/gs1_ai.dat, + stdnum/imsi.dat, stdnum/isbn.dat, stdnum/nz/banks.dat, + stdnum/oui.dat: Update database files + +2022-11-13 Arthur de Jong + + * [f691bf7] stdnum/de/handelsregisternummer.py, + tests/test_de_handelsregisternummer.py: Update German + OffeneRegister lookup data format + + It appears that the data structure at OffeneRegister has changed + which requires a different query. Data is returned in a different + structure. + +2022-11-13 Arthur de Jong + + * [5cdef0d] update/cn_loc.py: Increase timeout for CN Open Data + download + + It seems that raw.githubusercontent.com can be extremely slow. + +2022-11-13 Arthur de Jong + + * [580d6e0] update/my_bp.py: Pick up custom certificate from + script path + + This ensures that the script can be run from any directory. + + Fixes c4ad714 + +2022-09-06 Leandro Regueiro + + * [7348c7a] tests/test_vatin.doctest: vatin: Add a few more tests + for is_valid + + See https://github.com/arthurdejong/python-stdnum/pull/316 + +2022-11-13 Arthur de Jong + + * [fa62ea3] stdnum/pk/__init__.py, stdnum/pk/cnic.py, + tests/test_pk_cnic.doctest: Add Pakistani ID card number + + Based on the implementation provided by Quantum Novice (Syed + Haseeb Shah). + + Closes https://github.com/arthurdejong/python-stdnum/pull/306 + Closes https://github.com/arthurdejong/python-stdnum/issues/304 + +2022-10-16 Blaž Bregar + + * [feccaff] stdnum/si/__init__.py, stdnum/si/emso.py, + tests/test_si_emso.doctest: Add support for Slovenian EMŠO + (Unique Master Citizen Number) + + Closes https://github.com/arthurdejong/python-stdnum/pull/338 + +2022-11-12 Arthur de Jong + + * [74cc981] stdnum/cz/bankaccount.py, stdnum/nz/bankaccount.py, + tox.ini, update/iban.py: Ensure we always run flake8-bugbear + + This assumes that we no longer use Python 2.7 for running the + flake8 tests any more. + +2022-11-12 Arthur de Jong + + * [a03ac04] stdnum/cz/bankaccount.py, + stdnum/es/referenciacatastral.py, stdnum/lei.py, stdnum/nl/bsn.py: + Use HTTPS in URLs where possible + +2022-10-23 Leandro Regueiro + + * [8e76cd2] stdnum/cr/cpf.py: Pad with zeroes in a more readable + manner + + Closes https://github.com/arthurdejong/python-stdnum/pull/340 + +2022-11-12 Arthur de Jong + + * [45f098b] stdnum/exceptions.py: Make all exceptions inherit + from ValueError + + All the validation exceptions (subclasses of ValidationError) + are raised when a number is provided with an inappropriate value. + +2022-11-12 Arthur de Jong + + * [a218032] stdnum/ch/uid.py, tests/test_ch_uid.py: Add a check_uid() + function to the stdnum.ch.uid module + + This function can be used to performa a lookup of organisation + information by the Swiss Federal Statistical Office web service. + + Related to https://github.com/arthurdejong/python-stdnum/issues/336 + +2022-11-12 Arthur de Jong + + * [1364e19] stdnum/cusip.py, tests/test_cusip.doctest: Support + "I" and "O" in CUSIP number + + It is unclear why these letters were considered invalid at the + time of the implementation. + + This also reduces the test set a bit while still covering + most cases. + + Closes https://github.com/arthurdejong/python-stdnum/issues/337 + +2022-10-23 Arthur de Jong + + * [f972894] online_check/stdnum.wsgi: Switch to escape() from html + + The function was removed from the cgi module in Python 3.8. + +2022-10-23 Arthur de Jong + + * [c5d3bf4] online_check/stdnum.wsgi: Switch to parse_qs() from + urllib.parse + + The function was removed from the cgi module in Python 3.8. + +2022-10-19 Arthur de Jong + + * [8b5b07a] stdnum/casrn.py: Remove unused import + + Fixes 09d595b + +2022-10-19 Arthur de Jong + + * [09d595b] stdnum/casrn.py: Improve validation of CAS Registry + Number + + This ensures that a leading 0 is treated as invalid. + +2022-10-19 Arthur de Jong + + * [7c2153e] stdnum/cas.py: Remove duplicate CAS Registry Number + + The recently added stdnum.cas module was already available as + teh stdnum.casrn module. + + Reverts acb6934 + +2022-10-19 Arthur de Jong + + * [1003033] tests/test_no_fodselsnummer.doctest: Update + Fødselsnummer test case for date in future + + The future was now. This problem was pushed forwards to October + 2039. + +2022-10-15 Arthur de Jong + + * [1636045] tox.ini: Support running tests with PyPy 2.7 + + This also applies the fix from cfc80c8 from Python 2.7 to PyPy. + +2022-09-11 Leandro Regueiro + + * [7be2291] stdnum/gh/__init__.py, stdnum/gh/tin.py, + tests/test_gh_tin.doctest: Add support for Ghana TIN + + Closes https://github.com/arthurdejong/python-stdnum/pull/326 + Closes https://github.com/arthurdejong/python-stdnum/issues/262 + +2022-10-15 Arthur de Jong + + * [acb6934] stdnum/cas.py: Add CAS Registry Number + +2022-09-18 Leandro Regueiro + + * [2b6e087] stdnum/me/__init__.py, stdnum/me/pib.py, + tests/test_me_pib.doctest: Add support for Montenegro TIN + + Closes https://github.com/arthurdejong/python-stdnum/pull/331 + Closes https://github.com/arthurdejong/python-stdnum/issues/223 + +2022-09-10 Leandro Regueiro + + * [fbe094c] stdnum/fo/__init__.py, stdnum/fo/vn.py, + tests/test_fo_vn.doctest: Add Faroe Islands V-number + + Closes https://github.com/arthurdejong/python-stdnum/pull/323 + Closes https://github.com/arthurdejong/python-stdnum/issues/219 + +2022-09-17 Leandro Regueiro + + * [a261a93] stdnum/mk/__init__.py, stdnum/mk/edb.py, + tests/test_mk_edb.doctest: Add North Macedonian ЕДБ + + Note that this is implementation is mostly based + on unofficial sources describing the format, + which match the hundreds of examples found online. + https://forum.it.mk/threads/modularna-kontrola-na-embg-edb-dbs-itn.15663/?__cf_chl_tk=Op2PaEIauip6Z.ZjvhP897O8gRVAwe5CDAVTpjx1sEo-1663498930-0-gaNycGzNCRE#post-187048 + + Also note that the algorithm for the check digit was tested on + all found examples, and it doesn't work for all of them, despite + those failing examples don't seem to be valid according to the + official online search. + + Closes https://github.com/arthurdejong/python-stdnum/pull/330 + Closes https://github.com/arthurdejong/python-stdnum/issues/222 + +2022-09-23 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [eff3f52] stdnum/cn/ric.py, stdnum/ma/ice.py: Fix a couple typos + found by codespell + + Closes https://github.com/arthurdejong/python-stdnum/pull/333 + +2022-09-04 Leandro Regueiro + + * [31709fc] stdnum/dz/__init__.py, stdnum/dz/nif.py, + tests/test_dz_nif.doctest: Add Algerian NIF number + + This currently only checks the length and whether it only + contains digits because little could be found on the structure + of the number of whether there are any check digits. + + Closes https://github.com/arthurdejong/python-stdnum/pull/313 + Closes https://github.com/arthurdejong/python-stdnum/issues/307 + +2022-09-03 Leandro Regueiro + + * [2907676] stdnum/ma/__init__.py, stdnum/ma/ice.py, + tests/test_ma_ice.doctest: Add support for Morocco TIN + + Closes https://github.com/arthurdejong/python-stdnum/issues/226 + Closes https://github.com/arthurdejong/python-stdnum/pull/312 + +2022-08-08 Leandro Regueiro + + * [d70549a] stdnum/ke/__init__.py, stdnum/ke/pin.py, + tests/test_ke_pin.doctest: Add Kenyan TIN + + Closes https://github.com/arthurdejong/python-stdnum/issues/300 + Closes https://github.com/arthurdejong/python-stdnum/pull/310 + +2022-09-06 Leandro Regueiro + + * [dd70cd5] stdnum/tn/__init__.py, stdnum/tn/mf.py, + tests/test_tn_mf.doctest: Add support for Tunisia TIN + + Closes https://github.com/arthurdejong/python-stdnum/pull/317 + Closes https://github.com/arthurdejong/python-stdnum/issues/309 + +2022-08-15 Arthur de Jong + + * [e40c827] tests/test_eu_vat.py: Update EU VAT Vies test with + new number + + The number used before was apparently no longer valid. + +2022-08-15 Arthur de Jong + + * [5bcc460] stdnum/de/handelsregisternummer.py: Fix German + OffeneRegister company registry URL + +2022-08-15 Arthur de Jong + + * [ee9dfdf] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cfi.dat, stdnum/cn/loc.dat, stdnum/eu/nace.dat, + stdnum/gs1_ai.dat, stdnum/iban.dat, stdnum/imsi.dat, + stdnum/isbn.dat, stdnum/isil.dat, stdnum/my/bp.dat, + stdnum/nz/banks.dat, stdnum/oui.dat: Update database files + +2022-08-15 Arthur de Jong + + * [6b39c3d] update/nz_banks.py: Do not print trailing space + +2022-08-15 Arthur de Jong + + * [e901ac7] update/my_bp.py: Ignore invalid downloaded country codes + + The page currently lists a country without a country code (is + listed as "-"). This also ensures that lists of country codes + are handled consistently. + +2022-08-15 Arthur de Jong + + * [2cf78c2] update/imsi.py: Update names of Wikipedia pages with + IMSI codes + +2022-08-15 Arthur de Jong + + * [975d508] update/at_postleitzahl.py, update/be_banks.py, + update/cfi.py, update/cn_loc.py, update/cz_banks.py, + update/do_whitelists.py, update/eu_nace.py, update/gs1_ai.py, + update/iban.py, update/imsi.py, update/isbn.py, update/isil.py, + update/my_bp.py, update/nz_banks.py, update/oui.py: Provide a + timeout to all download scripts + +2022-08-15 Arthur de Jong + + * [ed37a6a] stdnum/isil.py, update/isil.py: Update ISIL download URL + +2022-08-13 Christian Clauss + + * [8aa6b5e] .github/workflows/test.yml: Remove redundant steps + with tox_job + + This also switches the other Tox jobs to use the latest Python + 3.x interpreter. + + Closes https://github.com/arthurdejong/python-stdnum/pull/305 + +2022-08-03 Romuald R + + * [ce9322c] stdnum/de/handelsregisternummer.py, + tests/test_de_handelsregisternummer.doctest: Add extra court + alias for german Handelsregisternummer + + Charlottenburg (Berlin) is a valid court representation for Berlin + (Charlottenburg). + + See + https://www.northdata.com/VRB+Service+GmbH,+Berlin/Amtsgericht+Charlottenburg+%28Berlin%29+HRB+103587+B + + Closes https://github.com/arthurdejong/python-stdnum/pull/298 + +2022-08-15 Arthur de Jong + + * [eae1dd2] stdnum/ch/esr.py, stdnum/il/idnr.py, stdnum/isin.py, + stdnum/nl/bsn.py, stdnum/no/kontonr.py, stdnum/nz/ird.py, + stdnum/ro/cui.py: Use str.zfill() for padding leading zeros + +2022-06-08 petr.prikryl + + * [c5595c7] stdnum/cz/bankaccount.py, stdnum/cz/banks.dat, + tests/test_cz_bankaccount.doctest, update/cz_banks.py: Add Czech + bank account numbers + + Closes https://github.com/arthurdejong/python-stdnum/issues/295 + Closes https://github.com/arthurdejong/python-stdnum/pull/296 + +2022-08-06 vovavili <64227274+vovavili@users.noreply.github.com> + + * [4d4a0b3] stdnum/isin.py: Fix small typo + + Improper inflection of plurals. + + Closes https://github.com/arthurdejong/python-stdnum/pull/299 + +2022-08-13 Arthur de Jong + + * [7ee0563] setup.cfg, stdnum/ad/nrt.py, stdnum/cr/cpj.py, + stdnum/eu/nace.py, stdnum/id/npwp.py, stdnum/il/hp.py, + stdnum/it/aic.py, stdnum/li/peid.py, stdnum/nz/ird.py, + stdnum/sg/uen.py, stdnum/sv/nit.py, stdnum/za/tin.py, + update/eu_nace.py: Put long line flake8 ignores in files instead + of globally + + We have some long URLs in the code (mostly in docstrings) and + wrapping them does not improve readability (and is difficult + in docstrings) so the E501 ignore is now put inside each file + instead of globally. + + Closes https://github.com/arthurdejong/python-stdnum/pull/302 + +2022-08-13 Arthur de Jong + + * [351be74] .github/workflows/test.yml, setup.py, tox.ini: Add + support for Python 3.10 + +2022-08-08 Christian Clauss + + * [b36c0d6] .github/workflows/test.yml: Upgrade GitHub Actions + + Update checkout to v3 (no relevant changes) and setup-python to v4 + (changes the names for pypy versions). + +2022-08-12 Arthur de Jong + + * [9f79691] stdnum/it/iva.py, update/iban.py: Fix flake8 error + + This stops using not as a function and hopefully also makes the + logic clearer. + +2022-07-04 Arthur de Jong + + * [a280d53] .github/workflows/test.yml: Upgrade to CodeQL Action v2 + + https://github.blog/changelog/2022-04-27-code-scanning-deprecation-of-codeql-action-v1/ + +2022-04-09 Arthur de Jong + + * [8a28e38] setup.cfg, tox.ini: Switch from nose to pytest + + Nose hasn't seen a release since 2015 and sadly doesn't work + with Python 3.10. + + See https://github.com/nose-devs/nose/issues/1099 + +2022-05-09 Arthur de Jong + + * [e831d07] setup.cfg: Ignore flake8 complaining about print + statements + + It seems that flake8 now uses T201 instead of T001 for this check. + +2022-04-08 Alexis de Lattre + + * [7d81eac] stdnum/gs1_128.py, tests/test_gs1_128.doctest: Support + parsing dates without a day in GS1-128 + + Date such as '(17)260400' is now properly interpreted as April + 30th 2026. + + Closes https://github.com/arthurdejong/python-stdnum/pull/294 + +2022-02-05 Cédric Krier + + * [bda2a9c] stdnum/be/nn.py, tests/test_be_nn.doctest: Compute + birth date from Belgian National Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/288 + +2022-03-21 Arthur de Jong + + * [e2a2774] stdnum/iso7064/mod_97_10.py, tests/test_iso7064.doctest: + Return check digits in 02-98 range for ISO 7064 Mod 97, 10 + + There are some valid ranges for check digits within ISO 7064 + Mod 97, 10 that all result in a valid checksum. This changes the + calculated check digits to be in the range from 02 to 98 as is + specified for use in IBAN. + + See + https://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits + + Closes https://github.com/arthurdejong/python-stdnum/pull/289 + +2022-03-07 Cédric Krier + + * [73f5e3a] stdnum/fr/siret.py, tests/test_fr_siret.doctest: + Support special validation of La Post SIRET + + See + https://fr.wikipedia.org/wiki/Système_d'identification_du_répertoire_des_établissements#Exceptions_pour_le_groupe_La_Poste + + Closes https://github.com/arthurdejong/python-stdnum/pull/293 + Closes https://github.com/arthurdejong/python-stdnum/issues/291 + +2022-02-14 Arthur de Jong + + * [27c7c74] stdnum/cfi.py, tests/test_cfi.doctest: Fix Python 2.7 + compatibility of the tests + + Fixes a9039c1 + +2022-02-14 Arthur de Jong + + * [cfc80c8] tox.ini: Support running tests with Python 2.7 + + When using recent versions of virtualenv this ensures that + older versions of pip and setuptools will be used inside the + virtualenvs that are created by tox. + +2022-02-13 Arthur de Jong + + * [a9039c1] stdnum/cfi.dat, stdnum/cfi.py, tests/test_cfi.doctest, + update/cfi.py: Add Classification of Financial Instruments + + This implements parsing of ISO 10962 CFI codes based on the + published description of the structure of these numbers. + + Closes https://github.com/arthurdejong/python-stdnum/issues/283 + +2022-02-13 Arthur de Jong + + * [219ff54] stdnum/numdb.py, tests/numdb-test.dat: Fix problem in + numdb with missing sub-properties + + If a numdb data file line contains multiple values or ranges + the sub-ranges were only applied to the last value in the range. + +2022-02-13 Arthur de Jong + + * [fd32e61] setup.py: Also ensure that embedded certificates + are shipped + +2022-01-09 Arthur de Jong + + * [02dec52] stdnum/mx/curp.py: Fix disabling check digit validation + of Mexican CURP + + The validation functions supported an optional parameter to + disable check digit validation in the number that didn't actually + affect validation and was most likely accidentally copied from + the RFC module. + + Fixes 50874a9 Closes + https://github.com/arthurdejong/python-stdnum/issues/285 + +2021-11-29 Cédric Krier + + * [dcf4730] stdnum/be/__init__.py, stdnum/be/nn.py: Add Belgian + National Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/284 + +2021-10-03 Arthur de Jong + + * [50650a9] ChangeLog, NEWS, README.md, docs/index.rst, + docs/stdnum.in_.epic.rst, docs/stdnum.in_.gstin.rst, + docs/stdnum.isrc.rst, docs/stdnum.pt.cc.rst, + docs/stdnum.se.postnummer.rst, docs/stdnum.th.moa.rst, + docs/stdnum.th.pin.rst, docs/stdnum.th.tin.rst, stdnum/__init__.py: + Get files ready for 1.17 release + +2021-10-03 Arthur de Jong + + * [0779d6a] stdnum/kr/brn.py, tests/test_kr_brn.py: Remove South + Korean BRN online check + + The Korea Fair Trade Commission website now requires solving + a CAPTCHA before submitting the request so this is no longer + possible. + +2021-10-03 Arthur de Jong + + * [61ebc9c] stdnum/no/orgnr.py: Add documentation for Norwegian + Organisasjonsnummer + +2021-10-03 Arthur de Jong + + * [9da63a4] tests/test_do_cedula.py: Update Cedula online test value + + Apparently the previously whitelisted value is no longer recognised + as a valid value by the DGII service. + +2021-10-03 Arthur de Jong + + * [25c30d7] stdnum/by/portal.nalog.gov.by.crt: Update Let's Encrypt + R3 intermediate certificate + + The portal.nalog.gov.by web site serves an incomplete certificate + chain and the certificate chain was changed. + +2021-10-03 Arthur de Jong + + * [3406c24] MANIFEST.in, README.md, docs/index.rst, setup.py, + update/numlist.py: Rename README to README.md + + Mostly to please GitHub. + + See https://github.com/arthurdejong/python-stdnum/issues/280 + +2021-10-03 Arthur de Jong + + * [d5cba0a] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/eu/nace.dat, stdnum/gs1_ai.dat, + stdnum/iban.dat, stdnum/imsi.dat, stdnum/isbn.dat, stdnum/isil.dat, + stdnum/nz/banks.dat, stdnum/oui.dat, update/gs1_ai.py: Update + database files + +2021-09-30 Gaurav Chauhan <71322586+vairag22@users.noreply.github.com> + + * [26a7e7b] stdnum/in_/__init__.py, stdnum/in_/gstin.py: Add Indian + GSTIN (VAT number) + + Closes https://github.com/arthurdejong/python-stdnum/pull/279 + +2021-09-30 Gaurav Chauhan <71322586+vairag22@users.noreply.github.com> + + * [ca560cd] stdnum/in_/epic.py: Add Indian EPIC number (Voter + ID number) + + Closes https://github.com/arthurdejong/python-stdnum/pull/279 + +2021-09-30 Gaurav Chauhan <71322586+vairag22@users.noreply.github.com> + + * [fc56388] stdnum/in_/aadhaar.py, stdnum/in_/pan.py: Improve + validation and docstrings of Indian numbers + + This ensures that an Aadhaar cannot be a palindrome and checks the + serial part of the PAN to not be all zeros. It also updates some + descriptions of PAN holder types and renames the card_holder_type + to just holder_type. + + Closes https://github.com/arthurdejong/python-stdnum/pull/279 + +2021-09-19 Arthur de Jong + + * [1a0e613] stdnum/ec/ruc.py, tests/test_ec_ruc.doctest: Fix + detection of natural RUC values + + A natural RUC is the CI plus an establishment number. Both the + natural RUC and the public RUC can have a third digit with the + value 6. + + Closes https://github.com/arthurdejong/python-stdnum/issues/267 + +2021-08-20 michele + + * [8071444] stdnum/se/__init__.py, stdnum/se/postnummer.py, + tests/test_se_postnummer.doctest: Add swedish postcode validator + + Closes https://github.com/arthurdejong/python-stdnum/pull/271 + +2021-02-21 Piruin Panichphol + + * [424e408] stdnum/th/__init__.py, stdnum/th/moa.py, + stdnum/th/pin.py, stdnum/th/tin.py, tests/test_th_moa.doctest, + tests/test_th_pin.doctest, tests/test_th_tin.doctest: Add support + for Thai Numbers + + - TIN Taxpayer Identification Number - PIN Personal Identification + Number - MOA Memorandum of Association Number + + Closes https://github.com/arthurdejong/python-stdnum/issues/118 + Closes https://github.com/arthurdejong/python-stdnum/pull/255 + +2021-03-10 Nuno André + + * [36d723c] stdnum/isrc.py, tests/test_isrc.doctest: Add ISRC + (International Standard Recording Code) + + Closes https://github.com/arthurdejong/python-stdnum/pull/261 + +2021-08-07 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [48bfd84] stdnum/ad/nrt.py, stdnum/bitcoin.py, stdnum/do/ncf.py, + stdnum/isbn.py, stdnum/util.py, stdnum/vn/mst.py, + tests/test_cusip.doctest, tests/test_de_idnr.doctest, + update/be_banks.py, update/imsi.py, update/isil.py, + update/numlist.py: Fix typos found by codespell + + Closes https://github.com/arthurdejong/python-stdnum/pull/269 + +2021-08-07 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [dcdb5c9] stdnum/exceptions.py: Explicilty define exported + exceptions + + LGTM alert: Import pollutes the enclosing namespace + See: https://lgtm.com/rules/3980091/ Closes + https://github.com/arthurdejong/python-stdnum/pull/270 + +2021-08-07 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [abda037] stdnum/no/fodselsnummer.py: Simplify range checking + in Norwegian birth numbers + + LGTM alert: Test is always true See: https://lgtm.com/rules/900073/ + Closes https://github.com/arthurdejong/python-stdnum/pull/270 + +2021-08-07 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [c69b4f6] update/be_banks.py: Fix handling of empty worksheet + in Belgian bank download + + LGTM alert: Call to next() in a generator + See: https://lgtm.com/rules/11000086/ Closes + https://github.com/arthurdejong/python-stdnum/pull/270 + +2021-06-09 David Vaz + + * [4516748] stdnum/pt/cc.py, tests/test_pt_cc.doctest: Add CC + (Número de Cartão de Cidadão, Portuguese Identity number) + + Closes https://github.com/arthurdejong/python-stdnum/pull/265 + +2021-06-10 FRANK ROBERTO CHAVEZ SOSA <1085268@est.intec.edu.do> + + * [4c51860] stdnum/do/ncf.py: Add new e-CF types to Dominican + Republic NCF + +2021-01-18 Andres Rodriguez + + * [48e6502] stdnum/do/ncf.py: Fix parsing of empty fields in + DGII checking + +2020-12-11 Cristopher Ortega + + * [2b452b6] stdnum/do/ncf.py, tests/test_do_ncf.py: Add ENCF + validation support for Dominican Republic NCF + + Closes https://github.com/arthurdejong/python-stdnum/pull/248 + +2021-06-09 Dimitri Papadopoulos +<3234522+DimitriPapadopoulos@users.noreply.github.com> + + * [eeaf665] stdnum/fr/nif.py: Improve French NIF validation + + Closes https://github.com/arthurdejong/python-stdnum/pull/266 + +2021-07-12 Arthur de Jong + + * [e2a95fc] .github/workflows/test.yml: Configure CodeQL code + scanning + +2021-07-18 Arthur de Jong + + * [175b1e5] stdnum/exceptions.py: Ignore N818 because our exceptions + are not named error + +2021-04-11 Arthur de Jong + + * [38c368d] stdnum/numdb.py, tests/numdb-test.dat: Only process + the shortest matches in the numdb module + + This ensures that matching numbers is done consistently when + the numdb database file has conflicting information about the + length of numbers. + + This also refactors the _find() function to be simpler and + reduces the number of recursive calls that have to be done. + + The tests have been re-formatted to use pprint to make it easier + to spot differences if any of the tests fail (instead of just + saying expected True, got False). + + Closes https://github.com/arthurdejong/python-stdnum/issues/257 + +2021-04-11 Arthur de Jong + + * [b7901d6] update/imsi.py: Stop non-operational MNCs from confusing + IMSI dataset + + This only includes data from non-operational (status "Not + operational" according to Wikipedia) Mobile Network Code operators + in the generated data file if they would not confuse the lookup + of operational numbers. + + This avoid problems when the "030" to "039" non-operational ranges + conflicting with the "03" operational range. This ensures that + only the "03" value is kept. For historical completeness we keep + the other non-operational values. + + Closes https://github.com/arthurdejong/python-stdnum/issues/257 + +2021-03-03 Jakub Wilk + + * [7e69090] docs/index.rst: Fix typo + + Closes https://github.com/arthurdejong/python-stdnum/pull/258 + +2021-03-21 Arthur de Jong + + * [5785afb] .github/workflows/test.yml, .travis.yml: Replace Travis + with GitHub actions + +2021-03-21 Arthur de Jong + + * [7c0bb84] .travis.yml, setup.py, tox.ini: Drop support for Python + 2.6 and 3.4 + + It is increasingly difficult to test with these versions of + Python and everybody should have upgraded to a more recent + version long ago. + +2021-02-06 Arthur de Jong + + * [075d85e] ChangeLog, NEWS, stdnum/__init__.py: Get files ready + for 1.16 release + +2021-02-06 Arthur de Jong + + * [fad3064] stdnum/by/portal.nalog.gov.by.crt: Add Let's Encrypt + R3 intermediate certificate + + The portal.nalog.gov.by web site serves an incomplete certificate + chain and the intermediate certificate was changed. + +2021-02-06 Arthur de Jong + + * [8c4ec55] stdnum/be/banks.dat, stdnum/cn/loc.dat, + stdnum/eu/nace.dat, stdnum/gs1_ai.dat, stdnum/imsi.dat, + stdnum/isbn.dat, stdnum/nz/banks.dat, stdnum/oui.dat: Update + database files + +2021-02-06 Arthur de Jong + + * [fe34e15] stdnum/kr/rrn.py, stdnum/pe/ruc.py, stdnum/ua/edrpou.py: + Use HTTPS in URLs where possible + +2021-01-24 Arthur de Jong + + * [407a02f] stdnum/at/postleitzahl.dat, update/at_postleitzahl.py: + Switch postal code download to Austrian open-data portal + + This simplifies the process of downloading Austrian + postal codes by downloading a JSON blob instead from + https://www.data.gv.at/katalog/dataset/f76ed887-00d6-450f-a158-9f8b1cbbeebf + + This filters the list to only use addressable (adressierbar) + postal codes because it matches the previous list. + + Thanks Bernd Schlapsi for providing the pointer. + + Closes https://github.com/arthurdejong/python-stdnum/issues/235 + +2021-01-21 Alexis de Lattre + + * [53f13b4] stdnum/vatin.py, tests/test_vatin.doctest: Add support + for XI VAT numbers in vatin + + Closes https://github.com/arthurdejong/python-stdnum/pull/251 + +2021-01-21 Arthur de Jong + + * [b93d695] stdnum/eu/vat.py, stdnum/gb/vat.py, + tests/test_eu_vat.doctest: Support xi country code for Northern + Ireland + + While Great Brittain is no longer an EU member state some GB VAT + numbers are still valid if the company meets certain requirements. + + See + https://www.gov.uk/government/publications/accounting-for-vat-on-goods-moving-between-great-britain-and-northern-ireland-from-1-january-2021/check-when-you-are-trading-under-the-northern-ireland-protocol-if-you-are-vat-registered-business + + Closes https://github.com/arthurdejong/python-stdnum/issues/250 + +2021-01-11 Arthur de Jong + + * [6b7f209] ChangeLog, NEWS, README, docs/conf.py, docs/index.rst, + docs/stdnum.li.peid.rst, docs/stdnum.ro.cui.rst, + docs/stdnum.ua.edrpou.rst, docs/stdnum.ua.rntrc.rst, + stdnum/__init__.py, tox.ini: Get files ready for 1.15 release + +2021-01-11 Arthur de Jong + + * [755eee7] .travis.yml: Simplify Travis matrix + + This also ensures that supported Python interpreters are output + in order. + +2021-01-10 Arthur de Jong + + * [a0c62ee] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/eu/nace.dat, stdnum/gs1_ai.dat, + stdnum/iban.dat, stdnum/imsi.dat, stdnum/isbn.dat, + stdnum/my/bp.dat, stdnum/nz/banks.dat, stdnum/oui.dat, + update/at_postleitzahl.py, update/my_bp.py, update/nz_banks.py: + Update database files + +2021-01-10 Arthur de Jong + + * [df0623b] stdnum/by/unp.py, stdnum/do/ncf.py, stdnum/imsi.py, + stdnum/isbn.py, stdnum/meid.py, tox.ini: Drop pinning of isort + now flake8-isort has been fixed + + This changes a few inline imports in the code to pass with the + new isort. + + Reverts 291b831 + +2021-01-10 Arthur de Jong + + * [b202eee] stdnum/my/nric.py: Fix typo + +2021-01-10 Arthur de Jong + + * [7e86331] setup.py: Add project URLs for PyPI + +2020-10-25 Leandro Regueiro + + * [126496c] stdnum/ua/rntrc.py, tests/test_ua_rntrc.doctest: + Add support for Ukraine РНОКПП number + + Closes https://github.com/arthurdejong/python-stdnum/pull/242 + Closes https://github.com/arthurdejong/python-stdnum/issues/117 + +2020-10-25 Leandro Regueiro + + * [b7b2af8] stdnum/ua/__init__.py, stdnum/ua/edrpou.py, + tests/test_ua_edrpou.doctest: Add support for Ukraine ЄДРПОУ + number + + Closes https://github.com/arthurdejong/python-stdnum/pull/242 + Closes https://github.com/arthurdejong/python-stdnum/issues/117 + +2021-01-04 Viggo de Vries + + * [0427b01] stdnum/eu/vat.py, tests/test_eu_vat.doctest, + tests/test_gb_vat.doctest: Remove GB from EU member states + + Closes https://github.com/arthurdejong/python-stdnum/pull/246 + +2021-01-10 Arthur de Jong + + * [2f2c742] .travis.yml, setup.py, tox.ini: Add support for + Python 3.9 + + This switches Travis tests to bionic by default. + +2021-01-10 Arthur de Jong + + * [2046f51] stdnum/damm.py, stdnum/eu/at_02.py, stdnum/gs1_128.py, + stdnum/iso7064/mod_11_10.py, stdnum/iso7064/mod_11_2.py, + stdnum/iso7064/mod_37_2.py, stdnum/iso7064/mod_37_36.py, + stdnum/iso7064/mod_97_10.py, stdnum/luhn.py, stdnum/util.py, + stdnum/verhoeff.py: Fix flake8 blind except Exception error + +2021-01-04 Viggo de Vries + + * [cc3a970] stdnum/au/__init__.py: Use ABN as Australian VAT number + + See https://www.ato.gov.au/Business/GST/Tax-invoices/ + + Closes https://github.com/arthurdejong/python-stdnum/pull/246 + +2021-01-02 Arthur de Jong + + * [c74e322] stdnum/vatin.py, tests/test_vatin.doctest: Support + VAT numbers that are only valid with country prefix + + The Swish VAT number has the CH prefix embedded as a required + part of the number. This ensures that the international VAT + number module also supports that. + + Closes https://github.com/arthurdejong/python-stdnum/issues/245 + Fixes ff188bd + +2020-10-27 Matthias Schmid, M.Sc + + * [5082af4] stdnum/li/__init__.py, stdnum/li/peid.py, + tests/test_li_peid.doctest: Add Liechtenstein + Personenidentifikationsnummer + + Closes https://github.com/arthurdejong/python-stdnum/pull/241 + Closes https://github.com/arthurdejong/python-stdnum/issues/125 + +2020-10-02 Jonas Geuens + + * [3a592e4] stdnum/be/vat.py, tests/test_be_vat.doctest: Expanded + validation for BE VAT numbers + + Specifically invalidated all-zero numbers + + Closes https://github.com/arthurdejong/python-stdnum/pull/240 + +2020-11-01 Arthur de Jong + + * [c5eb2d8] stdnum/eu/vat.py, stdnum/ro/cf.py, + tests/test_eu_vat.doctest: Retain RO prefix in Romanian VAT numbers + + This does not strip the RO prefix from Romanian VAT numbers to be + able to keep the distinction between a CUI/CIF that is registered + for VAT (which commonly has the RO prefix) and those that don't. + + Closes https://github.com/arthurdejong/python-stdnum/issues/231 + +2020-11-01 Arthur de Jong + + * [1f6c77f] stdnum/ro/cnp.py, stdnum/ro/onrc.py: Minor updates + +2020-11-01 Arthur de Jong + + * [e0417f6] stdnum/ro/cf.py, stdnum/ro/cui.py: Add Romanian + CUI/CIF number + + This module separates the validation of numbers assigned to + companies (CUI or CIF) of those assigned to natural persons (CNP). + +2020-09-19 Arthur de Jong + + * [19d3f70] stdnum/eu/vat.py: Make list of EU member states list + of public API + + This provides stdnum.eu.vat.MEMBER_STATES. Note that Greece is + listed with a country code of "gr" while the prefix used in VAT + numbers is "el". + + Closes https://github.com/arthurdejong/python-stdnum/issues/238 + +2020-09-04 Arthur de Jong + + * [992dc20] online_check/check.js, + online_check/jquery-1.7.1.js, online_check/jquery-1.7.1.min.js, + online_check/jquery-3.5.1.js, online_check/jquery-3.5.1.min.js, + online_check/jquery-3.5.1.min.map, online_check/template.html: + Upgrade jQuery to 3.5.1 + + This also runs eslint over check.js and fixes an issue from + the upgrade. + +2020-08-09 Arthur de Jong + + * [3373938] ChangeLog, NEWS, README, docs/index.rst, + docs/stdnum.by.unp.rst, docs/stdnum.cn.uscc.rst, + docs/stdnum.gb.utr.rst, docs/stdnum.gs1_128.rst, + docs/stdnum.id.npwp.rst, docs/stdnum.il.hp.rst, + docs/stdnum.it.aic.rst, docs/stdnum.kr.brn.rst, + docs/stdnum.ro.onrc.rst, docs/stdnum.sg.uen.rst, + docs/stdnum.sv.nit.rst, docs/stdnum.tw.ubn.rst, + docs/stdnum.vatin.rst, docs/stdnum.vn.mst.rst, + docs/stdnum.za.idnr.rst, stdnum/__init__.py: Get files ready + for 1.14 release + +2020-08-09 Arthur de Jong + + * [40fcc24] stdnum/be/banks.dat, stdnum/cn/loc.dat, + stdnum/eu/nace.dat, stdnum/gs1_ai.dat, stdnum/iban.dat, + stdnum/imsi.dat, stdnum/isbn.dat, stdnum/nz/banks.dat, + stdnum/oui.dat, update/imsi.py, update/nz_banks.py: Update + database files + +2020-03-08 Leandro Regueiro + + * [ff188bd] stdnum/vatin.py, tests/test_vatin.doctest: Add module + to check any VAT number + + This effectively mimics vatnumber's `check_vat` function, so people + can easily replace the outdated vatnumber library with stdnum. + + Closes https://github.com/arthurdejong/python-stdnum/pull/199 + +2020-08-08 Arthur de Jong + + * [b6e43cd] update/gs1_ai.py: Fix Python 3.6 issue in update script + + Fixes 180788a + +2020-08-08 Arthur de Jong + + * [180788a] stdnum/gs1_128.py, stdnum/gs1_ai.dat, + tests/test_gs1_128.doctest, update/gs1_ai.py: Add GS1-128 format + + This adds validation, parsing and encoding functions for + GS1-128. It is based on the lists of formats as published by + the GS1 organisation. + + Based on the implementation provided by Sergi Almacellas Abellana + . + + Closes https://github.com/arthurdejong/python-stdnum/pull/144 + +2020-08-02 Arthur de Jong + + * [c2284f3] stdnum/ro/onrc.py, tests/test_ro_onrc.doctest: Add + Romanian Trade Register identifier + + Closes https://github.com/arthurdejong/python-stdnum/issues/229 + Closes https://github.com/arthurdejong/python-stdnum/pull/234 + +2020-06-02 Mohammed Salman + + * [94e2c63] stdnum/gb/utr.py, tests/test_gb_utr.doctest: Add + English Unique Tax Reference + + Closes https://github.com/arthurdejong/python-stdnum/pull/227 + +2020-08-02 Arthur de Jong + + * [505521e] stdnum/ro/cnp.py: Support foreign residents for + Romanian CNP + + This supports 7 or 8 as first digits in the CNP which are + apparently used to identify foreign residents. + + This also changes the exception for an incorrect first digit + from InvalidFormat to InvalidComponent which is a little clearer. + + Closes https://github.com/arthurdejong/python-stdnum/issues/230 + +2020-08-02 Arthur de Jong + + * [51a122d] stdnum/kr/GPKIRootCA1.crt, stdnum/kr/brn.py: Remove + custom CA certificate for www.ftc.go.kr + + This certificate is not needed any more because the site now + uses a different certificate that is signed by a known CA. + +2020-07-31 evaldez89 + + * [feca1fe] stdnum/do/rnc.py, tests/test_do_rnc.py: Scape new + line character + + Closes https://github.com/arthurdejong/python-stdnum/pull/233 + Closes https://github.com/arthurdejong/python-stdnum/issues/232 + +2020-04-05 Leandro Regueiro + + * [dab926c] stdnum/tw/__init__.py, stdnum/tw/ubn.py, + tests/test_tw_ubn.doctest: Add support for Taiwan TIN number + + Closes https://github.com/arthurdejong/python-stdnum/pull/214 + Closes https://github.com/arthurdejong/python-stdnum/issues/209 + +2020-07-05 Arthur de Jong + + * [291b831] tox.ini: Avoid newer isort for flake8 tests + + Do not install the latest isort because it currently breaks + flake8-isort. This pinning should be removed as soon as + https://github.com/gforcada/flake8-isort/issues/88 is resolved. + +2020-03-08 Leandro Regueiro + + * [7112874] stdnum/id/__init__.py, stdnum/id/npwp.py, + tests/test_id_npwp.doctest: Add support for Indonesian NPWP + + Closes https://github.com/arthurdejong/python-stdnum/issues/106 + Closes https://github.com/arthurdejong/python-stdnum/pull/198 + +2020-04-18 Leandro Regueiro + + * [a34a76d] stdnum/vn/__init__.py, stdnum/vn/mst.py, + tests/test_vn_mst.doctest: Add support for Vietnam TIN number + + Closes https://github.com/arthurdejong/python-stdnum/issues/217 + Closes https://github.com/arthurdejong/python-stdnum/pull/218 + +2020-05-16 Arthur de Jong + + * [1b7e985] stdnum/kr/GPKIRootCA1.crt, stdnum/kr/brn.py, + tests/test_kr_brn.py: Add an online check for the South Korean BRN + +2020-03-07 Leandro Regueiro + + * [b3891f1] stdnum/kr/__init__.py, stdnum/kr/brn.py, + tests/test_kr_brn.doctest: Add support for South Korea Business + Registration Number + + Closes https://github.com/arthurdejong/python-stdnum/pull/197 + Closes https://github.com/arthurdejong/python-stdnum/issues/101 + +2020-06-06 Christopher Ormaza + + * [127fff1] stdnum/ec/ci.py: Support 6 as third digit for foreign + people in Ecuador + + Closes https://github.com/arthurdejong/python-stdnum/pull/228 + +2020-03-18 Leandro Regueiro + + * [0d5b8b1] stdnum/sg/__init__.py, stdnum/sg/uen.py, + tests/test_sg_uen.doctest: Add support for Singapore Unique + Entity Number + + Closes https://github.com/arthurdejong/python-stdnum/issues/111 + Closes https://github.com/arthurdejong/python-stdnum/pull/203 + +2020-03-18 Leandro Regueiro + + * [4eda3f3] stdnum/nz/__init__.py: Add missing vat alias for + New Zealand + + Closes https://github.com/arthurdejong/python-stdnum/pull/202 + +2020-04-04 Leandro Regueiro + + * [f3ce70c] stdnum/cn/__init__.py, stdnum/cn/uscc.py, + tests/test_cn_uscc.doctest: Add support for Chinese TIN number + + Closes https://github.com/arthurdejong/python-stdnum/issues/207 + Closes https://github.com/arthurdejong/python-stdnum/pull/210 + +2020-04-10 Leandro Regueiro + + * [54e2e8f] stdnum/sv/__init__.py, stdnum/sv/nit.py, + tests/test_sv_nit.doctest: Add support for El Salvador TIN number + + Closes https://github.com/arthurdejong/python-stdnum/issues/133 + Closes https://github.com/arthurdejong/python-stdnum/pull/215 + +2020-03-31 Leandro Regueiro + + * [356a729] stdnum/il/__init__.py, stdnum/il/hp.py, + tests/test_il_hp.doctest: Add Israeli TIN number + + Closes https://github.com/arthurdejong/python-stdnum/pull/208 + Closes https://github.com/arthurdejong/python-stdnum/issues/107 + +2020-04-25 Arthur de Jong + + * [e49e0e9] docs/index.rst: Document function return behaviour + +2020-04-19 Arthur de Jong + + * [417b500] setup.cfg, setup.py, tox.ini: Flake 8 fixes + +2020-04-18 Arthur de Jong + + * [ff86618] .travis.yml: Resolve Travis configuration warnings + +2020-04-18 Arthur de Jong + + * [982322a] tox.ini: Avoid newest Sphinx + + Newer versions of Sphinx treat underscores differently when + used in arguments to automodule causing problems in generating + documentation for the stdnum.in_.aadhaar, stdnum.in_.pan, + stdnum.is_.kennitala and stdnum.is_.vsk modules. + +2020-03-20 Arthur de Jong + + * [91ca4da] stdnum/cu/ni.py, stdnum/do/ncf.py, stdnum/do/rnc.py, + stdnum/es/ccc.py, stdnum/es/referenciacatastral.py, + stdnum/eu/eic.py, stdnum/eu/nace.py, stdnum/fi/hetu.py, + stdnum/fr/nir.py, stdnum/gb/nhs.py, stdnum/gr/amka.py, + stdnum/isil.py, stdnum/issn.py, stdnum/kr/rrn.py, stdnum/mu/nid.py, + stdnum/mx/curp.py, stdnum/mx/rfc.py, stdnum/pl/regon.py: Use + HTTPS in URLs where possible + +2020-03-19 grzekru + + * [273dd54] stdnum/eu/vat.py: Use HTTPS instead of HTTP fox + VIES lookups + + Closes https://github.com/arthurdejong/python-stdnum/issues/204 + Closes https://github.com/arthurdejong/python-stdnum/pull/205 + +2020-03-03 FabrizioMontanari + + * [8433821] stdnum/it/aic.py, tests/test_it_aic.doctest: Add + Italian AIC codes + + Closes https://github.com/arthurdejong/python-stdnum/pull/193 + +2020-03-09 Arthur de Jong + + * [f7b968c] stdnum/by/unp.py: Fix typo + + Thanks @unho + +2020-03-08 Arthur de Jong + + * [d09ed52] stdnum/lv/pvn.py, stdnum/ru/inn.py: Use zip() for + applying weights in check algorithms + +2020-03-07 Arthur de Jong + + * [60139a8] stdnum/by/__init__.py, stdnum/by/portal.nalog.gov.by.crt, + stdnum/by/unp.py, tests/test_by_unp.doctest, tests/test_by_unp.py: + Add Bellarus УНП number + + This also adds a function to do an online lookup of the number. + + Closes https://github.com/arthurdejong/python-stdnum/issues/196 + +2020-03-07 Leandro Regueiro + + * [ebe7e10] stdnum/jp/__init__.py: Add missing vat alias for Japan + +2020-03-07 Leandro Regueiro + + * [6429080] stdnum/ca/__init__.py: Add missing vat alias for Canada + +2020-03-07 Leandro Regueiro + + * [84ee720] stdnum/tr/__init__.py: Add missing vat alias for Turkey + +2020-03-07 Leandro Regueiro + + * [fcbe159] stdnum/pe/__init__.py: Add missing vat alias for Peru + +2020-03-07 Leandro Regueiro + + * [9be7dee] stdnum/cr/__init__.py: Add missing vat alias for + Costa Rica + +2020-03-07 Leandro Regueiro + + * [69d22e9] stdnum/br/__init__.py: Add missing vat alias for Brazil + +2020-01-31 Leon Sandøy + + * [df9f922] stdnum/no/fodselsnummer.py, + tests/test_no_fodselsnummer.doctest: Implement get_birth_date() + for no.fodselsnummer + + This adds a function that allows you to determine a persons + birth date from a Norwegian fødselsnummer. + + This also accounts for D-numbers, H-numbers, and FH-numbers, + which contain special exceptions and modifications to the + birthdate portion of the number. + + Most of the information this is based on was found here: + https://no.wikipedia.org/wiki/F%C3%B8dselsnummer#H-nummer + + It also updates the list of valid fødselsnummer in the tests, + since this list contained many numbers that are not valid by + this new validation that now accounts for dates. + + Additionally, this updates all tests that were failing under the + new validation, and adds a few new tests to bring the coverage + to 100%. + + Closes https://github.com/arthurdejong/python-stdnum/pull/187 + +2020-01-31 Leon Sandøy + + * [4500881] stdnum/dk/cpr.py: Improve birth date validation + for dk.cpr + + This adds a check to validate that the birth date information + in a personnummer is not set in the future, resolving a TODO + from this file. + + It also improves exception messages for certain validation + fail conditions. + +2020-01-31 Leon Sandøy + + * [f5e0456] stdnum/se/personnummer.py: Fix misleading docstring + in se.personnummer get_birth_date() + + The docstring for get_birth_date() in the Swedish personnummer.py + warned that the datetime might be 100 years off because of the + lack of precision in the personnummer. + + This was accurate when the docstring was written, but this is + no longer accurate after the - and + signs were correctly handled. + + Fixes 5441ffa + +2020-03-01 Arthur de Jong + + * [8437b8e] .travis.yml: Use bionic for pypy3 tests on Travis + + This switches the pypy3 tests to bionic which has Python + 3.6.9. There were installation issues with 3.5.3 on trusty and + coverage issues with 3.6.1 of xenial (now the default on Travis). + +2020-02-24 Aleksi Hoffman + + * [353db92] stdnum/fi/hetu.py, tests/test_fi_hetu.doctest: Support + validating temporary Finnish personal identity codes + + This adds an optional allow_temporary parameter, which defaults + to False, to the validate() function. + + Closes https://github.com/arthurdejong/python-stdnum/pull/191 + +2020-02-18 Gustavo Valverde + + * [efa70f1] stdnum/do/ncf.py: Change DGII endpoint to new one + + The old endpoint has been deprecated. + + Closes https://github.com/arthurdejong/python-stdnum/pull/190 + +2020-02-12 Arthur de Jong + + * [e513888] stdnum/se/personnummer.py, + tests/test_se_personnummer.doctest: Fix issue with extra plus + or minus in se.personnummer + + Fixes 5441ffa Closes + https://github.com/arthurdejong/python-stdnum/issues/188 + +2020-01-22 Gustavo Valverde + + * [77a77ba] stdnum/do/ncf.py: Add missing NCF document types + for validation + + These document types are in the official + documentation, but were not being validated: + https://dgii.gov.do/cicloContribuyente/facturacion/comprobantesFiscales/Paginas/tiposComprobantes.aspx + + Closes https://github.com/arthurdejong/python-stdnum/pull/186 + +2020-01-19 Arthur de Jong + + * [d5666b8] ChangeLog, NEWS, README, docs/index.rst, + docs/stdnum.ch.esr.rst, setup.py, stdnum/__init__.py: Get files + ready for 1.13 release + +2020-01-19 Arthur de Jong + + * [334e907] online_check/stdnum.wsgi: Fix online check to be Python + 3 compatible + +2020-01-18 Arthur de Jong + + * [53d9934] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, + stdnum/cn/loc.dat, stdnum/eu/nace.dat, stdnum/iban.dat, + stdnum/imsi.dat, stdnum/isbn.dat, stdnum/isil.dat, + stdnum/nz/banks.dat, stdnum/oui.dat, update/iban.py: Update + database files + +2020-01-18 Arthur de Jong + + * [f23c549] stdnum/za/idnr.py, tests/test_za_idnr.doctest: Add + South African Identity Document number + + Closes https://github.com/arthurdejong/python-stdnum/issues/126 + +2020-01-12 Arthur de Jong + + * [42e096e] stdnum/isin.py, tests/test_isin.doctest: Add temporary + and internal ISIN country codes + + This adds a few temporary and internal country codes that are + used by various agencies so that they can also be validated. This + does not mean that all these numbers are globally valid. + + Closes https://github.com/arthurdejong/python-stdnum/issues/158 + +2019-12-06 anwarbaroudi + + * [87c195f] stdnum/isin.py, tests/test_isin.doctest: Add three + country codes to ISIN + + This adds three missing country codes: 'AN' for 'Netherlands + Antilles', 'CS' for 'Serbia and Montenegro' and 'XK' for 'Kosovo'. + + Closes https://github.com/arthurdejong/python-stdnum/issues/173 + Closes https://github.com/arthurdejong/python-stdnum/pull/174 + Closes https://github.com/arthurdejong/python-stdnum/pull/176 + +2020-01-09 Emmanuel Arias + + * [0b30c4b] stdnum/ar/cuit.py, tests/test_ar_cuit.doctest: Test + Argentinian CUIT type + + The first two digits of the CUIT indicate the type of CUIT + (personal, company or international) and can only have certain + values. + + Closes https://github.com/arthurdejong/python-stdnum/issues/179 + Closes https://github.com/arthurdejong/python-stdnum/pull/181 + +2020-01-09 Arthur de Jong + + * [a9b3e90] stdnum/nl/btw.py, tests/test_eu_vat.doctest: Support + new btw-identificatienummer + + The btw-identificatienummer has been introduced on January 1st + 2020 in the Netherlands as an alternative to the btw-nummer that + contains the BSN personal identifier. The number has the same + structure and function but does not contain a BSN and uses a + different check digit algorithm. + + Thanks to Cas Vissers, Jeroen van Heiningen, Jerome Hanke, Nicolas + Martinelli, Ronald Portier and Tim Muller for contributing to + the fix. + + More information: + + * + http://kleineondernemer.nl/index.php/nieuw-btw-identificatienummer-vanaf-1-januari-2020-voor-eenmanszaken + * https://nl.wikipedia.org/wiki/Btw-nummer_(Nederland) * + https://www.belastingdienst.nl/wps/wcm/connect/bldcontenten/belastingdienst/business/vat/new-vat-id/ + * + https://www.belastingdienst.nl/wps/wcm/connect/bldcontentnl/belastingdienst/zakelijk/btw/administratie_bijhouden/btw_nummers_controleren/uw_btw_nummer + + Closes https://github.com/arthurdejong/python-stdnum/issues/182 + Closes https://github.com/arthurdejong/python-stdnum/pull/183 + Closes https://github.com/arthurdejong/python-stdnum/pull/184 + Closes https://github.com/arthurdejong/python-stdnum/pull/185 + +2020-01-04 Arthur de Jong + + * [9605dbe] stdnum/it/codicefiscale.py, + tests/test_it_codicefiscale.doctest: The Italian IVA is also a + Codice Fiscale + + Closes https://github.com/arthurdejong/python-stdnum/issues/180 + +2019-12-18 Sergi Almacellas Abellana + + * [087c668] .travis.yml, setup.py, tox.ini: Add support for + Python 3.8 + + Closes https://github.com/arthurdejong/python-stdnum/pull/177 + +2019-12-27 Arthur de Jong + + * [922505a] stdnum/eu/nace.py: Broaden noqa docstring exclusion + + Nowadays flake8 seems to report this as D401 (First line should + be in imperative mood) while before it was D402 (First line + should not be the function’s signature). + +2019-12-27 Arthur de Jong + + * [de50109] stdnum/do/ncf.py: Switch to using lxml for HTML parsing + + This avoids an extra dependency on BeautifulSoup and makes the + code more consistent. + +2019-11-12 Jakub Wilk + + * [831c669] NEWS, README, stdnum/br/__init__.py, stdnum/br/cnpj.py, + stdnum/br/cpf.py: Fix typos + + Closes https://github.com/arthurdejong/python-stdnum/pull/172 + +2019-11-04 Kurt Keller + + * [388bac9] stdnum/iso11649.py: Add format to iso11649 + + Closes https://github.com/arthurdejong/python-stdnum/pull/171 + +2019-11-02 Kurt Keller + + * [a45d4f7] stdnum/ch/esr.py, tests/test_ch_esr.doctest: Add Swiss + ESR/ISR/QR-reference + + Closes https://github.com/arthurdejong/python-stdnum/pull/170 + +2019-10-27 Arthur de Jong + + * [41b9c94] ChangeLog, NEWS, README, docs/index.rst, + docs/stdnum.ad.nrt.rst, docs/stdnum.cr.cpf.rst, + docs/stdnum.cr.cpj.rst, docs/stdnum.cr.cr.rst, + docs/stdnum.gt.nit.rst, docs/stdnum.il.idnr.rst, + docs/stdnum.jp.cn.rst, docs/stdnum.kr.rrn.rst, + docs/stdnum.nz.ird.rst, docs/stdnum.pe.cui.rst, + docs/stdnum.pe.ruc.rst, docs/stdnum.py.ruc.rst, + docs/stdnum.tr.vkn.rst, docs/stdnum.uy.rut.rst, + docs/stdnum.ve.rif.rst, docs/stdnum.za.tin.rst, stdnum/__init__.py: + Get files ready for 1.12 release + 2019-10-27 Arthur de Jong * [6ca5b53] stdnum/at/postleitzahl.dat, stdnum/be/banks.dat, diff --git a/MANIFEST.in b/MANIFEST.in index ac3b4245..b718eaf2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ -include README NEWS ChangeLog COPYING *.py tox.ini +include README.md CONTRIBUTING.md NEWS ChangeLog COPYING *.py tox.ini recursive-include tests *.doctest *.dat *.py recursive-include docs *.rst *.py recursive-include online_check * recursive-include update README requirements.txt *.py +recursive-include scripts *.py diff --git a/NEWS b/NEWS index c25b326b..8eb60b3a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,302 @@ +changes from 2.1 to 2.2 +----------------------- + +* Add modules for the following number formats: + + - VÖEN (Vergi ödəyicisinin eyniləşdirmə nömrəsi, Azerbaijan tax number) + (thanks Leandro Regueiro) + - Belgian OGM-VCS + (thanks Cédric Krier) + - Leitweg-ID, a buyer reference or routing identifier for electronic invoices + (thanks Tuukka Tolvanen) + - European Excise Number (thanks Cédric Krier) + - n° d'accise (French number to identify taxpayers of excise taxes) + (thanks Cédric Krier) + - RCS (French trade registration number for commercial companies) + (thanks Fabien MICHEL) + - NUIT (Número Único de Identificação Tributaria, Mozambique tax number) + (thanks Luca and Leandro Regueiro) + - NINEA (Numéro d'Identification Nationale des Entreprises et Associations, Senegal tax number) + (thanks Leandro Regueiro) + +* Fix handling of decimals in Application Identifiers (thanks zipus) +* Update list of valid Chinese counties (thanks 电子旅人 and Luca) +* Mark more Romanian CNP county codes as valid (thanks luella-s) +* Support Latvian personal codes issued after 2017 (thanks José Luis López Pino) +* Provide aliases for Estonian numbers (thanks Joni Saarinen) +* Add validation of country code in BIC (thanks Luuk Gubbels) +* Add function to convert a French VAT number into a SIREN (thanks Fabien MICHEL) +* Add a function to format a French SIREN (thanks Fabien MICHEL) +* Add extra validation of Belgian VAT numbers (thanks Antonio Ginestar) +* Add support for nace revision 2.1 (thanks KathrinM) +* Support the new Romanian ONRC format (thanks dotbit1) +* Support new format for Brazilian CNPJ (thanks Cloves Oliveira) + + +changes from 2.0 to 2.1 +----------------------- + +* Add python_requires to setup.py to avoid installation with older Python versions + (thanks Cédric Krier) +* Remove superfluous modulus operation in Japanese Individual Number + (thanks Luca Sicurello) + + +changes from 1.20 to 2.0 +------------------------ + +* Only support Python 3.8 and newer (drop Python 2 support so major version bump) +* Include type hints for mypy (thanks David Salvisberg) + +* Add modules for the following number formats: + + - eID Number (Belgian electronic Identity Card Number) (thanks Jeff Horemans) + - SSN, INSZ, NISS (Belgian social security number) (thanks Jeff Horemans) + - CAE (Código de Actividad y Establecimiento, Spanish activity establishment code) + (thanks Quique Porta) + - NIK (Nomor Induk Kependudukan, Indonesian identity number) + - ISNI (International Standard Name Identifier) (thanks Henning Kage) + - IN (個人番号, kojin bangō, Japanese Individual Number) (thanks Luca Sicurello) + - Identiteitskaartnummer, Paspoortnummer (the Dutch passport number) + (thanks Jeff Horemans) + - ОГРН, OGRN, PSRN, ОГРНИП, OGRNIP (Russian Primary State Registration Number) + (thanks Ivan Stavropoltsev) + +* Fix Czech RČ check digit validation (thanks Jan Chaloupecky) +* Support Ecuador public RUC with juridical format (thanks Leandro) +* Allow Uruguay RUT numbers starting with 22 +* Add missing music industry ISRC country codes (thanks Victor Sordoillet) +* Support 16 digit Indonesian NPWP numbers (thanks Chris Smola) +* Adjust Swiss uid module to accept numbers without CHE prefix (thanks Jeff Horemans) +* Update Irish PPS validator to support new numbers (thanks Olly Middleton) +* Add missing vat alias for Thailand VAT number (thanks Leandro Regueiro) +* Add more tests for the Verhoeff implementation +* Ensure that certificate verification can be configured using the verify + argument when using web services +* The check_dgii() and search_dgii() functions from the Dominican Republic Cedula + and RNC modules no longer work due to a change in the DGII online web service +* Various small code cleanups (thanks David Salvisberg) +* Various small fixes to update scripts +* The stdnum.util.to_unicode() function is now deprecated and will be removed + in an upcoming release + + +changes from 1.19 to 1.20 +------------------------- + +* Add modules for the following number formats: + - BC PHN (British Columbia Personal Health Number) (thanks Ömer Boratav) + - EC Number (European Community number) (thanks Daniel Weber) + - VID (Indian personal virtual identity number) (thanks Atul Deolekar) + +* Fix typo in German Umsatzsteur Identifikationnummer (thanks Александр Кизеев) +* Ensure EU VAT numbers don't accept duplicate country codes +* Fix vatin number compacting for "EU" VAT numbers (thanks Davide Walder) +* Add check digit validation to French NIF (thanks Kevin Dagostino) +* Fix Ukrainian EDRPOU check digit calculation (thanks sector119) + + +changes from 1.18 to 1.19 +------------------------- + +* Add modules for the following number formats: + + - Tax Registration Number (الرقم الضريبي, Egypt tax number) (thanks Leandro Regueiro) + - Postcode (the Spanish postal code) (thanks Víctor) + - NIFp (Numéro d'Identification Fiscale Permanent, Guinea tax number) + (thanks Leandro Regueiro) + - BIS (Belgian BIS number) (thanks Jeff Horemans) + - Matična številka poslovnega registra (Corporate Registration Number) (thanks Blaž Bregar) + - OSS (European VAT on e-Commerce - One Stop Shop) (thanks Sergi Almacellas Abellana) + +* Extend the validation of the Albanian NIPT (NUIS) number (thanks Julien Launois) +* Support different date formats in parsing GS1-128 application identifiers +* Add get_county() function to Romanian CNP (thanks RaduBorzea) +* Add functionality to get gender from Belgian National Number (thanks Jeff Horemans) +* Add support for Finland HETU new century indicating signs (thanks Maks Turtiainen) +* Add functionality to get (partial) birth date from Belgian National Number + (thanks Jeff Horemans) +* Extend validation of Canadian SIN (thanks Marcel Lecker) +* Fix Belarusian UNP online validation +* Various typo and documentation fixes (thanks valeriko, Dimitri Papadopoulos, + Ali-Akber Saifee and Chales Horn) +* Add contribution information to documentation +* Test suite improvements (including checking file headers) + + +changes from 1.17 to 1.18 +------------------------- + +* Add modules for the following number formats: + + - NN, NISS (Belgian national number) (thanks Cédric Krier) + - CFI (ISO 10962 Classification of Financial Instruments) + - Czech bank account number (thanks Petr Přikryl) + - NIF, sometimes N.I.F. (Numéro d'Identification Fiscale, Algeria tax number) + (thanks Leandro Regueiro) + - V-number (Vinnutal, Faroe Islands tax number) (thanks Leandro Regueiro) + - TIN (Taxpayer Identification Number, Ghana tax number) (thanks Leandro Regueiro) + - PIN (Personal Identification Number, Kenya tax number) (thanks Leandro Regueiro) + - ICE (Identifiant Commun de l’Entreprise, التعريف الموحد للمقاولة, Morocco tax number) + (thanks Leandro Regueiro) + - PIB (Poreski Identifikacioni Broj, Montenegro tax number) (thanks Leandro Regueiro) + - ЕДБ (Едниствен Даночен Број, North Macedonia tax number) (thanks Leandro Regueiro) + - CNIC number (Pakistani Computerised National Identity Card number) + (thanks Syed Haseeb Shah) + - Enotna matična številka občana (Unique Master Citizen Number) + (thanks Blaž Bregar) + - MF (Matricule Fiscal, Tunisia tax number) (thanks Leandro Regueiro) + +* Fix disabling check digit validation of Mexican CURP (thanks guyskk) +* Support special validation of La Post SIRET (thanks BIGBen99 and Cédric Krier) +* Fix support for "I" and "O" in CUSIP number (thanks Thomas Kavanagh) +* Calculate ISO 7064 Mod 97, 10 check digits in the range 02-98 for IBAN + (thanks David Svenson) +* Fix German OffeneRegister lookups (change of URL and of data structure) +* Add extra court alias for Berlin in German Handelsregisternummer (thanks Romuald R) +* Ensure certificate for the Belarus VAT number check_nalog() lookup is included +* Support parsing incomplete dates in GS1-128 (thanks Alexis de Lattre) +* Improve validation of CAS Registry Number +* Typo fixes (thanks Vladimir and Dimitri Papadopoulos) +* Add a check_uid() function to the stdnum.ch.uid module +* All validation exceptions should now inherit from ValueError +* Switch from nose to pytest as test runner + + +changes from 1.16 to 1.17 +------------------------- + +* Add modules for the following number formats: + + - EPIC (Electoral Photo Identity Card, Indian Voter ID) + (thanks Gaurav Chauhan) + - GSTIN (Goods and Services Tax identification number, Indian VAT number) + (thanks Gaurav Chauhan) + - ISRC (International Standard Recording Code) (thanks Nuno André) + - CC (Número de Cartão de Cidadão, Portuguese Identity number) + (thanks David Vaz) + - Postcode (the Swedish postal code) (thanks Michele Ciccozzi) + - MOA (Thailand Memorandum of Association Number) (thanks Piruin Panichphol) + - PIN (Thailand Personal Identification Number) (thanks Piruin Panichphol) + - TIN (Thailand Taxpayer Identification Number) (thanks Piruin Panichphol) + +* Add ENCF validation support for Dominican Republic NCF + (thanks Cristopher Ortega) +* Add new e-CF types to Dominican Republic NCF (thanks Frank Roberto Chavez Sosa) +* Improve French NIF validation (thanks Dimitri Papadopoulos) +* Drop support for Python 2.6 and 3.4 +* Fix parsing of empty fields in Dominican Republic DGII checking + (thanks Andres Rodriguez) +* Fix handling of empty worksheet in Belgian bank download + (thanks Dimitri Papadopoulos) +* Fix detection of natural RUC values (thanks Victor Rodriguez) +* Fix Belarus VAT number online lookup again +* Fixes for problems with loading IMSI data from Wikipedia and dealing with + inconsistencies +* Remove South Korean BRN Fair Trade Commission website check due to CAPTCHA +* Various code and documentation improvements (thanks Dimitri Papadopoulos and Gaurav Chauhan) + + +changes from 1.15 to 1.16 +------------------------- + +* Support XI country code for Northern Ireland VAT numbers + (thanks Alexis de Lattre) +* Switch data source for Austrian postal codes + (thanks Bernd Schlapsi) +* Fix Belarus VAT number online lookup + + +changes from 1.14 to 1.15 +------------------------- + +* Add modules for the following number formats: + + - CUI or CIF (Codul Unic de Înregistrare, Romanian company identifier) + - PEID (Liechtenstein tax code for individuals and entities) + (thanks Matthias Schmid) + - ЄДРПОУ, EDRPOU (Identifier for enterprises and organizations in Ukraine) + (thanks Leandro Regueiro) + - РНОКПП, RNTRC (Individual taxpayer registration number in Ukraine) + (thanks Leandro Regueiro) + +* Make list of EU member states part of public API +* Retain RO prefix in Romanian VAT numbers +* Support international VAT numbers that are only valid with country prefix +* Expanded validation for Belgian VAT numbers +* Use ABN as Australian VAT number +* Remove GB from EU member states + + +changes from 1.13 to 1.14 +------------------------- + +* Add modules for the following number formats: + + - УНП, UNP (Учетный номер плательщика, the Belarus VAT number) + - AIC (Italian code for identification of drugs) (thanks Fabrizio Montanari) + - Company Number (מספר חברה, or short ח.פ. Israeli company number) + (thanks Leandro Regueiro) + - NIT (Número de Identificación Tributaria, El Salvador tax number) + (thanks Leandro Regueiro) + - USCC (Unified Social Credit Code, 统一社会信用代码, China tax number) + (thanks Leandro Regueiro) + - UEN (Singapore's Unique Entity Number) (thanks Leandro Regueiro) + - BRN (사업자 등록 번호, South Korea Business Registration Number) + (thanks Leandro Regueiro) + - MST (Mã số thuế, Vietnam tax number) (thanks Leandro Regueiro) + - NPWP (Nomor Pokok Wajib Pajak, Indonesian VAT Number) + (thanks Leandro Regueiro) + - UBN (Unified Business Number, 統一編號, Taiwanese tax number) + (thanks Leandro Regueiro) + - UTR (United Kingdom Unique Taxpayer Reference) (thanks Mohammed Salman) + - ONRC (Ordine din Registrul Comerţului, Romanian Trade Register identifier) + (thanks dotbit1) + - GS1-128 (Standard to encode product information in Code 128 barcodes) + (thanks Sergi Almacellas Abellana) + - VATIN (International value added tax identification number) + (thanks Leandro Regueiro) + +* Fix missing Dominican Republic NCF document types (thanks Gustavo Valverde) +* Fix issue with extra plus or minus in Swedish Personnummer + (thanks balderman) +* Update Dominican Republic DGII endpoint (thanks Gustavo Valverde) +* Support validating temporary Finnish personal identity codes + (thanks Aleksi Hoffman) +* Fix misleading docstring in se.personnummer.get_birth_date() + (thanks Leon Sandøy) +* Improve birth date validation in Danish CPR (thanks Leon Sandøy) +* Add birth date validating in Norwegian Fødselsnummer (thanks Leon Sandøy) +* Add missing vat aliases for a number of countries (thanks Leandro Regueiro) +* Use HTTPS instead of HTTP fox VIES lookups (thanks grzekru) +* Switch to HTTPS URLs where possible +* Support 6 as third digit in Ecuadorian CI (thanks Christopher Ormaza) +* Add an online check for South Korean BRN +* Fix unescaping in Dominican Republic RNC online check (thanks evaldez89) +* Support foreign residents for Romanian CNP (thanks dotbit1) + + +changes from 1.12 to 1.13 +------------------------- + +* Add modules for the following number formats: + + - ESR, ISR, QR-reference (reference number on Swiss payment slips) + (thanks Kurt Keller) + - ID number (South African Identity Document number) + +* Add format function for ISO 11649 numbers (thanks Kurt Keller) +* Add support for Python 3.8 (thanks Sergi Almacellas Abellana) +* Clarify that the Italian Codice Fiscale can also be the IVA for companies + (thanks Nicholas Fiorentini) +* Support the new Dutch btw-identificatienummer (thanks Cas Vissers, + Jeroen van Heiningen, Jerome Hanke, Nicolas Martinelli, Ronald Portier and + Tim Muller) +* Extend test for Argentinian CUIT to check first two digits +* Add more country codes to ISIN (thanks nocluebutalotofit, Anwar Baroudi and + alexbond73) + + changes from 1.11 to 1.12 ------------------------- @@ -254,7 +553,7 @@ changes from 1.1 to 1.2 - VAT, MWST, TVA, IVA, TPV (Mehrwertsteuernummer, the Swiss VAT number) - CUSIP number (financial security identification number) - Wertpapierkennnummer (German securities identification code) - - Isikukood (Estonian Personcal ID number) + - Isikukood (Estonian Personal ID number) - Finnish Association Identifier - Y-tunnus (Finnish business identifier) - SEDOL number (Stock Exchange Daily Official List number) diff --git a/README b/README.md similarity index 73% rename from README rename to README.md index d43693c3..75bc4fbd 100644 --- a/README +++ b/README.md @@ -16,7 +16,7 @@ Available formats Currently this package supports the following formats: * NRT (Número de Registre Tributari, Andorra tax number) - * NIPT (Numri i Identifikimit për Personin e Tatueshëm, Albanian VAT number) + * NIPT, NUIS (Numri i Identifikimit për Personin e Tatueshëm, Albanian tax number) * CBU (Clave Bancaria Uniforme, Argentine bank account number) * CUIT (Código Único de Identificación Tributaria, Argentinian tax number) * DNI (Documento Nacional de Identidad, Argentinian national identity nr.) @@ -28,7 +28,13 @@ Currently this package supports the following formats: * ABN (Australian Business Number) * ACN (Australian Company Number) * TFN (Australian Tax File Number) + * VÖEN (Vergi ödəyicisinin eyniləşdirmə nömrəsi, Azerbaijan tax number) + * BIS (Belgian BIS number) + * eID Number (Belgian electronic Identity Card Number) * Belgian IBAN (International Bank Account Number) + * NN, NISS, RRN (Belgian national number) + * Belgian OGM-VCS + * SSN, INSZ, NISS (Belgian social security number) * BTW, TVA, NWSt, ondernemingsnummer (Belgian enterprise number) * EGN (ЕГН, Единен граждански номер, Bulgarian personal identity codes) * PNF (ЛНЧ, Личен номер на чужденец, Bulgarian number of a foreigner) @@ -37,14 +43,19 @@ Currently this package supports the following formats: * Bitcoin address * CNPJ (Cadastro Nacional da Pessoa Jurídica, Brazilian company identifier) * CPF (Cadastro de Pessoas Físicas, Brazilian national identifier) + * УНП, UNP (Учетный номер плательщика, the Belarus VAT number) + * BC PHN (British Columbia Personal Health Number) * BN (Canadian Business Number) * SIN (Canadian Social Insurance Number) * CAS RN (Chemical Abstracts Service Registry Number) + * CFI (ISO 10962 Classification of Financial Instruments) + * ESR, ISR, QR-reference (reference number on Swiss payment slips) * Swiss social security number ("Sozialversicherungsnummer") * UID (Unternehmens-Identifikationsnummer, Swiss business identifier) * VAT, MWST, TVA, IVA, TPV (Mehrwertsteuernummer, the Swiss VAT number) * RUT (Rol Único Tributario, Chilean national tax number) * RIC No. (Chinese Resident Identity Card Number) + * USCC (Unified Social Credit Code, 统一社会信用代码, China tax number) * NIT (Número De Identificación Tributaria, Colombian identity code) * CPF (Cédula de Persona Física, Costa Rica physical person ID number) * CPJ (Cédula de Persona Jurídica, Costa Rica tax number) @@ -52,10 +63,12 @@ Currently this package supports the following formats: * NI (Número de identidad, Cuban identity card numbers) * CUSIP number (financial security identification number) * Αριθμός Εγγραφής Φ.Π.Α. (Cypriot VAT number) + * Czech bank account number * DIČ (Daňové identifikační číslo, Czech VAT number) * RČ (Rodné číslo, the Czech birth number) * Handelsregisternummer (German company register number) * IdNr (Steuerliche Identifikationsnummer, German personal tax number) + * Leitweg-ID, a buyer reference or routing identifier for electronic invoices * St.-Nr. (Steuernummer, German tax number) * Ust ID Nr. (Umsatzsteur Identifikationnummer, German VAT number) * Wertpapierkennnummer (German securities identification code) @@ -64,12 +77,15 @@ Currently this package supports the following formats: * Cedula (Dominican Republic national identification number) * NCF (Números de Comprobante Fiscal, Dominican Republic receipt number) * RNC (Registro Nacional del Contribuyente, Dominican Republic tax number) + * NIF, sometimes N.I.F. (Numéro d'Identification Fiscale, Algeria tax number) * EAN (International Article Number) * CI (Cédula de identidad, Ecuadorian personal identity code) * RUC (Registro Único de Contribuyentes, Ecuadorian company tax number) - * Isikukood (Estonian Personcal ID number) + * Isikukood (Estonian Personal ID number) * KMKR (Käibemaksukohuslase, Estonian VAT number) * Registrikood (Estonian organisation registration code) + * Tax Registration Number (الرقم الضريبي, Egypt tax number) + * CAE (Código de Actividad y Establecimiento, Spanish activity establishment code) * CCC (Código Cuenta Corriente, Spanish Bank Account Code) * CIF (Código de Identificación Fiscal, Spanish company tax number) * CUPS (Código Unificado de Punto de Suministro, Spanish meter point number) @@ -77,11 +93,15 @@ Currently this package supports the following formats: * Spanish IBAN (International Bank Account Number) * NIE (Número de Identificación de Extranjero, Spanish foreigner number) * NIF (Número de Identificación Fiscal, Spanish VAT number) + * Postcode (the Spanish postal code) * Referencia Catastral (Spanish real estate property id) * SEPA Identifier of the Creditor (AT-02) * Euro banknote serial numbers + * EC Number (European Community number) * EIC (European Energy Identification Code) + * European Excise Number * NACE (classification for businesses in the European Union) + * OSS (European VAT on e-Commerce - One Stop Shop) * VAT (European Union VAT number) * ALV nro (Arvonlisäveronumero, Finnish VAT number) * Finnish Association Identifier @@ -89,30 +109,43 @@ Currently this package supports the following formats: * Veronumero (Finnish individual tax number) * Y-tunnus (Finnish business identifier) * FIGI (Financial Instrument Global Identifier) + * V-number (Vinnutal, Faroe Islands tax number) + * n° d'accise (French number to identify taxpayers of excise taxes) * NIF (Numéro d'Immatriculation Fiscale, French tax identification number) * NIR (French personal identification number) + * RCS (French trade registration number for commercial companies) * SIREN (a French company identification number) * SIRET (a French company establishment identification number) * n° TVA (taxe sur la valeur ajoutée, French VAT number) * NHS (United Kingdom National Health Service patient identifier) * SEDOL number (Stock Exchange Daily Official List number) * UPN (English Unique Pupil Number) + * UTR (United Kingdom Unique Taxpayer Reference) * VAT (United Kingdom (and Isle of Man) VAT registration number) + * TIN (Taxpayer Identification Number, Ghana tax number) + * NIFp (Numéro d'Identification Fiscale Permanent, Guinea tax number) * AMKA (Αριθμός Μητρώου Κοινωνικής Ασφάλισης, Greek social security number) * FPA, ΦΠΑ, ΑΦΜ (Αριθμός Φορολογικού Μητρώου, the Greek VAT number) * GRid (Global Release Identifier) + * GS1-128 (Standard to encode product information in Code 128 barcodes) * NIT (Número de Identificación Tributaria, Guatemala tax number) * OIB (Osobni identifikacijski broj, Croatian identification number) * ANUM (Közösségi adószám, Hungarian VAT number) * IBAN (International Bank Account Number) + * NIK (Nomor Induk Kependudukan, Indonesian identity number) + * NPWP (Nomor Pokok Wajib Pajak, Indonesian VAT Number) * PPS No (Personal Public Service Number, Irish personal number) * VAT (Irish tax reference number) + * Company Number (מספר חברה, or short ח.פ. Israeli company number) * Identity Number (Mispar Zehut, מספר זהות, Israeli identity number) * IMEI (International Mobile Equipment Identity) * IMO number (International Maritime Organization number) * IMSI (International Mobile Subscriber Identity) - * Aadhaar (Indian digital resident personal identity number) + * Aadhaar (Indian personal identity number) + * EPIC (Electoral Photo Identity Card, Indian Voter ID) + * GSTIN (Goods and Services Tax identification number, Indian VAT number) * PAN (Permanent Account Number, Indian income tax identifier) + * VID (Indian personal virtual identity number) * Kennitala (Icelandic personal and organisation identity code) * VSK number (Virðisaukaskattsnúmer, Icelandic VAT number) * ISAN (International Standard Audiovisual Number) @@ -120,31 +153,43 @@ Currently this package supports the following formats: * ISIL (International Standard Identifier for Libraries) * ISIN (International Securities Identification Number) * ISMN (International Standard Music Number) + * ISNI (International Standard Name Identifier) * ISO 11649 (Structured Creditor Reference) * ISO 6346 (International standard for container identification) + * ISRC (International Standard Recording Code) * ISSN (International Standard Serial Number) + * AIC (Italian code for identification of drugs) * Codice Fiscale (Italian tax code for individuals) * Partita IVA (Italian VAT number) * CN (法人番号, hōjin bangō, Japanese Corporate Number) + * IN (個人番号, kojin bangō, Japanese Individual Number) + * PIN (Personal Identification Number, Kenya tax number) + * BRN (사업자 등록 번호, South Korea Business Registration Number) * RRN (South Korean resident registration number) * LEI (Legal Entity Identifier) + * PEID (Liechtenstein tax code for individuals and entities) * Asmens kodas (Lithuanian, personal numbers) * PVM (Pridėtinės vertės mokestis mokėtojo kodas, Lithuanian VAT number) * TVA (taxe sur la valeur ajoutée, Luxembourgian VAT number) * PVN (Pievienotās vērtības nodokļa, Latvian VAT number) + * ICE (Identifiant Commun de l’Entreprise, التعريف الموحد للمقاولة, Morocco tax number) * MAC address (Media Access Control address) * n° TVA (taxe sur la valeur ajoutée, Monacan VAT number) * IDNO (Moldavian company identification number) * Montenegro IBAN (International Bank Account Number) + * PIB (Poreski Identifikacioni Broj, Montenegro tax number) * MEID (Mobile Equipment Identifier) + * ЕДБ (Едниствен Даночен Број, North Macedonia tax number) * VAT (Maltese VAT number) * ID number (Mauritian national identifier) * CURP (Clave Única de Registro de Población, Mexican personal ID) * RFC (Registro Federal de Contribuyentes, Mexican tax number) * NRIC No. (Malaysian National Registration Identity Card Number) + * NUIT (Número Único de Identificação Tributaria, Mozambique tax number) * BRIN number (the Dutch school identification number) * BSN (Burgerservicenummer, the Dutch citizen identification number) - * Btw-nummer (Omzetbelastingnummer, the Dutch VAT number) + * Btw-identificatienummer (Omzetbelastingnummer, the Dutch VAT number) + * Identiteitskaartnummer, Paspoortnummer (the Dutch passport number) * Onderwijsnummer (the Dutch student identification number) * Postcode (the Dutch postal code) * Fødselsnummer (Norwegian birth number, the national identity number) @@ -156,24 +201,42 @@ Currently this package supports the following formats: * IRD number (New Zealand Inland Revenue Department (Te Tari Tāke) number) * CUI (Cédula Única de Identidad, Peruvian identity number) * RUC (Registro Único de Contribuyentes, Peruvian company tax number) + * CNIC number (Pakistani Computerised National Identity Card number) * NIP (Numer Identyfikacji Podatkowej, Polish VAT number) * PESEL (Polish national identification number) * REGON (Rejestr Gospodarki Narodowej, Polish register of economic units) + * CC (Número de Cartão de Cidadão, Portuguese Identity number) * NIF (Número de identificação fiscal, Portuguese VAT number) * RUC number (Registro Único de Contribuyentes, Paraguay tax number) * CF (Cod de înregistrare în scopuri de TVA, Romanian VAT number) * CNP (Cod Numeric Personal, Romanian Numerical Personal Code) + * CUI or CIF (Codul Unic de Înregistrare, Romanian company identifier) + * ONRC (Ordine din Registrul Comerţului, Romanian Trade Register identifier) * PIB (Poreski Identifikacioni Broj, Serbian tax identification number) * ИНН (Идентификационный номер налогоплательщика, Russian tax identifier) + * ОГРН, OGRN, PSRN, ОГРНИП, OGRNIP (Russian Primary State Registration Number) * Orgnr (Organisationsnummer, Swedish company number) * Personnummer (Swedish personal identity number) + * Postcode (the Swedish postal code) * VAT (Moms, Mervärdesskatt, Swedish VAT number) + * UEN (Singapore's Unique Entity Number) * ID za DDV (Davčna številka, Slovenian VAT number) + * Enotna matična številka občana (Unique Master Citizen Number) + * Matična številka poslovnega registra (Corporate Registration Number) * IČ DPH (IČ pre daň z pridanej hodnoty, Slovak VAT number) * RČ (Rodné číslo, the Slovak birth number) * COE (Codice operatore economico, San Marino national tax number) + * NINEA (Numéro d'Identification Nationale des Entreprises et Associations, Senegal tax number) + * NIT (Número de Identificación Tributaria, El Salvador tax number) + * MOA (Thailand Memorandum of Association Number) + * PIN (Thailand Personal Identification Number) + * TIN (Thailand Taxpayer Identification Number) + * MF (Matricule Fiscal, Tunisia tax number) * T.C. Kimlik No. (Turkish personal identification number) * VKN (Vergi Kimlik Numarası, Turkish tax identification number) + * UBN (Unified Business Number, 統一編號, Taiwanese tax number) + * ЄДРПОУ, EDRPOU (Identifier for enterprises and organizations in Ukraine) + * РНОКПП, RNTRC (Individual taxpayer registration number in Ukraine) * ATIN (U.S. Adoption Taxpayer Identification Number) * EIN (U.S. Employer Identification Number) * ITIN (U.S. Individual Taxpayer Identification Number) @@ -182,7 +245,10 @@ Currently this package supports the following formats: * SSN (U.S. Social Security Number) * TIN (U.S. Taxpayer Identification Number) * RUT (Registro Único Tributario, Uruguay tax number) + * VATIN (International value added tax identification number) * RIF (Registro de Identificación Fiscal, Venezuelan VAT number) + * MST (Mã số thuế, Vietnam tax number) + * ID number (South African Identity Document number) * TIN (South African Tax Identification Number) Furthermore a number of generic check digit algorithms are available: @@ -233,13 +299,12 @@ Requirements ------------ The modules should not require any external Python modules and should be pure -Python. The modules are developed and tested with Python 2.7 and 3.6 but may -also work with older versions of Python. +Python. The modules are developed and tested with Python 3 versions (see `setup.py`). Copyright --------- -Copyright (C) 2010-2019 Arthur de Jong and others +Copyright (C) 2010-2026 Arthur de Jong and others This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -252,9 +317,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA +License along with this library; if not, see . Feedback and bug reports ------------------------ diff --git a/docs/conf.py b/docs/conf.py index 6c8e4a24..d37c1cbe 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,25 +11,18 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +"""python-stdnum documentation build configuration.""" import stdnum -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('..')) # -- General configuration ----------------------------------------------------- -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', - 'sphinx.ext.coverage', 'sphinx.ext.autosummary' + 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', + 'sphinx.ext.coverage', 'sphinx.ext.autosummary', ] # Add any paths that contain templates here, relative to this directory. @@ -46,7 +39,7 @@ # General information about the project. project = u'python-stdnum' -copyright = u'2013-2019, Arthur de Jong' +copyright = u'2013-2026, Arthur de Jong' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -57,43 +50,21 @@ # The full version, including alpha/beta/rc tags. release = version -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_*', '.svn', '.git'] -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['stdnum.', ] +modindex_common_prefix = ['stdnum.'] # Automatically generate stub pages for autosummary entries. autosummary_generate = True +# Autosummary overwrites existing files by generated stub pages. +autosummary_generate_overwrite = False # -- Options for HTML output --------------------------------------------------- @@ -101,79 +72,13 @@ # a list of builtin themes. html_theme = 'default' -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] - # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%Y-%m-%d' -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - # If true, links to the reST sources are added to the pages. html_show_sourcelink = False -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Suffix for generated links to HTML files. -#html_link_suffix = '' - # Output file base name for HTML help builder. htmlhelp_basename = 'python-stdnumdoc' @@ -184,10 +89,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'python-stdnum', u'python-stdnum Documentation', - [u'Arthur de Jong'], 1) + [u'Arthur de Jong'], 1), ] -# If true, show URL addresses after external links. -#man_show_urls = False - intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 00000000..58977a88 --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.md diff --git a/docs/index.rst b/docs/index.rst index 80469ce2..7cb0b702 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,6 @@ .. module:: stdnum -.. include:: ../README +.. include:: ../README.md :end-before: Available formats @@ -9,44 +9,57 @@ Common Interface Most of the number format modules implement the following functions: -.. function:: module.validate(number) +.. function:: module.validate(number: str) -> str Validate the number and return a compact, consistent representation of the number or code. If the validation fails, :mod:`an exception <.exceptions>` is raised that indicates the type of error. -.. function:: module.is_valid(number) + :raises ValidationError: When the specified number is invalid + :returns: str -- A compact (canonical) representation of the number + +.. function:: module.is_valid(number: str) -> bool Return either ``True`` or ``False`` depending on whether the passed number is in any supported and valid form and passes all embedded checks of the number. This function should never raise an exception. -.. function:: module.compact(number) + :returns: bool -- ``True`` if validated, ``False`` otherwise + +.. function:: module.compact(number: str) -> str Return a compact representation of the number or code. This function generally does not do validation but may raise exceptions for wildly invalid numbers. -.. function:: module.format(number) + :returns: str -- The compacted number + +.. function:: module.format(number: str) -> str Return a formatted version of the number in the preferred format. This function generally expects to be passed a valid number or code and may raise exceptions for invalid numbers. + :returns: str -- A formatted number + The check digit modules generally also provide the following functions: -.. function:: module.checksum(number) +.. function:: module.checksum(number: str) -> int Calculate the checksum over the provided number. This is generally a number that can be used to determine whether the provided number is valid. It depends on the algorithm which checksum is considered valid. -.. function:: module.calc_check_digit(number) + :returns: int -- A numeric checksum over the number + +.. function:: module.calc_check_digit(number: str) -> str Calculate the check digit that should be added to the number to make it valid. + :returns: str -- A check digit that can be appended + Apart from the above, the modules may add extra parsing, validation or conversion functions. @@ -79,7 +92,7 @@ Helper functions and modules may have multiple) * ``'personalid'`` for generic personal identifiers (some countries may have multiple, especially for tax purposes) - * ``'postcal_code'`` for address postal codes + * ``'postal_code'`` for address postal codes Generic check digit algorithms @@ -113,7 +126,13 @@ Available formats au.abn au.acn au.tfn + az.voen + be.bis + be.eid be.iban + be.nn + be.ogm_vcs + be.ssn be.vat bg.egn bg.pnf @@ -122,14 +141,19 @@ Available formats bitcoin br.cnpj br.cpf + by.unp + ca.bc_phn ca.bn ca.sin casrn + cfi + ch.esr ch.ssn ch.uid ch.vat cl.rut cn.ric + cn.uscc co.nit cr.cpf cr.cpj @@ -137,10 +161,12 @@ Available formats cu.ni cusip cy.vat + cz.bankaccount cz.dic cz.rc de.handelsregisternummer de.idnr + de.leitweg de.stnr de.vat de.wkn @@ -149,12 +175,15 @@ Available formats do.cedula do.ncf do.rnc + dz.nif ean ec.ci ec.ruc ee.ik ee.kmkr ee.registrikood + eg.tn + es.cae es.ccc es.cif es.cups @@ -162,11 +191,15 @@ Available formats es.iban es.nie es.nif + es.postal_code es.referenciacatastral eu.at_02 eu.banknote + eu.ecnumber eu.eic + eu.excise eu.nace + eu.oss eu.vat fi.alv fi.associationid @@ -174,30 +207,43 @@ Available formats fi.veronumero fi.ytunnus figi + fo.vn + fr.accise fr.nif fr.nir + fr.rcs fr.siren fr.siret fr.tva gb.nhs gb.sedol gb.upn + gb.utr gb.vat + gh.tin + gn.nifp gr.amka gr.vat grid + gs1_128 gt.nit hr.oib hu.anum iban + id.nik + id.npwp ie.pps ie.vat + il.hp il.idnr imei imo imsi in_.aadhaar + in_.epic + in_.gstin in_.pan + in_.vid is_.kennitala is_.vsk isan @@ -205,31 +251,43 @@ Available formats isil isin ismn + isni iso11649 iso6346 + isrc issn + it.aic it.codicefiscale it.iva jp.cn + jp.in_ + ke.pin + kr.brn kr.rrn lei + li.peid lt.asmens lt.pvm lu.tva lv.pvn + ma.ice mac mc.tva md.idno me.iban + me.pib meid + mk.edb mt.vat mu.nid mx.curp mx.rfc my.nric + mz.nuit nl.brin nl.bsn nl.btw + nl.identiteitskaartnummer nl.onderwijsnummer nl.postcode no.fodselsnummer @@ -241,24 +299,42 @@ Available formats nz.ird pe.cui pe.ruc + pk.cnic pl.nip pl.pesel pl.regon + pt.cc pt.nif py.ruc ro.cf ro.cnp + ro.cui + ro.onrc rs.pib ru.inn + ru.ogrn se.orgnr se.personnummer + se.postnummer se.vat + sg.uen si.ddv + si.emso + si.maticna sk.dph sk.rc sm.coe + sn.ninea + sv.nit + th.moa + th.pin + th.tin + tn.mf tr.tckimlik tr.vkn + tw.ubn + ua.edrpou + ua.rntrc us.atin us.ein us.itin @@ -267,7 +343,10 @@ Available formats us.ssn us.tin uy.rut + vatin ve.rif + vn.mst + za.idnr za.tin @@ -278,3 +357,12 @@ Changes in python-stdnum :maxdepth: 2 changes + + +Contributing to python-stdnum +----------------------------- + +.. toctree:: + :maxdepth: 2 + + contributing diff --git a/docs/stdnum.az.voen.rst b/docs/stdnum.az.voen.rst new file mode 100644 index 00000000..8c303dd3 --- /dev/null +++ b/docs/stdnum.az.voen.rst @@ -0,0 +1,5 @@ +stdnum.az.voen +============== + +.. automodule:: stdnum.az.voen + :members: \ No newline at end of file diff --git a/docs/stdnum.be.bis.rst b/docs/stdnum.be.bis.rst new file mode 100644 index 00000000..916faf4c --- /dev/null +++ b/docs/stdnum.be.bis.rst @@ -0,0 +1,5 @@ +stdnum.be.bis +============= + +.. automodule:: stdnum.be.bis + :members: \ No newline at end of file diff --git a/docs/stdnum.be.eid.rst b/docs/stdnum.be.eid.rst new file mode 100644 index 00000000..2bcedf5f --- /dev/null +++ b/docs/stdnum.be.eid.rst @@ -0,0 +1,5 @@ +stdnum.be.eid +============= + +.. automodule:: stdnum.be.eid + :members: \ No newline at end of file diff --git a/docs/stdnum.be.nn.rst b/docs/stdnum.be.nn.rst new file mode 100644 index 00000000..1937b8b7 --- /dev/null +++ b/docs/stdnum.be.nn.rst @@ -0,0 +1,5 @@ +stdnum.be.nn +============ + +.. automodule:: stdnum.be.nn + :members: \ No newline at end of file diff --git a/docs/stdnum.be.ogm_vcs.rst b/docs/stdnum.be.ogm_vcs.rst new file mode 100644 index 00000000..efb1854e --- /dev/null +++ b/docs/stdnum.be.ogm_vcs.rst @@ -0,0 +1,5 @@ +stdnum.be.ogm_vcs +================= + +.. automodule:: stdnum.be.ogm_vcs + :members: \ No newline at end of file diff --git a/docs/stdnum.be.ssn.rst b/docs/stdnum.be.ssn.rst new file mode 100644 index 00000000..3cf31865 --- /dev/null +++ b/docs/stdnum.be.ssn.rst @@ -0,0 +1,5 @@ +stdnum.be.ssn +============= + +.. automodule:: stdnum.be.ssn + :members: \ No newline at end of file diff --git a/docs/stdnum.by.unp.rst b/docs/stdnum.by.unp.rst new file mode 100644 index 00000000..571babe7 --- /dev/null +++ b/docs/stdnum.by.unp.rst @@ -0,0 +1,5 @@ +stdnum.by.unp +============= + +.. automodule:: stdnum.by.unp + :members: \ No newline at end of file diff --git a/docs/stdnum.ca.bc_phn.rst b/docs/stdnum.ca.bc_phn.rst new file mode 100644 index 00000000..1299ee4d --- /dev/null +++ b/docs/stdnum.ca.bc_phn.rst @@ -0,0 +1,5 @@ +stdnum.ca.bc_phn +================ + +.. automodule:: stdnum.ca.bc_phn + :members: \ No newline at end of file diff --git a/docs/stdnum.cfi.rst b/docs/stdnum.cfi.rst new file mode 100644 index 00000000..bc4be164 --- /dev/null +++ b/docs/stdnum.cfi.rst @@ -0,0 +1,5 @@ +stdnum.cfi +========== + +.. automodule:: stdnum.cfi + :members: \ No newline at end of file diff --git a/docs/stdnum.ch.esr.rst b/docs/stdnum.ch.esr.rst new file mode 100644 index 00000000..edb2ef99 --- /dev/null +++ b/docs/stdnum.ch.esr.rst @@ -0,0 +1,5 @@ +stdnum.ch.esr +============= + +.. automodule:: stdnum.ch.esr + :members: \ No newline at end of file diff --git a/docs/stdnum.cn.uscc.rst b/docs/stdnum.cn.uscc.rst new file mode 100644 index 00000000..c76956c2 --- /dev/null +++ b/docs/stdnum.cn.uscc.rst @@ -0,0 +1,5 @@ +stdnum.cn.uscc +============== + +.. automodule:: stdnum.cn.uscc + :members: \ No newline at end of file diff --git a/docs/stdnum.cz.bankaccount.rst b/docs/stdnum.cz.bankaccount.rst new file mode 100644 index 00000000..64ed9d56 --- /dev/null +++ b/docs/stdnum.cz.bankaccount.rst @@ -0,0 +1,5 @@ +stdnum.cz.bankaccount +===================== + +.. automodule:: stdnum.cz.bankaccount + :members: \ No newline at end of file diff --git a/docs/stdnum.de.leitweg.rst b/docs/stdnum.de.leitweg.rst new file mode 100644 index 00000000..747e1016 --- /dev/null +++ b/docs/stdnum.de.leitweg.rst @@ -0,0 +1,5 @@ +stdnum.de.leitweg +================= + +.. automodule:: stdnum.de.leitweg + :members: \ No newline at end of file diff --git a/docs/stdnum.dz.nif.rst b/docs/stdnum.dz.nif.rst new file mode 100644 index 00000000..845b47d6 --- /dev/null +++ b/docs/stdnum.dz.nif.rst @@ -0,0 +1,5 @@ +stdnum.dz.nif +============= + +.. automodule:: stdnum.dz.nif + :members: \ No newline at end of file diff --git a/docs/stdnum.eg.tn.rst b/docs/stdnum.eg.tn.rst new file mode 100644 index 00000000..4cf97686 --- /dev/null +++ b/docs/stdnum.eg.tn.rst @@ -0,0 +1,5 @@ +stdnum.eg.tn +============ + +.. automodule:: stdnum.eg.tn + :members: \ No newline at end of file diff --git a/docs/stdnum.es.cae.rst b/docs/stdnum.es.cae.rst new file mode 100644 index 00000000..93ddd64c --- /dev/null +++ b/docs/stdnum.es.cae.rst @@ -0,0 +1,5 @@ +stdnum.es.cae +============= + +.. automodule:: stdnum.es.cae + :members: \ No newline at end of file diff --git a/docs/stdnum.es.postal_code.rst b/docs/stdnum.es.postal_code.rst new file mode 100644 index 00000000..d6c8bf61 --- /dev/null +++ b/docs/stdnum.es.postal_code.rst @@ -0,0 +1,5 @@ +stdnum.es.postal_code +===================== + +.. automodule:: stdnum.es.postal_code + :members: \ No newline at end of file diff --git a/docs/stdnum.eu.ecnumber.rst b/docs/stdnum.eu.ecnumber.rst new file mode 100644 index 00000000..f6626e6d --- /dev/null +++ b/docs/stdnum.eu.ecnumber.rst @@ -0,0 +1,5 @@ +stdnum.eu.ecnumber +================== + +.. automodule:: stdnum.eu.ecnumber + :members: \ No newline at end of file diff --git a/docs/stdnum.eu.excise.rst b/docs/stdnum.eu.excise.rst new file mode 100644 index 00000000..0bfc38fd --- /dev/null +++ b/docs/stdnum.eu.excise.rst @@ -0,0 +1,5 @@ +stdnum.eu.excise +================ + +.. automodule:: stdnum.eu.excise + :members: \ No newline at end of file diff --git a/docs/stdnum.eu.oss.rst b/docs/stdnum.eu.oss.rst new file mode 100644 index 00000000..8f4b004b --- /dev/null +++ b/docs/stdnum.eu.oss.rst @@ -0,0 +1,5 @@ +stdnum.eu.oss +============= + +.. automodule:: stdnum.eu.oss + :members: \ No newline at end of file diff --git a/docs/stdnum.fo.vn.rst b/docs/stdnum.fo.vn.rst new file mode 100644 index 00000000..74730ee7 --- /dev/null +++ b/docs/stdnum.fo.vn.rst @@ -0,0 +1,5 @@ +stdnum.fo.vn +============ + +.. automodule:: stdnum.fo.vn + :members: \ No newline at end of file diff --git a/docs/stdnum.fr.accise.rst b/docs/stdnum.fr.accise.rst new file mode 100644 index 00000000..3c5b93db --- /dev/null +++ b/docs/stdnum.fr.accise.rst @@ -0,0 +1,5 @@ +stdnum.fr.accise +================ + +.. automodule:: stdnum.fr.accise + :members: \ No newline at end of file diff --git a/docs/stdnum.fr.rcs.rst b/docs/stdnum.fr.rcs.rst new file mode 100644 index 00000000..a77f27b9 --- /dev/null +++ b/docs/stdnum.fr.rcs.rst @@ -0,0 +1,5 @@ +stdnum.fr.rcs +============= + +.. automodule:: stdnum.fr.rcs + :members: \ No newline at end of file diff --git a/docs/stdnum.gb.utr.rst b/docs/stdnum.gb.utr.rst new file mode 100644 index 00000000..abfd4cdf --- /dev/null +++ b/docs/stdnum.gb.utr.rst @@ -0,0 +1,5 @@ +stdnum.gb.utr +============= + +.. automodule:: stdnum.gb.utr + :members: \ No newline at end of file diff --git a/docs/stdnum.gh.tin.rst b/docs/stdnum.gh.tin.rst new file mode 100644 index 00000000..fe8aaf5d --- /dev/null +++ b/docs/stdnum.gh.tin.rst @@ -0,0 +1,5 @@ +stdnum.gh.tin +============= + +.. automodule:: stdnum.gh.tin + :members: \ No newline at end of file diff --git a/docs/stdnum.gn.nifp.rst b/docs/stdnum.gn.nifp.rst new file mode 100644 index 00000000..0361b779 --- /dev/null +++ b/docs/stdnum.gn.nifp.rst @@ -0,0 +1,5 @@ +stdnum.gn.nifp +============== + +.. automodule:: stdnum.gn.nifp + :members: \ No newline at end of file diff --git a/docs/stdnum.gs1_128.rst b/docs/stdnum.gs1_128.rst new file mode 100644 index 00000000..ef40122c --- /dev/null +++ b/docs/stdnum.gs1_128.rst @@ -0,0 +1,5 @@ +stdnum.gs1_128 +============== + +.. automodule:: stdnum.gs1_128 + :members: \ No newline at end of file diff --git a/docs/stdnum.id.nik.rst b/docs/stdnum.id.nik.rst new file mode 100644 index 00000000..ca388859 --- /dev/null +++ b/docs/stdnum.id.nik.rst @@ -0,0 +1,5 @@ +stdnum.id.nik +============= + +.. automodule:: stdnum.id.nik + :members: \ No newline at end of file diff --git a/docs/stdnum.id.npwp.rst b/docs/stdnum.id.npwp.rst new file mode 100644 index 00000000..1a064638 --- /dev/null +++ b/docs/stdnum.id.npwp.rst @@ -0,0 +1,5 @@ +stdnum.id.npwp +============== + +.. automodule:: stdnum.id.npwp + :members: \ No newline at end of file diff --git a/docs/stdnum.il.hp.rst b/docs/stdnum.il.hp.rst new file mode 100644 index 00000000..8b4a6e80 --- /dev/null +++ b/docs/stdnum.il.hp.rst @@ -0,0 +1,5 @@ +stdnum.il.hp +============ + +.. automodule:: stdnum.il.hp + :members: \ No newline at end of file diff --git a/docs/stdnum.in_.epic.rst b/docs/stdnum.in_.epic.rst new file mode 100644 index 00000000..d7e3e901 --- /dev/null +++ b/docs/stdnum.in_.epic.rst @@ -0,0 +1,5 @@ +stdnum.in\_.epic +================ + +.. automodule:: stdnum.in_.epic + :members: \ No newline at end of file diff --git a/docs/stdnum.in_.gstin.rst b/docs/stdnum.in_.gstin.rst new file mode 100644 index 00000000..d0871072 --- /dev/null +++ b/docs/stdnum.in_.gstin.rst @@ -0,0 +1,5 @@ +stdnum.in\_.gstin +================= + +.. automodule:: stdnum.in_.gstin + :members: \ No newline at end of file diff --git a/docs/stdnum.in_.vid.rst b/docs/stdnum.in_.vid.rst new file mode 100644 index 00000000..602124c4 --- /dev/null +++ b/docs/stdnum.in_.vid.rst @@ -0,0 +1,5 @@ +stdnum.in\_.vid +=============== + +.. automodule:: stdnum.in_.vid + :members: \ No newline at end of file diff --git a/docs/stdnum.isni.rst b/docs/stdnum.isni.rst new file mode 100644 index 00000000..fd9ab985 --- /dev/null +++ b/docs/stdnum.isni.rst @@ -0,0 +1,5 @@ +stdnum.isni +=========== + +.. automodule:: stdnum.isni + :members: \ No newline at end of file diff --git a/docs/stdnum.isrc.rst b/docs/stdnum.isrc.rst new file mode 100644 index 00000000..e9c8f63d --- /dev/null +++ b/docs/stdnum.isrc.rst @@ -0,0 +1,5 @@ +stdnum.isrc +=========== + +.. automodule:: stdnum.isrc + :members: \ No newline at end of file diff --git a/docs/stdnum.it.aic.rst b/docs/stdnum.it.aic.rst new file mode 100644 index 00000000..ef2661f3 --- /dev/null +++ b/docs/stdnum.it.aic.rst @@ -0,0 +1,5 @@ +stdnum.it.aic +============= + +.. automodule:: stdnum.it.aic + :members: \ No newline at end of file diff --git a/docs/stdnum.jp.in_.rst b/docs/stdnum.jp.in_.rst new file mode 100644 index 00000000..7957124f --- /dev/null +++ b/docs/stdnum.jp.in_.rst @@ -0,0 +1,5 @@ +stdnum.jp.in_ +============= + +.. automodule:: stdnum.jp.in_ + :members: \ No newline at end of file diff --git a/docs/stdnum.ke.pin.rst b/docs/stdnum.ke.pin.rst new file mode 100644 index 00000000..bd47baf7 --- /dev/null +++ b/docs/stdnum.ke.pin.rst @@ -0,0 +1,5 @@ +stdnum.ke.pin +============= + +.. automodule:: stdnum.ke.pin + :members: \ No newline at end of file diff --git a/docs/stdnum.kr.brn.rst b/docs/stdnum.kr.brn.rst new file mode 100644 index 00000000..77331aed --- /dev/null +++ b/docs/stdnum.kr.brn.rst @@ -0,0 +1,5 @@ +stdnum.kr.brn +============= + +.. automodule:: stdnum.kr.brn + :members: \ No newline at end of file diff --git a/docs/stdnum.li.peid.rst b/docs/stdnum.li.peid.rst new file mode 100644 index 00000000..70ec351f --- /dev/null +++ b/docs/stdnum.li.peid.rst @@ -0,0 +1,5 @@ +stdnum.li.peid +============== + +.. automodule:: stdnum.li.peid + :members: diff --git a/docs/stdnum.ma.ice.rst b/docs/stdnum.ma.ice.rst new file mode 100644 index 00000000..32ef626c --- /dev/null +++ b/docs/stdnum.ma.ice.rst @@ -0,0 +1,5 @@ +stdnum.ma.ice +============= + +.. automodule:: stdnum.ma.ice + :members: \ No newline at end of file diff --git a/docs/stdnum.me.pib.rst b/docs/stdnum.me.pib.rst new file mode 100644 index 00000000..b713647c --- /dev/null +++ b/docs/stdnum.me.pib.rst @@ -0,0 +1,5 @@ +stdnum.me.pib +============= + +.. automodule:: stdnum.me.pib + :members: \ No newline at end of file diff --git a/docs/stdnum.mk.edb.rst b/docs/stdnum.mk.edb.rst new file mode 100644 index 00000000..bff1a283 --- /dev/null +++ b/docs/stdnum.mk.edb.rst @@ -0,0 +1,5 @@ +stdnum.mk.edb +============= + +.. automodule:: stdnum.mk.edb + :members: \ No newline at end of file diff --git a/docs/stdnum.mz.nuit.rst b/docs/stdnum.mz.nuit.rst new file mode 100644 index 00000000..8fd5d05f --- /dev/null +++ b/docs/stdnum.mz.nuit.rst @@ -0,0 +1,5 @@ +stdnum.mz.nuit +============== + +.. automodule:: stdnum.mz.nuit + :members: \ No newline at end of file diff --git a/docs/stdnum.nl.identiteitskaartnummer.rst b/docs/stdnum.nl.identiteitskaartnummer.rst new file mode 100644 index 00000000..782416d0 --- /dev/null +++ b/docs/stdnum.nl.identiteitskaartnummer.rst @@ -0,0 +1,5 @@ +stdnum.nl.identiteitskaartnummer +================================ + +.. automodule:: stdnum.nl.identiteitskaartnummer + :members: \ No newline at end of file diff --git a/docs/stdnum.pk.cnic.rst b/docs/stdnum.pk.cnic.rst new file mode 100644 index 00000000..c3a191b2 --- /dev/null +++ b/docs/stdnum.pk.cnic.rst @@ -0,0 +1,5 @@ +stdnum.pk.cnic +============== + +.. automodule:: stdnum.pk.cnic + :members: \ No newline at end of file diff --git a/docs/stdnum.pt.cc.rst b/docs/stdnum.pt.cc.rst new file mode 100644 index 00000000..954c9a99 --- /dev/null +++ b/docs/stdnum.pt.cc.rst @@ -0,0 +1,5 @@ +stdnum.pt.cc +============ + +.. automodule:: stdnum.pt.cc + :members: \ No newline at end of file diff --git a/docs/stdnum.ro.cui.rst b/docs/stdnum.ro.cui.rst new file mode 100644 index 00000000..e46aa91c --- /dev/null +++ b/docs/stdnum.ro.cui.rst @@ -0,0 +1,5 @@ +stdnum.ro.cui +============= + +.. automodule:: stdnum.ro.cui + :members: diff --git a/docs/stdnum.ro.onrc.rst b/docs/stdnum.ro.onrc.rst new file mode 100644 index 00000000..6cdb3aca --- /dev/null +++ b/docs/stdnum.ro.onrc.rst @@ -0,0 +1,5 @@ +stdnum.ro.onrc +============== + +.. automodule:: stdnum.ro.onrc + :members: \ No newline at end of file diff --git a/docs/stdnum.ru.ogrn.rst b/docs/stdnum.ru.ogrn.rst new file mode 100644 index 00000000..aee48283 --- /dev/null +++ b/docs/stdnum.ru.ogrn.rst @@ -0,0 +1,5 @@ +stdnum.ru.ogrn +============== + +.. automodule:: stdnum.ru.ogrn + :members: \ No newline at end of file diff --git a/docs/stdnum.se.postnummer.rst b/docs/stdnum.se.postnummer.rst new file mode 100644 index 00000000..025aeaf3 --- /dev/null +++ b/docs/stdnum.se.postnummer.rst @@ -0,0 +1,5 @@ +stdnum.se.postnummer +==================== + +.. automodule:: stdnum.se.postnummer + :members: \ No newline at end of file diff --git a/docs/stdnum.sg.uen.rst b/docs/stdnum.sg.uen.rst new file mode 100644 index 00000000..611216c3 --- /dev/null +++ b/docs/stdnum.sg.uen.rst @@ -0,0 +1,5 @@ +stdnum.sg.uen +============= + +.. automodule:: stdnum.sg.uen + :members: \ No newline at end of file diff --git a/docs/stdnum.si.emso.rst b/docs/stdnum.si.emso.rst new file mode 100644 index 00000000..e4cd833a --- /dev/null +++ b/docs/stdnum.si.emso.rst @@ -0,0 +1,5 @@ +stdnum.si.emso +============== + +.. automodule:: stdnum.si.emso + :members: \ No newline at end of file diff --git a/docs/stdnum.si.maticna.rst b/docs/stdnum.si.maticna.rst new file mode 100644 index 00000000..5a9de042 --- /dev/null +++ b/docs/stdnum.si.maticna.rst @@ -0,0 +1,5 @@ +stdnum.si.maticna +================= + +.. automodule:: stdnum.si.maticna + :members: \ No newline at end of file diff --git a/docs/stdnum.sn.ninea.rst b/docs/stdnum.sn.ninea.rst new file mode 100644 index 00000000..087fd3bb --- /dev/null +++ b/docs/stdnum.sn.ninea.rst @@ -0,0 +1,5 @@ +stdnum.sn.ninea +=============== + +.. automodule:: stdnum.sn.ninea + :members: \ No newline at end of file diff --git a/docs/stdnum.sv.nit.rst b/docs/stdnum.sv.nit.rst new file mode 100644 index 00000000..c5747a5f --- /dev/null +++ b/docs/stdnum.sv.nit.rst @@ -0,0 +1,5 @@ +stdnum.sv.nit +============= + +.. automodule:: stdnum.sv.nit + :members: \ No newline at end of file diff --git a/docs/stdnum.th.moa.rst b/docs/stdnum.th.moa.rst new file mode 100644 index 00000000..7377b73c --- /dev/null +++ b/docs/stdnum.th.moa.rst @@ -0,0 +1,5 @@ +stdnum.th.moa +============= + +.. automodule:: stdnum.th.moa + :members: \ No newline at end of file diff --git a/docs/stdnum.th.pin.rst b/docs/stdnum.th.pin.rst new file mode 100644 index 00000000..40c21e63 --- /dev/null +++ b/docs/stdnum.th.pin.rst @@ -0,0 +1,5 @@ +stdnum.th.pin +============= + +.. automodule:: stdnum.th.pin + :members: \ No newline at end of file diff --git a/docs/stdnum.th.tin.rst b/docs/stdnum.th.tin.rst new file mode 100644 index 00000000..c889ec2a --- /dev/null +++ b/docs/stdnum.th.tin.rst @@ -0,0 +1,5 @@ +stdnum.th.tin +============= + +.. automodule:: stdnum.th.tin + :members: \ No newline at end of file diff --git a/docs/stdnum.tn.mf.rst b/docs/stdnum.tn.mf.rst new file mode 100644 index 00000000..781d0b94 --- /dev/null +++ b/docs/stdnum.tn.mf.rst @@ -0,0 +1,5 @@ +stdnum.tn.mf +============ + +.. automodule:: stdnum.tn.mf + :members: \ No newline at end of file diff --git a/docs/stdnum.tw.ubn.rst b/docs/stdnum.tw.ubn.rst new file mode 100644 index 00000000..33d3575f --- /dev/null +++ b/docs/stdnum.tw.ubn.rst @@ -0,0 +1,5 @@ +stdnum.tw.ubn +============= + +.. automodule:: stdnum.tw.ubn + :members: \ No newline at end of file diff --git a/docs/stdnum.ua.edrpou.rst b/docs/stdnum.ua.edrpou.rst new file mode 100644 index 00000000..88c5c5db --- /dev/null +++ b/docs/stdnum.ua.edrpou.rst @@ -0,0 +1,5 @@ +stdnum.ua.edrpou +================ + +.. automodule:: stdnum.ua.edrpou + :members: diff --git a/docs/stdnum.ua.rntrc.rst b/docs/stdnum.ua.rntrc.rst new file mode 100644 index 00000000..89e92a6a --- /dev/null +++ b/docs/stdnum.ua.rntrc.rst @@ -0,0 +1,5 @@ +stdnum.ua.rntrc +=============== + +.. automodule:: stdnum.ua.rntrc + :members: diff --git a/docs/stdnum.vatin.rst b/docs/stdnum.vatin.rst new file mode 100644 index 00000000..f2b520d7 --- /dev/null +++ b/docs/stdnum.vatin.rst @@ -0,0 +1,5 @@ +stdnum.vatin +============ + +.. automodule:: stdnum.vatin + :members: \ No newline at end of file diff --git a/docs/stdnum.vn.mst.rst b/docs/stdnum.vn.mst.rst new file mode 100644 index 00000000..43a8755e --- /dev/null +++ b/docs/stdnum.vn.mst.rst @@ -0,0 +1,5 @@ +stdnum.vn.mst +============= + +.. automodule:: stdnum.vn.mst + :members: \ No newline at end of file diff --git a/docs/stdnum.za.idnr.rst b/docs/stdnum.za.idnr.rst new file mode 100644 index 00000000..e96da5f4 --- /dev/null +++ b/docs/stdnum.za.idnr.rst @@ -0,0 +1,5 @@ +stdnum.za.idnr +============== + +.. automodule:: stdnum.za.idnr + :members: \ No newline at end of file diff --git a/online_check/check.js b/online_check/check.js index 8a503729..68d16652 100644 --- a/online_check/check.js +++ b/online_check/check.js @@ -1,7 +1,7 @@ /* # check.js - simple application to check numbers # - # Copyright (C) 2017-2018 Arthur de Jong. + # Copyright (C) 2017-2020 Arthur de Jong. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -14,18 +14,15 @@ # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public - # License along with this library; if not, write to the Free Software - # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - # 02110-1301 USA + # License along with this library; if not, see . */ -$( document ).ready(function() { - +$(document).ready(function () { function format(value) { - return $("
").text(value).html().replace( - /\n\n/g, "
\n" + return $('
').text(value).html().replace( + /\n\n/g, '
\n' ).replace( - /^[*] (.*)$/gm, "
  • $1
" + /^[*] (.*)$/gm, '
  • $1
' ).replace( /(\b(https?|ftp):\/\/[^\s<]*[-\w+&@#/%=~_|])/ig, "$1" @@ -34,98 +31,96 @@ $( document ).ready(function() { function updateresults(field, results) { // build HTML to present - var h = ["
    "]; - $.each(results, function(index, result) { + var h = ['
      '] + $.each(results, function (index, result) { h.push( - "
    • ", - $("
      ").text(result["number"]).html(), - ": ", - $("
      ").text(result["name"]).html(), - "", - "

      ", - format(result["description"]), - $.map(result["conversions"], function(value, key){ + '

    • ', + $('
      ').text(result.number).html(), + ': ', + $('
      ').text(result.name).html(), + '', + '

      ', + format(result.description), + $.map(result.conversions, function (value, key) { return [ - "
      ", - $("

      ").text(key).html(), - ": ", - $("
      ").text(value).html()].join('') + '
      ', + $('
      ').text(key).html(), + ': ', + $('
      ').text(value).html()].join('') }).join(''), - "

    • ") - }); - h.push("
    "); + '

    ') + }) + h.push('
') // replace the results div - $("#" + $(field).attr("id") + "_results").html(h.join("")); + $('#' + $(field).attr('id') + '_results').html(h.join('')) } function checkfield(field) { - var value = field.val(); + var value = field.val() // only trigger update if value changed from previous validation - if (value != field.data("oldvalue")) { - field.data("oldvalue", value); - $("#" + $(field).attr("id") + "_results").slideUp(200, function() { - $.get('', {"number": value}, function(data) { - window.history.pushState({"value": value, "data": data}, $(document).find("title").text(), "?number=" + encodeURIComponent(value)); - updateresults(field, data); - }); - $(this).slideDown(300); - }); + if (value !== field.data('oldvalue')) { + field.data('oldvalue', value) + $('#' + $(field).attr('id') + '_results').slideUp(200, function () { + $.get('.', {number: value}, function (data) { + window.history.pushState({value: value, data: data}, $(document).find('title').text(), '?number=' + encodeURIComponent(value)) + updateresults(field, data) + }) + $(this).slideDown(300) + }) } } // update results based on history navigation - window.onpopstate = function(e) { - var field = $(".stdnum_check"); + window.onpopstate = function (e) { + var field = $('.stdnum_check') if (e.state) { - var value = e.state.value; - var data = e.state.data; + var value = e.state.value + var data = e.state.data field.val(value) - field.data("oldvalue", value); - updateresults(field, data); + field.data('oldvalue', value) + updateresults(field, data) } else { - field.val("") - field.data("oldvalue", ""); - updateresults(field, []); + field.val('') + field.data('oldvalue', '') + updateresults(field, []) } - }; + } // trigger a check when user stopped typing - $(".stdnum_check").on("input propertychange", function (event) { - if (window.event && event.type == "propertychange" && event.propertyName != "value") - return; - var field = $(this); - window.clearTimeout($(this).data("timeout")); - $(this).data("timeout", setTimeout(function () { - checkfield(field); - }, 2000)); - }); + $('.stdnum_check').on('input propertychange', function (event) { + if (window.event && event.type === 'propertychange' && event.propertyName !== 'value') { return } + var field = $(this) + window.clearTimeout($(this).data('timeout')) + $(this).data('timeout', setTimeout(function () { + checkfield(field) + }, 2000)) + }) // trigger a check when losing focus - $(".stdnum_check").on("blur", function() { - window.clearTimeout($(this).data("timeout")); - checkfield($(this)); - }); + $('.stdnum_check').on('blur', function () { + window.clearTimeout($(this).data('timeout')) + checkfield($(this)) + }) // prevent enter from submitting the form - $(".stdnum_check").keydown(function(event) { - if(event.keyCode == 13) { - event.preventDefault(); - checkfield($(this)); - return false; + $('.stdnum_check').keydown(function (event) { + if (event.keyCode === 13) { + event.preventDefault() + checkfield($(this)) + return false } - }); + }) // hide the submit button - $(".stdnum_hide").hide(); + $('.stdnum_hide').hide() // focus the text field - $(".stdnum_check").focus(); + $('.stdnum_check').focus() // save current state - var value = $(".stdnum_check").val(); - $(".stdnum_check").data("oldvalue", value); - $.get('', {number: value}, function(data) { - window.history.replaceState({"value": value, "data": data}, $(document).find("title").text(), "?number=" + encodeURIComponent(value)); + var value = $('.stdnum_check').val() + $('.stdnum_check').data('oldvalue', value) + $.get('', {number: value}, function (data) { + window.history.replaceState({value: value, data: data}, $(document).find('title').text(), '?number=' + encodeURIComponent(value)) }) - -}); +}) diff --git a/online_check/jquery-1.7.1.js b/online_check/jquery-1.7.1.js deleted file mode 100644 index 8ccd0ea7..00000000 --- a/online_check/jquery-1.7.1.js +++ /dev/null @@ -1,9266 +0,0 @@ -/*! - * jQuery JavaScript Library v1.7.1 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Mon Nov 21 21:11:03 2011 -0500 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Matches dashed string for camelizing - rdashAlpha = /-([a-z]|[0-9])/ig, - rmsPrefix = /^-ms-/, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return ( letter + "" ).toUpperCase(); - }, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = quickExpr.exec( selector ); - } - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = ( context ? context.ownerDocument || context : document ); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.7.1", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // Add the callback - readyList.add( fn ); - - return this; - }, - - eq: function( i ) { - i = +i; - return i === -1 ? - this.slice( i ) : - this.slice( i, i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } - - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.fireWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).off( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyList ) { - return; - } - - readyList = jQuery.Callbacks( "once memory" ); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - // A crude way of determining if an object is a window - isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; - }, - - isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw new Error( msg ); - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return ( new Function( "return " + data ) )(); - - } - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - parseXML: function( data ) { - var xml, tmp; - try { - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; - }, - - noop: function() {}, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array, i ) { - var len; - - if ( array ) { - if ( indexOf ) { - return indexOf.call( array, elem, i ); - } - - len = array.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in array && array[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, - j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; - - // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; - }, - - now: function() { - return ( new Date() ).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, - - browser: {} -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -return jQuery; - -})(); - - -// String to Object flags format cache -var flagsCache = {}; - -// Convert String-formatted flags into Object-formatted ones and store in cache -function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } - return object; -} - -/* - * Create a callback list using the following parameters: - * - * flags: an optional list of space-separated flags that will change how - * the callback list behaves - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible flags: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( flags ) { - - // Convert flags from String-formatted to Object-formatted - // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; - - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - list.push( elem ); - } - } - } - }, - // Fire callbacks - fire = function( context, args ) { - args = args || []; - memory = !flags.memory || [ context, args ]; - firing = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { - memory = true; // Mark as halted - break; - } - } - firing = false; - if ( list ) { - if ( !flags.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); - } - } else if ( memory === true ) { - self.disable(); - } else { - list = []; - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - var length = list.length; - add( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } - } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; - } - } - } - } - } - return this; - }, - // Control if a given callback is in the list - has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; - }, - // Remove all callbacks from the list - empty: function() { - list = []; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory || memory === true ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( stack ) { - if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!memory; - } - }; - - return self; -}; - - - - -var // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - - Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), - state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, - promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - - state: function() { - return state; - }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, - always: function() { - deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); - return this; - }, - pipe: function( fnDone, fnFail, fnProgress ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; - } - }, - deferred = promise.promise({}), - key; - - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } - - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } - if ( length > 1 ) { - for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return promise; - } -}); - - - - -jQuery.support = (function() { - - var support, - all, - a, - select, - opt, - input, - marginDiv, - fragment, - tds, - events, - eventName, - i, - isSupported, - div = document.createElement( "div" ), - documentElement = document.documentElement; - - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
a"; - - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return {}; - } - - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: ( div.firstChild.nodeType === 3 ), - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, - - // Get the style information from getAttribute - // (IE uses .cssText instead) - style: /top/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: ( a.getAttribute("href") === "/a" ), - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: ( input.value === "on" ), - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: opt.selected, - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - - // Tests for enctype support on a form(#6743) - enctype: !!document.createElement("form").enctype, - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", - - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, - deleteExpando: true, - noCloneEvent: true, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableMarginRight: true - }; - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent( "onclick" ); - } - - // Check if a radio maintains its value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; - - input.setAttribute("checked", "checked"); - div.appendChild( input ); - fragment = document.createDocumentFragment(); - fragment.appendChild( div.lastChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - fragment.removeChild( input ); - fragment.appendChild( div ); - - div.innerHTML = ""; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( window.getComputedStyle ) { - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.style.width = "2px"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - // Technique from Juriy Zaytsev - // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for( i in { - submit: 1, - change: 1, - focusin: 1 - }) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } - } - - fragment.removeChild( div ); - - // Null elements to avoid leaks in IE - fragment = select = opt = marginDiv = div = input = null; - - // Run tests that need a body at doc ready - jQuery(function() { - var container, outer, inner, table, td, offsetSupport, - conMarginTop, ptlm, vb, style, html, - body = document.getElementsByTagName("body")[0]; - - if ( !body ) { - // Return for frameset docs that don't have a body - return; - } - - conMarginTop = 1; - ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; - vb = "visibility:hidden;border:0;"; - style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; - html = "
" + - "" + - "
"; - - container = document.createElement("div"); - container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; - body.insertBefore( container, body.firstChild ); - - // Construct the test element - div = document.createElement("div"); - container.appendChild( div ); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - div.innerHTML = "
t
"; - tds = div.getElementsByTagName( "td" ); - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE <= 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - - // Figure out if the W3C box model works as expected - div.innerHTML = ""; - div.style.width = div.style.paddingLeft = "1px"; - jQuery.boxModel = support.boxModel = div.offsetWidth === 2; - - if ( typeof div.style.zoom !== "undefined" ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); - } - - div.style.cssText = ptlm + vb; - div.innerHTML = html; - - outer = div.firstChild; - inner = outer.firstChild; - td = outer.nextSibling.firstChild.firstChild; - - offsetSupport = { - doesNotAddBorder: ( inner.offsetTop !== 5 ), - doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) - }; - - inner.style.position = "fixed"; - inner.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); - inner.style.position = inner.style.top = ""; - - outer.style.overflow = "hidden"; - outer.style.position = "relative"; - - offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); - offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); - - body.removeChild( container ); - div = container = null; - - jQuery.extend( support, offsetSupport ); - }); - - return support; -})(); - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([A-Z])/g; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var privateCache, thisCache, ret, - internalKey = jQuery.expando, - getByName = typeof name === "string", - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, - isEvents = name === "events"; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ internalKey ] = id = ++jQuery.uuid; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // Avoids exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - privateCache = thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Users should not attempt to inspect the internal events object using jQuery.data, - // it is undocumented and subject to change. But does anyone listen? No. - if ( isEvents && !thisCache[ name ] ) { - return privateCache.events; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( getByName ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, l, - - // Reference to internal data cache key - internalKey = jQuery.expando, - - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ internalKey ] : internalKey; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split( " " ); - } - } - } - - for ( i = 0, l = name.length; i < l; i++ ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - // Ensure that `cache` is not a window object #10080 - if ( jQuery.support.deleteExpando || !cache.setInterval ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the cache and need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( internalKey ); - } else { - elem[ internalKey ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var parts, attr, name, - data = null; - - if ( typeof key === "undefined" ) { - if ( this.length ) { - data = jQuery.data( this[0] ); - - if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { - attr = this[0].attributes; - for ( var i = 0, l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - - dataAttr( this[0], name, data[ name ] ); - } - } - jQuery._data( this[0], "parsedAttrs", true ); - } - } - - return data; - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - - } else { - return this.each(function() { - var self = jQuery( this ), - args = [ parts[0], value ]; - - self.triggerHandler( "setData" + parts[1] + "!", args ); - jQuery.data( this, key, value ); - self.triggerHandler( "changeData" + parts[1] + "!", args ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - jQuery.isNumeric( data ) ? parseFloat( data ) : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery._data( elem, deferDataKey ); - if ( defer && - ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && - ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery._data( elem, queueDataKey ) && - !jQuery._data( elem, markDataKey ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.fire(); - } - }, 0 ); - } -} - -jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = ( type || "fx" ) + "mark"; - jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); - if ( count ) { - jQuery._data( elem, key, count ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - - queue: function( elem, type, data ) { - var q; - if ( elem ) { - type = ( type || "fx" ) + "queue"; - q = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - q.push( data ); - } - } - return q || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - fn = queue.shift(), - hooks = {}; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - jQuery._data( elem, type + ".run", hooks ); - fn.call( elem, function() { - jQuery.dequeue( elem, type ); - }, hooks ); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue " + type + ".run", true ); - handleQueueMarkDefer( elem, type, "queue" ); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - } - - if ( data === undefined ) { - return jQuery.queue( this[0], type ); - } - return this.each(function() { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { - count++; - tmp.add( resolve ); - } - } - resolve(); - return defer.promise(); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, - rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - nodeHook, boolHook, fixSpecified; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - - addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); - }); - } - - if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - classNames = ( value || "" ).split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var hooks, ret, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var self = jQuery(this), val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, i, max, option, - index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - i = one ? index : 0; - max = one ? index + 1 : options.length; - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( notxml ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var propName, attrNames, name, l, - i = 0; - - if ( value && elem.nodeType === 1 ) { - attrNames = value.toLowerCase().split( rspace ); - l = attrNames.length; - - for ( ; i < l; i++ ) { - name = attrNames[ i ]; - - if ( name ) { - propName = jQuery.propFix[ name ] || name; - - // See #9699 for explanation of this approach (setting first, then removal) - jQuery.attr( elem, name, "" ); - elem.removeAttribute( getSetAttribute ? name : propName ); - - // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && propName in elem ) { - elem[ propName ] = false; - } - } - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - }, - // Use the value property for back compat - // Use the nodeHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.get( elem, name ); - } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return ( elem[ name ] = value ); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - return elem[ name ]; - } - } - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - var attributeNode = elem.getAttributeNode("tabindex"); - - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - } - } -}); - -// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) -jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; - -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - // Fall back to attribute presence where some booleans are not supported - var attrNode, - property = jQuery.prop( elem, name ); - return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; - } - - elem.setAttribute( name, name.toLowerCase() ); - } - return name; - } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - fixSpecified = { - name: true, - id: true - }; - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - ret = document.createAttribute( name ); - elem.setAttributeNode( ret ); - } - return ( ret.nodeValue = value + "" ); - } - }; - - // Apply the nodeHook to tabindex - jQuery.attrHooks.tabindex.set = nodeHook.set; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - get: nodeHook.get, - set: function( elem, value, name ) { - if ( value === "" ) { - value = "false"; - } - nodeHook.set( elem, value, name ); - } - }; -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - return null; - } - }); -} - -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }); -}); - - - - -var rformElems = /^(?:textarea|input|select)$/i, - rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, - rhoverHack = /\bhover(\.\S+)?\b/, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - var attrs = elem.attributes || {}; - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || (attrs.id || {}).value === m[2]) && - (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) - ); - }, - hoverHack = function( events ) { - return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); - }; - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - add: function( elem, types, handler, data, selector ) { - - var elemData, eventHandle, events, - t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; - - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; - } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = jQuery.trim( hoverHack(types) ).split( " " ); - for ( t = 0; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: tns[1], - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - quick: quickParse( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - t, tns, type, origType, namespaces, origCount, - j, events, special, handle, eventType, handleObj; - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = jQuery.trim( hoverHack( types || "" ) ).split(" "); - for ( t = 0; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = origType = tns[1]; - namespaces = tns[2]; - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - - // Remove matching events - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !namespaces || namespaces.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - eventType.splice( j--, 1 ); - - if ( handleObj.selector ) { - eventType.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery.removeData( elem, [ "events", "handle" ], true ); - } - }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - - trigger: function( event, data, elem, onlyHandlers ) { - // Don't do events on text and comment nodes - if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { - return; - } - - // Event object or event type - var type = event.type || event, - namespaces = [], - cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "!" ) >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } - - if ( type.indexOf( "." ) >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } - - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.isTrigger = true; - event.exclusive = exclusive; - event.namespace = namespaces.join( "." ); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; - - // Handle a global trigger - if ( !elem ) { - - // TODO: Stop taunting the data cache; remove global events and always attach to document - cache = jQuery.cache; - for ( i in cache ) { - if ( cache[ i ].events && cache[ i ].events[ type ] ) { - jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); - } - } - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - old = null; - for ( ; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old && old === elem.ownerDocument ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); - } - } - - // Fire handlers on the event path - for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { - - cur = eventPath[i][0]; - event.type = eventPath[i][1]; - - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - // Note that this is a bare JS function and not a jQuery handler - handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { - event.preventDefault(); - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - // IE<9 dies on focus/blur to hidden element (#1486) - if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; - - if ( old ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( old ) { - elem[ ontype ] = old; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event || window.event ); - - var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, - args = [].slice.call( arguments, 0 ), - run_all = !event.exclusive && !event.namespace, - handlerQueue = [], - i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Determine handlers that should run if there are delegated events - // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { - - // Pregenerate a single jQuery object for reuse with .is() - jqcur = jQuery(this); - jqcur.context = this.ownerDocument || this; - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - selMatch = {}; - matches = []; - jqcur[0] = cur; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = ( - handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) - ); - } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); - } - - // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; - event.currentTarget = matched.elem; - - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; - - // Triggered event must either 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { - - event.data = handleObj.data; - event.handleObj = handleObj; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - return event.result; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** - props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) - if ( event.metaKey === undefined ) { - event.metaKey = event.ctrlKey; - } - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - - focus: { - delegateType: "focusin" - }, - blur: { - delegateType: "focusout" - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var target = this, - related = event.relatedTarget, - handleObj = event.handleObj, - selector = handleObj.selector, - ret; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !form._submit_attached ) { - jQuery.event.add( form, "submit._submit", function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - }); - form._submit_attached = true; - } - }); - // return undefined since we don't need an event listener - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - jQuery.event.simulate( "change", this, event, true ); - } - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - elem._change_attached = true; - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0, - handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on.call( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - var handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( var type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - - live: function( types, data, fn ) { - jQuery( this.context ).on( types, this.selector, data, fn ); - return this; - }, - die: function( types, fn ) { - jQuery( this.context ).off( types, this.selector || "**", fn ); - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - }; - - // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; - while ( i < args.length ) { - args[ i++ ].guid = guid; - } - - return this.click( toggler ); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } - - if ( rkeyEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; - } - - if ( rmouseEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; - } -}); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - expando = "sizcache" + (Math.random() + '').replace('.', ''), - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rReturn = /\r\n/g, - rNonWord = /\W/; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context, seed ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set, seed ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set, i, len, match, type, left; - - if ( !expr ) { - return []; - } - - for ( i = 0, len = Expr.order.length; i < len; i++ ) { - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - type, found, item, filter, left, - i, pass, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - filter = Expr.filter[ type ]; - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - pass = not ^ found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Utility function for retreiving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var i, node, - nodeType = elem.nodeType, - ret = ""; - - if ( nodeType ) { - if ( nodeType === 1 || nodeType === 9 ) { - // Use textContent || innerText for elements - if ( typeof elem.textContent === 'string' ) { - return elem.textContent; - } else if ( typeof elem.innerText === 'string' ) { - // Replace IE's carriage returns - return elem.innerText.replace( rReturn, '' ); - } else { - // Traverse it's children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - } else { - - // If no nodeType, this is expected to be an array - for ( i = 0; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - if ( node.nodeType !== 8 ) { - ret += getText( node ); - } - } - } - return ret; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - checked: function( elem ) { - return elem.checked === true; - }, - - selected: function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - text: function( elem ) { - var attr = elem.getAttribute( "type" ), type = elem.type; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var first, last, - doneName, parent, cache, - count, diff, - type = match[1], - node = elem; - - switch ( type ) { - case "only": - case "first": - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - if ( type === "first" ) { - return true; - } - - node = elem; - - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - first = match[2]; - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - doneName = match[0]; - parent = elem.parentNode; - - if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { - count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent[ expando ] = doneName; - } - - diff = elem.nodeIndex - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - TAG: function( elem, match ) { - return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; - }, - - CLASS: function( elem, match ) { - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Sizzle.attr ? - Sizzle.attr( elem, name ) : - Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - !type && Sizzle.attr ? - result != null : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Fallback to using sourceIndex (in IE) if it's available on both nodes - } else if ( a.sourceIndex && b.sourceIndex ) { - return a.sourceIndex - b.sourceIndex; - } - - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // If the nodes are siblings (or identical) we can do a quick check - if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || !disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function( match, context, isXML ) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context, seed ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet, seed ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -// Override sizzle attribute retrieval -Sizzle.attr = jQuery.attr; -Sizzle.selectors.attrMap = {}; -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.POS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - - var ret = this.pushStack( "", "find", selector ), - length, n, r; - - for ( i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && ( - typeof selector === "string" ? - // If this is a positional selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - POS.test( selector ) ? - jQuery( selector, this.context ).index( this[0] ) >= 0 : - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - // Array (deprecated as of jQuery 1.7) - if ( jQuery.isArray( selectors ) ) { - var level = 1; - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( i = 0; i < selectors.length; i++ ) { - - if ( jQuery( cur ).is( selectors[ i ] ) ) { - ret.push({ selector: selectors[ i ], elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call( arguments ).join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return ( elem === qualifier ) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; - }); -} - - - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /", "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }, - safeFragment = createSafeFragment( document ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and